]> git.ipfire.org Git - thirdparty/glibc.git/commitdiff
Updated to fedora-glibc-20041112T1640
authorJakub Jelinek <jakub@redhat.com>
Fri, 12 Nov 2004 16:56:15 +0000 (16:56 +0000)
committerJakub Jelinek <jakub@redhat.com>
Fri, 12 Nov 2004 16:56:15 +0000 (16:56 +0000)
45 files changed:
ChangeLog
Makeconfig
Rules
fedora/branch.mk
fedora/glibc.spec.in
nptl/ChangeLog
nptl/Makefile
nptl/allocatestack.c
nptl/descr.h
nptl/pthreadP.h
nptl/sysdeps/pthread/pthread-functions.h
nptl/sysdeps/pthread/setxid.h [new file with mode: 0644]
nptl/tst-setuid1-static.c [new file with mode: 0644]
nptl/tst-setuid1.c [new file with mode: 0644]
posix/Makefile
posix/bug-regex24.c [new file with mode: 0644]
posix/regex_internal.c
posix/regex_internal.h
posix/regexec.c
posix/tst-waitid.c
sysdeps/generic/strtok_r.c
sysdeps/unix/setxid.h [new file with mode: 0644]
sysdeps/unix/sysv/linux/alpha/setregid.c
sysdeps/unix/sysv/linux/alpha/setresgid.c
sysdeps/unix/sysv/linux/alpha/setresuid.c
sysdeps/unix/sysv/linux/alpha/setreuid.c
sysdeps/unix/sysv/linux/i386/setegid.c
sysdeps/unix/sysv/linux/i386/seteuid.c
sysdeps/unix/sysv/linux/i386/setgid.c
sysdeps/unix/sysv/linux/i386/setregid.c
sysdeps/unix/sysv/linux/i386/setresgid.c
sysdeps/unix/sysv/linux/i386/setresuid.c
sysdeps/unix/sysv/linux/i386/setreuid.c
sysdeps/unix/sysv/linux/i386/setuid.c
sysdeps/unix/sysv/linux/setegid.c
sysdeps/unix/sysv/linux/seteuid.c
sysdeps/unix/sysv/linux/setgid.c
sysdeps/unix/sysv/linux/setregid.c
sysdeps/unix/sysv/linux/setresgid.c
sysdeps/unix/sysv/linux/setresuid.c
sysdeps/unix/sysv/linux/setreuid.c
sysdeps/unix/sysv/linux/setuid.c
sysdeps/unix/sysv/linux/syscalls.list
time/difftime.c
time/mktime.c

