package os
import (
)
type sysfdType = int
func ( string) (*Root, error) {
var int
:= ignoringEINTR(func() error {
var error
, _, = open(, syscall.O_CLOEXEC, 0)
return
})
if != nil {
return nil, &PathError{Op: "open", Path: , Err: }
}
return newRoot(, )
}
func ( int, string) (*Root, error) {
var fileStat
:= ignoringEINTR(func() error {
return syscall.Fstat(, &.sys)
})
fillFileStatFromSys(&, )
if == nil && !.IsDir() {
syscall.Close()
return nil, &PathError{Op: "open", Path: , Err: errors.New("not a directory")}
}
if !supportsCloseOnExec {
syscall.CloseOnExec()
}
:= &Root{&root{
fd: ,
name: ,
}}
runtime.SetFinalizer(.root, (*root).Close)
return , nil
}
func ( *Root, string) (*Root, error) {
, := doInRoot(, , nil, func( int, string) ( int, error) {
ignoringEINTR(func() error {
, = unix.Openat(, , syscall.O_NOFOLLOW|syscall.O_CLOEXEC, 0)
if isNoFollowErr() {
= checkSymlink(, , )
}
return
})
return ,
})
if != nil {
return nil, &PathError{Op: "openat", Path: , Err: }
}
return newRoot(, joinPath(.Name(), ))
}
func ( *Root, string, int, FileMode) (*File, error) {
, := doInRoot(, , nil, func( int, string) ( int, error) {
ignoringEINTR(func() error {
, = unix.Openat(, , syscall.O_NOFOLLOW|syscall.O_CLOEXEC|, uint32())
if != nil {
:= &(O_CREATE|O_EXCL) == (O_CREATE | O_EXCL)
if ! && (isNoFollowErr() || == syscall.ENOTDIR) {
= checkSymlink(, , )
}
if && == syscall.ELOOP {
= syscall.EEXIST
}
}
return
})
return ,
})
if != nil {
return nil, &PathError{Op: "openat", Path: , Err: }
}
:= newFile(, joinPath(.Name(), ), kindOpenFile, unix.HasNonblockFlag())
return , nil
}
func ( int, string) (int, error) {
var (
int
error
)
ignoringEINTR(func() error {
, = unix.Openat(, , syscall.O_NOFOLLOW|syscall.O_CLOEXEC|syscall.O_DIRECTORY, 0)
if isNoFollowErr() || == syscall.ENOTDIR {
= checkSymlink(, , )
} else if == syscall.ENOTSUP || == syscall.EOPNOTSUPP {
= syscall.ENOTDIR
}
return
})
return ,
}
func ( *Root, string, bool) (FileInfo, error) {
, := doInRoot(, , nil, func( sysfdType, string) (FileInfo, error) {
var fileStat
if := unix.Fstatat(, , &.sys, unix.AT_SYMLINK_NOFOLLOW); != nil {
return nil,
}
fillFileStatFromSys(&, )
if ! && .Mode()&ModeSymlink != 0 {
return nil, checkSymlink(, , syscall.ELOOP)
}
return &, nil
})
if != nil {
return nil, &PathError{Op: "statat", Path: , Err: }
}
return , nil
}
func ( *Root, , string) error {
, := doInRoot(, , nil, func( sysfdType, string) (struct{}, error) {
return struct{}{}, symlinkat(, , )
})
if != nil {
return &LinkError{"symlinkat", , , }
}
return nil
}
func ( int, string, func() error) error {
if := checkSymlink(, , nil); != nil {
return
}
return ()
}
func ( int, string, FileMode) error {
return afterResolvingSymlink(, , func() error {
return ignoringEINTR(func() error {
return unix.Fchmodat(, , syscallMode(), unix.AT_SYMLINK_NOFOLLOW)
})
})
}
func ( int, string, , int) error {
return afterResolvingSymlink(, , func() error {
return ignoringEINTR(func() error {
return unix.Fchownat(, , , , unix.AT_SYMLINK_NOFOLLOW)
})
})
}
func ( int, string, , int) error {
return ignoringEINTR(func() error {
return unix.Fchownat(, , , , unix.AT_SYMLINK_NOFOLLOW)
})
}
func ( int, string, time.Time, time.Time) error {
return afterResolvingSymlink(, , func() error {
return ignoringEINTR(func() error {
:= chtimesUtimes(, )
return unix.Utimensat(, , &, unix.AT_SYMLINK_NOFOLLOW)
})
})
}
func ( int, string, FileMode) error {
return ignoringEINTR(func() error {
return unix.Mkdirat(, , syscallMode())
})
}
func ( int, string) error {
:= ignoringEINTR(func() error {
return unix.Unlinkat(, , 0)
})
if == nil {
return nil
}
:= ignoringEINTR(func() error {
return unix.Unlinkat(, , unix.AT_REMOVEDIR)
})
if == nil {
return nil
}
if != syscall.ENOTDIR {
return
}
return
}
func ( int, string) error {
return ignoringEINTR(func() error {
return unix.Unlinkat(, , 0)
})
}
func ( int, string) error {
return ignoringEINTR(func() error {
return unix.Unlinkat(, , unix.AT_REMOVEDIR)
})
}
func ( int, string, int, string) error {
return unix.Renameat(, , , )
}
func ( int, string, int, string) error {
return unix.Linkat(, , , , 0)
}
func ( string, int, string) error {
return unix.Symlinkat(, , )
}
func ( int, string) (FileMode, error) {
var fileStat
if := unix.Fstatat(, , &.sys, unix.AT_SYMLINK_NOFOLLOW); != nil {
return 0,
}
fillFileStatFromSys(&, )
return .mode, nil
}
func ( int, string, error) error {
, := readlinkat(, )
if != nil {
return
}
return errSymlink()
}
func ( int, string) (string, error) {
for := 128; ; *= 2 {
:= make([]byte, )
var (
int
error
)
ignoringEINTR(func() error {
, = unix.Readlinkat(, , )
return
})
if == syscall.ERANGE {
continue
}
if != nil {
return "",
}
= max(, 0)
if < {
return string([0:]), nil
}
}
}