syscall: document Sendfile semantics

syscall.Sendfile behavior differs significantly between operating
systems.

Document the platform-specific behavior for the offset argument and
partial write reporting on Linux versus BSD-derived systems.

Fixes #64044

Change-Id: I93f740c3e2df911a10bf0884ffab218d4bb4e5fc
GitHub-Last-Rev: a11b898bb9
GitHub-Pull-Request: golang/go#77224
Reviewed-on: https://go-review.googlesource.com/c/go/+/737122
Reviewed-by: Carlos Amedee <carlos@golang.org>
Reviewed-by: Michael Pratt <mpratt@google.com>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Reviewed-by: Tobias Klauser <tobias.klauser@gmail.com>
Auto-Submit: Michael Pratt <mpratt@google.com>
Reviewed-by: Ian Lance Taylor <iant@golang.org>
This commit is contained in:
Bill Morgan
2026-01-18 14:11:05 +00:00
committed by Gopher Robot
parent 858d4bf851
commit a006e17162

View File

@@ -525,6 +525,22 @@ func Socketpair(domain, typ, proto int) (fd [2]int, err error) {
return
}
// Sendfile copies up to count bytes from file descriptor infd to file descriptor outfd.
//
// It wraps the sendfile system call. The behavior varies by operating system,
// particularly regarding the offset argument and how partial writes are reported.
//
// On Linux, if offset is nil, Sendfile uses and updates the current file
// position of infd. If offset is non-nil, the current file position is
// unchanged, and the offset pointer is updated to reflect the bytes written.
// A non-nil error typically implies that no bytes were written.
//
// On BSD-derived systems (including macOS), if offset is nil, Sendfile panics.
// The offset argument is not updated by the system call; the caller must manually
// update the offset using the number of bytes written. These systems may
// return a non-zero byte count together with an error (for example, EAGAIN).
//
// For precise semantics, see the system documentation (e.g., man 2 sendfile).
func Sendfile(outfd int, infd int, offset *int64, count int) (written int, err error) {
if race.Enabled {
race.ReleaseMerge(unsafe.Pointer(&ioSync))