index bf062849e9bb9d8b51b97f0a5604cb271c36e1df..7b36bcfa8c20c03e457c24d90790788cbe34d8b7 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
+2004-11-12  Ulrich Drepper  <drepper@redhat.com>
+
+       * posix/Makefile (tests): Add bug-regex24.
+       * posix/bug-regex24.c: New file.
+
+2004-11-12  Paolo Bonzini  <bonzini@gnu.org>
+
+       * posix/regexec.c (check_dst_limits_calc_pos_1): Use the map to
+       cut recursive paths.  Make exit condition more precise.
+       (match_ctx_add_entry): Initialize the map.
+       * posix/regex_internal.h (struct re_backref_cache_entry): Add a map of
+       reachable subexpression nodes from each backreference cache entry.
+
+2004-11-10  Jakub Jelinek  <jakub@redhat.com>
+
+       * sysdeps/unix/sysv/linux/setreuid.c: Remove sys/syscall.h,
+       sys/types.h, linux/posix_types.h, sysdep.h and pthread-functions.h
+       includes.  Include setxid.h.  Use INLINE_SETXID_SYSCALL macro
+       instead of INLINE_SYSCALL, kill the HAVE_PTR__NPTL_SETXID guarded
+       snippets.
+       * sysdeps/unix/sysv/linux/setegid.c: Likewise.
+       * sysdeps/unix/sysv/linux/setuid.c: Likewise.
+       * sysdeps/unix/sysv/linux/seteuid.c: Likewise.
+       * sysdeps/unix/sysv/linux/setgid.c: Likewise.
+       * sysdeps/unix/sysv/linux/setresuid.c: Likewise.
+       * sysdeps/unix/sysv/linux/setresgid.c: Likewise.
+       * sysdeps/unix/sysv/linux/setregid.c: Likewise.
+       * sysdeps/unix/sysv/linux/i386/setegid.c: Likewise.
+       * sysdeps/unix/sysv/linux/i386/setreuid.c: Likewise.
+       * sysdeps/unix/sysv/linux/i386/setuid.c: Likewise.
+       * sysdeps/unix/sysv/linux/i386/seteuid.c: Likewise.
+       * sysdeps/unix/sysv/linux/i386/setgid.c: Likewise.
+       * sysdeps/unix/sysv/linux/i386/setresuid.c: Likewise.
+       * sysdeps/unix/sysv/linux/i386/setresgid.c: Likewise.
+       * sysdeps/unix/sysv/linux/i386/setregid.c: Likewise.
+       * sysdeps/unix/sysv/linux/alpha/setreuid.c: Likewise.
+       Formatting.  Change signed int into int.
+       * sysdeps/unix/sysv/linux/alpha/setresuid.c: Likewise.
+       * sysdeps/unix/sysv/linux/alpha/setresgid.c: Likewise.
+       * sysdeps/unix/sysv/linux/alpha/setregid.c: Likewise.
+       * sysdeps/unix/sysv/linux/syscalls.list (setresuid, setresgid):
+       Remove.
+       * sysdeps/unix/setxid.h: New file.
+
+       * Rules (binaries-static): Add xtests-static.
+       * Makeconfig (run-program-prefix): Filter also xtests-static.
+
+2004-11-09  Paul Eggert  <eggert@cs.ucla.edu.
+
+       [BZ #535]
+       * time/difftime.c: Fix a double-rounding bug on hosts with
+       64-bit time_t and long double being IEEE double.  Also, port
+       to more valid C99 hosts, even those that have padding bits.
+       Don't include <values.h> since it is marked as an obsolescent
+       interface.  Include <limits.h>, <float.h>, and <stdint.h> instead.
+       (TYPE_BITS, TYPE_FLOATING, TYPE_SIGNED): New macros.
+       (subtract): New static function, that works correctly without
+       double-rounding, even on hosts with 64-bit time_t.  Also cater
+       to hosts with padding bits.
+       (__difftime): Use it.  Use DBL_MANT_DIG and LDBL_MANT_DIG to
+       determine whether floating types are wide enough: the old
+       test (which used sizeof) could in theory report the wrong results
+       on hosts with padding bits in floating-point values.
+
+2004-11-11  Simon Josefsson  <jas@extundo.com>
+
+       [BZ #542]
+       * sysdeps/generic/strtok_r.c [HAVE_CONFIG_H]: Include config.h.
+       [!_LIBC]: Include strtok_r.h (in gnulib), map __strtok_r to
+       strtok_r and __rawmemchr to strch.
+       (__strtok_r): Use C89 prototype.
+       [weak_alias]: Move calls to libc_hidden_def and weak_alias into
+       this #ifdef.
+
+2004-11-10  Paul Eggert  <eggert@cs.ucla.edu>
+
+       [BZ #541]
+       * time/mktime.c (SHR): New macro, which is a portable
+       substitute for >> that should work even on Crays.
+       (TIME_T_MIDPOINT, ydhms_diff, __mktime_internal): Use it.
+       Problem reported by Mark D. Baushke in
+       <http://lists.gnu.org/archive/html/bug-gnulib/2004-11/msg00071.html>.
+
+2004-11-09  Paolo Bonzini  <bonzini@gnu.org>
+
+       * posix/regexec.c (match_ctx_free_subtops): Remove, merge into...
+       (match_ctx_clean): ... this function.
+       (match_ctx_free): Call match_ctx_clean.
+
+       * posix/regexec.c (transit_state): Remove the check for
+       out-of-bounds buffers.
+       (check_matching): Check here for out-of-bounds buffers.
+       (re_search_internal): Store into match_kind a set of bits
+       indicating which incantation of fastmap scanning must be
+       used.  Use a switch statement instead of multiple ifs.
+       Exit the final "for (;;)" with goto free_return unless
+       the match succeeded, thus simplifying some conditionals.
+
+       * posix/regex_internal.c (re_string_reconstruct,
+       re_string_context_at): Add several branch predictions for
+       case-sensitive matching and no transition table being used.
+
+2004-11-10  Ulrich Drepper  <drepper@redhat.com>
+
+       * posix/tst-waitid.c: Don't use error to print error message, they
+       won't end up in the .out file.
+
 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_getgr_r.c: Likewise.  Make map externally visible.
+       * nscd/nscd_gethst_r.c: Likewise.
        * nscd/nscd_getai.c: Use map from nscd_gethost.c.
        * nscd/nscd_initgroups.c: Use map from nscd_getgr.c.
 
index dc70aa68c4fd4348c39248831d39d3e04b4a23e2..ab9f806eff6e8366d54b3303dcb93fb07283147e 100644 (file)
@@ -541,7 +541,7 @@ $(subst $(empty) ,:,$(strip $(patsubst -Wl$(comma)-rpath-link=%, %,\
                                       $(filter -Wl$(comma)-rpath-link=%,\
                                                $(sysdep-LDFLAGS)))))
 run-program-prefix = $(if $(filter $(notdir $(built-program-file)),\
-                                  $(tests-static)),, \
+                                  $(tests-static) $(xtests-static)),, \
                          $(elf-objpfx)$(rtld-installed-name) \
                          --library-path $(rpath-link)$(patsubst %,:%,$(sysdep-library-path)))
 else
diff --git a/Rules b/Rules
index 64179ad64df90e1e1c3440f4ac251dcc76a56c86..a29daaa7b5a51f89175b95bd61cb00d5921c33b0 100644 (file)
--- a/Rules
+++ b/Rules
@@ -104,7 +104,7 @@ endif
 
 ifeq ($(build-programs),yes)
 binaries-all = $(others) $(sysdep-others) $(tests) $(xtests) $(test-srcs)
-binaries-static = $(others-static) $(tests-static)
+binaries-static = $(others-static) $(tests-static) $(xtests-static)
 else
 binaries-all = $(tests) $(xtests) $(test-srcs)
 binaries-static =
index b07840623ef80cc9f4115170f3f5e0fa5a95aa6d..2714ad4822778af478bed593f7cdde66f1dcbbed 100644 (file)
@@ -1,5 +1,5 @@
 # This file is updated automatically by Makefile.
 glibc-branch := fedora
 glibc-base := HEAD
-fedora-sync-date := 2004-11-10 08:39 UTC
-fedora-sync-tag := fedora-glibc-20041110T0839
+fedora-sync-date := 2004-11-12 16:40 UTC
+fedora-sync-tag := fedora-glibc-20041112T1640
index 735419c94a6a2972049be7e44deeb7fabc3c2b97..0d97316b37927b6fbd5ca6085207cccec49f0090 100644 (file)
@@ -1,4 +1,4 @@
-%define glibcrelease 76
+%define glibcrelease 77
 %define auxarches i586 i686 athlon sparcv9 alphaev6
 %define prelinkarches noarch
 %define nptlarches i386 i686 athlon x86_64 ia64 s390 s390x sparcv9 ppc ppc64
@@ -1256,6 +1256,12 @@ rm -f *.filelist*
 %endif
 
 %changelog
+* Fri Nov 12 2004 Jakub Jelinek <jakub@redhat.com> 2.3.3-77
+- update from CVS
+  - speedup regex on palindromes (BZ #429)
+  - fix NPTL set{,e,re,res}[ug]id, so that even if making process
+    less priviledged all threads change their credentials successfully
+
 * Wed Nov 10 2004 Jakub Jelinek <jakub@redhat.com> 2.3.3-76
 - update from CVS
   - fix regcomp crash (#138439)
index 98df5cf228a0e4e1792c7a21e609fbe31919f0b0..e183a02c7766305e6f5a077bc0f6c1c8b7fcbe0b 100644 (file)
@@ -1,3 +1,20 @@
+2004-11-10  Jakub Jelinek  <jakub@redhat.com>
+
+       * sysdeps/pthread/setxid.h: New file.
+       * sysdeps/pthread/pthread-functions.h (HAVE_PTR__NPTL_SETXID): Remove.
+       (struct xid_command): Add forward decl.
+       (struct pthread_functions): Change return type of __nptl_setxid hook
+       to int.
+       * pthreadP.h (__nptl_setxid): Change return type to int.
+       * allocatestack.c (__nptl_setxid): Call INTERNAL_SYSCALL_NCS in the
+       calling thread, return its return value and set errno on failure.
+       * descr.h (struct xid_command): Change id type to long array.
+
+       * Makefile: Add rules to build and test tst-setuid1 and
+       tst-setuid1-static.
+       * tst-setuid1.c: New test.
+       * tst-setuid1-static.c: New test.
+
 2004-11-10  Jakub Jelinek  <jakub@redhat.com>
 
        * Makefile (tests): Add tst-exit3.
index 564eaca6c52f939275e90c14fa646af316a9b445..805b4dc046118d75b97ee4ff97950061ea770078 100644 (file)
@@ -242,6 +242,7 @@ tests = tst-attr1 tst-attr2 tst-attr3 \
        tst-backtrace1 \
        tst-oddstacklimit \
        tst-vfork1 tst-vfork2 tst-vfork1x tst-vfork2x
+xtests = tst-setuid1 tst-setuid1-static
 
 # Files which must not be linked with libpthread.
 tests-nolibpthread = tst-unload
@@ -342,6 +343,7 @@ link-libc-static := $(common-objpfx)libc.a $(static-gnulib) \
 
 ifeq ($(build-static),yes)
 tests-static += tst-locale1 tst-locale2
+xtests-static += tst-setuid1-static
 endif
 # These tests are linked with libc before libpthread
 tests-reverse += tst-cancel5 tst-cancel23 tst-vfork1x tst-vfork2x
@@ -499,9 +501,10 @@ $(objpfx)libpthread.so: $(common-objpfx)libc.so \
 # Make sure we link with the thread library.
 ifeq ($(build-shared),yes)
 $(addprefix $(objpfx), \
-  $(filter-out $(tests-static) $(tests-reverse) $(tests-nolibpthread), \
-    $(tests) $(test-srcs))): $(objpfx)libpthread.so \
-                            $(objpfx)libpthread_nonshared.a
+  $(filter-out $(tests-static) $(xtests-static) $(tests-reverse) \
+    $(tests-nolibpthread), \
+    $(tests) $(xtests) $(test-srcs))): $(objpfx)libpthread.so \
+                                      $(objpfx)libpthread_nonshared.a
 $(objpfx)tst-unload: $(common-objpfx)dlfcn/libdl.so
 # $(objpfx)linklibc.so is used instead of $(common-objpfx)libc.so,
 # since otherwise libpthread.so comes before libc.so when linking.
@@ -509,7 +512,7 @@ $(addprefix $(objpfx), $(tests-reverse)): \
   $(objpfx)linklibc.so $(objpfx)libpthread.so \
   $(objpfx)libpthread_nonshared.a
 $(objpfx)../libc.so: $(common-objpfx)libc.so ;
-$(addprefix $(objpfx),$(tests-static)): $(objpfx)libpthread.a
+$(addprefix $(objpfx),$(tests-static) $(xtests-static)): $(objpfx)libpthread.a
 
 $(objpfx)tst-atfork2.out: $(objpfx)tst-atfork2mod.so
 
index d4f3188f5375a6d28c79d50f5134fb24c547becd..6c2367cc89313040a070c50599fd3b1445d09741 100644 (file)
@@ -816,10 +816,11 @@ __find_thread_by_id (pid_t tid)
 }
 #endif
 
-void
+int
 attribute_hidden
 __nptl_setxid (struct xid_command *cmdp)
 {
+  int result;
   lll_lock (stack_cache_lock);
 
   __xidcmd = cmdp;
@@ -891,7 +892,18 @@ __nptl_setxid (struct xid_command *cmdp)
       cur = cmdp->cntr;
     }
 
+  /* This must be last, otherwise the current thread might not have
+     permissions to send SIGSETXID syscall to the other threads.  */
+  result = INTERNAL_SYSCALL_NCS (cmdp->syscall_no, err, 3,
+                                cmdp->id[0], cmdp->id[1], cmdp->id[2]);
+  if (INTERNAL_SYSCALL_ERROR_P (result, err))
+    {
+      __set_errno (INTERNAL_SYSCALL_ERRNO (result, err));
+      result = -1;
+    }
+
   lll_unlock (stack_cache_lock);
+  return result;
 }
 
 static inline void __attribute__((always_inline))
index 7ef4221e83f7a9a6402c00a26cdbb45961babb2a..4c234a2349adb9639cd14665c0ec47bf2cee39e6 100644 (file)
@@ -101,7 +101,7 @@ struct pthread_unwind_buf
 struct xid_command
 {
   int syscall_no;
-  id_t id[3];
+  long id[3];
   volatile int cntr;
 };
 
index 1fedce5f3ad9f51bddd64c9d43420a59f3bfe031..f73c817f6002255d64ebcc32210302d6f55237b2 100644 (file)
@@ -448,6 +448,6 @@ extern void _pthread_cleanup_pop_restore (struct _pthread_cleanup_buffer *buffer
 
 extern void __nptl_deallocate_tsd (void) attribute_hidden;
 
-extern void __nptl_setxid (struct xid_command *cmdp) attribute_hidden;
+extern int __nptl_setxid (struct xid_command *cmdp) attribute_hidden;
 
 #endif /* pthreadP.h */
index b1e0fcb26da0cf568c63f550cf669544659bd6d4..284534612850db95e9f2f2516edffeeb83a39863 100644 (file)
@@ -24,6 +24,7 @@
 #include <setjmp.h>
 #include <internaltypes.h>
 
+struct xid_command;
 
 /* Data type shared with libc.  The libc uses it to pass on calls to
    the thread functions.  */
@@ -93,8 +94,7 @@ struct pthread_functions
   void (*ptr___pthread_unwind) (__pthread_unwind_buf_t *)
        __attribute ((noreturn)) __cleanup_fct_attribute;
   void (*ptr__nptl_deallocate_tsd) (void);
-#define HAVE_PTR__NPTL_SETXID
-  void (*ptr__nptl_setxid) (struct xid_command *);
+  int (*ptr__nptl_setxid) (struct xid_command *);
 };
 
 /* Variable in libc.so.  */
diff --git a/nptl/sysdeps/pthread/setxid.h b/nptl/sysdeps/pthread/setxid.h
new file mode 100644 (file)
index 0000000..8ec382f
--- /dev/null
@@ -0,0 +1,64 @@
+/* Copyright (C) 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
+   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 <pthreadP.h>
+#include <sysdep.h>
+
+#define __SETXID_1(cmd, arg1) \
+  cmd.id[0] = arg1
+#define __SETXID_2(cmd, arg1, arg2) \
+  __SETXID_1 (cmd, arg1); cmd.id[1] = arg2
+#define __SETXID_3(cmd, arg1, arg2, arg3) \
+  __SETXID_2 (cmd, arg1, arg2); cmd.id[2] = arg3
+
+#ifdef SINGLE_THREAD
+# define INLINE_SETXID_SYSCALL(name, nr, args...) \
+  INLINE_SYSCALL (name, nr, args)
+#elif defined SHARED
+# define INLINE_SETXID_SYSCALL(name, nr, args...) \
+  ({                                                                   \
+    int __result;                                                      \
+    if (__builtin_expect (__libc_pthread_functions.ptr__nptl_setxid    \
+                         != NULL, 0))                                  \
+      {                                                                        \
+       struct xid_command __cmd;                                       \
+       __cmd.syscall_no = __NR_##name;                                 \
+       __SETXID_##nr (__cmd, args);                                    \
+       __result = __libc_pthread_functions.ptr__nptl_setxid (&__cmd);  \
+       }                                                               \
+    else                                                               \
+      __result = INLINE_SYSCALL (name, nr, args);                      \
+    __result;                                                          \
+   })
+#else
+# define INLINE_SETXID_SYSCALL(name, nr, args...) \
+  ({                                                                   \
+    extern __typeof (__nptl_setxid) __nptl_setxid __attribute__((weak));\
+    int __result;                                                      \
+    if (__builtin_expect (__nptl_setxid        != NULL, 0))                    \
+      {                                                                        \
+       struct xid_command __cmd;                                       \
+       __cmd.syscall_no = __NR_##name;                                 \
+       __SETXID_##nr (__cmd, args);                                    \
+       __result =__nptl_setxid (&__cmd);                               \
+      }                                                                        \
+    else                                                               \
+      __result = INLINE_SYSCALL (name, nr, args);                      \
+    __result;                                                          \
+   })
+#endif
diff --git a/nptl/tst-setuid1-static.c b/nptl/tst-setuid1-static.c
new file mode 100644 (file)
index 0000000..46d26f0
--- /dev/null
@@ -0,0 +1 @@
+#include "tst-setuid1.c"
diff --git a/nptl/tst-setuid1.c b/nptl/tst-setuid1.c
new file mode 100644 (file)
index 0000000..f026c57
--- /dev/null
@@ -0,0 +1,1085 @@
+/* Copyright (C) 2004 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Jakub Jelinek <jaku@redhat.com>, 2004.
+
+   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 <pthread.h>
+#include <pwd.h>
+#include <grp.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <sys/wait.h>
+#include <unistd.h>
+
+
+static pthread_barrier_t b3, b4;
+static uid_t prev_ruid, prev_euid, prev_suid, nobody_uid;
+static gid_t prev_rgid, prev_egid, prev_sgid, nobody_gid;
+enum ACTION { PREPARE, SET, CHECK_BEFORE, CHECK_AFTER };
+#define TESTNO(arg) ((long int) (arg) & 0xff)
+#define THREADNO(arg) ((long int) (arg) >> 8)
+
+
+static void
+check_prev_uid (int tno)
+{
+  uid_t ruid, euid, suid;
+  if (getresuid (&ruid, &euid, &suid) < 0)
+    {
+      printf ("getresuid failed: %d %m\n", tno);
+      exit (1);
+    }
+
+  if (ruid != prev_ruid || euid != prev_euid || suid != prev_suid)
+    {
+      printf ("uids before in %d (%d %d %d) != (%d %d %d)\n", tno,
+             ruid, euid, suid, prev_ruid, prev_euid, prev_suid);
+      exit (1);
+    }
+}
+
+
+static void
+check_prev_gid (int tno)
+{
+  gid_t rgid, egid, sgid;
+  if (getresgid (&rgid, &egid, &sgid) < 0)
+    {
+      printf ("getresgid failed: %d %m\n", tno);
+      exit (1);
+    }
+
+  if (rgid != prev_rgid || egid != prev_egid || sgid != prev_sgid)
+    {
+      printf ("gids before in %d (%d %d %d) != (%d %d %d)\n", tno,
+             rgid, egid, sgid, prev_rgid, prev_egid, prev_sgid);
+      exit (1);
+    }
+}
+
+
+static void
+test_setuid1 (enum ACTION action, int tno)
+{
+  if (action == PREPARE)
+    return;
+
+  if (action != CHECK_AFTER)
+    check_prev_uid (tno);
+
+  if (action == SET && setuid (nobody_uid) < 0)
+    {
+       printf ("setuid failed: %m\n");
+       exit (1);
+    }
+
+  if (action != CHECK_BEFORE)
+    {
+      uid_t ruid, euid, suid;
+      if (getresuid (&ruid, &euid, &suid) < 0)
+       {
+         printf ("getresuid failed: %d %m\n", tno);
+         exit (1);
+       }
+
+      if (ruid != nobody_uid || euid != nobody_uid || suid != nobody_uid)
+       {
+         printf ("after setuid %d (%d %d %d) != (%d %d %d)\n", tno,
+                 ruid, euid, suid, nobody_uid, nobody_uid, nobody_uid);
+         exit (1);
+       }
+    }
+}
+
+
+static void
+test_setuid2 (enum ACTION action, int tno)
+{
+  if (action == PREPARE)
+    {
+      if (setresuid (nobody_uid, nobody_uid, -1) < 0)
+       {
+         printf ("setresuid failed: %m\n");
+         exit (1);
+       }
+
+      prev_ruid = nobody_uid;
+      prev_euid = nobody_uid;
+      return;
+    }
+
+  if (action != CHECK_AFTER)
+    check_prev_uid (tno);
+
+  if (action == SET && setuid (prev_suid) < 0)
+    {
+      printf ("setuid failed: %m\n");
+      exit (1);
+    }
+
+  if (action != CHECK_BEFORE)
+    {
+      uid_t ruid, euid, suid;
+      if (getresuid (&ruid, &euid, &suid) < 0)
+       {
+         printf ("getresuid failed: %d %m\n", tno);
+         exit (1);
+       }
+
+      if (ruid != nobody_uid || euid != prev_suid || suid != prev_suid)
+       {
+         printf ("after setuid %d (%d %d %d) != (%d %d %d)\n", tno,
+                 ruid, euid, suid, nobody_uid, prev_suid, prev_suid);
+         exit (1);
+       }
+    }
+}
+
+
+static void
+test_seteuid1 (enum ACTION action, int tno)
+{
+  if (action == PREPARE)
+    return;
+
+  if (action != CHECK_AFTER)
+    check_prev_uid (tno);
+
+  if (action == SET && seteuid (nobody_uid) < 0)
+    {
+       printf ("seteuid failed: %m\n");
+       exit (1);
+    }
+
+  if (action != CHECK_BEFORE)
+    {
+      uid_t ruid, euid, suid;
+      if (getresuid (&ruid, &euid, &suid) < 0)
+       {
+         printf ("getresuid failed: %d %m\n", tno);
+         exit (1);
+       }
+
+      if (ruid != prev_ruid || euid != nobody_uid || suid != prev_suid)
+       {
+         printf ("after seteuid %d (%d %d %d) != (%d %d %d)\n", tno,
+                 ruid, euid, suid, prev_ruid, nobody_uid, prev_suid);
+         exit (1);
+       }
+    }
+}
+
+
+static void
+test_seteuid2 (enum ACTION action, int tno)
+{
+  if (action == PREPARE)
+    {
+      if (setresuid (nobody_uid, nobody_uid, -1) < 0)
+       {
+         printf ("setresuid failed: %m\n");
+         exit (1);
+       }
+
+      prev_ruid = nobody_uid;
+      prev_euid = nobody_uid;
+      nobody_uid = prev_suid;
+      return;
+    }
+
+  test_seteuid1 (action, tno);
+}
+
+
+static void
+test_setreuid1 (enum ACTION action, int tno)
+{
+  if (action == PREPARE)
+    return;
+
+  if (action != CHECK_AFTER)
+    check_prev_uid (tno);
+
+  if (action == SET && setreuid (-1, nobody_uid) < 0)
+    {
+       printf ("setreuid failed: %m\n");
+       exit (1);
+    }
+
+  if (action != CHECK_BEFORE)
+    {
+      uid_t ruid, euid, suid, esuid;
+      if (getresuid (&ruid, &euid, &suid) < 0)
+       {
+         printf ("getresuid failed: %d %m\n", tno);
+         exit (1);
+       }
+
+      if (prev_ruid != nobody_uid)
+       esuid = nobody_uid;
+      else
+       esuid = prev_suid;
+
+      if (ruid != prev_ruid || euid != nobody_uid || suid != esuid)
+       {
+         printf ("after setreuid %d (%d %d %d) != (%d %d %d)\n", tno,
+                 ruid, euid, suid, prev_ruid, nobody_uid, esuid);
+         exit (1);
+       }
+    }
+}
+
+
+static void
+test_setreuid2 (enum ACTION action, int tno)
+{
+  if (action == PREPARE)
+    return;
+
+  if (action != CHECK_AFTER)
+    check_prev_uid (tno);
+
+  if (action == SET && setreuid (nobody_uid, -1) < 0)
+    {
+       printf ("setreuid failed: %m\n");
+       exit (1);
+    }
+
+  if (action != CHECK_BEFORE)
+    {
+      uid_t ruid, euid, suid;
+      if (getresuid (&ruid, &euid, &suid) < 0)
+       {
+         printf ("getresuid failed: %d %m\n", tno);
+         exit (1);
+       }
+
+      if (ruid != nobody_uid || euid != prev_euid || suid != prev_euid)
+       {
+         printf ("after setreuid %d (%d %d %d) != (%d %d %d)\n", tno,
+                 ruid, euid, suid, nobody_uid, prev_euid, prev_euid);
+         exit (1);
+       }
+    }
+}
+
+
+static void
+test_setreuid3 (enum ACTION action, int tno)
+{
+  if (action == PREPARE)
+    return;
+
+  if (action != CHECK_AFTER)
+    check_prev_uid (tno);
+
+  if (action == SET && setreuid (nobody_uid, nobody_uid) < 0)
+    {
+       printf ("setreuid failed: %m\n");
+       exit (1);
+    }
+
+  if (action != CHECK_BEFORE)
+    {
+      uid_t ruid, euid, suid;
+      if (getresuid (&ruid, &euid, &suid) < 0)
+       {
+         printf ("getresuid failed: %d %m\n", tno);
+         exit (1);
+       }
+
+      if (ruid != nobody_uid || euid != nobody_uid || suid != nobody_uid)
+       {
+         printf ("after setreuid %d (%d %d %d) != (%d %d %d)\n", tno,
+                 ruid, euid, suid, nobody_uid, nobody_uid, nobody_uid);
+         exit (1);
+       }
+    }
+}
+
+
+static void
+test_setreuid4 (enum ACTION action, int tno)
+{
+  if (action == PREPARE)
+    {
+      if (setresuid (nobody_uid, nobody_uid, -1) < 0)
+       {
+         printf ("setresuid failed: %m\n");
+         exit (1);
+       }
+
+      prev_ruid = nobody_uid;
+      prev_euid = nobody_uid;
+      nobody_uid = prev_suid;
+      return;
+    }
+
+  test_setreuid1 (action, tno);
+}
+
+
+static void
+test_setresuid1 (enum ACTION action, int tno)
+{
+  if (action == PREPARE)
+    return;
+
+  if (action != CHECK_AFTER)
+    check_prev_uid (tno);
+
+  if (action == SET && setresuid (-1, nobody_uid, -1) < 0)
+    {
+       printf ("setresuid failed: %m\n");
+       exit (1);
+    }
+
+  if (action != CHECK_BEFORE)
+    {
+      uid_t ruid, euid, suid;
+      if (getresuid (&ruid, &euid, &suid) < 0)
+       {
+         printf ("getresuid failed: %d %m\n", tno);
+         exit (1);
+       }
+
+      if (ruid != prev_ruid || euid != nobody_uid || suid != prev_suid)
+       {
+         printf ("after setresuid %d (%d %d %d) != (%d %d %d)\n", tno,
+                 ruid, euid, suid, prev_ruid, nobody_uid, prev_suid);
+         exit (1);
+       }
+    }
+}
+
+
+static void
+test_setresuid2 (enum ACTION action, int tno)
+{
+  if (action == PREPARE)
+    return;
+
+  if (action != CHECK_AFTER)
+    check_prev_uid (tno);
+
+  if (action == SET && setresuid (prev_euid, nobody_uid, nobody_uid) < 0)
+    {
+       printf ("setresuid failed: %m\n");
+       exit (1);
+    }
+
+  if (action != CHECK_BEFORE)
+    {
+      uid_t ruid, euid, suid;
+      if (getresuid (&ruid, &euid, &suid) < 0)
+       {
+         printf ("getresuid failed: %d %m\n", tno);
+         exit (1);
+       }
+
+      if (ruid != prev_euid || euid != nobody_uid || suid != nobody_uid)
+       {
+         printf ("after setresuid %d (%d %d %d) != (%d %d %d)\n", tno,
+                 ruid, euid, suid, prev_euid, nobody_uid, nobody_uid);
+         exit (1);
+       }
+    }
+}
+
+
+static void
+test_setresuid3 (enum ACTION action, int tno)
+{
+  if (action == PREPARE)
+    return;
+
+  if (action != CHECK_AFTER)
+    check_prev_uid (tno);
+
+  if (action == SET && setresuid (nobody_uid, nobody_uid, nobody_uid) < 0)
+    {
+       printf ("setresuid failed: %m\n");
+       exit (1);
+    }
+
+  if (action != CHECK_BEFORE)
+    {
+      uid_t ruid, euid, suid;
+      if (getresuid (&ruid, &euid, &suid) < 0)
+       {
+         printf ("getresuid failed: %d %m\n", tno);
+         exit (1);
+       }
+
+      if (ruid != nobody_uid || euid != nobody_uid || suid != nobody_uid)
+       {
+         printf ("after setresuid %d (%d %d %d) != (%d %d %d)\n", tno,
+                 ruid, euid, suid, nobody_uid, nobody_uid, nobody_uid);
+         exit (1);
+       }
+    }
+}
+
+
+static void
+test_setresuid4 (enum ACTION action, int tno)
+{
+  if (action == PREPARE)
+    {
+      if (setresuid (nobody_uid, nobody_uid, -1) < 0)
+       {
+         printf ("setresuid failed: %m\n");
+         exit (1);
+       }
+
+      prev_ruid = nobody_uid;
+      prev_euid = nobody_uid;
+      nobody_uid = prev_suid;
+      return;
+    }
+
+  test_setresuid1 (action, tno);
+}
+
+
+static void
+test_setgid1 (enum ACTION action, int tno)
+{
+  if (action == PREPARE)
+    return;
+
+  if (action != CHECK_AFTER)
+    check_prev_gid (tno);
+
+  if (action == SET && setgid (nobody_gid) < 0)
+    {
+       printf ("setgid failed: %m\n");
+       exit (1);
+    }
+
+  if (action != CHECK_BEFORE)
+    {
+      gid_t rgid, egid, sgid;
+      if (getresgid (&rgid, &egid, &sgid) < 0)
+       {
+         printf ("getresgid failed: %d %m\n", tno);
+         exit (1);
+       }
+
+      if (rgid != nobody_gid || egid != nobody_gid || sgid != nobody_gid)
+       {
+         printf ("after setgid %d (%d %d %d) != (%d %d %d)\n", tno,
+                 rgid, egid, sgid, nobody_gid, nobody_gid, nobody_gid);
+         exit (1);
+       }
+    }
+}
+
+
+static void
+test_setgid2 (enum ACTION action, int tno)
+{
+  if (action == PREPARE)
+    {
+      if (setresgid (nobody_gid, nobody_gid, -1) < 0)
+       {
+         printf ("setresgid failed: %m\n");
+         exit (1);
+       }
+
+      prev_rgid = nobody_gid;
+      prev_egid = nobody_gid;
+
+      if (setresuid (nobody_uid, nobody_uid, -1) < 0)
+       {
+         printf ("setresuid failed: %m\n");
+         exit (1);
+       }
+
+      prev_ruid = nobody_uid;
+      prev_euid = nobody_uid;
+      return;
+    }
+
+  if (action != CHECK_AFTER)
+    check_prev_gid (tno);
+
+  if (action == SET && setgid (prev_sgid) < 0)
+    {
+      printf ("setgid failed: %m\n");
+      exit (1);
+    }
+
+  if (action != CHECK_BEFORE)
+    {
+      gid_t rgid, egid, sgid;
+      if (getresgid (&rgid, &egid, &sgid) < 0)
+       {
+         printf ("getresgid failed: %d %m\n", tno);
+         exit (1);
+       }
+
+      if (rgid != nobody_gid || egid != prev_sgid || sgid != prev_sgid)
+       {
+         printf ("after setgid %d (%d %d %d) != (%d %d %d)\n", tno,
+                 rgid, egid, sgid, nobody_gid, prev_sgid, prev_sgid);
+         exit (1);
+       }
+    }
+}
+
+
+static void
+test_setegid1 (enum ACTION action, int tno)
+{
+  if (action == PREPARE)
+    return;
+
+  if (action != CHECK_AFTER)
+    check_prev_gid (tno);
+
+  if (action == SET && setegid (nobody_gid) < 0)
+    {
+       printf ("setegid failed: %m\n");
+       exit (1);
+    }
+
+  if (action != CHECK_BEFORE)
+    {
+      gid_t rgid, egid, sgid;
+      if (getresgid (&rgid, &egid, &sgid) < 0)
+       {
+         printf ("getresgid failed: %d %m\n", tno);
+         exit (1);
+       }
+
+      if (rgid != prev_rgid || egid != nobody_gid || sgid != prev_sgid)
+       {
+         printf ("after setegid %d (%d %d %d) != (%d %d %d)\n", tno,
+                 rgid, egid, sgid, prev_rgid, nobody_gid, prev_sgid);
+         exit (1);
+       }
+    }
+}
+
+
+static void
+test_setegid2 (enum ACTION action, int tno)
+{
+  if (action == PREPARE)
+    {
+      if (setresgid (nobody_gid, nobody_gid, -1) < 0)
+       {
+         printf ("setresgid failed: %m\n");
+         exit (1);
+       }
+
+      prev_rgid = nobody_gid;
+      prev_egid = nobody_gid;
+      nobody_gid = prev_sgid;
+      return;
+    }
+
+  test_setegid1 (action, tno);
+}
+
+
+static void
+test_setregid1 (enum ACTION action, int tno)
+{
+  if (action == PREPARE)
+    return;
+
+  if (action != CHECK_AFTER)
+    check_prev_gid (tno);
+
+  if (action == SET && setregid (-1, nobody_gid) < 0)
+    {
+       printf ("setregid failed: %m\n");
+       exit (1);
+    }
+
+  if (action != CHECK_BEFORE)
+    {
+      gid_t rgid, egid, sgid, esgid;
+      if (getresgid (&rgid, &egid, &sgid) < 0)
+       {
+         printf ("getresgid failed: %d %m\n", tno);
+         exit (1);
+       }
+
+      if (prev_rgid != nobody_gid)
+       esgid = nobody_gid;
+      else
+       esgid = prev_sgid;
+
+      if (rgid != prev_rgid || egid != nobody_gid || sgid != esgid)
+       {
+         printf ("after setregid %d (%d %d %d) != (%d %d %d)\n", tno,
+                 rgid, egid, sgid, prev_rgid, nobody_gid, esgid);
+         exit (1);
+       }
+    }
+}
+
+
+static void
+test_setregid2 (enum ACTION action, int tno)
+{
+  if (action == PREPARE)
+    return;
+
+  if (action != CHECK_AFTER)
+    check_prev_gid (tno);
+
+  if (action == SET && setregid (nobody_gid, -1) < 0)
+    {
+       printf ("setregid failed: %m\n");
+       exit (1);
+    }
+
+  if (action != CHECK_BEFORE)
+    {
+      gid_t rgid, egid, sgid;
+      if (getresgid (&rgid, &egid, &sgid) < 0)
+       {
+         printf ("getresgid failed: %d %m\n", tno);
+         exit (1);
+       }
+
+      if (rgid != nobody_gid || egid != prev_egid || sgid != prev_egid)
+       {
+         printf ("after setregid %d (%d %d %d) != (%d %d %d)\n", tno,
+                 rgid, egid, sgid, nobody_gid, prev_egid, prev_egid);
+         exit (1);
+       }
+    }
+}
+
+
+static void
+test_setregid3 (enum ACTION action, int tno)
+{
+  if (action == PREPARE)
+    return;
+
+  if (action != CHECK_AFTER)
+    check_prev_gid (tno);
+
+  if (action == SET && setregid (nobody_gid, nobody_gid) < 0)
+    {
+       printf ("setregid failed: %m\n");
+       exit (1);
+    }
+
+  if (action != CHECK_BEFORE)
+    {
+      gid_t rgid, egid, sgid;
+      if (getresgid (&rgid, &egid, &sgid) < 0)
+       {
+         printf ("getresgid failed: %d %m\n", tno);
+         exit (1);
+       }
+
+      if (rgid != nobody_gid || egid != nobody_gid || sgid != nobody_gid)
+       {
+         printf ("after setregid %d (%d %d %d) != (%d %d %d)\n", tno,
+                 rgid, egid, sgid, nobody_gid, nobody_gid, nobody_gid);
+         exit (1);
+       }
+    }
+}
+
+
+static void
+test_setregid4 (enum ACTION action, int tno)
+{
+  if (action == PREPARE)
+    {
+      if (setresgid (nobody_gid, nobody_gid, -1) < 0)
+       {
+         printf ("setresgid failed: %m\n");
+         exit (1);
+       }
+
+      prev_rgid = nobody_gid;
+      prev_egid = nobody_gid;
+      nobody_gid = prev_sgid;
+      return;
+    }
+
+  test_setregid1 (action, tno);
+}
+
+
+static void
+test_setresgid1 (enum ACTION action, int tno)
+{
+  if (action == PREPARE)
+    return;
+
+  if (action != CHECK_AFTER)
+    check_prev_gid (tno);
+
+  if (action == SET && setresgid (-1, nobody_gid, -1) < 0)
+    {
+       printf ("setresgid failed: %m\n");
+       exit (1);
+    }
+
+  if (action != CHECK_BEFORE)
+    {
+      gid_t rgid, egid, sgid;
+      if (getresgid (&rgid, &egid, &sgid) < 0)
+       {
+         printf ("getresgid failed: %d %m\n", tno);
+         exit (1);
+       }
+
+      if (rgid != prev_rgid || egid != nobody_gid || sgid != prev_sgid)
+       {
+         printf ("after setresgid %d (%d %d %d) != (%d %d %d)\n", tno,
+                 rgid, egid, sgid, prev_rgid, nobody_gid, prev_sgid);
+         exit (1);
+       }
+    }
+}
+
+
+static void
+test_setresgid2 (enum ACTION action, int tno)
+{
+  if (action == PREPARE)
+    return;
+
+  if (action != CHECK_AFTER)
+    check_prev_gid (tno);
+
+  if (action == SET && setresgid (prev_egid, nobody_gid, nobody_gid) < 0)
+    {
+       printf ("setresgid failed: %m\n");
+       exit (1);
+    }
+
+  if (action != CHECK_BEFORE)
+    {
+      gid_t rgid, egid, sgid;
+      if (getresgid (&rgid, &egid, &sgid) < 0)
+       {
+         printf ("getresgid failed: %d %m\n", tno);
+         exit (1);
+       }
+
+      if (rgid != prev_egid || egid != nobody_gid || sgid != nobody_gid)
+       {
+         printf ("after setresgid %d (%d %d %d) != (%d %d %d)\n", tno,
+                 rgid, egid, sgid, prev_egid, nobody_gid, nobody_gid);
+         exit (1);
+       }
+    }
+}
+
+
+static void
+test_setresgid3 (enum ACTION action, int tno)
+{
+  if (action == PREPARE)
+    return;
+
+  if (action != CHECK_AFTER)
+    check_prev_gid (tno);
+
+  if (action == SET && setresgid (nobody_gid, nobody_gid, nobody_gid) < 0)
+    {
+       printf ("setresgid failed: %m\n");
+       exit (1);
+    }
+
+  if (action != CHECK_BEFORE)
+    {
+      gid_t rgid, egid, sgid;
+      if (getresgid (&rgid, &egid, &sgid) < 0)
+       {
+         printf ("getresgid failed: %d %m\n", tno);
+         exit (1);
+       }
+
+      if (rgid != nobody_gid || egid != nobody_gid || sgid != nobody_gid)
+       {
+         printf ("after setresgid %d (%d %d %d) != (%d %d %d)\n", tno,
+                 rgid, egid, sgid, nobody_gid, nobody_gid, nobody_gid);
+         exit (1);
+       }
+    }
+}
+
+
+static void
+test_setresgid4 (enum ACTION action, int tno)
+{
+  if (action == PREPARE)
+    {
+      if (setresgid (nobody_gid, nobody_gid, -1) < 0)
+       {
+         printf ("setresgid failed: %m\n");
+         exit (1);
+       }
+
+      prev_rgid = nobody_gid;
+      prev_egid = nobody_gid;
+      nobody_gid = prev_sgid;
+      return;
+    }
+
+  test_setresgid1 (action, tno);
+}
+
+
+static struct setuid_test
+{
+  const char *name;
+  void (*test) (enum ACTION, int tno);
+} setuid_tests[] =
+{
+  { "setuid1", test_setuid1 },
+  { "setuid2", test_setuid2 },
+  { "seteuid1", test_seteuid1 },
+  { "seteuid2", test_seteuid2 },
+  { "setreuid1", test_setreuid1 },
+  { "setreuid2", test_setreuid2 },
+  { "setreuid3", test_setreuid3 },
+  { "setreuid4", test_setreuid4 },
+  { "setresuid1", test_setresuid1 },
+  { "setresuid2", test_setresuid2 },
+  { "setresuid3", test_setresuid3 },
+  { "setresuid4", test_setresuid4 },
+  { "setgid1", test_setgid1 },
+  { "setgid2", test_setgid2 },
+  { "setegid1", test_setegid1 },
+  { "setegid2", test_setegid2 },
+  { "setregid1", test_setregid1 },
+  { "setregid2", test_setregid2 },
+  { "setregid3", test_setregid3 },
+  { "setregid4", test_setregid4 },
+  { "setresgid1", test_setresgid1 },
+  { "setresgid2", test_setresgid2 },
+  { "setresgid3", test_setresgid3 },
+  { "setresgid4", test_setresgid4 }
+};
+
+
+static void *
+tf2 (void *arg)
+{
+  int e = pthread_barrier_wait (&b4);
+  if (e != 0 && e != PTHREAD_BARRIER_SERIAL_THREAD)
+    {
+      puts ("barrier_wait failed");
+      exit (1);
+    }
+
+  setuid_tests[TESTNO (arg)].test (CHECK_AFTER, THREADNO (arg));
+  return NULL;
+}
+
+
+static void *
+tf (void *arg)
+{
+  setuid_tests[TESTNO (arg)].test (CHECK_BEFORE, THREADNO (arg));
+
+  int e = pthread_barrier_wait (&b3);
+  if (e != 0 && e != PTHREAD_BARRIER_SERIAL_THREAD)
+    {
+      puts ("barrier_wait failed");
+      exit (1);
+    }
+
+  return tf2 (arg);
+}
+
+
+static int
+do_one_test (long int testno)
+{
+  printf ("%s test\n", setuid_tests[testno].name);
+
+  pid_t pid = fork ();
+  if (pid == 0)
+    {
+      setuid_tests[testno].test (PREPARE, 0);
+      setuid_tests[testno].test (SET, 0);
+      exit (0);
+    }
+
+  if (pid < 0)
+    {
+      printf ("fork failed: %m\n");
+      exit (1);
+    }
+
+  int status;
+  if (waitpid (pid, &status, 0) < 0)
+    {
+      printf ("waitpid failed: %m\n");
+      exit (1);
+    }
+
+  if (!WIFEXITED (status))
+    {
+      puts ("child did not exit");
+      exit (1);
+    }
+
+  if (WEXITSTATUS (status))
+    {
+      printf ("skipping %s test\n", setuid_tests[testno].name);
+      return 0;
+    }
+
+  pid = fork ();
+  if (pid == 0)
+    {
+      setuid_tests[testno].test (PREPARE, 0);
+
+      pthread_t th;
+      int e = pthread_create (&th, NULL, tf, (void *) (testno | 0x100L));
+      if (e != 0)
+       {
+         printf ("create failed: %m\n");
+         exit (1);
+       }
+
+      pthread_t th2;
+      e = pthread_create (&th2, NULL, tf, (void *) (testno | 0x200L));
+      if (e != 0)
+       {
+         printf ("create failed: %m\n");
+         exit (1);
+       }
+
+      e = pthread_barrier_wait (&b3);
+      if (e != 0 && e != PTHREAD_BARRIER_SERIAL_THREAD)
+       {
+         puts ("barrier_wait failed");
+         exit (1);
+       }
+
+      setuid_tests[testno].test (SET, 0);
+
+      pthread_t th3;
+      e = pthread_create (&th3, NULL, tf2, (void *) (testno | 0x300L));
+      if (e != 0)
+       {
+         printf ("create failed: %m\n");
+         exit (1);
+       }
+
+      e = pthread_barrier_wait (&b4);
+      if (e != 0 && e != PTHREAD_BARRIER_SERIAL_THREAD)
+       {
+         puts ("barrier_wait failed");
+         exit (1);
+       }
+
+      exit (0);
+    }
+
+  if (pid < 0)
+    {
+      printf ("fork failed: %m\n");
+      exit (1);
+    }
+
+  if (waitpid (pid, &status, 0) < 0)
+    {
+      printf ("waitpid failed: %m\n");
+      exit (1);
+    }
+
+  if (!WIFEXITED (status))
+    {
+      puts ("second child did not exit");
+      exit (1);
+    }
+
+  if (WEXITSTATUS (status))
+    exit (WEXITSTATUS (status));
+
+  return 0;
+}
+
+
+static int
+do_test (void)
+{
+  struct passwd *pwd = getpwnam ("nobody");
+  if (pwd == NULL)
+    {
+      puts ("User nobody doesn't exist");
+      return 0;
+    }
+  nobody_uid = pwd->pw_uid;
+  nobody_gid = pwd->pw_gid;
+
+  if (getresuid (&prev_ruid, &prev_euid, &prev_suid) < 0)
+    {
+      printf ("getresuid failed: %m\n");
+      exit (1);
+    }
+
+  if (getresgid (&prev_rgid, &prev_egid, &prev_sgid) < 0)
+    {
+      printf ("getresgid failed: %m\n");
+      exit (1);
+    }
+
+  if (prev_ruid == nobody_uid || prev_euid == nobody_uid
+      || prev_suid == nobody_uid)
+    {
+      puts ("already running as user nobody, skipping tests");
+      exit (0);
+    }
+
+  if (prev_rgid == nobody_gid || prev_egid == nobody_gid
+      || prev_sgid == nobody_gid)
+    {
+      puts ("already running as group nobody, skipping tests");
+      exit (0);
+    }
+
+  if (pthread_barrier_init (&b3, NULL, 3) != 0)
+    {
+      puts ("barrier_init failed");
+      exit (1);
+    }
+
+  if (pthread_barrier_init (&b4, NULL, 4) != 0)
+    {
+      puts ("barrier_init failed");
+      exit (1);
+    }
+
+  for (unsigned long int testno = 0;
+       testno < sizeof (setuid_tests) / sizeof (setuid_tests[0]);
+       ++testno)
+    do_one_test (testno);
+  return 0;
+}
+
+#define TEST_FUNCTION do_test ()
+#include "../test-skeleton.c"
index cd6a52c0989ca5ed4e5a87d60fb4a9e26da7f592..8bc15ad215b9397f6054d64be153fa76995cd8e0 100644 (file)
@@ -79,7 +79,8 @@ tests         := tstgetopt testfnm runtests runptests      \
                   bug-regex8 bug-regex9 bug-regex10 bug-regex11 bug-regex12 \
                   bug-regex13 bug-regex14 bug-regex15 bug-regex16 \
                   bug-regex17 bug-regex18 bug-regex19 bug-regex20 \
-                  bug-regex21 bug-regex22 bug-regex23 tst-nice tst-nanosleep \
+                  bug-regex21 bug-regex22 bug-regex23 bug-regex24 \
+                  tst-nice tst-nanosleep \
                   transbug tst-rxspencer tst-pcre tst-boost \
                   bug-ga1 tst-vfork1 tst-vfork2 tst-waitid \
                   tst-getaddrinfo2 bug-glob1 bug-glob2
diff --git a/posix/bug-regex24.c b/posix/bug-regex24.c
new file mode 100644 (file)
index 0000000..83ea10b
--- /dev/null
@@ -0,0 +1,59 @@
+#include <regex.h>
+#include <stdio.h>
+
+#define str "civic"
+
+#define N 10
+static const char *expected[N] =
+  {
+    str, "c", "i", "", "", "", "", "", "", ""
+  };
+
+static int
+do_test (void)
+{
+  regex_t rbuf;
+  static const char pat[] = "\
+^(.?)(.?)(.?)(.?)(.?)(.?)(.?)(.?)(.?).?\\9\\8\\7\\6\\5\\4\\3\\2\\1$";
+
+  int err = regcomp (&rbuf, pat, REG_EXTENDED);
+  if (err != 0)
+    {
+      char errstr[300];
+      regerror (err, &rbuf, errstr, sizeof (errstr));
+      puts (errstr);
+      return err;
+    }
+
+  regmatch_t m[N];
+  err = regexec (&rbuf, str, N, m, 0);
+  if (err != 0)
+    {
+      puts ("regexec failed");
+      return 1;
+    }
+
+  int result = 0;
+  for (int i = 0; i < N; ++i)
+    if (m[i].rm_so == -1)
+      {
+       printf ("m[%d] unused\n", i);
+       result = 1;
+      }
+    else
+      {
+       int len = m[i].rm_eo - m[i].rm_so;
+
+       printf ("m[%d] = \"%.*s\"\n", i, len, str + m[i].rm_so);
+
+       if (strlen (expected[i]) != len
+           || memcmp (expected[i], str + m[i].rm_so, len) != 0)
+         result = 1;
+      }
+
+  return result;
+}
+
+#define TIMEOUT 30
+#define TEST_FUNCTION do_test ()
+#include "../test-skeleton.c"
index 609719f79cecd6109259d94dce8647ff3d3865f0..bb1d73d9a0157b363a38980ecab185c40b8a7265 100644 (file)
@@ -576,7 +576,7 @@ re_string_reconstruct (pstr, idx, eflags)
      int idx, eflags;
 {
   int offset = idx - pstr->raw_mbs_idx;
-  if (offset < 0)
+  if (BE (offset < 0, 0))
     {
       /* Reset buffer.  */
 #ifdef RE_ENABLE_I18N
@@ -596,10 +596,10 @@ re_string_reconstruct (pstr, idx, eflags)
       offset = idx;
     }
 
