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(, , 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(, )
}
func ( *Root, string, int, FileMode) (*File, error) {
, := doInRoot(, , func( int, string) ( int, error) {
ignoringEINTR(func() error {
, = unix.Openat(, , syscall.O_NOFOLLOW|syscall.O_CLOEXEC|, uint32())
if isNoFollowErr() || == syscall.ENOTDIR {
= checkSymlink(, , )
}
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(, , 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 ( 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) 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 "",
}
if < 0 {
= 0
}
if < {
return string([0:]), nil
}
}
}