diff --git a/libc/include/sys/stat.h b/libc/include/sys/stat.h index a074401d..03e139be 100644 --- a/libc/include/sys/stat.h +++ b/libc/include/sys/stat.h @@ -18,6 +18,9 @@ extern "C" /* Change the mode bits of a file. */ int chmod(const char* path, mode_t mode); + /* Change the mode bits of a file descriptor. */ + int fchmod(int fd, mode_t mode); + #pragma GCC push_options #pragma GCC diagnostic ignored "-Wshadow" diff --git a/libc/include/unistd.h b/libc/include/unistd.h index e1045d96..ce7c5ec3 100644 --- a/libc/include/unistd.h +++ b/libc/include/unistd.h @@ -14,6 +14,9 @@ #define STDOUT_FILENO 1 #define STDERR_FILENO 2 +#define _POSIX_CHOWN_RESTRICTED 200112L +#define _POSIX_SHELL 200112L + #ifdef __cplusplus extern "C" { @@ -55,6 +58,9 @@ extern "C" /* Change the owner and group of a file. */ int chown(const char* path, uid_t uid, gid_t gid); + /* Change the owner and group of a file descriptor. */ + int fchown(int fd, uid_t uid, gid_t gid); + /* Replace the current process with another one. On success, does not return. */ int execv(const char* path, char* const* argv); diff --git a/libc/src/sys/stat.cpp b/libc/src/sys/stat.cpp index 06ddfecc..7a02a22d 100644 --- a/libc/src/sys/stat.cpp +++ b/libc/src/sys/stat.cpp @@ -18,6 +18,12 @@ extern "C" __errno_return(rc, int); } + int fchmod(int fd, mode_t mode) + { + long rc = syscall(SYS_fchmodat, fd, "", mode, AT_EMPTY_PATH); + __errno_return(rc, int); + } + int stat(const char* path, struct stat* st) { long rc = syscall(SYS_fstatat, AT_FDCWD, path, st, 0); diff --git a/libc/src/unistd.cpp b/libc/src/unistd.cpp index 6fc7dce7..42c7296e 100644 --- a/libc/src/unistd.cpp +++ b/libc/src/unistd.cpp @@ -148,6 +148,12 @@ extern "C" __errno_return(rc, int); } + int fchown(int fd, uid_t uid, gid_t gid) + { + long rc = syscall(SYS_fchownat, fd, "", uid, gid, AT_EMPTY_PATH); + __errno_return(rc, int); + } + int execv(const char* path, char* const* argv) { return execve(path, argv, environ);