-  if (offset != 0)
+  if (BE (offset != 0, 1))
     {
       /* Are the characters which are already checked remain?  */
-      if (offset < pstr->valid_raw_len
+      if (BE (offset < pstr->valid_raw_len, 1)
 #ifdef RE_ENABLE_I18N
          /* Handling this would enlarge the code too much.
             Accept a slowdown in that case.  */
@@ -614,7 +614,7 @@ re_string_reconstruct (pstr, idx, eflags)
            memmove (pstr->wcs, pstr->wcs + offset,
                     (pstr->valid_len - offset) * sizeof (wint_t));
 #endif /* RE_ENABLE_I18N */
-         if (pstr->mbs_allocated)
+         if (BE (pstr->mbs_allocated, 0))
            memmove (pstr->mbs, pstr->mbs + offset,
                     pstr->valid_len - offset);
          pstr->valid_len -= offset;
@@ -711,7 +711,7 @@ re_string_reconstruct (pstr, idx, eflags)
                                      ? CONTEXT_NEWLINE : 0));
            }
        }
-      if (!pstr->mbs_allocated)
+      if (!BE (pstr->mbs_allocated, 0))
        pstr->mbs += offset;
     }
   pstr->raw_mbs_idx = idx;
@@ -733,16 +733,17 @@ re_string_reconstruct (pstr, idx, eflags)
     }
   else
 #endif /* RE_ENABLE_I18N */
