From 486fffdaaf7f16e65bea9f4fde7d5d3c3726ece8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Axel=20D=C3=B6rfler?= Date: Thu, 26 Nov 2009 16:30:16 +0000 Subject: [PATCH] * Forgot to add linkat(), this really closes #4928 now. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@34289 a95241bf-73f2-0310-859d-f6bbb57e9c96 --- headers/posix/unistd.h | 4 +++- headers/private/kernel/vfs.h | 3 ++- headers/private/system/syscalls.h | 3 ++- src/system/kernel/fs/vfs.cpp | 22 ++++++++++++++-------- src/system/libroot/posix/unistd/link.c | 12 +++++++++--- 5 files changed, 30 insertions(+), 14 deletions(-) diff --git a/headers/posix/unistd.h b/headers/posix/unistd.h index 67d64260f5..bab15c1b96 100644 --- a/headers/posix/unistd.h +++ b/headers/posix/unistd.h @@ -134,7 +134,9 @@ extern int pipe(int fildes[2]); extern int dup(int fd); extern int dup2(int fd1, int fd2); extern int close(int fd); -extern int link(const char *name, const char *new_name); +extern int link(const char *toPath, const char *path); +extern int linkat(int toFD, const char *toPath, int pathFD, + const char *path, int flag); extern int unlink(const char *name); extern int unlinkat(int fd, const char *path, int flag); extern int rmdir(const char *path); diff --git a/headers/private/kernel/vfs.h b/headers/private/kernel/vfs.h index 446165004d..93c3a29c95 100644 --- a/headers/private/kernel/vfs.h +++ b/headers/private/kernel/vfs.h @@ -190,7 +190,8 @@ status_t _user_read_link(int fd, const char *path, char *buffer, status_t _user_write_link(const char *path, const char *toPath); status_t _user_create_symlink(int fd, const char *path, const char *toPath, int mode); -status_t _user_create_link(const char *path, const char *toPath); +status_t _user_create_link(int pathFD, const char *path, int toFD, + const char *toPath, bool traverseLeafLink); status_t _user_unlink(int fd, const char *path); status_t _user_rename(int oldFD, const char *oldpath, int newFD, const char *newpath); diff --git a/headers/private/system/syscalls.h b/headers/private/system/syscalls.h index 7f708b85f3..f2e19581d8 100644 --- a/headers/private/system/syscalls.h +++ b/headers/private/system/syscalls.h @@ -239,7 +239,8 @@ extern status_t _kern_read_link(int fd, const char *path, char *buffer, size_t *_bufferSize); extern status_t _kern_create_symlink(int fd, const char *path, const char *toPath, int mode); -extern status_t _kern_create_link(const char *path, const char *toPath); +extern status_t _kern_create_link(int pathFD, const char *path, int toFD, + const char *toPath, bool traverseLeafLink); extern status_t _kern_unlink(int fd, const char *path); extern status_t _kern_rename(int oldDir, const char *oldpath, int newDir, const char *newpath); diff --git a/src/system/kernel/fs/vfs.cpp b/src/system/kernel/fs/vfs.cpp index 83925da2dd..2197b45d33 100644 --- a/src/system/kernel/fs/vfs.cpp +++ b/src/system/kernel/fs/vfs.cpp @@ -5995,7 +5995,8 @@ common_create_symlink(int fd, char* path, const char* toPath, int mode, static status_t -common_create_link(char* path, char* toPath, bool kernel) +common_create_link(int pathFD, char* path, int toFD, char* toPath, + bool traverseLeafLink, bool kernel) { // path validity checks have to be in the calling function! @@ -6004,12 +6005,14 @@ common_create_link(char* path, char* toPath, bool kernel) char name[B_FILE_NAME_LENGTH]; struct vnode* directory; - status_t status = path_to_dir_vnode(path, &directory, name, kernel); + status_t status = fd_and_path_to_dir_vnode(pathFD, path, &directory, name, + kernel); if (status != B_OK) return status; struct vnode* vnode; - status = path_to_vnode(toPath, true, &vnode, NULL, kernel); + status = fd_and_path_to_vnode(toFD, toPath, traverseLeafLink, &vnode, NULL, + kernel); if (status != B_OK) goto err; @@ -7992,15 +7995,16 @@ _kern_create_symlink(int fd, const char* path, const char* toPath, int mode) status_t -_kern_create_link(const char* path, const char* toPath) +_kern_create_link(int pathFD, const char* path, int toFD, const char* toPath, + bool traverseLeafLink) { KPath pathBuffer(path, false, B_PATH_NAME_LENGTH + 1); KPath toPathBuffer(toPath, false, B_PATH_NAME_LENGTH + 1); if (pathBuffer.InitCheck() != B_OK || toPathBuffer.InitCheck() != B_OK) return B_NO_MEMORY; - return common_create_link(pathBuffer.LockBuffer(), - toPathBuffer.LockBuffer(), true); + return common_create_link(pathFD, pathBuffer.LockBuffer(), toFD, + toPathBuffer.LockBuffer(), traverseLeafLink, true); } @@ -8869,7 +8873,8 @@ _user_create_symlink(int fd, const char* userPath, const char* userToPath, status_t -_user_create_link(const char* userPath, const char* userToPath) +_user_create_link(int pathFD, const char* userPath, int toFD, + const char* userToPath, bool traverseLeafLink) { KPath pathBuffer(B_PATH_NAME_LENGTH + 1); KPath toPathBuffer(B_PATH_NAME_LENGTH + 1); @@ -8889,7 +8894,8 @@ _user_create_link(const char* userPath, const char* userToPath) if (status != B_OK) return status; - return common_create_link(path, toPath, false); + return common_create_link(pathFD, path, toFD, toPath, traverseLeafLink, + false); } diff --git a/src/system/libroot/posix/unistd/link.c b/src/system/libroot/posix/unistd/link.c index 2a04c7c74f..0363703a31 100644 --- a/src/system/libroot/posix/unistd/link.c +++ b/src/system/libroot/posix/unistd/link.c @@ -75,8 +75,14 @@ unlinkat(int fd, const char *path, int flag) int link(const char *toPath, const char *linkPath) { - int status = _kern_create_link(linkPath, toPath); - - RETURN_AND_SET_ERRNO(status); + RETURN_AND_SET_ERRNO(_kern_create_link(-1, linkPath, -1, toPath, true)); +} + + +int +linkat(int toFD, const char *toPath, int linkFD, const char *linkPath, int flag) +{ + RETURN_AND_SET_ERRNO(_kern_create_link(linkFD, linkPath, toFD, toPath, + (flag & AT_SYMLINK_FOLLOW) != 0)); }