]> git.ipfire.org Git - thirdparty/glibc.git/commitdiff
Updated to fedora-glibc-20041110T0839
authorJakub Jelinek <jakub@redhat.com>
Wed, 10 Nov 2004 09:02:52 +0000 (09:02 +0000)
committerJakub Jelinek <jakub@redhat.com>
Wed, 10 Nov 2004 09:02:52 +0000 (09:02 +0000)
43 files changed:
ChangeLog
Makeconfig
debug/tst-chk1.c
elf/dl-support.c
elf/rtld.c
fedora/branch.mk
fedora/glibc.spec.in
libio/Makefile
libio/bug-ungetc3.c [new file with mode: 0644]
libio/fileops.c
libio/ftello.c
libio/ftello64.c
libio/iofgetpos.c
libio/iofgetpos64.c
libio/ioftell.c
libio/oldiofgetpos.c
libio/oldiofgetpos64.c
nptl/ChangeLog
nptl/Makefile
nptl/pthread_create.c
nptl/sysdeps/pthread/createthread.c
nptl/tst-exit2.c [new file with mode: 0644]
nptl/tst-exit3.c [new file with mode: 0644]
nscd/nscd-client.h
nscd/nscd_getai.c
nscd/nscd_getgr_r.c
nscd/nscd_gethst_r.c
nscd/nscd_getpw_r.c
nscd/nscd_initgroups.c
posix/regcomp.c
posix/regex_internal.c
posix/regex_internal.h
posix/regexec.c
posix/rxspencer/tests
sysdeps/generic/dl-sysdep.c
sysdeps/generic/ldsodefs.h
sysdeps/generic/sysconf.c
sysdeps/generic/tempname.c
sysdeps/generic/utime.c
sysdeps/gnu/_G_config.h
sysdeps/mach/hurd/_G_config.h [new file with mode: 0644]
sysdeps/unix/sysv/linux/alpha/register-dump.h
sysdeps/unix/sysv/linux/ifaddrs.c

index 0bbe073a7a7df3c851fb9450ab0663a162dba4e5..bf062849e9bb9d8b51b97f0a5604cb271c36e1df 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
-2004-11-02  Jakub Jelinek  <jakub@redhat.com>
+2004-11-09  Ulrich Drepper  <drepper@redhat.com>
+
+       * nscd/nscd-client.h (libc_locked_map_ptr): Add new first
+       parameter, used as class for definition.
+       * nscd/nscd_getpw_r.c: Adjust for libc_locked_map_ptr change.
+       (pw_map_free): Ensure no crash after memory is freed.
+       * nscd/nscd_getgr.c: Likewise.  Make map externally visible.
+       * nscd/nscd_gethst.c: Likewise.
+       * nscd/nscd_getai.c: Use map from nscd_gethost.c.
+       * nscd/nscd_initgroups.c: Use map from nscd_getgr.c.
+
+       * nscd/nscd_getai.c: Add some checks to detect corrupt databases.
+       * nscd/nscd_getgr_r.c: Likewise
+       * nscd/nscd_gethst_r.c: Likewise.
+       * nscd/nscd_getpw_r.c: Likewise
 
-       * include/features.h (__USE_FORTIFY_LEVEL): Also set for Red Hat
-       GCC 3.4.x-RH >= 3.4.2-8.
-       * libio/bits/features.h (printf, fprintf, vprintf, vfprintf): For
-       GCC 3.4.x-RH use __builtin___{,v}{,f}printf_chk instead of
-       __{,v}{,f}printf_chk.
-       * debug/tst-chk1.c (do_test): Deal with GCC 3.4.x-RH not
-       being able to recognize subobjects.
+2004-11-09  Jakub Jelinek  <jakub@redhat.com>
+
+       * posix/regcomp.c (calc_eclosure_iter): Don't access
+       dfa->edests[node].elems[0] if dfa->edests[node].nelem == 0.
+       * posix/rxspencer/tests: Add 5 new tests.
+
+2004-11-09  Ulrich Drepper  <drepper@redhat.com>
+
+       * sysdeps/unix/sysv/linux/ifaddrs.c: Determine sin6_scope_id field
+       value correctly.  Patch by Mitsuru Kanda <mk@karaba.org>.
+
+2004-11-04  Jakub Jelinek  <jakub@redhat.com>
+
+       * libio/fileops.c (_IO_new_file_seekoff): If mode is 0 and
+       fp->_offset == _IO_pos_BAD, just call _IO_SYSSEEK (fp, 0, dir)
+       and if successful set fp->_offset.
+       * libio/Makefile (tests): Add bug-ungetc3.
+       * libio/bug-ungetc3.c: New test.
+
+2004-11-03  Marcus Brinkmann  <marcus@gnu.org>
+
+       * sysdeps/gnu/_G_config.h (_G_HAVE_MREMAP): Define symbol.
+       * sysdeps/mach/hurd/_G_config.h: New file.
+       * libio/fileops.c (mmap_remap_check) [__linux__]: Replaced with
+       [_G_HAVE_MREMAP].
+
+2004-11-08  Ulrich Drepper  <drepper@redhat.com>
+
+       * posix/regcomp.c (utf8_sb_map): Define.
+       (free_dfa_content): Don't free dfa->sb_char if it's a pointer to
+       utf8_sb_map.
+       (init_dfa): Use utf8_sb_map instead of initializing memory when the
+       encoding is UTF-8.
+
+2004-11-03  Paolo Bonzini  <bonzini@gnu.org>
+
+       * posix/regcomp.c (init_dfa): Get the codeset name outside glibc as
+       well.  Check if it is spelled UTF8 as well as UTF-8, and check
+       case-insensitively.  Set dfa->map_notascii manually when outside
+       glibc.
+       * posix/regex_internal.c (build_wcs_upper_buffer) [!_LIBC]: Enable
+       optimizations based on map_notascii.
+       * posix/regex_internal.h [HAVE_LANGINFO_H || HAVE_LANGINFO_CODESET
+       || _LIBC]: Include langinfo.h.
+
+       * posix/regex_internal.h (struct re_backref_cache_entry): Add "more"
+       field.
+       * posix/regexec.c (check_dst_limits): Hoist computation of the source
+       and destination bkref_idx out of the loop.  Pass it to
+       check_dst_limits_calc_pos.
+       (check_dst_limits_calc_pos_1): New function, containing the recursive
+       loop of check_dst_limits_calc_pos; uses the "more" field of
+       struct re_backref_cache to control the loop.
+       (check_dst_limits_calc_pos): Store into "boundaries" the position
+       relative to lim's start and end positions.  Do not accept eclosures,
+       accept bkref_idx instead.  Call check_dst_limits_calc_pos_1 to do the
+       work.
+       (sift_states_bkref): Use the "more" field of struct re_backref_cache
+       to control the loop.  A big "if" was turned into a continue and the
+       function was reindented.
+       (get_subexp): Use the "more" field of struct re_backref_cache
+       to control the loop.
+       (match_ctx_add_entry): Initialize the bkref_ents' "more" field.
+       (search_cur_bkref_entry): Return -1 if out of bounds.
+
+       * posix/regexec.c (empty_set): Remove.
+       (sift_states_backward): Remove cur_src variable.  Move inner loop
+       to build_sifted_states.
+       (build_sifted_states): Extract from sift_states_backward.  Do not
+       use empty_set.
+       (update_cur_sifted_state): Do not use empty_set.  Special case
+       dest_nodes->nelem == 0.
+
+       * posix/regex_internal.h (struct re_backref_cache_entry): Remove flag
+       field.
+       (struct re_sift_context_t): Remove cur_bkref, cls_subexp_idx,
+       check_subexp fields.  Move limits last.
+       * posix/regexec.c (match_ctx_clear_flag): Remove.
+       (sift_ctx_init): Remove check_subexp parameter.  Do not set removed
+       fields.  Callers adjusted.
+       (expand_bkref_cache): Remove last_str parameter.  Callers adjusted.
+       (re_search_internal): Remove fast_translate variable.
+       (update_cur_sifted_state): Pass candidates as the final parameter
+       to sift_states_bkref.
+       (sift_states_bkref): Change last unused parameter to be "candidates",
+       do not fetch candidates into a local variable.
+       Remove dead test for "node == sctx->bkref", and the cur_bkref_idx
+       variable.
+       Remove loops that set/reset the flag field of backref cache entries.
+       (check_arrival_add_next_nodes): Use a signed int to hold the return
+       value of re_node_set_insert.
+       (group_nodes_into_DFAstates): Likewise.
+       (match_ctx_add_entry): Do not set the flag field of the new entry.
+
+2004-11-05  Roland McGrath  <roland@redhat.com>
+
+       * sysdeps/generic/ldsodefs.h (struct rtld_global_ro): Define
+       _dl_sysinfo_dso under [NEED_DL_SYSINFO_DSO] as well.
+       * elf/rtld.c (dl_main): Set up GLRO(dl_sysinfo_dso) under
+       [NEED_DL_SYSINFO_DSO] as well.
+       * sysdeps/generic/dl-sysdep.c (_dl_show_auxv): Always include
+       AT_SYSINFO and AT_SYSINFO_EHDR in name table.
+       (_dl_sysdep_start) [NEED_DL_SYSINFO_DSO]: Match AT_SYSINFO_EHDR.
+       * elf/dl-support.c (_dl_sysinfo_dso): Define also under
+       [NEED_DL_SYSINFO_DSO].
+       (_dl_aux_init) [NEED_DL_SYSINFO || NEED_DL_SYSINFO_DSO]:
+       Match AT_SYSINFO_EHDR and set GL(dl_sysinfo_dso).
+
+2004-11-05  Roland McGrath  <roland@redhat.com>
+
+       * manual/errno.texi (Error Codes): Revert last change for now.
+       * sysdeps/gnu/errlist.c: Regenerated.
+
+2004-11-04  Roland McGrath  <roland@frob.com>
+
+       * Makeconfig (link-libc, rpath-dirs): Remove AIX cruft definitions.
+       (LDFLAGS-rpath-ORIGIN, LDFLAGS-soname-fname): Likewise.
+       (LDFLAGS-rdynamic, LDFLAGS-Bsymbolic): Likewise.
+       ($(common-objpfx)gnu/lib-names.stmp): Likewise.
 
 2004-11-01  Jakub Jelinek  <jakub@redhat.com>
 
        * sysdeps/x86_64/fpu/bits/fenv.h: Include bits/wordsize.h.
        (fenv_t): Remove __mxcsr field for -m32.
 
+2004-11-04  Jakub Jelinek  <jakub@redhat.com>
+
+       * libio/ftello.c (ftello): Don't subtract save_end - save_base
+       if pos is _IO_pos_BAD.
+       * libio/ftello64.c (ftello64): Likewise.
+       * libio/iofgetpos.c (_IO_new_fgetpos): Likewise.
+       * libio/iofgetpos64.c (_IO_new_fgetpos64): Likewise.
+       * libio/oldiofgetpos.c (_IO_old_fgetpos): Likewise.
+       * libio/oldiofgetpos64.c (_IO_old_fgetpos64): Likewise.
+       * libio/ioftell.c (_IO_ftell): Likewise.
+       Cast to long int instead of off_t when checking for overflow.
+
+2004-11-04  Richard Henderson  <rth@redhat.com>
+
+       * sysdeps/unix/sysv/linux/alpha/register-dump.h (regnames): Align.
+       (linefeed): Remove.
+       (register_dump): Rewrite to generate into a flat buffer instead
+       of into iovecs.
+
+2004-11-02  Jakub Jelinek  <jakub@redhat.com>
+
+       * debug/tst-chk1.c (ret): New volatile variable.
+       (CHK_FAIL_END): Remove redundant ret setting.
+       (do_test): Remote ret variable.
+
+2004-01-03  Paolo Bonzini  <bonzini@gnu.org>
+
+       * posix/regex_internal.h (__regfree) [!_LIBC]: Define to regfree.
+
+2004-11-03  Marcus Brinkmann  <marcus@gnu.org>
+
+       * sysdeps/generic/utime.c: Include <stddef.h>.
+
+       * sysdeps/generic/sysconf.c: Include <grp.h> and <pwd.h>.
+
+       * sysdeps/generic/tempname.c (__path_search): Add missing argument
+       TRY_TMPDIR.
+
+2004-11-02  Jakub Jelinek  <jakub@redhat.com>
+
+       * include/features.h (__USE_FORTIFY_LEVEL): Also set for Red Hat
+       GCC 3.4.x-RH >= 3.4.2-8.
+       * libio/bits/features.h (printf, fprintf, vprintf, vfprintf): For
+       GCC 3.4.x-RH use __builtin___{,v}{,f}printf_chk instead of
+       __{,v}{,f}printf_chk.
+       * debug/tst-chk1.c (do_test): Deal with GCC 3.4.x-RH not
+       being able to recognize subobjects.
+
 2004-10-31  Mariusz Mazur <mmazur@kernel.pl>
 
        * sysdeps/unix/sysv/linux/alpha/setregid.c: New file.
index ea3a782cdab2bd72f9988b879788864d54e5ebcf..dc70aa68c4fd4348c39248831d39d3e04b4a23e2 100644 (file)
@@ -452,12 +452,6 @@ link-libc = -Wl,-rpath-link=$(rpath-link) \
            $(common-objpfx)$(patsubst %,$(libtype.oS),c) $(gnulib)
 # This is how to find at build-time things that will be installed there.
 rpath-dirs = math elf dlfcn nss nis rt resolv crypt
