summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog67
-rw-r--r--elf/dl-deps.c12
-rw-r--r--elf/dl-load.c37
-rw-r--r--fedora/branch.mk4
-rw-r--r--fedora/glibc.spec.in22
-rw-r--r--intl/dcigettext.c54
-rw-r--r--misc/Makefile2
-rw-r--r--misc/insremque.c22
-rw-r--r--misc/tst-insremque.c61
-rw-r--r--nis/nis_subr.c73
-rw-r--r--nptl/ChangeLog6
-rw-r--r--nptl/sysdeps/pthread/pthread.h10
-rw-r--r--posix/Makefile3
-rw-r--r--posix/bug-regex25.c57
-rw-r--r--posix/regex_internal.c26
-rw-r--r--string/Makefile3
-rw-r--r--string/_strerror.c7
-rw-r--r--string/bug-envz1.c76
-rw-r--r--string/envz.c4
-rw-r--r--sysdeps/generic/local-setxid.h4
-rw-r--r--sysdeps/i386/Makefile8
-rw-r--r--sysdeps/posix/spawni.c15
-rw-r--r--sysdeps/unix/sysv/linux/local-setxid.h23
23 files changed, 495 insertions, 101 deletions
diff --git a/ChangeLog b/ChangeLog
index 0fca57dc90..520062b8c8 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,70 @@
+2006-06-27 Ulrich Drepper <drepper@redhat.com>
+
+ * elf/dl-load.c (open_path): Fix test to determine whether DSO is
+ auditing.
+
+ * elf/dl-load.c (_dl_map_object): Try harder to avoid looking at
+ RPATH of main map twice.
+
+2006-06-22 Ulrich Drepper <drepper@redhat.com>
+
+ * intl/dcigettext.c (DCIGETTEXT): If _nl_find_msg returns -1 don't
+ look further, return original strings.
+ (_nl_find_msg): Do not return found translation if the conversion
+ failed. Either signal the string is unusable or that something went
+ wrong and the original should be used.
+
+2006-06-21 Ulrich Drepper <drepper@redhat.com>
+
+ * string/_strerror.c (__strerror_r): Add __builtin_expect.
+
+2006-06-14 Jakub Jelinek <jakub@redhat.com>
+
+ [BZ #2766]
+ * misc/insremque.c (insque): Handle prev == NULL.
+ * misc/Makefile (tests): Add tst-insremque.
+ * misc/tst-insremque.c: New test.
+
+2006-06-17 Ulrich Drepper <drepper@redhat.com>
+
+ [BZ #2792]
+ * elf/dl-deps.c (expand_dst): Rename __cnt variable to not
+ conflict with DL_DST_REQUIRED.
+
+2006-06-16 Ulrich Drepper <drepper@redhat.com>
+
+ * nis/nis_subr.c (nis_getnames): Fix the implementation to better
+ match what Solaris does.
+
+2006-06-04 Ulrich Drepper <drepper@redhat.com>
+
+ * sysdeps/posix/spawni.c (__spawni): Use local_seteuid and
+ local_setegid instead of seteuid and setegid.
+ * sysdeps/generic/local-setxid.h: New file.
+ * sysdeps/unix/sysv/linux/local-setxid.h: New file.
+
+ * sysdeps/posix/spawni.c (__spawni): Use non-cancelable interfaces.
+
+ * string/Makefile (tests): Add bug-envz1.
+ * string/bug-envz1.c: New file.
+
+2006-06-02 Jakub Jelinek <jakub@redhat.com>
+
+ * posix/regex_internal.c (re_string_skip_chars): If no character has
+ been converted at all, set *last_wc to WEOF. If mbrtowc failed, set wc
+ to the byte which couldn't be converted.
+ (re_string_reconstruct): Don't clear valid_raw_len before calling
+ re_string_skip_chars. If wc is WEOF after re_string_skip_chars, set
+ tip_context using re_string_context_at.
+ * posix/Makefile: Add rules to build and run bug-regex25 test.
+ * posix/bug-regex25.c: New test.
+
+2006-06-02 Ryan S. Arnold <rsa@us.ibm.com>
+
+ [BZ #2703]
+ * string/envz.c (envz_strip): Correct erroneously reversed src
+ and dest parameters to memmove() invocation.
+
2006-05-30 Jakub Jelinek <jakub@redhat.com>
* nscd/nscd.h (prune_cache): Add fd argument to prototype.
diff --git a/elf/dl-deps.c b/elf/dl-deps.c
index fd3b5243fd..c35cc977fa 100644
--- a/elf/dl-deps.c
+++ b/elf/dl-deps.c
@@ -1,5 +1,5 @@
/* Load the dependencies of a mapped object.
- Copyright (C) 1996-2003, 2004, 2005 Free Software Foundation, Inc.
+ Copyright (C) 1996-2003, 2004, 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
@@ -92,7 +92,7 @@ struct list
{
int done; /* Nonzero if this map was processed. */
struct link_map *map; /* The data. */
- struct list *next; /* Elements for normal list. */
+ struct list *next; /* Elements for normal list. */
};
@@ -101,9 +101,9 @@ struct list
({ \
const char *__str = (str); \
const char *__result = __str; \
- size_t __cnt = DL_DST_COUNT(__str, 0); \
+ size_t __dst_cnt = DL_DST_COUNT (__str, 0); \
\
- if (__cnt != 0) \
+ if (__dst_cnt != 0) \
{ \
char *__newp; \
\
@@ -113,9 +113,9 @@ struct list
DST not allowed in SUID/SGID programs")); \
\
__newp = (char *) alloca (DL_DST_REQUIRED (l, __str, strlen (__str), \
- __cnt)); \
+ __dst_cnt)); \
\
- __result = _dl_dst_substitute (l, __str, __newp, 0); \
+ __result = _dl_dst_substitute (l, __str, __newp, 0); \
\
if (*__result == '\0') \
{ \
diff --git a/elf/dl-load.c b/elf/dl-load.c
index 01e1572f51..902ffc4109 100644
--- a/elf/dl-load.c
+++ b/elf/dl-load.c
@@ -1846,7 +1846,7 @@ open_path (const char *name, size_t namelen, int preloaded,
auditing code. We must try to disturb the program as
little as possible. */
else if (loader == NULL
- || GL(dl_ns)[loader->l_ns]._ns_loaded->l_audit == 0)
+ || GL(dl_ns)[loader->l_ns]._ns_loaded->l_auditing == 0)
{
/* We failed to open machine dependent library. Let's
test whether there is any directory at all. */
@@ -2030,25 +2030,34 @@ _dl_map_object (struct link_map *loader, const char *name, int preloaded,
RPATHs. */
if (loader == NULL || loader->l_info[DT_RUNPATH] == NULL)
{
+ /* This is the executable's map (if there is one). Make sure that
+ we do not look at it twice. */
+ struct link_map *main_map = GL(dl_ns)[LM_ID_BASE]._ns_loaded;
+ bool did_main_map = false;
+
/* First try the DT_RPATH of the dependent object that caused NAME
to be loaded. Then that object's dependent, and on up. */
- for (l = loader; fd == -1 && l; l = l->l_loader)
+ for (l = loader; l; l = l->l_loader)
if (cache_rpath (l, &l->l_rpath_dirs, DT_RPATH, "RPATH"))
- fd = open_path (name, namelen, preloaded, &l->l_rpath_dirs,
- &realname, &fb, loader, LA_SER_RUNPATH,
- &found_other_class);
+ {
+ fd = open_path (name, namelen, preloaded, &l->l_rpath_dirs,
+ &realname, &fb, loader, LA_SER_RUNPATH,
+ &found_other_class);
+ if (fd != -1)
+ break;
+
+ did_main_map |= l == main_map;
+ }
/* If dynamically linked, try the DT_RPATH of the executable
itself. NB: we do this for lookups in any namespace. */
- if (fd == -1)
- {
- l = GL(dl_ns)[LM_ID_BASE]._ns_loaded;
- if (l && l->l_type != lt_loaded && l != loader
- && cache_rpath (l, &l->l_rpath_dirs, DT_RPATH, "RPATH"))
- fd = open_path (name, namelen, preloaded, &l->l_rpath_dirs,
- &realname, &fb, loader ?: l, LA_SER_RUNPATH,
- &found_other_class);
- }
+ if (fd == -1 && !did_main_map
+ && main_map != NULL && main_map->l_type != lt_loaded
+ && cache_rpath (main_map, &main_map->l_rpath_dirs, DT_RPATH,
+ "RPATH"))
+ fd = open_path (name, namelen, preloaded, &main_map->l_rpath_dirs,
+ &realname, &fb, loader ?: main_map, LA_SER_RUNPATH,
+ &found_other_class);
}
/* Try the LD_LIBRARY_PATH environment variable. */
diff --git a/fedora/branch.mk b/fedora/branch.mk
index 93d7c4f3d8..5bfb701238 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-05-31 13:22 UTC
-fedora-sync-tag := fedora-glibc-20060531T1322
+fedora-sync-date := 2006-06-30 08:58 UTC
+fedora-sync-tag := fedora-glibc-20060630T0858
diff --git a/fedora/glibc.spec.in b/fedora/glibc.spec.in
index 58760fec40..996510aec6 100644
--- a/fedora/glibc.spec.in
+++ b/fedora/glibc.spec.in
@@ -1,6 +1,5 @@
-%define glibcrelease 11
+%define glibcrelease 12
%define auxarches i586 i686 athlon sparcv9 alphaev6
-%define prelinkarches noarch
%define xenarches i686 athlon
%ifarch %{xenarches}
%define buildxen 1
@@ -41,10 +40,7 @@ Prereq: basesystem, libgcc
# This is for building auxiliary programs like memusage, nscd
# For initial glibc bootstraps it can be commented out
BuildPreReq: gd-devel libpng-devel zlib-devel texinfo, libselinux-devel >= 1.17.10-1
-BuildPreReq: audit-libs-devel >= 1.1.3, sed >= 3.95, libcap-devel
-%ifarch %{prelinkarches}
-BuildPreReq: prelink >= 0.2.0-5
-%endif
+BuildPreReq: audit-libs-devel >= 1.1.3, sed >= 3.95, libcap-devel, gettext
# This is to ensure that __frame_state_for is exported by glibc
# will be compatible with egcs 1.x.y
BuildPreReq: gcc >= 3.2
@@ -720,11 +716,6 @@ cat > override_headers/asm/unistd.h <<EOF
#define __NR_vmsplice 278
#endif
%endif
-%ifnarch %{ix86} x86_64
-/* FIXME: Reenable it when the kernel side is more stable. */
-#undef __NR_newfstatat
-#undef __NR_fstatat64
-%endif
#endif
EOF
cat > override_headers/asm/errno.h <<EOF
@@ -1439,6 +1430,15 @@ rm -f *.filelist*
%endif
%changelog
+* Fri Jun 30 2006 Jakub Jelinek <jakub@redhat.com> 2.4.90-12
+- buildrequire gettext
+- enable fstatat64/newfstatat syscalls even on ppc*/s390*/ia64 (#196494)
+- fix out of memory behavior in gettext (#194321)
+- fix regex on multi-byte non-UTF-8 charsets (#193873)
+- minor NIS+ fixes (#190803)
+- don't use cancellable calls in posix_spawn* and only set{u,g}id
+ current thread if requested (#193631)
+
* Wed May 31 2006 Jakub Jelinek <jakub@redhat.com> 2.4.90-11
- don't exit from nscd -i <database> before the database is
actually invalidated, add locking to prune_cache (#191464)
diff --git a/intl/dcigettext.c b/intl/dcigettext.c
index b56196ccbe..cb2b1813a7 100644
--- a/intl/dcigettext.c
+++ b/intl/dcigettext.c
@@ -611,6 +611,7 @@ DCIGETTEXT (domainname, msgid1, msgid2, plural, n, category)
if (strcmp (single_locale, "C") == 0
|| strcmp (single_locale, "POSIX") == 0)
{
+ no_translation:
FREE_BLOCKS (block_list);
__libc_rwlock_unlock (_nl_state_lock);
__set_errno (saved_errno);
@@ -646,6 +647,12 @@ DCIGETTEXT (domainname, msgid1, msgid2, plural, n, category)
}
}
+ /* Returning -1 means that some resource problem exists
+ (likely memory) and that the strings could not be
+ converted. Return the original strings. */
+ if (__builtin_expect (retval == (char *) -1, 0))
+ goto no_translation;
+
if (retval != NULL)
{
/* Found the translation of MSGID1 in domain DOMAIN:
@@ -865,21 +872,22 @@ _nl_find_msg (domain_file, domainbinding, msgid, convert, lengthp)
encoding. */
struct converted_domain *new_conversions =
(struct converted_domain *)
- (domain->conversions != NULL
- ? realloc (domain->conversions,
- (nconversions + 1) * sizeof (struct converted_domain))
- : malloc ((nconversions + 1) * sizeof (struct converted_domain)));
+ realloc (domain->conversions,
+ (nconversions + 1) * sizeof (struct converted_domain));
if (__builtin_expect (new_conversions == NULL, 0))
- /* Nothing we can do, no more memory. */
- goto converted;
+ /* Nothing we can do, no more memory. We cannot use the
+ translation because it might be encoded incorrectly. */
+ return (char *) -1;
+
domain->conversions = new_conversions;
/* Copy the 'encoding' string to permanent storage. */
encoding = strdup (encoding);
if (__builtin_expect (encoding == NULL, 0))
- /* Nothing we can do, no more memory. */
- goto converted;
+ /* Nothing we can do, no more memory. We cannot use the
+ translation because it might be encoded incorrectly. */
+ return (char *) -1;
convd = &new_conversions[nconversions];
convd->encoding = encoding;
@@ -933,10 +941,18 @@ _nl_find_msg (domain_file, domainbinding, msgid, convert, lengthp)
/* We always want to use transliteration. */
outcharset = norm_add_slashes (outcharset, "TRANSLIT");
charset = norm_add_slashes (charset, "");
- if (__gconv_open (outcharset, charset, &convd->conv,
- GCONV_AVOID_NOCONV)
- != __GCONV_OK)
- convd->conv = (__gconv_t) -1;
+ int r = __gconv_open (outcharset, charset, &convd->conv,
+ GCONV_AVOID_NOCONV);
+ if (__builtin_expect (r != __GCONV_OK, 0))
+ {
+ /* If the output encoding is the same there is
+ nothing to do. Otherwise do not use the
+ translation at all. */
+ if (__builtin_expect (r != __GCONV_NOCONV, 1))
+ return NULL;
+
+ convd->conv = (__gconv_t) -1;
+ }
# else
# if HAVE_ICONV
/* When using GNU libc >= 2.2 or GNU libiconv >= 1.5,
@@ -1000,8 +1016,9 @@ _nl_find_msg (domain_file, domainbinding, msgid, convert, lengthp)
convd->conv_tab = (char **) -1;
if (__builtin_expect (convd->conv_tab == (char **) -1, 0))
- /* Nothing we can do, no more memory. */
- goto converted;
+ /* Nothing we can do, no more memory. We cannot use the
+ translation because it might be encoded incorrectly. */
+ return (char *) -1;
if (convd->conv_tab[act] == NULL)
{
@@ -1049,8 +1066,10 @@ _nl_find_msg (domain_file, domainbinding, msgid, convert, lengthp)
if (res != __GCONV_FULL_OUTPUT)
{
+ /* We should not use the translation at all, it
+ is incorrectly encoded. */
__libc_lock_unlock (lock);
- goto converted;
+ return NULL;
}
inbuf = (const unsigned char *) result;
@@ -1076,7 +1095,7 @@ _nl_find_msg (domain_file, domainbinding, msgid, convert, lengthp)
if (errno != E2BIG)
{
__libc_lock_unlock (lock);
- goto converted;
+ return NULL;
}
# endif
# endif
@@ -1112,7 +1131,7 @@ _nl_find_msg (domain_file, domainbinding, msgid, convert, lengthp)
freemem = NULL;
freemem_size = 0;
__libc_lock_unlock (lock);
- goto converted;
+ return (char *) -1;
}
# ifdef _LIBC
@@ -1151,7 +1170,6 @@ _nl_find_msg (domain_file, domainbinding, msgid, convert, lengthp)
}
}
- converted:
/* The result string is converted. */
#endif /* _LIBC || HAVE_ICONV */
diff --git a/misc/Makefile b/misc/Makefile
index 63b6d413b3..f9ad0b76fc 100644
--- a/misc/Makefile
+++ b/misc/Makefile
@@ -78,7 +78,7 @@ endif
gpl2lgpl := error.c error.h
tests := tst-dirname tst-tsearch tst-fdset tst-efgcvt tst-mntent tst-hsearch \
- tst-error1 tst-pselect
+ tst-error1 tst-pselect tst-insremque
ifeq (no,$(cross-compiling))
tests: $(objpfx)tst-error1-mem
endif
diff --git a/misc/insremque.c b/misc/insremque.c
index e366ac8063..7f086cd392 100644
--- a/misc/insremque.c
+++ b/misc/insremque.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1992, 1995, 1996 Free Software Foundation, Inc.
+/* Copyright (C) 1992, 1995, 1996, 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
@@ -24,12 +24,20 @@
void
insque (void *elem, void *prev)
{
- struct qelem *next = ((struct qelem *) prev)->q_forw;
- ((struct qelem *) prev)->q_forw = (struct qelem *) elem;
- if (next != NULL)
- next->q_back = (struct qelem *) elem;
- ((struct qelem *) elem)->q_forw = next;
- ((struct qelem *) elem)->q_back = (struct qelem *) prev;
+ if (prev == NULL)
+ {
+ ((struct qelem *) elem)->q_forw = NULL;
+ ((struct qelem *) elem)->q_back = NULL;
+ }
+ else
+ {
+ struct qelem *next = ((struct qelem *) prev)->q_forw;
+ ((struct qelem *) prev)->q_forw = (struct qelem *) elem;
+ if (next != NULL)
+ next->q_back = (struct qelem *) elem;
+ ((struct qelem *) elem)->q_forw = next;
+ ((struct qelem *) elem)->q_back = (struct qelem *) prev;
+ }
}
/* Unlink ELEM from the doubly-linked list that it is in. */
diff --git a/misc/tst-insremque.c b/misc/tst-insremque.c
new file mode 100644
index 0000000000..9f17055ef5
--- /dev/null
+++ b/misc/tst-insremque.c
@@ -0,0 +1,61 @@
+#include <search.h>
+#include <stdio.h>
+#include <string.h>
+
+#define CHECK(cond) \
+ do \
+ if (! (cond)) \
+ { \
+ printf ("Condition " #cond " not true on line %d\n", __LINE__); \
+ ret = 1; \
+ } \
+ while (0)
+
+static int
+do_test (void)
+{
+ struct qelem elements[4];
+ int ret = 0;
+
+ /* Linear list. */
+ memset (elements, 0xff, sizeof (elements));
+ insque (&elements[0], NULL);
+ remque (&elements[0]);
+ insque (&elements[0], NULL);
+ insque (&elements[2], &elements[0]);
+ insque (&elements[1], &elements[0]);
+ insque (&elements[3], &elements[2]);
+ remque (&elements[2]);
+ insque (&elements[2], &elements[0]);
+ CHECK (elements[0].q_back == NULL);
+ CHECK (elements[0].q_forw == &elements[2]);
+ CHECK (elements[1].q_back == &elements[2]);
+ CHECK (elements[1].q_forw == &elements[3]);
+ CHECK (elements[2].q_back == &elements[0]);
+ CHECK (elements[2].q_forw == &elements[1]);
+ CHECK (elements[3].q_back == &elements[1]);
+ CHECK (elements[3].q_forw == NULL);
+
+ /* Circular list. */
+ memset (elements, 0xff, sizeof (elements));
+ elements[0].q_back = &elements[0];
+ elements[0].q_forw = &elements[0];
+ insque (&elements[2], &elements[0]);
+ insque (&elements[1], &elements[0]);
+ insque (&elements[3], &elements[2]);
+ remque (&elements[2]);
+ insque (&elements[2], &elements[0]);
+ CHECK (elements[0].q_back == &elements[3]);
+ CHECK (elements[0].q_forw == &elements[2]);
+ CHECK (elements[1].q_back == &elements[2]);
+ CHECK (elements[1].q_forw == &elements[3]);
+ CHECK (elements[2].q_back == &elements[0]);
+ CHECK (elements[2].q_forw == &elements[1]);
+ CHECK (elements[3].q_back == &elements[1]);
+ CHECK (elements[3].q_forw == &elements[0]);
+
+ return ret;
+}
+
+#define TEST_FUNCTION do_test ()
+#include "../test-skeleton.c"
diff --git a/nis/nis_subr.c b/nis/nis_subr.c
index 7e29168111..40c9270501 100644
--- a/nis/nis_subr.c
+++ b/nis/nis_subr.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 1997, 1999, 2000, 2004, 2005 Free Software Foundation, Inc.
+/* Copyright (c) 1997,1999,2000,2004,2005,2006 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Thorsten Kukuk <kukuk@vt.uni-paderborn.de>, 1997.
@@ -107,25 +107,23 @@ count_dots (const_nis_name str)
nis_name *
nis_getnames (const_nis_name name)
{
- nis_name *getnames = NULL;
- char local_domain[NIS_MAXNAMELEN + 1];
+ const char *local_domain = nis_local_directory ();
+ size_t local_domain_len = strlen (local_domain);
+ size_t name_len = strlen (name);
char *path;
- char *cp;
- int count;
int pos = 0;
- int have_point;
char *saveptr;
+ int have_point;
+ const char *cp;
+ const char *cp2;
- strncpy (local_domain, nis_local_directory (), NIS_MAXNAMELEN);
- local_domain[NIS_MAXNAMELEN] = '\0';
-
- count = 1;
- getnames = malloc ((count + 1) * sizeof (char *));
+ int count = 2;
+ nis_name *getnames = malloc ((count + 1) * sizeof (char *));
if (__builtin_expect (getnames == NULL, 0))
return NULL;
/* Do we have a fully qualified NIS+ name ? If yes, give it back */
- if (name[strlen (name) - 1] == '.')
+ if (name[name_len - 1] == '.')
{
if ((getnames[0] = strdup (name)) == NULL)
{
@@ -141,6 +139,44 @@ nis_getnames (const_nis_name name)
return getnames;
}
+ /* If the passed NAME is shared a suffix (the latter of course with
+ a final dot) with each other we pass back NAME with a final
+ dot. */
+ if (local_domain_len > 2)
+ {
+ have_point = 0;
+ cp = &local_domain[local_domain_len - 2];
+ cp2 = &name[name_len - 1];
+
+ while (*cp == *cp2)
+ {
+ if (*cp == '.')
+ have_point = 1;
+ --cp;
+ --cp2;
+ if (cp < local_domain)
+ {
+ have_point = cp2 < name || *cp2 == '.';
+ break;
+ }
+ if (cp2 < name)
+ {
+ have_point = *cp == '.';
+ break;
+ }
+ }
+
+ if (have_point)
+ {
+ getnames[0] = malloc (name_len + 2);
+ if (getnames[0] == NULL)
+ goto free_null;
+
+ strcpy (stpcpy (getnames[0], name), ".");
+ ++pos;
+ }
+ }
+
/* Get the search path, where we have to search "name" */
path = getenv ("NIS_PATH");
if (path == NULL)
@@ -148,17 +184,17 @@ nis_getnames (const_nis_name name)
else
path = strdupa (path);
- have_point = (strchr (name, '.') != NULL);
+ have_point = strchr (name, '.') != NULL;
cp = __strtok_r (path, ":", &saveptr);
while (cp)
{
if (strcmp (cp, "$") == 0)
{
- char *cptr = local_domain;
+ const char *cptr = local_domain;
char *tmp;
- while ((have_point && *cptr != '\0') || (count_dots (cptr) >= 2))
+ while (*cptr != '\0' && count_dots (cptr) >= 2)
{
if (pos >= count)
{
@@ -169,8 +205,7 @@ nis_getnames (const_nis_name name)
goto free_null;
getnames = newp;
}
- tmp = malloc (strlen (cptr) + strlen (local_domain) +
- strlen (name) + 2);
+ tmp = malloc (strlen (cptr) + local_domain_len + name_len + 2);
if (__builtin_expect (tmp == NULL, 0))
goto free_null;
@@ -200,7 +235,7 @@ nis_getnames (const_nis_name name)
{
char *p;
- tmp = malloc (cplen + strlen (local_domain) + strlen (name) + 2);
+ tmp = malloc (cplen + local_domain_len + name_len + 2);
if (__builtin_expect (tmp == NULL, 0))
goto free_null;
@@ -216,7 +251,7 @@ nis_getnames (const_nis_name name)
{
char *p;
- tmp = malloc (cplen + strlen (name) + 2);
+ tmp = malloc (cplen + name_len + 2);
if (__builtin_expect (tmp == NULL, 0))
goto free_null;
diff --git a/nptl/ChangeLog b/nptl/ChangeLog
index 04a4cfad4e..985c92d4e1 100644
--- a/nptl/ChangeLog
+++ b/nptl/ChangeLog
@@ -1,6 +1,10 @@
+2006-06-04 Ulrich Drepper <drepper@redhat.com>
+
+ * sysdeps/pthread/pthread.h: Add pthread_equal inline version.
+
2006-05-15 Ulrich Drepper <drepper@redhat.com>
- * sysdeps/unix/sysv/linux/fork.h: Makr __fork_handlers as hidden.
+ * sysdeps/unix/sysv/linux/fork.h: Mark __fork_handlers as hidden.
2006-05-11 Ulrich Drepper <drepper@redhat.com>
diff --git a/nptl/sysdeps/pthread/pthread.h b/nptl/sysdeps/pthread/pthread.h
index 5f34302e0c..f60ecdee18 100644
--- a/nptl/sysdeps/pthread/pthread.h
+++ b/nptl/sysdeps/pthread/pthread.h
@@ -1100,6 +1100,16 @@ extern int pthread_atfork (void (*__prepare) (void),
void (*__parent) (void),
void (*__child) (void)) __THROW;
+
+#ifdef __USE_EXTERN_INLINES
+/* Optimizations. */
+extern __inline int
+__NTH (pthread_equal (pthread_t __thread1, pthread_t __thread2))
+{
+ return __thread1 == __thread2;
+}
+#endif
+
__END_DECLS
#endif /* pthread.h */
diff --git a/posix/Makefile b/posix/Makefile
index 30ade92836..4f76a267e9 100644
--- a/posix/Makefile
+++ b/posix/Makefile
@@ -81,7 +81,7 @@ tests := tstgetopt testfnm runtests runptests \
bug-regex13 bug-regex14 bug-regex15 bug-regex16 \
bug-regex17 bug-regex18 bug-regex19 bug-regex20 \
bug-regex21 bug-regex22 bug-regex23 bug-regex24 \
- tst-nice tst-nanosleep tst-regex2 \
+ bug-regex25 tst-nice tst-nanosleep tst-regex2 \
transbug tst-rxspencer tst-pcre tst-boost \
bug-ga1 tst-vfork1 tst-vfork2 tst-waitid \
tst-getaddrinfo2 bug-glob1 bug-glob2 tst-sysconf \
@@ -189,6 +189,7 @@ bug-regex19-ENV = LOCPATH=$(common-objpfx)localedata
bug-regex20-ENV = LOCPATH=$(common-objpfx)localedata
bug-regex22-ENV = LOCPATH=$(common-objpfx)localedata
bug-regex23-ENV = LOCPATH=$(common-objpfx)localedata
+bug-regex25-ENV = LOCPATH=$(common-objpfx)localedata
tst-rxspencer-ARGS = --utf8 rxspencer/tests
tst-rxspencer-ENV = LOCPATH=$(common-objpfx)localedata
tst-pcre-ARGS = PCRE.tests
diff --git a/posix/bug-regex25.c b/posix/bug-regex25.c
new file mode 100644
index 0000000000..5e56e49bb5
--- /dev/null
+++ b/posix/bug-regex25.c
@@ -0,0 +1,57 @@
+/* Test re_search in multibyte locale other than UTF-8.
+ Copyright (C) 2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Jakub Jelinek <jakub@redhat.com>, 2006.
+
+ 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 <locale.h>
+#include <regex.h>
+#include <stdio.h>
+#include <string.h>
+
+const char *str1 = "\xa3\xd8\xa3\xc9\xa3\xc9";
+const char *str2 = "\xa3\xd8\xa3\xc9";
+
+int
+main (void)
+{
+ setlocale (LC_ALL, "ja_JP.eucJP");
+
+ re_set_syntax (RE_SYNTAX_SED);
+
+ struct re_pattern_buffer re;
+ memset (&re, 0, sizeof (re));
+
+ struct re_registers regs;
+ memset (&regs, 0, sizeof (regs));
+
+ re_compile_pattern ("$", 1, &re);
+
+ int ret = 0, r = re_search (&re, str1, 4, 0, 4, &regs);
+ if (r != 4)
+ {
+ printf ("First re_search returned %d\n", r);
+ ret = 1;
+ }
+ r = re_search (&re, str2, 4, 0, 4, &regs);
+ if (r != 4)
+ {
+ printf ("Second re_search returned %d\n", r);
+ ret = 1;
+ }
+ return ret;
+}
diff --git a/posix/regex_internal.c b/posix/regex_internal.c
index 855497ebf1..ac312db0cd 100644
--- a/posix/regex_internal.c
+++ b/posix/regex_internal.c
@@ -482,7 +482,7 @@ re_string_skip_chars (re_string_t *pstr, int new_raw_idx, wint_t *last_wc)
mbstate_t prev_st;
int rawbuf_idx;
size_t mbclen;
- wchar_t wc = 0;
+ wchar_t wc = WEOF;
/* Skip the characters which are not necessary to check. */
for (rawbuf_idx = pstr->raw_mbs_idx + pstr->valid_raw_len;
@@ -495,7 +495,11 @@ re_string_skip_chars (re_string_t *pstr, int new_raw_idx, wint_t *last_wc)
remain_len, &pstr->cur_state);
if (BE (mbclen == (size_t) -2 || mbclen == (size_t) -1 || mbclen == 0, 0))
{
- /* We treat these cases as a singlebyte character. */
+ /* We treat these cases as a single byte character. */
+ if (mbclen == 0 || remain_len == 0)
+ wc = L'\0';
+ else
+ wc = *(unsigned char *) (pstr->raw_mbs + rawbuf_idx);
mbclen = 1;
pstr->cur_state = prev_st;
}
@@ -618,7 +622,6 @@ re_string_reconstruct (re_string_t *pstr, int idx, int eflags)
}
#endif
pstr->valid_len = 0;
- pstr->valid_raw_len = 0;
#ifdef RE_ENABLE_I18N
if (pstr->mb_cur_max > 1)
{
@@ -681,6 +684,16 @@ re_string_reconstruct (re_string_t *pstr, int idx, int eflags)
if (wc == WEOF)
pstr->valid_len = re_string_skip_chars (pstr, idx, &wc) - idx;
+ if (wc == WEOF)
+ pstr->tip_context
+ = re_string_context_at (pstr, pstr->valid_raw_len - 1, eflags);
+ else
+ pstr->tip_context = ((BE (pstr->word_ops_used != 0, 0)
+ && IS_WIDE_WORD_CHAR (wc))
+ ? CONTEXT_WORD
+ : ((IS_WIDE_NEWLINE (wc)
+ && pstr->newline_anchor)
+ ? CONTEXT_NEWLINE : 0));
if (BE (pstr->valid_len, 0))
{
for (wcs_idx = 0; wcs_idx < pstr->valid_len; ++wcs_idx)
@@ -689,17 +702,12 @@ re_string_reconstruct (re_string_t *pstr, int idx, int eflags)
memset (pstr->mbs, 255, pstr->valid_len);
}
pstr->valid_raw_len = pstr->valid_len;
- pstr->tip_context = ((BE (pstr->word_ops_used != 0, 0)
- && IS_WIDE_WORD_CHAR (wc))
- ? CONTEXT_WORD
- : ((IS_WIDE_NEWLINE (wc)
- && pstr->newline_anchor)
- ? CONTEXT_NEWLINE : 0));
}
else
#endif /* RE_ENABLE_I18N */
{
int c = pstr->raw_mbs[pstr->raw_mbs_idx + offset - 1];
+ pstr->valid_raw_len = 0;
if (pstr->trans)
c = pstr->trans[c];
pstr->tip_context = (bitset_contain (pstr->word_char, c)
diff --git a/string/Makefile b/string/Makefile
index 7c11c1ac22..a84ebebcaa 100644
--- a/string/Makefile
+++ b/string/Makefile
@@ -53,7 +53,8 @@ tests := tester inl-tester noinl-tester testcopy test-ffs \
tst-strlen stratcliff tst-svc tst-inlcall \
bug-strncat1 bug-strspn1 bug-strpbrk1 tst-bswap \
tst-strtok tst-strxfrm bug-strcoll1 tst-strfry \
- bug-strtok1 $(addprefix test-,$(strop-tests))
+ bug-strtok1 $(addprefix test-,$(strop-tests)) \
+ bug-envz1
distribute := memcopy.h pagecopy.h tst-svc.expect test-string.h
diff --git a/string/_strerror.c b/string/_strerror.c
index f6f16ff2af..cb5d9e3609 100644
--- a/string/_strerror.c
+++ b/string/_strerror.c
@@ -1,4 +1,5 @@
-/* Copyright (C) 1991,93,95,96,97,98,2000,2002 Free Software Foundation, Inc.
+/* Copyright (C) 1991,93,95,96,97,98,2000,2002,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
@@ -35,8 +36,8 @@
char *
__strerror_r (int errnum, char *buf, size_t buflen)
{
- if (errnum < 0 || errnum >= _sys_nerr_internal
- || _sys_errlist_internal[errnum] == NULL)
+ if (__builtin_expect (errnum < 0 || errnum >= _sys_nerr_internal
+ || _sys_errlist_internal[errnum] == NULL, 0))
{
/* Buffer we use to print the number in. For a maximum size for
`int' of 8 bytes we never need more than 20 digits. */
diff --git a/string/bug-envz1.c b/string/bug-envz1.c
new file mode 100644
index 0000000000..e8a60972b5
--- /dev/null
+++ b/string/bug-envz1.c
@@ -0,0 +1,76 @@
+/* Test for bug BZ #2703. */
+#include <stdio.h>
+#include <envz.h>
+#include <stdlib.h>
+#include <string.h>
+
+static const struct
+{
+ const char *s;
+ int in_result;
+} strs[] =
+{
+ { "a=1", 1 },
+ { "b=2", 1 },
+ { "(*)", 0 },
+ { "(*)", 0 },
+ { "e=5", 1 },
+ { "f=", 1 },
+ { "(*)", 0 },
+ { "h=8", 1 },
+ { "i=9", 1 },
+ { "j", 0 }
+};
+
+#define nstrs (sizeof (strs) / sizeof (strs[0]))
+
+
+static int
+do_test (void)
+{
+
+ size_t size = 0;
+ char *str = malloc (100);
+ if (str == NULL)
+ {
+ puts ("out of memory");
+ return 1;
+ }
+
+ char **argz = &str;
+
+ for (int i = 0; i < nstrs; ++i)
+ argz_add_sep (argz, &size, strs[i].s, '\0');
+
+ printf ("calling envz_strip with size=%zu\n", size);
+ envz_strip (argz, &size);
+
+ int result = 0;
+ printf ("new size=%zu\n", size);
+ for (int i = 0; i < nstrs; ++i)
+ if (strs[i].in_result)
+ {
+ char name[2];
+ name[0] = strs[i].s[0];
+ name[1] = '\0';
+
+ char *e = envz_entry (*argz, size, name);
+ if (e == NULL)
+ {
+ printf ("entry '%s' not found\n", name);
+ result = 1;
+ }
+ else if (strcmp (e, strs[i].s) != 0)
+ {
+ printf ("entry '%s' does not match: is '%s', expected '%s'\n",
+ name, e, strs[i].s);
+ result = 1;
+ }
+ }
+
+ free (*argz);
+ return result;
+}
+
+#define TEST_FUNCTION do_test ()
+#include "../test-skeleton.c"
diff --git a/string/envz.c b/string/envz.c
index 5c5804c12b..a9d420212f 100644
--- a/string/envz.c
+++ b/string/envz.c
@@ -1,5 +1,5 @@
/* Routines for dealing with '\0' separated environment vectors
- Copyright (C) 1995,96,97,98,2001,02 Free Software Foundation, Inc.
+ Copyright (C) 1995-1998,2001,2002,2006 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Written by Miles Bader <miles@gnu.org>
@@ -165,7 +165,7 @@ envz_strip (char **envz, size_t *envz_len)
left -= entry_len;
if (! strchr (entry, SEP))
/* Null entry. */
- memmove (entry + entry_len, entry, left);
+ memmove (entry, entry + entry_len, left);
else
entry += entry_len;
}
diff --git a/sysdeps/generic/local-setxid.h b/sysdeps/generic/local-setxid.h
new file mode 100644
index 0000000000..b70d9ffb32
--- /dev/null
+++ b/sysdeps/generic/local-setxid.h
@@ -0,0 +1,4 @@
+/* No special support. Fall back to the regular functions. */
+
+#define local_seteuid(id) seteuid (id)
+#define local_setegid(id) setegid (id)
diff --git a/sysdeps/i386/Makefile b/sysdeps/i386/Makefile
index ddd3d04e07..e192b91dbd 100644
--- a/sysdeps/i386/Makefile
+++ b/sysdeps/i386/Makefile
@@ -64,4 +64,12 @@ endif
ifneq (,$(filter -mno-tls-direct-seg-refs,$(CFLAGS)))
defines += -DNO_TLS_DIRECT_SEG_REFS
+else
+# .a libraries are not performance critical and so we
+# build them without direct TLS segment references
+# always.
+CPPFLAGS-.o += -DNO_TLS_DIRECT_SEG_REFS
+CFLAGS-.o += -mno-tls-direct-seg-refs
+CPPFLAGS-.oS += -DNO_TLS_DIRECT_SEG_REFS
+CFLAGS-.oS += -mno-tls-direct-seg-refs
endif
diff --git a/sysdeps/posix/spawni.c b/sysdeps/posix/spawni.c
index 27699f4df8..29803a8461 100644
--- a/sysdeps/posix/spawni.c
+++ b/sysdeps/posix/spawni.c
@@ -1,5 +1,5 @@
/* Guts of POSIX spawn interface. Generic POSIX.1 version.
- Copyright (C) 2000,2001,2002,2003,2004,2005 Free Software Foundation, Inc.
+ Copyright (C) 2000-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
@@ -26,6 +26,7 @@
#include <unistd.h>
#include "spawn_int.h"
#include <not-cancel.h>
+#include <local-setxid.h>
/* The Unix standard contains a long explanation of the way to signal
@@ -155,7 +156,8 @@ __spawni (pid_t *pid, const char *file,
/* Set the effective user and group IDs. */
if ((flags & POSIX_SPAWN_RESETIDS) != 0
- && (seteuid (__getuid ()) != 0 || setegid (__getgid ()) != 0))
+ && (local_seteuid (__getuid ()) != 0
+ || local_setegid (__getgid ()) != 0))
_exit (SPAWN_ERROR);
/* Execute the file actions. */
@@ -177,9 +179,10 @@ __spawni (pid_t *pid, const char *file,
case spawn_do_open:
{
- int new_fd = __open64 (action->action.open_action.path,
- action->action.open_action.oflag,
- action->action.open_action.mode);
+ int new_fd = open_not_cancel (action->action.open_action.path,
+ action->action.open_action.oflag
+ | O_LARGEFILE,
+ action->action.open_action.mode);
if (new_fd == -1)
/* The `open' call failed. */
@@ -193,7 +196,7 @@ __spawni (pid_t *pid, const char *file,
/* The `dup2' call failed. */
_exit (SPAWN_ERROR);
- if (__close (new_fd) != 0)
+ if (close_not_cancel (new_fd) != 0)
/* The `close' call failed. */
_exit (SPAWN_ERROR);
}
diff --git a/sysdeps/unix/sysv/linux/local-setxid.h b/sysdeps/unix/sysv/linux/local-setxid.h
new file mode 100644
index 0000000000..0579687982
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/local-setxid.h
@@ -0,0 +1,23 @@
+/* SETxID functions which only have to change the local thread and
+ none of the possible other threads. */
+#include <kernel-features.h>
+#include <sysdep.h>
+
+/* If we can use the syscall directly, use it. */
+#if __ASSUME_32BITUIDS > 0 && defined __NR_setresuid32
+# define local_seteuid(id) INLINE_SYSCALL (setresuid32, 3, -1, id, -1)
+#elif __ASSUME_SETRESUID_SYSCALL > 0
+# define local_seteuid(id) INLINE_SYSCALL (setresuid, 3, -1, id, -1)
+#else
+# define local_seteuid(id) seteuid (id)
+#endif
+
+
+/* If we can use the syscall directly, use it. */
+#if __ASSUME_32BITUIDS > 0 && defined __NR_setresgid32
+# define local_setegid(id) INLINE_SYSCALL (setresgid32, 3, -1, id, -1)
+#elif __ASSUME_SETRESGID_SYSCALL > 0
+# define local_setegid(id) INLINE_SYSCALL (setresgid, 3, -1, id, -1)
+#else
+# define local_setegid(id) setegid (id)
+#endif