+  if (BE (pstr->mbs_allocated, 0))
     {
       if (pstr->icase)
        build_upper_buffer (pstr);
       else if (pstr->trans != NULL)
        re_string_translate_buffer (pstr);
-      else
-       pstr->valid_len = pstr->len;
     }
-  pstr->cur_idx = 0;
+  else
+    pstr->valid_len = pstr->len;
 
+  pstr->cur_idx = 0;
   return REG_NOERROR;
 }
 
@@ -840,16 +841,13 @@ re_string_context_at (input, idx, eflags)
      int idx, eflags;
 {
   int c;
-  if (idx < 0 || idx == input->len)
-    {
-      if (idx < 0)
-       /* In this case, we use the value stored in input->tip_context,
-          since we can't know the character in input->mbs[-1] here.  */
-       return input->tip_context;
-      else /* (idx == input->len) */
-       return ((eflags & REG_NOTEOL) ? CONTEXT_ENDBUF
-               : CONTEXT_NEWLINE | CONTEXT_ENDBUF);
-    }
+  if (BE (idx < 0, 0))
+    /* In this case, we use the value stored in input->tip_context,
+       since we can't know the character in input->mbs[-1] here.  */
+    return input->tip_context;
+  if (BE (idx == input->len, 0))
+    return ((eflags & REG_NOTEOL) ? CONTEXT_ENDBUF
+           : CONTEXT_NEWLINE | CONTEXT_ENDBUF);
 #ifdef RE_ENABLE_I18N
   if (input->mb_cur_max > 1)
     {
index 023056c0282793c10f68e5ed1d373c8dd59d07bd..14d95a5b841ec7e2bb732741b018aa9cbf09d0e9 100644 (file)
@@ -548,9 +548,9 @@ struct re_backref_cache_entry
   int str_idx;
   int subexp_from;
   int subexp_to;
-  /* We need only one byte from the following field.  If other small
-     fields are added the type could be changed to 'char'.  */
-  int more;
+  char more;
+  char unused;
+  unsigned short int eps_reachable_subexps_map;
 };
 
 typedef struct
index 72ae70b9164bd457c9c8fc12b7afe708b69ca5f9..a03df2636a8d92cf3c4f0dcacf557a4b898365cb 100644 (file)
@@ -22,8 +22,6 @@ static reg_errcode_t match_ctx_init (re_match_context_t *cache, int eflags,
                                     int n) internal_function;
 static void match_ctx_clean (re_match_context_t *mctx) internal_function;
 static void match_ctx_free (re_match_context_t *cache) internal_function;
-static void match_ctx_free_subtops (re_match_context_t *mctx)
-     internal_function;
 static reg_errcode_t match_ctx_add_entry (re_match_context_t *cache, int node,
                                          int str_idx, int from, int to)
      internal_function;
@@ -606,15 +604,16 @@ re_search_internal (preg, string, length, start, range, stop, nmatch, pmatch,
   reg_errcode_t err;
   re_dfa_t *dfa = (re_dfa_t *)preg->buffer;
   int left_lim, right_lim, incr;
-  int fl_longest_match, match_first, match_last = -1;
-  int fast_translate, sb;
+  int fl_longest_match, match_first, match_kind, match_last = -1;
+  int sb, ch;
 #if defined _LIBC || (defined __STDC_VERSION__ && __STDC_VERSION__ >= 199901L)
   re_match_context_t mctx = { .dfa = dfa };
 #else
   re_match_context_t mctx;
 #endif
-  char *fastmap = ((preg->fastmap != NULL && preg->fastmap_accurate
-                   && range && !preg->can_be_null) ? preg->fastmap : NULL);
+  char *fastmap = (preg->fastmap != NULL && preg->fastmap_accurate
+                  && range && !preg->can_be_null) ? preg->fastmap : NULL;
+  unsigned RE_TRANSLATE_TYPE t = (unsigned RE_TRANSLATE_TYPE) preg->translate;
 
 #if !(defined _LIBC || (defined __STDC_VERSION__ && __STDC_VERSION__ >= 199901L))
   memset (&mctx, '\0', sizeof (re_match_context_t));
@@ -685,88 +684,100 @@ re_search_internal (preg, string, length, start, range, stop, nmatch, pmatch,
   left_lim = (range < 0) ? start + range : start;
   right_lim = (range < 0) ? start : start + range;
   sb = dfa->mb_cur_max == 1;
-  fast_translate = sb || !(preg->syntax & RE_ICASE || preg->translate);
-
-  for (;;)
+  match_kind =
+    (fastmap
+     ? ((sb || !(preg->syntax & RE_ICASE || t) ? 4 : 0)
+       | (range >= 0 ? 2 : 0)
+       | (t != NULL ? 1 : 0))
+     : 8);
+
+  for (;; match_first += incr)
     {
-      /* At first get the current byte from input string.  */
-      if (fastmap)
+      err = REG_NOMATCH;
+      if (match_first < left_lim || right_lim < match_first)
+       goto free_return;
+
+      /* Advance as rapidly as possible through the string, until we
+        find a plausible place to start matching.  This may be done
+        with varying efficiency, so there are various possibilities:
+        only the most common of them are specialized, in order to
+        save on code size.  We use a switch statement for speed.  */
+      switch (match_kind)
        {
-         if (BE (fast_translate, 1))
+       case 8:
+         /* No fastmap.  */
+         break;
+
+       case 7:
+         /* Fastmap with single-byte translation, match forward.  */
+         while (BE (match_first < right_lim, 1)
+                && !fastmap[t[(unsigned char) string[match_first]]])
+           ++match_first;
+         goto forward_match_found_start_or_reached_end;
+
+       case 6:
+         /* Fastmap without translation, match forward.  */
+         while (BE (match_first < right_lim, 1)
+                && !fastmap[(unsigned char) string[match_first]])
+           ++match_first;
+
+       forward_match_found_start_or_reached_end:
+         if (BE (match_first == right_lim, 0))
            {
-             unsigned RE_TRANSLATE_TYPE t
-               = (unsigned RE_TRANSLATE_TYPE) preg->translate;
-             if (BE (range >= 0, 1))
-               {
-                 if (BE (t != NULL, 0))
-                   {
-                     while (BE (match_first < right_lim, 1)
-                            && !fastmap[t[(unsigned char) string[match_first]]])
-                       ++match_first;
-                   }
-                 else
-                   {
-                     while (BE (match_first < right_lim, 1)
-                            && !fastmap[(unsigned char) string[match_first]])
-                       ++match_first;
-                   }
-                 if (BE (match_first == right_lim, 0))
-                   {
-                     int ch = match_first >= length
-                              ? 0 : (unsigned char) string[match_first];
-                     if (!fastmap[t ? t[ch] : ch])
-                       break;
-                   }
-               }
-             else
-               {
-                 while (match_first >= left_lim)
-                   {
-                     int ch = match_first >= length
-                              ? 0 : (unsigned char) string[match_first];
-                     if (fastmap[t ? t[ch] : ch])
-                       break;
-                     --match_first;
-                   }
-                 if (match_first < left_lim)
-                   break;
-               }
+             ch = match_first >= length
+                      ? 0 : (unsigned char) string[match_first];
+             if (!fastmap[t ? t[ch] : ch])
+               goto free_return;
            }
-         else
+         break;
+
+       case 4:
+       case 5:
+         /* Fastmap without multi-byte translation, match backwards.  */
+         while (match_first >= left_lim)
            {
-             int ch;
+             ch = match_first >= length
+                      ? 0 : (unsigned char) string[match_first];
+             if (fastmap[t ? t[ch] : ch])
+               break;
+             --match_first;
+           }
+         if (match_first < left_lim)
+           goto free_return;
+         break;
 
-             do
+       default:
+         /* In this case, we can't determine easily the current byte,
+            since it might be a component byte of a multibyte
+            character.  Then we use the constructed buffer instead.  */
+         for (;;)
+           {
+             /* If MATCH_FIRST is out of the valid range, reconstruct the
+                buffers.  */
+             unsigned int offset = match_first - mctx.input.raw_mbs_idx;
+             if (BE (offset >= (unsigned int) mctx.input.valid_raw_len, 0))
                {
-                 /* In this case, we can't determine easily the current byte,
-                    since it might be a component byte of a multibyte
-                    character.  Then we use the constructed buffer
-                    instead.  */
-                 /* If MATCH_FIRST is out of the valid range, reconstruct the
-                    buffers.  */
-                 if (mctx.input.raw_mbs_idx + mctx.input.valid_raw_len
-                     <= match_first
-                     || match_first < mctx.input.raw_mbs_idx)
-                   {
-                     err = re_string_reconstruct (&mctx.input, match_first,
-                                                  eflags);
-                     if (BE (err != REG_NOERROR, 0))
-                       goto free_return;
-                   }
-                 /* If MATCH_FIRST is out of the buffer, leave it as '\0'.
-                    Note that MATCH_FIRST must not be smaller than 0.  */
-                 ch = ((match_first >= length) ? 0
-                      : re_string_byte_at (&mctx.input,
-                                           match_first
-                                           - mctx.input.raw_mbs_idx));
-                 if (fastmap[ch])
-                   break;
-                 match_first += incr;
+                 err = re_string_reconstruct (&mctx.input, match_first,
+                                              eflags);
+                 if (BE (err != REG_NOERROR, 0))
+                   goto free_return;
+
+                 offset = match_first - mctx.input.raw_mbs_idx;
                }
-             while (match_first >= left_lim && match_first <= right_lim);
-             if (! fastmap[ch])
+             /* If MATCH_FIRST is out of the buffer, leave it as '\0'.
+                Note that MATCH_FIRST must not be smaller than 0.  */
+             ch = (match_first >= length
+                   ? 0 : re_string_byte_at (&mctx.input, offset));
+             if (fastmap[ch])
                break;
+             match_first += incr;
+             if (match_first < left_lim || match_first > right_lim)
+               {
+                 err = REG_NOMATCH;
+                 goto free_return;
+               }
            }
+         break;
        }
 
       /* Reconstruct the buffers so that the matcher can assume that
@@ -774,57 +785,60 @@ re_search_internal (preg, string, length, start, range, stop, nmatch, pmatch,
       err = re_string_reconstruct (&mctx.input, match_first, eflags);
       if (BE (err != REG_NOERROR, 0))
        goto free_return;
+
 #ifdef RE_ENABLE_I18N
-     /* Eliminate it when it is a component of a multibyte character
-        and isn't the head of a multibyte character.  */
-      if (sb || re_string_first_byte (&mctx.input, 0))
+     /* Don't consider this char as a possible match start if it part,
+       yet isn't the head, of a multibyte character.  */
+      if (!sb && !re_string_first_byte (&mctx.input, 0))
+       continue;
 #endif
+
+      /* It seems to be appropriate one, then use the matcher.  */
+      /* We assume that the matching starts from 0.  */
+      mctx.state_log_top = mctx.nbkref_ents = mctx.max_mb_elem_len = 0;
+      match_last = check_matching (&mctx, fl_longest_match,
+                                  range >= 0 ? &match_first : NULL);
+      if (match_last != -1)
        {
-         /* It seems to be appropriate one, then use the matcher.  */
-         /* We assume that the matching starts from 0.  */
-         mctx.state_log_top = mctx.nbkref_ents = mctx.max_mb_elem_len = 0;
-         match_last = check_matching (&mctx, fl_longest_match,
-                                      range >= 0 ? &match_first : NULL);
-         if (match_last != -1)
+         if (BE (match_last == -2, 0))
            {
-             if (BE (match_last == -2, 0))
+             err = REG_ESPACE;
+             goto free_return;
+           }
+         else
+           {
+             mctx.match_last = match_last;
+             if ((!preg->no_sub && nmatch > 1) || dfa->nbackref)
                {
-                 err = REG_ESPACE;
-                 goto free_return;
+                 re_dfastate_t *pstate = mctx.state_log[match_last];
+                 mctx.last_node = check_halt_state_context (&mctx, pstate,
+                                                            match_last);
                }
-             else
+             if ((!preg->no_sub && nmatch > 1 && dfa->has_plural_match)
+                 || dfa->nbackref)
                {
-                 mctx.match_last = match_last;
-                 if ((!preg->no_sub && nmatch > 1) || dfa->nbackref)
-                   {
-                     re_dfastate_t *pstate = mctx.state_log[match_last];
-                     mctx.last_node = check_halt_state_context (&mctx, pstate,
-                                                                match_last);
-                   }
-                 if ((!preg->no_sub && nmatch > 1 && dfa->has_plural_match)
-                     || dfa->nbackref)
-                   {
-                     err = prune_impossible_nodes (&mctx);
-                     if (err == REG_NOERROR)
-                       break;
-                     if (BE (err != REG_NOMATCH, 0))
-                       goto free_return;
-                     match_last = -1;
-                   }
-                 else
-                   break; /* We found a match.  */
+                 err = prune_impossible_nodes (&mctx);
+                 if (err == REG_NOERROR)
+                   break;
+                 if (BE (err != REG_NOMATCH, 0))
+                   goto free_return;
+                 match_last = -1;
                }
+             else
+               break; /* We found a match.  */
            }
-         match_ctx_clean (&mctx);
        }
-      /* Update counter.  */
-      match_first += incr;
-      if (match_first < left_lim || right_lim < match_first)
-       break;
+
+      match_ctx_clean (&mctx);
     }
 
+#ifdef DEBUG
+  assert (match_last != -1);
+  assert (err == REG_NOERROR);
+#endif
+
   /* Set pmatch[] if we need.  */
-  if (match_last != -1 && nmatch > 0)
+  if (nmatch > 0)
     {
       int reg_idx;
 
@@ -869,7 +883,7 @@ re_search_internal (preg, string, length, start, range, stop, nmatch, pmatch,
            pmatch[reg_idx].rm_eo += match_first;
          }
     }
-  err = (match_last == -1) ? REG_NOMATCH : REG_NOERROR;
+
  free_return:
   re_free (mctx.state_log);
   if (dfa->nbackref)
@@ -1072,6 +1086,20 @@ check_matching (mctx, fl_longest_match, p_match_first)
   while (!re_string_eoi (&mctx->input))
     {
       re_dfastate_t *old_state = cur_state;
+      int next_char_idx = re_string_cur_idx (&mctx->input) + 1;
+
+      if (BE (next_char_idx >= mctx->input.bufs_len, 0)
+          || (BE (next_char_idx >= mctx->input.valid_len, 0)
+              && mctx->input.valid_len < mctx->input.len))
+        {
+          err = extend_buffers (mctx);
+          if (BE (err != REG_NOERROR, 0))
+           {
+             assert (err == REG_ESPACE);
+             return -2;
+           }
+        }
+
       cur_state = transit_state (&err, mctx, cur_state);
       if (mctx->state_log != NULL)
        cur_state = merge_state_with_log (&err, mctx, cur_state);
@@ -1090,10 +1118,10 @@ check_matching (mctx, fl_longest_match, p_match_first)
            break;
        }
 
-      if (at_init_state)
+      if (BE (at_init_state, 0))
        {
          if (old_state == cur_state)
-           next_start_idx = re_string_cur_idx (&mctx->input);
+           next_start_idx = next_char_idx;
          else
            at_init_state = 0;
        }
@@ -1109,13 +1137,16 @@ check_matching (mctx, fl_longest_match, p_match_first)
              /* We found an appropriate halt state.  */
              match_last = re_string_cur_idx (&mctx->input);
              match = 1;
+
+             /* We found a match, do not modify match_first below.  */
+             p_match_first = NULL;
              if (!fl_longest_match)
                break;
            }
        }
-   }
+    }
 
