Implement the AT_SYMLINK_NOFOLLOW flag to fchmodat() by calling open at fchmod emulating lchmod()
This commit is contained in:
@@ -146,6 +146,12 @@ faccessat(int fd, const char* path, int accessMode, int flag)
|
|||||||
int
|
int
|
||||||
fchmodat(int fd, const char* path, mode_t mode, int flag)
|
fchmodat(int fd, const char* path, mode_t mode, int flag)
|
||||||
{
|
{
|
||||||
|
if ((flag & AT_SYMLINK_NOFOLLOW) == 0 && flag != 0) {
|
||||||
|
// invalid flag
|
||||||
|
errno = EINVAL;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
if ((flag & AT_SYMLINK_NOFOLLOW) != 0) {
|
if ((flag & AT_SYMLINK_NOFOLLOW) != 0) {
|
||||||
// do not dereference, instead return information about the link
|
// do not dereference, instead return information about the link
|
||||||
// itself
|
// itself
|
||||||
@@ -180,7 +186,16 @@ fchmodat(int fd, const char* path, mode_t mode, int flag)
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int status = chmod(fullPath, mode);
|
int status;
|
||||||
|
|
||||||
|
if ((flag & AT_SYMLINK_NOFOLLOW) != 0) {
|
||||||
|
// Since there is no lchmod(), fake it with open() and fchmod()
|
||||||
|
int fullfd = open(fullPath, O_RDONLY | O_SYMLINK);
|
||||||
|
status = fchmod(fullfd, mode);
|
||||||
|
close(fullfd);
|
||||||
|
} else
|
||||||
|
status = chmod(fullPath, mode);
|
||||||
|
|
||||||
free(fullPath);
|
free(fullPath);
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
@@ -499,6 +514,12 @@ symlinkat(const char *oldPath, int fd, const char *newPath)
|
|||||||
int
|
int
|
||||||
unlinkat(int fd, const char *path, int flag)
|
unlinkat(int fd, const char *path, int flag)
|
||||||
{
|
{
|
||||||
|
if ((flag & AT_REMOVEDIR) == 0 && flag != 0) {
|
||||||
|
// invalid flag
|
||||||
|
errno = EINVAL;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
if (fd == AT_FDCWD || path != NULL && path[0] == '/') {
|
if (fd == AT_FDCWD || path != NULL && path[0] == '/') {
|
||||||
// call rmdir() or unlink() ignoring fd
|
// call rmdir() or unlink() ignoring fd
|
||||||
return (flag & AT_REMOVEDIR) != 0 ? rmdir(path) : unlink(path);
|
return (flag & AT_REMOVEDIR) != 0 ? rmdir(path) : unlink(path);
|
||||||
|
|||||||
Reference in New Issue
Block a user