diff --git a/kernel/include/sortix/kernel/syscall.h b/kernel/include/sortix/kernel/syscall.h index e4ab72e6..ebe2696e 100644 --- a/kernel/include/sortix/kernel/syscall.h +++ b/kernel/include/sortix/kernel/syscall.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, 2012, 2013, 2014, 2015 Jonas 'Sortie' Termansen. + * Copyright (c) 2011, 2012, 2013, 2014, 2015, 2016 Jonas 'Sortie' Termansen. * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -46,6 +46,9 @@ namespace Sortix { +#if defined(__i386__) +struct fchownat_request; +#endif struct mmap_request; int sys_accept4(int, void*, size_t*, int); @@ -71,6 +74,9 @@ int sys_fchmod(int, mode_t); int sys_fchmodat(int, const char*, mode_t, int); int sys_fchown(int, uid_t, gid_t); int sys_fchownat(int, const char*, uid_t, gid_t, int); +#if defined(__i386__) +int sys_fchownat_wrapper(const struct fchownat_request*); +#endif int sys_fchroot(int); int sys_fchrootat(int, const char*); int sys_fcntl(int, int, uintptr_t); diff --git a/kernel/io.cpp b/kernel/io.cpp index 96d0a35c..b8fe2d9a 100644 --- a/kernel/io.cpp +++ b/kernel/io.cpp @@ -472,6 +472,26 @@ int sys_fchownat(int dirfd, const char* path, uid_t owner, gid_t group, int flag return desc->chown(&ctx, owner, group); } +#if defined(__i386__) +struct fchownat_request /* duplicated in libc/unistd/fchownat.c */ +{ + int dirfd; + const char* path; + uid_t owner; + gid_t group; + int flags; +}; + +int sys_fchownat_wrapper(const struct fchownat_request* user_request) +{ + struct fchownat_request request; + if ( !CopyFromUser(&request, user_request, sizeof(request)) ) + return -1; + return sys_fchownat(request.dirfd, request.path, request.owner, + request.group, request.flags); +} +#endif + int sys_fchmod(int fd, mode_t mode) { Ref desc = CurrentProcess()->GetDescriptor(fd); diff --git a/kernel/syscall.cpp b/kernel/syscall.cpp index 4e5dee31..4d5abdb7 100644 --- a/kernel/syscall.cpp +++ b/kernel/syscall.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, 2012, 2013, 2014, 2015 Jonas 'Sortie' Termansen. + * Copyright (c) 2011, 2012, 2013, 2014, 2015, 2016 Jonas 'Sortie' Termansen. * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -96,7 +96,11 @@ void* syscall_list[SYSCALL_MAX_NUM + 1] = [SYSCALL_MKDIRAT] = (void*) sys_mkdirat, [SYSCALL_FCHDIR] = (void*) sys_fchdir, [SYSCALL_TRUNCATEAT] = (void*) sys_truncateat, +#if !defined(__i386__) [SYSCALL_FCHOWNAT] = (void*) sys_fchownat, +#else + [SYSCALL_FCHOWNAT] = (void*) sys_fchownat_wrapper, +#endif [SYSCALL_FCHOWN] = (void*) sys_fchown, [SYSCALL_FCHMOD] = (void*) sys_fchmod, [SYSCALL_FCHMODAT] = (void*) sys_fchmodat, diff --git a/libc/unistd/fchownat.c b/libc/unistd/fchownat.c index e84e719d..a2d290bc 100644 --- a/libc/unistd/fchownat.c +++ b/libc/unistd/fchownat.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012 Jonas 'Sortie' Termansen. + * Copyright (c) 2012, 2016 Jonas 'Sortie' Termansen. * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -23,9 +23,35 @@ #include #include +#if !defined(__i386__) + DEFN_SYSCALL5(int, sys_fchownat, SYSCALL_FCHOWNAT, int, const char*, uid_t, gid_t, int); int fchownat(int dirfd, const char* path, uid_t owner, gid_t group, int flags) { return sys_fchownat(dirfd, path, owner, group, flags); } + +#else + +// TODO: The i386 system call ABI doesn't have enough registers to do this with +// 64-bit uid_t and gid_t. + +struct fchownat_request /* duplicated in kernel/io.cpp */ +{ + int dirfd; + const char* path; + uid_t owner; + gid_t group; + int flags; +}; + +DEFN_SYSCALL1(int, sys_fchownat_wrapper, SYSCALL_FCHOWNAT, const struct fchownat_request*); + +int fchownat(int dirfd, const char* path, uid_t owner, gid_t group, int flags) +{ + struct fchownat_request request = { dirfd, path, owner, group, flags }; + return sys_fchownat_wrapper(&request); +} + +#endif