-  if (match_last == -1 && p_match_first)
+  if (p_match_first)
     *p_match_first += next_start_idx;
 
   return match_last;
@@ -1854,7 +1885,12 @@ check_dst_limits_calc_pos_1 (mctx, boundaries, subexp_idx, from_node, bkref_idx)
              {
                int dst, cpos;
 
-               if (ent->node != node || ent->subexp_from != ent->subexp_to)
+               if (ent->node != node)
+                 continue;
+
+               if (subexp_idx <= 8 * sizeof (ent->eps_reachable_subexps_map)
+                   && (ent->eps_reachable_subexps_map
+                       & (1 << (subexp_idx - 1))) == 0)
                  continue;
 
                /* Recurse trying to reach the OP_OPEN_SUBEXP and
@@ -1875,11 +1911,13 @@ check_dst_limits_calc_pos_1 (mctx, boundaries, subexp_idx, from_node, bkref_idx)
                cpos = check_dst_limits_calc_pos_1 (mctx, boundaries,
                                                    subexp_idx, dst, bkref_idx);
 
-               if (cpos == -1 && (boundaries & 1))
+               if (cpos == -1 /* && (boundaries & 1) */)
                  return -1;
 
-               if (cpos == 0 /* && (boundaries & 2) */)
+               if (cpos == 0 && (boundaries & 2))
                  return 0;
+
+               ent->eps_reachable_subexps_map &= ~(1 << (subexp_idx - 1));
              }
            while (ent++->more);
            break;
@@ -2167,23 +2205,14 @@ transit_state (err, mctx, state)
   re_dfastate_t **trtable;
   unsigned char ch;
 
-  if (re_string_cur_idx (&mctx->input) + 1 >= mctx->input.bufs_len
-      || (re_string_cur_idx (&mctx->input) + 1 >= mctx->input.valid_len
-         && mctx->input.valid_len < mctx->input.len))
+#ifdef RE_ENABLE_I18N
+  /* If the current state can accept multibyte.  */
+  if (BE (state->accept_mb, 0))
     {
-      *err = extend_buffers (mctx);
+      *err = transit_state_mb (mctx, state);
       if (BE (*err != REG_NOERROR, 0))
        return NULL;
     }
-
-#ifdef RE_ENABLE_I18N
-      /* If the current state can accept multibyte.  */
-      if (state->accept_mb)
-       {
-         *err = transit_state_mb (mctx, state);
-         if (BE (*err != REG_NOERROR, 0))
-           return NULL;
-       }
 #endif /* RE_ENABLE_I18N */
 
   /* Then decide the next state with the single byte.  */
@@ -4077,28 +4106,6 @@ match_ctx_init (mctx, eflags, n)
 static void
 match_ctx_clean (mctx)
     re_match_context_t *mctx;
-{
-  match_ctx_free_subtops (mctx);
-  mctx->nsub_tops = 0;
-  mctx->nbkref_ents = 0;
-}
-
-/* Free all the memory associated with MCTX.  */
-
-static void
-match_ctx_free (mctx)
-    re_match_context_t *mctx;
-{
-  match_ctx_free_subtops (mctx);
-  re_free (mctx->sub_tops);
-  re_free (mctx->bkref_ents);
-}
-
-/* Free all the memory associated with MCTX->SUB_TOPS.  */
-
-static void
-match_ctx_free_subtops (mctx)
-     re_match_context_t *mctx;
 {
   int st_idx;
   for (st_idx = 0; st_idx < mctx->nsub_tops; ++st_idx)
@@ -4119,6 +4126,21 @@ match_ctx_free_subtops (mctx)
        }
       free (top);
     }
+
+  mctx->nsub_tops = 0;
+  mctx->nbkref_ents = 0;
+}
+
+/* Free all the memory associated with MCTX.  */
+
+static void
+match_ctx_free (mctx)
+    re_match_context_t *mctx;
+{
+  /* First, free all the memory associated with MCTX->SUB_TOPS.  */
+  match_ctx_clean (mctx);
+  re_free (mctx->sub_tops);
+  re_free (mctx->bkref_ents);
 }
 
 /* Add a new backreference entry to MCTX.
@@ -4154,6 +4176,18 @@ match_ctx_add_entry (mctx, node, str_idx, from, to)
   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;
+
+  /* This is a cache that saves negative results of check_dst_limits_calc_pos.
+     If bit N is clear, means that this entry won't epsilon-transition to
+     an OP_OPEN_SUBEXP or OP_CLOSE_SUBEXP for the N+1-th subexpression.  If
+     it is set, check_dst_limits_calc_pos_1 will recurse and try to find one
+     such node.
+
+     A backreference does not epsilon-transition unless it is empty, so set
+     to all zeros if FROM != TO.  */
+  mctx->bkref_ents[mctx->nbkref_ents].eps_reachable_subexps_map
+    = (from == to ? ~0 : 0);
+
   mctx->bkref_ents[mctx->nbkref_ents++].more = 0;
   if (mctx->max_mb_elem_len < to - from)
     mctx->max_mb_elem_len = to - from;
index 642d529a9a965de1ea3fbc95435b8f915ac8a35f..d810922f04ddc836799df30fbea696d27714455a 100644 (file)
@@ -18,7 +18,7 @@
    02111-1307 USA.  */
 
 #include <errno.h>
-#include <error.h>
+#include <stdio.h>
 #include <stdlib.h>
 #include <unistd.h>
 #include <sys/wait.h>