-else
-ifneq (,$(filter aix aix%,$(config-os)))
-link-libc = $(common-objpfx)libc.a \
-           $(common-objpfx)$(patsubst %,$(libtype.oS),c) $(gnulib)
-rpath-dirs = math dlfcn nss nis rt resolv crypt
-endif
 endif
 rpath-link = \
 $(common-objdir):$(subst $(empty) ,:,$(patsubst ../$(subdir),.,$(rpath-dirs:%=$(common-objpfx)%)))
@@ -475,13 +469,6 @@ LDFLAGS-rpath-ORIGIN = -Wl,-rpath,'$$ORIGIN'
 LDFLAGS-soname-fname = -Wl,-soname,$(@F)
 LDFLAGS-rdynamic = -rdynamic
 LDFLAGS-Bsymbolic = -Bsymbolic
-else
-ifneq (,$(filter aix aix%,$(config-os)))
-LDFLAGS-rpath-ORIGIN =
-LDFLAGS-soname-fname =
-LDFLAGS-rdynamic = -Wl,-bdynamic
-LDFLAGS-Bsymbolic = -Wl,-bsymbolic
-endif
 endif
 
 # Choose the default search path for the dynamic linker based on
@@ -835,13 +822,6 @@ postclean-generated += soversions.mk soversions.i \
 before-compile += $(common-objpfx)gnu/lib-names.h
 ifeq ($(soversions.mk-done),t)
 $(common-objpfx)gnu/lib-names.h: $(common-objpfx)gnu/lib-names.stmp; @:
-ifneq (,$(findstring aix,$(config-os)))
-$(common-objpfx)gnu/lib-names.stmp: $(..)sysdeps/unix/sysv/aix/gnu/lib-names.h
-       $(make-target-directory)
-       @rm -f ${@:stmp=T} $@
-       @cp $(..)sysdeps/unix/sysv/aix/gnu/lib-names.h $(common-objpfx)gnu
-       touch $@
-else
 $(common-objpfx)gnu/lib-names.stmp: $(common-objpfx)soversions.mk
        $(make-target-directory)
        @rm -f ${@:stmp=T} $@
@@ -870,7 +850,6 @@ $(common-objpfx)gnu/lib-names.stmp: $(common-objpfx)soversions.mk
        $(move-if-change) ${@:stmp=T} ${@:stmp=h}
        touch $@
 endif
-endif
 
 common-generated += gnu/lib-names.h gnu/lib-names.stmp
 
index 27b4f1534662ad8dd51b6cd2187ab41bed58246e..9c9f82a3af9f51a9d83ee28cc0765d76b4dcd875 100644 (file)
@@ -51,6 +51,7 @@ do_prepare (void)
 }
 
 volatile int chk_fail_ok;
+volatile int ret;
 jmp_buf chk_fail_buf;
 
 static void
@@ -86,7 +87,6 @@ int num2 = 987654;
 #define CHK_FAIL_END \
       chk_fail_ok = 0;                         \
       FAIL ();                                 \
-      ret = 1;                                 \
     }
 #if __USE_FORTIFY_LEVEL >= 2
 #define CHK_FAIL2_START CHK_FAIL_START
@@ -99,7 +99,6 @@ int num2 = 987654;
 static int
 do_test (void)
 {
-  int ret = 0;
   struct sigaction sa;
   sa.sa_handler = handler;
   sa.sa_flags = 0;
index 88378a60a65a6cc0e45328708078b493ba678105..cfe01babbf1a29967a224f9db7473cc3b61d230b 100644 (file)
@@ -136,6 +136,8 @@ int (*_dl_make_stack_executable_hook) (void **) internal_function
 #ifdef NEED_DL_SYSINFO
 /* Needed for improved syscall handling on at least x86/Linux.  */
 uintptr_t _dl_sysinfo = DL_SYSINFO_DEFAULT;
+#endif
+#if defined NEED_DL_SYSINFO || defined NEED_DL_SYSINFO_DSO
 /* Address of the ELF headers in the vsyscall page.  */
 const ElfW(Ehdr) *_dl_sysinfo_dso;
 #endif
@@ -183,6 +185,11 @@ _dl_aux_init (ElfW(auxv_t) *av)
       case AT_SYSINFO:
        GL(dl_sysinfo) = av->a_un.a_val;
        break;
+#endif
+#if defined NEED_DL_SYSINFO || defined NEED_DL_SYSINFO_DSO
+      case AT_SYSINFO_EHDR:
+       GL(dl_sysinfo_dso) = av->a_un.a_ptr;
+       break;
 #endif
       case AT_UID:
        uid ^= av->a_un.a_val;
index 4adbb437bf46fce7214ec911ab9f2aa6922cef91..e53273c2bb2f592ed2468c91439df0d17bf50630 100644 (file)
@@ -1382,7 +1382,7 @@ ERROR: ld.so: object '%s' from %s cannot be preloaded: ignored.\n",
       assert (i == npreloads);
     }
 
-#ifdef NEED_DL_SYSINFO
+#if defined NEED_DL_SYSINFO || defined NEED_DL_SYSINFO_DSO
   struct link_map *sysinfo_map = NULL;
   if (GLRO(dl_sysinfo_dso) != NULL)
     {
@@ -1446,9 +1446,11 @@ ERROR: ld.so: object '%s' from %s cannot be preloaded: ignored.\n",
            }
 
          /* We have a prelinked DSO preloaded by the system.  */
+         sysinfo_map = l;
+# ifdef NEED_DL_SYSINFO
          if (GLRO(dl_sysinfo) == DL_SYSINFO_DEFAULT)
            GLRO(dl_sysinfo) = GLRO(dl_sysinfo_dso)->e_entry + l->l_addr;
-         sysinfo_map = l;
+# endif
        }
     }
 #endif
@@ -1497,7 +1499,7 @@ ERROR: ld.so: object '%s' from %s cannot be preloaded: ignored.\n",
          GL(dl_rtld_map).l_next = (i + 1 < main_map->l_searchlist.r_nlist
                                    ? main_map->l_searchlist.r_list[i + 1]
                                    : NULL);
-#ifdef NEED_DL_SYSINFO
+#if defined NEED_DL_SYSINFO || defined NEED_DL_SYSINFO_DSO
          if (sysinfo_map != NULL
              && GL(dl_rtld_map).l_prev->l_next == sysinfo_map
              && GL(dl_rtld_map).l_next != sysinfo_map)
index 24832500365592bc8ba78ac7c6124287feda4e45..b07840623ef80cc9f4115170f3f5e0fa5a95aa6d 100644 (file)
@@ -1,5 +1,5 @@
 # This file is updated automatically by Makefile.
 glibc-branch := fedora
 glibc-base := HEAD
-fedora-sync-date := 2004-11-02 11:53 UTC
-fedora-sync-tag := fedora-glibc-20041102T1153
+fedora-sync-date := 2004-11-10 08:39 UTC
+fedora-sync-tag := fedora-glibc-20041110T0839
index 7dfa25a4f90c589b83ddd310812a1115a5fc2ca7..735419c94a6a2972049be7e44deeb7fabc3c2b97 100644 (file)
@@ -1,4 +1,4 @@
-%define glibcrelease 75
+%define glibcrelease 76
 %define auxarches i586 i686 athlon sparcv9 alphaev6
 %define prelinkarches noarch
 %define nptlarches i386 i686 athlon x86_64 ia64 s390 s390x sparcv9 ppc ppc64
@@ -1256,9 +1256,17 @@ rm -f *.filelist*
 %endif
 
 %changelog
