diff options
author | Ulrich Drepper <drepper@redhat.com> | 2006-09-25 15:33:09 +0000 |
---|---|---|
committer | Ulrich Drepper <drepper@redhat.com> | 2006-09-25 15:33:09 +0000 |
commit | f1122ec3ae47bbf40e38bec56d879502005397b1 (patch) | |
tree | 8ac3b9d7a104815f0f3ff1b6b796827823f2ac90 /sysdeps/unix/sysv/linux/i386/fchownat.c | |
parent | 457b559e2ec7bd66c6da9e99d27f0d1723da4874 (diff) | |
download | glibc-f1122ec3ae47bbf40e38bec56d879502005397b1.tar.gz glibc-f1122ec3ae47bbf40e38bec56d879502005397b1.tar.xz glibc-f1122ec3ae47bbf40e38bec56d879502005397b1.zip |
[BZ #3252, BZ #3253] cvs/fedora-glibc-20060925T1535
2006-09-25 Jakub Jelinek <jakub@redhat.com> [BZ #3252] * sysdeps/unix/sysv/linux/powerpc/fchownat.c (fchownat): Handle only fchownat syscall and __ASSUME_LCHOWN_SYSCALL case inline, call __{,l}chown to handle the rest. * sysdeps/unix/sysv/linux/i386/fchownat.c (fchownat): Handle only fchownat syscall and __ASSUME_32BITUIDS case inline, call __{,l}chown to handle the rest. * sysdeps/unix/sysv/linux/sparc/sparc32/fchownat.c: Include i386/fchownat.c. * sysdeps/unix/sysv/linux/s390/s390-32/fchownat.c: Likewise. * sysdeps/unix/sysv/linux/sh/fchownat.c: Likewise. [BZ #3253] * posix/glob.c (glob_in_dir): Don't alloca one struct globlink at a time, rather allocate increasingly bigger arrays of pointers, if possible with alloca, if too large with malloc. 2006-09-24 Jakub Jelinek <jakub@redhat.com> * sysdeps/powerpc/fpu/libm-test-ulps: Updated. * sysdeps/ieee754/ldbl-128/s_lrintl.c (__lrintl): Fix 2 typos.
Diffstat (limited to 'sysdeps/unix/sysv/linux/i386/fchownat.c')
-rw-r--r-- | sysdeps/unix/sysv/linux/i386/fchownat.c | 120 |
1 files changed, 17 insertions, 103 deletions
diff --git a/sysdeps/unix/sysv/linux/i386/fchownat.c b/sysdeps/unix/sysv/linux/i386/fchownat.c index db5481705a..34acf10c27 100644 --- a/sysdeps/unix/sysv/linux/i386/fchownat.c +++ b/sysdeps/unix/sysv/linux/i386/fchownat.c @@ -30,33 +30,6 @@ #include <linux/posix_types.h> #include <kernel-features.h> -/* - In Linux 2.1.x the chown functions have been changed. A new function lchown - was introduced. The new chown now follows symlinks - the old chown and the - new lchown do not follow symlinks. - The new lchown function has the same number as the old chown had and the - new chown has a new number. When compiling with headers from Linux > 2.1.8x - it's impossible to run this libc with older kernels. In these cases libc - has therefore to route calls to chown to the old chown function. -*/ - -extern int __chown_is_lchown (const char *__file, uid_t __owner, - gid_t __group); -extern int __real_chown (const char *__file, uid_t __owner, gid_t __group); - - -#if defined __NR_lchown || __ASSUME_LCHOWN_SYSCALL > 0 -/* Running under Linux > 2.1.80. */ - -# ifdef __NR_chown32 -# if __ASSUME_32BITUIDS == 0 -/* This variable is shared with all files that need to check for 32bit - uids. */ -extern int __libc_missing_32bit_uids; -# endif -# endif /* __NR_chown32 */ -#endif - int fchownat (int fd, const char *file, uid_t owner, gid_t group, int flag) @@ -105,92 +78,33 @@ fchownat (int fd, const char *file, uid_t owner, gid_t group, int flag) file = buf; } +# if __ASSUME_32BITUIDS > 0 + /* This implies __ASSUME_LCHOWN_SYSCALL. */ INTERNAL_SYSCALL_DECL (err); -# if defined __NR_lchown || __ASSUME_LCHOWN_SYSCALL > 0 -# if __ASSUME_LCHOWN_SYSCALL == 0 - static int __libc_old_chown; - -# ifdef __NR_chown32 - if (__libc_missing_32bit_uids <= 0) - { - if (flag & AT_SYMLINK_NOFOLLOW) - result = INTERNAL_SYSCALL (lchown32, err, 3, CHECK_STRING (file), - owner, group); - else - result = INTERNAL_SYSCALL (chown32, err, 3, CHECK_STRING (file), - owner, group); - - if (!INTERNAL_SYSCALL_ERROR_P (result, err)) - return result; - if (INTERNAL_SYSCALL_ERRNO (result, err) != ENOSYS) - goto fail; - - __libc_missing_32bit_uids = 1; - } -# endif /* __NR_chown32 */ - - if (((owner + 1) > (uid_t) ((__kernel_uid_t) -1U)) - || ((group + 1) > (gid_t) ((__kernel_gid_t) -1U))) - { - __set_errno (EINVAL); - return -1; - } + if (flag & AT_SYMLINK_NOFOLLOW) + result = INTERNAL_SYSCALL (lchown32, err, 3, CHECK_STRING (file), owner, + group); + else + result = INTERNAL_SYSCALL (chown32, err, 3, CHECK_STRING (file), owner, + group); - if (!__libc_old_chown && (flag & AT_SYMLINK_NOFOLLOW) == 0) - { - result = INTERNAL_SYSCALL (chown, err, 3, CHECK_STRING (file), owner, - group); - - if (!INTERNAL_SYSCALL_ERROR_P (result, err)) - return result; - if (INTERNAL_SYSCALL_ERRNO (result, err) != ENOSYS) - goto fail; - - __libc_old_chown = 1; - } - - result = INTERNAL_SYSCALL (lchown, err, 3, CHECK_STRING (file), owner, - group); -# elif __ASSUME_32BITUIDS - /* This implies __ASSUME_LCHOWN_SYSCALL. */ - result = INTERNAL_SYSCALL (chown32, err, 3, CHECK_STRING (file), owner, - group); -# else - /* !__ASSUME_32BITUIDS && ASSUME_LCHOWN_SYSCALL */ -# ifdef __NR_chown32 - if (__libc_missing_32bit_uids <= 0) - { - result = INTERNAL_SYSCALL (chown32, err, 3, CHECK_STRING (file), owner, - group); - if (__builtin_expect (!INTERNAL_SYSCALL_ERROR_P (result, err), 1)) - return result; - if (INTERNAL_SYSCALL_ERRNO (result, err) != ENOSYS) - goto fail; - - __libc_missing_32bit_uids = 1; - } -# endif /* __NR_chown32 */ - if (((owner + 1) > (uid_t) ((__kernel_uid_t) -1U)) - || ((group + 1) > (gid_t) ((__kernel_gid_t) -1U))) + if (__builtin_expect (INTERNAL_SYSCALL_ERROR_P (result, err), 0)) { - __set_errno (EINVAL); + __atfct_seterrno (INTERNAL_SYSCALL_ERRNO (result, err), fd, buf); return -1; } - - result = INTERNAL_SYSCALL (chown, err, 3, CHECK_STRING (file), owner, group); -# endif # else - result = INTERNAL_SYSCALL (chown, err, 3, CHECK_STRING (file), owner, group); + /* Don't inline the rest to avoid unnecessary code duplication. */ + if (flag & AT_SYMLINK_NOFOLLOW) + result = __lchown (file, owner, group); + else + result = __chown (file, owner, group); + if (result < 0) + __atfct_seterrno (errno, fd, buf); # endif - if (__builtin_expect (INTERNAL_SYSCALL_ERROR_P (result, err), 0)) - goto fail; - return result; - fail: - __atfct_seterrno (INTERNAL_SYSCALL_ERRNO (result, err), fd, buf); - return -1; #endif } |