From 55c4519707d88cc6d3ac1617d9903b0d5fd37540 Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Fri, 24 Apr 2026 14:56:29 +0530 Subject: [PATCH] More pointless UNIX variability --- tools/utils/file_at_fd.go | 11 +++------- tools/utils/file_at_fd_darwin.go | 13 ++++++++++-- tools/utils/file_at_fd_dragonfly.go | 31 +++++++++++++++++++++++++++++ tools/utils/file_at_fd_freebsd.go | 28 ++++++++++++++++++++++++++ tools/utils/file_at_fd_generic.go | 15 +++++++++++--- 5 files changed, 85 insertions(+), 13 deletions(-) create mode 100644 tools/utils/file_at_fd_dragonfly.go create mode 100644 tools/utils/file_at_fd_freebsd.go diff --git a/tools/utils/file_at_fd.go b/tools/utils/file_at_fd.go index 94ab714a7..593a6e182 100644 --- a/tools/utils/file_at_fd.go +++ b/tools/utils/file_at_fd.go @@ -148,7 +148,7 @@ func (m *UnixFileInfo) Mode() os.FileMode { return m.mode } func (m *UnixFileInfo) ModTime() time.Time { return time.Unix(m.stat.Mtim.Unix()) } func (m *UnixFileInfo) IsDir() bool { return m.Mode().IsDir() } func (m *UnixFileInfo) Sys() any { return m.stat } -func (m *UnixFileInfo) Dev() int { return int(m.stat.Rdev) } +func (m *UnixFileInfo) Dev() uint64 { return uint64(m.stat.Rdev) } // Get file info relative to the parent FD, follows symlinks func StatAt(dirFile *os.File, name string) (ans os.FileInfo, err error) { @@ -300,12 +300,7 @@ func DupFile(f *os.File) (ans *os.File, err error) { func ReadLinkAt(parent *os.File, name string) (ans string, err error) { buf := [unix.PathMax]byte{} - var n int - for { - if n, err = unix.Readlinkat(int(parent.Fd()), name, buf[:]); err != unix.EINTR { - break - } - } + n, err := readLinkAt(parent, name, buf[:]) if err != nil { return "", &os.PathError{Op: "readlinkat", Path: filepath.Join(parent.Name(), name), Err: err} } @@ -352,7 +347,7 @@ func ConvertFileModeToUnix(goMode os.FileMode) uint32 { return unixMode } -func MknodAt(parent *os.File, name string, mode os.FileMode, dev int) (err error) { +func MknodAt(parent *os.File, name string, mode os.FileMode, dev uint64) (err error) { unix_mode := ConvertFileModeToUnix(mode) if err = mknodAt(parent, name, unix_mode, dev); err != nil { err = &os.PathError{Op: "mknodat", Path: filepath.Join(parent.Name(), name), Err: err} diff --git a/tools/utils/file_at_fd_darwin.go b/tools/utils/file_at_fd_darwin.go index 94d2ad451..35aafd086 100644 --- a/tools/utils/file_at_fd_darwin.go +++ b/tools/utils/file_at_fd_darwin.go @@ -10,10 +10,19 @@ import ( var _ = fmt.Print -func mknodAt(parent *os.File, name string, mode uint32, dev int) (err error) { +func mknodAt(parent *os.File, name string, mode uint32, dev uint64) (err error) { path := filepath.Join(parent.Name(), name) for { - if err = unix.Mknod(path, mode, dev); err != unix.EINTR { + if err = unix.Mknod(path, mode, int(dev)); err != unix.EINTR { + break + } + } + return +} + +func readLinkAt(parent *os.File, name string, buf []byte) (n int, err error) { + for { + if n, err = unix.Readlinkat(int(parent.Fd()), name, buf[:]); err != unix.EINTR { break } } diff --git a/tools/utils/file_at_fd_dragonfly.go b/tools/utils/file_at_fd_dragonfly.go new file mode 100644 index 000000000..95ecd8c35 --- /dev/null +++ b/tools/utils/file_at_fd_dragonfly.go @@ -0,0 +1,31 @@ +package utils + +import ( + "fmt" + "os" + "path/filepath" + + "golang.org/x/sys/unix" +) + +var _ = fmt.Print + +func mknodAt(parent *os.File, name string, mode uint32, dev uint64) (err error) { + for { + if err = unix.Mknodat(int(parent.Fd()), name, mode, int(dev)); err != unix.EINTR { + break + } + } + return +} + +func readLinkAt(parent *os.File, name string, buf []byte) (n int, err error) { + path := filepath.Join(parent.Name(), name) + for { + if n, err = unix.Readlink(path, buf[:]); err != unix.EINTR { + break + } + } + return +} + diff --git a/tools/utils/file_at_fd_freebsd.go b/tools/utils/file_at_fd_freebsd.go new file mode 100644 index 000000000..1c86d0e20 --- /dev/null +++ b/tools/utils/file_at_fd_freebsd.go @@ -0,0 +1,28 @@ +package utils + +import ( + "fmt" + "os" + + "golang.org/x/sys/unix" +) + +var _ = fmt.Print + +func mknodAt(parent *os.File, name string, mode uint32, dev uint64) (err error) { + for { + if err = unix.Mknodat(int(parent.Fd()), name, mode, dev); err != unix.EINTR { + break + } + } + return +} + +func readLinkAt(parent *os.File, name string, buf []byte) (n int, err error) { + for { + if n, err = unix.Readlinkat(int(parent.Fd()), name, buf[:]); err != unix.EINTR { + break + } + } + return +} diff --git a/tools/utils/file_at_fd_generic.go b/tools/utils/file_at_fd_generic.go index e7c5285a0..bda426090 100644 --- a/tools/utils/file_at_fd_generic.go +++ b/tools/utils/file_at_fd_generic.go @@ -1,4 +1,4 @@ -//go:build !darwin +//go:build !darwin && !freebsd && !dragonfly package utils @@ -11,9 +11,18 @@ import ( var _ = fmt.Print -func mknodAt(parent *os.File, name string, mode uint32, dev int) (err error) { +func mknodAt(parent *os.File, name string, mode uint32, dev uint64) (err error) { for { - if err = unix.Mknodat(int(parent.Fd()), name, mode, dev); err != unix.EINTR { + if err = unix.Mknodat(int(parent.Fd()), name, mode, int(dev)); err != unix.EINTR { + break + } + } + return +} + +func readLinkAt(parent *os.File, name string, buf []byte) (n int, err error) { + for { + if n, err = unix.Readlinkat(int(parent.Fd()), name, buf[:]); err != unix.EINTR { break } }