mirror of
git://sourceware.org/git/glibc.git
synced 2025-04-12 14:21:18 +08:00
Updated to fedora-glibc-20041112T1640
This commit is contained in:
parent
9abf55c24c
commit
8ae4ba1c6d
111
ChangeLog
111
ChangeLog
@ -1,11 +1,118 @@
|
||||
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.
|
||||
|
||||
|
@ -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
|
||||
|
2
Rules
2
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 =
|
||||
|
@ -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
|
||||
|
@ -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)
|
||||
|
@ -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.
|
||||
|
@ -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
|
||||
|
||||
|
@ -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))
|
||||
|
@ -101,7 +101,7 @@ struct pthread_unwind_buf
|
||||
struct xid_command
|
||||
{
|
||||
int syscall_no;
|
||||
id_t id[3];
|
||||
long id[3];
|
||||
volatile int cntr;
|
||||
};
|
||||
|
||||
|
@ -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 */
|
||||
|
@ -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. */
|
||||
|
64
nptl/sysdeps/pthread/setxid.h
Normal file
64
nptl/sysdeps/pthread/setxid.h
Normal file
@ -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
|
1
nptl/tst-setuid1-static.c
Normal file
1
nptl/tst-setuid1-static.c
Normal file
@ -0,0 +1 @@
|
||||
#include "tst-setuid1.c"
|
1085
nptl/tst-setuid1.c
Normal file
1085
nptl/tst-setuid1.c
Normal file
File diff suppressed because it is too large
Load Diff
@ -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
|
||||
|
59
posix/bug-regex24.c
Normal file
59
posix/bug-regex24.c
Normal file
@ -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"
|
@ -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)
|
||||
{
|
||||
|
@ -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
|
||||
|
366
posix/regexec.c
366
posix/regexec.c
@ -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);
|
||||
match_kind =
|
||||
(fastmap
|
||||
? ((sb || !(preg->syntax & RE_ICASE || t) ? 4 : 0)
|
||||
| (range >= 0 ? 2 : 0)
|
||||
| (t != NULL ? 1 : 0))
|
||||
: 8);
|
||||
|
||||
for (;;)
|
||||
for (;; match_first += incr)
|
||||
{
|
||||
/* At first get the current byte from input string. */
|
||||
if (fastmap)
|
||||
{
|
||||
if (BE (fast_translate, 1))
|
||||
{
|
||||
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;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
int ch;
|
||||
err = REG_NOMATCH;
|
||||
if (match_first < left_lim || right_lim < match_first)
|
||||
goto free_return;
|
||||
|
||||
do
|
||||
{
|
||||
/* 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;
|
||||
}
|
||||
while (match_first >= left_lim && match_first <= right_lim);
|
||||
if (! fastmap[ch])
|
||||
break;
|
||||
/* 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)
|
||||
{
|
||||
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))
|
||||
{
|
||||
ch = match_first >= length
|
||||
? 0 : (unsigned char) string[match_first];
|
||||
if (!fastmap[t ? t[ch] : ch])
|
||||
goto free_return;
|
||||
}
|
||||
break;
|
||||
|
||||
case 4:
|
||||
case 5:
|
||||
/* Fastmap without multi-byte translation, match backwards. */
|
||||
while (match_first >= left_lim)
|
||||
{
|
||||
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;
|
||||
|
||||
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))
|
||||
{
|
||||
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;
|
||||
}
|
||||
/* 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);
|
||||
}
|
||||
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
|
||||
{
|
||||
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. */
|
||||
}
|
||||
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;
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -17,11 +17,22 @@
|
||||
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:
|
||||
@ -33,10 +44,7 @@
|
||||
// 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
|
||||
|
4
sysdeps/unix/setxid.h
Normal file
4
sysdeps/unix/setxid.h
Normal file
@ -0,0 +1,4 @@
|
||||
#include <sysdep.h>
|
||||
|
||||
#define INLINE_SETXID_SYSCALL(name, nr, args...) \
|
||||
INLINE_SYSCALL (name, nr, args)
|
@ -18,35 +18,13 @@
|
||||
|
||||
#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)
|
||||
|
@ -18,36 +18,14 @@
|
||||
|
||||
#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
|
||||
|
@ -18,36 +18,14 @@
|
||||
|
||||
#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
|
||||
|
@ -18,35 +18,13 @@
|
||||
|
||||
#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)
|
||||
|
@ -18,11 +18,8 @@
|
||||
|
||||
#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)
|
||||
|
@ -17,12 +17,9 @@
|
||||
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)
|
||||
|
@ -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
|
||||
@ -19,15 +18,8 @@
|
||||
|
||||
#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
|
||||
|
@ -17,15 +17,9 @@
|
||||
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
|
||||
|
@ -18,14 +18,8 @@
|
||||
|
||||
#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)
|
||||
|
@ -18,14 +18,8 @@
|
||||
|
||||
#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)
|
||||
|
@ -17,15 +17,9 @@
|
||||
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
|
||||
|
@ -18,14 +18,8 @@
|
||||
|
||||
#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
|
||||
|
@ -17,13 +17,9 @@
|
||||
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
|
||||
|
@ -17,13 +17,9 @@
|
||||
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
|
||||
|
@ -18,35 +18,13 @@
|
||||
|
||||
#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)
|
||||
|
@ -18,35 +18,13 @@
|
||||
|
||||
#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)
|
||||
|
@ -18,37 +18,15 @@
|
||||
|
||||
#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
|
||||
|
@ -18,37 +18,15 @@
|
||||
|
||||
#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
|
||||
|
@ -18,35 +18,13 @@
|
||||
|
||||
#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)
|
||||
|
@ -18,34 +18,12 @@
|
||||
|
||||
#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)
|
||||
|
@ -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
|
||||
|
129
time/difftime.c
129
time/difftime.c
@ -16,52 +16,107 @@
|
||||
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
||||
02111-1307 USA. */
|
||||
|
||||
#include <time.h>
|
||||
#include <values.h>
|
||||
/* Written by Paul Eggert <eggert@cs.ucla.edu>. */
|
||||
|
||||
#include <time.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). */
|
||||
/* Convert to double and then subtract if no double-rounding error could
|
||||
result. */
|
||||
|
||||
time_t delta, hibit;
|
||||
|
||||
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);
|
||||
/* Subtract the smaller integer from the larger, convert the difference to
|
||||
double, and then negate if needed. */
|
||||
|
||||
/* 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;
|
||||
return time1 < time0 ? - subtract (time0, time1) : subtract (time1, time0);
|
||||
}
|
||||
strong_alias (__difftime, difftime)
|
||||
|
@ -46,6 +46,21 @@
|
||||
# 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.
|
||||
@ -60,14 +75,13 @@
|
||||
#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));
|
||||
(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 = t0 >> 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)
|
||||
|
Loading…
x
Reference in New Issue
Block a user