mirror of
https://github.com/golang/go
synced 2025-05-25 15:00:09 +00:00
os: consolidate and clarify File.Fd docs
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>
This commit is contained in:
committed by
Gopher Robot
parent
89c2f282dc
commit
0044bc614a
@ -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
|
||||
|
@ -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
|
||||
|
@ -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))
|
||||
}
|
||||
|
@ -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)
|
||||
}
|
||||
|
@ -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
|
||||
|
Reference in New Issue
Block a user