diff --git a/libc/include/sys/stat.h b/libc/include/sys/stat.h index 03e139be..b8b3d192 100644 --- a/libc/include/sys/stat.h +++ b/libc/include/sys/stat.h @@ -29,6 +29,9 @@ extern "C" #pragma GCC pop_options + /* Retrieve information about a file or symbolic link. */ + int lstat(const char* path, struct stat* st); + /* Retrieve information about a file. */ int fstat(int fd, struct stat* st); diff --git a/libc/include/unistd.h b/libc/include/unistd.h index ce7c5ec3..d01aecec 100644 --- a/libc/include/unistd.h +++ b/libc/include/unistd.h @@ -133,6 +133,12 @@ extern "C" /* Create a pipe for inter-process communication. */ int pipe(int pfds[2]); + /* Create a symbolic link. */ + int symlink(const char* target, const char* linkpath); + + /* Create a symbolic link relative to a file descriptor. */ + int symlinkat(const char* target, int dirfd, const char* linkpath); + #ifdef __cplusplus } #endif diff --git a/libc/src/sys/stat.cpp b/libc/src/sys/stat.cpp index 7a02a22d..d4ffa1e8 100644 --- a/libc/src/sys/stat.cpp +++ b/libc/src/sys/stat.cpp @@ -30,6 +30,12 @@ extern "C" __errno_return(rc, int); } + int lstat(const char* path, struct stat* st) + { + long rc = syscall(SYS_fstatat, AT_FDCWD, path, st, AT_SYMLINK_NOFOLLOW); + __errno_return(rc, int); + } + int fstat(int fd, struct stat* st) { long rc = syscall(SYS_fstatat, fd, "", st, AT_EMPTY_PATH); diff --git a/libc/src/unistd.cpp b/libc/src/unistd.cpp index bfe870a3..3758ef1d 100644 --- a/libc/src/unistd.cpp +++ b/libc/src/unistd.cpp @@ -406,4 +406,16 @@ extern "C" long rc = syscall(SYS_pipe, (int*)pfds); __errno_return(rc, int); } + + int symlink(const char* target, const char* linkpath) + { + long rc = syscall(SYS_symlinkat, target, AT_FDCWD, linkpath); + __errno_return(rc, int); + } + + int symlinkat(const char* target, int dirfd, const char* linkpath) + { + long rc = syscall(SYS_symlinkat, target, dirfd, linkpath); + __errno_return(rc, int); + } }