@@ -56,16 +56,15 @@ sigchld (int signo, siginfo_t *info, void *ctx)
 {
   if (signo != SIGCHLD)
     {
-      error (0, 0, "SIGCHLD handler got signal %d instead!", signo);
+      printf ("SIGCHLD handler got signal %d instead!\n", signo);
       _exit (EXIT_FAILURE);
     }
 
   if (! expecting_sigchld)
     {
       spurious_sigchld = 1;
-      error (0, 0,
-            "spurious SIGCHLD: signo %d code %d status %d pid %d\n",
-            info->si_signo, info->si_code, info->si_status, info->si_pid);
+      printf ("spurious SIGCHLD: signo %d code %d status %d pid %d\n",
+             info->si_signo, info->si_code, info->si_status, info->si_pid);
     }
   else
     {
@@ -79,7 +78,7 @@ check_sigchld (const char *phase, int *ok, int code, int status, pid_t pid)
 {
   if (expecting_sigchld)
     {
-      error (0, 0, "missing SIGCHLD on %s", phase);
+      printf ("missing SIGCHLD on %s\n", phase);
       *ok = EXIT_FAILURE;
       expecting_sigchld = 0;
       return;
@@ -87,22 +86,22 @@ check_sigchld (const char *phase, int *ok, int code, int status, pid_t pid)
 
   if (sigchld_info.si_signo != SIGCHLD)
     {
-      error (0, 0, "SIGCHLD for %s signal %d", phase, sigchld_info.si_signo);
+      printf ("SIGCHLD for %s signal %d\n", phase, sigchld_info.si_signo);
       *ok = EXIT_FAILURE;
     }
   if (sigchld_info.si_code != code)
     {
-      error (0, 0, "SIGCHLD for %s code %d", phase, sigchld_info.si_code);
+      printf ("SIGCHLD for %s code %d\n", phase, sigchld_info.si_code);
       *ok = EXIT_FAILURE;
     }
   if (sigchld_info.si_status != status)
     {
-      error (0, 0, "SIGCHLD for %s status %d", phase, sigchld_info.si_status);
+      printf ("SIGCHLD for %s status %d\n", phase, sigchld_info.si_status);
       *ok = EXIT_FAILURE;
     }
   if (sigchld_info.si_pid != pid)
     {
-      error (0, 0, "SIGCHLD for %s pid %d", phase, sigchld_info.si_pid);
+      printf ("SIGCHLD for %s pid %d\n", phase, sigchld_info.si_pid);
       *ok = EXIT_FAILURE;
     }
 }
@@ -121,7 +120,7 @@ do_test (int argc, char *argv[])
   sa.sa_sigaction = &sigchld;
   if (sigemptyset (&sa.sa_mask) < 0 || sigaction (SIGCHLD, &sa, NULL) < 0)
     {
-      error (0, errno, "setting SIGCHLD handler");
+      printf ("setting SIGCHLD handler: %m\n");
       return EXIT_FAILURE;
     }
 #endif
@@ -131,7 +130,7 @@ do_test (int argc, char *argv[])
   pid_t pid = fork ();
   if (pid < 0)
     {
-      error (0, errno, "fork");
+      printf ("fork: %m\n");
       return EXIT_FAILURE;
     }
   else if (pid == 0)
@@ -156,18 +155,18 @@ do_test (int argc, char *argv[])
   switch (fail)
     {
     default:
-      error (0, 0, "waitid returned bogus value %d\n", fail);
+      printf ("waitid returned bogus value %d\n", fail);
       RETURN (EXIT_FAILURE);
     case -1:
-      error (0, errno, "waitid WNOHANG on stopped");
+      printf ("waitid WNOHANG on stopped: %m\n");
       RETURN (errno == ENOTSUP ? EXIT_SUCCESS : EXIT_FAILURE);
     case 0:
       if (info.si_signo == 0)
        break;
       if (info.si_signo == SIGCHLD)
-       error (0, 0, "waitid WNOHANG on stopped status %d\n", info.si_status);
+       printf ("waitid WNOHANG on stopped status %d\n", info.si_status);
       else
-       error (0, 0, "waitid WNOHANG on stopped signal %d\n", info.si_signo);
+       printf ("waitid WNOHANG on stopped signal %d\n", info.si_signo);
       RETURN (EXIT_FAILURE);
     }
 
@@ -179,34 +178,34 @@ do_test (int argc, char *argv[])
   switch (fail)
     {
     default:
-      error (0, 0, "waitid WSTOPPED|WNOHANG returned bogus value %d\n", fail);
+      printf ("waitid WSTOPPED|WNOHANG returned bogus value %d\n", fail);
       RETURN (EXIT_FAILURE);
     case -1:
-      error (0, errno, "waitid WSTOPPED|WNOHANG on stopped");
+      printf ("waitid WSTOPPED|WNOHANG on stopped: %m\n");
       RETURN (errno == ENOTSUP ? EXIT_SUCCESS : EXIT_FAILURE);
     case 0:
       if (info.si_signo != SIGCHLD)
        {
-         error (0, 0, "waitid WSTOPPED|WNOHANG on stopped signal %d\n",
-                info.si_signo);
+         printf ("waitid WSTOPPED|WNOHANG on stopped signal %d\n",
+                 info.si_signo);
          RETURN (EXIT_FAILURE);
        }
       if (info.si_code != CLD_STOPPED)
        {
-         error (0, 0, "waitid WSTOPPED|WNOHANG on stopped code %d\n",
-                info.si_code);
+         printf ("waitid WSTOPPED|WNOHANG on stopped code %d\n",
+                 info.si_code);
          RETURN (EXIT_FAILURE);
        }
       if (info.si_status != SIGSTOP)
        {
-         error (0, 0, "waitid WSTOPPED|WNOHANG on stopped status %d\n",
-                info.si_status);
+         printf ("waitid WSTOPPED|WNOHANG on stopped status %d\n",
+                 info.si_status);
          RETURN (EXIT_FAILURE);
        }
       if (info.si_pid != pid)
        {
-         error (0, 0, "waitid WSTOPPED|WNOHANG on stopped pid %d != %d\n",
-                info.si_pid, pid);
+         printf ("waitid WSTOPPED|WNOHANG on stopped pid %d != %d\n",
+                 info.si_pid, pid);
          RETURN (EXIT_FAILURE);
        }
     }
@@ -215,7 +214,7 @@ do_test (int argc, char *argv[])
 
   if (kill (pid, SIGCONT) != 0)
     {
-      error (0, errno, "kill (%d, SIGCONT)", pid);
+      printf ("kill (%d, SIGCONT): %m\n", pid);
       RETURN (EXIT_FAILURE);
     }
 
@@ -225,7 +224,7 @@ do_test (int argc, char *argv[])
 #if WCONTINUED != 0
   if (expecting_sigchld)
     {
-      error (0, 0, "no SIGCHLD seen for SIGCONT (optional)");
+      printf ("no SIGCHLD seen for SIGCONT (optional)\n");
       expecting_sigchld = 0;
     }
   else
@@ -238,35 +237,34 @@ do_test (int argc, char *argv[])
   switch (fail)
     {
     default:
-      error (0, 0,
-            "waitid WCONTINUED|WNOWAIT returned bogus value %d\n", fail);
+      printf ("waitid WCONTINUED|WNOWAIT returned bogus value %d\n", fail);
       RETURN (EXIT_FAILURE);
     case -1:
-      error (0, errno, "waitid WCONTINUED|WNOWAIT on continued");
+      printf ("waitid WCONTINUED|WNOWAIT on continued: %m\n");
       RETURN (errno == ENOTSUP ? EXIT_SUCCESS : EXIT_FAILURE);
     case 0:
       if (info.si_signo != SIGCHLD)
        {
-         error (0, 0, "waitid WCONTINUED|WNOWAIT on continued signal %d\n",
-                info.si_signo);
+         printf ("waitid WCONTINUED|WNOWAIT on continued signal %d\n",
+                 info.si_signo);
          RETURN (EXIT_FAILURE);
        }
       if (info.si_code != CLD_CONTINUED)
        {
-         error (0, 0, "waitid WCONTINUED|WNOWAIT on continued code %d\n",
-                info.si_code);
+         printf ("waitid WCONTINUED|WNOWAIT on continued code %d\n",
+                 info.si_code);
          RETURN (EXIT_FAILURE);
        }
       if (info.si_status != SIGCONT)
        {
-         error (0, 0, "waitid WCONTINUED|WNOWAIT on continued status %d\n",
-                info.si_status);
+         printf ("waitid WCONTINUED|WNOWAIT on continued status %d\n",
+                 info.si_status);
          RETURN (EXIT_FAILURE);
        }
       if (info.si_pid != pid)
        {
-         error (0, 0, "waitid WCONTINUED|WNOWAIT on continued pid %d != %d\n",
-                info.si_pid, pid);
+         printf ("waitid WCONTINUED|WNOWAIT on continued pid %d != %d\n",
+                 info.si_pid, pid);
          RETURN (EXIT_FAILURE);
        }
     }
@@ -279,34 +277,32 @@ do_test (int argc, char *argv[])
   switch (fail)
     {
     default:
-      error (0, 0, "waitid WCONTINUED returned bogus value %d\n", fail);
+      printf ("waitid WCONTINUED returned bogus value %d\n", fail);
       RETURN (EXIT_FAILURE);
     case -1:
-      error (0, errno, "waitid WCONTINUED on continued");
+      printf ("waitid WCONTINUED on continued: %m\n");
       RETURN (errno == ENOTSUP ? EXIT_SUCCESS : EXIT_FAILURE);
     case 0:
       if (info.si_signo != SIGCHLD)
        {
-         error (0, 0, "waitid WCONTINUED on continued signal %d\n",
-                info.si_signo);
+         printf ("waitid WCONTINUED on continued signal %d\n", info.si_signo);
          RETURN (EXIT_FAILURE);
        }
       if (info.si_code != CLD_CONTINUED)
        {
-         error (0, 0, "waitid WCONTINUED on continued code %d\n",
-                info.si_code);
+         printf ("waitid WCONTINUED on continued code %d\n", info.si_code);
          RETURN (EXIT_FAILURE);
        }
       if (info.si_status != SIGCONT)
        {
-         error (0, 0, "waitid WCONTINUED on continued status %d\n",
-                info.si_status);
+         printf ("waitid WCONTINUED on continued status %d\n",
+                 info.si_status);
          RETURN (EXIT_FAILURE);
        }
       if (info.si_pid != pid)
        {
-         error (0, 0, "waitid WCONTINUED on continued pid %d != %d\n",
-                info.si_pid, pid);
+         printf ("waitid WCONTINUED on continued pid %d != %d\n",
+                 info.si_pid, pid);
          RETURN (EXIT_FAILURE);
        }
     }
@@ -317,22 +313,20 @@ do_test (int argc, char *argv[])
   switch (fail)
     {
     default:
-      error (0, 0, "waitid returned bogus value %d\n", fail);
+      printf ("waitid returned bogus value %d\n", fail);
       RETURN (EXIT_FAILURE);
     case -1:
-      error (0, errno, "waitid WCONTINUED|WNOHANG on waited continued");
+      printf ("waitid WCONTINUED|WNOHANG on waited continued: %m\n");
       RETURN (errno == ENOTSUP ? EXIT_SUCCESS : EXIT_FAILURE);
     case 0:
       if (info.si_signo == 0)
        break;
       if (info.si_signo == SIGCHLD)
-       error (0, 0,
-              "waitid WCONTINUED|WNOHANG on waited continued status %d\n",
-              info.si_status);
+       printf ("waitid WCONTINUED|WNOHANG on waited continued status %d\n",
+               info.si_status);
       else
-       error (0, 0,
-              "waitid WCONTINUED|WNOHANG on waited continued signal %d\n",
-              info.si_signo);
+       printf ("waitid WCONTINUED|WNOHANG on waited continued signal %d\n",
+               info.si_signo);
       RETURN (EXIT_FAILURE);
     }
 
@@ -340,26 +334,25 @@ do_test (int argc, char *argv[])
   expecting_sigchld = 1;
   if (kill (pid, SIGSTOP) != 0)
     {
-      error (0, errno, "kill (%d, SIGSTOP)", pid);
+      printf ("kill (%d, SIGSTOP): %m\n", pid);
       RETURN (EXIT_FAILURE);
     }
   pid_t wpid = waitpid (pid, &fail, WUNTRACED);
   if (wpid < 0)
     {
-      error (0, errno, "waitpid WUNTRACED on stopped");
+      printf ("waitpid WUNTRACED on stopped: %m\n");
       RETURN (EXIT_FAILURE);
     }
   else if (wpid != pid)
     {
-      error (0, 0,
-            "waitpid WUNTRACED on stopped returned %d != %d (status %x)",
-            wpid, pid, fail);
+      printf ("waitpid WUNTRACED on stopped returned %d != %d (status %x)\n",
+             wpid, pid, fail);
       RETURN (EXIT_FAILURE);
     }
   else if (!WIFSTOPPED (fail) || WIFSIGNALED (fail) || WIFEXITED (fail)
           || WIFCONTINUED (fail) || WSTOPSIG (fail) != SIGSTOP)
     {
-      error (0, 0, "waitpid WUNTRACED on stopped: status %x", fail);
+      printf ("waitpid WUNTRACED on stopped: status %x\n", fail);
       RETURN (EXIT_FAILURE);
     }
   CHECK_SIGCHLD ("stopped", CLD_STOPPED, SIGSTOP);
@@ -367,7 +360,7 @@ do_test (int argc, char *argv[])
   expecting_sigchld = 1;
   if (kill (pid, SIGCONT) != 0)
     {
-      error (0, errno, "kill (%d, SIGCONT)", pid);
+      printf ("kill (%d, SIGCONT): %m\n", pid);
       RETURN (EXIT_FAILURE);
     }
 
@@ -376,7 +369,7 @@ do_test (int argc, char *argv[])
 
   if (expecting_sigchld)
     {
-      error (0, 0, "no SIGCHLD seen for SIGCONT (optional)");
+      printf ("no SIGCHLD seen for SIGCONT (optional)\n");
       expecting_sigchld = 0;
     }
   else
@@ -386,24 +379,24 @@ do_test (int argc, char *argv[])
   if (wpid < 0)
     {
       if (errno == EINVAL)
-       error (0, 0, "waitpid does not support WCONTINUED");
+       printf ("waitpid does not support WCONTINUED\n");
       else
        {
-         error (0, errno, "waitpid WCONTINUED on continued");
+         printf ("waitpid WCONTINUED on continued: %m\n");
          RETURN (EXIT_FAILURE);
        }
     }
   else if (wpid != pid)
     {
-      error (0, 0,
-            "waitpid WCONTINUED on continued returned %d != %d (status %x)",
+      printf ("\
+waitpid WCONTINUED on continued returned %d != %d (status %x)\n",
             wpid, pid, fail);
       RETURN (EXIT_FAILURE);
     }
   else if (WIFSTOPPED (fail) || WIFSIGNALED (fail) || WIFEXITED (fail)
           || !WIFCONTINUED (fail))
     {
-      error (0, 0, "waitpid WCONTINUED on continued: status %x", fail);
+      printf ("waitpid WCONTINUED on continued: status %x\n", fail);
       RETURN (EXIT_FAILURE);
     }
 #endif
@@ -413,7 +406,7 @@ do_test (int argc, char *argv[])
   /* Die, child, die!  */
   if (kill (pid, SIGKILL) != 0)
     {
-      error (0, errno, "kill (%d, SIGKILL)", pid);
+      printf ("kill (%d, SIGKILL): %m\n", pid);
       RETURN (EXIT_FAILURE);
     }
 
@@ -425,34 +418,30 @@ do_test (int argc, char *argv[])
   switch (fail)
     {
     default:
-      error (0, 0, "waitid WNOWAIT returned bogus value %d\n", fail);
+      printf ("waitid WNOWAIT returned bogus value %d\n", fail);
       RETURN (EXIT_FAILURE);
     case -1:
-      error (0, errno, "waitid WNOWAIT on killed");
+      printf ("waitid WNOWAIT on killed: %m\n");
       RETURN (errno == ENOTSUP ? EXIT_SUCCESS : EXIT_FAILURE);
     case 0:
       if (info.si_signo != SIGCHLD)
        {
-         error (0, 0, "waitid WNOWAIT on killed signal %d\n",
-                info.si_signo);
+         printf ("waitid WNOWAIT on killed signal %d\n", info.si_signo);
          RETURN (EXIT_FAILURE);
        }
       if (info.si_code != CLD_KILLED)
        {
-         error (0, 0, "waitid WNOWAIT on killed code %d\n",
-                info.si_code);
+         printf ("waitid WNOWAIT on killed code %d\n", info.si_code);
          RETURN (EXIT_FAILURE);
        }
       if (info.si_status != SIGKILL)
        {
-         error (0, 0, "waitid WNOWAIT on killed status %d\n",
-                info.si_status);
+         printf ("waitid WNOWAIT on killed status %d\n", info.si_status);
          RETURN (EXIT_FAILURE);
        }
       if (info.si_pid != pid)
        {
-         error (0, 0, "waitid WNOWAIT on killed pid %d != %d\n",
-                info.si_pid, pid);
+         printf ("waitid WNOWAIT on killed pid %d != %d\n", info.si_pid, pid);
          RETURN (EXIT_FAILURE);
        }
     }
@@ -470,34 +459,30 @@ do_test (int argc, char *argv[])
   switch (fail)
     {
     default:
-      error (0, 0, "waitid WNOHANG returned bogus value %d\n", fail);
+      printf ("waitid WNOHANG returned bogus value %d\n", fail);
       RETURN (EXIT_FAILURE);
     case -1:
-      error (0, errno, "waitid WNOHANG on killed");
+      printf ("waitid WNOHANG on killed: %m\n");
       RETURN (EXIT_FAILURE);
     case 0:
       if (info.si_signo != SIGCHLD)
        {
-         error (0, 0, "waitid WNOHANG on killed signal %d\n",
-                info.si_signo);
+         printf ("waitid WNOHANG on killed signal %d\n", info.si_signo);
          RETURN (EXIT_FAILURE);
        }
       if (info.si_code != CLD_KILLED)
        {
-         error (0, 0, "waitid WNOHANG on killed code %d\n",
-                info.si_code);
+         printf ("waitid WNOHANG on killed code %d\n", info.si_code);
          RETURN (EXIT_FAILURE);
        }
       if (info.si_status != SIGKILL)
        {
-         error (0, 0, "waitid WNOHANG on killed status %d\n",
-                info.si_status);
+         printf ("waitid WNOHANG on killed status %d\n", info.si_status);
          RETURN (EXIT_FAILURE);
        }
       if (info.si_pid != pid)
        {
-         error (0, 0, "waitid WNOHANG on killed pid %d != %d\n",
-                info.si_pid, pid);
+         printf ("waitid WNOHANG on killed pid %d != %d\n", info.si_pid, pid);
          RETURN (EXIT_FAILURE);
        }
     }
@@ -507,13 +492,13 @@ do_test (int argc, char *argv[])
     {
       if (errno != ECHILD)
        {
-         error (0, errno, "waitid WEXITED on killed");
+         printf ("waitid WEXITED on killed: %m\n");
          RETURN (EXIT_FAILURE);
        }
     }
   else
     {
-      error (0, 0, "waitid WEXITED returned bogus value %d\n", fail);
+      printf ("waitid WEXITED returned bogus value %d\n", fail);
       RETURN (EXIT_FAILURE);
     }
 
index 3a5c047b8c9fa2d49649313a2c06d5ef0ec87b5e..b11cb520f67223ca00f65d69f6665b2914037034 100644 (file)
    Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
    02111-1307 USA.  */
 
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
 #include <string.h>
 
 #undef strtok_r
 #undef __strtok_r
 
+#ifndef _LIBC
+/* Get specification.  */
+# include "strtok_r.h"
+# define __strtok_r strtok_r
+# define __rawmemchr strchr
+#endif
+
 /* Parse S into tokens separated by characters in DELIM.
    If S is NULL, the saved pointer in SAVE_PTR is used as
    the next starting point.  For example:
                // s = "abc\0-def\0"
 */
 char *
-__strtok_r (s, delim, save_ptr)
-     char *s;
-     const char *delim;
-     char **save_ptr;
+__strtok_r (char *s, const char *delim, char **save_ptr)
 {
   char *token;
 
@@ -65,5 +73,7 @@ __strtok_r (s, delim, save_ptr)
     }
   return token;
 }
+#ifdef weak_alias
 libc_hidden_def (__strtok_r)
 weak_alias (__strtok_r, strtok_r)
+#endif
diff --git a/sysdeps/unix/setxid.h b/sysdeps/unix/setxid.h
new file mode 100644 (file)
index 0000000..c18e2d4
--- /dev/null
@@ -0,0 +1,4 @@
+#include <sysdep.h>
+
+#define INLINE_SETXID_SYSCALL(name, nr, args...) \
+  INLINE_SYSCALL (name, nr, args)
index cfc8283c3ae9306e530db605dbee8672d7fdd37d..0973fe4ac1553865893f25a3523d9347c13e959d 100644 (file)
 
 #include <errno.h>
 #include <unistd.h>
-#include <sys/types.h>
-
-#include <sysdep.h>
-#include <sys/syscall.h>
-
-#include <linux/posix_types.h>
-#include "kernel-features.h"
-#include <pthread-functions.h>
+#include <setxid.h>
 
 
 int
 __setregid (gid_t rgid, gid_t egid)
 {
-  int result;
-
-  result = INLINE_SYSCALL (setregid, 2, (signed int)rgid, (signed int)egid);
-
-#if defined HAVE_PTR__NPTL_SETXID && !defined SINGLE_THREAD
-  if (result == 0 && __libc_pthread_functions.ptr__nptl_setxid != NULL)
-    {
-      struct xid_command cmd;
-      cmd.syscall_no = __NR_setregid;
-      cmd.id[0] = rgid;
-      cmd.id[1] = egid;
-      __libc_pthread_functions.ptr__nptl_setxid (&cmd);
-    }
-#endif
-
-  return result;
+  return INLINE_SETXID_SYSCALL (setregid, 2, (int) rgid, (int) egid);
 }
 #ifndef __setregid
 weak_alias (__setregid, setregid)
index fdfa486534daa62d512a3a841211a07c7e038d30..50e29e3c7623c8c3865bb46d05a8868914b4fa57 100644 (file)
 
 #include <errno.h>
 #include <unistd.h>
-#include <sys/types.h>
-
-#include <sysdep.h>
-#include <sys/syscall.h>
-
-#include <linux/posix_types.h>
-#include "kernel-features.h"
-#include <pthread-functions.h>
+#include <setxid.h>
 
 
 int
 __setresgid (gid_t rgid, gid_t egid, gid_t sgid)
 {
-  int result;
-
-  result = INLINE_SYSCALL (setresgid, 3, (signed int)rgid, (signed int)egid, (signed int)sgid);
-
-#if defined HAVE_PTR__NPTL_SETXID && !defined SINGLE_THREAD
-  if (result == 0 && __libc_pthread_functions.ptr__nptl_setxid != NULL)
-    {
-      struct xid_command cmd;
-      cmd.syscall_no = __NR_setresgid;
-      cmd.id[0] = rgid;
-      cmd.id[1] = egid;
-      cmd.id[2] = sgid;
-      __libc_pthread_functions.ptr__nptl_setxid (&cmd);
-    }
-#endif
-
-  return result;
+  return INLINE_SETXID_SYSCALL (setresgid, 3, (int) rgid,
+                               (int) egid, (int) sgid);
 }
 libc_hidden_def (__setresgid)
 #ifndef __setresgid
index 49671278ee62007c79aaef1206ce4744766aa613..e76413bf6a730bc20dcf8dad0f14941fdbb295a8 100644 (file)
 
 #include <errno.h>
 #include <unistd.h>
-#include <sys/types.h>
-
-#include <sysdep.h>
-#include <sys/syscall.h>
-
-#include <linux/posix_types.h>
-#include "kernel-features.h"
-#include <pthread-functions.h>
+#include <setxid.h>
 
 
 int
 __setresuid (uid_t ruid, uid_t euid, uid_t suid)
 {
-  int result;
-
-  result = INLINE_SYSCALL (setresuid, 3, (signed int)ruid, (signed int)euid, (signed int)suid);
-
-#if defined HAVE_PTR__NPTL_SETXID && !defined SINGLE_THREAD
-  if (result == 0 && __libc_pthread_functions.ptr__nptl_setxid != NULL)
-    {
-      struct xid_command cmd;
-      cmd.syscall_no = __NR_setresuid;
-      cmd.id[0] = ruid;
-      cmd.id[1] = euid;
-      cmd.id[2] = suid;
-      __libc_pthread_functions.ptr__nptl_setxid (&cmd);
-    }
-#endif
-
-  return result;
+  return INLINE_SETXID_SYSCALL (setresuid, 3, (int) ruid,
+                               (int) euid, (int) suid);
 }
 libc_hidden_def (__setresuid)
 #ifndef __setresuid
index b29aed479ee73933b7c0515c31250734a7a21be2..a23a34792e037464097a5e156aab547a77e2d216 100644 (file)
 
 #include <errno.h>
 #include <unistd.h>
-#include <sys/types.h>
-
-#include <sysdep.h>
-#include <sys/syscall.h>
-
-#include <linux/posix_types.h>
-#include "kernel-features.h"
-#include <pthread-functions.h>
+#include <setxid.h>
 
 
 int
 __setreuid (uid_t ruid, uid_t euid)
 {
-  int result;
-
-  result = INLINE_SYSCALL (setreuid, 2, (signed int)ruid, (signed int)euid);
-
-#if defined HAVE_PTR__NPTL_SETXID && !defined SINGLE_THREAD
-  if (result == 0 && __libc_pthread_functions.ptr__nptl_setxid != NULL)
-    {
-      struct xid_command cmd;
-      cmd.syscall_no = __NR_setreuid;
-      cmd.id[0] = ruid;
-      cmd.id[1] = euid;
-      __libc_pthread_functions.ptr__nptl_setxid (&cmd);
-    }
-#endif
-
-  return result;
+  return INLINE_SETXID_SYSCALL (setreuid, 2, (int) ruid, (int) euid);
 }
 #ifndef __setreuid
 weak_alias (__setreuid, setreuid)
index b8682e3681b94ae53f3e6f847e344da1c6e77838..b4bf33f18f0d7fa4ebe2eba25877345d42e823eb 100644 (file)
 
 #include <errno.h>
 #include <unistd.h>
-#include <sys/types.h>
-
-#include <sysdep.h>
+#include <setxid.h>
 #include "kernel-features.h"
-#include <pthread-functions.h>
 
 
 #ifdef __NR_setresgid
@@ -42,7 +39,7 @@ setegid (gid)
     }
 
 #if __ASSUME_32BITUIDS > 0
-  result = INLINE_SYSCALL (setresgid32, 3, -1, gid, -1);
+  result = INLINE_SETXID_SYSCALL (setresgid32, 3, -1, gid, -1);
 #else
   /* First try the syscall.  */
 # ifdef __NR_setresgid
@@ -59,18 +56,6 @@ setegid (gid)
     result = __setregid (-1, gid);
 #endif
 
-#if defined HAVE_PTR__NPTL_SETXID && !defined SINGLE_THREAD
-  if (result == 0 && __libc_pthread_functions.ptr__nptl_setxid != NULL)
-    {
-      struct xid_command cmd;
-      cmd.syscall_no = __NR_setresgid32;
-      cmd.id[0] = -1;
-      cmd.id[1] = gid;
-      cmd.id[2] = -1;
-      __libc_pthread_functions.ptr__nptl_setxid (&cmd);
-    }
-#endif
-
   return result;
 }
 libc_hidden_def (setegid)
index 0abdac832f83758f4d1fc5619831b89e9d8dfb16..c139684d04896ef96d0393355668c6bde9cabea2 100644 (file)
    02111-1307 USA.  */
 
 #include <errno.h>
-#include <sys/types.h>
 #include <unistd.h>
-
-#include <sysdep.h>
+#include <setxid.h>
 #include "kernel-features.h"
-#include <pthread-functions.h>
 
 
 #ifdef __NR_setresuid
@@ -41,7 +38,7 @@ seteuid (uid_t uid)
     }
 
 #if __ASSUME_32BITUIDS > 0
-  result = INLINE_SYSCALL (setresuid32, 3, -1, uid, -1);
+  result = INLINE_SETXID_SYSCALL (setresuid32, 3, -1, uid, -1);
 #else
   /* First try the syscall.  */
 # ifdef __NR_setresuid
@@ -58,18 +55,6 @@ seteuid (uid_t uid)
     result = __setreuid (-1, uid);
 #endif
 
-#if defined HAVE_PTR__NPTL_SETXID && !defined SINGLE_THREAD
-  if (result == 0 && __libc_pthread_functions.ptr__nptl_setxid != NULL)
-    {
-      struct xid_command cmd;
-      cmd.syscall_no = __NR_setresuid32;
-      cmd.id[0] = -1;
-      cmd.id[1] = uid;
-      cmd.id[2] = -1;
-      __libc_pthread_functions.ptr__nptl_setxid (&cmd);
-    }
-#endif
-
   return result;
 }
 libc_hidden_def (seteuid)
