1
0
Fork 0
mirror of https://gitlab.com/sortix/sortix.git synced 2023-02-13 20:55:38 -05:00

Implement AT_SYMLINK_FOLLOW and AT_SYMLINK_NOFOLLOW.

This commit is contained in:
Jonas 'Sortie' Termansen 2013-11-16 13:21:44 +01:00
parent 2311d634ac
commit eb831479fb

View file

@ -186,8 +186,8 @@ static int sys_open(const char* path, int flags, mode_t mode)
// TODO: This is a hack! Stat the file in some manner and check permissions. // TODO: This is a hack! Stat the file in some manner and check permissions.
static int sys_faccessat(int dirfd, const char* path, int /*mode*/, int flags) static int sys_faccessat(int dirfd, const char* path, int /*mode*/, int flags)
{ {
if ( flags ) if ( flags & (AT_SYMLINK_NOFOLLOW) )
return errno = ENOSYS, -1; return errno = EINVAL, -1;
char* pathcopy = GetStringFromUser(path); char* pathcopy = GetStringFromUser(path);
if ( !pathcopy ) if ( !pathcopy )
return -1; return -1;
@ -195,7 +195,8 @@ static int sys_faccessat(int dirfd, const char* path, int /*mode*/, int flags)
const char* relpath = pathcopy; const char* relpath = pathcopy;
Ref<Descriptor> from = PrepareLookup(&relpath, dirfd); Ref<Descriptor> from = PrepareLookup(&relpath, dirfd);
if ( !from ) { delete[] pathcopy; return -1; } if ( !from ) { delete[] pathcopy; return -1; }
Ref<Descriptor> desc = from->open(&ctx, relpath, O_READ); int open_flags = O_READ | (flags & AT_SYMLINK_NOFOLLOW ? O_SYMLINK_NOFOLLOW : 0);
Ref<Descriptor> desc = from->open(&ctx, relpath, open_flags);
delete[] pathcopy; delete[] pathcopy;
return desc ? 0 : -1; return desc ? 0 : -1;
} }
@ -289,8 +290,10 @@ static int sys_ftruncate(int fd, off_t length)
return desc->truncate(&ctx, length); return desc->truncate(&ctx, length);
} }
static int sys_fstatat(int dirfd, const char* path, struct stat* st, int /*flags*/) static int sys_fstatat(int dirfd, const char* path, struct stat* st, int flags)
{ {
if ( flags & ~(AT_SYMLINK_NOFOLLOW) )
return errno = EINVAL;
char* pathcopy = GetStringFromUser(path); char* pathcopy = GetStringFromUser(path);
if ( !pathcopy ) if ( !pathcopy )
return -1; return -1;
@ -298,7 +301,8 @@ static int sys_fstatat(int dirfd, const char* path, struct stat* st, int /*flags
const char* relpath = pathcopy; const char* relpath = pathcopy;
Ref<Descriptor> from = PrepareLookup(&relpath, dirfd); Ref<Descriptor> from = PrepareLookup(&relpath, dirfd);
if ( !from ) { delete[] pathcopy; return -1; } if ( !from ) { delete[] pathcopy; return -1; }
Ref<Descriptor> desc = from->open(&ctx, relpath, O_READ); int open_flags = O_READ | (flags & AT_SYMLINK_NOFOLLOW ? O_SYMLINK_NOFOLLOW : 0);
Ref<Descriptor> desc = from->open(&ctx, relpath, open_flags);
delete[] pathcopy; delete[] pathcopy;
if ( !desc ) if ( !desc )
return -1; return -1;
@ -451,8 +455,8 @@ static int sys_fchown(int fd, uid_t owner, gid_t group)
static int sys_fchownat(int dirfd, const char* path, uid_t owner, gid_t group, int flags) static int sys_fchownat(int dirfd, const char* path, uid_t owner, gid_t group, int flags)
{ {
if ( flags ) if ( flags & ~(AT_SYMLINK_NOFOLLOW) )
return errno = ENOTSUP, -1; return errno = EINVAL, -1;
char* pathcopy = GetStringFromUser(path); char* pathcopy = GetStringFromUser(path);
if ( !pathcopy ) if ( !pathcopy )
return -1; return -1;
@ -460,7 +464,8 @@ static int sys_fchownat(int dirfd, const char* path, uid_t owner, gid_t group, i
const char* relpath = pathcopy; const char* relpath = pathcopy;
Ref<Descriptor> from = PrepareLookup(&relpath, dirfd); Ref<Descriptor> from = PrepareLookup(&relpath, dirfd);
if ( !from ) { delete[] pathcopy; return -1; } if ( !from ) { delete[] pathcopy; return -1; }
Ref<Descriptor> desc = from->open(&ctx, relpath, O_WRITE); int open_flags = O_WRITE | (flags & AT_SYMLINK_NOFOLLOW ? O_SYMLINK_NOFOLLOW : 0);
Ref<Descriptor> desc = from->open(&ctx, relpath, open_flags);
from.Reset(); from.Reset();
delete[] pathcopy; delete[] pathcopy;
if ( !desc ) if ( !desc )
@ -485,8 +490,8 @@ static int sys_fchmod(int fd, mode_t mode)
static int sys_fchmodat(int dirfd, const char* path, mode_t mode, int flags) static int sys_fchmodat(int dirfd, const char* path, mode_t mode, int flags)
{ {
if ( flags ) if ( flags & ~(AT_SYMLINK_NOFOLLOW) )
return errno = ENOTSUP, -1; return errno = EINVAL, -1;
char* pathcopy = GetStringFromUser(path); char* pathcopy = GetStringFromUser(path);
if ( !pathcopy ) if ( !pathcopy )
return -1; return -1;
@ -494,7 +499,8 @@ static int sys_fchmodat(int dirfd, const char* path, mode_t mode, int flags)
const char* relpath = pathcopy; const char* relpath = pathcopy;
Ref<Descriptor> from = PrepareLookup(&relpath, dirfd); Ref<Descriptor> from = PrepareLookup(&relpath, dirfd);
if ( !from ) { delete[] pathcopy; return -1; } if ( !from ) { delete[] pathcopy; return -1; }
Ref<Descriptor> desc = from->open(&ctx, relpath, O_WRITE); int open_flags = O_WRITE | (flags & AT_SYMLINK_NOFOLLOW ? O_SYMLINK_NOFOLLOW : 0);
Ref<Descriptor> desc = from->open(&ctx, relpath, open_flags);
from.Reset(); from.Reset();
delete[] pathcopy; delete[] pathcopy;
if ( !desc ) if ( !desc )
@ -523,8 +529,8 @@ static int sys_futimens(int fd, const struct timespec user_times[2])
static int sys_utimensat(int dirfd, const char* path, static int sys_utimensat(int dirfd, const char* path,
const struct timespec user_times[2], int flags) const struct timespec user_times[2], int flags)
{ {
if ( flags ) if ( flags & ~(AT_SYMLINK_NOFOLLOW) )
return errno = ENOTSUP, -1; return errno = EINVAL, -1;
struct timespec times[2]; struct timespec times[2];
if ( !CopyFromUser(times, user_times, sizeof(times)) ) if ( !CopyFromUser(times, user_times, sizeof(times)) )
return -1; return -1;
@ -535,7 +541,8 @@ static int sys_utimensat(int dirfd, const char* path,
const char* relpath = pathcopy; const char* relpath = pathcopy;
Ref<Descriptor> from = PrepareLookup(&relpath, dirfd); Ref<Descriptor> from = PrepareLookup(&relpath, dirfd);
if ( !from ) { delete[] pathcopy; return -1; } if ( !from ) { delete[] pathcopy; return -1; }
Ref<Descriptor> desc = from->open(&ctx, relpath, O_WRITE); int open_flags = O_WRITE | (flags & AT_SYMLINK_NOFOLLOW ? O_SYMLINK_NOFOLLOW : 0);
Ref<Descriptor> desc = from->open(&ctx, relpath, open_flags);
from.Reset(); from.Reset();
delete[] pathcopy; delete[] pathcopy;
if ( !desc ) if ( !desc )
@ -547,8 +554,8 @@ static int sys_linkat(int olddirfd, const char* oldpath,
int newdirfd, const char* newpath, int newdirfd, const char* newpath,
int flags) int flags)
{ {
if ( flags ) if ( flags & ~(AT_SYMLINK_FOLLOW) )
return errno = ENOTSUP, -1; return errno = EINVAL, -1;
ioctx_t ctx; SetupUserIOCtx(&ctx); ioctx_t ctx; SetupUserIOCtx(&ctx);
@ -572,7 +579,8 @@ static int sys_linkat(int olddirfd, const char* oldpath,
Ref<Descriptor> oldfrom = PrepareLookup(&oldrelpath, olddirfd); Ref<Descriptor> oldfrom = PrepareLookup(&oldrelpath, olddirfd);
if ( !oldfrom ) { delete[] oldpathcopy; delete[] final_elem; return -1; } if ( !oldfrom ) { delete[] oldpathcopy; delete[] final_elem; return -1; }
Ref<Descriptor> file = oldfrom->open(&ctx, oldrelpath, O_READ); int open_flags = O_READ | (flags & AT_SYMLINK_FOLLOW ? 0 : O_SYMLINK_NOFOLLOW);
Ref<Descriptor> file = oldfrom->open(&ctx, oldrelpath, open_flags);
delete[] oldpathcopy; delete[] oldpathcopy;
if ( !file ) { delete[] final_elem; return -1; } if ( !file ) { delete[] final_elem; return -1; }