diff --git a/internal/lib/os/os.go b/internal/lib/os/os.go index ebc0b46a..8f03caa3 100644 --- a/internal/lib/os/os.go +++ b/internal/lib/os/os.go @@ -19,12 +19,14 @@ package os // llgo:skipall import ( "errors" + "io/fs" "runtime" "syscall" _ "unsafe" "github.com/goplus/llgo/c" "github.com/goplus/llgo/c/os" + sys "github.com/goplus/llgo/c/syscall" ) const ( @@ -49,7 +51,8 @@ func (e *LinkError) Unwrap() error { } func toMode(mode FileMode) os.ModeT { - panic("todo: toMode") + unixMode := fileModeToUnixMode(mode) << 16 + return os.ModeT(unixMode) } func toPathErr(op, path string, errno c.Int) error { @@ -466,3 +469,33 @@ func UserHomeDir() (string, error) { // TODO(xsw): // func WriteFile(name string, data []byte, perm FileMode) error + +func fileModeToUnixMode(mode fs.FileMode) uint32 { + var m uint32 + switch mode & fs.ModeType { + default: + m = sys.S_IFREG + case fs.ModeDir: + m = sys.S_IFDIR + case fs.ModeSymlink: + m = sys.S_IFLNK + case fs.ModeNamedPipe: + m = sys.S_IFIFO + case fs.ModeSocket: + m = sys.S_IFSOCK + case fs.ModeDevice: + m = sys.S_IFBLK + case fs.ModeDevice | fs.ModeCharDevice: + m = sys.S_IFCHR + } + if mode&fs.ModeSetuid != 0 { + m |= sys.S_ISUID + } + if mode&fs.ModeSetgid != 0 { + m |= sys.S_ISGID + } + if mode&fs.ModeSticky != 0 { + m |= sys.S_ISVTX + } + return m | uint32(mode&0777) +}