index 17bfc3e58a8f1c579d768f171e6c665753bd78e1..19b1e9f50055922d29fb6f08633cb013054935a4 100644 (file)
@@ -1,5 +1,4 @@
-/* Copyright (C) 1998, 2000, 2003, 2004
-   Free Software Foundation, Inc.
+/* Copyright (C) 1998, 2000, 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
 
 #include <errno.h>
 #include <unistd.h>
-#include <sys/types.h>
-
-#include <sysdep.h>
-#include <sys/syscall.h>
-
-#include <linux/posix_types.h>
-
+#include <setxid.h>
 #include "kernel-features.h"
-#include <pthread-functions.h>
 
 
 #ifdef __NR_setgid32
@@ -44,14 +36,14 @@ __setgid (gid_t gid)
   int result;
 
 #if __ASSUME_32BITUIDS > 0
-  result = INLINE_SYSCALL (setgid32, 1, gid);
+  result = INLINE_SETXID_SYSCALL (setgid32, 1, gid);
 #else
 # ifdef __NR_setgid32
   if (__libc_missing_32bit_uids <= 0)
     {
       int saved_errno = errno;
 
-      result = INLINE_SYSCALL (setgid32, 1, gid);
+      result = INLINE_SETXID_SYSCALL (setgid32, 1, gid);
 
       if (result == 0)
        goto out;
@@ -70,22 +62,12 @@ __setgid (gid_t gid)
       return -1;
     }
 
-  result = INLINE_SYSCALL (setgid, 1, gid);
+  result = INLINE_SETXID_SYSCALL (setgid, 1, gid);
 # ifdef __NR_setgid32
  out:
 # endif
 #endif
 
-#if defined HAVE_PTR__NPTL_SETXID && !defined SINGLE_THREAD
-  if (result == 0 && __libc_pthread_functions.ptr__nptl_setxid != NULL)
-    {
-      struct xid_command cmd;
-      cmd.syscall_no = __NR_setgid32;
-      cmd.id[0] = gid;
-      __libc_pthread_functions.ptr__nptl_setxid (&cmd);
-    }
-#endif
-
   return result;
 }
 #ifndef __setgid
index f883497fae56abc9805779ab13501d91a37df19e..be7870d3b72db36604c81b6bd09908b2da1bc0d9 100644 (file)
    02111-1307 USA.  */
 
 #include <errno.h>
-#include <sys/types.h>
 #include <unistd.h>
-
-#include <sysdep.h>
-#include <sys/syscall.h>
-
-#include <linux/posix_types.h>
+#include <setxid.h>
 #include "kernel-features.h"
-#include <pthread-functions.h>
 
 
 #ifdef __NR_setregid32
@@ -42,14 +36,14 @@ __setregid (gid_t rgid, gid_t egid)
   int result;
 
 #if __ASSUME_32BITUIDS > 0
-  result = INLINE_SYSCALL (setregid32, 2, rgid, egid);
+  result = INLINE_SETXID_SYSCALL (setregid32, 2, rgid, egid);
 #else
 # ifdef __NR_setregid32
   if (__libc_missing_32bit_uids <= 0)
     {
       int saved_errno = errno;
 
-      result = INLINE_SYSCALL (setregid32, 2, rgid, egid);
+      result = INLINE_SETXID_SYSCALL (setregid32, 2, rgid, egid);
 
       if (result == 0)
        goto out;
@@ -67,23 +61,12 @@ __setregid (gid_t rgid, gid_t egid)
       return -1;
     }
 
-  result = INLINE_SYSCALL (setregid, 2, rgid, egid);
+  result = INLINE_SETXID_SYSCALL (setregid, 2, rgid, egid);
 # ifdef __NR_setregid32
  out:
 # endif
 #endif
 
-#if defined HAVE_PTR__NPTL_SETXID && !defined SINGLE_THREAD
-  if (result == 0 && __libc_pthread_functions.ptr__nptl_setxid != NULL)
-    {
-      struct xid_command cmd;
-      cmd.syscall_no = __NR_setregid32;
-      cmd.id[0] = rgid;
-      cmd.id[1] = egid;
-      __libc_pthread_functions.ptr__nptl_setxid (&cmd);
-    }
-#endif
-
   return result;
 }
 #ifndef __setregid
index 614e2c256dc2d728d75223300c612bea5d8949ab..c8b17ee7fcf53924c06c8b4d31b9b471aa778539 100644 (file)
 
 #include <errno.h>
 #include <unistd.h>
-#include <sys/types.h>
-
-#include <linux/posix_types.h>
-
-#include <sysdep.h>
-#include <sys/syscall.h>
+#include <setxid.h>
 #include "kernel-features.h"
-#include <pthread-functions.h>
 
 
 #if defined __NR_setresgid || defined __NR_setresgid32
@@ -44,14 +38,14 @@ __setresgid (gid_t rgid, gid_t egid, gid_t sgid)
   int result;
 
 # if __ASSUME_32BITUIDS > 0 || !defined __NR_setresgid
-  result = INLINE_SYSCALL (setresgid32, 3, rgid, egid, sgid);
+  result = INLINE_SETXID_SYSCALL (setresgid32, 3, rgid, egid, sgid);
 # else
 #  ifdef __NR_setresgid32
   if (__libc_missing_32bit_uids <= 0)
     {
       int saved_errno = errno;
 
-      result = INLINE_SYSCALL (setresgid32, 3, rgid, egid, sgid);
+      result = INLINE_SETXID_SYSCALL (setresgid32, 3, rgid, egid, sgid);
       if (result == 0)
        goto out;
       if (errno != ENOSYS)
@@ -70,24 +64,12 @@ __setresgid (gid_t rgid, gid_t egid, gid_t sgid)
       return -1;
     }
 
-  result = INLINE_SYSCALL (setresgid, 3, rgid, egid, sgid);
+  result = INLINE_SETXID_SYSCALL (setresgid, 3, rgid, egid, sgid);
 #  ifdef __NR_setresgid32
  out:
 #  endif
 # endif
 
-#if defined HAVE_PTR__NPTL_SETXID && !defined SINGLE_THREAD
-  if (result == 0 && __libc_pthread_functions.ptr__nptl_setxid != NULL)
-    {
-      struct xid_command cmd;
-      cmd.syscall_no = __NR_setresgid32;
-      cmd.id[0] = rgid;
-      cmd.id[1] = egid;
-      cmd.id[2] = sgid;
-      __libc_pthread_functions.ptr__nptl_setxid (&cmd);
-    }
-#endif
-
   return result;
 }
 libc_hidden_def (__setresgid)
index 4d735ca0f9c98b32a7c3218df0ce6ba623acf076..a91896a1a4f4b386d8400ea4b19a451a21a63e02 100644 (file)
 
 #include <errno.h>
 #include <unistd.h>
-#include <sys/types.h>
-
-#include <linux/posix_types.h>
-
-#include <sysdep.h>
-#include <sys/syscall.h>
+#include <setxid.h>
 #include "kernel-features.h"
-#include <pthread-functions.h>
 
 
 #if defined __NR_setresuid || defined __NR_setresuid32
@@ -44,14 +38,14 @@ __setresuid (uid_t ruid, uid_t euid, uid_t suid)
   int result;
 
 # if __ASSUME_32BITUIDS > 0 || !defined __NR_setresuid
-  result = INLINE_SYSCALL (setresuid32, 3, ruid, euid, suid);
+  result = INLINE_SETXID_SYSCALL (setresuid32, 3, ruid, euid, suid);
 # else
 #  ifdef __NR_setresuid32
   if (__libc_missing_32bit_uids <= 0)
     {
       int saved_errno = errno;
 
-      result = INLINE_SYSCALL (setresuid32, 3, ruid, euid, suid);
+      result = INLINE_SETXID_SYSCALL (setresuid32, 3, ruid, euid, suid);
       if (result == 0)
        goto out;
       if (errno != ENOSYS)
@@ -70,24 +64,12 @@ __setresuid (uid_t ruid, uid_t euid, uid_t suid)
       return -1;
     }
 
-  result = INLINE_SYSCALL (setresuid, 3, ruid, euid, suid);
+  result = INLINE_SETXID_SYSCALL (setresuid, 3, ruid, euid, suid);
 #  ifdef __NR_setresuid32
  out:
 #  endif
 # endif
 
-#if defined HAVE_PTR__NPTL_SETXID && !defined SINGLE_THREAD
-  if (result == 0 && __libc_pthread_functions.ptr__nptl_setxid != NULL)
-    {
-      struct xid_command cmd;
-      cmd.syscall_no = __NR_setresuid32;
-      cmd.id[0] = ruid;
-      cmd.id[1] = euid;
-      cmd.id[2] = suid;
-      __libc_pthread_functions.ptr__nptl_setxid (&cmd);
-    }
-#endif
-
   return result;
 }
 libc_hidden_def (__setresuid)
index 1e1bfcf0d4c47c5e507ed6bce43a0f4a9479ab79..55dae1ebab3bee1a74fc276cc890f63d5b21560e 100644 (file)
    02111-1307 USA.  */
 
 #include <errno.h>
-#include <sys/types.h>
 #include <unistd.h>
-
-#include <sysdep.h>
-#include <sys/syscall.h>
-
-#include <linux/posix_types.h>
+#include <setxid.h>
 #include "kernel-features.h"
-#include <pthread-functions.h>
 
 
 #ifdef __NR_setreuid32
@@ -42,14 +36,14 @@ __setreuid (uid_t ruid, uid_t euid)
   int result;
 
 #if __ASSUME_32BITUIDS > 0
-  result = INLINE_SYSCALL (setreuid32, 2, ruid, euid);
+  result = INLINE_SETXID_SYSCALL (setreuid32, 2, ruid, euid);
 #else
 # ifdef __NR_setreuid32
   if (__libc_missing_32bit_uids <= 0)
     {
       int saved_errno = errno;
 
-      result = INLINE_SYSCALL (setreuid32, 2, ruid, euid);
+      result = INLINE_SETXID_SYSCALL (setreuid32, 2, ruid, euid);
 
       if (result == 0)
        goto out;
@@ -67,23 +61,12 @@ __setreuid (uid_t ruid, uid_t euid)
       return -1;
     }
 
-  result = INLINE_SYSCALL (setreuid, 2, ruid, euid);
+  result = INLINE_SETXID_SYSCALL (setreuid, 2, ruid, euid);
 # ifdef __NR_setreuid32
  out:
 # endif
 #endif
 
-#if defined HAVE_PTR__NPTL_SETXID && !defined SINGLE_THREAD
-  if (result == 0 && __libc_pthread_functions.ptr__nptl_setxid != NULL)
-    {
-      struct xid_command cmd;
-      cmd.syscall_no = __NR_setreuid32;
-      cmd.id[0] = ruid;
-      cmd.id[1] = euid;
-      __libc_pthread_functions.ptr__nptl_setxid (&cmd);
-    }
-#endif
-
   return result;
 }
 #ifndef __setreuid
index 0d948fb77534c8c999dda34cc11e34ad25770d71..9ebf76267fa6e5a49f3647c59575f19a16da8815 100644 (file)
 
 #include <errno.h>
 #include <unistd.h>
-#include <sys/types.h>
-
-#include <sysdep.h>
-#include <sys/syscall.h>
-
-#include <linux/posix_types.h>
+#include <setxid.h>
 #include "kernel-features.h"
-#include <pthread-functions.h>
 
 
 #ifdef __NR_setuid32
@@ -42,14 +36,14 @@ __setuid (uid_t uid)
   int result;
 
 #if __ASSUME_32BITUIDS > 0 && defined __NR_setuid32
-  result = INLINE_SYSCALL (setuid32, 1, uid);
+  result = INLINE_SETXID_SYSCALL (setuid32, 1, uid);
 #else
 # ifdef __NR_setuid32
   if (__libc_missing_32bit_uids <= 0)
     {
       int saved_errno = errno;
 
-      result = INLINE_SYSCALL (setuid32, 1, uid);
+      result = INLINE_SETXID_SYSCALL (setuid32, 1, uid);
       if (result == 0)
        goto out;
       if (errno != ENOSYS)
@@ -67,22 +61,12 @@ __setuid (uid_t uid)
       return -1;
     }
 
-  result = INLINE_SYSCALL (setuid, 1, uid);
+  result = INLINE_SETXID_SYSCALL (setuid, 1, uid);
 # ifdef __NR_setuid32
  out:
 # endif
 #endif
 
-#if defined HAVE_PTR__NPTL_SETXID && !defined SINGLE_THREAD
-  if (result == 0 && __libc_pthread_functions.ptr__nptl_setxid != NULL)
-    {
-      struct xid_command cmd;
-      cmd.syscall_no = __NR_setuid32;
-      cmd.id[0] = uid;
-      __libc_pthread_functions.ptr__nptl_setxid (&cmd);
-    }
-#endif
-
   return result;
 }
 #ifndef __setuid
index 33e91c773a4545364a04c54f2ffc4047981e0c6c..f87af0d16f359b65086f4638311252845f2eedea 100644 (file)
    02111-1307 USA.  */
 
 #include <errno.h>
-#include <sys/syscall.h>
-#include <sys/types.h>
 #include <unistd.h>
-
-#include <sysdep.h>
+#include <setxid.h>
 #include "kernel-features.h"
-#include <pthread-functions.h>
 
 
 #if defined __NR_setresgid || __ASSUME_SETRESGID_SYSCALL > 0
@@ -42,10 +38,10 @@ setegid (gid_t gid)
     }
 
 # if __ASSUME_32BITUIDS > 0 && defined __NR_setresgid32
-  result = INLINE_SYSCALL (setresgid32, 3, -1, gid, -1);
+  result = INLINE_SETXID_SYSCALL (setresgid32, 3, -1, gid, -1);
 # else
   /* First try the syscall.  */
-  result = INLINE_SYSCALL (setresgid, 3, -1, gid, -1);
+  result = INLINE_SETXID_SYSCALL (setresgid, 3, -1, gid, -1);
 #  if __ASSUME_SETRESGID_SYSCALL == 0
   if (result == -1 && errno == ENOSYS)
     /* No system call available.  Use emulation.  This may not work
@@ -55,22 +51,6 @@ setegid (gid_t gid)
 #  endif
 # endif
 
-#if defined HAVE_PTR__NPTL_SETXID && !defined SINGLE_THREAD
-  if (result == 0 && __libc_pthread_functions.ptr__nptl_setxid != NULL)
-    {
-      struct xid_command cmd;
-# ifdef __NR_setresgid32
-      cmd.syscall_no = __NR_setresgid32;
-# else
-      cmd.syscall_no = __NR_setresgid;
-# endif
-      cmd.id[0] = -1;
-      cmd.id[1] = gid;
-      cmd.id[2] = -1;
-      __libc_pthread_functions.ptr__nptl_setxid (&cmd);
-    }
-#endif
-
   return result;
 }
 #ifndef setegid
index da03a1e6ef2277fc20ced5e26a4000f473033e00..5e5d1e184f721458e397121ea39be6cdf9462fbc 100644 (file)
    02111-1307 USA.  */
 
 #include <errno.h>
-#include <sys/syscall.h>
-#include <sys/types.h>
 #include <unistd.h>
-
-#include <sysdep.h>
+#include <setxid.h>
 #include "kernel-features.h"
-#include <pthread-functions.h>
 
 
 #if defined __NR_setresuid || __ASSUME_SETRESUID_SYSCALL > 0
@@ -42,10 +38,10 @@ seteuid (uid_t uid)
     }
 
 # if __ASSUME_32BITUIDS > 0 && defined __NR_setresuid32
-  result = INLINE_SYSCALL (setresuid32, 3, -1, uid, -1);
+  result = INLINE_SETXID_SYSCALL (setresuid32, 3, -1, uid, -1);
 # else
   /* First try the syscall.  */
