diff --git a/libc/include/fcntl.h b/libc/include/fcntl.h index 6a90deaa..3f58a3fc 100644 --- a/libc/include/fcntl.h +++ b/libc/include/fcntl.h @@ -16,6 +16,9 @@ extern "C" /* Open a file path and return a file descriptor to it. */ int open(const char* path, int flags, ...); + /* Open a file path relative to a file descriptor and return a file descriptor to it. */ + int openat(int dirfd, const char* path, int flags, ...); + /* Create a file and return a file descriptor to it. */ int creat(const char* path, mode_t mode); diff --git a/libc/include/unistd.h b/libc/include/unistd.h index c0265ea2..cfae95bd 100644 --- a/libc/include/unistd.h +++ b/libc/include/unistd.h @@ -115,6 +115,9 @@ extern "C" /* Remove a name from the filesystem. */ int unlink(const char* path); + /* Remove a name or directory from the filesystem. */ + int unlinkat(int dirfd, const char* path, int flags); + /* Remove a directory from the filesystem. */ int rmdir(const char* path); diff --git a/libc/src/fcntl.cpp b/libc/src/fcntl.cpp index 02314909..1c869596 100644 --- a/libc/src/fcntl.cpp +++ b/libc/src/fcntl.cpp @@ -19,9 +19,22 @@ extern "C" __errno_return(rc, int); } + int openat(int dirfd, const char* path, int flags, ...) + { + va_list ap; + va_start(ap, flags); + + mode_t mode = (mode_t)va_arg(ap, int); + + long rc = syscall(SYS_openat, dirfd, path, flags, mode); + + va_end(ap); + __errno_return(rc, int); + } + int creat(const char* path, mode_t mode) { - return open(path, O_WRONLY | O_CREAT | O_TRUNC, mode); + return openat(AT_FDCWD, path, O_WRONLY | O_CREAT | O_TRUNC, mode); } int fcntl(int fd, int cmd, ...) diff --git a/libc/src/unistd.cpp b/libc/src/unistd.cpp index bd836555..e6764b3a 100644 --- a/libc/src/unistd.cpp +++ b/libc/src/unistd.cpp @@ -370,14 +370,18 @@ extern "C" int unlink(const char* path) { - long rc = syscall(SYS_unlinkat, AT_FDCWD, path, 0); + return unlinkat(AT_FDCWD, path, 0); + } + + int unlinkat(int dirfd, const char* path, int flags) + { + long rc = syscall(SYS_unlinkat, dirfd, path, flags); __errno_return(rc, int); } int rmdir(const char* path) { - long rc = syscall(SYS_unlinkat, AT_FDCWD, path, AT_REMOVEDIR); - __errno_return(rc, int); + return unlinkat(AT_FDCWD, path, AT_REMOVEDIR); } int gethostname(char* buf, size_t len)