]> Cypherpunks repositories - gostls13.git/commitdiff
os: consolidate and clarify File.Fd docs
authorIan Lance Taylor <iant@golang.org>
Tue, 11 Feb 2025 20:56:27 +0000 (12:56 -0800)
committerGopher Robot <gobot@golang.org>
Thu, 13 Feb 2025 21:10:32 +0000 (13:10 -0800)
Change-Id: Id062b969fe7d6908a0797b36a4a379e4d46ba557
Reviewed-on: https://go-review.googlesource.com/c/go/+/648516
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Auto-Submit: Ian Lance Taylor <iant@google.com>
Reviewed-by: Ian Lance Taylor <iant@google.com>
Reviewed-by: Damien Neil <dneil@google.com>
src/os/file.go
src/os/file_plan9.go
src/os/file_unix.go
src/os/file_windows.go
src/os/stat_plan9.go

index 1d4382e4861f6a311f6eabe589538d23a389f908..32ff6be7be253823259f334d0ae632aea931fdc8 100644 (file)
@@ -685,6 +685,23 @@ func (f *File) SyscallConn() (syscall.RawConn, error) {
        return newRawConn(f)
 }
 
+// Fd returns the system file descriptor or handle referencing the open file.
+// If f is closed, the descriptor becomes invalid.
+// If f is garbage collected, a cleanup may close the descriptor,
+// making it invalid; see [runtime.AddCleanup] for more information on when
+// a cleanup might be run.
+//
+// Do not close the returned descriptor; that could cause a later
+// close of f to close an unrelated descriptor.
+//
+// On Unix systems this will cause the [File.SetDeadline]
+// methods to stop working.
+//
+// For most uses prefer the f.SyscallConn method.
+func (f *File) Fd() uintptr {
+       return f.fd()
+}
+
 // DirFS returns a file system (an fs.FS) for the tree of files rooted at the directory dir.
 //
 // Note that DirFS("/prefix") only guarantees that the Open calls it makes to the