-  result = INLINE_SYSCALL (setresuid, 3, -1, uid, -1);
+  result = INLINE_SETXID_SYSCALL (setresuid, 3, -1, uid, -1);
 #  if __ASSUME_SETRESUID_SYSCALL == 0
   if (result == -1 && errno == ENOSYS)
     /* No system call available.  Use emulation.  This may not work
@@ -55,22 +51,6 @@ seteuid (uid_t uid)
 #  endif
 # endif
 
-#if defined HAVE_PTR__NPTL_SETXID && !defined SINGLE_THREAD
-  if (result == 0 && __libc_pthread_functions.ptr__nptl_setxid != NULL)
-    {
-      struct xid_command cmd;
-# ifdef __NR_setresuid32
-      cmd.syscall_no = __NR_setresuid32;
-# else
-      cmd.syscall_no = __NR_setresuid;
-# endif
-      cmd.id[0] = -1;
-      cmd.id[1] = uid;
-      cmd.id[2] = -1;
-      __libc_pthread_functions.ptr__nptl_setxid (&cmd);
-    }
-#endif
-
   return result;
 }
 #ifndef seteuid
index dae642abb51d1ddea33ab6808eaec3be26bfa6d5..1411f536597a1d1257380c357d2e697e05fa034c 100644 (file)
 
 #include <errno.h>
 #include <unistd.h>
-#include <sys/types.h>
-
-#include <sysdep.h>
-#include <sys/syscall.h>
-
-#include <linux/posix_types.h>
-#include "kernel-features.h"
-#include <pthread-functions.h>
-
+#include <setxid.h>
 
 
 int
 __setgid (gid_t gid)
 {
-  int result;
-
-  result = INLINE_SYSCALL (setgid, 1, gid);
-
-#if defined HAVE_PTR__NPTL_SETXID && !defined SINGLE_THREAD
-  if (result == 0 && __libc_pthread_functions.ptr__nptl_setxid != NULL)
-    {
-      struct xid_command cmd;
-      cmd.syscall_no = __NR_setgid;
-      cmd.id[0] = gid;
-      __libc_pthread_functions.ptr__nptl_setxid (&cmd);
-    }
-#endif
-
-  return result;
+  return INLINE_SETXID_SYSCALL (setgid, 1, gid);
 }
 #ifndef __setgid
 weak_alias (__setgid, setgid)
index 1d539260ed2e9a0af4efabde78e23e1454e7b435..df79eae9132211dc165b34d9e714baa1030fdae1 100644 (file)
 
 #include <errno.h>
 #include <unistd.h>
-#include <sys/types.h>
-
-#include <sysdep.h>
-#include <sys/syscall.h>
-
-#include <linux/posix_types.h>
-#include "kernel-features.h"
-#include <pthread-functions.h>
+#include <setxid.h>
 
 
 int
 __setregid (gid_t rgid, gid_t egid)
 {
-  int result;
-
-  result = INLINE_SYSCALL (setregid, 2, rgid, egid);
-
-#if defined HAVE_PTR__NPTL_SETXID && !defined SINGLE_THREAD
-  if (result == 0 && __libc_pthread_functions.ptr__nptl_setxid != NULL)
-    {
-      struct xid_command cmd;
-      cmd.syscall_no = __NR_setregid;
-      cmd.id[0] = rgid;
-      cmd.id[1] = egid;
-      __libc_pthread_functions.ptr__nptl_setxid (&cmd);
-    }
-#endif
-
-  return result;
+  return INLINE_SETXID_SYSCALL (setregid, 2, rgid, egid);
 }
 #ifndef __setregid
 weak_alias (__setregid, setregid)
index ae61d42e6b997c1def34e28de69e8a47d7ebe05c..d6c9758d712a76e6d20272acd4bafea31202bd1c 100644 (file)
 
 #include <errno.h>
 #include <unistd.h>
-#include <sys/types.h>
-
-#include <sysdep.h>
-#include <sys/syscall.h>
-
-#include <linux/posix_types.h>
-#include "kernel-features.h"
-#include <pthread-functions.h>
+#include <setxid.h>
 
 
 int
 __setresgid (gid_t rgid, gid_t egid, gid_t sgid)
 {
-  int result;
-
-  result = INLINE_SYSCALL (setresgid, 3, rgid, egid, sgid);
-
-#if defined HAVE_PTR__NPTL_SETXID && !defined SINGLE_THREAD
-  if (result == 0 && __libc_pthread_functions.ptr__nptl_setxid != NULL)
-    {
-      struct xid_command cmd;
-      cmd.syscall_no = __NR_setresgid;
-      cmd.id[0] = rgid;
-      cmd.id[1] = egid;
-      cmd.id[2] = sgid;
-      __libc_pthread_functions.ptr__nptl_setxid (&cmd);
-    }
-#endif
-
-  return result;
+  return INLINE_SETXID_SYSCALL (setresgid, 3, rgid, egid, sgid);
 }
+libc_hidden_def (__setresgid)
 #ifndef __setresgid
 weak_alias (__setresgid, setresgid)
 #endif
index 962d944aa4b0d2e9d03d824910c4855776f76850..e7feeefce026d9d8ac19aa04d1b062bad1aafa2b 100644 (file)
 
 #include <errno.h>
 #include <unistd.h>
-#include <sys/types.h>
-
-#include <sysdep.h>
-#include <sys/syscall.h>
-
-#include <linux/posix_types.h>
-#include "kernel-features.h"
-#include <pthread-functions.h>
+#include <setxid.h>
 
 
 int
 __setresuid (uid_t ruid, uid_t euid, uid_t suid)
 {
-  int result;
-
-  result = INLINE_SYSCALL (setresuid, 3, ruid, euid, suid);
-
-#if defined HAVE_PTR__NPTL_SETXID && !defined SINGLE_THREAD
-  if (result == 0 && __libc_pthread_functions.ptr__nptl_setxid != NULL)
-    {
-      struct xid_command cmd;
-      cmd.syscall_no = __NR_setresuid;
-      cmd.id[0] = ruid;
-      cmd.id[1] = euid;
-      cmd.id[2] = suid;
-      __libc_pthread_functions.ptr__nptl_setxid (&cmd);
-    }
-#endif
-
-  return result;
+  return INLINE_SETXID_SYSCALL (setresuid, 3, ruid, euid, suid);
 }
+libc_hidden_def (__setresuid)
 #ifndef __setresuid
 weak_alias (__setresuid, setresuid)
 #endif
index c9d841eca02d20b5df6c1a0b98309c0f1f24a7c1..ce30d3c69629de4af8f03a7db6451958aa4efada 100644 (file)
 
 #include <errno.h>
 #include <unistd.h>
-#include <sys/types.h>
-
-#include <sysdep.h>
-#include <sys/syscall.h>
-
-#include <linux/posix_types.h>
-#include "kernel-features.h"
-#include <pthread-functions.h>
+#include <setxid.h>
 
 
 int
 __setreuid (uid_t ruid, uid_t euid)
 {
-  int result;
-
-  result = INLINE_SYSCALL (setreuid, 2, ruid, euid);
-
-#if defined HAVE_PTR__NPTL_SETXID && !defined SINGLE_THREAD
-  if (result == 0 && __libc_pthread_functions.ptr__nptl_setxid != NULL)
-    {
-      struct xid_command cmd;
-      cmd.syscall_no = __NR_setreuid;
-      cmd.id[0] = ruid;
-      cmd.id[1] = euid;
-      __libc_pthread_functions.ptr__nptl_setxid (&cmd);
-    }
-#endif
-
-  return result;
+  return INLINE_SETXID_SYSCALL (setreuid, 2, ruid, euid);
 }
 #ifndef __setreuid
 weak_alias (__setreuid, setreuid)
index 84f35176a1be7a5571be13e27db5dead0c55c88a..a523dfdbd292b999ec1a45e0b8999d8daf02b998 100644 (file)
 
 #include <errno.h>
 #include <unistd.h>
-#include <sys/types.h>
-
-#include <sysdep.h>
-#include <sys/syscall.h>
-
-#include <linux/posix_types.h>
-#include "kernel-features.h"
-#include <pthread-functions.h>
-
+#include <setxid.h>
 
 int
 __setuid (uid_t uid)
 {
-  int result;
-
-  result = INLINE_SYSCALL (setuid, 1, uid);
-
-#if defined HAVE_PTR__NPTL_SETXID && !defined SINGLE_THREAD
-  if (result == 0 && __libc_pthread_functions.ptr__nptl_setxid != NULL)
-    {
-      struct xid_command cmd;
-      cmd.syscall_no = __NR_setuid;
-      cmd.id[0] = uid;
-      __libc_pthread_functions.ptr__nptl_setxid (&cmd);
-    }
-#endif
-
-  return result;
+  return INLINE_SETXID_SYSCALL (setuid, 1, uid);
 }
 #ifndef __setuid
 weak_alias (__setuid, setuid)
index d7c8b443c478c681a09ee1bd6cc0f85691c01f6a..a97305e822817d2316c7ba6320d4d53421e5fdc3 100644 (file)
@@ -66,8 +66,6 @@ sendfile64    -       sendfile64      i:iipi  sendfile64
 setfsgid       EXTRA   setfsgid        i:i     setfsgid
 setfsuid       EXTRA   setfsuid        i:i     setfsuid
 setpgid                -       setpgid         i:ii    __setpgid       setpgid
-setresuid      -       setresuid       i:iii   __setresuid     setresuid
-setresgid      -       setresgid       i:iii   __setresgid     setresgid
 sigaltstack    -       sigaltstack     i:PP    __sigaltstack   sigaltstack
 sysinfo                EXTRA   sysinfo         i:p     sysinfo
 swapon         -       swapon          i:si    __swapon        swapon
index 228090c057cc4dc641509e84c360660634df44d4..ad896e207d40c2d745c381c80e3fcac14b544da8 100644 (file)
    Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
    02111-1307 USA.  */
 
+/* Written by Paul Eggert <eggert@cs.ucla.edu>.  */
+
 #include <time.h>
-#include <values.h>
 
+#include <limits.h>
+#include <float.h>
+#include <stdint.h>
+
+#define TYPE_BITS(type) (sizeof (type) * CHAR_BIT)
+#define TYPE_FLOATING(type) ((type) 0.5 == 0.5)
+#define TYPE_SIGNED(type) ((type) -1 < 0)
+
+/* Return the difference between TIME1 and TIME0, where TIME0 <= TIME1.
+   time_t is known to be an integer type.  */
+
+static double
+subtract (time_t time1, time_t time0)
+{
+  if (! TYPE_SIGNED (time_t))
+    return time1 - time0;
+  else
+    {
+      /* Optimize the common special cases where time_t
+        can be converted to uintmax_t without losing information.  */
+      uintmax_t dt = (uintmax_t) time1 - (uintmax_t) time0;
+      double delta = dt;
+
+      if (UINTMAX_MAX / 2 < INTMAX_MAX)
+       {
+         /* This is a rare host where uintmax_t has padding bits, and possibly
+            information was lost when converting time_t to uintmax_t.
+            Check for overflow by comparing dt/2 to (time1/2 - time0/2).
+            Overflow occurred if they differ by more than a small slop.
+            Thanks to Clive D.W. Feather for detailed technical advice about
+            hosts with padding bits.
+
+            In the following code the "h" prefix means half.  By range
+            analysis, we have:
+
+                  -0.5 <= ht1 - 0.5*time1 <= 0.5
+                  -0.5 <= ht0 - 0.5*time0 <= 0.5
+                  -1.0 <= dht - 0.5*(time1 - time0) <= 1.0
+
+             If overflow has not occurred, we also have:
+
+                  -0.5 <= hdt - 0.5*(time1 - time0) <= 0
+                  -1.0 <= dht - hdt <= 1.5
+
+             and since dht - hdt is an integer, we also have:
+
+                  -1 <= dht - hdt <= 1
+
+             or equivalently:
+
+                  0 <= dht - hdt + 1 <= 2
+
+             In the above analysis, all the operators have their exact
+             mathematical semantics, not C semantics.  However, dht - hdt +
+             1 is unsigned in C, so it need not be compared to zero.  */
+
+         uintmax_t hdt = dt / 2;
+         time_t ht1 = time1 / 2;
+         time_t ht0 = time0 / 2;
+         time_t dht = ht1 - ht0;
+
+         if (2 < dht - hdt + 1)
+           {
+             /* Repair delta overflow.
+
+                The following expression contains a second rounding,
+                so the result may not be the closest to the true answer.
+                This problem occurs only with very large differences.
+                It's too painful to fix this portably.  */
+
+             delta = dt + 2.0L * (UINTMAX_MAX - UINTMAX_MAX / 2);
+           }
+       }
+
+      return delta;
+    }
+}
 
 /* Return the difference between TIME1 and TIME0.  */
 double
-__difftime (time1, time0)
-     time_t time1;
-     time_t time0;
+__difftime (time_t time1, time_t time0)
 {
-  /* Algorithm courtesy Paul Eggert (eggert@twinsun.com).  */
-
-  time_t delta, hibit;
+  /* Convert to double and then subtract if no double-rounding error could
+     result.  */
 
-  if (sizeof (time_t) < sizeof (double))
+  if (TYPE_BITS (time_t) <= DBL_MANT_DIG
+      || (TYPE_FLOATING (time_t) && sizeof (time_t) < sizeof (long double)))
     return (double) time1 - (double) time0;
-  if (sizeof (time_t) < sizeof (long double))
+
+  /* Likewise for long double.  */
+
+  if (TYPE_BITS (time_t) <= LDBL_MANT_DIG || TYPE_FLOATING (time_t))
     return (long double) time1 - (long double) time0;
 
-  if (time1 < time0)
-    return - __difftime (time0, time1);
-
-  /* As much as possible, avoid loss of precision by computing the
-    difference before converting to double.  */
-  delta = time1 - time0;
-  if (delta >= 0)
-    return delta;
-
-  /* Repair delta overflow.  */
-  hibit = (~ (time_t) 0) << (_TYPEBITS (time_t) - 1);
-
-  /* The following expression rounds twice, which means the result may not
-     be the closest to the true answer.  For example, suppose time_t is
-     64-bit signed int, long_double is IEEE 754 double with default
-     rounding, time1 = 9223372036854775807 and time0 = -1536.  Then the
-     true difference is 9223372036854777343, which rounds to
-     9223372036854777856 with a total error of 513.  But delta overflows to
-     -9223372036854774273, which rounds to -9223372036854774784, and
-     correcting this by subtracting 2 * (long_double) hibit (i.e. by adding
-     2**64 = 18446744073709551616) yields 9223372036854776832, which rounds
-     to 9223372036854775808 with a total error of 1535 instead.  This
-     problem occurs only with very large differences.  It's too painful to
-     fix this portably.  We are not alone in this problem; many C compilers
-     round twice when converting large unsigned types to small floating
-     types, so if time_t is unsigned the "return delta" above has the same
-     double-rounding problem.  */
-  return delta - 2 * (long double) hibit;
+  /* Subtract the smaller integer from the larger, convert the difference to
+     double, and then negate if needed.  */
+
+  return time1 < time0 ? - subtract (time0, time1) : subtract (time1, time0);
 }
 strong_alias (__difftime, difftime)
index 72b20128a30c5deadd53f0416ca66dac5a76ba00..280f5f47d518d016980e11eb6c65ebaf6ffc2986 100644 (file)
 # define mktime my_mktime
 #endif /* DEBUG */
 
+/* Shift A right by B bits portably, by dividing A by 2**B and
+   truncating towards minus infinity.  A and B should be free of side
+   effects, and B should be in the range 0 <= B <= INT_BITS - 2, where
+   INT_BITS is the number of useful bits in an int.  GNU code can
+   assume that INT_BITS is at least 32.
+
+   ISO C99 says that A >> B is implementation-defined if A < 0.  Some
+   implementations (e.g., UNICOS 9.0 on a Cray Y-MP EL) don't shift
+   right in the usual way when A < 0, so SHR falls back on division if
+   ordinary A >> B doesn't seem to be the usual signed shift.  */
+#define SHR(a, b)      \
+  (-1 >> 1 == -1       \
+   ? (a) >> (b)                \
+   : (a) / (1 << (b)) - ((a) % (1 << (b)) < 0))
+
 /* The extra casts work around common compiler bugs.  */
 #define TYPE_SIGNED(t) (! ((t) 0 < (t) -1))
 /* The outer cast is needed to work around a bug in Cray C 5.0.3.0.
 #ifndef TIME_T_MAX
 # define TIME_T_MAX TYPE_MAXIMUM (time_t)
 #endif
-#define TIME_T_MIDPOINT (((TIME_T_MIN + TIME_T_MAX) >> 1) + 1)
+#define TIME_T_MIDPOINT (SHR (TIME_T_MIN + TIME_T_MAX, 1) + 1)
 
 /* Verify a requirement at compile-time (unlike assert, which is runtime).  */
 #define verify(name, assertion) struct name { char a[(assertion) ? 1 : -1]; }
 
 verify (time_t_is_integer, (time_t) 0.5 == 0);
 verify (twos_complement_arithmetic, -1 == ~1 + 1);
-verify (right_shift_propagates_sign, -1 >> 1 == -1);
 /* The code also assumes that signed integer overflow silently wraps
    around, but this assumption can't be stated without causing a
    diagnostic on some hosts.  */
@@ -133,12 +147,12 @@ ydhms_diff (long int year1, long int yday1, int hour1, int min1, int sec1,
 
   /* Compute intervening leap days correctly even if year is negative.
      Take care to avoid integer overflow here.  */
-  int a4 = (year1 >> 2) + (TM_YEAR_BASE >> 2) - ! (year1 & 3);
-  int b4 = (year0 >> 2) + (TM_YEAR_BASE >> 2) - ! (year0 & 3);
+  int a4 = SHR (year1, 2) + SHR (TM_YEAR_BASE, 2) - ! (year1 & 3);
+  int b4 = SHR (year0, 2) + SHR (TM_YEAR_BASE, 2) - ! (year0 & 3);
   int a100 = a4 / 25 - (a4 % 25 < 0);
   int b100 = b4 / 25 - (b4 % 25 < 0);
-  int a400 = a100 >> 2;
-  int b400 = b100 >> 2;
+  int a400 = SHR (a100, 2);
+  int b400 = SHR (b100, 2);
   int intervening_leap_days = (a4 - b4) - (a100 - b100) + (a400 - b400);
 
   /* Compute the desired time in time_t precision.  Overflow might
@@ -322,14 +336,16 @@ __mktime_internal (struct tm *tp,
       int LOG2_YEARS_PER_BIENNIUM = 1;
 
       int approx_requested_biennia =
-       ((year_requested >> LOG2_YEARS_PER_BIENNIUM)
-        - ((EPOCH_YEAR - TM_YEAR_BASE) >> LOG2_YEARS_PER_BIENNIUM)
-        + (mday >> ALOG2_DAYS_PER_BIENNIUM)
-        + (hour >> ALOG2_HOURS_PER_BIENNIUM)
-        + (min >> ALOG2_MINUTES_PER_BIENNIUM)
-        + (LEAP_SECONDS_POSSIBLE ? 0 : sec >> ALOG2_SECONDS_PER_BIENNIUM));
-
-      int approx_biennia = t0 >> ALOG2_SECONDS_PER_BIENNIUM;
+       (SHR (year_requested, LOG2_YEARS_PER_BIENNIUM)
+        - SHR (EPOCH_YEAR - TM_YEAR_BASE, LOG2_YEARS_PER_BIENNIUM)
+        + SHR (mday, ALOG2_DAYS_PER_BIENNIUM)
+        + SHR (hour, ALOG2_HOURS_PER_BIENNIUM)
+        + SHR (min, ALOG2_MINUTES_PER_BIENNIUM)
+        + (LEAP_SECONDS_POSSIBLE
+           ? 0
+           : SHR (sec, ALOG2_SECONDS_PER_BIENNIUM)));
+
+      int approx_biennia = SHR (t0, ALOG2_SECONDS_PER_BIENNIUM);
       int diff = approx_biennia - approx_requested_biennia;
       int abs_diff = diff < 0 ? - diff : diff;
 
@@ -347,7 +363,7 @@ __mktime_internal (struct tm *tp,
          /* Overflow occurred.  Try repairing it; this might work if
             the time zone offset is enough to undo the overflow.  */
          time_t repaired_t0 = -1 - t0;
-         approx_biennia = repaired_t0 >> ALOG2_SECONDS_PER_BIENNIUM;
+         approx_biennia = SHR (repaired_t0, ALOG2_SECONDS_PER_BIENNIUM);
          diff = approx_biennia - approx_requested_biennia;
          abs_diff = diff < 0 ? - diff : diff;
          if (overflow_threshold < abs_diff)