diff --git a/src/net/sendfile_dragonfly.go b/src/net/sendfile_bsd.go similarity index 76% rename from src/net/sendfile_dragonfly.go rename to src/net/sendfile_bsd.go index d4b825c370..67e80c9c6a 100644 --- a/src/net/sendfile_dragonfly.go +++ b/src/net/sendfile_bsd.go @@ -2,6 +2,8 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. +// +build dragonfly freebsd + package net import ( @@ -22,10 +24,11 @@ const maxSendfileSize int = 4 << 20 // // if handled == false, sendFile performed no work. func sendFile(c *netFD, r io.Reader) (written int64, err error, handled bool) { - // DragonFly uses 0 as the "until EOF" value. If you pass in more bytes than the - // file contains, it will loop back to the beginning ad nauseam until it's sent - // exactly the number of bytes told to. As such, we need to know exactly how many - // bytes to send. + // FreeBSD and DragonFly use 0 as the "until EOF" value. + // If you pass in more bytes than the file contains, it will + // loop back to the beginning ad nauseam until it's sent + // exactly the number of bytes told to. As such, we need to + // know exactly how many bytes to send. var remain int64 = 0 lr, ok := r.(*io.LimitedReader) @@ -49,10 +52,11 @@ func sendFile(c *netFD, r io.Reader) (written int64, err error, handled bool) { remain = fi.Size() } - // The other quirk with DragonFly's sendfile implementation is that it doesn't - // use the current position of the file -- if you pass it offset 0, it starts - // from offset 0. There's no way to tell it "start from current position", so - // we have to manage that explicitly. + // The other quirk with FreeBSD/DragonFly's sendfile + // implementation is that it doesn't use the current position + // of the file -- if you pass it offset 0, it starts from + // offset 0. There's no way to tell it "start from current + // position", so we have to manage that explicitly. pos, err := f.Seek(0, io.SeekCurrent) if err != nil { return 0, err, false diff --git a/src/net/sendfile_freebsd.go b/src/net/sendfile_freebsd.go deleted file mode 100644 index 18cbb27b53..0000000000 --- a/src/net/sendfile_freebsd.go +++ /dev/null @@ -1,106 +0,0 @@ -// Copyright 2011 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package net - -import ( - "io" - "os" - "syscall" -) - -// maxSendfileSize is the largest chunk size we ask the kernel to copy -// at a time. -const maxSendfileSize int = 4 << 20 - -// sendFile copies the contents of r to c using the sendfile -// system call to minimize copies. -// -// if handled == true, sendFile returns the number of bytes copied and any -// non-EOF error. -// -// if handled == false, sendFile performed no work. -func sendFile(c *netFD, r io.Reader) (written int64, err error, handled bool) { - // FreeBSD uses 0 as the "until EOF" value. If you pass in more bytes than the - // file contains, it will loop back to the beginning ad nauseam until it's sent - // exactly the number of bytes told to. As such, we need to know exactly how many - // bytes to send. - var remain int64 = 0 - - lr, ok := r.(*io.LimitedReader) - if ok { - remain, r = lr.N, lr.R - if remain <= 0 { - return 0, nil, true - } - } - f, ok := r.(*os.File) - if !ok { - return 0, nil, false - } - - if remain == 0 { - fi, err := f.Stat() - if err != nil { - return 0, err, false - } - - remain = fi.Size() - } - - // The other quirk with FreeBSD's sendfile implementation is that it doesn't - // use the current position of the file -- if you pass it offset 0, it starts - // from offset 0. There's no way to tell it "start from current position", so - // we have to manage that explicitly. - pos, err := f.Seek(0, io.SeekCurrent) - if err != nil { - return 0, err, false - } - - if err := c.writeLock(); err != nil { - return 0, err, true - } - defer c.writeUnlock() - - dst := c.sysfd - src := int(f.Fd()) - for remain > 0 { - n := maxSendfileSize - if int64(n) > remain { - n = int(remain) - } - pos1 := pos - n, err1 := syscall.Sendfile(dst, src, &pos1, n) - if n > 0 { - pos += int64(n) - written += int64(n) - remain -= int64(n) - } - if n == 0 && err1 == nil { - break - } - if err1 == syscall.EAGAIN { - if err1 = c.pd.waitWrite(); err1 == nil { - continue - } - } - if err1 == syscall.EINTR { - continue - } - if err1 != nil { - // This includes syscall.ENOSYS (no kernel - // support) and syscall.EINVAL (fd types which - // don't implement sendfile) - err = err1 - break - } - } - if lr != nil { - lr.N = remain - } - if err != nil { - err = os.NewSyscallError("sendfile", err) - } - return written, err, written > 0 -}