index f74dbf20c49df76f7e5f2bdad34db221f02f4b53..73df3b086dc3d765d41aa95644229463eb3893b0 100644 (file)
@@ -27,26 +27,19 @@ func fixLongPath(path string) string {
 // to close the wrong file descriptor.
 type file struct {
        fdmu       poll.FDMutex
-       fd         int
+       sysfd      int
        name       string
        dirinfo    atomic.Pointer[dirInfo] // nil unless directory being read
        appendMode bool                    // whether file is opened for appending
        cleanup    runtime.Cleanup         // cleanup closes the file when no longer referenced
 }
 
-// Fd returns the integer Plan 9 file descriptor referencing the open file.
-// If f is closed, the file descriptor becomes invalid.
-// If f is garbage collected, a cleanup may close the file descriptor,
-// making it invalid; see [runtime.AddCleanup] for more information on when
-// a cleanup might be run. On Unix systems this will cause the [File.SetDeadline]
-// methods to stop working.
-//
-// As an alternative, see the f.SyscallConn method.
-func (f *File) Fd() uintptr {
+// fd is the Plan 9 implementation of Fd.
+func (f *File) fd() uintptr {
        if f == nil {
                return ^(uintptr(0))
        }
-       return uintptr(f.fd)
+       return uintptr(f.sysfd)
 }
 
 // NewFile returns a new File with the given file descriptor and
@@ -57,7 +50,7 @@ func NewFile(fd uintptr, name string) *File {
        if fdi < 0 {
                return nil
        }
-       f := &File{&file{fd: fdi, name: name}}
+       f := &File{&file{sysfd: fdi, name: name}}
        f.cleanup = runtime.AddCleanup(f, func(f *file) { f.close() }, f.file)
        return f
 }
@@ -180,7 +173,7 @@ func (file *file) close() error {
 // and writeUnlock methods.
 func (file *file) destroy() error {
        var err error
-       if e := syscall.Close(file.fd); e != nil {
+       if e := syscall.Close(file.sysfd); e != nil {
                err = &PathError{Op: "close", Path: file.name, Err: e}
        }
        return err
@@ -222,7 +215,7 @@ func (f *File) Truncate(size int64) error {
        }
        defer f.decref()
 
-       if err = syscall.Fwstat(f.fd, buf[:n]); err != nil {
+       if err = syscall.Fwstat(f.sysfd, buf[:n]); err != nil {
                return &PathError{Op: "truncate", Path: f.name, Err: err}
        }
        return nil
@@ -254,7 +247,7 @@ func (f *File) chmod(mode FileMode) error {
        }
        defer f.decref()
 
-       if err = syscall.Fwstat(f.fd, buf[:n]); err != nil {
+       if err = syscall.Fwstat(f.sysfd, buf[:n]); err != nil {
                return &PathError{Op: "chmod", Path: f.name, Err: err}
        }
        return nil
@@ -281,7 +274,7 @@ func (f *File) Sync() error {
        }
        defer f.decref()
 
-       if err = syscall.Fwstat(f.fd, buf[:n]); err != nil {
+       if err = syscall.Fwstat(f.sysfd, buf[:n]); err != nil {
                return &PathError{Op: "sync", Path: f.name, Err: err}
        }
        return nil
@@ -294,7 +287,7 @@ func (f *File) read(b []byte) (n int, err error) {
                return 0, err
        }
        defer f.readUnlock()
-       n, e := fixCount(syscall.Read(f.fd, b))
+       n, e := fixCount(syscall.Read(f.sysfd, b))
        if n == 0 && len(b) > 0 && e == nil {
                return 0, io.EOF
        }
@@ -309,7 +302,7 @@ func (f *File) pread(b []byte, off int64) (n int, err error) {
                return 0, err
        }
        defer f.readUnlock()
-       n, e := fixCount(syscall.Pread(f.fd, b, off))
+       n, e := fixCount(syscall.Pread(f.sysfd, b, off))
        if n == 0 && len(b) > 0 && e == nil {
                return 0, io.EOF
        }
@@ -328,7 +321,7 @@ func (f *File) write(b []byte) (n int, err error) {
        if len(b) == 0 {
                return 0, nil
        }
-       return fixCount(syscall.Write(f.fd, b))
+       return fixCount(syscall.Write(f.sysfd, b))
 }
 
 // pwrite writes len(b) bytes to the File starting at byte offset off.
@@ -343,7 +336,7 @@ func (f *File) pwrite(b []byte, off int64) (n int, err error) {
        if len(b) == 0 {
                return 0, nil
        }
-       return fixCount(syscall.Pwrite(f.fd, b, off))
+       return fixCount(syscall.Pwrite(f.sysfd, b, off))
 }
 
 // seek sets the offset for the next Read or Write on file to offset, interpreted
@@ -358,7 +351,7 @@ func (f *File) seek(offset int64, whence int) (ret int64, err error) {
        // Free cached dirinfo, so we allocate a new one if we
        // access this file as a directory again. See #35767 and #37161.
        f.dirinfo.Store(nil)
-       return syscall.Seek(f.fd, offset, whence)
+       return syscall.Seek(f.sysfd, offset, whence)
 }
 
 // Truncate changes the size of the named file.
@@ -555,7 +548,7 @@ func (f *File) Chdir() error {
                return err
        }
        defer f.decref()
-       if e := syscall.Fchdir(f.fd); e != nil {
+       if e := syscall.Fchdir(f.sysfd); e != nil {
                return &PathError{Op: "chdir", Path: f.name, Err: e}
        }
        return nil
index 5e9239edc56e40dd94ca415e1932787124ca9343..bb99b5279de53b1289f5904911a0bb4f0b88de6d 100644 (file)
@@ -66,19 +66,8 @@ type file struct {
        cleanup     runtime.Cleanup         // cleanup closes the file when no longer referenced
 }
 
-// Fd returns the integer Unix file descriptor referencing the open file.
-// If f is closed, the file descriptor becomes invalid.
-// If f is garbage collected, a cleanup may close the file descriptor,
-// making it invalid; see [runtime.AddCleanup] for more information on when
-// a cleanup might be run. On Unix systems this will cause the [File.SetDeadline]
-// methods to stop working.
-// Because file descriptors can be reused, the returned file descriptor may
-// only be closed through the [File.Close] method of f, or by its cleanup during
-// garbage collection. Otherwise, during garbage collection the cleanup
-// may close an unrelated file descriptor with the same (reused) number.
-//
-// As an alternative, see the f.SyscallConn method.
-func (f *File) Fd() uintptr {
+// fd is the Unix implementation of Fd.
+func (f *File) fd() uintptr {
        if f == nil {
                return ^(uintptr(0))
        }
index 2da924fe437db453316ca151566c2191f981171e..c209a9f003b39bdc0571c496fabfdb8640faca56 100644 (file)
@@ -32,13 +32,8 @@ type file struct {
        cleanup    runtime.Cleanup         // cleanup closes the file when no longer referenced
 }
 
-// Fd returns the Windows handle referencing the open file.
-// If f is closed, the file descriptor becomes invalid.
-// If f is garbage collected, a cleanup may close the file descriptor,
-// making it invalid; see [runtime.AddCleanup] for more information on when
-// a cleanup might be run. On Unix systems this will cause the [File.SetDeadline]
-// methods to stop working.
-func (file *File) Fd() uintptr {
+// fd is the Windows implementation of Fd.
+func (file *File) fd() uintptr {
        if file == nil {
                return uintptr(syscall.InvalidHandle)
        }
index a5e9901379aeac52c68c94682c5f903945bac0e2..e9fba17e9d1b5171e21ef51811caaa91f16f4fad 100644 (file)
@@ -59,7 +59,7 @@ func dirstat(arg any) (*syscall.Dir, error) {
                        if err := a.incref("fstat"); err != nil {
                                return nil, err
                        }
-                       n, err = syscall.Fstat(a.fd, buf)
+                       n, err = syscall.Fstat(a.sysfd, buf)
                        a.decref()
                case string:
                        name = a