From f1122ec3ae47bbf40e38bec56d879502005397b1 Mon Sep 17 00:00:00 2001 From: Ulrich Drepper Date: Mon, 25 Sep 2006 15:33:09 +0000 Subject: [PATCH] [BZ #3252, BZ #3253] 2006-09-25 Jakub Jelinek [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 * sysdeps/powerpc/fpu/libm-test-ulps: Updated. * sysdeps/ieee754/ldbl-128/s_lrintl.c (__lrintl): Fix 2 typos. --- ChangeLog | 25 +++ posix/glob.c | 142 ++++++++++------ sysdeps/ieee754/ldbl-128/s_lrintl.c | 4 +- sysdeps/powerpc/fpu/libm-test-ulps | 16 +- sysdeps/unix/sysv/linux/i386/fchownat.c | 128 +++----------- sysdeps/unix/sysv/linux/powerpc/fchownat.c | 139 ++------------- .../unix/sysv/linux/s390/s390-32/fchownat.c | 160 +----------------- sysdeps/unix/sysv/linux/sh/fchownat.c | 141 +-------------- .../unix/sysv/linux/sparc/sparc32/fchownat.c | 2 +- 9 files changed, 164 insertions(+), 593 deletions(-) diff --git a/ChangeLog b/ChangeLog index a100d235a7..beb014377b 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,28 @@ +2006-09-25 Jakub Jelinek + + [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 + + * sysdeps/powerpc/fpu/libm-test-ulps: Updated. + + * sysdeps/ieee754/ldbl-128/s_lrintl.c (__lrintl): Fix 2 typos. + 2006-09-24 Ulrich Drepper * sysdeps/posix/getaddrinfo.c (rfc3484_sort): Implement rule 4, diff --git a/posix/glob.c b/posix/glob.c index d2a9981e31..630d54063a 100644 --- a/posix/glob.c +++ b/posix/glob.c @@ -1090,16 +1090,25 @@ glob_in_dir (const char *pattern, const char *directory, int flags, { size_t dirlen = strlen (directory); void *stream = NULL; - struct globlink + struct globnames { - struct globlink *next; - char *name; + struct globnames *next; + size_t count; + char *name[64]; }; - struct globlink *names = NULL; - size_t nfound; +#define INITIAL_COUNT sizeof (init_names.name) / sizeof (init_names.name[0]) + struct globnames init_names; + struct globnames *names = &init_names; + struct globnames *names_alloca = &init_names; + size_t nfound = 0; + size_t allocasize = sizeof (init_names); + size_t cur = 0; int meta; int save; + init_names.next = NULL; + init_names.count = INITIAL_COUNT; + meta = __glob_pattern_p (pattern, !(flags & GLOB_NOESCAPE)); if (meta == 0 && (flags & (GLOB_NOCHECK|GLOB_NOMAGIC))) { @@ -1107,7 +1116,6 @@ glob_in_dir (const char *pattern, const char *directory, int flags, characters and we must not return an error therefore the result will always contain exactly one name. */ flags |= GLOB_NOCHECK; - nfound = 0; } else if (meta == 0 && ((flags & GLOB_NOESCAPE) || strchr (pattern, '\\') == NULL)) @@ -1128,8 +1136,6 @@ glob_in_dir (const char *pattern, const char *directory, int flags, /* We found this file to be existing. Now tell the rest of the function to copy this name into the result. */ flags |= GLOB_NOCHECK; - - nfound = 0; } else { @@ -1137,12 +1143,10 @@ glob_in_dir (const char *pattern, const char *directory, int flags, { /* This is a special case for matching directories like in "*a/". */ - names = (struct globlink *) __alloca (sizeof (struct globlink)); - names->name = (char *) malloc (1); - if (names->name == NULL) + names->name[cur] = (char *) malloc (1); + if (names->name[cur] == NULL) goto memory_error; - names->name[0] = '\0'; - names->next = NULL; + *names->name[cur++] = '\0'; nfound = 1; meta = 0; } @@ -1157,7 +1161,6 @@ glob_in_dir (const char *pattern, const char *directory, int flags, && ((errfunc != NULL && (*errfunc) (directory, errno)) || (flags & GLOB_ERR))) return GLOB_ABORTED; - nfound = 0; meta = 0; } else @@ -1168,7 +1171,6 @@ glob_in_dir (const char *pattern, const char *directory, int flags, | FNM_CASEFOLD #endif ); - nfound = 0; flags |= GLOB_MAGCHAR; while (1) @@ -1224,15 +1226,30 @@ glob_in_dir (const char *pattern, const char *directory, int flags, || link_exists_p (directory, dirlen, name, pglob, flags)) { - struct globlink *new = (struct globlink *) - __alloca (sizeof (struct globlink)); + if (cur == names->count) + { + struct globnames *newnames; + size_t count = names->count * 2; + size_t size = (sizeof (struct globnames) + + ((count - INITIAL_COUNT) + * sizeof (char *))); + allocasize += size; + if (__libc_use_alloca (allocasize)) + newnames = names_alloca = __alloca (size); + else if ((newnames = malloc (size)) + == NULL) + goto memory_error; + newnames->count = count; + newnames->next = names; + names = newnames; + cur = 0; + } len = NAMLEN (d); - new->name = (char *) malloc (len + 1); - if (new->name == NULL) + names->name[cur] = (char *) malloc (len + 1); + if (names->name[cur] == NULL) goto memory_error; - *((char *) mempcpy (new->name, name, len)) = '\0'; - new->next = names; - names = new; + *((char *) mempcpy (names->name[cur++], name, len)) + = '\0'; ++nfound; } } @@ -1245,59 +1262,76 @@ glob_in_dir (const char *pattern, const char *directory, int flags, { size_t len = strlen (pattern); nfound = 1; - names = (struct globlink *) __alloca (sizeof (struct globlink)); - names->next = NULL; - names->name = (char *) malloc (len + 1); - if (names->name == NULL) + names->name[cur] = (char *) malloc (len + 1); + if (names->name[cur] == NULL) goto memory_error; - *((char *) mempcpy (names->name, pattern, len)) = '\0'; + *((char *) mempcpy (names->name[cur++], pattern, len)) = '\0'; } + int result = GLOB_NOMATCH; if (nfound != 0) { - char **new_gl_pathv; + result = 0; + char **new_gl_pathv; new_gl_pathv = (char **) realloc (pglob->gl_pathv, (pglob->gl_pathc + pglob->gl_offs + nfound + 1) * sizeof (char *)); if (new_gl_pathv == NULL) - goto memory_error; - pglob->gl_pathv = new_gl_pathv; + { + memory_error: + while (1) + { + struct globnames *old = names; + for (size_t i = 0; i < cur; ++i) + free (names->name[i]); + names = names->next; + if (names == NULL) + break; + cur = names->count; + if (old == names_alloca) + names_alloca = names; + else + free (old); + } + result = GLOB_NOSPACE; + } + else + { + while (1) + { + struct globnames *old = names; + for (size_t i = 0; i < cur; ++i) + new_gl_pathv[pglob->gl_offs + pglob->gl_pathc++] + = names->name[i]; + names = names->next; + if (names == NULL) + break; + cur = names->count; + if (old == names_alloca) + names_alloca = names; + else + free (old); + } - for (; names != NULL; names = names->next) - pglob->gl_pathv[pglob->gl_offs + pglob->gl_pathc++] = names->name; - pglob->gl_pathv[pglob->gl_offs + pglob->gl_pathc] = NULL; + pglob->gl_pathv = new_gl_pathv; - pglob->gl_flags = flags; + pglob->gl_pathv[pglob->gl_offs + pglob->gl_pathc] = NULL; + + pglob->gl_flags = flags; + } } - save = errno; if (stream != NULL) { + save = errno; if (flags & GLOB_ALTDIRFUNC) (*pglob->gl_closedir) (stream); else closedir (stream); + __set_errno (save); } - __set_errno (save); - return nfound == 0 ? GLOB_NOMATCH : 0; - - memory_error: - { - int save = errno; - if (flags & GLOB_ALTDIRFUNC) - (*pglob->gl_closedir) (stream); - else - closedir (stream); - __set_errno (save); - } - while (names != NULL) - { - if (names->name != NULL) - free (names->name); - names = names->next; - } - return GLOB_NOSPACE; + return result; } diff --git a/sysdeps/ieee754/ldbl-128/s_lrintl.c b/sysdeps/ieee754/ldbl-128/s_lrintl.c index 53835a4bbc..ead24e99f0 100644 --- a/sysdeps/ieee754/ldbl-128/s_lrintl.c +++ b/sysdeps/ieee754/ldbl-128/s_lrintl.c @@ -50,7 +50,7 @@ __lrintl (long double x) { w = two112[sx] + x; t = w - two112[sx]; - GET_LDOUBLE_WORDS64 (i0, i1, x); + GET_LDOUBLE_WORDS64 (i0, i1, t); j0 = ((i0 >> 48) & 0x7fff) - 0x3fff; i0 &= 0x0000ffffffffffffLL; i0 |= 0x0001000000000000LL; @@ -65,7 +65,7 @@ __lrintl (long double x) { w = two112[sx] + x; t = w - two112[sx]; - GET_LDOUBLE_WORDS64 (i0, i1, x); + GET_LDOUBLE_WORDS64 (i0, i1, t); j0 = ((i0 >> 48) & 0x7fff) - 0x3fff; i0 &= 0x0000ffffffffffffLL; i0 |= 0x0001000000000000LL; diff --git a/sysdeps/powerpc/fpu/libm-test-ulps b/sysdeps/powerpc/fpu/libm-test-ulps index 37ebc93d90..8516e915e7 100644 --- a/sysdeps/powerpc/fpu/libm-test-ulps +++ b/sysdeps/powerpc/fpu/libm-test-ulps @@ -264,8 +264,8 @@ ldouble: 1 Test "Real part of: clog10 (0.75 + 1.25 i) == 0.163679467193165171449476605077428975 + 0.447486970040493067069984724340855636 i": float: 1 ifloat: 1 -ildouble: 2 -ldouble: 2 +ildouble: 3 +ldouble: 3 Test "Imaginary part of: clog10 (3 + inf i) == inf + pi/2*log10(e) i": double: 1 float: 1 @@ -364,6 +364,8 @@ ldouble: 2 Test "Imaginary part of: csinh (-2 - 3 i) == 3.59056458998577995201256544779481679 - 0.530921086248519805267040090660676560 i": double: 1 idouble: 1 +ildouble: 1 +ldouble: 1 Test "Real part of: csinh (0.75 + 1.25 i) == 0.259294854551162779153349830618433028 + 1.22863452409509552219214606515777594 i": float: 1 ifloat: 1 @@ -739,6 +741,9 @@ idouble: 1 ifloat: 1 # y0 +Test "y0 (0.125) == -1.38968062514384052915582277745018693": +ildouble: 1 +ldouble: 1 Test "y0 (0.75) == -0.137172769385772397522814379396581855": ildouble: 1 ldouble: 1 @@ -800,6 +805,9 @@ ildouble: 2 ldouble: 2 # yn +Test "yn (0, 0.125) == -1.38968062514384052915582277745018693": +ildouble: 1 +ldouble: 1 Test "yn (0, 0.75) == -0.137172769385772397522814379396581855": ildouble: 1 ldouble: 1 @@ -1066,8 +1074,8 @@ ldouble: 1 Function: Real part of "clog10": float: 1 ifloat: 1 -ildouble: 2 -ldouble: 2 +ildouble: 3 +ldouble: 3 Function: Imaginary part of "clog10": double: 1 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 #include -/* - 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 (!__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))) - { - __set_errno (EINVAL); - 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); -# endif + 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 (__builtin_expect (INTERNAL_SYSCALL_ERROR_P (result, err), 0)) - goto fail; + { + __atfct_seterrno (INTERNAL_SYSCALL_ERRNO (result, err), fd, buf); + return -1; + } +# else + /* 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 return result; - fail: - __atfct_seterrno (INTERNAL_SYSCALL_ERRNO (result, err), fd, buf); - return -1; #endif } diff --git a/sysdeps/unix/sysv/linux/powerpc/fchownat.c b/sysdeps/unix/sysv/linux/powerpc/fchownat.c index f1b9b4db4a..67c570648a 100644 --- a/sysdeps/unix/sysv/linux/powerpc/fchownat.c +++ b/sysdeps/unix/sysv/linux/powerpc/fchownat.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2005 Free Software Foundation, Inc. +/* Copyright (C) 2005, 2006 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or @@ -81,143 +81,30 @@ fchownat (int fd, const char *file, uid_t owner, gid_t group, int flag) file = buf; } +# if __ASSUME_LCHOWN_SYSCALL INTERNAL_SYSCALL_DECL (err); -# if __ASSUME_LCHOWN_SYSCALL if (flag & AT_SYMLINK_NOFOLLOW) result = INTERNAL_SYSCALL (lchown, err, 3, file, owner, group); else result = INTERNAL_SYSCALL (chown, err, 3, file, owner, group); -# else - char link[PATH_MAX + 2]; - char path[2 * PATH_MAX + 4]; - int loopct; - size_t filelen; - static int libc_old_chown = 0 /* -1=old linux, 1=new linux, 0=unknown */; - - if (libc_old_chown == 1) - { - if (flag & AT_SYMLINK_NOFOLLOW) - result = INTERNAL_SYSCALL (lchown, err, 3, __ptrvalue (file), owner, - group); - else - result = INTERNAL_SYSCALL (chown, err, 3, __ptrvalue (file), owner, - group); - goto out; - } - -# ifdef __NR_lchown - if (flag & AT_SYMLINK_NOFOLLOW) - { - result = INTERNAL_SYSCALL (lchown, err, 3, __ptrvalue (file), owner, - group); - goto out; - } - - if (libc_old_chown == 0) - { - result = INTERNAL_SYSCALL (chown, err, 3, __ptrvalue (file), owner, - group); - if (__builtin_expect (!INTERNAL_SYSCALL_ERROR_P (result, err), 1)) - return result; - if (INTERNAL_SYSCALL_ERRNO (result, err) != ENOSYS) - { - libc_old_chown = 1; - goto fail; - } - libc_old_chown = -1; - } -# else - if (flag & AT_SYMLINK_NOFOLLOW) - { - result = INTERNAL_SYSCALL (chown, err, 3, __ptrvalue (file), owner, - group); - goto out; - } -# endif - - result = __readlink (file, link, PATH_MAX + 1); - if (result == -1) - { -# ifdef __NR_lchown - result = INTERNAL_SYSCALL (lchown, err, 3, __ptrvalue (file), owner, - group); -# else - result = INTERNAL_SYSCALL (chown, err, 3, __ptrvalue (file), owner, - group); -# endif - goto out; - } - - filelen = strlen (file) + 1; - if (filelen > sizeof (path)) - { - errno = ENAMETOOLONG; - return -1; - } - memcpy (path, file, filelen); - - /* 'The system has an arbitrary limit...' In practise, we'll hit - ENAMETOOLONG before this, usually. */ - for (loopct = 0; loopct < 128; ++loopct) - { - size_t linklen; - - if (result >= PATH_MAX + 1) - { - errno = ENAMETOOLONG; - return -1; - } - - link[result] = 0; /* Null-terminate string, just-in-case. */ - - linklen = strlen (link) + 1; - - if (link[0] == '/') - memcpy (path, link, linklen); - else - { - filelen = strlen (path); - - while (filelen > 1 && path[filelen - 1] == '/') - --filelen; - while (filelen > 0 && path[filelen - 1] != '/') - --filelen; - if (filelen + linklen > sizeof (path)) - { - errno = ENAMETOOLONG; - return -1; - } - memcpy (path + filelen, link, linklen); - } - - result = __readlink (path, link, PATH_MAX + 1); - - if (result == -1) - { -# ifdef __NR_lchown - result = INTERNAL_SYSCALL (lchown, err, 3, path, owner, group); -# else - result = INTERNAL_SYSCALL (chown, err, 3, path, owner, group); -# endif - goto out; - } - } - __set_errno (ELOOP); - return -1; - - out: -# endif if (__builtin_expect (INTERNAL_SYSCALL_ERROR_P (result, err), 0)) { -# if !__ASSUME_LCHOWN_SYSCALL - fail: -# endif __atfct_seterrno (INTERNAL_SYSCALL_ERRNO (result, err), fd, buf); - result = -1; + return -1; } +# else + /* 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 return result; + #endif } diff --git a/sysdeps/unix/sysv/linux/s390/s390-32/fchownat.c b/sysdeps/unix/sysv/linux/s390/s390-32/fchownat.c index abc06b07d9..dfed76aeb4 100644 --- a/sysdeps/unix/sysv/linux/s390/s390-32/fchownat.c +++ b/sysdeps/unix/sysv/linux/s390/s390-32/fchownat.c @@ -1,159 +1 @@ -/* Copyright (C) 2005, 2006 Free Software Foundation, Inc. - This file is part of the GNU C Library. - - The GNU C Library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - The GNU C Library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with the GNU C Library; if not, write to the Free - Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA - 02111-1307 USA. */ - -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -#include -#include - -/* - 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. -*/ - -/* 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 */ - -int -fchownat (int fd, const char *file, uid_t owner, gid_t group, int flag) -{ - int result; - -#ifdef __NR_fchownat -# ifndef __ASSUME_ATFCTS - if (__have_atfcts >= 0) -# endif - { - result = INLINE_SYSCALL (fchownat, 5, fd, file, owner, group, flag); -# ifndef __ASSUME_ATFCTS - if (result == -1 && errno == ENOSYS) - __have_atfcts = -1; - else -# endif - return result; - } -#endif - -#ifndef __ASSUME_ATFCTS - if (flag & ~AT_SYMLINK_NOFOLLOW) - { - __set_errno (EINVAL); - return -1; - } - - char *buf = NULL; - - if (fd != AT_FDCWD && file[0] != '/') - { - size_t filelen = strlen (file); - static const char procfd[] = "/proc/self/fd/%d/%s"; - /* Buffer for the path name we are going to use. It consists of - - the string /proc/self/fd/ - - the file descriptor number - - the file name provided. - The final NUL is included in the sizeof. A bit of overhead - due to the format elements compensates for possible negative - numbers. */ - size_t buflen = sizeof (procfd) + sizeof (int) * 3 + filelen; - buf = alloca (buflen); - - __snprintf (buf, buflen, procfd, fd, file); - file = buf; - } - - INTERNAL_SYSCALL_DECL (err); - -# if __ASSUME_32BITUIDS > 0 - result = INTERNAL_SYSCALL (chown32, err, 3, CHECK_STRING (file), owner, - group); -# else - 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 (__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))) - { - __set_errno (EINVAL); - return -1; - } - - 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); -# endif - - if (__builtin_expect (INTERNAL_SYSCALL_ERROR_P (result, err), 0)) - { - fail: - __atfct_seterrno (INTERNAL_SYSCALL_ERRNO (result, err), fd, buf); - result = -1; - } - - return result; -#endif -} +#include diff --git a/sysdeps/unix/sysv/linux/sh/fchownat.c b/sysdeps/unix/sysv/linux/sh/fchownat.c index 61df787c2a..dfed76aeb4 100644 --- a/sysdeps/unix/sysv/linux/sh/fchownat.c +++ b/sysdeps/unix/sysv/linux/sh/fchownat.c @@ -1,140 +1 @@ -/* Copyright (C) 2005, 2006 Free Software Foundation, Inc. - This file is part of the GNU C Library. - - The GNU C Library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - The GNU C Library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with the GNU C Library; if not, write to the Free - Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA - 02111-1307 USA. */ - -#include -#include -#include -#include -#include - -#include -#include -#include - -#include -#include - -#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 */ - -int -fchownat (int fd, const char *file, uid_t owner, gid_t group, int flag) -{ - int result; - -#ifdef __NR_fchownat -# ifndef __ASSUME_ATFCTS - if (__have_atfcts >= 0) -# endif - { - result = INLINE_SYSCALL (fchownat, 5, fd, file, owner, group, flag); -# ifndef __ASSUME_ATFCTS - if (result == -1 && errno == ENOSYS) - __have_atfcts = -1; - else -# endif - return result; - } -#endif - -#ifndef __ASSUME_ATFCTS - if (flag & ~AT_SYMLINK_NOFOLLOW) - { - __set_errno (EINVAL); - return -1; - } - - char *buf = NULL; - - if (fd != AT_FDCWD && file[0] != '/') - { - size_t filelen = strlen (file); - static const char procfd[] = "/proc/self/fd/%d/%s"; - /* Buffer for the path name we are going to use. It consists of - - the string /proc/self/fd/ - - the file descriptor number - - the file name provided. - The final NUL is included in the sizeof. A bit of overhead - due to the format elements compensates for possible negative - numbers. */ - size_t buflen = sizeof (procfd) + sizeof (int) * 3 + filelen; - buf = alloca (buflen); - - __snprintf (buf, buflen, procfd, fd, file); - file = buf; - } - - INTERNAL_SYSCALL_DECL (err); - -# if __ASSUME_32BITUIDS > 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); -# else -# 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 (__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) > (gid_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 (lchown, err, 3, CHECK_STRING (file), owner, - group); - else - result = INTERNAL_SYSCALL (chown, err, 3, CHECK_STRING (file), owner, - group); -# endif - - if (__builtin_expect (INTERNAL_SYSCALL_ERROR_P (result, err), 0)) - { - fail: - __atfct_seterrno (INTERNAL_SYSCALL_ERRNO (result, err), fd, buf); - result = -1; - } - - return result; -#endif -} +#include diff --git a/sysdeps/unix/sysv/linux/sparc/sparc32/fchownat.c b/sysdeps/unix/sysv/linux/sparc/sparc32/fchownat.c index 7ba5bf44a1..dfed76aeb4 100644 --- a/sysdeps/unix/sysv/linux/sparc/sparc32/fchownat.c +++ b/sysdeps/unix/sysv/linux/sparc/sparc32/fchownat.c @@ -1 +1 @@ -#include +#include