From 2279be17465d20e08b161c3fa51d144822363843 Mon Sep 17 00:00:00 2001 From: Damian Gryski Date: Thu, 22 Feb 2024 10:31:34 -0800 Subject: [PATCH] syscall: libc_wasip2: mkdir/rmdir/rename/symlink/readlink/unlink --- src/syscall/libc_wasip2.go | 78 +++++++++++++++++++++++++++++++++++++- 1 file changed, 76 insertions(+), 2 deletions(-) diff --git a/src/syscall/libc_wasip2.go b/src/syscall/libc_wasip2.go index 9dc2dc572d..d53305d514 100644 --- a/src/syscall/libc_wasip2.go +++ b/src/syscall/libc_wasip2.go @@ -420,6 +420,15 @@ func chmod(pathname *byte, mode uint32) int32 { // //go:export mkdir func mkdir(pathname *byte, mode uint32) int32 { + path := goString(pathname) + dir, relPath := findPreopenForPath(path) + + result := dir.CreateDirectoryAt(relPath) + if err := result.Err(); err != nil { + libcErrno = uintptr(errorCodeToErrno(*err)) + return -1 + } + return 0 } @@ -427,6 +436,15 @@ func mkdir(pathname *byte, mode uint32) int32 { // //go:export rmdir func rmdir(pathname *byte) int32 { + path := goString(pathname) + dir, relPath := findPreopenForPath(path) + + result := dir.RemoveDirectoryAt(relPath) + if err := result.Err(); err != nil { + libcErrno = uintptr(errorCodeToErrno(*err)) + return -1 + } + return 0 } @@ -434,6 +452,18 @@ func rmdir(pathname *byte) int32 { // //go:export rename func rename(from, to *byte) int32 { + fromPath := goString(from) + fromDir, fromRelPath := findPreopenForPath(fromPath) + + toPath := goString(to) + toDir, toRelPath := findPreopenForPath(toPath) + + result := fromDir.RenameAt(fromRelPath, toDir, toRelPath) + if err := result.Err(); err != nil { + libcErrno = uintptr(errorCodeToErrno(*err)) + return -1 + } + return 0 } @@ -441,6 +471,25 @@ func rename(from, to *byte) int32 { // //go:export symlink func symlink(from, to *byte) int32 { + fromPath := goString(from) + fromDir, fromRelPath := findPreopenForPath(fromPath) + + toPath := goString(to) + toDir, toRelPath := findPreopenForPath(toPath) + + if fromDir != toDir { + libcErrno = uintptr(EACCES) + return -1 + } + + // TODO(dgryski): check fromDir == toDir? + + result := fromDir.SymlinkAt(fromRelPath, toRelPath) + if err := result.Err(); err != nil { + libcErrno = uintptr(errorCodeToErrno(*err)) + return -1 + } + return 0 } @@ -455,14 +504,39 @@ func fsync(fd int32) int32 { // ssize_t readlink(const char *path, void *buf, size_t count); // //go:export readlink -func readlink(path *byte, buf *byte, count uint) int { - return 0 +func readlink(pathname *byte, buf *byte, count uint) int { + path := goString(pathname) + dir, relPath := findPreopenForPath(path) + + result := dir.ReadLinkAt(relPath) + if err := result.Err(); err != nil { + libcErrno = uintptr(errorCodeToErrno(*err)) + return -1 + } + + s := *result.OK() + size := uintptr(count) + if size > uintptr(len(s)) { + size = uintptr(len(s)) + } + + memcpy(unsafe.Pointer(buf), unsafe.Pointer(unsafe.StringData(s)), size) + return int(size) } // int unlink(const char *pathname); // //go:export unlink func unlink(pathname *byte) int32 { + path := goString(pathname) + dir, relPath := findPreopenForPath(path) + + result := dir.UnlinkFileAt(relPath) + if err := result.Err(); err != nil { + libcErrno = uintptr(errorCodeToErrno(*err)) + return -1 + } + return 0 }