+* Wed Nov 10 2004 Jakub Jelinek <jakub@redhat.com> 2.3.3-76
+- update from CVS
+  - fix regcomp crash (#138439)
+  - fix ftell{,o,o64} (#137885)
+  - robustification of nscd to cope with corrupt databases (#137140)
+  - fix NPTL with pthread_exit immediately after pthread_create (BZ #530)
+  - some regex optimizations
+
 * Tue Nov  2 2004 Jakub Jelinek <jakub@redhat.com> 2.3.3-75
 - update from CVS
-  - mktime cleanups (BZ #487, #473
+  - mktime cleanups (BZ #487, #473)
   - unique comments in free(3) check error messages
 - adjust some x86_64 headers for -m32 (#129712)
 - object size checking support even with GCC-3.4.2-RH >= 3.4.2-8
index a9384b55a9efd05b455bdafbcdeff46e58a3075e..1d7611d252abf2fc9299b5b70e76b125dd302bfc 100644 (file)
@@ -54,7 +54,7 @@ tests = tst_swprintf tst_wprintf tst_swscanf tst_wscanf tst_getwc tst_putwc   \
        tst-freopen bug-rewind bug-rewind2 bug-ungetc bug-fseek \
        tst-mmap-eofsync tst-mmap-fflushsync bug-mmap-fflush \
        tst-mmap2-eofsync tst-mmap-offend bug-fopena+ bug-wfflush \
-       bug-ungetc2 bug-ftell
+       bug-ungetc2 bug-ftell bug-ungetc3
 test-srcs = test-freopen
 
 all: # Make this the default target; it will be defined in Rules.
diff --git a/libio/bug-ungetc3.c b/libio/bug-ungetc3.c
new file mode 100644 (file)
index 0000000..0c83c11
--- /dev/null
@@ -0,0 +1,94 @@
+/* Test program for ungetc/ftell interaction bug.  */
+
+#include <stdio.h>
+
+static void do_prepare (void);
+#define PREPARE(argc, argv) do_prepare ()
+static int do_test (void);
+#define TEST_FUNCTION do_test ()
+#include "../test-skeleton.c"
+
+static const char pattern[] = "12345";
+static char *temp_file;
+
+static void
+do_prepare (void)
+{
+  int fd = create_temp_file ("bug-ungetc.", &temp_file);
+  if (fd == -1)
+    {
+      printf ("cannot create temporary file: %m\n");
+      exit (1);
+    }
+  write (fd, pattern, sizeof (pattern));
+  close (fd);
+}
+
+static int
+do_one_test (int mode)
+{
+  FILE *f;
+
+  f = fopen (temp_file, "r");
+  if (f == NULL)
+    {
+      printf ("could not open temporary file: %m\n");
+      return 1;
+    }
+
+  if (mode == 1 && ftell (f) != 0)
+    {
+      printf ("first ftell returned wrong position %ld\n", ftell (f));
+      return 1;
+    }
+
+  if (fgetc (f) != '1' || fgetc (f) != '2')
+    {
+      puts ("fgetc failed");
+      return 1;
+    }
+
+  if (mode == 2 && ftell (f) != 2)
+    {
+      printf ("second ftell returned wrong position %ld\n", ftell (f));
+      return 1;
+    }
+
+  if (ungetc ('6', f) != '6')
+    {
+      puts ("ungetc failed");
+      return 1;
+    }
+
+  if (ftell (f) != 1)
+    {
+      printf ("third ftell returned wrong position %ld\n", ftell (f));
+      return 1;
+    }
+
+  if (fgetc (f) != '6')
+    {
+      puts ("fgetc failed");
+      return 1;
+    }
+
+  if (ftell (f) != 2)
+    {
+      printf ("fourth ftell returned wrong position %ld\n", ftell (f));
+      return 1;
+    }
+
+  fclose (f);
+
+  return 0;
+}
+
+static int
+do_test (void)
+{
+  int mode;
+  for (mode = 0; mode <= 2; mode++)
+    if (do_one_test (mode))
+      return 1;
+  return 0;
+}
index 7d90cbaa2da6d93ad7e47a8a9d681c24d4e2d3dc..2d787d296f966d3ac199f79bd4bb7d8b05c987cb 100644 (file)
@@ -635,7 +635,7 @@ mmap_remap_check (_IO_FILE *fp)
        {
          /* The file added some pages.  We need to remap it.  */
          void *p;
-#if defined __linux__          /* XXX */
+#ifdef _G_HAVE_MREMAP
          p = __mremap (fp->_IO_buf_base, ROUNDED (fp->_IO_buf_end
                                                   - fp->_IO_buf_base),
                        ROUNDED (st.st_size), MREMAP_MAYMOVE);
@@ -989,7 +989,18 @@ _IO_new_file_seekoff (fp, offset, dir, mode)
       /* Adjust for read-ahead (bytes is buffer). */
       offset -= fp->_IO_read_end - fp->_IO_read_ptr;
       if (fp->_offset == _IO_pos_BAD)
-       goto dumb;
+        {
+          if (mode != 0)
+            goto dumb;
+          else
+            {
+              result = _IO_SYSSEEK (fp, 0, dir);
+              if (result == EOF)
+                return result;
+
+              fp->_offset = result;
+            }
+        }
       /* Make offset absolute, assuming current pointer is file_ptr(). */
       offset += fp->_offset;
       if (offset < 0)
index 4975a0bd73587484846901dd99fcf2a7bc23a35d..e58daacad417c81edb9bed6c2bc65f6e26e7df44 100644 (file)
@@ -1,4 +1,5 @@
-/* Copyright (C) 1993, 1995-2001, 2002, 2003 Free Software Foundation, Inc.
+/* Copyright (C) 1993, 1995-2001, 2002, 2003, 2004
+   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
@@ -39,7 +40,7 @@ ftello (fp)
   CHECK_FILE (fp, -1L);
   _IO_acquire_lock (fp);
   pos = _IO_seekoff_unlocked (fp, 0, _IO_seek_cur, 0);
-  if (_IO_in_backup (fp))
+  if (_IO_in_backup (fp) && pos != _IO_pos_BAD)
     {
       if (fp->_mode <= 0)
        pos -= fp->_IO_save_end - fp->_IO_save_base;
index 0275c0ca3598a400d60c8dbfff1fcf0dae28fa42..d39fc2d1b240696fd6eaedbf5681f8d2538aaec7 100644 (file)
@@ -1,4 +1,5 @@
-/* Copyright (C) 1993, 1995-2001, 2002, 2003 Free Software Foundation, Inc.
+/* Copyright (C) 1993, 1995-2001, 2002, 2003, 2004
+   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
@@ -40,7 +41,7 @@ ftello64 (fp)
   CHECK_FILE (fp, -1L);
   _IO_acquire_lock (fp);
   pos = _IO_seekoff_unlocked (fp, 0, _IO_seek_cur, 0);
-  if (_IO_in_backup (fp))
+  if (_IO_in_backup (fp) && pos != _IO_pos_BAD)
     {
       if (fp->_mode <= 0)
        pos -= fp->_IO_save_end - fp->_IO_save_base;
index aff39bbed45878b85a807df03ef810c1cede47a8..8b7ef9f34d047bffcae2fb00e7647e6f736a7f62 100644 (file)
@@ -1,4 +1,5 @@
-/* Copyright (C) 1993, 1995-2001, 2002, 2003 Free Software Foundation, Inc.
+/* Copyright (C) 1993, 1995-2001, 2002, 2003, 2004
+   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
@@ -40,7 +41,7 @@ _IO_new_fgetpos (fp, posp)
   CHECK_FILE (fp, EOF);
   _IO_acquire_lock (fp);
   pos = _IO_seekoff_unlocked (fp, 0, _IO_seek_cur, 0);
-  if (_IO_in_backup (fp))
+  if (_IO_in_backup (fp) && pos != _IO_pos_BAD)
     {
       if (fp->_mode <= 0)
        pos -= fp->_IO_save_end - fp->_IO_save_base;
index be224ca103a77040b5a7b6127e20854a3543449d..10446857e7d5dd0ecadad4ac1e4205141a1aa4d7 100644 (file)
@@ -1,4 +1,5 @@
-/* Copyright (C) 1993, 1995-2001, 2002, 2003 Free Software Foundation, Inc.
+/* Copyright (C) 1993, 1995-2001, 2002, 2003, 2004
+   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
@@ -41,7 +42,7 @@ _IO_new_fgetpos64 (fp, posp)
   CHECK_FILE (fp, EOF);
   _IO_acquire_lock (fp);
   pos = _IO_seekoff_unlocked (fp, 0, _IO_seek_cur, 0);
-  if (_IO_in_backup (fp))
+  if (_IO_in_backup (fp) && pos != _IO_pos_BAD)
     {
       if (fp->_mode <= 0)
        pos -= fp->_IO_save_end - fp->_IO_save_base;
index b991ef69ea2052d81e046d9dd426e916d3b84bbb..03e5f2840453f720c32132721d9cfcd1480f0f68 100644 (file)
@@ -1,4 +1,5 @@
-/* Copyright (C) 1993,1995-2000,2001,2002,2003 Free Software Foundation, Inc.
+/* Copyright (C) 1993, 1995-2000, 2001, 2002, 2003, 2004
+   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
@@ -38,7 +39,7 @@ _IO_ftell (fp)
   CHECK_FILE (fp, -1L);
   _IO_acquire_lock (fp);
   pos = _IO_seekoff_unlocked (fp, 0, _IO_seek_cur, 0);
-  if (_IO_in_backup (fp))
+  if (_IO_in_backup (fp) && pos != _IO_pos_BAD)
     {
       if (_IO_vtable_offset (fp) != 0 || fp->_mode <= 0)
        pos -= fp->_IO_save_end - fp->_IO_save_base;
@@ -52,7 +53,7 @@ _IO_ftell (fp)
 #endif
       return -1L;
     }
-  if ((_IO_off64_t) (off_t) pos != pos)
+  if ((_IO_off64_t) (long int) pos != pos)
     {
 #ifdef EOVERFLOW
       __set_errno (EOVERFLOW);
index fbac21bdd4ac717b02a84ba8923e504b6a7b224c..6b14e1970fced0bc7b9b11162d401bee1fef5a47 100644 (file)
@@ -42,7 +42,7 @@ _IO_old_fgetpos (fp, posp)
   CHECK_FILE (fp, EOF);
   _IO_acquire_lock (fp);
   pos = _IO_seekoff_unlocked (fp, 0, _IO_seek_cur, 0);
-  if (_IO_in_backup (fp))
+  if (_IO_in_backup (fp) && pos != _IO_pos_BAD)
     pos -= fp->_IO_save_end - fp->_IO_save_base;
   _IO_release_lock (fp);
   if (pos == _IO_pos_BAD)
index 996ad2075b5c470e0e3f552d022aacd7b6f5c311..1c1adb38840f2e670816e9900817146e6e1c1960 100644 (file)
@@ -43,7 +43,7 @@ _IO_old_fgetpos64 (fp, posp)
   CHECK_FILE (fp, EOF);
   _IO_acquire_lock (fp);
   pos = _IO_seekoff_unlocked (fp, 0, _IO_seek_cur, 0);
-  if (_IO_in_backup (fp))
+  if (_IO_in_backup (fp) && pos != _IO_pos_BAD)
     pos -= fp->_IO_save_end - fp->_IO_save_base;
   _IO_release_lock (fp);
   if (pos == _IO_pos_BAD)
index 31be4c37bbd3da659651464b2dc2c1f83fe82c9c..98df5cf228a0e4e1792c7a21e609fbe31919f0b0 100644 (file)
@@ -1,3 +1,28 @@
+2004-11-10  Jakub Jelinek  <jakub@redhat.com>
+
+       * Makefile (tests): Add tst-exit3.
+       * tst-exit3.c: New test.
+
+2004-11-09  Ulrich Drepper  <drepper@redhat.com>
+
+       * Makefile (tests): Add tst-exit2.
+       * tst-exit2.c: New file.
+
+2004-11-09  Roland McGrath  <roland@redhat.com>
+
+       [BZ #530]
+       * sysdeps/pthread/createthread.c (do_clone): Increment __nptl_nthreads
+       here, before calling clone.
+       * pthread_create.c (start_thread): Don't do it here.
+
+2004-11-04  Roland McGrath  <roland@redhat.com>
+
+       * sysdeps/unix/sysv/linux/pthread_getcpuclockid.c: New file.
+
+2004-11-02  Jakub Jelinek  <jakub@redhat.com>
+
+       * sysdeps/unix/sysv/linux/smp.h: Include <errno.h>.
+
 2004-10-29  Kaz  Kojima  <kkojima@rr.iij4u.or.jp>
 
        * sysdeps/unix/sysv/linux/sh/sem_timedwait.S (sem_timedwait):
index f39e0bd303d7527b8a26317a9aaf5d6c14b35da9..564eaca6c52f939275e90c14fa646af316a9b445 100644 (file)
@@ -227,7 +227,7 @@ tests = tst-attr1 tst-attr2 tst-attr3 \
        tst-signal1 tst-signal2 tst-signal3 tst-signal4 tst-signal5 \
        tst-signal6 \
        tst-exec1 tst-exec2 tst-exec3 tst-exec4 \
-       tst-exit1 \
+       tst-exit1 tst-exit2 tst-exit3 \
        tst-stdio1 tst-stdio2 \
        tst-stack1 tst-stack2 tst-stack3 \
        tst-unload \
index 7293f4c71cf5262094f4f5f89878e984ded9343f..82a3c683aaaf0df6bfabf7d7553edabe1672636a 100644 (file)
@@ -222,9 +222,6 @@ __free_tcb (struct pthread *pd)
 static int
 start_thread (void *arg)
 {
-  /* One more thread.  */
-  atomic_increment (&__nptl_nthreads);
-
   struct pthread *pd = (struct pthread *) arg;
 
 #if HP_TIMING_AVAIL
index 8620519887b33f618f2f792eee7e4fa6bab8548b..25a2703ae139581bebbcd805bddc312ac27f3540 100644 (file)
@@ -64,9 +64,21 @@ do_clone (struct pthread *pd, const struct pthread_attr *attr,
        until we tell it to.  */
     lll_lock (pd->lock);
 
+  /* One more thread.  We cannot have the thread do this itself, since it
+     might exist but not have been scheduled yet by the time we've returned
+     and need to check the value to behave correctly.  We must do it before
+     creating the thread, in case it does get scheduled first and then
+     might mistakenly think it was the only thread.  In the failure case,
+     we momentarily store a false value; this doesn't matter because there
+     is no kosher thing a signal handler interrupting us right here can do
+     that cares whether the thread count is correct.  */
+  atomic_increment (&__nptl_nthreads);
+
   if (ARCH_CLONE (fct, STACK_VARIABLES_ARGS, clone_flags,
                  pd, &pd->tid, TLS_VALUE, &pd->tid) == -1)
     {
+      atomic_decrement (&__nptl_nthreads); /* Oops, we lied for a second.  */
+
       /* Failed.  If the thread is detached, remove the TCB here since
         the caller cannot do this.  The caller remembered the thread
         as detached and cannot reverify that it is not since it must
diff --git a/nptl/tst-exit2.c b/nptl/tst-exit2.c
new file mode 100644 (file)
index 0000000..3f5ff27
--- /dev/null
@@ -0,0 +1,40 @@
+#include <pthread.h>
+#include <signal.h>
+#include <stdio.h>
+#include <string.h>
+#include <unistd.h>
+
+
+static void *
+tf (void *arg)
+{
+  while (1)
+    sleep (100);
+
+  /* NOTREACHED */
+  return NULL;
+}
+
+
+static int
+do_test (void)
+{
+  pthread_t th;
+
+  int e = pthread_create (&th, NULL, tf, NULL);
+  if (e != 0)
+    {
+      printf ("create failed: %s\n", strerror (e));
+      return 1;
+    }
+
+  /* Terminate only this thread.  */
+  pthread_exit (NULL);
+
+  /* NOTREACHED */
+  return 1;
+}
+
+#define EXPECTED_SIGNAL SIGALRM
+#define TEST_FUNCTION do_test ()
+#include "../test-skeleton.c"
diff --git a/nptl/tst-exit3.c b/nptl/tst-exit3.c
new file mode 100644 (file)
index 0000000..da92c82
--- /dev/null
@@ -0,0 +1,81 @@
+#include <pthread.h>
+#include <signal.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+
+static pthread_barrier_t b;
+
+
+static void *
+tf2 (void *arg)
+{
+  while (1)
+    sleep (100);
+
+  /* NOTREACHED */
+  return NULL;
+}
+
+
+static void *
+tf (void *arg)
+{
+  pthread_t th;
+
+  int e = pthread_barrier_wait (&b);
+  if (e != 0 && e != PTHREAD_BARRIER_SERIAL_THREAD)
+    {
+      puts ("barrier_wait failed");
+      exit (1);
+    }
+
+  e = pthread_create (&th, NULL, tf2, NULL);
+  if (e != 0)
+    {
+      printf ("create failed: %s\n", strerror (e));
+      exit (1);
+    }
+
+  /* Terminate only this thread.  */
+  return NULL;
+}
+
+
+static int
+do_test (void)
+{
+  pthread_t th;
+
+  if (pthread_barrier_init (&b, NULL, 2) != 0)
+    {
+      puts ("barrier_init failed");
+      exit (1);
+    }
+
+  int e = pthread_create (&th, NULL, tf, NULL);
+  if (e != 0)
+    {
+      printf ("create failed: %s\n", strerror (e));
+      exit (1);
+    }
+
+  e = pthread_barrier_wait (&b);
+  if (e != 0 && e != PTHREAD_BARRIER_SERIAL_THREAD)
+    {
+      puts ("barrier_wait failed");
+      exit (1);
+    }
+
+  /* Terminate only this thread.  */
+  pthread_exit (NULL);
+
+  /* NOTREACHED */
+  return 1;
+}
+
+#define EXPECTED_SIGNAL SIGALRM
+#define TEST_FUNCTION do_test ()
+#include "../test-skeleton.c"
index 2e7f27b8d56da4ab8b7ad3a7957c9dd59760bb0e..d49cb8136ce158300e6247582d125a4ed685fff1 100644 (file)
@@ -264,7 +264,7 @@ struct locked_map_ptr
   int lock;
   struct mapped_database *mapped;
 };
-#define libc_locked_map_ptr(name) static struct locked_map_ptr name
+#define libc_locked_map_ptr(class, name) class struct locked_map_ptr name
 
 
 /* Open socket connection to nscd server.  */
index a683976d87b6e0eac3918eac6a2a65dd4b7b05be..f0b2082baad4c9af4b7e7c4ca4f7514dd09627cd 100644 (file)
 extern int __nss_not_use_nscd_hosts;
 
 
-libc_locked_map_ptr (map_handle);
-/* Note that we only free the structure if necessary.  The memory
-   mapping is not removed since it is not visible to the malloc
-   handling.  */
-libc_freeres_fn (ai_map_free)
-{
-  if (map_handle.mapped != NO_MAPPING)
-    free (map_handle.mapped);
-}
+/* We use the mapping from nscd_gethst.  */
+libc_locked_map_ptr (extern, __hst_map_handle);
 
 
 int
@@ -53,7 +46,8 @@ __nscd_getai (const char *key, struct nscd_ai_result **result, int *h_errnop)
   /* If the mapping is available, try to search there instead of
      communicating with the nscd.  */
   struct mapped_database *mapped;
-  mapped = __nscd_get_map_ref (GETFDHST, "hosts", &map_handle, &gc_cycle);
+  mapped = __nscd_get_map_ref (GETFDHST, "hosts", &__hst_map_handle,
+                              &gc_cycle);
 
  retry:;
   const ai_response_header *ai_resp = NULL;
@@ -142,6 +136,12 @@ __nscd_getai (const char *key, struct nscd_ai_result **result, int *h_errnop)
          /* Copy the data in the block.  */
          memcpy (resultbuf + 1, respdata, datalen);
 
+         /* Try to detect corrupt databases.  */
+         if (resultbuf->canon != NULL
+             && resultbuf->canon[ai_resp->canonlen - 1] != '\0')
+           /* We cannot use the database.  */
+           goto out_close;
+
          retval = 0;
          *result = resultbuf;
        }
@@ -157,6 +157,7 @@ __nscd_getai (const char *key, struct nscd_ai_result **result, int *h_errnop)
       retval = 0;
     }
 
+ out_close:
   if (sock != -1)
     close_not_cancel_no_status (sock);
  out:
index 1b94bf584fece32e667f0aac52daf0291e8c9a00..282912db3e5dee8d731ceadc44c38ef0426f1528 100644 (file)
@@ -67,14 +67,18 @@ __nscd_getgrgid_r (gid_t gid, struct group *resultbuf, char *buffer,
 }
 
 
-libc_locked_map_ptr (map_handle);
+libc_locked_map_ptr (,__gr_map_handle);
 /* Note that we only free the structure if necessary.  The memory
    mapping is not removed since it is not visible to the malloc
    handling.  */
 libc_freeres_fn (gr_map_free)
 {
-  if (map_handle.mapped != NO_MAPPING)
-    free (map_handle.mapped);
+  if (__gr_map_handle.mapped != NO_MAPPING)
+    {
+      void *p = __gr_map_handle.mapped;
+      __gr_map_handle.mapped = NO_MAPPING;
+      free (p);
+    }
 }
 
 
@@ -91,7 +95,8 @@ nscd_getgr_r (const char *key, size_t keylen, request_type type,
   /* If the mapping is available, try to search there instead of
      communicating with the nscd.  */
   struct mapped_database *mapped = __nscd_get_map_ref (GETFDGR, "group",
-                                                      &map_handle, &gc_cycle);
+                                                      &__gr_map_handle,
+                                                      &gc_cycle);
  retry:;
   const gr_response_header *gr_resp = NULL;
   const char *gr_name = NULL;
@@ -204,7 +209,8 @@ nscd_getgr_r (const char *key, size_t keylen, request_type type,
       else
        /* We already have the data.  Just copy the group name and
           password.  */
-       memcpy (resultbuf->gr_name, gr_name, gr_name_len);
+       memcpy (resultbuf->gr_name, gr_name,
+               gr_resp->gr_name_len + gr_resp->gr_passwd_len);
 
       /* Clear the terminating entry.  */
       resultbuf->gr_mem[gr_resp->gr_mem_cnt] = NULL;
@@ -242,6 +248,19 @@ nscd_getgr_r (const char *key, size_t keylen, request_type type,
          /* Copy the group member names.  */
          memcpy (resultbuf->gr_mem[0], gr_name + gr_name_len, total_len);
 
+         /* Try to detect corrupt databases.  */
+         if (resultbuf->gr_name[gr_name_len - 1] != '\0'
+             || resultbuf->gr_passwd[gr_resp->gr_passwd_len - 1] != '\0'
+             || ({for (cnt = 0; cnt < gr_resp->gr_mem_cnt; ++cnt)
+                    if (resultbuf->gr_mem[cnt][len[cnt] - 1] != '\0')
+                      break;
+                  cnt < gr_resp->gr_mem_cnt; }))
+           {
+             /* We cannot use the database.  */
+             retval = -1;
+             goto out_close;
+           }
+
          *result = resultbuf;
        }
     }
index 407be1441f17be4c5c486eb8ecfde585431a314f..5d9d569107a8f43c74bea9898e52f0b01a2c46bb 100644 (file)
@@ -87,14 +87,18 @@ __nscd_gethostbyaddr_r (const void *addr, socklen_t len, int type,
 }
 
 
-libc_locked_map_ptr (map_handle);
+libc_locked_map_ptr (, __hst_map_handle);
 /* Note that we only free the structure if necessary.  The memory
    mapping is not removed since it is not visible to the malloc
    handling.  */
-libc_freeres_fn (gr_map_free)
+libc_freeres_fn (hst_map_free)
 {
-  if (map_handle.mapped != NO_MAPPING)
-    free (map_handle.mapped);
+  if (__hst_map_handle.mapped != NO_MAPPING)
+    {
+      void *p = __hst_map_handle.mapped;
+      __hst_map_handle.mapped = NO_MAPPING;
+      free (p);
+    }
 }
 
 
@@ -110,7 +114,8 @@ nscd_gethst_r (const char *key, size_t keylen, request_type type,
   /* If the mapping is available, try to search there instead of
      communicating with the nscd.  */
   struct mapped_database *mapped;
-  mapped = __nscd_get_map_ref (GETFDHST, "hosts", &map_handle, &gc_cycle);
+  mapped = __nscd_get_map_ref (GETFDHST, "hosts", &__hst_map_handle,
+                              &gc_cycle);
 
  retry:;
   const hst_response_header *hst_resp = NULL;
@@ -336,6 +341,16 @@ nscd_gethst_r (const char *key, size_t keylen, request_type type,
          memcpy (resultbuf->h_aliases[0],
                  (const char *) addr_list + addr_list_len, total_len);
 
+         /* Try to detect corrupt databases.  */
+         if (resultbuf->h_name[hst_resp->h_name_len - 1] != '\0'
+             || ({for (cnt = 0; cnt < hst_resp->h_aliases_cnt; ++cnt)
+                    if (resultbuf->h_aliases[cnt][aliases_len[cnt] - 1]
+                        != '\0')
+                      break;
+                  cnt < hst_resp->h_aliases_cnt; }))
+           /* We cannot use the database.  */
+           goto out_close;
+
          retval = 0;
          *result = resultbuf;
        }
index b04dcfaa9933fcb4d67d6fa8995665fa2e7d9c36..fe5fb43ca1001265125450b82deb1b0ace80f1b1 100644 (file)
@@ -66,14 +66,18 @@ __nscd_getpwuid_r (uid_t uid, struct passwd *resultbuf, char *buffer,
 }
 
 
-libc_locked_map_ptr (map_handle);
+libc_locked_map_ptr (static, map_handle);
 /* Note that we only free the structure if necessary.  The memory
    mapping is not removed since it is not visible to the malloc
    handling.  */
-libc_freeres_fn (gr_map_free)
+libc_freeres_fn (pw_map_free)
 {
   if (map_handle.mapped != NO_MAPPING)
-    free (map_handle.mapped);
+    {
+      void *p = map_handle.mapped;
+      map_handle.mapped = NO_MAPPING;
+      free (p);
+    }
 }
 
 
@@ -184,6 +188,18 @@ nscd_getpw_r (const char *key, size_t keylen, request_type type,
          /* Copy the various strings.  */
          memcpy (resultbuf->pw_name, pw_name, total);
 
+         /* Try to detect corrupt databases.  */
+         if (resultbuf->pw_name[pw_resp->pw_name_len - 1] != '\0'
+             || resultbuf->pw_passwd[pw_resp->pw_passwd_len - 1] != '\0'
+             || resultbuf->pw_gecos[pw_resp->pw_gecos_len - 1] != '\0'
+             || resultbuf->pw_dir[pw_resp->pw_dir_len - 1] != '\0'
+             || resultbuf->pw_shell[pw_resp->pw_shell_len - 1] != '\0')
+           {
+             /* We cannot use the database.  */
+             retval = -1;
+             goto out_close;
+           }
+
          *result = resultbuf;
        }
     }
index ce44f654d7ae16545fa4a8c83de1dbc94192f4a6..2ea9e7f86230934787aa7d70f98b6054f59ce583 100644 (file)
 #include "nscd_proto.h"
 
 
-libc_locked_map_ptr (map_handle);
-/* Note that we only free the structure if necessary.  The memory
-   mapping is not removed since it is not visible to the malloc
-   handling.  */
-libc_freeres_fn (gr_map_free)
-{
-  if (map_handle.mapped != NO_MAPPING)
-    free (map_handle.mapped);
-}
+/* We use the same mapping as in nscd_getgr.   */
+libc_locked_map_ptr (extern, __gr_map_handle);
 
 
 int
@@ -50,7 +43,7 @@ __nscd_getgrouplist (const char *user, gid_t group, long int *size,
   /* If the mapping is available, try to search there instead of
      communicating with the nscd.  */
   struct mapped_database *mapped;
-  mapped = __nscd_get_map_ref (GETFDGR, "group", &map_handle, &gc_cycle);
+  mapped = __nscd_get_map_ref (GETFDGR, "group", &__gr_map_handle, &gc_cycle);
 
  retry:;
   const initgr_response_header *initgr_resp = NULL;
index 9b435a885e53ac14f408c3ffd461ab0484d4747b..ba7a1cc5d47a69718ced643cbba6b466eb5ecb2d 100644 (file)
@@ -566,6 +566,23 @@ weak_alias (__regerror, regerror)
 #endif
 
 
+#ifdef RE_ENABLE_I18N
+/* This static array is used for the map to single-byte characters when
+   UTF-8 is used.  Otherwise we would allocate memory just to initialize
+   it the same all the time.  UTF-8 is the preferred encoding so this is
+   a worthwhile optimization.  */
+static const bitset utf8_sb_map =
+{
+  /* Set the first 128 bits.  */
+# if UINT_MAX == 0xffffffff
+  0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff
+# else
+#  error "Add case for new unsigned int size"
+# endif
+};
+#endif
+
+
 static void
 free_dfa_content (re_dfa_t *dfa)
 {
@@ -613,7 +630,8 @@ free_dfa_content (re_dfa_t *dfa)
       }
   re_free (dfa->state_table);
 #ifdef RE_ENABLE_I18N
-  re_free (dfa->sb_char);
+  if (dfa->sb_char != utf8_sb_map)
+    re_free (dfa->sb_char);
 #endif
 #ifdef DEBUG
   re_free (dfa->re_str);
@@ -824,6 +842,9 @@ init_dfa (dfa, pat_len)
      int pat_len;
 {
   int table_size;
+#ifndef _LIBC
+  char *codeset_name;
+#endif
 
   memset (dfa, '\0', sizeof (re_dfa_t));
 
@@ -853,22 +874,59 @@ init_dfa (dfa, pat_len)
     dfa->is_utf8 = 1;
   dfa->map_notascii = (_NL_CURRENT_WORD (LC_CTYPE, _NL_CTYPE_MAP_TO_NONASCII)
                       != 0);
+#else
+# ifdef HAVE_LANGINFO_CODESET
+  codeset_name = nl_langinfo (CODESET);
+# else
+  codeset_name = getenv ("LC_ALL");
+  if (codeset_name == NULL || codeset[0] == '\0')
+    codeset_name = getenv ("LC_CTYPE");
+  if (codeset_name == NULL || codeset[0] == '\0')
+    codeset_name = getenv ("LANG");
+  if (codeset_name == NULL)
+    codeset_name = "";
+  else if (strchr (codeset_name, '.') !=  NULL)
+    codeset_name = strchr (codeset_name, '.') + 1;
+# endif
+
+  if (strcasecmp (codeset_name, "UTF-8") == 0
+      || strcasecmp (codeset_name, "UTF8") == 0)
+    dfa->is_utf8 = 1;
+
+  /* We check exhaustively in the loop below if this charset is a
+     superset of ASCII.  */
+  dfa->map_notascii = 0;
 #endif
+
 #ifdef RE_ENABLE_I18N
   if (dfa->mb_cur_max > 1)
     {
-      int i, j, ch;
-
-      dfa->sb_char = (re_bitset_ptr_t) calloc (sizeof (bitset), 1);
-      if (BE (dfa->sb_char == NULL, 0))
-       return REG_ESPACE;
       if (dfa->is_utf8)
-       memset (dfa->sb_char, 255, sizeof (unsigned int) * BITSET_UINTS / 2);
+       dfa->sb_char = (re_bitset_ptr_t) utf8_sb_map;
       else
-       for (i = 0, ch = 0; i < BITSET_UINTS; ++i)
-         for (j = 0; j < UINT_BITS; ++j, ++ch)
-           if (__btowc (ch) != WEOF)
-             dfa->sb_char[i] |= 1 << j;
+       {
+         int i, j, ch;
+
+         dfa->sb_char = (re_bitset_ptr_t) calloc (sizeof (bitset), 1);
+         if (BE (dfa->sb_char == NULL, 0))
+           return REG_ESPACE;
+
+         /* Clear all bits by, then set those corresponding to single
+            byte chars.  */
+         bitset_empty (dfa->sb_char);
+
+         for (i = 0, ch = 0; i < BITSET_UINTS; ++i)
+           for (j = 0; j < UINT_BITS; ++j, ++ch)
+             {
+               wchar_t wch = __btowc (ch);
+               if (wch != WEOF)
+                 dfa->sb_char[i] |= 1 << j;
+# ifndef _LIBC
+               if (isascii (ch) && wch != (wchar_t) ch)
+                 dfa->map_notascii = 1;
+# endif
+             }
+       }
     }
 #endif
 
@@ -1544,7 +1602,9 @@ calc_eclosure_iter (new_set, dfa, node, root)
                ? dfa->nodes[node].opr.ctx_type : 0);
   /* If the current node has constraints, duplicate all nodes.
      Since they must inherit the constraints.  */
-  if (constraint && !dfa->nodes[dfa->edests[node].elems[0]].duplicated)
+  if (constraint
+      && dfa->edests[node].nelem
+      && !dfa->nodes[dfa->edests[node].elems[0]].duplicated)
     {
       int org_node, cur_node;
       org_node = cur_node = node;
index 96f113745f0ab8d63d07c6cb80feb0ee99a15d0a..609719f79cecd6109259d94dce8647ff3d3865f0 100644 (file)
@@ -293,9 +293,8 @@ build_wcs_upper_buffer (pstr)
   byte_idx = pstr->valid_len;
   end_idx = (pstr->bufs_len > pstr->len) ? pstr->len : pstr->bufs_len;
 
-#ifdef _LIBC
-  /* The following optimization assumes that the wchar_t encoding is
-     always ISO 10646.  */
+  /* The following optimization assumes that ASCII characters can be
+     mapped to wide characters with a simple cast.  */
   if (! pstr->map_notascii && pstr->trans == NULL && !pstr->offsets_needed)
     {
       while (byte_idx < end_idx)
@@ -309,8 +308,7 @@ build_wcs_upper_buffer (pstr)
              pstr->mbs[byte_idx]
                = toupper (pstr->raw_mbs[pstr->raw_mbs_idx + byte_idx]);
              /* The next step uses the assumption that wchar_t is encoded
-                with ISO 10646: all ASCII values can be converted like
-                this.  */
+                ASCII-safe: all ASCII values can be converted like this.  */
              pstr->wcs[byte_idx] = (wchar_t) pstr->mbs[byte_idx];
              ++byte_idx;
              continue;
@@ -368,14 +366,11 @@ build_wcs_upper_buffer (pstr)
       return REG_NOERROR;
     }
   else
-#endif
     for (src_idx = pstr->valid_raw_len; byte_idx < end_idx;)
       {
        wchar_t wc;
        const char *p;
-#ifdef _LIBC
-offsets_needed:
-#endif
+      offsets_needed:
        remain_len = end_idx - byte_idx;
        prev_st = pstr->cur_state;
        if (BE (pstr->trans != NULL, 0))
@@ -647,7 +642,6 @@ re_string_reconstruct (pstr, idx, eflags)
              int wcs_idx;
              wint_t wc = WEOF;
 
-#ifdef _LIBC
              if (pstr->is_utf8)
                {
                  const unsigned char *raw, *p, *q, *end;
@@ -687,7 +681,7 @@ re_string_reconstruct (pstr, idx, eflags)
                        break;
                      }
                }
-#endif
+
              if (wc == WEOF)
                pstr->valid_len = re_string_skip_chars (pstr, idx, &wc) - idx;
              if (BE (pstr->valid_len, 0))
index d7d7d9a8b11b97c26417dc0f1116082f7eb47a84..023056c0282793c10f68e5ed1d373c8dd59d07bd 100644 (file)
@@ -27,6 +27,9 @@
 #include <stdlib.h>
 #include <string.h>
 
+#if defined HAVE_LANGINFO_H || defined HAVE_LANGINFO_CODESET || defined _LIBC
+# include <langinfo.h>
+#endif
 #if defined HAVE_LOCALE_H || defined _LIBC
 # include <locale.h>
 #endif
 # define __btowc btowc
 # define __mempcpy mempcpy
 # define __wcrtomb wcrtomb
+# define __regfree regfree
 # define attribute_hidden
 #endif /* not _LIBC */
 
@@ -544,7 +548,9 @@ struct re_backref_cache_entry
   int str_idx;
   int subexp_from;
   int subexp_to;
-  int flag;
+  /* We need only one byte from the following field.  If other small
+     fields are added the type could be changed to 'char'.  */
+  int more;
 };
 
 typedef struct
@@ -576,17 +582,11 @@ typedef struct
 
 typedef struct
 {
-  int cur_bkref;
-  int cls_subexp_idx;
-
   re_dfastate_t **sifted_states;
   re_dfastate_t **limited_states;
-
-  re_node_set limits;
-
   int last_node;
   int last_str_idx;
-  int check_subexp;
+  re_node_set limits;
 } re_sift_context_t;
 
 struct re_fail_stack_ent_t
index b7b5b1a6d4e63b4385c088478c1f1d786927d5e0..72ae70b9164bd457c9c8fc12b7afe708b69ca5f9 100644 (file)
@@ -29,7 +29,6 @@ static reg_errcode_t match_ctx_add_entry (re_match_context_t *cache, int node,
      internal_function;
 static int search_cur_bkref_entry (re_match_context_t *mctx, int str_idx)
      internal_function;
-static void match_ctx_clear_flag (re_match_context_t *mctx) internal_function;
 static reg_errcode_t match_ctx_add_subtop (re_match_context_t *mctx, int node,
                                           int str_idx) internal_function;
 static re_sub_match_last_t * match_ctx_add_sublast (re_sub_match_top_t *subtop,
@@ -37,7 +36,7 @@ static re_sub_match_last_t * match_ctx_add_sublast (re_sub_match_top_t *subtop,
      internal_function;
 static void sift_ctx_init (re_sift_context_t *sctx, re_dfastate_t **sifted_sts,
                           re_dfastate_t **limited_sts, int last_node,
-                          int last_str_idx, int check_subexp)
+                          int last_str_idx)
      internal_function;
 static reg_errcode_t re_search_internal (const regex_t *preg,
                                         const char *string, int length,
@@ -94,6 +93,9 @@ static int sift_states_iter_mb (const re_match_context_t *mctx,
 #endif /* RE_ENABLE_I18N */
 static reg_errcode_t sift_states_backward (re_match_context_t *mctx,
                                           re_sift_context_t *sctx) internal_function;
+static reg_errcode_t build_sifted_states (re_match_context_t *mctx,
+                                         re_sift_context_t *sctx, int str_idx,
+                                         re_node_set *cur_dest) internal_function;
 static reg_errcode_t update_cur_sifted_state (re_match_context_t *mctx,
                                              re_sift_context_t *sctx,
                                              int str_idx,
@@ -107,9 +109,13 @@ static reg_errcode_t sub_epsilon_src_nodes (re_dfa_t *dfa, int node,
 static int check_dst_limits (re_match_context_t *mctx, re_node_set *limits,
                             int dst_node, int dst_idx, int src_node,
                             int src_idx) internal_function;
+static int check_dst_limits_calc_pos_1 (re_match_context_t *mctx,
+                                       int boundaries, int subexp_idx,
+                                       int from_node, int bkref_idx) internal_function;
 static int check_dst_limits_calc_pos (re_match_context_t *mctx,
-                                     int limit, re_node_set *eclosures,
-                                     int subexp_idx, int node, int str_idx) internal_function;
+                                     int limit, int subexp_idx,
+                                     int node, int str_idx,
+                                     int bkref_idx) internal_function;
 static reg_errcode_t check_subexp_limits (re_dfa_t *dfa,
                                          re_node_set *dest_nodes,
                                          const re_node_set *candidates,
@@ -118,7 +124,7 @@ static reg_errcode_t check_subexp_limits (re_dfa_t *dfa,
                                          int str_idx) internal_function;
 static reg_errcode_t sift_states_bkref (re_match_context_t *mctx,
                                        re_sift_context_t *sctx,
-                                       int str_idx, re_node_set *dest_nodes) internal_function;
+                                       int str_idx, const re_node_set *candidates) internal_function;
 static reg_errcode_t clean_state_log_if_needed (re_match_context_t *mctx,
                                                int next_state_log_idx) internal_function;
 static reg_errcode_t merge_state_array (re_dfa_t *dfa, re_dfastate_t **dst,
@@ -170,8 +176,7 @@ static reg_errcode_t check_arrival_expand_ecl_sub (re_dfa_t *dfa,
                                                   int type) internal_function;
 static reg_errcode_t expand_bkref_cache (re_match_context_t *mctx,
                                         re_node_set *cur_nodes, int cur_str,
-                                        int last_str, int subexp_num,
-                                        int type) internal_function;
+                                        int subexp_num, int type) internal_function;
 static re_dfastate_t **build_trtable (re_dfa_t *dfa,
                                      re_dfastate_t *state) internal_function;
 #ifdef RE_ENABLE_I18N
@@ -578,8 +583,6 @@ re_exec (s)
 }
 #endif /* _REGEX_RE_COMP */
 \f
-static re_node_set empty_set;
-
 /* Internal entry point.  */
 
 /* Searches for a compiled pattern PREG in the string STRING, whose
@@ -642,8 +645,6 @@ re_search_internal (preg, string, length, start, range, stop, nmatch, pmatch,
       start = range = 0;
     }
 
-  re_node_set_init_empty (&empty_set);
-
   /* We must check the longest matching, if nmatch > 0.  */
   fl_longest_match = (nmatch != 0 || dfa->nbackref);
 
@@ -910,9 +911,8 @@ prune_impossible_nodes (mctx)
        {
          memset (lim_states, '\0',
                  sizeof (re_dfastate_t *) * (match_last + 1));
-         match_ctx_clear_flag (mctx);
          sift_ctx_init (&sctx, sifted_states, lim_states, halt_node,
-                        match_last, 0);
+                        match_last);
          ret = sift_states_backward (mctx, &sctx);
          re_node_set_free (&sctx.limits);
          if (BE (ret != REG_NOERROR, 0))
@@ -942,8 +942,7 @@ prune_impossible_nodes (mctx)
     }
   else
     {
-      sift_ctx_init (&sctx, sifted_states, lim_states, halt_node,
-                    match_last, 0);
+      sift_ctx_init (&sctx, sifted_states, lim_states, halt_node, match_last);
       ret = sift_states_backward (mctx, &sctx);
       re_node_set_free (&sctx.limits);
       if (BE (ret != REG_NOERROR, 0))
@@ -1496,17 +1495,14 @@ sift_states_backward (mctx, sctx)
      re_match_context_t *mctx;
      re_sift_context_t *sctx;
 {
-  re_dfa_t *const dfa = mctx->dfa;
   reg_errcode_t err;
   int null_cnt = 0;
   int str_idx = sctx->last_str_idx;
   re_node_set cur_dest;
-  re_node_set *cur_src; /* Points the state_log[str_idx]->nodes  */
 
 #ifdef DEBUG
   assert (mctx->state_log != NULL && mctx->state_log[str_idx] != NULL);
 #endif
-  cur_src = &mctx->state_log[str_idx]->nodes;
 
   /* Build sifted state_log[str_idx].  It has the nodes which can epsilon
      transit to the last_node and the last_node itself.  */
@@ -1520,7 +1516,6 @@ sift_states_backward (mctx, sctx)
   /* Then check each states in the state_log.  */
   while (str_idx > 0)
     {
-      int i, ret;
       /* Update counters.  */
       null_cnt = (sctx->sifted_states[str_idx] == NULL) ? null_cnt + 1 : 0;
       if (null_cnt > mctx->max_mb_elem_len)
@@ -1532,56 +1527,12 @@ sift_states_backward (mctx, sctx)
        }
       re_node_set_empty (&cur_dest);
       --str_idx;
-      cur_src = ((mctx->state_log[str_idx] == NULL) ? &empty_set
-                : &mctx->state_log[str_idx]->nodes);
-
-      /* Then build the next sifted state.
-        We build the next sifted state on `cur_dest', and update
-        `sifted_states[str_idx]' with `cur_dest'.
-        Note:
-        `cur_dest' is the sifted state from `state_log[str_idx + 1]'.
-        `cur_src' points the node_set of the old `state_log[str_idx]'.  */
-      for (i = 0; i < cur_src->nelem; i++)
-       {
-         int prev_node = cur_src->elems[i];
-         int naccepted = 0;
-         re_token_type_t type = dfa->nodes[prev_node].type;
-
-         if (IS_EPSILON_NODE (type))
-           continue;
-#ifdef RE_ENABLE_I18N
-         /* If the node may accept `multi byte'.  */
-         if (ACCEPT_MB_NODE (type))
-           naccepted = sift_states_iter_mb (mctx, sctx, prev_node,
-                                            str_idx, sctx->last_str_idx);
-
-#endif /* RE_ENABLE_I18N */
-         /* We don't check backreferences here.
-            See update_cur_sifted_state().  */
-
-         if (!naccepted
-             && check_node_accept (mctx, dfa->nodes + prev_node, str_idx)
-             && STATE_NODE_CONTAINS (sctx->sifted_states[str_idx + 1],
-                                     dfa->nexts[prev_node]))
-           naccepted = 1;
-
-         if (naccepted == 0)
-           continue;
 
-         if (sctx->limits.nelem)
-           {
-             int to_idx = str_idx + naccepted;
-             if (check_dst_limits (mctx, &sctx->limits,
-                                   dfa->nexts[prev_node], to_idx,
-                                   prev_node, str_idx))
-               continue;
-           }
-         ret = re_node_set_insert (&cur_dest, prev_node);
-         if (BE (ret == -1, 0))
-           {
-             err = REG_ESPACE;
-             goto free_return;
-           }
+      if (mctx->state_log[str_idx])
+       {
+         err = build_sifted_states (mctx, sctx, str_idx, &cur_dest);
+          if (BE (err != REG_NOERROR, 0))
+           goto free_return;
        }
 
       /* Add all the nodes which satisfy the following conditions:
@@ -1598,6 +1549,66 @@ sift_states_backward (mctx, sctx)
   return err;
 }
 
+static reg_errcode_t
+build_sifted_states (mctx, sctx, str_idx, cur_dest)
+     re_match_context_t *mctx;
+     re_sift_context_t *sctx;
+     int str_idx;
+     re_node_set *cur_dest;
+{
+  re_dfa_t *const dfa = mctx->dfa;
+  re_node_set *cur_src = &mctx->state_log[str_idx]->nodes;
+  int i;
+
+  /* Then build the next sifted state.
+     We build the next sifted state on `cur_dest', and update
+     `sifted_states[str_idx]' with `cur_dest'.
+     Note:
+     `cur_dest' is the sifted state from `state_log[str_idx + 1]'.
+     `cur_src' points the node_set of the old `state_log[str_idx]'.  */
+  for (i = 0; i < cur_src->nelem; i++)
+    {
+      int prev_node = cur_src->elems[i];
+      int naccepted = 0;
+      re_token_type_t type = dfa->nodes[prev_node].type;
+      int ret;
+
+      if (IS_EPSILON_NODE (type))
+       continue;
+#ifdef RE_ENABLE_I18N
+      /* If the node may accept `multi byte'.  */
+      if (ACCEPT_MB_NODE (type))
+       naccepted = sift_states_iter_mb (mctx, sctx, prev_node,
+                                        str_idx, sctx->last_str_idx);
+#endif /* RE_ENABLE_I18N */
+
+      /* We don't check backreferences here.
+        See update_cur_sifted_state().  */
+      if (!naccepted
+         && check_node_accept (mctx, dfa->nodes + prev_node, str_idx)
+         && STATE_NODE_CONTAINS (sctx->sifted_states[str_idx + 1],
+                                 dfa->nexts[prev_node]))
+       naccepted = 1;
+
+      if (naccepted == 0)
+       continue;
+
+      if (sctx->limits.nelem)
+       {
+         int to_idx = str_idx + naccepted;
+         if (check_dst_limits (mctx, &sctx->limits,
+                               dfa->nexts[prev_node], to_idx,
+                               prev_node, str_idx))
+           continue;
+       }
+      ret = re_node_set_insert (cur_dest, prev_node);
+      if (BE (ret == -1, 0))
+       return REG_ESPACE;
+    }
+
+  return REG_NOERROR;
+}
+
 /* Helper functions.  */
 
 static reg_errcode_t
@@ -1665,36 +1676,39 @@ update_cur_sifted_state (mctx, sctx, str_idx, dest_nodes)
   re_dfa_t *const dfa = mctx->dfa;
   reg_errcode_t err;
   const re_node_set *candidates;
-  candidates = ((mctx->state_log[str_idx] == NULL) ? &empty_set
+  candidates = ((mctx->state_log[str_idx] == NULL) ? NULL
                : &mctx->state_log[str_idx]->nodes);
 
-  /* At first, add the nodes which can epsilon transit to a node in
-     DEST_NODE.  */
-  if (dest_nodes->nelem)
+  if (dest_nodes->nelem == 0)
+    sctx->sifted_states[str_idx] = NULL;
+  else
     {
-      err = add_epsilon_src_nodes (dfa, dest_nodes, candidates);
-      if (BE (err != REG_NOERROR, 0))
-       return err;
-    }
+      if (candidates)
+       {
+         /* At first, add the nodes which can epsilon transit to a node in
+            DEST_NODE.  */
+         err = add_epsilon_src_nodes (dfa, dest_nodes, candidates);
+         if (BE (err != REG_NOERROR, 0))
+           return err;
 
-  /* Then, check the limitations in the current sift_context.  */
-  if (dest_nodes->nelem && sctx->limits.nelem)
-    {
-      err = check_subexp_limits (dfa, dest_nodes, candidates, &sctx->limits,
-                                mctx->bkref_ents, str_idx);
+         /* Then, check the limitations in the current sift_context.  */
+         if (sctx->limits.nelem)
+           {
+             err = check_subexp_limits (dfa, dest_nodes, candidates, &sctx->limits,
+                                        mctx->bkref_ents, str_idx);
+             if (BE (err != REG_NOERROR, 0))
+               return err;
+           }
+       }
+
+      sctx->sifted_states[str_idx] = re_acquire_state (&err, dfa, dest_nodes);
       if (BE (err != REG_NOERROR, 0))
        return err;
     }
 
-  /* Update state_log.  */
-  sctx->sifted_states[str_idx] = re_acquire_state (&err, dfa, dest_nodes);
-  if (BE (sctx->sifted_states[str_idx] == NULL && err != REG_NOERROR, 0))
-    return err;
-
-  if ((mctx->state_log[str_idx] != NULL
-       && mctx->state_log[str_idx]->has_backref))
+  if (candidates && mctx->state_log[str_idx]->has_backref)
     {
-      err = sift_states_bkref (mctx, sctx, str_idx, dest_nodes);
+      err = sift_states_bkref (mctx, sctx, str_idx, candidates);
       if (BE (err != REG_NOERROR, 0))
        return err;
     }
@@ -1789,6 +1803,8 @@ check_dst_limits (mctx, limits, dst_node, dst_idx, src_node, src_idx)
   re_dfa_t *const dfa = mctx->dfa;
   int lim_idx, src_pos, dst_pos;
 
+  int dst_bkref_idx = search_cur_bkref_entry (mctx, dst_idx);
+  int src_bkref_idx = search_cur_bkref_entry (mctx, src_idx);
   for (lim_idx = 0; lim_idx < limits->nelem; ++lim_idx)
     {
       int subexp_idx;
@@ -1797,11 +1813,11 @@ check_dst_limits (mctx, limits, dst_node, dst_idx, src_node, src_idx)
       subexp_idx = dfa->nodes[ent->node].opr.idx - 1;
 
       dst_pos = check_dst_limits_calc_pos (mctx, limits->elems[lim_idx],
-                                          dfa->eclosures + dst_node,
-                                          subexp_idx, dst_node, dst_idx);
+                                          subexp_idx, dst_node, dst_idx,
+                                          dst_bkref_idx);
       src_pos = check_dst_limits_calc_pos (mctx, limits->elems[lim_idx],
-                                          dfa->eclosures + src_node,
-                                          subexp_idx, src_node, src_idx);
+                                          subexp_idx, src_node, src_idx,
+                                          src_bkref_idx);
 
       /* In case of:
         <src> <dst> ( <subexp> )
@@ -1816,27 +1832,14 @@ check_dst_limits (mctx, limits, dst_node, dst_idx, src_node, src_idx)
 }
 
 static int
-check_dst_limits_calc_pos (mctx, limit, eclosures, subexp_idx, from_node,
-                          str_idx)
+check_dst_limits_calc_pos_1 (mctx, boundaries, subexp_idx, from_node, bkref_idx)
      re_match_context_t *mctx;
-     re_node_set *eclosures;
-     int limit, subexp_idx, from_node, str_idx;
+     int boundaries, subexp_idx, from_node, bkref_idx;
 {
   re_dfa_t *const dfa = mctx->dfa;
-  struct re_backref_cache_entry *lim = mctx->bkref_ents + limit;
+  re_node_set *eclosures = dfa->eclosures + from_node;
   int node_idx;
 
-  /* If we are outside the range of the subexpression, return -1 or 1.  */
-  if (str_idx < lim->subexp_from)
-    return -1;
-
-  if (lim->subexp_to < str_idx)
-    return 1;
-
-  /* If we are within the subexpression, return 0.  */
-  if (str_idx != lim->subexp_from && str_idx != lim->subexp_to)
-    return 0;
-
   /* Else, we are on the boundary: examine the nodes on the epsilon
      closure.  */
   for (node_idx = 0; node_idx < eclosures->nelem; ++node_idx)
@@ -1846,17 +1849,11 @@ check_dst_limits_calc_pos (mctx, limit, eclosures, subexp_idx, from_node,
        {
        case OP_BACK_REF:
          {
-           int bi = search_cur_bkref_entry (mctx, str_idx);
-           for (; bi < mctx->nbkref_ents; ++bi)
+           struct re_backref_cache_entry *ent = mctx->bkref_ents + bkref_idx;
+           do
              {
-               struct re_backref_cache_entry *ent = mctx->bkref_ents + bi;
                int dst, cpos;
 
-               /* If this backreference goes beyond the point we're
-                  examining, don't go any further.  */
-               if (ent->str_idx > str_idx)
-                 break;
-
                if (ent->node != node || ent->subexp_from != ent->subexp_to)
                  continue;
 
@@ -1869,33 +1866,32 @@ check_dst_limits_calc_pos (mctx, limit, eclosures, subexp_idx, from_node,
                dst = dfa->edests[node].elems[0];
                if (dst == from_node)
                  {
-                   if (str_idx == lim->subexp_from)
+                   if (boundaries & 1)
                      return -1;
-                   else /* if (str_idx == lim->subexp_to) */
+                   else /* if (boundaries & 2) */
                      return 0;
                  }
 
-               cpos = check_dst_limits_calc_pos (mctx, limit,
-                                                 dfa->eclosures + dst,
-                                                 subexp_idx, dst,
-                                                 str_idx);
+               cpos = check_dst_limits_calc_pos_1 (mctx, boundaries,
+                                                   subexp_idx, dst, bkref_idx);
 
-               if (cpos == -1 && str_idx == lim->subexp_from)
+               if (cpos == -1 && (boundaries & 1))
                  return -1;
 
-               if (cpos == 0 /* && str_idx == lim->lim->subexp_to */)
+               if (cpos == 0 /* && (boundaries & 2) */)
                  return 0;
              }
-             break;
-           }
+           while (ent++->more);
+           break;
+         }
 
        case OP_OPEN_SUBEXP:
-         if (str_idx == lim->subexp_from && subexp_idx == dfa->nodes[node].opr.idx)
+         if ((boundaries & 1) && subexp_idx == dfa->nodes[node].opr.idx)
            return -1;
          break;
 
        case OP_CLOSE_SUBEXP:
-         if (str_idx == lim->subexp_to && subexp_idx == dfa->nodes[node].opr.idx)
+         if ((boundaries & 2) && subexp_idx == dfa->nodes[node].opr.idx)
            return 0;
          break;
 
@@ -1904,10 +1900,33 @@ check_dst_limits_calc_pos (mctx, limit, eclosures, subexp_idx, from_node,
        }
     }
 
-  if (str_idx == lim->subexp_to)
+  return (boundaries & 2) ? 1 : 0;
+}
+
+static int
+check_dst_limits_calc_pos (mctx, limit, subexp_idx, from_node, str_idx, bkref_idx)
+     re_match_context_t *mctx;
+     int limit, subexp_idx, from_node, str_idx, bkref_idx;
+{
+  struct re_backref_cache_entry *lim = mctx->bkref_ents + limit;
+  int boundaries;
+
+  /* If we are outside the range of the subexpression, return -1 or 1.  */
+  if (str_idx < lim->subexp_from)
+    return -1;
+
+  if (lim->subexp_to < str_idx)
     return 1;
-  else
+
+  /* If we are within the subexpression, return 0.  */
+  boundaries = (str_idx == lim->subexp_from);
+  boundaries |= (str_idx == lim->subexp_to) << 1;
+  if (boundaries == 0)
     return 0;
+
+  /* Else, examine epsilon closure.  */
+  return check_dst_limits_calc_pos_1 (mctx, boundaries, subexp_idx,
+                                     from_node, bkref_idx);
 }
 
 /* Check the limitations of sub expressions LIMITS, and remove the nodes
@@ -2009,115 +2028,91 @@ check_subexp_limits (dfa, dest_nodes, candidates, limits, bkref_ents, str_idx)
 }
 
 static reg_errcode_t
-sift_states_bkref (mctx, sctx, str_idx, dest_nodes)
+sift_states_bkref (mctx, sctx, str_idx, candidates)
      re_match_context_t *mctx;
      re_sift_context_t *sctx;
      int str_idx;
-     re_node_set *dest_nodes;
+     const re_node_set *candidates;
 {
   re_dfa_t *const dfa = mctx->dfa;
   reg_errcode_t err;
   int node_idx, node;
   re_sift_context_t local_sctx;
-  const re_node_set *candidates;
-  candidates = ((mctx->state_log[str_idx] == NULL) ? &empty_set
-               : &mctx->state_log[str_idx]->nodes);
+  int first_idx = search_cur_bkref_entry (mctx, str_idx);
+
+  if (first_idx == -1)
+    return REG_NOERROR;
+
   local_sctx.sifted_states = NULL; /* Mark that it hasn't been initialized.  */
 
   for (node_idx = 0; node_idx < candidates->nelem; ++node_idx)
     {
-      int cur_bkref_idx = re_string_cur_idx (&mctx->input);
+      int enabled_idx;
       re_token_type_t type;
+      struct re_backref_cache_entry *entry;
       node = candidates->elems[node_idx];
       type = dfa->nodes[node].type;
-      if (node == sctx->cur_bkref && str_idx == cur_bkref_idx)
-       continue;
       /* Avoid infinite loop for the REs like "()\1+".  */
       if (node == sctx->last_node && str_idx == sctx->last_str_idx)
        continue;
-      if (type == OP_BACK_REF)
+      if (type != OP_BACK_REF)
+       continue;
+
+      entry = mctx->bkref_ents + first_idx;
+      enabled_idx = first_idx;
+      do
        {
-         int enabled_idx = search_cur_bkref_entry (mctx, str_idx);
-         for (; enabled_idx < mctx->nbkref_ents; ++enabled_idx)
-           {
-             int disabled_idx, subexp_len, to_idx, dst_node;
-             struct re_backref_cache_entry *entry;
-             entry = mctx->bkref_ents + enabled_idx;
-             if (entry->str_idx > str_idx)
-               break;
-             if (entry->node != node)
-                 continue;
-             subexp_len = entry->subexp_to - entry->subexp_from;
-             to_idx = str_idx + subexp_len;
-             dst_node = (subexp_len ? dfa->nexts[node]
-                         : dfa->edests[node].elems[0]);
-
-             if (to_idx > sctx->last_str_idx
-                 || sctx->sifted_states[to_idx] == NULL
-                 || !STATE_NODE_CONTAINS (sctx->sifted_states[to_idx],
-                                          dst_node)
-                 || check_dst_limits (mctx, &sctx->limits, node,
-                                      str_idx, dst_node, to_idx))
-               continue;
-               {
-                 re_dfastate_t *cur_state;
-                 entry->flag = 0;
-                 for (disabled_idx = enabled_idx + 1;
-                      disabled_idx < mctx->nbkref_ents; ++disabled_idx)
-                   {
-                     struct re_backref_cache_entry *entry2;
-                     entry2 = mctx->bkref_ents + disabled_idx;
-                     if (entry2->str_idx > str_idx)
-                       break;
-                     entry2->flag = (entry2->node == node) ? 1 : entry2->flag;
-                   }
+         int subexp_len, to_idx, dst_node;
+         re_dfastate_t *cur_state;
 
-                 if (local_sctx.sifted_states == NULL)
-                   {
-                     local_sctx = *sctx;
-                     err = re_node_set_init_copy (&local_sctx.limits,
-                                                  &sctx->limits);
-                     if (BE (err != REG_NOERROR, 0))
-                       goto free_return;
-                   }
-                 local_sctx.last_node = node;
-                 local_sctx.last_str_idx = str_idx;
-                 err = re_node_set_insert (&local_sctx.limits, enabled_idx);
-                 if (BE (err < 0, 0))
-                   {
-                     err = REG_ESPACE;
-                     goto free_return;
-                   }
-                 cur_state = local_sctx.sifted_states[str_idx];
-                 err = sift_states_backward (mctx, &local_sctx);
-                 if (BE (err != REG_NOERROR, 0))
-                   goto free_return;
-                 if (sctx->limited_states != NULL)
-                   {
-                     err = merge_state_array (dfa, sctx->limited_states,
-                                              local_sctx.sifted_states,
-                                              str_idx + 1);
-                     if (BE (err != REG_NOERROR, 0))
-                       goto free_return;
-                   }
-                 local_sctx.sifted_states[str_idx] = cur_state;
-                 re_node_set_remove (&local_sctx.limits, enabled_idx);
-                 /* We must not use the variable entry here, since
-                    mctx->bkref_ents might be realloced.  */
-                 mctx->bkref_ents[enabled_idx].flag = 1;
-               }
+         if (entry->node != node)
+           continue;
+         subexp_len = entry->subexp_to - entry->subexp_from;
+         to_idx = str_idx + subexp_len;
+         dst_node = (subexp_len ? dfa->nexts[node]
+                     : dfa->edests[node].elems[0]);
+
+         if (to_idx > sctx->last_str_idx
+             || sctx->sifted_states[to_idx] == NULL
+             || !STATE_NODE_CONTAINS (sctx->sifted_states[to_idx], dst_node)
+             || check_dst_limits (mctx, &sctx->limits, node,
+                                  str_idx, dst_node, to_idx))
+           continue;
+
+         if (local_sctx.sifted_states == NULL)
+           {
+             local_sctx = *sctx;
+             err = re_node_set_init_copy (&local_sctx.limits, &sctx->limits);
+             if (BE (err != REG_NOERROR, 0))
+               goto free_return;
            }
-         enabled_idx = search_cur_bkref_entry (mctx, str_idx);
-         for (; enabled_idx < mctx->nbkref_ents; ++enabled_idx)
+         local_sctx.last_node = node;
+         local_sctx.last_str_idx = str_idx;
+         err = re_node_set_insert (&local_sctx.limits, enabled_idx);
+         if (BE (err < 0, 0))
            {
-             struct re_backref_cache_entry *entry;
-             entry = mctx->bkref_ents + enabled_idx;
-             if (entry->str_idx > str_idx)
-               break;
-             if (entry->node == node)
-               entry->flag = 0;
+             err = REG_ESPACE;
+             goto free_return;
            }
+         cur_state = local_sctx.sifted_states[str_idx];
+         err = sift_states_backward (mctx, &local_sctx);
+         if (BE (err != REG_NOERROR, 0))
+           goto free_return;
+         if (sctx->limited_states != NULL)
+           {
+             err = merge_state_array (dfa, sctx->limited_states,
+                                      local_sctx.sifted_states,
+                                      str_idx + 1);
+             if (BE (err != REG_NOERROR, 0))
+               goto free_return;
+           }
+         local_sctx.sifted_states[str_idx] = cur_state;
+         re_node_set_remove (&local_sctx.limits, enabled_idx);
+
+         /* mctx->bkref_ents may have changed, reload the pointer.  */
+          entry = mctx->bkref_ents + enabled_idx;
        }
+      while (enabled_idx++, entry++->more);
     }
   err = REG_NOERROR;
  free_return:
@@ -2611,15 +2606,15 @@ get_subexp (mctx, bkref_node, bkref_str_idx)
   const char *buf = (const char *) re_string_get_buffer (&mctx->input);
   /* Return if we have already checked BKREF_NODE at BKREF_STR_IDX.  */
   int cache_idx = search_cur_bkref_entry (mctx, bkref_str_idx);
-  for (; cache_idx < mctx->nbkref_ents; ++cache_idx)
+  if (cache_idx != -1)
     {
-      const struct re_backref_cache_entry *entry
-       = &mctx->bkref_ents[cache_idx];
-      if (entry->str_idx > bkref_str_idx)
-       break;
-      if (entry->node == bkref_node)
-       return REG_NOERROR; /* We already checked it.  */
+      const struct re_backref_cache_entry *entry = mctx->bkref_ents + cache_idx;
+      do
+        if (entry->node == bkref_node)
+         return REG_NOERROR; /* We already checked it.  */
+      while (entry++->more);
     }
+
   subexp_num = dfa->nodes[bkref_node].opr.idx - 1;
 
   /* For each sub expression  */
@@ -2871,7 +2866,7 @@ check_arrival (mctx, path, top_node, top_str, last_node, last_str,
     {
       if (next_nodes.nelem)
        {
-         err = expand_bkref_cache (mctx, &next_nodes, str_idx, last_str,
+         err = expand_bkref_cache (mctx, &next_nodes, str_idx,
                                    subexp_num, type);
          if (BE ( err != REG_NOERROR, 0))
            {
@@ -2920,7 +2915,7 @@ check_arrival (mctx, path, top_node, top_str, last_node, last_str,
              re_node_set_free (&next_nodes);
              return err;
            }
-         err = expand_bkref_cache (mctx, &next_nodes, str_idx, last_str,
+         err = expand_bkref_cache (mctx, &next_nodes, str_idx,
                                    subexp_num, type);
          if (BE ( err != REG_NOERROR, 0))
            {
@@ -2969,6 +2964,7 @@ check_arrival_add_next_nodes (mctx, str_idx, cur_nodes, next_nodes)
      re_node_set *cur_nodes, *next_nodes;
 {
   re_dfa_t *const dfa = mctx->dfa;
+  int result;
   int cur_idx;
   reg_errcode_t err;
   re_node_set union_set;
@@ -3002,8 +2998,8 @@ check_arrival_add_next_nodes (mctx, str_idx, cur_nodes, next_nodes)
                      return err;
                    }
                }
-             err = re_node_set_insert (&union_set, next_node);
-             if (BE (err < 0, 0))
+             result = re_node_set_insert (&union_set, next_node);
+             if (BE (result < 0, 0))
                {
                  re_node_set_free (&union_set);
                  return REG_ESPACE;
@@ -3022,8 +3018,8 @@ check_arrival_add_next_nodes (mctx, str_idx, cur_nodes, next_nodes)
       if (naccepted
          || check_node_accept (mctx, dfa->nodes + cur_node, str_idx))
        {
-         err = re_node_set_insert (next_nodes, dfa->nexts[cur_node]);
-         if (BE (err < 0, 0))
+         result = re_node_set_insert (next_nodes, dfa->nexts[cur_node]);
+         if (BE (result < 0, 0))
            {
              re_node_set_free (&union_set);
              return REG_ESPACE;
@@ -3140,24 +3136,26 @@ check_arrival_expand_ecl_sub (dfa, dst_nodes, target, ex_subexp, type)
    in MCTX->BKREF_ENTS.  */
 
 static reg_errcode_t
-expand_bkref_cache (mctx, cur_nodes, cur_str, last_str, subexp_num,
+expand_bkref_cache (mctx, cur_nodes, cur_str, subexp_num,
                    type)
      re_match_context_t *mctx;
-     int cur_str, last_str, subexp_num, type;
+     int cur_str, subexp_num, type;
      re_node_set *cur_nodes;
 {
   re_dfa_t *const dfa = mctx->dfa;
   reg_errcode_t err;
-  int cache_idx, cache_idx_start;
-  /* The current state.  */
+  int cache_idx_start = search_cur_bkref_entry (mctx, cur_str);
+  struct re_backref_cache_entry *ent;
 
-  cache_idx_start = search_cur_bkref_entry (mctx, cur_str);
-  for (cache_idx = cache_idx_start; cache_idx < mctx->nbkref_ents; ++cache_idx)
+  if (cache_idx_start == -1)
+    return REG_NOERROR;
+
+ restart:
+  ent = mctx->bkref_ents + cache_idx_start;
+  do
     {
       int to_idx, next_node;
-      struct re_backref_cache_entry *ent = mctx->bkref_ents + cache_idx;
-      if (ent->str_idx > cur_str)
-       break;
+
       /* Is this entry ENT is appropriate?  */
       if (!re_node_set_contains (cur_nodes, ent->node))
        continue; /* No.  */
@@ -3186,8 +3184,7 @@ expand_bkref_cache (mctx, cur_nodes, cur_str, last_str, subexp_num,
              return err;
            }
          /* TODO: It is still inefficient...  */
-         cache_idx = cache_idx_start - 1;
-         continue;
+         goto restart;
        }
       else
        {
@@ -3222,6 +3219,7 @@ expand_bkref_cache (mctx, cur_nodes, cur_str, last_str, subexp_num,
            return err;
        }
     }
+  while (ent++->more);
   return REG_NOERROR;
 }
 
@@ -3463,6 +3461,7 @@ group_nodes_into_DFAstates (dfa, state, dests_node, dests_ch)
     bitset *dests_ch;
 {
   reg_errcode_t err;
+  int result;
   int i, j, k;
   int ndests; /* Number of the destinations from `state'.  */
   bitset accepts; /* Characters a node can accept.  */
@@ -3611,8 +3610,8 @@ group_nodes_into_DFAstates (dfa, state, dests_node, dests_ch)
            }
 
          /* Put the position in the current group. */
-         err = re_node_set_insert (&dests_node[j], cur_nodes->elems[i]);
-         if (BE (err < 0, 0))
+         result = re_node_set_insert (&dests_node[j], cur_nodes->elems[i]);
+         if (BE (result < 0, 0))
            goto error_return;
 
          /* If all characters are consumed, go to next node. */
@@ -4147,26 +4146,30 @@ match_ctx_add_entry (mctx, node, str_idx, from, to)
              sizeof (struct re_backref_cache_entry) * mctx->abkref_ents);
       mctx->abkref_ents *= 2;
     }
+  if (mctx->nbkref_ents > 0
+      && mctx->bkref_ents[mctx->nbkref_ents - 1].str_idx == str_idx)
+    mctx->bkref_ents[mctx->nbkref_ents - 1].more = 1;
+
   mctx->bkref_ents[mctx->nbkref_ents].node = node;
   mctx->bkref_ents[mctx->nbkref_ents].str_idx = str_idx;
   mctx->bkref_ents[mctx->nbkref_ents].subexp_from = from;
   mctx->bkref_ents[mctx->nbkref_ents].subexp_to = to;
-  mctx->bkref_ents[mctx->nbkref_ents++].flag = 0;
+  mctx->bkref_ents[mctx->nbkref_ents++].more = 0;
   if (mctx->max_mb_elem_len < to - from)
     mctx->max_mb_elem_len = to - from;
   return REG_NOERROR;
 }
 
-/* Search for the first entry which has the same str_idx.
-   Note that MCTX->BKREF_ENTS is already sorted by MCTX->STR_IDX.  */
+/* Search for the first entry which has the same str_idx, or -1 if none is
+   found.  Note that MCTX->BKREF_ENTS is already sorted by MCTX->STR_IDX.  */
 
 static int
 search_cur_bkref_entry (mctx, str_idx)
      re_match_context_t *mctx;
      int str_idx;
 {
-  int left, right, mid;
-  right = mctx->nbkref_ents;
+  int left, right, mid, last;
+  last = right = mctx->nbkref_ents;
   for (left = 0; left < right;)
     {
       mid = (left + right) / 2;
@@ -4175,16 +4178,10 @@ search_cur_bkref_entry (mctx, str_idx)
       else
        right = mid;
     }
-  return left;
-}
-
-static void
-match_ctx_clear_flag (mctx)
-     re_match_context_t *mctx;
-{
-  int i;
-  for (i = 0; i < mctx->nbkref_ents; ++i)
-    mctx->bkref_ents[i].flag = 0;
+  if (left < last && mctx->bkref_ents[left].str_idx == str_idx)
+    return left;
+  else
+    return -1;
 }
 
 /* Register the node NODE, whose type is OP_OPEN_SUBEXP, and which matches
@@ -4250,18 +4247,14 @@ match_ctx_add_sublast (subtop, node, str_idx)
 }
 
 static void
-sift_ctx_init (sctx, sifted_sts, limited_sts, last_node, last_str_idx,
-              check_subexp)
+sift_ctx_init (sctx, sifted_sts, limited_sts, last_node, last_str_idx)
     re_sift_context_t *sctx;
     re_dfastate_t **sifted_sts, **limited_sts;
-    int last_node, last_str_idx, check_subexp;
+    int last_node, last_str_idx;
 {
   sctx->sifted_states = sifted_sts;
   sctx->limited_states = limited_sts;
   sctx->last_node = last_node;
   sctx->last_str_idx = last_str_idx;
-  sctx->check_subexp = check_subexp;
-  sctx->cur_bkref = -1;
-  sctx->cls_subexp_idx = -1;
   re_node_set_init_empty (&sctx->limits);
 }
index f4a3fb3df5968523f9e667eb6ea022eef9a76467..30fff15946985c9c04f18a9acc7fa93ecb9b2df8 100644 (file)
@@ -505,3 +505,8 @@ Char \([a-z0-9_]*\)\[.*     b       Char xyz[k      Char xyz[k      xyz
 a?b    -       ab      ab
 -\{0,1\}[0-9]*$        b       -5      -5
 a*a*a*a*a*a*a* &       aaaaaa  aaaaaa
+(\b){0}        -       x       @x      -
+\(\b\)\{0,0\}  b       abc     @abc    -
+a(\b){0}c      -       ac      ac      -
+a(.*)b(\0){0}c -       abc     abc     @bc,-
+a(.*)b(\0){0}c -       axbc    axbc    x,-
index 429947ccd9175cdfcf581a60ea6936eace5a6870..34498a880ca414ad3a2f63203b2a6a0d33e52426 100644 (file)
@@ -161,6 +161,8 @@ _dl_sysdep_start (void **start_argptr,
       case AT_SYSINFO:
        new_sysinfo = av->a_un.a_val;
        break;
+#endif
+#if defined NEED_DL_SYSINFO || defined NEED_DL_SYSINFO_DSO
       case AT_SYSINFO_EHDR:
        GLRO(dl_sysinfo_dso) = av->a_un.a_ptr;
        break;
@@ -287,10 +289,8 @@ _dl_show_auxv (void)
          [AT_UCACHEBSIZE - 2] =        { "AT_UCACHEBSIZE:  0x", hex },
          [AT_IGNOREPPC - 2] =          { "AT_IGNOREPPC", ignore },
          [AT_SECURE - 2] =             { "AT_SECURE:       ", dec },
-#ifdef NEED_DL_SYSINFO
          [AT_SYSINFO - 2] =            { "AT_SYSINFO:      0x", hex },
          [AT_SYSINFO_EHDR - 2] =       { "AT_SYSINFO_EHDR: 0x", hex },
-#endif
        };
       unsigned int idx = (unsigned int) (av->a_type - 2);
 
index fd45bdc87fda6d526a2b08d405484bda0d5cea60..ec68e1a565781f7ae40a340d127d2d9abaceb3ef 100644 (file)
@@ -470,7 +470,9 @@ struct rtld_global_ro
 #ifdef NEED_DL_SYSINFO
   /* Syscall handling improvements.  This is very specific to x86.  */
   EXTERN uintptr_t _dl_sysinfo;
+#endif
 
+#if defined NEED_DL_SYSINFO || defined NEED_DL_SYSINFO_DSO
   /* The vsyscall page is a virtual DSO pre-mapped by the kernel.
      This points to its ELF header.  */
   EXTERN const ElfW(Ehdr) *_dl_sysinfo_dso;
index d67e3568a393f438fa958001a2908ea229588620..f22685cb2955f99fd5cde9a8aa464b7a3312d410 100644 (file)
@@ -18,6 +18,8 @@
    02111-1307 USA.  */
 
 #include <errno.h>
+#include <grp.h>
+#include <pwd.h>
 #include <stdio.h>
 #include <unistd.h>
 #include <time.h>
index fd4db36dc37e3d6123f88c40c44163a460cfcd0b..60c94d6409990050e63f587030914feac5925231 100644 (file)
    template suitable for use in __gen_tempname into TMPL, bounded
    by TMPL_LEN. */
 int
-__path_search (tmpl, tmpl_len, dir, pfx)
+__path_search (tmpl, tmpl_len, dir, pfx, try_tmpdir)
      char *tmpl;
      size_t tmpl_len;
      const char *dir;
      const char *pfx;
+     int try_tmpdir;
 {
   __set_errno (ENOSYS);
   return -1;
index 09d0cc66798d29874f85ad7d17d26caa362df0af..3a3bcc38ccdb754ea6e68c16278efa7d3c0319c3 100644 (file)
@@ -17,6 +17,7 @@
    02111-1307 USA.  */
 
 #include <errno.h>
+#include <stddef.h>
 #include <utime.h>
 
 
index b6430592341e2bc55865f080c155658dd7944857..83c78f0b933acc6476c33dc6cc08775f27d08926 100644 (file)
@@ -69,6 +69,7 @@ typedef unsigned int _G_uint32_t __attribute__ ((__mode__ (__SI__)));
 
 #define _G_HAVE_PRINTF_FP 1
 #define _G_HAVE_MMAP 1
+#define _G_HAVE_MREMAP 1
 #define _G_HAVE_LONG_DOUBLE_IO 1
 #define _G_HAVE_IO_FILE_OPEN 1
 #define _G_HAVE_IO_GETLINE_INFO 1
diff --git a/sysdeps/mach/hurd/_G_config.h b/sysdeps/mach/hurd/_G_config.h
new file mode 100644 (file)
index 0000000..b643059
--- /dev/null
@@ -0,0 +1,102 @@
+/* This file is needed by libio to define various configuration parameters.
+   These are always the same in the GNU C library.  */
+
+#ifndef _G_config_h
+#define _G_config_h 1
+
+/* Define types for libio in terms of the standard internal type names.  */
+
+#include <bits/types.h>
+#define __need_size_t
+#define __need_wchar_t
+#define __need_wint_t
+#define __need_NULL
+#include <stddef.h>
+#ifndef _WINT_T
+/* Integral type unchanged by default argument promotions that can
+   hold any value corresponding to members of the extended character
+   set, as well as at least one value that does not correspond to any
+   member of the extended character set.  */
+# define _WINT_T
+typedef unsigned int wint_t;
+#endif
+#define __need_mbstate_t
+#include <wchar.h>
+#define _G_size_t      size_t
+typedef struct
+{
+  __off_t __pos;
+  __mbstate_t __state;
+} _G_fpos_t;
+typedef struct
+{
+  __off64_t __pos;
+  __mbstate_t __state;
+} _G_fpos64_t;
+#define _G_ssize_t     __ssize_t
+#define _G_off_t       __off_t
+#define _G_off64_t     __off64_t
+#define        _G_pid_t        __pid_t
+#define        _G_uid_t        __uid_t
+#define _G_wchar_t     wchar_t
+#define _G_wint_t      wint_t
+#define _G_stat64      stat64
+#include <gconv.h>
+typedef union
+{
+  struct __gconv_info __cd;
+  struct
+  {
+    struct __gconv_info __cd;
+    struct __gconv_step_data __data;
+  } __combined;
+} _G_iconv_t;
+
+typedef int _G_int16_t __attribute__ ((__mode__ (__HI__)));
+typedef int _G_int32_t __attribute__ ((__mode__ (__SI__)));
+typedef unsigned int _G_uint16_t __attribute__ ((__mode__ (__HI__)));
+typedef unsigned int _G_uint32_t __attribute__ ((__mode__ (__SI__)));
+
+#define _G_HAVE_BOOL 1
+
+
+/* These library features are always available in the GNU C library.  */
+#define _G_HAVE_ATEXIT 1
+#define _G_HAVE_SYS_CDEFS 1
+#define _G_HAVE_SYS_WAIT 1
+#define _G_NEED_STDARG_H 1
+#define _G_va_list __gnuc_va_list
+
+#define _G_HAVE_PRINTF_FP 1
+#define _G_HAVE_MMAP 1
+#define _G_HAVE_LONG_DOUBLE_IO 1
+#define _G_HAVE_IO_FILE_OPEN 1
+#define _G_HAVE_IO_GETLINE_INFO 1
+
+#define _G_IO_IO_FILE_VERSION 0x20001
+
+#define _G_OPEN64      __open64
+#define _G_LSEEK64     __lseek64
+#define _G_MMAP64      __mmap64
+#define _G_FSTAT64(fd,buf) __fxstat64 (_STAT_VER, fd, buf)
+
+/* This is defined by <bits/stat.h> if `st_blksize' exists.  */
+#define _G_HAVE_ST_BLKSIZE defined (_STATBUF_ST_BLKSIZE)
+
+#define _G_BUFSIZ 8192
+
+/* These are the vtbl details for ELF.  */
+#define _G_NAMES_HAVE_UNDERSCORE 0
+#define _G_VTABLE_LABEL_HAS_LENGTH 1
+#define _G_USING_THUNKS        1
+#define _G_VTABLE_LABEL_PREFIX "__vt_"
+#define _G_VTABLE_LABEL_PREFIX_ID __vt_
+
+
+#if defined __cplusplus || defined __STDC__
+# define _G_ARGS(ARGLIST) ARGLIST
+#else
+# define _G_ARGS(ARGLIST) ()
+#endif
+
+#endif /* _G_config.h */
index d55899a2c157eb52b9bd329c67cff55a49f6c777..77f962952adf661f217c59c725ee16c0a94def2e 100644 (file)
@@ -18,7 +18,7 @@
    02111-1307 USA.  */
 
 #include <stddef.h>
-#include <sys/uio.h>
+#include <string.h>
 
 /* We will print the register dump in this format:
 
@@ -51,7 +51,7 @@
 
 #define NREGS (32+32+3)
 
-static const char regnames[NREGS][8] = 
+static const char __attribute__((aligned(8))) regnames[NREGS][8] = 
 {
   "    V0: ", "    T0: ", "    T1: ",
   "    T2: ", "    T3: ", "    T4: ",
@@ -113,49 +113,45 @@ static const int offsets[NREGS] =
 
 #undef O
 
-static const char linefeed[2] = "\n\n";
-
 static void
 register_dump (int fd, struct sigcontext *ctx)
 {
-  char regs[NREGS][16];
-  struct iovec iov[2*NREGS+24];
-  size_t iov_i = 0, i, j;
+  char buf[NREGS*(8+16) + 25 + 80];
+  char *p = buf;
+  size_t i;
   
-#define ADD_MEM(str, len)                      \
-  (iov[iov_i].iov_base = (void *)(str),                \
-   iov[iov_i].iov_len = len,                   \
-   ++iov_i)
-
-#define ADD_STRING(str) ADD_MEM(str, strlen(str))
-
-  ADD_STRING ("Register dump:\n\n");
+  p = stpcpy (p, "Register dump:\n\n");
 
   for (i = 0; i < NREGS; ++i)
     {
       int this_offset, this_lf;
       unsigned long val;
+      signed long j;
       
       this_offset = offsets[i];
       this_lf = this_offset & 7;
-      this_offset &= -8;
 
-      val = *(unsigned long *)((char *)ctx + this_offset);
+      val = *(unsigned long *)(((size_t)ctx + this_offset) & -8);
 
-      for (j = 0; j < 16; ++j)
+      memcpy (p, regnames[i], 8);
+      p += 8;
+
+      for (j = 60; j >= 0; j -= 4)
        {
-         unsigned long x = (val >> (64 - (j + 1) * 4)) & 15;
+         unsigned long x = (val >> j) & 15;
          x += x < 10 ? '0' : 'a' - 10;
-         regs[i][j] = x;
+         *p++ = x;
        }
 
-      ADD_MEM (regnames[i], 8);
-      ADD_MEM (regs[i], 16);
-      if (this_lf)
-       ADD_MEM (linefeed, this_lf);
+      if (this_lf > 0)
+       {
+         if (this_lf > 1)
+           *p++ = '\n';
+         *p++ = '\n';
+       }
     }
 
-  writev (fd, iov, iov_i);
+  write (fd, buf, p - buf);
 }
 
 #define REGISTER_DUMP register_dump (fd, ctx)
index f4dce4cd612447de27006a203966c54210fe52e7..8a052e212db41e0513c08d87a9ce5d866e756a82 100644 (file)
@@ -566,7 +566,7 @@ getifaddrs (struct ifaddrs **ifap)
                                if (IN6_IS_ADDR_LINKLOCAL (rta_data)
                                    || IN6_IS_ADDR_MC_LINKLOCAL (rta_data))
                                  ((struct sockaddr_in6 *) sa)->sin6_scope_id
-                                   = ifam->ifa_scope;
+                                   = ifam->ifa_index;
                              }
                            break;
 
@@ -610,10 +610,10 @@ getifaddrs (struct ifaddrs **ifap)
                            {
                              memcpy (&ifas[ifa_index].addr.s6.sin6_addr,
                                      rta_data, rta_payload);
-                             if (IN6_IS_ADDR_LINKLOCAL (rta_data) ||
-                                 IN6_IS_ADDR_MC_LINKLOCAL (rta_data))
+                             if (IN6_IS_ADDR_LINKLOCAL (rta_data)
+                                 || IN6_IS_ADDR_MC_LINKLOCAL (rta_data))
                                ifas[ifa_index].addr.s6.sin6_scope_id =
-                                 ifam->ifa_scope;
+                                 ifam->ifa_index;
                            }
                          break;
 
@@ -654,7 +654,7 @@ getifaddrs (struct ifaddrs **ifap)
                              if (IN6_IS_ADDR_LINKLOCAL (rta_data)
                                  || IN6_IS_ADDR_MC_LINKLOCAL (rta_data))
                                ifas[ifa_index].broadaddr.s6.sin6_scope_id
-                                 = ifam->ifa_scope;
+                                 = ifam->ifa_index;
                            }
                          break;