summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJakub Jelinek <jakub@redhat.com>2006-09-25 15:44:20 +0000
committerJakub Jelinek <jakub@redhat.com>2006-09-25 15:44:20 +0000
commit5ed9cc7c21189bab600d08763133a2b8fe90896d (patch)
treef8965f20db2401865e69451279de722a186e01ee
parent0e4d91bd31869b6f67e9284e1de3d470e10a3156 (diff)
Updated to fedora-glibc-20060925T1535cvs/fedora-glibc-2_4_90-35
-rw-r--r--ChangeLog34
-rw-r--r--NEWS7
-rw-r--r--fedora/branch.mk4
-rw-r--r--fedora/glibc.spec.in7
-rw-r--r--include/ifaddrs.h3
-rw-r--r--nptl/ChangeLog6
-rw-r--r--nptl/descr.h2
-rw-r--r--posix/glob.c142
-rw-r--r--sysdeps/ieee754/ldbl-128/s_lrintl.c4
-rw-r--r--sysdeps/posix/getaddrinfo.c12
-rw-r--r--sysdeps/powerpc/fpu/libm-test-ulps16
-rw-r--r--sysdeps/unix/sysv/linux/check_pf.c12
-rw-r--r--sysdeps/unix/sysv/linux/i386/fchownat.c120
-rw-r--r--sysdeps/unix/sysv/linux/powerpc/fchownat.c139
-rw-r--r--sysdeps/unix/sysv/linux/s390/s390-32/fchownat.c160
-rw-r--r--sysdeps/unix/sysv/linux/sh/fchownat.c141
-rw-r--r--sysdeps/unix/sysv/linux/sparc/sparc32/fchownat.c2
17 files changed, 210 insertions, 601 deletions
diff --git a/ChangeLog b/ChangeLog
index 62c9a6946c..5176ef7aba 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,37 @@
+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.
+
+2006-09-24 Ulrich Drepper <drepper@redhat.com>
+
+ * sysdeps/posix/getaddrinfo.c (rfc3484_sort): Implement rule 4,
+ home addresses.
+ * sysdeps/unix/sysv/linux/check_pf.c (make_request): Recognize
+ IFA_F_HOMEADDRESS flag for interfaces.
+ * include/ifaddrs.h (struct in6addrinfo): Define
+ in6ai_homeaddress.
+
2006-09-21 Jakub Jelinek <jakub@redhat.com>
[BZ #3225]
diff --git a/NEWS b/NEWS
index 14abed4782..5a51c03549 100644
--- a/NEWS
+++ b/NEWS
@@ -1,4 +1,4 @@
-GNU C Library NEWS -- history of user-visible changes. 2006-08-14
+GNU C Library NEWS -- history of user-visible changes. 2006-09-24
Copyright (C) 1992-2002,2003,2004,2005,2006 Free Software Foundation, Inc.
See the end for copying conditions.
@@ -8,7 +8,8 @@ using `glibc' in the "product" field.
Version 2.5
* For Linux, the sorting of addresses returned by getaddrinfo now also
- handles rules 3 and 7 from RFC 3484. Implemented by Ulrich Drepper.
+ handles rules 3, 4, and 7 from RFC 3484. I.e., all rules are handled.
+ Implemented by Ulrich Drepper.
* Allow system admin to configure getaddrinfo with the /etc/gai.conf file.
Implemented by Ulrich Drepper.
@@ -20,7 +21,7 @@ Version 2.5
* For sites with broken group and/or passwd database, the auto-propagate
option of nscd can prevent creating ID lookup entries from the results
of a name lookup and vice versa. This usually is no problem but some
- site might have problems with default behavior.
+ site might have problems with the default behavior.
Implemented by Ulrich Drepper.
* Iterating over entire database in NIS can be slow. With the
diff --git a/fedora/branch.mk b/fedora/branch.mk
index 029201b763..1141ca3461 100644
--- a/fedora/branch.mk
+++ b/fedora/branch.mk
@@ -3,5 +3,5 @@ glibc-branch := fedora
glibc-base := HEAD
DIST_BRANCH := devel
COLLECTION := dist-fc4
-fedora-sync-date := 2006-09-23 09:46 UTC
-fedora-sync-tag := fedora-glibc-20060923T0946
+fedora-sync-date := 2006-09-25 15:35 UTC
+fedora-sync-tag := fedora-glibc-20060925T1535
diff --git a/fedora/glibc.spec.in b/fedora/glibc.spec.in
index c8ea8090d3..970ba8c958 100644
--- a/fedora/glibc.spec.in
+++ b/fedora/glibc.spec.in
@@ -1,4 +1,4 @@
-%define glibcrelease 34
+%define glibcrelease 35
%define auxarches i586 i686 athlon sparcv9 alphaev6
%define xenarches i686 athlon
%ifarch %{xenarches}
@@ -1528,6 +1528,11 @@ rm -f *.filelist*
%endif
%changelog
+* Mon Sep 25 2006 Jakub Jelinek <jakub@redhat.com> 2.4.90-35
+- fix glob with large number of matches (BZ#3253)
+- fix fchownat on kernels that don't support that syscall (BZ#3252)
+- fix lrintl on s390{,64}
+
* Sat Sep 23 2006 Jakub Jelinek <jakub@redhat.com> 2.4.90-34
- fix ppc{32,64} longjmp (BZ#3225)
- fix user visible spelling errors (BZ#3137)
diff --git a/include/ifaddrs.h b/include/ifaddrs.h
index d790fcbe87..71bdaeb180 100644
--- a/include/ifaddrs.h
+++ b/include/ifaddrs.h
@@ -10,7 +10,8 @@ struct in6addrinfo
{
enum {
in6ai_deprecated = 1,
- in6ai_temporary = 2
+ in6ai_temporary = 2,
+ in6ai_homeaddress = 4
} flags;
uint32_t addr[4];
};
diff --git a/nptl/ChangeLog b/nptl/ChangeLog
index 0d05e200ff..8024bd302c 100644
--- a/nptl/ChangeLog
+++ b/nptl/ChangeLog
@@ -1,3 +1,9 @@
+2006-09-24 Ulrich Drepper <drepper@redhat.com>
+
+ [BZ #3251]
+ * descr.h (ENQUEUE_MUTEX_BOTH): Add cast to avoid warning.
+ Patch by Petr Baudis.
+
2006-09-18 Jakub Jelinek <jakub@redhat.com>
* tst-kill4.c (do_test): Explicitly set tf thread's stack size.
diff --git a/nptl/descr.h b/nptl/descr.h
index b9b9ed7b98..321ce85085 100644
--- a/nptl/descr.h
+++ b/nptl/descr.h
@@ -201,7 +201,7 @@ struct pthread
mutex->__data.__list.__next \
= THREAD_GETMEM (THREAD_SELF, robust_list.__next); \
THREAD_SETMEM (THREAD_SELF, robust_list.__next, \
- ((uintptr_t) &mutex->__data.__list) | val); \
+ (void *) (((uintptr_t) &mutex->__data.__list) | val)); \
} while (0)
# define DEQUEUE_MUTEX(mutex) \
do { \
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);
+ }
+
+ pglob->gl_pathv = new_gl_pathv;
- 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[pglob->gl_offs + pglob->gl_pathc] = NULL;
- pglob->gl_flags = flags;
+ 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/posix/getaddrinfo.c b/sysdeps/posix/getaddrinfo.c
index 185957be6a..dd5a57d9e0 100644
--- a/sysdeps/posix/getaddrinfo.c
+++ b/sysdeps/posix/getaddrinfo.c
@@ -1390,8 +1390,16 @@ rfc3484_sort (const void *p1, const void *p2)
return 1;
}
- /* Rule 4: Prefer home addresses.
- Another thing only the kernel can decide. */
+ /* Rule 4: Prefer home addresses. */
+ if (a1->got_source_addr)
+ {
+ if (!(a1->source_addr_flags & in6ai_homeaddress)
+ && (a2->source_addr_flags & in6ai_homeaddress))
+ return -1;
+ if ((a1->source_addr_flags & in6ai_homeaddress)
+ && !(a2->source_addr_flags & in6ai_homeaddress))
+ return 1;
+ }
/* Rule 5: Prefer matching label. */
if (a1->got_source_addr)
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/check_pf.c b/sysdeps/unix/sysv/linux/check_pf.c
index 7fbb7543d6..13ccd7acb4 100644
--- a/sysdeps/unix/sysv/linux/check_pf.c
+++ b/sysdeps/unix/sysv/linux/check_pf.c
@@ -38,6 +38,9 @@
#ifndef IFA_F_TEMPORARY
# define IFA_F_TEMPORARY IFA_F_SECONDARY
#endif
+#ifndef IFA_F_HOMEADDRESS
+# define IFA_F_HOMEADDRESS 0
+#endif
static int
@@ -124,7 +127,9 @@ make_request (int fd, pid_t pid, bool *seen_ipv4, bool *seen_ipv6,
case AF_INET6:
*seen_ipv6 = true;
- if (ifam->ifa_flags & (IFA_F_DEPRECATED | IFA_F_TEMPORARY))
+ if (ifam->ifa_flags & (IFA_F_DEPRECATED
+ | IFA_F_TEMPORARY
+ | IFA_F_HOMEADDRESS))
{
struct rtattr *rta = IFA_RTA (ifam);
size_t len = (nlmh->nlmsg_len
@@ -152,7 +157,10 @@ make_request (int fd, pid_t pid, bool *seen_ipv4, bool *seen_ipv6,
? in6ai_deprecated : 0)
| ((ifam->ifa_flags
& IFA_F_TEMPORARY)
- ? in6ai_temporary : 0));
+ ? in6ai_temporary : 0)
+ | ((ifam->ifa_flags
+ & IFA_F_HOMEADDRESS)
+ ? in6ai_homeaddress : 0));
memcpy (newp->info.addr, address ?: local,
sizeof (newp->info.addr));
newp->next = in6ailist;
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
}
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 <errno.h>
-#include <fcntl.h>
-#include <stdio.h>
-#include <string.h>
-#include <unistd.h>
-
-#include <sysdep.h>
-#include <sys/syscall.h>
-#include <shlib-compat.h>
-#include <bp-checks.h>
-
-#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.
-*/
-
-/* 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 <sysdeps/unix/sysv/linux/i386/fchownat.c>
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 <errno.h>
-#include <fcntl.h>
-#include <stdio.h>
-#include <unistd.h>
-#include <string.h>
-
-#include <sysdep.h>
-#include <sys/syscall.h>
-#include <bp-checks.h>
-
-#include <linux/posix_types.h>
-#include <kernel-features.h>
-
-#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 <sysdeps/unix/sysv/linux/i386/fchownat.c>
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 <sysdeps/unix/sysv/linux/sh/fchownat.c>
+#include <sysdeps/unix/sysv/linux/i386/fchownat.c>