Lindenii Project Forge
misc: Remove open_file, openat2, etc.
# 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 | | - | - | - | - | | scfg | Configuration parsing library | emersion | MIT | | cmap | Generic concurrent maps | Go | BSD-3-Clause | | gpool | Generic wrapper for sync.Pool | Go | BSD-3-Clause | ## Custom packages All custom packages are licensed under CC0-1.0. | Name | Description | | - | - | | misc | Misc functions | | clog | Logging utilities | | ansiec | ANSI escape codes |
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 }
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 }