diff options
-rw-r--r-- | README.md | 5 | ||||
-rw-r--r-- | misc/open_file.go | 75 | ||||
-rw-r--r-- | misc/openat2.go | 36 |
3 files changed, 0 insertions, 116 deletions
@@ -1,10 +1,5 @@ # Common Go libraries for Lindenii projects -## Warning - -Currently this only works on Linux because we use Linux-specific system calls. -This needs to be addressed in the future. - ## Ported/forked packages | Name | Description | Origin | License | diff --git a/misc/open_file.go b/misc/open_file.go deleted file mode 100644 index 07ac1b8..0000000 --- a/misc/open_file.go +++ /dev/null @@ -1,75 +0,0 @@ -package misc - -import ( - "errors" - "os" - "path" - "strings" - "syscall" -) - -type Dir struct { - fd int - name string -} - -var ( - ErrIllegalFilename = errors.New("illegal filename") - ErrInvalidFD = errors.New("invalid file descriptor") -) - -// Open a file at exactly the given directory. -func OpenFileAt(dir Dir, filename string, flags int, perms os.FileMode) (*os.File, error) { - if strings.IndexByte(filename, '/') != -1 { - return nil, ErrIllegalFilename - } - return OpenFileBeneath(dir, filename, flags, perms) -} - -// Open a file at or beneath the given directory. -func OpenFileBeneath(dir Dir, filename string, flags int, perms os.FileMode) (*os.File, error) { - fd, err := Openat2(dir.fd, filename, &Open_how_t{ - Flags: uint64(flags) | syscall.O_CLOEXEC, - Mode: uint64(syscallMode(perms)), - Resolve: RESOLVE_BENEATH | RESOLVE_NO_SYMLINKS, - }) - if err != nil { - return nil, err - } - file := os.NewFile(uintptr(fd), path.Join(dir.name, filename)) - if file == nil { - return nil, ErrInvalidFD - } else { - return file, nil - } -} - -// Open a directory as read-only and return a Dir_t to it. The caller is -// responsible for closing the directory with [Close_directory]. -func Open_directory_readonly(path string) (Dir, error) { - _fd, err := syscall.Open(path, syscall.O_RDONLY|syscall.O_DIRECTORY|syscall.O_CLOEXEC, 0) - return Dir{fd: _fd, name: path}, err -} - -// Close a directory returned by [Open_directory_readonly]. -func (dir *Dir) Close() error { - return syscall.Close(dir.fd) -} - -// syscallMode returns the syscall-specific mode flags from Go's portable mode flags. -func syscallMode(i os.FileMode) (o uint32) { - // This part actually came from Go's os/file_posix.go but IMO it's too - // small and should fall under fair use. - o |= uint32(i.Perm()) - if i&os.ModeSetuid != 0 { - o |= syscall.S_ISUID - } - if i&os.ModeSetgid != 0 { - o |= syscall.S_ISGID - } - if i&os.ModeSticky != 0 { - o |= syscall.S_ISVTX - } - // No mapping for Go's ModeTemporary (plan9 only). - return -} diff --git a/misc/openat2.go b/misc/openat2.go deleted file mode 100644 index e5938ca..0000000 --- a/misc/openat2.go +++ /dev/null @@ -1,36 +0,0 @@ -package misc - -import ( - "syscall" - "unsafe" -) - -const SYS_OPENAT2 = 437 - -type Open_how_t struct { - Flags uint64 - Mode uint64 - Resolve uint64 -} - -const ( - RESOLVE_BENEATH = 0x8 - RESOLVE_IN_ROOT = 0x10 - RESOLVE_NO_MAGICLINKS = 0x2 - RESOLVE_NO_SYMLINKS = 0x4 - RESOLVE_NO_XDEV = 0x1 -) - -// See openat2(2) on Linux -func Openat2(dirfd int, path string, open_how *Open_how_t) (fd int, err error) { - path_ptr, err := StringToBytePtr(path) - if err != nil { - return - } - _fd, _, errno := syscall.Syscall6(SYS_OPENAT2, uintptr(dirfd), uintptr(unsafe.Pointer(path_ptr)), uintptr(unsafe.Pointer(open_how)), uintptr(unsafe.Sizeof(Open_how_t{})), 0, 0) - fd = int(_fd) - if errno != 0 { - err = errno - } - return -} |