mirror of
git://sourceware.org/git/glibc.git
synced 2026-09-09 11:58:23 +08:00
Compare commits
54
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
01682b1f05 | ||
|
|
82496aab64 | ||
|
|
9869e6ec91 | ||
|
|
3ee87ca7d4 | ||
|
|
7dbf6a6cd5 | ||
|
|
8802619dd4 | ||
|
|
8d5be89424 | ||
|
|
0caba1fbdb | ||
|
|
6fb78a8758 | ||
|
|
c25d26bbb4 | ||
|
|
ddbf09971d | ||
|
|
09c3bcb4ad | ||
|
|
fd63f7c6ce | ||
|
|
85148842d4 | ||
|
|
6d96590587 | ||
|
|
b7a09b9201 | ||
|
|
6a87697239 | ||
|
|
bd307f4e23 | ||
|
|
f9ff03a835 | ||
|
|
2b13f2ccc0 | ||
|
|
f1750fb9c6 | ||
|
|
efaf80c5d0 | ||
|
|
959f4c0547 | ||
|
|
627cc92643 | ||
|
|
1b16f19afc | ||
|
|
037c97bbc9 | ||
|
|
bd7c3bed54 | ||
|
|
338cc5101b | ||
|
|
04a9e7f251 | ||
|
|
fd8e1ac720 | ||
|
|
b402c96065 | ||
|
|
5ab387d33b | ||
|
|
ff9e0dc823 | ||
|
|
5d44b2ea72 | ||
|
|
1547e88a9a | ||
|
|
1a19a35223 | ||
|
|
237910315c | ||
|
|
a0d24ebc12 | ||
|
|
1e96287768 | ||
|
|
a1711aa2c9 | ||
|
|
996d168e57 | ||
|
|
05bb11efb2 | ||
|
|
0847bc6ef9 | ||
|
|
f66e5db9b0 | ||
|
|
dc60a4e495 | ||
|
|
c699a3bdd7 | ||
|
|
aaadc59ce1 | ||
|
|
a343cb0f24 | ||
|
|
b9bdb95c3f | ||
|
|
f67c6d9684 | ||
|
|
3cd7504450 | ||
|
|
59ae4124b7 | ||
|
|
ee414d57cf | ||
|
|
b5707b44d2 |
@@ -1,3 +1,710 @@
|
||||
2004-10-12 Jakub Jelinek <jakub@redhat.com>
|
||||
|
||||
* sysdeps/generic/segfault.c: Include alloca.h and stdint.h.
|
||||
Don't include frame.h.
|
||||
(CURRENT_STACK_FRAME, INNER_THAN, ADVANCE_STACK_FRAME): Remove.
|
||||
(catch_segfault): Use backtrace function.
|
||||
|
||||
* sysdeps/unix/sysv/linux/ia64/bits/sigcontext.h: Fix comment.
|
||||
* sysdeps/unix/sysv/linux/ia64/register-dump.h: New file.
|
||||
* sysdeps/unix/sysv/linux/ia64/sigcontextinfo.h (GET_PC): Return sc_ip
|
||||
field.
|
||||
|
||||
2004-10-13 Ulrich Drepper <drepper@redhat.com>
|
||||
|
||||
Add support for namespaces in the dynamic linker.
|
||||
* dlfcn/Makefile (libdl-routines): Add dlmopen.
|
||||
* dlfcn/Versions [libdl, GLIBC_2.3.4]: Add dlmopen.
|
||||
* dlfcn/dlfcn.h: Define Lmid_t, LM_ID_BASE, and LM_ID_NEWLM.
|
||||
Declare dlmopen. Document RTLD_DI_LMID.
|
||||
* dlfcn/dlinfo.c: Handle RTLD_DI_LMID.
|
||||
* dlfcn/dlmopen.c: New file.
|
||||
* dlfcn/dlopen.c: Pass new parameter to _dl_open.
|
||||
* dlfcn/dlopenold.c: Likewise.
|
||||
* elf/dl-addr.c: Adjust for removal of GL(dl_loaded).
|
||||
* elf/dl-caller.c: Likewise.
|
||||
* elf/dl-close.c: Likewise.
|
||||
* elf/dl-conflict.c: Likewise.
|
||||
* elf/dl-debug.c: Likewise.
|
||||
* elf/dl-lookup.c: Likewise.
|
||||
* elf/dl-sym.c: Likewise.
|
||||
* elf/dl-version.c: Likewise.
|
||||
* elf/do-lookup.h: Likewise.
|
||||
* elf/rtld.c: Likewise.
|
||||
* sysdeps/unix/sysv/linux/i386/dl-librecon.h: Likewise.
|
||||
* elf/dl-depsc: Likewise. Add new parameter to _dl_map_object.
|
||||
* elf/dl-fini.c: Call destructors in all namespaces.
|
||||
* elf/dl-iteratephdr.c: Compute total nloaded. Adjust for removal of
|
||||
GL(dl_loaded).
|
||||
* elf/dl-libc.c: Pass new parameter to _dl_open. Adjust for removal
|
||||
of GL(dl_loaded).
|
||||
* elf/dl-load.c (_dl_map_object_from_fd): Don't load ld.so a second
|
||||
time. Reuse the one from the main namespace in all others.
|
||||
Pass new parameter to _dl_new_object.
|
||||
Adjust for removal of GL(dl_loaded).
|
||||
* elf/dl-object.c: Take new parameter. Use it to initialize l_ns.
|
||||
Adjust for removal of GL(dl_loaded).
|
||||
* elf/dl-open.c (_dl_open): Take new parameter.
|
||||
Adjust for removal of GL(dl_loaded).
|
||||
* elf/dl-support.c: Replace global _dl_loaded etc variables with
|
||||
_dl_ns variable.
|
||||
* include/dlfcn.h: Adjust prototype of _dl_open.
|
||||
Define __LM_ID_CALLER.
|
||||
* include/link.h: Add l_real, l_ns, and l_direct_opencount elements.
|
||||
* sysdeps/generic/dl-tls.c: Bump TLS_STATIC_SURPLUS. Since libc is
|
||||
using TLS we need memory appropriate to the number of namespaces.
|
||||
* sysdeps/generic/ldsodefs.h (struct rtld_global): Replace _dl_loaded,
|
||||
_dl_nloaded, _dl_global_scope, _dl_main_searchlist, and
|
||||
_dl_global_scope_alloc with _dl_ns element. Define DL_NNS.
|
||||
Adjust prototypes of _dl_map_object and member in rtld_global_ro.
|
||||
* malloc/malloc.c: Include <dlfcn.h>.
|
||||
* malloc/arena.c (ptmalloc_init): If libc is not in primary namespace,
|
||||
never use brk.
|
||||
* elf/Makefile: Add rules to build and run tst-dlmopen1 and
|
||||
tst-dlmopen2.
|
||||
* elf/tst-dlmopen1.c: New file.
|
||||
* elf/tst-dlmopen1mod.c: New file.
|
||||
* elf/tst-dlmopen2.c: New file.
|
||||
|
||||
* elf/dl-close.c: Improve reference counting by tracking direct loads.
|
||||
* elf/dl-lookup.c (add_dependency): Likewise.
|
||||
* elf/dl-open.c (dl_open_worker): Likewise.
|
||||
* elf/rtld.c (dl_main): Likewise.
|
||||
|
||||
2004-09-09 GOTO Masanori <gotom@debian.or.jp>
|
||||
|
||||
[BZ #77]
|
||||
* elf/dl-close.c: Count down l_opencount to check not only for
|
||||
l_reldeps, but also l_initfini.
|
||||
|
||||
2004-10-13 Ulrich Drepper <drepper@redhat.com>
|
||||
|
||||
* elf/dl-close.c (_dl_close): Update bug reporting instructions.
|
||||
|
||||
2004-10-11 Ulrich Drepper <drepper@redhat.com>
|
||||
|
||||
* timezone/asia: Update from tzdata2004e.
|
||||
* timezone/southamerica: Likewise.
|
||||
* timezone/private.h: Update from tzcode2004e.
|
||||
* timezone/zdump.c: Likewise.
|
||||
|
||||
* stdio-common/vfscanf.c: Add support for reading localized
|
||||
digits. Patch mainly by Hamed Malek <hamed@bamdad.org>.
|
||||
|
||||
* resolv/res_init.c (res_thread_freeres): Reset _res.options.
|
||||
[BZ #434]
|
||||
|
||||
* resolv/res_send.c (send_dg): Use nonblocking sockets. Add
|
||||
appropriate poll/select calls and restart operation if necessary.
|
||||
Also handle EINTR.
|
||||
|
||||
* elf/tst-dlopenrpath.c (do_test): Enable code which was disabled
|
||||
for debugging.
|
||||
|
||||
* elf/dl-sym.c (do_sym): Avoid using global variable.
|
||||
|
||||
* elf/dl-addr.c (_dl_addr): Really use match everywhere.
|
||||
|
||||
2004-10-09 Andreas Schwab <schwab@suse.de>
|
||||
|
||||
* sysdeps/m68k/memcopy.h (WORD_COPY_BWD): Remove use of cast as
|
||||
lvalue.
|
||||
|
||||
* sysdeps/m68k/fpu/bits/mathinline.h: Remove __THROW from inline
|
||||
definitions.
|
||||
|
||||
2004-10-07 Andreas Schwab <schwab@suse.de>
|
||||
|
||||
* misc/sys/uio.h: Change __vector to __iovec to avoid clash with
|
||||
altivec.
|
||||
|
||||
2004-10-06 Alan Modra <amodra@bigpond.net.au>
|
||||
|
||||
* gmon/Makefile (CFLAGS-mcount.c): Move before inclusion of "Rules".
|
||||
* sysdeps/powerpc/powerpc64/Makefile (CFLAGS-mcount.c): Add
|
||||
-msoft-float.
|
||||
* sysdeps/powerpc/powerpc64/sysdep.h (SAVE_ARG, REST_ARG): New macros.
|
||||
(CALL_MCOUNT): Replace with a gas macro implementation.
|
||||
(EALIGN): Delete PROF version.
|
||||
* sysdeps/powerpc/powerpc64/__longjmp-common.S: Invoke CALL_MCOUNT.
|
||||
* sysdeps/powerpc/powerpc64/bsd-_setjmp.S: Likewise.
|
||||
* sysdeps/powerpc/powerpc64/bsd-setjmp.S: Likewise.
|
||||
* sysdeps/powerpc/powerpc64/setjmp-common.S: Likewise.
|
||||
* sysdeps/powerpc/powerpc64/memcpy.S: Likewise.
|
||||
* sysdeps/powerpc/powerpc64/memset.S: Likewise.
|
||||
* sysdeps/powerpc/powerpc64/stpcpy.S: Likewise.
|
||||
* sysdeps/powerpc/powerpc64/strchr.S: Likewise.
|
||||
* sysdeps/powerpc/powerpc64/strcmp.S: Likewise.
|
||||
* sysdeps/powerpc/powerpc64/strcpy.S: Likewise.
|
||||
* sysdeps/powerpc/powerpc64/strlen.S: Likewise.
|
||||
* sysdeps/powerpc/powerpc64/strncmp.S: Likewise.
|
||||
* sysdeps/powerpc/powerpc64/fpu/s_ceil.S: Likewise.
|
||||
* sysdeps/powerpc/powerpc64/fpu/s_ceilf.S: Likewise.
|
||||
* sysdeps/powerpc/powerpc64/fpu/s_copysign.S: Likewise.
|
||||
* sysdeps/powerpc/powerpc64/fpu/s_floor.S: Likewise.
|
||||
* sysdeps/powerpc/powerpc64/fpu/s_floorf.S: Likewise.
|
||||
* sysdeps/powerpc/powerpc64/fpu/s_llrint.S: Likewise.
|
||||
* sysdeps/powerpc/powerpc64/fpu/s_llrintf.S: Likewise.
|
||||
* sysdeps/powerpc/powerpc64/fpu/s_llround.S: Likewise.
|
||||
* sysdeps/powerpc/powerpc64/fpu/s_llroundf.S: Likewise.
|
||||
* sysdeps/powerpc/powerpc64/fpu/s_rint.S: Likewise.
|
||||
* sysdeps/powerpc/powerpc64/fpu/s_rintf.S: Likewise.
|
||||
* sysdeps/powerpc/powerpc64/fpu/s_round.S: Likewise.
|
||||
* sysdeps/powerpc/powerpc64/fpu/s_roundf.S: Likewise.
|
||||
* sysdeps/powerpc/powerpc64/fpu/s_trunc.S: Likewise.
|
||||
* sysdeps/powerpc/powerpc64/fpu/s_truncf.S: Likewise.
|
||||
|
||||
* sysdeps/powerpc/powerpc64/setjmp-common.S: Add extra entry point
|
||||
past _mcount call.
|
||||
* sysdeps/powerpc/powerpc64/bsd-_setjmp.S: Use it.
|
||||
* sysdeps/powerpc/powerpc64/bsd-setjmp.S: Likewise.
|
||||
|
||||
2004-10-06 Ulrich Drepper <drepper@redhat.com>
|
||||
|
||||
* resolv/res_mkquery.c (res_nmkquery): Reject randombits value if
|
||||
low 16 bits are zero.
|
||||
|
||||
2004-10-06 Jakub Jelinek <jakub@redhat.com>
|
||||
|
||||
* posix/tst-getaddrinfo2.c: Include stdlib.h and string.h.
|
||||
(do_test): Use %p instead of 0x%08X to print a pointer.
|
||||
|
||||
* malloc/malloc.c: Include stdio-common/_itoa.h.
|
||||
|
||||
2004-10-05 Ulrich Drepper <drepper@redhat.com>
|
||||
|
||||
* elf/rtld.c (dl_main): Use _dl_debug_printf instead of _dl_printf
|
||||
for prelink message.
|
||||
|
||||
2004-10-05 Jakub Jelinek <jakub@redhat.com>
|
||||
|
||||
* sysdeps/unix/sysv/linux/s390/s390-32/sysdep.h: Include dl-sysdep.h.
|
||||
* sysdeps/unix/sysv/linux/s390/s390-64/sysdep.h: Likewise.
|
||||
|
||||
2004-10-05 Ulrich Drepper <drepper@redhat.com>
|
||||
|
||||
* grp/initgroups.c: Remove duplicate group IDs.
|
||||
* grp/compat-initgroups.c: Likewise.
|
||||
* nscd/initgrcache.c: Likewise.
|
||||
|
||||
2004-10-05 Jakub Jelinek <jakub@redhat.com>
|
||||
|
||||
* sysdeps/unix/sysv/linux/x86_64/sysconf.c (__sysconf): Return 200112L
|
||||
for _SC_CPUTIME or _SC_THREAD_CPUTIME.
|
||||
|
||||
* nscd/Makefile (nscd-cflags): Set to -DIS_IN_nscd=1, plus
|
||||
-fpie if building PIE.
|
||||
(CFLAGS-*.c): Use it.
|
||||
|
||||
* nscd/Makefile (relro-LDFLAGS): Add -Wl,-z,now if have-z-relro.
|
||||
($(objpfx)nscd): Add $(relro-LDFLAGS).
|
||||
|
||||
* sysdeps/unix/sysv/linux/i386/sysconf.c: Include hp-timing.h.
|
||||
(__sysconf): Return -1 for _SC_CPUTIME or _SC_THREAD_CPUTIME if
|
||||
!HP_TIMING_AVAIL.
|
||||
|
||||
2004-10-05 Ulrich Drepper <drepper@redhat.com>
|
||||
|
||||
* nscd/Makefile (distribute): Remove TODO.
|
||||
* nscd/TODO: Removed.
|
||||
|
||||
2004-10-04 Ulrich Drepper <drepper@redhat.com>
|
||||
|
||||
* nscd/gai.c: Define __no_netlink_support if NEED_NETLINK is
|
||||
defined and __ASSUME_NETLINK_SUPPORT is zero.
|
||||
* sysdeps/unix/sysv/linux/Makefile (CFLAGS-gai.c): Add
|
||||
-DNEED_NETLINK.
|
||||
|
||||
* malloc/mtrace.pl: Avoid calling location unless it is needed for
|
||||
output. Patch by Edward Bishop <binutils@gmail.com>.
|
||||
|
||||
* nscd/Makefile (CFLAGS-gai.c): Add -fpie.
|
||||
|
||||
2004-10-04 H.J. Lu <hongjiu.lu@intel.com>
|
||||
|
||||
* sysdeps/unix/sysv/linux/ia64/clock_getcpuclockid.c
|
||||
(clock_getcpuclockid): Add missing retval.
|
||||
|
||||
* sysdeps/unix/sysv/linux/ia64/sysconf.c (linux_sysconf): Fix a typo.
|
||||
|
||||
2004-10-04 Roland McGrath <roland@redhat.com>
|
||||
|
||||
* include/errno.h [RTLD_PRIVATE_ERRNO] (errno): Rename the real symbol
|
||||
to rtld_errno.
|
||||
* sysdeps/generic/errno.c [RTLD_PRIVATE_ERRNO] (rtld_errno): Define it,
|
||||
and don't define any other errno names.
|
||||
* sysdeps/unix/alpha/sysdep.h [RTLD_PRIVATE_ERRNO]: Use rtld_errno in
|
||||
place of errno.
|
||||
* sysdeps/unix/i386/sysdep.S: Likewise.
|
||||
* sysdeps/unix/sysv/linux/i386/sysdep.h: Likewise.
|
||||
* sysdeps/unix/sysv/linux/ia64/sysdep.S: Likewise.
|
||||
* sysdeps/unix/sysv/linux/m68k/sysdep.h: Likewise.
|
||||
* sysdeps/unix/sysv/linux/s390/s390-32/sysdep.S: Likewise.
|
||||
* sysdeps/unix/sysv/linux/s390/s390-32/sysdep.h: Likewise.
|
||||
* sysdeps/unix/sysv/linux/s390/s390-64/sysdep.S: Likewise.
|
||||
* sysdeps/unix/sysv/linux/s390/s390-64/sysdep.h: Likewise.
|
||||
* sysdeps/unix/sysv/linux/sh/sysdep.h: Likewise.
|
||||
* sysdeps/unix/sysv/linux/sparc/sparc32/sysdep.h: Likewise.
|
||||
* sysdeps/unix/sysv/linux/x86_64/sysdep.h: Likewise.
|
||||
* sysdeps/unix/x86_64/sysdep.S: Likewise.
|
||||
|
||||
* sysdeps/generic/errno.c [! USE___THREAD] (errno): Use `nocommon'
|
||||
attribute instead of `section'.
|
||||
|
||||
2004-10-04 Ulrich Drepper <drepper@redhat.com>
|
||||
|
||||
* sysdeps/unix/sysv/linux/ia64/sysconf.c: New file.
|
||||
* sysdeps/unix/sysv/linux/ia64/Dist: Add has_cpuclock.c.
|
||||
* sysdeps/unix/sysv/linux/ia64/clock_getcpuclockid.c: Move actual
|
||||
testing code to...
|
||||
* sysdeps/unix/sysv/linux/ia64/has_cpuclock.c: ...here. New file.
|
||||
* sysdeps/unix/sysv/linux/i386/sysconf.c: Add dynamic check for
|
||||
_SC_CPUTIME and _SC_THREAD_CPUTIME.
|
||||
|
||||
* nscd/connections.c (start_threads): Use sysconf in case
|
||||
_POSIX_CLOCK_SELECTION or _POSIX_MONOTONIC_CLOCK is not greater zero.
|
||||
|
||||
* nscd/Makefile (nscd-modules): Add gai.
|
||||
* nscd/gai.c: New file.
|
||||
* nscd/nscd.c: Remove getaddrinfo stub definition.
|
||||
|
||||
* assert/assert.h: Give up on using __builtin_expect.
|
||||
|
||||
* elf/rtld.c (dl_main): Only skip => output in ldd mode if both
|
||||
strings are identical.
|
||||
|
||||
2004-03-18 Jakub Jelinek <jakub@redhat.com>
|
||||
|
||||
* malloc/arena.c (aligned_heap_area): New variable.
|
||||
(new_heap): If aligned_heap_area != NULL, attempt to use that
|
||||
first. If HEAP_MAX_SIZE << 1 area is already HEAP_MAX_SIZE bytes
|
||||
aligned, remember the second half in aligned_heap_area.
|
||||
(delete_heap): Clear aligned_heap_area if deleting the area right
|
||||
before aligned_heap_area.
|
||||
|
||||
2004-10-03 Juerg Billeter <j@bitron.ch>
|
||||
|
||||
* nscd/nscd_initgroups.c (__nscd_getgrouplist): Return -1 if nscd
|
||||
can't be used. [BZ #424]
|
||||
|
||||
2004-10-03 Ulrich Drepper <drepper@redhat.com>
|
||||
|
||||
Dynamically create new threads if necessary.
|
||||
* nscd/connections.c (fd_ready): If no thread available for processing
|
||||
the request, create a new one unless the limit is reached.
|
||||
(start_threads): Check errors from pthread_create.
|
||||
* nscd/nscd.h: Declare max_nthreads.
|
||||
* nscd/nscd_conf.c: Parse max-nthreads entry.
|
||||
* nscd/nscd.conf: Add max-threads entry.
|
||||
* nscd/nscd_stat.c: Print current and maximum number of threads.
|
||||
|
||||
Implement paranoia mode.
|
||||
* nscd/connections.c (nscd_init): Mark database and socket descriptors
|
||||
as close on exec.
|
||||
(restart): New function.
|
||||
(restart_p): New function.
|
||||
(nscd_run): Add missing descrement of nready in case readylist is
|
||||
empty.
|
||||
(main_loop_poll): Call restart_p and restart.
|
||||
(main_loop_epoll): Likewise.
|
||||
(begin_drop_privileges): Save original UID and GID.
|
||||
* nscd/nscd.c: Define new variables paranoia, restart_time,
|
||||
restart_interval, oldcwd, old_gid, old_uid.
|
||||
(main): Disable paranoia mode if we are not forking.
|
||||
(check_pid): When re-execing, the PID file contains the same PID as
|
||||
the current process. Do not fail in this case.
|
||||
* nscd/nscd.conf: Add paranoia and restart-interval entries.
|
||||
* nscd/nscd.h: Define RESTART_INTERVAL. Declare new variables.
|
||||
* nscd/nscd_conf.c: Parse paranoia and restart-internal configurations.
|
||||
* nscd/nscd_stat.c: Print paranoia and restart-internal values.
|
||||
|
||||
* nscd/connections.c: Implement alternative loop for main thread
|
||||
which uses epoll.
|
||||
* sysdeps/unix/sysv/linux/Makefile [subdir=nscd]
|
||||
(CFLAGS-connections.c): Add -DHAVE_EPOLL.
|
||||
|
||||
2004-10-02 Ulrich Drepper <drepper@redhat.com>
|
||||
|
||||
* nscd/Makefile (CFLAGS-initgrcache.c): Add to CFLAGS-* variables,
|
||||
don't replace old content.
|
||||
|
||||
* nscd/connections.c: Rewrite handling of incoming connections. All
|
||||
are handled by one thread which then hands off the descriptors for the
|
||||
real work to the worker threads.
|
||||
* nscd/Makefile: Link nscd with librt.
|
||||
|
||||
* nscd/selinux.c: Pretty printing.
|
||||
|
||||
* nscd/dbg_log.c (dbg_log): Don't add unnecessary newline to
|
||||
output. Let syslog do the formatting if debug_level == 0.
|
||||
|
||||
* nscd/nscd_helper.c (get_mapping): No need to check timestamp if
|
||||
nscd_certainly_running is nonzero.
|
||||
|
||||
2004-10-02 Simon Josefsson <jas@extundo.com>
|
||||
|
||||
[BZ #420]
|
||||
* sysdeps/generic/memmem.c [!_LIBC]: Define __builtin_expect, to
|
||||
make the file usable inside gnulib.
|
||||
|
||||
2004-10-01 Ulrich Drepper <drepper@redhat.com>
|
||||
|
||||
* malloc/malloc.c (public_vALLOc): Add missing use of hooks.
|
||||
(public_pVALLOc): Likewise.
|
||||
|
||||
* nscd/nscd_initgroups.c (__nscd_getgrouplist): Always add the
|
||||
group the caller provided unless there is a real problem.
|
||||
|
||||
* posix/bug-glob1.c (prepare): Fix creation of symlink.
|
||||
|
||||
2004-09-30 Ulrich Drepper <drepper@redhat.com>
|
||||
|
||||
* posix/Makefile: Add rules to build and run bug-glob1.
|
||||
* posix/bug-glob1.c: New file.
|
||||
|
||||
* iconv/iconv_prog.c (main): Print progress information to stderr.
|
||||
|
||||
* nscd/nscd.c (termination_handler): Reset timestamp so that
|
||||
clients immediately stop using the database.
|
||||
|
||||
* nscd/nscd-client.h (__nscd_get_map_ref): Drop volatile from last
|
||||
parameter.
|
||||
(__nscd_drop_map_ref): Change second parameter to be a reference to
|
||||
a variable. Update variable when cycle count changed.
|
||||
* nscd/nscd_helper.c (__nscd_get_map_ref): Remove volatile here, too.
|
||||
* nscd/nscd_getai.c: Correctly use __nscd_drop_map_ref. Reinitialize
|
||||
all variables and avoid memory leak in case of retries.
|
||||
* nscd/nscd_getgr_r.c: Likewise.
|
||||
* nscd/nscd_gethst_r.c: Likewise.
|
||||
* nscd/nscd_getpw_r.c: Likewise.
|
||||
* nscd/nscd_initgroups.c: Likewise.
|
||||
|
||||
* nscd/nscd.h: Add declaration of addinitgroups and
|
||||
readdinitgroups.
|
||||
|
||||
2004-09-30 Andreas Jaeger <aj@suse.de>
|
||||
|
||||
* nscd/Makefile (CFLAGS-nscd_initgroups.c): Set to -fpie.
|
||||
(CFLAGS-initgrcache.c): Set to -fexceptions.
|
||||
|
||||
2004-09-29 Ulrich Drepper <drepper@redhat.com>
|
||||
|
||||
* sysdeps/generic/glob.c (glob_in_dir): Don't blindly trust
|
||||
readdir results; for symlinks or files of unknown type check using
|
||||
stat whether the file exists.
|
||||
|
||||
* posix/tst-gnuglob.c (find_file): Handle leading "./". Fix
|
||||
recognition of files.
|
||||
|
||||
2004-09-29 Jakub Jelinek <jakub@redhat.com>
|
||||
|
||||
* time/tzfile.c (tzfile_mtime): New variable.
|
||||
(__tzfile_read): Reread the file if mtime is different.
|
||||
|
||||
2004-09-28 Jakub Jelinek <jakub@redhat.com>
|
||||
|
||||
* sysdeps/alpha/fpu/bits/mathinline.h (__fdimf, __fdim, fdimf, fdim):
|
||||
Handle +inf/+inf.
|
||||
* sysdeps/powerpc/fpu/bits/mathinline.h (fdim, fdimf): Likewise.
|
||||
* sysdeps/sparc/fpu/bits/mathinline.h (fdim, fdimf): Likewise.
|
||||
|
||||
2004-09-29 Ulrich Drepper <drepper@redhat.com>
|
||||
|
||||
* nscd/nscd_gethst_r.c (nscd_gethst_r): Use correct constant for
|
||||
testing result of __nscd_get_map_ref.
|
||||
|
||||
2004-09-29 Jakub Jelinek <jakub@redhat.com>
|
||||
|
||||
* sysdeps/i386/fpu/s_fdim.S (__fdim): Handle +inf/+inf.
|
||||
* sysdeps/i386/fpu/s_fdimf.S (__fdimf): Likewise.
|
||||
* sysdeps/i386/fpu/s_fdiml.S (__fdiml): Likewise.
|
||||
|
||||
004-09-29 Ulrich Drepper <drepper@redhat.com>
|
||||
|
||||
* grp/initgroups.c: Move compat_call implementation...
|
||||
* grp/compat-initgroups.c: ...to here. New file.
|
||||
* grp/Makefile (distribute): Add compat-initgroups.c.
|
||||
(CFLAGS-initgroups.c): Add -DUSE_NSCD=1.
|
||||
* mscd/initgrcache.c: New file.
|
||||
* nscd/nscd_initgroups.c: New file.
|
||||
* nscd/Makefile (routines): Add nscd_initgroups.
|
||||
(nscd-modules): Add initgrcache.
|
||||
* nscd/cache.c (prune_cache): Add support for INITGROUPS entries.
|
||||
* nscd/connections.c: Handle INITGROUPS requests.
|
||||
* nscd/nscd-client.h: Define INITGROUPS, initgr_response_header.
|
||||
Add initgrdata element to struct datahead. Fix typo in comment.
|
||||
* nscd/nscd_proto.h: Declare __nscd_getgrouplist. Fix parameter
|
||||
type in __nscd_getgrgrid_r.
|
||||
* nscd/selinux.c (perms): Add INITGROUPS entry.
|
||||
|
||||
* nscd/nscd_getai.c: No need to include <sys/mman.h>.
|
||||
|
||||
* sunrpc/get_myaddr.c (get_myaddress): Account for interfaces without
|
||||
assigned addresses.
|
||||
* sunrpc/pmap_clnt.c (__get_myaddress): Likewise.
|
||||
* sunrpc/pmap_rmt.c (getbroadcastnets): Likewise.
|
||||
* sunrpc/clnt_udp.c (is_network_up): Likewise.
|
||||
|
||||
* nscd/nscd.c: Define getaddrinfo hidden so that it is never found
|
||||
outside.
|
||||
|
||||
* sysdeps/unix/sysv/linux/ia64/bits/siginfo.h (si_segvflags):
|
||||
Renamed from si_flags due to conflict with si_flags from <elf.h>.
|
||||
|
||||
2004-09-28 Ulrich Drepper <drepper@redhat.com>
|
||||
|
||||
* nscd/nscd_getai.c: Use NO_MAPPING instead of MAP_FAILED for test
|
||||
of failing __nscd_get_map_ref. Fix a few typos.
|
||||
|
||||
* sysdeps/unix/sysv/linux/sigwait.c (do_sigwait): Make sure
|
||||
SIGSETXID is not blocked.
|
||||
* sysdeps/unix/sysv/linux/sigwaitinfo.c (do_sigwaitinfo): Likewise.
|
||||
* sysdeps/unix/sysv/linux/sigtimedwait.c (do_sigtimedwait): Likewise.
|
||||
* sysdeps/unix/sysv/linux/sigprocmask.c (__sigprocmask): Likewise.
|
||||
* sysdeps/generic/sigfillset.c (sigfillset): Don't set SIGSETXID.
|
||||
|
||||
* sunrpc/get_myaddr.c (get_myaddress): Fix test for failing
|
||||
getifaddrs call.
|
||||
* sunrpc/pmap_clnt.c (__get_myaddress): Likewise.
|
||||
* sunrpc/pmap_rmt.c (getbroadcastnets): Likewise.
|
||||
* sunrpc/Makefile (xtests): Add tst-getmyaddr.
|
||||
* sunrpc/tst-getmyaddr.c: New file.
|
||||
|
||||
* malloc/arena.c (ptmalloc_init): Allow MALLOC_CHECK_==0 to
|
||||
disable all checking.
|
||||
|
||||
* sysdeps/unix/sysv/linux/ia64/bits/siginfo.h (si_flags): Add
|
||||
support to get this value.
|
||||
|
||||
2004-09-28 Jakub Jelinek <jakub@redhat.com>
|
||||
|
||||
* io/utime.h (utime): Allow second argument to be NULL.
|
||||
|
||||
2004-09-28 Ulrich Drepper <drepper@redhat.com>
|
||||
|
||||
* sysdeps/posix/getaddrinfo.c (gaih_inet): If NAME is a numerical IP
|
||||
address and AI_CANONNAME is set, return copy of NAME as ai_canonname.
|
||||
|
||||
2004-09-27 Andreas Jaeger <aj@suse.de>
|
||||
|
||||
* sysdeps/i386/dl-machine.h (elf_machine_rela_relative): Replace
|
||||
static inline by auto inline, add always_inline attribute.
|
||||
(elf_machine_rel): Likewise.
|
||||
(elf_machine_rela): Likewise.
|
||||
(elf_machine_lazy_rel): Likewise.
|
||||
(elf_machine_lazy_rela): Likewise.
|
||||
(elf_machine_rel_relative): Likewise.
|
||||
|
||||
2004-09-27 Ulrich Drepper <drepper@redhat.com>
|
||||
|
||||
* sunrpc/xdr_intXX_t.c: Add xdr_quad_t and xdr_u_quad_t aliases.
|
||||
* sunrpc/rpc/xdr.h: Declare xdr_quad_t and xdr_u_quad_t.
|
||||
* sunrpc/rpc_parse.c (get_type): Use "quad_t" for TOK_HYPER.
|
||||
Otherwise isvectordef will loop infinitely if typedef hyper int64_t
|
||||
is seen.
|
||||
(unsigned_dec): Use "u_quad_t" for similar reasons.
|
||||
* sunrpc/Versions: Export xdr_quad_t and xdr_u_quad_t.
|
||||
|
||||
2004-09-27 Roland McGrath <roland@redhat.com>
|
||||
|
||||
* sysdeps/generic/bits/waitstatus.h (__WIFSIGNALED): Simplify bit
|
||||
twiddling in last change.
|
||||
|
||||
* posix/tst-waitid.c (do_test): Add tests for waitpid with WCONTINUED.
|
||||
|
||||
[BZ #409]
|
||||
* posix/sys/wait.h [__WIFCONTINUED] (WIFCONTINUED): New macro.
|
||||
* stdlib/stdlib.h [__WIFCONTINUED] (WIFCONTINUED): New macro.
|
||||
* sysdeps/generic/bits/waitstatus.h (__W_CONTINUED): New macro.
|
||||
[WCONTINUED] (__WIFCONTINUED): New macro.
|
||||
(__WIFSIGNALED): Rewritten to exclude __W_CONTINUED value, and have no
|
||||
branches.
|
||||
|
||||
* sysdeps/unix/sysv/linux/waitid.c (do_waitid): Add fifth argument to
|
||||
all three syscall uses, not just one!
|
||||
|
||||
2004-09-26 Richard Henderson <rth@redhat.com>
|
||||
|
||||
* sysdeps/alpha/alphaev6/memcpy.S: Mark .prologue.
|
||||
* sysdeps/unix/alpha/sysdep.h (LEAF, ENTRY): Align entry points
|
||||
to 16 byte boundaries.
|
||||
|
||||
2004-09-26 Ulrich Drepper <drepper@redhat.com>
|
||||
|
||||
* elf/readlib.c (process_file): Before complaining about too-short
|
||||
file, check that it potentially be an ELF file. Also complain about
|
||||
empty files. [BZ #151].
|
||||
|
||||
* scripts/test-installation.pl: Fix ld.so recognition for new
|
||||
LD_TRACE_LOADED_OBJECTS output format.
|
||||
Patch by <jsberg04+computing.glibc@ftml.net> [BZ #407].
|
||||
|
||||
* elf/dl-support.c (_dl_non_dynamic_init): Fix cleaning of
|
||||
environment. [BZ #384]
|
||||
|
||||
* sunrpc/clnt_udp.c (is_network_up): Use getifaddrs instead of ioctl.
|
||||
* sunrpc/get_myaddr.c (get_myaddress): Likewise.
|
||||
* sunrpc/pmap_clnt.c (__get_myaddress): Likewise.
|
||||
* sunrpc/pmap_rmt.c (getbroadcastnets): Likewise. Change interface
|
||||
to avoid buffer overrun and remove now useless parameters.
|
||||
(clnt_broadcast): Adjust caller. [BZ #381].
|
||||
|
||||
* sysdeps/generic/s_fdim.c: Handle +inf/+inf
|
||||
* sysdeps/generic/s_fdimf.c: Likewise.
|
||||
* sysdeps/generic/s_fdiml.c: Likewise.
|
||||
* sysdeps/i386/i686/fpu/s_fdim.S: Likewise.
|
||||
* sysdeps/i386/i686/fpu/s_fdimf.S: Likewise.
|
||||
* sysdeps/i386/i686/fpu/s_fdiml.S: Likewise.
|
||||
* sysdeps/powerpc/fpu/s_fdim.c: Likewise.
|
||||
* sysdeps/powerpc/fpu/s_fdimf.c: Likewise.
|
||||
* sysdeps/x86_64/fpu/s_fdiml.S: Likewise.
|
||||
* math/libm-test.inc (fdim_test): Add test case. [BZ #376].
|
||||
|
||||
* sysdeps/generic/bits/types.h: Fix __SQUAD_TYPE and __UQUAD_TYPE
|
||||
for compilers without __GLIBC_HAVE_LONG_LONG. [BZ #362]
|
||||
|
||||
* sysdeps/posix/getaddrinfo.c (getaddrinfo): Remove incorrect
|
||||
requirement on socktype and protocol.
|
||||
(gaih_inet): If numeric port number is given, return records for all
|
||||
possible socket types.
|
||||
* posix/tst-getaddrinfo2.c: New file.
|
||||
* posix/Makefile (tests): Add tst-getaddrinfo2. [BZ #358]
|
||||
|
||||
2004-09-25 Ulrich Drepper <drepper@redhat.com>
|
||||
|
||||
* locale/loadlocale.c (_nl_intern_locale_data): Recognize LC_CTYPE
|
||||
data where _nl_value_type_LC_CTYPE does not contain the type
|
||||
information. Add range checks.
|
||||
Reported by John Lumby <johnlumby@hotmail.com> [BZ #356].
|
||||
|
||||
* libio/vasprintf.c (_IO_vasprintf): Fix condition to decide
|
||||
whether to realloc or not.
|
||||
Reported by Pavel Kankovsky <peak@argo.troja.mff.cuni.cz> [BZ #346].
|
||||
|
||||
* intl/dcigettext.c (DCIGETTEXT): Protect tfind/tsearch calls.
|
||||
* intl/dcigettext.c (_nl_find_msg): Call _nl_load_domain also if
|
||||
decided < 0.
|
||||
* intl/finddomain.c (_nl_find_domain): Likewise.
|
||||
* intl/loadmsgcat.c (_nl_load_domain): Set decided to 1 only once we
|
||||
are done. First set to -1 to signal initialization is ongoing.
|
||||
Protect against concurrent callers with recursive lock.
|
||||
* intl/finddomain.c (_nl_find_domain): Protect calls to
|
||||
_nl_make_l10nflist. [BZ #322]
|
||||
|
||||
* sysdeps/posix/getaddrinfo.c (getaddrinfo): If determinination of
|
||||
source address fails, initialized source_addr_len field so that
|
||||
duplicate address recognition does not copy junk.
|
||||
|
||||
2004-09-25 Jakub Jelinek <jakub@redhat.com>
|
||||
|
||||
* sysdeps/unix/sysv/linux/i386/setuid.c (__setuid): Remove second
|
||||
result declaration.
|
||||
|
||||
2004-09-22 Andreas Schwab <schwab@suse.de>
|
||||
|
||||
* sysdeps/unix/sysv/linux/ia64/sysdep.h: Adjust whitespace.
|
||||
|
||||
2004-09-24 Ulrich Drepper <drepper@redhat.com>
|
||||
|
||||
* misc/daemon.c (daemon): Don't succeed if /dev/null cannot be
|
||||
opened.
|
||||
|
||||
* nis/ypclnt.c (do_ypcall): Add one missing unlock. Simplify the
|
||||
code a bit.
|
||||
|
||||
* misc/daemon.c (daemon): Define errno in case /dev/null is not
|
||||
the correct device.
|
||||
|
||||
* nis/ypclnt.c (yp_bind_file): Optimize a bit. Minimal cleanups.
|
||||
|
||||
2004-09-23 Andreas Jaeger <aj@suse.de>
|
||||
|
||||
* locale/weight.h (findidx): Remove static, it's not supported
|
||||
anymore with GCC 4.0 in a block scope.
|
||||
* locale/weightwc.h (findidx): Likewise.
|
||||
* posix/regcomp.c (seek_collating_symbol_entry): Likewise.
|
||||
(lookup_collation_sequence_value): Likewise.
|
||||
(build_range_exp): Likewise.
|
||||
(build_collating_symbol): Likewise.
|
||||
* iconv/iconvconfig.c (write_output): Likewise.
|
||||
* elf/do-rel.h (elf_dynamic_do_rel): Likewise.
|
||||
|
||||
* sysdeps/x86_64/dl-machine.h (elf_machine_rela_relative): Remove
|
||||
static, add always_inline attribute.
|
||||
(elf_machine_rela): Likewise.
|
||||
(elf_machine_lazy_rel): Likewise.
|
||||
|
||||
* elf/dynamic-link.h (elf_get_dynamic_info): Make static dependend
|
||||
on !RESOLVE so that it's not defined in local scope.
|
||||
|
||||
2004-09-23 Kaz Kojima <kkojima@rr.iij4u.or.jp>
|
||||
|
||||
* sysdeps/unix/sysv/linux/sh/sysdep.h (INTERNAL_SYSCALL_NCS): Define.
|
||||
|
||||
2004-09-23 Thorsten Kukuk <kukuk@suse.de>
|
||||
|
||||
* sysdeps/unix/sysv/linux/sys/mount.h: Sync MS_RMT_MASK flag
|
||||
and BLK* ioctls with linux kernel headers.
|
||||
|
||||
2004-09-23 Ulrich Drepper <drepper@redhat.com>
|
||||
|
||||
* sysdeps/generic/bits/dlfcn.h: Add RTLD_DEEPBIND.
|
||||
* elf/dl-object.c (_dl_new_object): Add new parameter mode. If mode
|
||||
has RTLD_DEEPBIND set add local searchlist before global scope.
|
||||
* sysdeps/generic/ldsodefs.h (_dl_new_object): Adjust prototype.
|
||||
* elf/rtld.c: Adjust callers of _dl_new_object.
|
||||
* elf/dl-load.c: Likewise.
|
||||
(_dl_map_object_from_fd): If RTLD_DEEPBIND is used, don't do anything
|
||||
for DF_SYMBOLIC.
|
||||
* elf/dl-open.c (dl_open_writer): Pass RTLD_DEEPBIND flag on to
|
||||
_dl_map_object_deps.
|
||||
* elf/tst-deep1.c: New file.
|
||||
* elf/tst-deep1mod1.c: New file.
|
||||
* elf/tst-deep1mod2.c: New file.
|
||||
* elf/tst-deep1mod3.c: New file.
|
||||
* elf/Makefile: Add rules to build and run new tests.
|
||||
|
||||
* elf/dl-deps.c: Pretty printing.
|
||||
|
||||
2004-09-23 Jakub Jelinek <jakub@redhat.com>
|
||||
|
||||
* sysdeps/unix/alpha/sysdep.h (inline_syscall[0-6]): Change name
|
||||
argument to numbers from syscall names.
|
||||
(INLINE_SYSCALL1): Pass __NR_##name to inline_syscall##nr.
|
||||
(INTERNAL_SYSCALL_NCS): Renamed from...
|
||||
(INTERNAL_SYSCALL_1): ... this. Use INTERNAL_SYSCALL_NCS.
|
||||
* sysdeps/unix/sysv/linux/s390/s390-32/sysdep.h
|
||||
(INTERNAL_SYSCALL_NCS): Define.
|
||||
* sysdeps/unix/sysv/linux/s390/s390-64/sysdep.h
|
||||
(INTERNAL_SYSCALL_NCS): Likewise.
|
||||
* sysdeps/unix/sysv/linux/sparc/sysdep.h (inline_syscall[0-6]):
|
||||
Change name argument to numbers from syscall names.
|
||||
(INLINE_SYSCALL, INTERNAL_SYSCALL): Adjust.
|
||||
(INTERNAL_SYSCALL_NCS): Define.
|
||||
|
||||
2004-09-22 Ulrich Drepper <drepper@redhat.com>
|
||||
|
||||
* malloc/malloc.c (malloc_printerr): Use syslog if writev failed.
|
||||
|
||||
* string/string.h: Add __nonnull annotations.
|
||||
* stdlib/stdlib.h: Likewise.
|
||||
|
||||
2004-09-20 Jakub Jelinek <jakub@redhat.com>
|
||||
|
||||
* sysdeps/unix/alpha/sysdep.h (inline_syscall[0-6]): Change name
|
||||
argument to numbers from syscall names.
|
||||
(INLINE_SYSCALL1): Pass __NR_##name to inline_syscall##nr.
|
||||
(INTERNAL_SYSCALL_NCS): Renamed from...
|
||||
(INTERNAL_SYSCALL_1): ... this. Use INTERNAL_SYSCALL_NCS.
|
||||
* sysdeps/unix/sysv/linux/s390/s390-32/sysdep.h
|
||||
(INTERNAL_SYSCALL_NCS): Define.
|
||||
* sysdeps/unix/sysv/linux/s390/s390-64/sysdep.h
|
||||
(INTERNAL_SYSCALL_NCS): Likewise.
|
||||
* sysdeps/unix/sysv/linux/sparc/sysdep.h (inline_syscall[0-6]):
|
||||
Change name argument to numbers from syscall names.
|
||||
(INLINE_SYSCALL, INTERNAL_SYSCALL): Adjust.
|
||||
(INTERNAL_SYSCALL_NCS): Define.
|
||||
|
||||
2004-09-20 H.J. Lu <hongjiu.lu@intel.com>
|
||||
|
||||
* sysdeps/unix/sysv/linux/ia64/sysdep.h (DO_INLINE_SYSCALL):
|
||||
@@ -727,6 +1434,23 @@
|
||||
before return type.
|
||||
* locale/localename.c (__current_locale_name): Likewise.
|
||||
|
||||
2004-08-31 Jakub Jelinek <jakub@redhat.com>
|
||||
|
||||
* elf/ldconfig.c (parse_conf): Add prefix argument, prepend it
|
||||
before arguments to add_dir and pass to parse_conf_include.
|
||||
(parse_conf_include): Add prefix argument, pass it down to
|
||||
parse_conf.
|
||||
(main): Call arch_startup. Adjust parse_conf caller.
|
||||
Call add_arch_dirs.
|
||||
* sysdeps/generic/dl-cache.h (arch_startup, add_arch_dirs): Define.
|
||||
* sysdeps/unix/sysv/linux/i386/dl-cache.h: New file.
|
||||
* sysdeps/unix/sysv/linux/ia64/dl-cache.h (EMUL_HACK, arch_startup,
|
||||
add_arch_dirs): Define.
|
||||
* sysdeps/unix/sysv/linux/ia64/ldd-rewrite.sed: Prepend
|
||||
/emul/ia32-linux before the 32-bit ld.so pathname.
|
||||
* sysdeps/unix/sysv/linux/ia64/dl-procinfo.c: New file.
|
||||
* sysdeps/unix/sysv/linux/ia64/dl-procinfo.h: New file.
|
||||
|
||||
2004-08-30 Roland McGrath <roland@frob.com>
|
||||
|
||||
* scripts/extract-abilist.awk: If `lastversion' variable defined, omit
|
||||
@@ -883,6 +1607,22 @@
|
||||
* resolv/nss_dns/dns-canon.c (_nss_dns_getcanonname_r): Initialize
|
||||
status to NSS_STATUS_UNAVAIL.
|
||||
|
||||
2004-08-19 Jakub Jelinek <jakub@redhat.com>
|
||||
|
||||
* sysdeps/powerpc/powerpc64/configure.in: New file.
|
||||
* sysdeps/powerpc/powerpc64/configure: Rebuilt.
|
||||
* config.h.in (USE_PPC64_OVERLAPPING_OPD): Add.
|
||||
* configure.in (HAVE_ASM_GLOBAL_DOT_NAME): Remove.
|
||||
* configure: Rebuilt.
|
||||
* sysdeps/powerpc/powerpc64/sysdep.h: Formatting.
|
||||
(OPD_ENT, BODY_LABEL, ENTRY_1, ENTRY_2, END_2, DOT_PREFIX,
|
||||
BODY_PREFIX): Define.
|
||||
(ENTRY, DOT_LABEL, END, TRACEBACK, END_GEN_TB, EALIGN): Support
|
||||
HAVE_ASM_GLOBAL_DOT_NAME or no dot symbols,
|
||||
USE_PPC64_OVERLAPPING_OPD or never overlapping .opd entries.
|
||||
* sysdeps/powerpc/powerpc64/dl-machine.h: Include sysdep.h.
|
||||
(TRAMPOLINE_TEMPLATE, RTLD_START): Use the new sysdep.h macros.
|
||||
|
||||
2004-08-19 Ulrich Drepper <drepper@redhat.com>
|
||||
|
||||
* sysdeps/posix/getaddrinfo.c (gaih_inet): Use h->h_name in the
|
||||
@@ -1187,6 +1927,12 @@
|
||||
|
||||
* iconvdata/testdata/ISO-2022-JP-3: Regenerated.
|
||||
|
||||
2004-07-23 Jakub Jelinek <jakub@redhat.com>
|
||||
|
||||
[BZ #284]
|
||||
* include/features.h (_POSIX_SOURCE, _POSIX_C_SOURCE): Define
|
||||
if _XOPEN_SOURCE >= 500 even if __STRICT_ANSI__ is defined.
|
||||
|
||||
2004-08-10 Alfred M. Szmidt <ams@kemisten.nu>
|
||||
|
||||
* sysdeps/generic/bits/in.h (struct ip_mreq): Remove definition.
|
||||
|
||||
@@ -1352,6 +1352,11 @@
|
||||
* sysdeps/unix/sysv/linux/mips/sys/tas.h: Add missing .mips0 at the
|
||||
end of inline assembler code.
|
||||
|
||||
2000-10-02 Jakub Jelinek <jakub@redhat.com>
|
||||
|
||||
* sunrpc/svc_udp.c (svcudp_recv): Set msg_controllen to all
|
||||
remaining xp_pad space.
|
||||
|
||||
2000-10-02 Ulrich Drepper <drepper@redhat.com>
|
||||
|
||||
* include/features.h [__USE_FILE_OFFSET && !__REDIRECT]: Define
|
||||
@@ -9280,6 +9285,12 @@
|
||||
syscall.
|
||||
* sysdeps/unix/sysv/linux/mips/truncate64.c: Likewise.
|
||||
|
||||
2000-05-30 Jakub Jelinek <jakub@redhat.com>
|
||||
|
||||
* resolv/res_query.c (res_nsearch): Remove unused variable
|
||||
root_on_list. If dots >= statp->ndots and as is querydomain
|
||||
fails, keep searching.
|
||||
|
||||
2000-05-30 Ulrich Drepper <drepper@redhat.com>
|
||||
|
||||
* sysdeps/unix/sysv/linux/alpha/oldglob.c (__old_glob): Loose __P.
|
||||
@@ -9480,6 +9491,11 @@
|
||||
* sysdeps/i386/fpu/bits/mathinline.h: Define expm1 inline only if
|
||||
__FAST_MATH__ is defined.
|
||||
|
||||
2000-05-22 Jakub Jelinek <jakub@redhat.com>
|
||||
|
||||
* sysdeps/i386/fpu/bits/mathinline.h (__expm1_code): Avoid using ?:
|
||||
with omitted middle operand.
|
||||
|
||||
2000-05-22 Andreas Jaeger <aj@suse.de>
|
||||
|
||||
* math/Makefile: Add -D__FAST_MATH__ to CFLAGS-test-ifloat.c,
|
||||
@@ -9718,6 +9734,11 @@
|
||||
* manual/arith.texi (Parsing of Integers): Fix typo.
|
||||
Closes PR libc/1744, reported by blp@gnu.org.
|
||||
|
||||
2000-05-17 Jakub Jelinek <jakub@redhat.com>
|
||||
|
||||
* inet/rcmd.c (rcmd_af): If *ahost cannot be resolved, include
|
||||
unresolved hostname in the message.
|
||||
|
||||
2000-05-17 Jakub Jelinek <jakub@redhat.com>
|
||||
|
||||
* sysdeps/arm/bits/huge_val.h (HUGE_VAL, HUGE_VALF): Add
|
||||
|
||||
@@ -7729,6 +7729,13 @@
|
||||
|
||||
* Versions.def [ld]: Add GLIBC_2.2.1.
|
||||
|
||||
2001-01-10 Jakub Jelinek <jakub@redhat.com>
|
||||
|
||||
* malloc/memusage.c (me): If not SUID/SGID, allow creating new
|
||||
$MEMUSAGE_OUTPUT file.
|
||||
* sysdeps/generic/segfault.c (segfault.c): If not SUID/SGID, allow
|
||||
creating new $SEGFAULT_OUTPUT_NAME file.
|
||||
|
||||
2001-01-10 H.J. Lu <hjl@gnu.org>
|
||||
|
||||
* elf/dl-libc.c (do_dlopen): Call DL_STATIC_INIT for static binaries.
|
||||
@@ -8130,6 +8137,11 @@
|
||||
* sysdeps/powerpc/soft-fp/Versions: Likewise.
|
||||
* sysdeps/sparc/sparc64/soft-fp/Versions: Likewise.
|
||||
|
||||
2001-01-02 Jakub Jelinek <jakub@redhat.com>
|
||||
|
||||
* locale/setlocale.c (setlocale): Don't allocate/free category name
|
||||
unnecessarily.
|
||||
|
||||
2001-01-02 Franz Sirl <Franz.Sirl-kernel@lauterbach.com>
|
||||
|
||||
* sysdeps/powerpc/dl-machine.c (__process_machine_rela): Fix typo.
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
Open jobs for finishing GNU libc:
|
||||
---------------------------------
|
||||
Status: September 2002
|
||||
Status: October 2004
|
||||
|
||||
If you have time and talent to take over any of the jobs below please
|
||||
contact <bug-glibc@gnu.org>.
|
||||
@@ -53,7 +53,7 @@ contact <bug-glibc@gnu.org>.
|
||||
|
||||
|
||||
[11] Write access function for netmasks, bootparams, and automount
|
||||
databases for nss_files and nss_db module.
|
||||
databases for nss_files, nss_nis, and nss_nisplus modules.
|
||||
The functions should be embedded in the nss scheme. This is not
|
||||
hard and not all services must be supported at once.
|
||||
|
||||
@@ -76,7 +76,7 @@ contact <bug-glibc@gnu.org>.
|
||||
[18] Based on the sprof program we need tools to analyze the output. The
|
||||
result should be a link map which specifies in which order the .o
|
||||
files are placed in the shared object. This should help to improve
|
||||
code locality and result in a smaller foorprint (in code and data
|
||||
code locality and result in a smaller footprint (in code and data
|
||||
memory) since less pages are only used in small parts.
|
||||
|
||||
|
||||
@@ -93,29 +93,6 @@ contact <bug-glibc@gnu.org>.
|
||||
available.
|
||||
|
||||
|
||||
[21] The nscd program and the stubs in the libc should be changed so
|
||||
that each program uses only one socket connect. Take a look at
|
||||
http://people.redhat.com/drepper/nscd.html
|
||||
|
||||
An alternative approach is to use an mmap()ed file. The idea is
|
||||
the following:
|
||||
- the nscd creates the hash tables and the information it stores
|
||||
in it in a mmap()ed region. This means no pointers must be
|
||||
used, only offsets.
|
||||
OR
|
||||
if POSIX shared memory is available use a named shared memory
|
||||
region to put the data in
|
||||
- each program using NSS functionality tries to open the file
|
||||
with the data.
|
||||
- by checking some timestamp (which the nscd renews frequently)
|
||||
the programs can test whether the file is still valid
|
||||
- if the file is valid look through the nscd and locate the
|
||||
appropriate hash table for the database and lookup the data.
|
||||
If it is included we are set.
|
||||
- if the data is not yet in the database we contact the nscd using
|
||||
the currently implemented methods.
|
||||
|
||||
|
||||
[23] The `strptime' function needs to be completed. This includes among
|
||||
other things that it must get teached about timezones. The solution
|
||||
envisioned is to extract the timezones from the ADO timezone
|
||||
@@ -127,18 +104,4 @@ contact <bug-glibc@gnu.org>.
|
||||
Australia/Canberra or if the current locale is en_AU.
|
||||
|
||||
|
||||
[25] Sun's nscd version implements a feature where the nscd keeps N entries
|
||||
for each database current. I.e., if an entries lifespan is over and
|
||||
it is one of the N entries to be kept the nscd updates the information
|
||||
instead of removing the entry.
|
||||
|
||||
How to decide about which N entries to keep has to be examined.
|
||||
Factors should be number of uses (of course), influenced by aging.
|
||||
Just imagine a computer used by several people. The IDs of the current
|
||||
user should be preferred even if the last user spent more time.
|
||||
|
||||
|
||||
[27] We need a second test suite with tests which cannot run during a normal
|
||||
`make check' run. This test suite can require root priviledges and
|
||||
can test things like DNS (i.e., require network access),
|
||||
user-interaction, networking in general, and probably many other things.
|
||||
[27] ...deleted...
|
||||
|
||||
+3
-20
@@ -1,4 +1,4 @@
|
||||
/* Copyright (C) 1991,1992,1994-2001,2003 Free Software Foundation, Inc.
|
||||
/* Copyright (C) 1991,1992,1994-2001,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
|
||||
@@ -84,33 +84,16 @@ extern void __assert (const char *__assertion, const char *__file, int __line)
|
||||
|
||||
__END_DECLS
|
||||
|
||||
/* For the macro definition we use gcc's __builtin_expect if possible
|
||||
to generate good code for the non-error case. gcc 3.0 is a good
|
||||
enough estimate for when the feature became available. */
|
||||
# if __GNUC_PREREQ (3, 0)
|
||||
# define assert(expr) \
|
||||
(__ASSERT_VOID_CAST (__builtin_expect (!!(expr), 1) ? 0 : \
|
||||
(__assert_fail (__STRING(expr), __FILE__, __LINE__, \
|
||||
__ASSERT_FUNCTION), 0)))
|
||||
# else
|
||||
# define assert(expr) \
|
||||
# define assert(expr) \
|
||||
(__ASSERT_VOID_CAST ((expr) ? 0 : \
|
||||
(__assert_fail (__STRING(expr), __FILE__, __LINE__, \
|
||||
__ASSERT_FUNCTION), 0)))
|
||||
# endif
|
||||
|
||||
# ifdef __USE_GNU
|
||||
# if __GNUC_PREREQ (3, 0)
|
||||
# define assert_perror(errnum) \
|
||||
(__ASSERT_VOID_CAST (__builtin_expect (!(errnum), 1) ? 0 : \
|
||||
(__assert_perror_fail ((errnum), __FILE__, __LINE__, \
|
||||
__ASSERT_FUNCTION), 0)))
|
||||
# else
|
||||
# define assert_perror(errnum) \
|
||||
# define assert_perror(errnum) \
|
||||
(__ASSERT_VOID_CAST (!(errnum) ? 0 : \
|
||||
(__assert_perror_fail ((errnum), __FILE__, __LINE__, \
|
||||
__ASSERT_FUNCTION), 0)))
|
||||
# endif
|
||||
# endif
|
||||
|
||||
/* Version 2.4 and later of GCC define a magical variable `__PRETTY_FUNCTION__'
|
||||
|
||||
@@ -1,84 +0,0 @@
|
||||
/* Macros to swap the order of bytes in integer values.
|
||||
Copyright (C) 1997, 1998, 2000, 2001, 2002 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. */
|
||||
|
||||
#if !defined _BYTESWAP_H && !defined _NETINET_IN_H
|
||||
# error "Never use <bits/byteswap.h> directly; include <byteswap.h> instead."
|
||||
#endif
|
||||
|
||||
#ifndef _BITS_BYTESWAP_H
|
||||
#define _BITS_BYTESWAP_H 1
|
||||
|
||||
/* Swap bytes in 16 bit value. */
|
||||
#ifdef __GNUC__
|
||||
# define __bswap_16(x) \
|
||||
(__extension__ \
|
||||
({ unsigned short int __bsx = (x); \
|
||||
((((__bsx) >> 8) & 0xff) | (((__bsx) & 0xff) << 8)); }))
|
||||
#else
|
||||
static __inline unsigned short int
|
||||
__bswap_16 (unsigned short int __bsx)
|
||||
{
|
||||
return ((((__bsx) >> 8) & 0xff) | (((__bsx) & 0xff) << 8));
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Swap bytes in 32 bit value. */
|
||||
#ifdef __GNUC__
|
||||
# define __bswap_32(x) \
|
||||
(__extension__ \
|
||||
({ unsigned int __bsx = (x); \
|
||||
((((__bsx) & 0xff000000) >> 24) | (((__bsx) & 0x00ff0000) >> 8) | \
|
||||
(((__bsx) & 0x0000ff00) << 8) | (((__bsx) & 0x000000ff) << 24)); }))
|
||||
#else
|
||||
static __inline unsigned int
|
||||
__bswap_32 (unsigned int __bsx)
|
||||
{
|
||||
return ((((__bsx) & 0xff000000) >> 24) | (((__bsx) & 0x00ff0000) >> 8) |
|
||||
(((__bsx) & 0x0000ff00) << 8) | (((__bsx) & 0x000000ff) << 24));
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined __GNUC__ && __GNUC__ >= 2
|
||||
/* Swap bytes in 64 bit value. */
|
||||
# define __bswap_constant_64(x) \
|
||||
((((x) & 0xff00000000000000ull) >> 56) \
|
||||
| (((x) & 0x00ff000000000000ull) >> 40) \
|
||||
| (((x) & 0x0000ff0000000000ull) >> 24) \
|
||||
| (((x) & 0x000000ff00000000ull) >> 8) \
|
||||
| (((x) & 0x00000000ff000000ull) << 8) \
|
||||
| (((x) & 0x0000000000ff0000ull) << 24) \
|
||||
| (((x) & 0x000000000000ff00ull) << 40) \
|
||||
| (((x) & 0x00000000000000ffull) << 56))
|
||||
|
||||
# define __bswap_64(x) \
|
||||
(__extension__ \
|
||||
({ union { __extension__ unsigned long long int __ll; \
|
||||
unsigned int __l[2]; } __w, __r; \
|
||||
if (__builtin_constant_p (x)) \
|
||||
__r.__ll = __bswap_constant_64 (x); \
|
||||
else \
|
||||
{ \
|
||||
__w.__ll = (x); \
|
||||
__r.__l[0] = __bswap_32 (__w.__l[1]); \
|
||||
__r.__l[1] = __bswap_32 (__w.__l[0]); \
|
||||
} \
|
||||
__r.__ll; }))
|
||||
#endif
|
||||
|
||||
#endif /* _BITS_BYTESWAP_H */
|
||||
-596
@@ -1,596 +0,0 @@
|
||||
/* `sysconf', `pathconf', and `confstr' NAME values. Generic version.
|
||||
Copyright (C) 1993,1995-1998,2000,2001,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
|
||||
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. */
|
||||
|
||||
#ifndef _UNISTD_H
|
||||
# error "Never use <bits/confname.h> directly; include <unistd.h> instead."
|
||||
#endif
|
||||
|
||||
/* Values for the NAME argument to `pathconf' and `fpathconf'. */
|
||||
enum
|
||||
{
|
||||
_PC_LINK_MAX,
|
||||
#define _PC_LINK_MAX _PC_LINK_MAX
|
||||
_PC_MAX_CANON,
|
||||
#define _PC_MAX_CANON _PC_MAX_CANON
|
||||
_PC_MAX_INPUT,
|
||||
#define _PC_MAX_INPUT _PC_MAX_INPUT
|
||||
_PC_NAME_MAX,
|
||||
#define _PC_NAME_MAX _PC_NAME_MAX
|
||||
_PC_PATH_MAX,
|
||||
#define _PC_PATH_MAX _PC_PATH_MAX
|
||||
_PC_PIPE_BUF,
|
||||
#define _PC_PIPE_BUF _PC_PIPE_BUF
|
||||
_PC_CHOWN_RESTRICTED,
|
||||
#define _PC_CHOWN_RESTRICTED _PC_CHOWN_RESTRICTED
|
||||
_PC_NO_TRUNC,
|
||||
#define _PC_NO_TRUNC _PC_NO_TRUNC
|
||||
_PC_VDISABLE,
|
||||
#define _PC_VDISABLE _PC_VDISABLE
|
||||
_PC_SYNC_IO,
|
||||
#define _PC_SYNC_IO _PC_SYNC_IO
|
||||
_PC_ASYNC_IO,
|
||||
#define _PC_ASYNC_IO _PC_ASYNC_IO
|
||||
_PC_PRIO_IO,
|
||||
#define _PC_PRIO_IO _PC_PRIO_IO
|
||||
_PC_SOCK_MAXBUF,
|
||||
#define _PC_SOCK_MAXBUF _PC_SOCK_MAXBUF
|
||||
_PC_FILESIZEBITS,
|
||||
#define _PC_FILESIZEBITS _PC_FILESIZEBITS
|
||||
_PC_REC_INCR_XFER_SIZE,
|
||||
#define _PC_REC_INCR_XFER_SIZE _PC_REC_INCR_XFER_SIZE
|
||||
_PC_REC_MAX_XFER_SIZE,
|
||||
#define _PC_REC_MAX_XFER_SIZE _PC_REC_MAX_XFER_SIZE
|
||||
_PC_REC_MIN_XFER_SIZE,
|
||||
#define _PC_REC_MIN_XFER_SIZE _PC_REC_MIN_XFER_SIZE
|
||||
_PC_REC_XFER_ALIGN,
|
||||
#define _PC_REC_XFER_ALIGN _PC_REC_XFER_ALIGN
|
||||
_PC_ALLOC_SIZE_MIN,
|
||||
#define _PC_ALLOC_SIZE_MIN _PC_ALLOC_SIZE_MIN
|
||||
_PC_SYMLINK_MAX,
|
||||
#define _PC_SYMLINK_MAX _PC_SYMLINK_MAX
|
||||
_PC_2_SYMLINKS
|
||||
#define _PC_2_SYMLINKS _PC_2_SYMLINKS
|
||||
};
|
||||
|
||||
/* Values for the argument to `sysconf'. */
|
||||
enum
|
||||
{
|
||||
_SC_ARG_MAX,
|
||||
#define _SC_ARG_MAX _SC_ARG_MAX
|
||||
_SC_CHILD_MAX,
|
||||
#define _SC_CHILD_MAX _SC_CHILD_MAX
|
||||
_SC_CLK_TCK,
|
||||
#define _SC_CLK_TCK _SC_CLK_TCK
|
||||
_SC_NGROUPS_MAX,
|
||||
#define _SC_NGROUPS_MAX _SC_NGROUPS_MAX
|
||||
_SC_OPEN_MAX,
|
||||
#define _SC_OPEN_MAX _SC_OPEN_MAX
|
||||
_SC_STREAM_MAX,
|
||||
#define _SC_STREAM_MAX _SC_STREAM_MAX
|
||||
_SC_TZNAME_MAX,
|
||||
#define _SC_TZNAME_MAX _SC_TZNAME_MAX
|
||||
_SC_JOB_CONTROL,
|
||||
#define _SC_JOB_CONTROL _SC_JOB_CONTROL
|
||||
_SC_SAVED_IDS,
|
||||
#define _SC_SAVED_IDS _SC_SAVED_IDS
|
||||
_SC_REALTIME_SIGNALS,
|
||||
#define _SC_REALTIME_SIGNALS _SC_REALTIME_SIGNALS
|
||||
_SC_PRIORITY_SCHEDULING,
|
||||
#define _SC_PRIORITY_SCHEDULING _SC_PRIORITY_SCHEDULING
|
||||
_SC_TIMERS,
|
||||
#define _SC_TIMERS _SC_TIMERS
|
||||
_SC_ASYNCHRONOUS_IO,
|
||||
#define _SC_ASYNCHRONOUS_IO _SC_ASYNCHRONOUS_IO
|
||||
_SC_PRIORITIZED_IO,
|
||||
#define _SC_PRIORITIZED_IO _SC_PRIORITIZED_IO
|
||||
_SC_SYNCHRONIZED_IO,
|
||||
#define _SC_SYNCHRONIZED_IO _SC_SYNCHRONIZED_IO
|
||||
_SC_FSYNC,
|
||||
#define _SC_FSYNC _SC_FSYNC
|
||||
_SC_MAPPED_FILES,
|
||||
#define _SC_MAPPED_FILES _SC_MAPPED_FILES
|
||||
_SC_MEMLOCK,
|
||||
#define _SC_MEMLOCK _SC_MEMLOCK
|
||||
_SC_MEMLOCK_RANGE,
|
||||
#define _SC_MEMLOCK_RANGE _SC_MEMLOCK_RANGE
|
||||
_SC_MEMORY_PROTECTION,
|
||||
#define _SC_MEMORY_PROTECTION _SC_MEMORY_PROTECTION
|
||||
_SC_MESSAGE_PASSING,
|
||||
#define _SC_MESSAGE_PASSING _SC_MESSAGE_PASSING
|
||||
_SC_SEMAPHORES,
|
||||
#define _SC_SEMAPHORES _SC_SEMAPHORES
|
||||
_SC_SHARED_MEMORY_OBJECTS,
|
||||
#define _SC_SHARED_MEMORY_OBJECTS _SC_SHARED_MEMORY_OBJECTS
|
||||
_SC_AIO_LISTIO_MAX,
|
||||
#define _SC_AIO_LISTIO_MAX _SC_AIO_LISTIO_MAX
|
||||
_SC_AIO_MAX,
|
||||
#define _SC_AIO_MAX _SC_AIO_MAX
|
||||
_SC_AIO_PRIO_DELTA_MAX,
|
||||
#define _SC_AIO_PRIO_DELTA_MAX _SC_AIO_PRIO_DELTA_MAX
|
||||
_SC_DELAYTIMER_MAX,
|
||||
#define _SC_DELAYTIMER_MAX _SC_DELAYTIMER_MAX
|
||||
_SC_MQ_OPEN_MAX,
|
||||
#define _SC_MQ_OPEN_MAX _SC_MQ_OPEN_MAX
|
||||
_SC_MQ_PRIO_MAX,
|
||||
#define _SC_MQ_PRIO_MAX _SC_MQ_PRIO_MAX
|
||||
_SC_VERSION,
|
||||
#define _SC_VERSION _SC_VERSION
|
||||
_SC_PAGESIZE,
|
||||
#define _SC_PAGESIZE _SC_PAGESIZE
|
||||
#define _SC_PAGE_SIZE _SC_PAGESIZE
|
||||
_SC_RTSIG_MAX,
|
||||
#define _SC_RTSIG_MAX _SC_RTSIG_MAX
|
||||
_SC_SEM_NSEMS_MAX,
|
||||
#define _SC_SEM_NSEMS_MAX _SC_SEM_NSEMS_MAX
|
||||
_SC_SEM_VALUE_MAX,
|
||||
#define _SC_SEM_VALUE_MAX _SC_SEM_VALUE_MAX
|
||||
_SC_SIGQUEUE_MAX,
|
||||
#define _SC_SIGQUEUE_MAX _SC_SIGQUEUE_MAX
|
||||
_SC_TIMER_MAX,
|
||||
#define _SC_TIMER_MAX _SC_TIMER_MAX
|
||||
|
||||
/* Values for the argument to `sysconf'
|
||||
corresponding to _POSIX2_* symbols. */
|
||||
_SC_BC_BASE_MAX,
|
||||
#define _SC_BC_BASE_MAX _SC_BC_BASE_MAX
|
||||
_SC_BC_DIM_MAX,
|
||||
#define _SC_BC_DIM_MAX _SC_BC_DIM_MAX
|
||||
_SC_BC_SCALE_MAX,
|
||||
#define _SC_BC_SCALE_MAX _SC_BC_SCALE_MAX
|
||||
_SC_BC_STRING_MAX,
|
||||
#define _SC_BC_STRING_MAX _SC_BC_STRING_MAX
|
||||
_SC_COLL_WEIGHTS_MAX,
|
||||
#define _SC_COLL_WEIGHTS_MAX _SC_COLL_WEIGHTS_MAX
|
||||
_SC_EQUIV_CLASS_MAX,
|
||||
#define _SC_EQUIV_CLASS_MAX _SC_EQUIV_CLASS_MAX
|
||||
_SC_EXPR_NEST_MAX,
|
||||
#define _SC_EXPR_NEST_MAX _SC_EXPR_NEST_MAX
|
||||
_SC_LINE_MAX,
|
||||
#define _SC_LINE_MAX _SC_LINE_MAX
|
||||
_SC_RE_DUP_MAX,
|
||||
#define _SC_RE_DUP_MAX _SC_RE_DUP_MAX
|
||||
_SC_CHARCLASS_NAME_MAX,
|
||||
#define _SC_CHARCLASS_NAME_MAX _SC_CHARCLASS_NAME_MAX
|
||||
|
||||
_SC_2_VERSION,
|
||||
#define _SC_2_VERSION _SC_2_VERSION
|
||||
_SC_2_C_BIND,
|
||||
#define _SC_2_C_BIND _SC_2_C_BIND
|
||||
_SC_2_C_DEV,
|
||||
#define _SC_2_C_DEV _SC_2_C_DEV
|
||||
_SC_2_FORT_DEV,
|
||||
#define _SC_2_FORT_DEV _SC_2_FORT_DEV
|
||||
_SC_2_FORT_RUN,
|
||||
#define _SC_2_FORT_RUN _SC_2_FORT_RUN
|
||||
_SC_2_SW_DEV,
|
||||
#define _SC_2_SW_DEV _SC_2_SW_DEV
|
||||
_SC_2_LOCALEDEF,
|
||||
#define _SC_2_LOCALEDEF _SC_2_LOCALEDEF
|
||||
|
||||
_SC_PII,
|
||||
#define _SC_PII _SC_PII
|
||||
_SC_PII_XTI,
|
||||
#define _SC_PII_XTI _SC_PII_XTI
|
||||
_SC_PII_SOCKET,
|
||||
#define _SC_PII_SOCKET _SC_PII_SOCKET
|
||||
_SC_PII_INTERNET,
|
||||
#define _SC_PII_INTERNET _SC_PII_INTERNET
|
||||
_SC_PII_OSI,
|
||||
#define _SC_PII_OSI _SC_PII_OSI
|
||||
_SC_POLL,
|
||||
#define _SC_POLL _SC_POLL
|
||||
_SC_SELECT,
|
||||
#define _SC_SELECT _SC_SELECT
|
||||
_SC_UIO_MAXIOV,
|
||||
#define _SC_UIO_MAXIOV _SC_UIO_MAXIOV
|
||||
_SC_IOV_MAX = _SC_UIO_MAXIOV,
|
||||
#define _SC_IOV_MAX _SC_IOV_MAX
|
||||
_SC_PII_INTERNET_STREAM,
|
||||
#define _SC_PII_INTERNET_STREAM _SC_PII_INTERNET_STREAM
|
||||
_SC_PII_INTERNET_DGRAM,
|
||||
#define _SC_PII_INTERNET_DGRAM _SC_PII_INTERNET_DGRAM
|
||||
_SC_PII_OSI_COTS,
|
||||
#define _SC_PII_OSI_COTS _SC_PII_OSI_COTS
|
||||
_SC_PII_OSI_CLTS,
|
||||
#define _SC_PII_OSI_CLTS _SC_PII_OSI_CLTS
|
||||
_SC_PII_OSI_M,
|
||||
#define _SC_PII_OSI_M _SC_PII_OSI_M
|
||||
_SC_T_IOV_MAX,
|
||||
#define _SC_T_IOV_MAX _SC_T_IOV_MAX
|
||||
|
||||
/* Values according to POSIX 1003.1c (POSIX threads). */
|
||||
_SC_THREADS,
|
||||
#define _SC_THREADS _SC_THREADS
|
||||
_SC_THREAD_SAFE_FUNCTIONS,
|
||||
#define _SC_THREAD_SAFE_FUNCTIONS _SC_THREAD_SAFE_FUNCTIONS
|
||||
_SC_GETGR_R_SIZE_MAX,
|
||||
#define _SC_GETGR_R_SIZE_MAX _SC_GETGR_R_SIZE_MAX
|
||||
_SC_GETPW_R_SIZE_MAX,
|
||||
#define _SC_GETPW_R_SIZE_MAX _SC_GETPW_R_SIZE_MAX
|
||||
_SC_LOGIN_NAME_MAX,
|
||||
#define _SC_LOGIN_NAME_MAX _SC_LOGIN_NAME_MAX
|
||||
_SC_TTY_NAME_MAX,
|
||||
#define _SC_TTY_NAME_MAX _SC_TTY_NAME_MAX
|
||||
_SC_THREAD_DESTRUCTOR_ITERATIONS,
|
||||
#define _SC_THREAD_DESTRUCTOR_ITERATIONS _SC_THREAD_DESTRUCTOR_ITERATIONS
|
||||
_SC_THREAD_KEYS_MAX,
|
||||
#define _SC_THREAD_KEYS_MAX _SC_THREAD_KEYS_MAX
|
||||
_SC_THREAD_STACK_MIN,
|
||||
#define _SC_THREAD_STACK_MIN _SC_THREAD_STACK_MIN
|
||||
_SC_THREAD_THREADS_MAX,
|
||||
#define _SC_THREAD_THREADS_MAX _SC_THREAD_THREADS_MAX
|
||||
_SC_THREAD_ATTR_STACKADDR,
|
||||
#define _SC_THREAD_ATTR_STACKADDR _SC_THREAD_ATTR_STACKADDR
|
||||
_SC_THREAD_ATTR_STACKSIZE,
|
||||
#define _SC_THREAD_ATTR_STACKSIZE _SC_THREAD_ATTR_STACKSIZE
|
||||
_SC_THREAD_PRIORITY_SCHEDULING,
|
||||
#define _SC_THREAD_PRIORITY_SCHEDULING _SC_THREAD_PRIORITY_SCHEDULING
|
||||
_SC_THREAD_PRIO_INHERIT,
|
||||
#define _SC_THREAD_PRIO_INHERIT _SC_THREAD_PRIO_INHERIT
|
||||
_SC_THREAD_PRIO_PROTECT,
|
||||
#define _SC_THREAD_PRIO_PROTECT _SC_THREAD_PRIO_PROTECT
|
||||
_SC_THREAD_PROCESS_SHARED,
|
||||
#define _SC_THREAD_PROCESS_SHARED _SC_THREAD_PROCESS_SHARED
|
||||
|
||||
_SC_NPROCESSORS_CONF,
|
||||
#define _SC_NPROCESSORS_CONF _SC_NPROCESSORS_CONF
|
||||
_SC_NPROCESSORS_ONLN,
|
||||
#define _SC_NPROCESSORS_ONLN _SC_NPROCESSORS_ONLN
|
||||
_SC_PHYS_PAGES,
|
||||
#define _SC_PHYS_PAGES _SC_PHYS_PAGES
|
||||
_SC_AVPHYS_PAGES,
|
||||
#define _SC_AVPHYS_PAGES _SC_AVPHYS_PAGES
|
||||
_SC_ATEXIT_MAX,
|
||||
#define _SC_ATEXIT_MAX _SC_ATEXIT_MAX
|
||||
_SC_PASS_MAX,
|
||||
#define _SC_PASS_MAX _SC_PASS_MAX
|
||||
|
||||
_SC_XOPEN_VERSION,
|
||||
#define _SC_XOPEN_VERSION _SC_XOPEN_VERSION
|
||||
_SC_XOPEN_XCU_VERSION,
|
||||
#define _SC_XOPEN_XCU_VERSION _SC_XOPEN_XCU_VERSION
|
||||
_SC_XOPEN_UNIX,
|
||||
#define _SC_XOPEN_UNIX _SC_XOPEN_UNIX
|
||||
_SC_XOPEN_CRYPT,
|
||||
#define _SC_XOPEN_CRYPT _SC_XOPEN_CRYPT
|
||||
_SC_XOPEN_ENH_I18N,
|
||||
#define _SC_XOPEN_ENH_I18N _SC_XOPEN_ENH_I18N
|
||||
_SC_XOPEN_SHM,
|
||||
#define _SC_XOPEN_SHM _SC_XOPEN_SHM
|
||||
|
||||
_SC_2_CHAR_TERM,
|
||||
#define _SC_2_CHAR_TERM _SC_2_CHAR_TERM
|
||||
_SC_2_C_VERSION,
|
||||
#define _SC_2_C_VERSION _SC_2_C_VERSION
|
||||
_SC_2_UPE,
|
||||
#define _SC_2_UPE _SC_2_UPE
|
||||
|
||||
_SC_XOPEN_XPG2,
|
||||
#define _SC_XOPEN_XPG2 _SC_XOPEN_XPG2
|
||||
_SC_XOPEN_XPG3,
|
||||
#define _SC_XOPEN_XPG3 _SC_XOPEN_XPG3
|
||||
_SC_XOPEN_XPG4,
|
||||
#define _SC_XOPEN_XPG4 _SC_XOPEN_XPG4
|
||||
|
||||
_SC_CHAR_BIT,
|
||||
#define _SC_CHAR_BIT _SC_CHAR_BIT
|
||||
_SC_CHAR_MAX,
|
||||
#define _SC_CHAR_MAX _SC_CHAR_MAX
|
||||
_SC_CHAR_MIN,
|
||||
#define _SC_CHAR_MIN _SC_CHAR_MIN
|
||||
_SC_INT_MAX,
|
||||
#define _SC_INT_MAX _SC_INT_MAX
|
||||
_SC_INT_MIN,
|
||||
#define _SC_INT_MIN _SC_INT_MIN
|
||||
_SC_LONG_BIT,
|
||||
#define _SC_LONG_BIT _SC_LONG_BIT
|
||||
_SC_WORD_BIT,
|
||||
#define _SC_WORD_BIT _SC_WORD_BIT
|
||||
_SC_MB_LEN_MAX,
|
||||
#define _SC_MB_LEN_MAX _SC_MB_LEN_MAX
|
||||
_SC_NZERO,
|
||||
#define _SC_NZERO _SC_NZERO
|
||||
_SC_SSIZE_MAX,
|
||||
#define _SC_SSIZE_MAX _SC_SSIZE_MAX
|
||||
_SC_SCHAR_MAX,
|
||||
#define _SC_SCHAR_MAX _SC_SCHAR_MAX
|
||||
_SC_SCHAR_MIN,
|
||||
#define _SC_SCHAR_MIN _SC_SCHAR_MIN
|
||||
_SC_SHRT_MAX,
|
||||
#define _SC_SHRT_MAX _SC_SHRT_MAX
|
||||
_SC_SHRT_MIN,
|
||||
#define _SC_SHRT_MIN _SC_SHRT_MIN
|
||||
_SC_UCHAR_MAX,
|
||||
#define _SC_UCHAR_MAX _SC_UCHAR_MAX
|
||||
_SC_UINT_MAX,
|
||||
#define _SC_UINT_MAX _SC_UINT_MAX
|
||||
_SC_ULONG_MAX,
|
||||
#define _SC_ULONG_MAX _SC_ULONG_MAX
|
||||
_SC_USHRT_MAX,
|
||||
#define _SC_USHRT_MAX _SC_USHRT_MAX
|
||||
|
||||
_SC_NL_ARGMAX,
|
||||
#define _SC_NL_ARGMAX _SC_NL_ARGMAX
|
||||
_SC_NL_LANGMAX,
|
||||
#define _SC_NL_LANGMAX _SC_NL_LANGMAX
|
||||
_SC_NL_MSGMAX,
|
||||
#define _SC_NL_MSGMAX _SC_NL_MSGMAX
|
||||
_SC_NL_NMAX,
|
||||
#define _SC_NL_NMAX _SC_NL_NMAX
|
||||
_SC_NL_SETMAX,
|
||||
#define _SC_NL_SETMAX _SC_NL_SETMAX
|
||||
_SC_NL_TEXTMAX,
|
||||
#define _SC_NL_TEXTMAX _SC_NL_TEXTMAX
|
||||
|
||||
_SC_XBS5_ILP32_OFF32,
|
||||
#define _SC_XBS5_ILP32_OFF32 _SC_XBS5_ILP32_OFF32
|
||||
_SC_XBS5_ILP32_OFFBIG,
|
||||
#define _SC_XBS5_ILP32_OFFBIG _SC_XBS5_ILP32_OFFBIG
|
||||
_SC_XBS5_LP64_OFF64,
|
||||
#define _SC_XBS5_LP64_OFF64 _SC_XBS5_LP64_OFF64
|
||||
_SC_XBS5_LPBIG_OFFBIG,
|
||||
#define _SC_XBS5_LPBIG_OFFBIG _SC_XBS5_LPBIG_OFFBIG
|
||||
|
||||
_SC_XOPEN_LEGACY,
|
||||
#define _SC_XOPEN_LEGACY _SC_XOPEN_LEGACY
|
||||
_SC_XOPEN_REALTIME,
|
||||
#define _SC_XOPEN_REALTIME _SC_XOPEN_REALTIME
|
||||
_SC_XOPEN_REALTIME_THREADS,
|
||||
#define _SC_XOPEN_REALTIME_THREADS _SC_XOPEN_REALTIME_THREADS
|
||||
|
||||
_SC_ADVISORY_INFO,
|
||||
#define _SC_ADVISORY_INFO _SC_ADVISORY_INFO
|
||||
_SC_BARRIERS,
|
||||
#define _SC_BARRIERS _SC_BARRIERS
|
||||
_SC_BASE,
|
||||
#define _SC_BASE _SC_BASE
|
||||
_SC_C_LANG_SUPPORT,
|
||||
#define _SC_C_LANG_SUPPORT _SC_C_LANG_SUPPORT
|
||||
_SC_C_LANG_SUPPORT_R,
|
||||
#define _SC_C_LANG_SUPPORT_R _SC_C_LANG_SUPPORT_R
|
||||
_SC_CLOCK_SELECTION,
|
||||
#define _SC_CLOCK_SELECTION _SC_CLOCK_SELECTION
|
||||
_SC_CPUTIME,
|
||||
#define _SC_CPUTIME _SC_CPUTIME
|
||||
_SC_THREAD_CPUTIME,
|
||||
#define _SC_THREAD_CPUTIME _SC_THREAD_CPUTIME
|
||||
_SC_DEVICE_IO,
|
||||
#define _SC_DEVICE_IO _SC_DEVICE_IO
|
||||
_SC_DEVICE_SPECIFIC,
|
||||
#define _SC_DEVICE_SPECIFIC _SC_DEVICE_SPECIFIC
|
||||
_SC_DEVICE_SPECIFIC_R,
|
||||
#define _SC_DEVICE_SPECIFIC_R _SC_DEVICE_SPECIFIC_R
|
||||
_SC_FD_MGMT,
|
||||
#define _SC_FD_MGMT _SC_FD_MGMT
|
||||
_SC_FIFO,
|
||||
#define _SC_FIFO _SC_FIFO
|
||||
_SC_PIPE,
|
||||
#define _SC_PIPE _SC_PIPE
|
||||
_SC_FILE_ATTRIBUTES,
|
||||
#define _SC_FILE_ATTRIBUTES _SC_FILE_ATTRIBUTES
|
||||
_SC_FILE_LOCKING,
|
||||
#define _SC_FILE_LOCKING _SC_FILE_LOCKING
|
||||
_SC_FILE_SYSTEM,
|
||||
#define _SC_FILE_SYSTEM _SC_FILE_SYSTEM
|
||||
_SC_MONOTONIC_CLOCK,
|
||||
#define _SC_MONOTONIC_CLOCK _SC_MONOTONIC_CLOCK
|
||||
_SC_MULTI_PROCESS,
|
||||
#define _SC_MULTI_PROCESS _SC_MULTI_PROCESS
|
||||
_SC_SINGLE_PROCESS,
|
||||
#define _SC_SINGLE_PROCESS _SC_SINGLE_PROCESS
|
||||
_SC_NETWORKING,
|
||||
#define _SC_NETWORKING _SC_NETWORKING
|
||||
_SC_READER_WRITER_LOCKS,
|
||||
#define _SC_READER_WRITER_LOCKS _SC_READER_WRITER_LOCKS
|
||||
_SC_SPIN_LOCKS,
|
||||
#define _SC_SPIN_LOCKS _SC_SPIN_LOCKS
|
||||
_SC_REGEXP,
|
||||
#define _SC_REGEXP _SC_REGEXP
|
||||
_SC_REGEX_VERSION,
|
||||
#define _SC_REGEX_VERSION _SC_REGEX_VERSION
|
||||
_SC_SHELL,
|
||||
#define _SC_SHELL _SC_SHELL
|
||||
_SC_SIGNALS,
|
||||
#define _SC_SIGNALS _SC_SIGNALS
|
||||
_SC_SPAWN,
|
||||
#define _SC_SPAWN _SC_SPAWN
|
||||
_SC_SPORADIC_SERVER,
|
||||
#define _SC_SPORADIC_SERVER _SC_SPORADIC_SERVER
|
||||
_SC_THREAD_SPORADIC_SERVER,
|
||||
#define _SC_THREAD_SPORADIC_SERVER _SC_THREAD_SPORADIC_SERVER
|
||||
_SC_SYSTEM_DATABASE,
|
||||
#define _SC_SYSTEM_DATABASE _SC_SYSTEM_DATABASE
|
||||
_SC_SYSTEM_DATABASE_R,
|
||||
#define _SC_SYSTEM_DATABASE_R _SC_SYSTEM_DATABASE_R
|
||||
_SC_TIMEOUTS,
|
||||
#define _SC_TIMEOUTS _SC_TIMEOUTS
|
||||
_SC_TYPED_MEMORY_OBJECTS,
|
||||
#define _SC_TYPED_MEMORY_OBJECTS _SC_TYPED_MEMORY_OBJECTS
|
||||
_SC_USER_GROUPS,
|
||||
#define _SC_USER_GROUPS _SC_USER_GROUPS
|
||||
_SC_USER_GROUPS_R,
|
||||
#define _SC_USER_GROUPS_R _SC_USER_GROUPS_R
|
||||
_SC_2_PBS,
|
||||
#define _SC_2_PBS _SC_2_PBS
|
||||
_SC_2_PBS_ACCOUNTING,
|
||||
#define _SC_2_PBS_ACCOUNTING _SC_2_PBS_ACCOUNTING
|
||||
_SC_2_PBS_LOCATE,
|
||||
#define _SC_2_PBS_LOCATE _SC_2_PBS_LOCATE
|
||||
_SC_2_PBS_MESSAGE,
|
||||
#define _SC_2_PBS_MESSAGE _SC_2_PBS_MESSAGE
|
||||
_SC_2_PBS_TRACK,
|
||||
#define _SC_2_PBS_TRACK _SC_2_PBS_TRACK
|
||||
_SC_SYMLOOP_MAX,
|
||||
#define _SC_SYMLOOP_MAX _SC_SYMLOOP_MAX
|
||||
_SC_STREAMS,
|
||||
#define _SC_STREAMS _SC_STREAMS
|
||||
_SC_2_PBS_CHECKPOINT,
|
||||
#define _SC_2_PBS_CHECKPOINT _SC_2_PBS_CHECKPOINT
|
||||
|
||||
_SC_V6_ILP32_OFF32,
|
||||
#define _SC_V6_ILP32_OFF32 _SC_V6_ILP32_OFF32
|
||||
_SC_V6_ILP32_OFFBIG,
|
||||
#define _SC_V6_ILP32_OFFBIG _SC_V6_ILP32_OFFBIG
|
||||
_SC_V6_LP64_OFF64,
|
||||
#define _SC_V6_LP64_OFF64 _SC_V6_LP64_OFF64
|
||||
_SC_V6_LPBIG_OFFBIG,
|
||||
#define _SC_V6_LPBIG_OFFBIG _SC_V6_LPBIG_OFFBIG
|
||||
|
||||
_SC_HOST_NAME_MAX,
|
||||
#define _SC_HOST_NAME_MAX _SC_HOST_NAME_MAX
|
||||
_SC_TRACE,
|
||||
#define _SC_TRACE _SC_TRACE
|
||||
_SC_TRACE_EVENT_FILTER,
|
||||
#define _SC_TRACE_EVENT_FILTER _SC_TRACE_EVENT_FILTER
|
||||
_SC_TRACE_INHERIT,
|
||||
#define _SC_TRACE_INHERIT _SC_TRACE_INHERIT
|
||||
_SC_TRACE_LOG,
|
||||
#define _SC_TRACE_LOG _SC_TRACE_LOG
|
||||
|
||||
_SC_LEVEL1_ICACHE_SIZE,
|
||||
#define _SC_LEVEL1_ICACHE_SIZE _SC_LEVEL1_ICACHE_SIZE
|
||||
_SC_LEVEL1_ICACHE_ASSOC,
|
||||
#define _SC_LEVEL1_ICACHE_ASSOC _SC_LEVEL1_ICACHE_ASSOC
|
||||
_SC_LEVEL1_ICACHE_LINESIZE,
|
||||
#define _SC_LEVEL1_ICACHE_LINESIZE _SC_LEVEL1_ICACHE_LINESIZE
|
||||
_SC_LEVEL1_DCACHE_SIZE,
|
||||
#define _SC_LEVEL1_DCACHE_SIZE _SC_LEVEL1_DCACHE_SIZE
|
||||
_SC_LEVEL1_DCACHE_ASSOC,
|
||||
#define _SC_LEVEL1_DCACHE_ASSOC _SC_LEVEL1_DCACHE_ASSOC
|
||||
_SC_LEVEL1_DCACHE_LINESIZE,
|
||||
#define _SC_LEVEL1_DCACHE_LINESIZE _SC_LEVEL1_DCACHE_LINESIZE
|
||||
_SC_LEVEL2_CACHE_SIZE,
|
||||
#define _SC_LEVEL2_CACHE_SIZE _SC_LEVEL2_CACHE_SIZE
|
||||
_SC_LEVEL2_CACHE_ASSOC,
|
||||
#define _SC_LEVEL2_CACHE_ASSOC _SC_LEVEL2_CACHE_ASSOC
|
||||
_SC_LEVEL2_CACHE_LINESIZE,
|
||||
#define _SC_LEVEL2_CACHE_LINESIZE _SC_LEVEL2_CACHE_LINESIZE
|
||||
_SC_LEVEL3_CACHE_SIZE,
|
||||
#define _SC_LEVEL3_CACHE_SIZE _SC_LEVEL3_CACHE_SIZE
|
||||
_SC_LEVEL3_CACHE_ASSOC,
|
||||
#define _SC_LEVEL3_CACHE_ASSOC _SC_LEVEL3_CACHE_ASSOC
|
||||
_SC_LEVEL3_CACHE_LINESIZE,
|
||||
#define _SC_LEVEL3_CACHE_LINESIZE _SC_LEVEL3_CACHE_LINESIZE
|
||||
_SC_LEVEL4_CACHE_SIZE,
|
||||
#define _SC_LEVEL4_CACHE_SIZE _SC_LEVEL4_CACHE_SIZE
|
||||
_SC_LEVEL4_CACHE_ASSOC,
|
||||
#define _SC_LEVEL4_CACHE_ASSOC _SC_LEVEL4_CACHE_ASSOC
|
||||
_SC_LEVEL4_CACHE_LINESIZE
|
||||
#define _SC_LEVEL4_CACHE_LINESIZE _SC_LEVEL4_CACHE_LINESIZE
|
||||
/* Leave room here, maybe we need a few more cache levels some day. */
|
||||
};
|
||||
|
||||
/* Values for the NAME argument to `confstr'. */
|
||||
enum
|
||||
{
|
||||
_CS_PATH, /* The default search path. */
|
||||
#define _CS_PATH _CS_PATH
|
||||
|
||||
_CS_V6_WIDTH_RESTRICTED_ENVS,
|
||||
# define _CS_V6_WIDTH_RESTRICTED_ENVS _CS_V6_WIDTH_RESTRICTED_ENVS
|
||||
|
||||
_CS_GNU_LIBC_VERSION,
|
||||
#define _CS_GNU_LIBC_VERSION _CS_GNU_LIBC_VERSION
|
||||
_CS_GNU_LIBPTHREAD_VERSION,
|
||||
#define _CS_GNU_LIBPTHREAD_VERSION _CS_GNU_LIBPTHREAD_VERSION
|
||||
|
||||
_CS_LFS_CFLAGS = 1000,
|
||||
#define _CS_LFS_CFLAGS _CS_LFS_CFLAGS
|
||||
_CS_LFS_LDFLAGS,
|
||||
#define _CS_LFS_LDFLAGS _CS_LFS_LDFLAGS
|
||||
_CS_LFS_LIBS,
|
||||
#define _CS_LFS_LIBS _CS_LFS_LIBS
|
||||
_CS_LFS_LINTFLAGS,
|
||||
#define _CS_LFS_LINTFLAGS _CS_LFS_LINTFLAGS
|
||||
_CS_LFS64_CFLAGS,
|
||||
#define _CS_LFS64_CFLAGS _CS_LFS64_CFLAGS
|
||||
_CS_LFS64_LDFLAGS,
|
||||
#define _CS_LFS64_LDFLAGS _CS_LFS64_LDFLAGS
|
||||
_CS_LFS64_LIBS,
|
||||
#define _CS_LFS64_LIBS _CS_LFS64_LIBS
|
||||
_CS_LFS64_LINTFLAGS,
|
||||
#define _CS_LFS64_LINTFLAGS _CS_LFS64_LINTFLAGS
|
||||
|
||||
_CS_XBS5_ILP32_OFF32_CFLAGS = 1100,
|
||||
#define _CS_XBS5_ILP32_OFF32_CFLAGS _CS_XBS5_ILP32_OFF32_CFLAGS
|
||||
_CS_XBS5_ILP32_OFF32_LDFLAGS,
|
||||
#define _CS_XBS5_ILP32_OFF32_LDFLAGS _CS_XBS5_ILP32_OFF32_LDFLAGS
|
||||
_CS_XBS5_ILP32_OFF32_LIBS,
|
||||
#define _CS_XBS5_ILP32_OFF32_LIBS _CS_XBS5_ILP32_OFF32_LIBS
|
||||
_CS_XBS5_ILP32_OFF32_LINTFLAGS,
|
||||
#define _CS_XBS5_ILP32_OFF32_LINTFLAGS _CS_XBS5_ILP32_OFF32_LINTFLAGS
|
||||
_CS_XBS5_ILP32_OFFBIG_CFLAGS,
|
||||
#define _CS_XBS5_ILP32_OFFBIG_CFLAGS _CS_XBS5_ILP32_OFFBIG_CFLAGS
|
||||
_CS_XBS5_ILP32_OFFBIG_LDFLAGS,
|
||||
#define _CS_XBS5_ILP32_OFFBIG_LDFLAGS _CS_XBS5_ILP32_OFFBIG_LDFLAGS
|
||||
_CS_XBS5_ILP32_OFFBIG_LIBS,
|
||||
#define _CS_XBS5_ILP32_OFFBIG_LIBS _CS_XBS5_ILP32_OFFBIG_LIBS
|
||||
_CS_XBS5_ILP32_OFFBIG_LINTFLAGS,
|
||||
#define _CS_XBS5_ILP32_OFFBIG_LINTFLAGS _CS_XBS5_ILP32_OFFBIG_LINTFLAGS
|
||||
_CS_XBS5_LP64_OFF64_CFLAGS,
|
||||
#define _CS_XBS5_LP64_OFF64_CFLAGS _CS_XBS5_LP64_OFF64_CFLAGS
|
||||
_CS_XBS5_LP64_OFF64_LDFLAGS,
|
||||
#define _CS_XBS5_LP64_OFF64_LDFLAGS _CS_XBS5_LP64_OFF64_LDFLAGS
|
||||
_CS_XBS5_LP64_OFF64_LIBS,
|
||||
#define _CS_XBS5_LP64_OFF64_LIBS _CS_XBS5_LP64_OFF64_LIBS
|
||||
_CS_XBS5_LP64_OFF64_LINTFLAGS,
|
||||
#define _CS_XBS5_LP64_OFF64_LINTFLAGS _CS_XBS5_LP64_OFF64_LINTFLAGS
|
||||
_CS_XBS5_LPBIG_OFFBIG_CFLAGS,
|
||||
#define _CS_XBS5_LPBIG_OFFBIG_CFLAGS _CS_XBS5_LPBIG_OFFBIG_CFLAGS
|
||||
_CS_XBS5_LPBIG_OFFBIG_LDFLAGS,
|
||||
#define _CS_XBS5_LPBIG_OFFBIG_LDFLAGS _CS_XBS5_LPBIG_OFFBIG_LDFLAGS
|
||||
_CS_XBS5_LPBIG_OFFBIG_LIBS,
|
||||
#define _CS_XBS5_LPBIG_OFFBIG_LIBS _CS_XBS5_LPBIG_OFFBIG_LIBS
|
||||
_CS_XBS5_LPBIG_OFFBIG_LINTFLAGS,
|
||||
#define _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS
|
||||
|
||||
_CS_POSIX_V6_ILP32_OFF32_CFLAGS,
|
||||
#define _CS_POSIX_V6_ILP32_OFF32_CFLAGS _CS_POSIX_V6_ILP32_OFF32_CFLAGS
|
||||
_CS_POSIX_V6_ILP32_OFF32_LDFLAGS,
|
||||
#define _CS_POSIX_V6_ILP32_OFF32_LDFLAGS _CS_POSIX_V6_ILP32_OFF32_LDFLAGS
|
||||
_CS_POSIX_V6_ILP32_OFF32_LIBS,
|
||||
#define _CS_POSIX_V6_ILP32_OFF32_LIBS _CS_POSIX_V6_ILP32_OFF32_LIBS
|
||||
_CS_POSIX_V6_ILP32_OFF32_LINTFLAGS,
|
||||
#define _CS_POSIX_V6_ILP32_OFF32_LINTFLAGS _CS_POSIX_V6_ILP32_OFF32_LINTFLAGS
|
||||
_CS_POSIX_V6_ILP32_OFFBIG_CFLAGS,
|
||||
#define _CS_POSIX_V6_ILP32_OFFBIG_CFLAGS _CS_POSIX_V6_ILP32_OFFBIG_CFLAGS
|
||||
_CS_POSIX_V6_ILP32_OFFBIG_LDFLAGS,
|
||||
#define _CS_POSIX_V6_ILP32_OFFBIG_LDFLAGS _CS_POSIX_V6_ILP32_OFFBIG_LDFLAGS
|
||||
_CS_POSIX_V6_ILP32_OFFBIG_LIBS,
|
||||
#define _CS_POSIX_V6_ILP32_OFFBIG_LIBS _CS_POSIX_V6_ILP32_OFFBIG_LIBS
|
||||
_CS_POSIX_V6_ILP32_OFFBIG_LINTFLAGS,
|
||||
#define _CS_POSIX_V6_ILP32_OFFBIG_LINTFLAGS _CS_POSIX_V6_ILP32_OFFBIG_LINTFLAGS
|
||||
_CS_POSIX_V6_LP64_OFF64_CFLAGS,
|
||||
#define _CS_POSIX_V6_LP64_OFF64_CFLAGS _CS_POSIX_V6_LP64_OFF64_CFLAGS
|
||||
_CS_POSIX_V6_LP64_OFF64_LDFLAGS,
|
||||
#define _CS_POSIX_V6_LP64_OFF64_LDFLAGS _CS_POSIX_V6_LP64_OFF64_LDFLAGS
|
||||
_CS_POSIX_V6_LP64_OFF64_LIBS,
|
||||
#define _CS_POSIX_V6_LP64_OFF64_LIBS _CS_POSIX_V6_LP64_OFF64_LIBS
|
||||
_CS_POSIX_V6_LP64_OFF64_LINTFLAGS,
|
||||
#define _CS_POSIX_V6_LP64_OFF64_LINTFLAGS _CS_POSIX_V6_LP64_OFF64_LINTFLAGS
|
||||
_CS_POSIX_V6_LPBIG_OFFBIG_CFLAGS,
|
||||
#define _CS_POSIX_V6_LPBIG_OFFBIG_CFLAGS _CS_POSIX_V6_LPBIG_OFFBIG_CFLAGS
|
||||
_CS_POSIX_V6_LPBIG_OFFBIG_LDFLAGS,
|
||||
#define _CS_POSIX_V6_LPBIG_OFFBIG_LDFLAGS _CS_POSIX_V6_LPBIG_OFFBIG_LDFLAGS
|
||||
_CS_POSIX_V6_LPBIG_OFFBIG_LIBS,
|
||||
#define _CS_POSIX_V6_LPBIG_OFFBIG_LIBS _CS_POSIX_V6_LPBIG_OFFBIG_LIBS
|
||||
_CS_POSIX_V6_LPBIG_OFFBIG_LINTFLAGS
|
||||
#define _CS_POSIX_V6_LPBIG_OFFBIG_LINTFLAGS _CS_POSIX_V6_LPBIG_OFFBIG_LINTFLAGS
|
||||
};
|
||||
@@ -1,64 +0,0 @@
|
||||
/* System dependent definitions for run-time dynamic loading.
|
||||
Copyright (C) 1996,1997,1998,1999,2000,2001 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. */
|
||||
|
||||
#ifndef _DLFCN_H
|
||||
# error "Never use <bits/dlfcn.h> directly; include <dlfcn.h> instead."
|
||||
#endif
|
||||
|
||||
/* The MODE argument to `dlopen' contains one of the following: */
|
||||
#define RTLD_LAZY 0x00001 /* Lazy function call binding. */
|
||||
#define RTLD_NOW 0x00002 /* Immediate function call binding. */
|
||||
#define RTLD_BINDING_MASK 0x3 /* Mask of binding time value. */
|
||||
#define RTLD_NOLOAD 0x00004 /* Do not load the object. */
|
||||
|
||||
/* If the following bit is set in the MODE argument to `dlopen',
|
||||
the symbols of the loaded object and its dependencies are made
|
||||
visible as if the object were linked directly into the program. */
|
||||
#define RTLD_GLOBAL 0x00100
|
||||
|
||||
/* Unix98 demands the following flag which is the inverse to RTLD_GLOBAL.
|
||||
The implementation does this by default and so we can define the
|
||||
value to zero. */
|
||||
#define RTLD_LOCAL 0
|
||||
|
||||
/* Do not delete object when closed. */
|
||||
#define RTLD_NODELETE 0x01000
|
||||
|
||||
#ifdef __USE_GNU
|
||||
/* To support profiling of shared objects it is a good idea to call
|
||||
the function found using `dlsym' using the following macro since
|
||||
these calls do not use the PLT. But this would mean the dynamic
|
||||
loader has no chance to find out when the function is called. The
|
||||
macro applies the necessary magic so that profiling is possible.
|
||||
Rewrite
|
||||
foo = (*fctp) (arg1, arg2);
|
||||
into
|
||||
foo = DL_CALL_FCT (fctp, (arg1, arg2));
|
||||
*/
|
||||
# define DL_CALL_FCT(fctp, args) \
|
||||
(_dl_mcount_wrapper_check ((void *) (fctp)), (*(fctp)) args)
|
||||
|
||||
__BEGIN_DECLS
|
||||
|
||||
/* This function calls the profiling functions. */
|
||||
extern void _dl_mcount_wrapper_check (void *__selfpc) __THROW;
|
||||
|
||||
__END_DECLS
|
||||
|
||||
#endif
|
||||
@@ -1,75 +0,0 @@
|
||||
/* Copyright (C) 1999, 2001 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. */
|
||||
|
||||
#ifndef _UNISTD_H
|
||||
# error "Never include this file directly. Use <unistd.h> instead"
|
||||
#endif
|
||||
|
||||
#include <bits/wordsize.h>
|
||||
|
||||
/* This header should define the following symbols under the described
|
||||
situations. A value `1' means that the model is always supported,
|
||||
`-1' means it is never supported. Undefined means it cannot be
|
||||
statically decided.
|
||||
|
||||
_POSIX_V6_ILP32_OFF32 32bit int, long, pointers, and off_t type
|
||||
_POSIX_V6_ILP32_OFFBIG 32bit int, long, and pointers and larger off_t type
|
||||
|
||||
_POSIX_V6_LP64_OFF32 64bit long and pointers and 32bit off_t type
|
||||
_POSIX_V6_LPBIG_OFFBIG 64bit long and pointers and large off_t type
|
||||
|
||||
The macros _XBS5_ILP32_OFF32, _XBS5_ILP32_OFFBIG, _XBS5_LP64_OFF32, and
|
||||
_XBS5_LPBIG_OFFBIG were used in previous versions of the Unix standard
|
||||
and are available only for compatibility.
|
||||
*/
|
||||
|
||||
#if __WORDSIZE == 64
|
||||
|
||||
/* We can never provide environments with 32-bit wide pointers. */
|
||||
# define _POSIX_V6_ILP32_OFF32 -1
|
||||
# define _POSIX_V6_ILP32_OFFBIG -1
|
||||
# define _XBS5_ILP32_OFF32 -1
|
||||
# define _XBS5_ILP32_OFFBIG -1
|
||||
/* We also have no use (for now) for an environment with bigger pointers
|
||||
and offsets. */
|
||||
# define _POSIX_V6_LPBIG_OFFBIG -1
|
||||
# define _XBS5_LPBIG_OFFBIG -1
|
||||
|
||||
/* By default we have 64-bit wide `long int', pointers and `off_t'. */
|
||||
# define _POSIX_V6_LP64_OFF64 1
|
||||
# define _XBS5_LP64_OFF64 1
|
||||
|
||||
#else /* __WORDSIZE == 32 */
|
||||
|
||||
/* By default we have 32-bit wide `int', `long int', pointers and `off_t'
|
||||
and all platforms support LFS. */
|
||||
# define _POSIX_V6_ILP32_OFF32 1
|
||||
# define _POSIX_V6_ILP32_OFFBIG 1
|
||||
# define _XBS5_ILP32_OFF32 1
|
||||
# define _XBS5_ILP32_OFFBIG 1
|
||||
|
||||
/* We optionally provide an environment with the above size but an 64-bit
|
||||
side `off_t'. Therefore we don't define _XBS5_ILP32_OFFBIG. */
|
||||
|
||||
/* We can never provide environments with 64-bit wide pointers. */
|
||||
# define _POSIX_V6_LP64_OFF64 -1
|
||||
# define _POSIX_V6_LPBIG_OFFBIG -1
|
||||
# define _XBS5_LP64_OFF64 -1
|
||||
# define _XBS5_LPBIG_OFFBIG -1
|
||||
|
||||
#endif /* __WORDSIZE == 32 */
|
||||
@@ -1,4 +0,0 @@
|
||||
struct link_map_machine
|
||||
{
|
||||
/* empty by default */
|
||||
};
|
||||
-91
@@ -1,91 +0,0 @@
|
||||
/* Definitions for BSD-style memory management.
|
||||
Copyright (C) 1994-1998,2000,01,02 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. */
|
||||
|
||||
/* These are the bits used by 4.4 BSD and its derivatives. On systems
|
||||
(such as GNU) where these facilities are not system services but can be
|
||||
emulated in the C library, these are the definitions we emulate. */
|
||||
|
||||
#ifndef _SYS_MMAN_H
|
||||
# error "Never use <bits/mman.h> directly; include <sys/mman.h> instead."
|
||||
#endif
|
||||
|
||||
/* Protections are chosen from these bits, OR'd together. The
|
||||
implementation does not necessarily support PROT_EXEC or PROT_WRITE
|
||||
without PROT_READ. The only guarantees are that no writing will be
|
||||
allowed without PROT_WRITE and no access will be allowed for PROT_NONE. */
|
||||
|
||||
#define PROT_NONE 0x00 /* No access. */
|
||||
#define PROT_READ 0x04 /* Pages can be read. */
|
||||
#define PROT_WRITE 0x02 /* Pages can be written. */
|
||||
#define PROT_EXEC 0x01 /* Pages can be executed. */
|
||||
|
||||
/* Flags contain mapping type, sharing type and options. */
|
||||
|
||||
/* Mapping type (must choose one and only one of these). */
|
||||
#ifdef __USE_BSD
|
||||
# define MAP_FILE 0x0001 /* Mapped from a file or device. */
|
||||
# define MAP_ANON 0x0002 /* Allocated from anonymous virtual memory. */
|
||||
# define MAP_TYPE 0x000f /* Mask for type field. */
|
||||
# ifdef __USE_MISC
|
||||
# define MAP_ANONYMOUS MAP_ANON /* Linux name. */
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/* Sharing types (must choose one and only one of these). */
|
||||
#ifdef __USE_BSD
|
||||
# define MAP_COPY 0x0020 /* Virtual copy of region at mapping time. */
|
||||
#endif
|
||||
#define MAP_SHARED 0x0010 /* Share changes. */
|
||||
#define MAP_PRIVATE 0x0000 /* Changes private; copy pages on write. */
|
||||
|
||||
/* Other flags. */
|
||||
#define MAP_FIXED 0x0100 /* Map address must be exactly as requested. */
|
||||
#ifdef __USE_BSD
|
||||
# define MAP_NOEXTEND 0x0200 /* For MAP_FILE, don't change file size. */
|
||||
# define MAP_HASSEMPHORE 0x0400 /* Region may contain semaphores. */
|
||||
# define MAP_INHERIT 0x0800 /* Region is retained after exec. */
|
||||
#endif
|
||||
|
||||
/* Advice to `madvise'. */
|
||||
#ifdef __USE_BSD
|
||||
# define MADV_NORMAL 0 /* No further special treatment. */
|
||||
# define MADV_RANDOM 1 /* Expect random page references. */
|
||||
# define MADV_SEQUENTIAL 2 /* Expect sequential page references. */
|
||||
# define MADV_WILLNEED 3 /* Will need these pages. */
|
||||
# define MADV_DONTNEED 4 /* Don't need these pages. */
|
||||
#endif
|
||||
|
||||
/* The POSIX people had to invent similar names for the same things. */
|
||||
#ifdef __USE_XOPEN2K
|
||||
# define POSIX_MADV_NORMAL 0 /* No further special treatment. */
|
||||
# define POSIX_MADV_RANDOM 1 /* Expect random page references. */
|
||||
# define POSIX_MADV_SEQUENTIAL 2 /* Expect sequential page references. */
|
||||
# define POSIX_MADV_WILLNEED 3 /* Will need these pages. */
|
||||
# define POSIX_MADV_DONTNEED 4 /* Don't need these pages. */
|
||||
#endif
|
||||
|
||||
/* Flags to `msync'. */
|
||||
#define MS_ASYNC 1 /* Sync memory asynchronously. */
|
||||
#define MS_SYNC 0 /* Synchronous memory sync. */
|
||||
#define MS_INVALIDATE 2 /* Invalidate the caches. */
|
||||
|
||||
/* Flags for `mlockall' (can be OR'd together). */
|
||||
#define MCL_CURRENT 1 /* Lock all currently mapped pages. */
|
||||
#define MCL_FUTURE 2 /* Lock all additions to address
|
||||
space. */
|
||||
-199
@@ -1,199 +0,0 @@
|
||||
/* bits/types.h -- definitions of __*_t types underlying *_t types.
|
||||
Copyright (C) 2002, 2003 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. */
|
||||
|
||||
/*
|
||||
* Never include this file directly; use <sys/types.h> instead.
|
||||
*/
|
||||
|
||||
#ifndef _BITS_TYPES_H
|
||||
#define _BITS_TYPES_H 1
|
||||
|
||||
#include <features.h>
|
||||
#include <bits/wordsize.h>
|
||||
|
||||
#define __need_size_t
|
||||
#include <stddef.h>
|
||||
|
||||
/* Convenience types. */
|
||||
typedef unsigned char __u_char;
|
||||
typedef unsigned short int __u_short;
|
||||
typedef unsigned int __u_int;
|
||||
typedef unsigned long int __u_long;
|
||||
|
||||
/* Fixed-size types, underlying types depend on word size and compiler. */
|
||||
typedef signed char __int8_t;
|
||||
typedef unsigned char __uint8_t;
|
||||
typedef signed short int __int16_t;
|
||||
typedef unsigned short int __uint16_t;
|
||||
typedef signed int __int32_t;
|
||||
typedef unsigned int __uint32_t;
|
||||
#if __WORDSIZE == 64
|
||||
typedef signed long int __int64_t;
|
||||
typedef unsigned long int __uint64_t;
|
||||
#elif defined __GLIBC_HAVE_LONG_LONG
|
||||
__extension__ typedef signed long long int __int64_t;
|
||||
__extension__ typedef unsigned long long int __uint64_t;
|
||||
#endif
|
||||
|
||||
/* quad_t is also 64 bits. */
|
||||
#if __WORDSIZE == 64
|
||||
typedef long int __quad_t;
|
||||
typedef unsigned long int __u_quad_t;
|
||||
#elif defined __GLIBC_HAVE_LONG_LONG
|
||||
__extension__ typedef long long int __quad_t;
|
||||
__extension__ typedef unsigned long long int __u_quad_t;
|
||||
#else
|
||||
typedef struct
|
||||
{
|
||||
long __val[2];
|
||||
} __quad_t;
|
||||
typedef struct
|
||||
{
|
||||
__u_long __val[2];
|
||||
} __u_quad_t;
|
||||
#endif
|
||||
|
||||
|
||||
/* The machine-dependent file <bits/typesizes.h> defines __*_T_TYPE
|
||||
macros for each of the OS types we define below. The definitions
|
||||
of those macros must use the following macros for underlying types.
|
||||
We define __S<SIZE>_TYPE and __U<SIZE>_TYPE for the signed and unsigned
|
||||
variants of each of the following integer types on this machine.
|
||||
|
||||
16 -- "natural" 16-bit type (always short)
|
||||
32 -- "natural" 32-bit type (always int)
|
||||
64 -- "natural" 64-bit type (long or long long)
|
||||
LONG32 -- 32-bit type, traditionally long
|
||||
QUAD -- 64-bit type, always long long
|
||||
WORD -- natural type of __WORDSIZE bits (int or long)
|
||||
LONGWORD -- type of __WORDSIZE bits, traditionally long
|
||||
|
||||
We distinguish WORD/LONGWORD, 32/LONG32, and 64/QUAD so that the
|
||||
conventional uses of `long' or `long long' type modifiers match the
|
||||
types we define, even when a less-adorned type would be the same size.
|
||||
This matters for (somewhat) portably writing printf/scanf formats for
|
||||
these types, where using the appropriate l or ll format modifiers can
|
||||
make the typedefs and the formats match up across all GNU platforms. If
|
||||
we used `long' when it's 64 bits where `long long' is expected, then the
|
||||
compiler would warn about the formats not matching the argument types,
|
||||
and the programmer changing them to shut up the compiler would break the
|
||||
program's portability.
|
||||
|
||||
Here we assume what is presently the case in all the GCC configurations
|
||||
we support: long long is always 64 bits, long is always word/address size,
|
||||
and int is always 32 bits. */
|
||||
|
||||
#define __S16_TYPE short int
|
||||
#define __U16_TYPE unsigned short int
|
||||
#define __S32_TYPE int
|
||||
#define __U32_TYPE unsigned int
|
||||
#define __SLONGWORD_TYPE long int
|
||||
#define __ULONGWORD_TYPE unsigned long int
|
||||
#if __WORDSIZE == 32
|
||||
# define __SQUAD_TYPE long long int
|
||||
# define __UQUAD_TYPE unsigned long long int
|
||||
# define __SWORD_TYPE int
|
||||
# define __UWORD_TYPE unsigned int
|
||||
# define __SLONG32_TYPE long int
|
||||
# define __ULONG32_TYPE unsigned long int
|
||||
# define __S64_TYPE __quad_t
|
||||
# define __U64_TYPE __u_quad_t
|
||||
#elif __WORDSIZE == 64
|
||||
# define __SQUAD_TYPE long int
|
||||
# define __UQUAD_TYPE unsigned long int
|
||||
# define __SWORD_TYPE long int
|
||||
# define __UWORD_TYPE unsigned long int
|
||||
# define __SLONG32_TYPE int
|
||||
# define __ULONG32_TYPE unsigned int
|
||||
# define __S64_TYPE long int
|
||||
# define __U64_TYPE unsigned long int
|
||||
#else
|
||||
# error
|
||||
#endif
|
||||
#include <bits/typesizes.h> /* Defines __*_T_TYPE macros. */
|
||||
|
||||
/* We want __extension__ before typedef's that use nonstandard base types
|
||||
such as `long long' in C89 mode. */
|
||||
#define __STD_TYPE __extension__ typedef
|
||||
|
||||
|
||||
__STD_TYPE __DEV_T_TYPE __dev_t; /* Type of device numbers. */
|
||||
__STD_TYPE __UID_T_TYPE __uid_t; /* Type of user identifications. */
|
||||
__STD_TYPE __GID_T_TYPE __gid_t; /* Type of group identifications. */
|
||||
__STD_TYPE __INO_T_TYPE __ino_t; /* Type of file serial numbers. */
|
||||
__STD_TYPE __INO64_T_TYPE __ino64_t; /* Type of file serial numbers (LFS).*/
|
||||
__STD_TYPE __MODE_T_TYPE __mode_t; /* Type of file attribute bitmasks. */
|
||||
__STD_TYPE __NLINK_T_TYPE __nlink_t; /* Type of file link counts. */
|
||||
__STD_TYPE __OFF_T_TYPE __off_t; /* Type of file sizes and offsets. */
|
||||
__STD_TYPE __OFF64_T_TYPE __off64_t; /* Type of file sizes and offsets (LFS). */
|
||||
__STD_TYPE __PID_T_TYPE __pid_t; /* Type of process identifications. */
|
||||
__STD_TYPE __FSID_T_TYPE __fsid_t; /* Type of file system IDs. */
|
||||
__STD_TYPE __CLOCK_T_TYPE __clock_t; /* Type of CPU usage counts. */
|
||||
__STD_TYPE __RLIM_T_TYPE __rlim_t; /* Type for resource measurement. */
|
||||
__STD_TYPE __RLIM64_T_TYPE __rlim64_t; /* Type for resource measurement (LFS). */
|
||||
__STD_TYPE __ID_T_TYPE __id_t; /* General type for IDs. */
|
||||
__STD_TYPE __TIME_T_TYPE __time_t; /* Seconds since the Epoch. */
|
||||
__STD_TYPE __USECONDS_T_TYPE __useconds_t; /* Count of microseconds. */
|
||||
__STD_TYPE __SUSECONDS_T_TYPE __suseconds_t; /* Signed count of microseconds. */
|
||||
|
||||
__STD_TYPE __DADDR_T_TYPE __daddr_t; /* The type of a disk address. */
|
||||
__STD_TYPE __SWBLK_T_TYPE __swblk_t; /* Type of a swap block maybe? */
|
||||
__STD_TYPE __KEY_T_TYPE __key_t; /* Type of an IPC key. */
|
||||
|
||||
/* Clock ID used in clock and timer functions. */
|
||||
__STD_TYPE __CLOCKID_T_TYPE __clockid_t;
|
||||
|
||||
/* Timer ID returned by `timer_create'. */
|
||||
__STD_TYPE __TIMER_T_TYPE __timer_t;
|
||||
|
||||
/* Type to represent block size. */
|
||||
__STD_TYPE __BLKSIZE_T_TYPE __blksize_t;
|
||||
|
||||
/* Types from the Large File Support interface. */
|
||||
|
||||
/* Type to count number of disk blocks. */
|
||||
__STD_TYPE __BLKCNT_T_TYPE __blkcnt_t;
|
||||
__STD_TYPE __BLKCNT64_T_TYPE __blkcnt64_t;
|
||||
|
||||
/* Type to count file system blocks. */
|
||||
__STD_TYPE __FSBLKCNT_T_TYPE __fsblkcnt_t;
|
||||
__STD_TYPE __FSBLKCNT64_T_TYPE __fsblkcnt64_t;
|
||||
|
||||
/* Type to count file system nodes. */
|
||||
__STD_TYPE __FSFILCNT_T_TYPE __fsfilcnt_t;
|
||||
__STD_TYPE __FSFILCNT64_T_TYPE __fsfilcnt64_t;
|
||||
|
||||
__STD_TYPE __SSIZE_T_TYPE __ssize_t; /* Type of a byte count, or error. */
|
||||
|
||||
/* These few don't really vary by system, they always correspond
|
||||
to one of the other defined types. */
|
||||
typedef __off64_t __loff_t; /* Type of file sizes and offsets (LFS). */
|
||||
typedef __quad_t *__qaddr_t;
|
||||
typedef char *__caddr_t;
|
||||
|
||||
/* Duplicates info from stdint.h but this is used in unistd.h. */
|
||||
__STD_TYPE __SWORD_TYPE __intptr_t;
|
||||
|
||||
/* Duplicate info from sys/socket.h. */
|
||||
__STD_TYPE __U32_TYPE __socklen_t;
|
||||
|
||||
|
||||
#undef __STD_TYPE
|
||||
|
||||
#endif /* bits/types.h */
|
||||
@@ -1,104 +0,0 @@
|
||||
/* Definitions of status bits for `wait' et al.
|
||||
Copyright (C) 1992, 1994, 1996, 1997, 2000 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. */
|
||||
|
||||
#if !defined _SYS_WAIT_H && !defined _STDLIB_H
|
||||
# error "Never include <bits/waitstatus.h> directly; use <sys/wait.h> instead."
|
||||
#endif
|
||||
|
||||
|
||||
/* Everything extant so far uses these same bits. */
|
||||
|
||||
|
||||
/* If WIFEXITED(STATUS), the low-order 8 bits of the status. */
|
||||
#define __WEXITSTATUS(status) (((status) & 0xff00) >> 8)
|
||||
|
||||
/* If WIFSIGNALED(STATUS), the terminating signal. */
|
||||
#define __WTERMSIG(status) ((status) & 0x7f)
|
||||
|
||||
/* If WIFSTOPPED(STATUS), the signal that stopped the child. */
|
||||
#define __WSTOPSIG(status) __WEXITSTATUS(status)
|
||||
|
||||
/* Nonzero if STATUS indicates normal termination. */
|
||||
#define __WIFEXITED(status) (__WTERMSIG(status) == 0)
|
||||
|
||||
/* Nonzero if STATUS indicates termination by a signal. */
|
||||
#ifdef __GNUC__
|
||||
# define __WIFSIGNALED(status) \
|
||||
(__extension__ ({ int __status = (status); \
|
||||
!__WIFSTOPPED(__status) && !__WIFEXITED(__status); }))
|
||||
#else /* Not GCC. */
|
||||
# define __WIFSIGNALED(status) (!__WIFSTOPPED(status) && !__WIFEXITED(status))
|
||||
#endif /* GCC. */
|
||||
|
||||
/* Nonzero if STATUS indicates the child is stopped. */
|
||||
#define __WIFSTOPPED(status) (((status) & 0xff) == 0x7f)
|
||||
|
||||
/* Nonzero if STATUS indicates the child dumped core. */
|
||||
#define __WCOREDUMP(status) ((status) & __WCOREFLAG)
|
||||
|
||||
/* Macros for constructing status values. */
|
||||
#define __W_EXITCODE(ret, sig) ((ret) << 8 | (sig))
|
||||
#define __W_STOPCODE(sig) ((sig) << 8 | 0x7f)
|
||||
#define __WCOREFLAG 0x80
|
||||
|
||||
|
||||
#ifdef __USE_BSD
|
||||
|
||||
# include <endian.h>
|
||||
|
||||
union wait
|
||||
{
|
||||
int w_status;
|
||||
struct
|
||||
{
|
||||
# if __BYTE_ORDER == __LITTLE_ENDIAN
|
||||
unsigned int __w_termsig:7; /* Terminating signal. */
|
||||
unsigned int __w_coredump:1; /* Set if dumped core. */
|
||||
unsigned int __w_retcode:8; /* Return code if exited normally. */
|
||||
unsigned int:16;
|
||||
# endif /* Little endian. */
|
||||
# if __BYTE_ORDER == __BIG_ENDIAN
|
||||
unsigned int:16;
|
||||
unsigned int __w_retcode:8;
|
||||
unsigned int __w_coredump:1;
|
||||
unsigned int __w_termsig:7;
|
||||
# endif /* Big endian. */
|
||||
} __wait_terminated;
|
||||
struct
|
||||
{
|
||||
# if __BYTE_ORDER == __LITTLE_ENDIAN
|
||||
unsigned int __w_stopval:8; /* W_STOPPED if stopped. */
|
||||
unsigned int __w_stopsig:8; /* Stopping signal. */
|
||||
unsigned int:16;
|
||||
# endif /* Little endian. */
|
||||
# if __BYTE_ORDER == __BIG_ENDIAN
|
||||
unsigned int:16;
|
||||
unsigned int __w_stopsig:8; /* Stopping signal. */
|
||||
unsigned int __w_stopval:8; /* W_STOPPED if stopped. */
|
||||
# endif /* Big endian. */
|
||||
} __wait_stopped;
|
||||
};
|
||||
|
||||
# define w_termsig __wait_terminated.__w_termsig
|
||||
# define w_coredump __wait_terminated.__w_coredump
|
||||
# define w_retcode __wait_terminated.__w_retcode
|
||||
# define w_stopsig __wait_stopped.__w_stopsig
|
||||
# define w_stopval __wait_stopped.__w_stopval
|
||||
|
||||
#endif /* Use BSD. */
|
||||
@@ -0,0 +1 @@
|
||||
The C stubs add-on version 2.1.2.
|
||||
@@ -0,0 +1,482 @@
|
||||
GNU LIBRARY GENERAL PUBLIC LICENSE
|
||||
Version 2, June 1991
|
||||
|
||||
Copyright (C) 1991 Free Software Foundation, Inc.
|
||||
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
of this license document, but changing it is not allowed.
|
||||
|
||||
[This is the first released version of the library GPL. It is
|
||||
numbered 2 because it goes with version 2 of the ordinary GPL.]
|
||||
|
||||
Preamble
|
||||
|
||||
The licenses for most software are designed to take away your
|
||||
freedom to share and change it. By contrast, the GNU General Public
|
||||
Licenses are intended to guarantee your freedom to share and change
|
||||
free software--to make sure the software is free for all its users.
|
||||
|
||||
This license, the Library General Public License, applies to some
|
||||
specially designated Free Software Foundation software, and to any
|
||||
other libraries whose authors decide to use it. You can use it for
|
||||
your libraries, too.
|
||||
|
||||
When we speak of free software, we are referring to freedom, not
|
||||
price. Our General Public Licenses are designed to make sure that you
|
||||
have the freedom to distribute copies of free software (and charge for
|
||||
this service if you wish), that you receive source code or can get it
|
||||
if you want it, that you can change the software or use pieces of it
|
||||
in new free programs; and that you know you can do these things.
|
||||
|
||||
To protect your rights, we need to make restrictions that forbid
|
||||
anyone to deny you these rights or to ask you to surrender the rights.
|
||||
These restrictions translate to certain responsibilities for you if
|
||||
you distribute copies of the library, or if you modify it.
|
||||
|
||||
For example, if you distribute copies of the library, whether gratis
|
||||
or for a fee, you must give the recipients all the rights that we gave
|
||||
you. You must make sure that they, too, receive or can get the source
|
||||
code. If you link a program with the library, you must provide
|
||||
complete object files to the recipients so that they can relink them
|
||||
with the library, after making changes to the library and recompiling
|
||||
it. And you must show them these terms so they know their rights.
|
||||
|
||||
Our method of protecting your rights has two steps: (1) copyright
|
||||
the library, and (2) offer you this license which gives you legal
|
||||
permission to copy, distribute and/or modify the library.
|
||||
|
||||
Also, for each distributor's protection, we want to make certain
|
||||
that everyone understands that there is no warranty for this free
|
||||
library. If the library is modified by someone else and passed on, we
|
||||
want its recipients to know that what they have is not the original
|
||||
version, so that any problems introduced by others will not reflect on
|
||||
the original authors' reputations.
|
||||
|
||||
Finally, any free program is threatened constantly by software
|
||||
patents. We wish to avoid the danger that companies distributing free
|
||||
software will individually obtain patent licenses, thus in effect
|
||||
transforming the program into proprietary software. To prevent this,
|
||||
we have made it clear that any patent must be licensed for everyone's
|
||||
free use or not licensed at all.
|
||||
|
||||
Most GNU software, including some libraries, is covered by the ordinary
|
||||
GNU General Public License, which was designed for utility programs. This
|
||||
license, the GNU Library General Public License, applies to certain
|
||||
designated libraries. This license is quite different from the ordinary
|
||||
one; be sure to read it in full, and don't assume that anything in it is
|
||||
the same as in the ordinary license.
|
||||
|
||||
The reason we have a separate public license for some libraries is that
|
||||
they blur the distinction we usually make between modifying or adding to a
|
||||
program and simply using it. Linking a program with a library, without
|
||||
changing the library, is in some sense simply using the library, and is
|
||||
analogous to running a utility program or application program. However, in
|
||||
a textual and legal sense, the linked executable is a combined work, a
|
||||
derivative of the original library, and the ordinary General Public License
|
||||
treats it as such.
|
||||
|
||||
Because of this blurred distinction, using the ordinary General
|
||||
Public License for libraries did not effectively promote software
|
||||
sharing, because most developers did not use the libraries. We
|
||||
concluded that weaker conditions might promote sharing better.
|
||||
|
||||
However, unrestricted linking of non-free programs would deprive the
|
||||
users of those programs of all benefit from the free status of the
|
||||
libraries themselves. This Library General Public License is intended to
|
||||
permit developers of non-free programs to use free libraries, while
|
||||
preserving your freedom as a user of such programs to change the free
|
||||
libraries that are incorporated in them. (We have not seen how to achieve
|
||||
this as regards changes in header files, but we have achieved it as regards
|
||||
changes in the actual functions of the Library.) The hope is that this
|
||||
will lead to faster development of free libraries.
|
||||
|
||||
The precise terms and conditions for copying, distribution and
|
||||
modification follow. Pay close attention to the difference between a
|
||||
"work based on the library" and a "work that uses the library". The
|
||||
former contains code derived from the library, while the latter only
|
||||
works together with the library.
|
||||
|
||||
Note that it is possible for a library to be covered by the ordinary
|
||||
General Public License rather than by this special one.
|
||||
|
||||
GNU LIBRARY GENERAL PUBLIC LICENSE
|
||||
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
||||
|
||||
0. This License Agreement applies to any software library which
|
||||
contains a notice placed by the copyright holder or other authorized
|
||||
party saying it may be distributed under the terms of this Library
|
||||
General Public License (also called "this License"). Each licensee is
|
||||
addressed as "you".
|
||||
|
||||
A "library" means a collection of software functions and/or data
|
||||
prepared so as to be conveniently linked with application programs
|
||||
(which use some of those functions and data) to form executables.
|
||||
|
||||
The "Library", below, refers to any such software library or work
|
||||
which has been distributed under these terms. A "work based on the
|
||||
Library" means either the Library or any derivative work under
|
||||
copyright law: that is to say, a work containing the Library or a
|
||||
portion of it, either verbatim or with modifications and/or translated
|
||||
straightforwardly into another language. (Hereinafter, translation is
|
||||
included without limitation in the term "modification".)
|
||||
|
||||
"Source code" for a work means the preferred form of the work for
|
||||
making modifications to it. For a library, complete source code means
|
||||
all the source code for all modules it contains, plus any associated
|
||||
interface definition files, plus the scripts used to control compilation
|
||||
and installation of the library.
|
||||
|
||||
Activities other than copying, distribution and modification are not
|
||||
covered by this License; they are outside its scope. The act of
|
||||
running a program using the Library is not restricted, and output from
|
||||
such a program is covered only if its contents constitute a work based
|
||||
on the Library (independent of the use of the Library in a tool for
|
||||
writing it). Whether that is true depends on what the Library does
|
||||
and what the program that uses the Library does.
|
||||
|
||||
1. You may copy and distribute verbatim copies of the Library's
|
||||
complete source code as you receive it, in any medium, provided that
|
||||
you conspicuously and appropriately publish on each copy an
|
||||
appropriate copyright notice and disclaimer of warranty; keep intact
|
||||
all the notices that refer to this License and to the absence of any
|
||||
warranty; and distribute a copy of this License along with the
|
||||
Library.
|
||||
|
||||
You may charge a fee for the physical act of transferring a copy,
|
||||
and you may at your option offer warranty protection in exchange for a
|
||||
fee.
|
||||
|
||||
2. You may modify your copy or copies of the Library or any portion
|
||||
of it, thus forming a work based on the Library, and copy and
|
||||
distribute such modifications or work under the terms of Section 1
|
||||
above, provided that you also meet all of these conditions:
|
||||
|
||||
a) The modified work must itself be a software library.
|
||||
|
||||
b) You must cause the files modified to carry prominent notices
|
||||
stating that you changed the files and the date of any change.
|
||||
|
||||
c) You must cause the whole of the work to be licensed at no
|
||||
charge to all third parties under the terms of this License.
|
||||
|
||||
d) If a facility in the modified Library refers to a function or a
|
||||
table of data to be supplied by an application program that uses
|
||||
the facility, other than as an argument passed when the facility
|
||||
is invoked, then you must make a good faith effort to ensure that,
|
||||
in the event an application does not supply such function or
|
||||
table, the facility still operates, and performs whatever part of
|
||||
its purpose remains meaningful.
|
||||
|
||||
(For example, a function in a library to compute square roots has
|
||||
a purpose that is entirely well-defined independent of the
|
||||
application. Therefore, Subsection 2d requires that any
|
||||
application-supplied function or table used by this function must
|
||||
be optional: if the application does not supply it, the square
|
||||
root function must still compute square roots.)
|
||||
|
||||
These requirements apply to the modified work as a whole. If
|
||||
identifiable sections of that work are not derived from the Library,
|
||||
and can be reasonably considered independent and separate works in
|
||||
themselves, then this License, and its terms, do not apply to those
|
||||
sections when you distribute them as separate works. But when you
|
||||
distribute the same sections as part of a whole which is a work based
|
||||
on the Library, the distribution of the whole must be on the terms of
|
||||
this License, whose permissions for other licensees extend to the
|
||||
entire whole, and thus to each and every part regardless of who wrote
|
||||
it.
|
||||
|
||||
Thus, it is not the intent of this section to claim rights or contest
|
||||
your rights to work written entirely by you; rather, the intent is to
|
||||
exercise the right to control the distribution of derivative or
|
||||
collective works based on the Library.
|
||||
|
||||
In addition, mere aggregation of another work not based on the Library
|
||||
with the Library (or with a work based on the Library) on a volume of
|
||||
a storage or distribution medium does not bring the other work under
|
||||
the scope of this License.
|
||||
|
||||
3. You may opt to apply the terms of the ordinary GNU General Public
|
||||
License instead of this License to a given copy of the Library. To do
|
||||
this, you must alter all the notices that refer to this License, so
|
||||
that they refer to the ordinary GNU General Public License, version 2,
|
||||
instead of to this License. (If a newer version than version 2 of the
|
||||
ordinary GNU General Public License has appeared, then you can specify
|
||||
that version instead if you wish.) Do not make any other change in
|
||||
these notices.
|
||||
|
||||
Once this change is made in a given copy, it is irreversible for
|
||||
that copy, so the ordinary GNU General Public License applies to all
|
||||
subsequent copies and derivative works made from that copy.
|
||||
|
||||
This option is useful when you wish to copy part of the code of
|
||||
the Library into a program that is not a library.
|
||||
|
||||
4. You may copy and distribute the Library (or a portion or
|
||||
derivative of it, under Section 2) in object code or executable form
|
||||
under the terms of Sections 1 and 2 above provided that you accompany
|
||||
it with the complete corresponding machine-readable source code, which
|
||||
must be distributed under the terms of Sections 1 and 2 above on a
|
||||
medium customarily used for software interchange.
|
||||
|
||||
If distribution of object code is made by offering access to copy
|
||||
from a designated place, then offering equivalent access to copy the
|
||||
source code from the same place satisfies the requirement to
|
||||
distribute the source code, even though third parties are not
|
||||
compelled to copy the source along with the object code.
|
||||
|
||||
5. A program that contains no derivative of any portion of the
|
||||
Library, but is designed to work with the Library by being compiled or
|
||||
linked with it, is called a "work that uses the Library". Such a
|
||||
work, in isolation, is not a derivative work of the Library, and
|
||||
therefore falls outside the scope of this License.
|
||||
|
||||
However, linking a "work that uses the Library" with the Library
|
||||
creates an executable that is a derivative of the Library (because it
|
||||
contains portions of the Library), rather than a "work that uses the
|
||||
library". The executable is therefore covered by this License.
|
||||
Section 6 states terms for distribution of such executables.
|
||||
|
||||
When a "work that uses the Library" uses material from a header file
|
||||
that is part of the Library, the object code for the work may be a
|
||||
derivative work of the Library even though the source code is not.
|
||||
Whether this is true is especially significant if the work can be
|
||||
linked without the Library, or if the work is itself a library. The
|
||||
threshold for this to be true is not precisely defined by law.
|
||||
|
||||
If such an object file uses only numerical parameters, data
|
||||
structure layouts and accessors, and small macros and small inline
|
||||
functions (ten lines or less in length), then the use of the object
|
||||
file is unrestricted, regardless of whether it is legally a derivative
|
||||
work. (Executables containing this object code plus portions of the
|
||||
Library will still fall under Section 6.)
|
||||
|
||||
Otherwise, if the work is a derivative of the Library, you may
|
||||
distribute the object code for the work under the terms of Section 6.
|
||||
Any executables containing that work also fall under Section 6,
|
||||
whether or not they are linked directly with the Library itself.
|
||||
|
||||
6. As an exception to the Sections above, you may also compile or
|
||||
link a "work that uses the Library" with the Library to produce a
|
||||
work containing portions of the Library, and distribute that work
|
||||
under terms of your choice, provided that the terms permit
|
||||
modification of the work for the customer's own use and reverse
|
||||
engineering for debugging such modifications.
|
||||
|
||||
You must give prominent notice with each copy of the work that the
|
||||
Library is used in it and that the Library and its use are covered by
|
||||
this License. You must supply a copy of this License. If the work
|
||||
during execution displays copyright notices, you must include the
|
||||
copyright notice for the Library among them, as well as a reference
|
||||
directing the user to the copy of this License. Also, you must do one
|
||||
of these things:
|
||||
|
||||
a) Accompany the work with the complete corresponding
|
||||
machine-readable source code for the Library including whatever
|
||||
changes were used in the work (which must be distributed under
|
||||
Sections 1 and 2 above); and, if the work is an executable linked
|
||||
with the Library, with the complete machine-readable "work that
|
||||
uses the Library", as object code and/or source code, so that the
|
||||
user can modify the Library and then relink to produce a modified
|
||||
executable containing the modified Library. (It is understood
|
||||
that the user who changes the contents of definitions files in the
|
||||
Library will not necessarily be able to recompile the application
|
||||
to use the modified definitions.)
|
||||
|
||||
b) Accompany the work with a written offer, valid for at
|
||||
least three years, to give the same user the materials
|
||||
specified in Subsection 6a, above, for a charge no more
|
||||
than the cost of performing this distribution.
|
||||
|
||||
c) If distribution of the work is made by offering access to copy
|
||||
from a designated place, offer equivalent access to copy the above
|
||||
specified materials from the same place.
|
||||
|
||||
d) Verify that the user has already received a copy of these
|
||||
materials or that you have already sent this user a copy.
|
||||
|
||||
For an executable, the required form of the "work that uses the
|
||||
Library" must include any data and utility programs needed for
|
||||
reproducing the executable from it. However, as a special exception,
|
||||
the source code distributed need not include anything that is normally
|
||||
distributed (in either source or binary form) with the major
|
||||
components (compiler, kernel, and so on) of the operating system on
|
||||
which the executable runs, unless that component itself accompanies
|
||||
the executable.
|
||||
|
||||
It may happen that this requirement contradicts the license
|
||||
restrictions of other proprietary libraries that do not normally
|
||||
accompany the operating system. Such a contradiction means you cannot
|
||||
use both them and the Library together in an executable that you
|
||||
distribute.
|
||||
|
||||
7. You may place library facilities that are a work based on the
|
||||
Library side-by-side in a single library together with other library
|
||||
facilities not covered by this License, and distribute such a combined
|
||||
library, provided that the separate distribution of the work based on
|
||||
the Library and of the other library facilities is otherwise
|
||||
permitted, and provided that you do these two things:
|
||||
|
||||
a) Accompany the combined library with a copy of the same work
|
||||
based on the Library, uncombined with any other library
|
||||
facilities. This must be distributed under the terms of the
|
||||
Sections above.
|
||||
|
||||
b) Give prominent notice with the combined library of the fact
|
||||
that part of it is a work based on the Library, and explaining
|
||||
where to find the accompanying uncombined form of the same work.
|
||||
|
||||
8. You may not copy, modify, sublicense, link with, or distribute
|
||||
the Library except as expressly provided under this License. Any
|
||||
attempt otherwise to copy, modify, sublicense, link with, or
|
||||
distribute the Library is void, and will automatically terminate your
|
||||
rights under this License. However, parties who have received copies,
|
||||
or rights, from you under this License will not have their licenses
|
||||
terminated so long as such parties remain in full compliance.
|
||||
|
||||
9. You are not required to accept this License, since you have not
|
||||
signed it. However, nothing else grants you permission to modify or
|
||||
distribute the Library or its derivative works. These actions are
|
||||
prohibited by law if you do not accept this License. Therefore, by
|
||||
modifying or distributing the Library (or any work based on the
|
||||
Library), you indicate your acceptance of this License to do so, and
|
||||
all its terms and conditions for copying, distributing or modifying
|
||||
the Library or works based on it.
|
||||
|
||||
10. Each time you redistribute the Library (or any work based on the
|
||||
Library), the recipient automatically receives a license from the
|
||||
original licensor to copy, distribute, link with or modify the Library
|
||||
subject to these terms and conditions. You may not impose any further
|
||||
restrictions on the recipients' exercise of the rights granted herein.
|
||||
You are not responsible for enforcing compliance by third parties to
|
||||
this License.
|
||||
|
||||
11. If, as a consequence of a court judgment or allegation of patent
|
||||
infringement or for any other reason (not limited to patent issues),
|
||||
conditions are imposed on you (whether by court order, agreement or
|
||||
otherwise) that contradict the conditions of this License, they do not
|
||||
excuse you from the conditions of this License. If you cannot
|
||||
distribute so as to satisfy simultaneously your obligations under this
|
||||
License and any other pertinent obligations, then as a consequence you
|
||||
may not distribute the Library at all. For example, if a patent
|
||||
license would not permit royalty-free redistribution of the Library by
|
||||
all those who receive copies directly or indirectly through you, then
|
||||
the only way you could satisfy both it and this License would be to
|
||||
refrain entirely from distribution of the Library.
|
||||
|
||||
If any portion of this section is held invalid or unenforceable under any
|
||||
particular circumstance, the balance of the section is intended to apply,
|
||||
and the section as a whole is intended to apply in other circumstances.
|
||||
|
||||
It is not the purpose of this section to induce you to infringe any
|
||||
patents or other property right claims or to contest validity of any
|
||||
such claims; this section has the sole purpose of protecting the
|
||||
integrity of the free software distribution system which is
|
||||
implemented by public license practices. Many people have made
|
||||
generous contributions to the wide range of software distributed
|
||||
through that system in reliance on consistent application of that
|
||||
system; it is up to the author/donor to decide if he or she is willing
|
||||
to distribute software through any other system and a licensee cannot
|
||||
impose that choice.
|
||||
|
||||
This section is intended to make thoroughly clear what is believed to
|
||||
be a consequence of the rest of this License.
|
||||
|
||||
12. If the distribution and/or use of the Library is restricted in
|
||||
certain countries either by patents or by copyrighted interfaces, the
|
||||
original copyright holder who places the Library under this License may add
|
||||
an explicit geographical distribution limitation excluding those countries,
|
||||
so that distribution is permitted only in or among countries not thus
|
||||
excluded. In such case, this License incorporates the limitation as if
|
||||
written in the body of this License.
|
||||
|
||||
13. The Free Software Foundation may publish revised and/or new
|
||||
versions of the Library General Public License from time to time.
|
||||
Such new versions will be similar in spirit to the present version,
|
||||
but may differ in detail to address new problems or concerns.
|
||||
|
||||
Each version is given a distinguishing version number. If the Library
|
||||
specifies a version number of this License which applies to it and
|
||||
"any later version", you have the option of following the terms and
|
||||
conditions either of that version or of any later version published by
|
||||
the Free Software Foundation. If the Library does not specify a
|
||||
license version number, you may choose any version ever published by
|
||||
the Free Software Foundation.
|
||||
|
||||
14. If you wish to incorporate parts of the Library into other free
|
||||
programs whose distribution conditions are incompatible with these,
|
||||
write to the author to ask for permission. For software which is
|
||||
copyrighted by the Free Software Foundation, write to the Free
|
||||
Software Foundation; we sometimes make exceptions for this. Our
|
||||
decision will be guided by the two goals of preserving the free status
|
||||
of all derivatives of our free software and of promoting the sharing
|
||||
and reuse of software generally.
|
||||
|
||||
NO WARRANTY
|
||||
|
||||
15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
|
||||
WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
|
||||
EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
|
||||
OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY
|
||||
KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
|
||||
LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
|
||||
THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
|
||||
|
||||
16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
|
||||
WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
|
||||
AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU
|
||||
FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
|
||||
CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
|
||||
LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
|
||||
RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
|
||||
FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
|
||||
SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
|
||||
DAMAGES.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
Appendix: How to Apply These Terms to Your New Libraries
|
||||
|
||||
If you develop a new library, and you want it to be of the greatest
|
||||
possible use to the public, we recommend making it free software that
|
||||
everyone can redistribute and change. You can do so by permitting
|
||||
redistribution under these terms (or, alternatively, under the terms of the
|
||||
ordinary General Public License).
|
||||
|
||||
To apply these terms, attach the following notices to the library. It is
|
||||
safest to attach them to the start of each source file to most effectively
|
||||
convey the exclusion of warranty; and each file should have at least the
|
||||
"copyright" line and a pointer to where the full notice is found.
|
||||
|
||||
<one line to give the library's name and a brief idea of what it does.>
|
||||
Copyright (C) <year> <name of author>
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Library General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2 of the License, or (at your option) any later version.
|
||||
|
||||
This 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
|
||||
Library General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Library General Public
|
||||
License along with this library; if not, write to the Free
|
||||
Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
|
||||
MA 02111-1307, USA
|
||||
|
||||
Also add information on how to contact you by electronic and paper mail.
|
||||
|
||||
You should also get your employer (if you work as a programmer) or your
|
||||
school, if any, to sign a "copyright disclaimer" for the library, if
|
||||
necessary. Here is a sample; alter the names:
|
||||
|
||||
Yoyodyne, Inc., hereby disclaims all copyright interest in the
|
||||
library `Frob' (a library for tweaking knobs) written by James Random Hacker.
|
||||
|
||||
<signature of Ty Coon>, 1 April 1990
|
||||
Ty Coon, President of Vice
|
||||
|
||||
That's all there is to it!
|
||||
@@ -0,0 +1,42 @@
|
||||
2001-08-07 Jakub Jelinek <jakub@redhat.com>
|
||||
|
||||
* gconv_stubs.c (__gconv_lookup_alias): Remove.
|
||||
(__gconv_NOOP, __gconv_compare_alias, __gconv_release_cache,
|
||||
__gconv_release_step): New.
|
||||
|
||||
2001-06-07 Jakub Jelinek <jakub@redhat.com>
|
||||
|
||||
* gconv_stubs.c (__gconv_lookup_alias): New.
|
||||
|
||||
2000-02-27 Cristian Gafton <gafton@redhat.com>
|
||||
|
||||
* gconv_stubs.c: Return __gconv_OK for:
|
||||
__gconv_transform_ascii_internal
|
||||
__gconv_transform_ucs2little_internal
|
||||
__gconv_transform_utf16_internal
|
||||
__gconv_transform_utf8_internal
|
||||
__gconv_transform_ucs2_internal
|
||||
|
||||
2000-02-25 Cristian Gafton <gafton@redhat.com>
|
||||
|
||||
* gconv_stubs.c: add __c_stubs_is_compiled_in so we can detect when
|
||||
the library is linked in.
|
||||
|
||||
Wed Dec 8 13:47:25 1999 Ivan Brunello <ivan.brunello@tiscalinet.it>
|
||||
|
||||
* Makefile (extra-objs): Changed stubs.o to gconv_stubs.o.
|
||||
|
||||
Sun Dec 5 11:32:17 1999 H.J. Lu <hjl@gnu.org>
|
||||
|
||||
* gconv_stubs.c: Renamed from stubs.c.
|
||||
Support glibc 2.1.x.
|
||||
|
||||
Mon Aug 23 16:42:05 1999 H.J. Lu <hjl@gnu.org>
|
||||
|
||||
* Banner: New.
|
||||
* COPYING.LIB: Likewise.
|
||||
* Makefile: Likewise.
|
||||
* README: Likewise.
|
||||
* configure: Likewise.
|
||||
* stubs.c: Likewise.
|
||||
* test-stdio.c: Likewise.
|
||||
@@ -0,0 +1,46 @@
|
||||
# Copyright (C) 1999 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 Library General Public License as
|
||||
# published by the Free Software Foundation; either version 2 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
|
||||
# Library General Public License for more details.
|
||||
|
||||
# You should have received a copy of the GNU Library General Public
|
||||
# License along with the GNU C Library; see the file COPYING.LIB. If not,
|
||||
# write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
# Boston, MA 02111-1307, USA.
|
||||
|
||||
#
|
||||
# Sub-makefile for the C stub add-on library.
|
||||
#
|
||||
subdir := c_stubs
|
||||
|
||||
tests-static := test-stdio
|
||||
tests := $(tests-static)
|
||||
|
||||
libc_stubs-objs := gconv_stubs.o
|
||||
|
||||
install-lib := libc_stubs.a
|
||||
non-lib.a := libc_stubs.a
|
||||
|
||||
extra-objs := gconv_stubs.o libc_stubs.a
|
||||
|
||||
include ../Makeconfig
|
||||
|
||||
CPPFLAGS += -I../iconv
|
||||
|
||||
include ../Rules
|
||||
|
||||
$(objpfx)libc_stubs.a: $(addprefix $(objpfx), $(libc_stubs-objs))
|
||||
-rm -f $@
|
||||
$(CC) -nostdlib -nostartfiles -r -o $@ $^
|
||||
|
||||
lib: $(objpfx)libc_stubs.a
|
||||
|
||||
$(objpfx)test-stdio: $(objpfx)libc_stubs.a
|
||||
@@ -0,0 +1,8 @@
|
||||
This is a stub add-on library for the GNU C library version 2.1.2 and
|
||||
above. It is used to create the smaller static binaries by stubbing
|
||||
out the gconv related functions. The resulting binaries may not have
|
||||
all the functionalities.
|
||||
|
||||
H.J. Lu
|
||||
hjl@gnu.org
|
||||
12/05/1999
|
||||
+3
@@ -0,0 +1,3 @@
|
||||
# This is only to keep the GNU C library configure mechanism happy.
|
||||
# This is a shell script fragment sourced by the main configure script.
|
||||
# We have nothing we need to add here.
|
||||
@@ -0,0 +1,126 @@
|
||||
/* Provide gconv stub functions for the minimum static binaries.
|
||||
Copyright (C) 1999, 2001, 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
|
||||
modify it under the terms of the GNU Library General Public License as
|
||||
published by the Free Software Foundation; either version 2 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
|
||||
Library General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Library General Public
|
||||
License along with the GNU C Library; see the file COPYING.LIB. If not,
|
||||
write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
Boston, MA 02111-1307, USA. */
|
||||
|
||||
#include <features.h>
|
||||
#include <string.h>
|
||||
#include <wchar.h>
|
||||
#include <bits/libc-lock.h>
|
||||
#if __GNUC_PREREQ(3, 3)
|
||||
# include <gconv_int.h>
|
||||
#else
|
||||
# include <gconv.h>
|
||||
#endif
|
||||
|
||||
__libc_lock_define_initialized (, __gconv_lock)
|
||||
|
||||
/* hack for self identification */
|
||||
int __c_stubs_is_compiled_in;
|
||||
|
||||
/* Don't drag in the dynamic linker. */
|
||||
void *__libc_stack_end;
|
||||
|
||||
int attribute_hidden
|
||||
__gconv_OK (void)
|
||||
{
|
||||
#if __GLIBC__ > 2 || __GLIBC_MINOR__ > 1
|
||||
return __GCONV_OK;
|
||||
#else
|
||||
return GCONV_OK;
|
||||
#endif
|
||||
}
|
||||
|
||||
int attribute_hidden
|
||||
__gconv_NOCONV (void)
|
||||
{
|
||||
#if __GLIBC__ > 2 || __GLIBC_MINOR__ > 1
|
||||
return __GCONV_NOCONV;
|
||||
#else
|
||||
return GCONV_NOCONV;
|
||||
#endif
|
||||
}
|
||||
|
||||
void attribute_hidden
|
||||
__gconv_NOOP (void)
|
||||
{
|
||||
}
|
||||
|
||||
int
|
||||
internal_function
|
||||
__gconv_compare_alias (const char *name1, const char *name2)
|
||||
{
|
||||
return strcmp (name1, name2);
|
||||
}
|
||||
|
||||
wint_t
|
||||
__gconv_btwoc_ascii (struct __gconv_step *step, unsigned char c)
|
||||
{
|
||||
if (c < 0x80)
|
||||
return c;
|
||||
else
|
||||
return WEOF;
|
||||
}
|
||||
|
||||
|
||||
#if __GNUC_PREREQ(3, 3)
|
||||
# undef strong_alias
|
||||
# define strong_alias(impl, name) \
|
||||
__typeof (name) name __attribute__ ((alias (#impl)))
|
||||
#endif
|
||||
|
||||
strong_alias (__gconv_OK,
|
||||
__gconv_close_transform);
|
||||
strong_alias (__gconv_OK,
|
||||
__gconv_close);
|
||||
|
||||
strong_alias (__gconv_NOCONV,
|
||||
__gconv);
|
||||
strong_alias (__gconv_NOCONV,
|
||||
__gconv_find_transform);
|
||||
strong_alias (__gconv_NOCONV,
|
||||
__gconv_open);
|
||||
|
||||
/* These transformations should not fail in normal conditions */
|
||||
strong_alias (__gconv_OK,
|
||||
__gconv_transform_ascii_internal);
|
||||
strong_alias (__gconv_OK,
|
||||
__gconv_transform_utf16_internal);
|
||||
strong_alias (__gconv_OK,
|
||||
__gconv_transform_utf8_internal);
|
||||
strong_alias (__gconv_OK,
|
||||
__gconv_transform_ucs2_internal);
|
||||
|
||||
/* We can assume no conversion for these ones */
|
||||
strong_alias (__gconv_NOCONV,
|
||||
__gconv_transform_internal_ascii);
|
||||
strong_alias (__gconv_NOCONV,
|
||||
__gconv_transform_internal_ucs2);
|
||||
strong_alias (__gconv_NOCONV,
|
||||
__gconv_transform_internal_ucs4);
|
||||
strong_alias (__gconv_NOCONV,
|
||||
__gconv_transform_internal_utf16);
|
||||
strong_alias (__gconv_NOCONV,
|
||||
__gconv_transform_internal_utf8);
|
||||
|
||||
strong_alias (__gconv_NOCONV,
|
||||
__gconv_transliterate);
|
||||
|
||||
strong_alias (__gconv_NOOP,
|
||||
__gconv_release_cache);
|
||||
strong_alias (__gconv_NOOP,
|
||||
__gconv_release_step);
|
||||
@@ -0,0 +1,8 @@
|
||||
#include <stdio.h>
|
||||
|
||||
int
|
||||
main (void)
|
||||
{
|
||||
printf ("Hello world\n");
|
||||
return 0;
|
||||
}
|
||||
@@ -6842,15 +6842,10 @@ rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
|
||||
echo "${ECHO_T}$have_selinux" >&6
|
||||
fi
|
||||
|
||||
if test x$with_selinux = xauto ; then
|
||||
if test x$with_selinux = xyes ; then
|
||||
if test x$have_selinux = xno ; then
|
||||
{ echo "$as_me:$LINENO: WARNING: Sufficiently new SELinux library not found" >&5
|
||||
echo "$as_me: WARNING: Sufficiently new SELinux library not found" >&2;}
|
||||
fi
|
||||
else
|
||||
if test x$have_selinux = xno ; then
|
||||
{ { echo "$as_me:$LINENO: error: SELinux explicitly required, and SELinux library not found" >&5
|
||||
echo "$as_me: error: SELinux explicitly required, and SELinux library not found" >&2;}
|
||||
{ { echo "$as_me:$LINENO: error: SELinux explicitly required, but sufficiently recent SELinux library not found" >&5
|
||||
echo "$as_me: error: SELinux explicitly required, but sufficiently recent SELinux library not found" >&2;}
|
||||
{ (exit 1); exit 1; }; }
|
||||
fi
|
||||
fi
|
||||
|
||||
@@ -44,6 +44,24 @@ extern void (*__init_array_start []) (void) attribute_hidden;
|
||||
extern void (*__init_array_end []) (void) attribute_hidden;
|
||||
extern void (*__fini_array_start []) (void) attribute_hidden;
|
||||
extern void (*__fini_array_end []) (void) attribute_hidden;
|
||||
|
||||
# if defined HAVE_VISIBILITY_ATTRIBUTE \
|
||||
&& (defined SHARED || defined LIBC_NONSHARED)
|
||||
# define hidden_undef_2(x) #x
|
||||
# define hidden_undef_1(x) hidden_undef_2 (x)
|
||||
# define hidden_undef(x) \
|
||||
__asm (hidden_undef_1 (ASM_GLOBAL_DIRECTIVE) " " #x); \
|
||||
__asm (".hidden " #x);
|
||||
# else
|
||||
# define hidden_undef(x)
|
||||
# endif
|
||||
|
||||
hidden_undef (__preinit_array_start)
|
||||
hidden_undef (__preinit_array_end)
|
||||
hidden_undef (__init_array_start)
|
||||
hidden_undef (__init_array_end)
|
||||
hidden_undef (__fini_array_start)
|
||||
hidden_undef (__fini_array_end)
|
||||
#endif
|
||||
|
||||
/* These function symbols are provided for the .init/.fini section entry
|
||||
|
||||
+2
-1
@@ -19,7 +19,8 @@
|
||||
subdir := dlfcn
|
||||
headers := bits/dlfcn.h dlfcn.h
|
||||
extra-libs := libdl
|
||||
libdl-routines := dlopen dlclose dlsym dlvsym dlerror dladdr dladdr1 dlinfo
|
||||
libdl-routines := dlopen dlclose dlsym dlvsym dlerror dladdr dladdr1 dlinfo \
|
||||
dlmopen
|
||||
distribute := dlopenold.c glreflib1.c glreflib2.c failtestmod.c \
|
||||
defaultmod1.c defaultmod2.c errmsg1mod.c modatexit.c \
|
||||
modcxaatexit.c modstatic.c \
|
||||
|
||||
@@ -8,4 +8,7 @@ libdl {
|
||||
GLIBC_2.3.3 {
|
||||
dladdr1; dlinfo;
|
||||
}
|
||||
GLIBC_2.3.4 {
|
||||
dlmopen;
|
||||
}
|
||||
}
|
||||
|
||||
+15
-2
@@ -1,5 +1,5 @@
|
||||
/* User functions for run-time dynamic loading.
|
||||
Copyright (C) 1995-1999,2000,2001,2003 Free Software Foundation, Inc.
|
||||
Copyright (C) 1995-1999,2000,2001,2003,2004 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
|
||||
The GNU C Library is free software; you can redistribute it and/or
|
||||
@@ -39,6 +39,14 @@
|
||||
the run-time address of the symbol called NAME in the global scope
|
||||
is returned. */
|
||||
# define RTLD_DEFAULT ((void *) 0)
|
||||
|
||||
|
||||
/* Type for namespace indeces. */
|
||||
typedef long int Lmid_t;
|
||||
|
||||
/* Special namespace ID values. */
|
||||
# define LM_ID_BASE 0 /* Initial namespace. */
|
||||
# define LM_ID_NEWLM -1 /* For dlmopen: request new namespace. */
|
||||
#endif
|
||||
|
||||
|
||||
@@ -58,6 +66,9 @@ extern void *dlsym (void *__restrict __handle,
|
||||
__const char *__restrict __name) __THROW;
|
||||
|
||||
#ifdef __USE_GNU
|
||||
/* Like `dlopen', but request object to be allocated in a new namespace. */
|
||||
extern void *dlmopen (Lmid_t __nsid, __const char *__file, int __mode) __THROW;
|
||||
|
||||
/* Find the run-time address in the shared object HANDLE refers to
|
||||
of the symbol called NAME with VERSION. */
|
||||
extern void *dlvsym (void *__restrict __handle,
|
||||
@@ -114,6 +125,9 @@ extern int dlinfo (void *__restrict __handle,
|
||||
/* These are the possible values for the REQUEST argument to `dlinfo'. */
|
||||
enum
|
||||
{
|
||||
/* Treat ARG as `lmid_t *'; store namespace ID for HANDLE there. */
|
||||
RTLD_DI_LMID = 1,
|
||||
|
||||
/* Treat ARG as `struct link_map **';
|
||||
store the `struct link_map *' for HANDLE there. */
|
||||
RTLD_DI_LINKMAP = 2,
|
||||
@@ -130,7 +144,6 @@ enum
|
||||
expand $ORIGIN in this shared object's dependency file names. */
|
||||
RTLD_DI_ORIGIN = 6,
|
||||
|
||||
RTLD_DI_LMID = 1, /* Unsupported, defined by Solaris. */
|
||||
RTLD_DI_CONFIGADDR = 3 /* Unsupported, defined by Solaris. */
|
||||
};
|
||||
|
||||
|
||||
+11
-6
@@ -39,13 +39,15 @@ dlinfo_doit (void *argsblock)
|
||||
#if 0
|
||||
if (args->handle == RTLD_SELF)
|
||||
{
|
||||
Lmid_t nsid;
|
||||
|
||||
/* Find the highest-addressed object that CALLER is not below. */
|
||||
for (l = GL(dl_loaded); l != NULL; l = l->l_next)
|
||||
if (caller >= l->l_map_start && caller < l->l_map_end)
|
||||
/* There must be exactly one DSO for the range of the virtual
|
||||
memory. Otherwise something is really broken. */
|
||||
break;
|
||||
for (nsid = 0; nsid < DL_NNS; ++nsid)
|
||||
for (l = GL(dl_ns)[nsid]._ns_loaded; l != NULL; l = l->l_next)
|
||||
if (caller >= l->l_map_start && caller < l->l_map_end)
|
||||
/* There must be exactly one DSO for the range of the virtual
|
||||
memory. Otherwise something is really broken. */
|
||||
break;
|
||||
|
||||
if (l == NULL)
|
||||
GLRO(dl_signal_error) (0, NULL, NULL, N_("\
|
||||
@@ -55,12 +57,15 @@ RTLD_SELF used in code not dynamically loaded"));
|
||||
|
||||
switch (args->request)
|
||||
{
|
||||
case RTLD_DI_LMID:
|
||||
case RTLD_DI_CONFIGADDR:
|
||||
default:
|
||||
GLRO(dl_signal_error) (0, NULL, NULL, N_("unsupported dlinfo request"));
|
||||
break;
|
||||
|
||||
case RTLD_DI_LMID:
|
||||
*(Lmid_t *) args->arg = l->l_ns;
|
||||
break;
|
||||
|
||||
case RTLD_DI_LINKMAP:
|
||||
*(struct link_map **) args->arg = l;
|
||||
break;
|
||||
|
||||
@@ -0,0 +1,69 @@
|
||||
/* Load a shared object at run time.
|
||||
Copyright (C) 1995,96,97,98,99,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
|
||||
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 <dlfcn.h>
|
||||
#include <errno.h>
|
||||
#include <libintl.h>
|
||||
#include <stddef.h>
|
||||
#include <ldsodefs.h>
|
||||
|
||||
struct dlmopen_args
|
||||
{
|
||||
/* Namespace ID. */
|
||||
Lmid_t nsid;
|
||||
/* The arguments for dlopen_doit. */
|
||||
const char *file;
|
||||
int mode;
|
||||
/* The return value of dlopen_doit. */
|
||||
void *new;
|
||||
/* Address of the caller. */
|
||||
const void *caller;
|
||||
};
|
||||
|
||||
static void
|
||||
dlmopen_doit (void *a)
|
||||
{
|
||||
struct dlmopen_args *args = (struct dlmopen_args *) a;
|
||||
|
||||
/* Non-shared code has no support for multiple namespaces. */
|
||||
if (args->nsid != LM_ID_BASE)
|
||||
#ifdef SHARED
|
||||
/* If trying to open the link map for the main executable the namespace
|
||||
must be the main one. */
|
||||
if (args->file == NULL)
|
||||
#endif
|
||||
GLRO(dl_signal_error) (EINVAL, NULL, NULL, N_("invalid namespace"));
|
||||
|
||||
args->new = _dl_open (args->file ?: "", args->mode | __RTLD_DLOPEN,
|
||||
args->caller, args->nsid);
|
||||
}
|
||||
|
||||
|
||||
void *
|
||||
dlmopen (Lmid_t nsid, const char *file, int mode)
|
||||
{
|
||||
struct dlmopen_args args;
|
||||
args.nsid = nsid;
|
||||
args.file = file;
|
||||
args.mode = mode;
|
||||
args.caller = RETURN_ADDRESS (0);
|
||||
|
||||
return _dlerror_run (dlmopen_doit, &args) ? NULL : args.new;
|
||||
}
|
||||
static_link_warning (dlmopen)
|
||||
+11
-2
@@ -1,5 +1,5 @@
|
||||
/* Load a shared object at run time.
|
||||
Copyright (C) 1995,96,97,98,99,2000,2003 Free Software Foundation, Inc.
|
||||
Copyright (C) 1995,96,97,98,99,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
|
||||
@@ -31,13 +31,22 @@ struct dlopen_args
|
||||
const void *caller;
|
||||
};
|
||||
|
||||
|
||||
/* Non-shared code has no support for multiple namespaces. */
|
||||
#ifdef SHARED
|
||||
# define NS __LM_ID_CALLER
|
||||
#else
|
||||
# define NS LM_ID_BASE
|
||||
#endif
|
||||
|
||||
|
||||
static void
|
||||
dlopen_doit (void *a)
|
||||
{
|
||||
struct dlopen_args *args = (struct dlopen_args *) a;
|
||||
|
||||
args->new = _dl_open (args->file ?: "", args->mode | __RTLD_DLOPEN,
|
||||
args->caller);
|
||||
args->caller, args->file == NULL ? LM_ID_BASE : NS);
|
||||
}
|
||||
|
||||
|
||||
|
||||
+10
-2
@@ -1,5 +1,5 @@
|
||||
/* Load a shared object at run time.
|
||||
Copyright (C) 1995-1999, 2000 Free Software Foundation, Inc.
|
||||
Copyright (C) 1995-1999, 2000, 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
|
||||
@@ -37,13 +37,21 @@ struct dlopen_args
|
||||
};
|
||||
|
||||
|
||||
/* Non-shared code has no support for multiple namespaces. */
|
||||
#ifdef SHARED
|
||||
# define NS __LM_ID_CALLER
|
||||
#else
|
||||
# define NS LM_ID_BASE
|
||||
#endif
|
||||
|
||||
|
||||
static void
|
||||
dlopen_doit (void *a)
|
||||
{
|
||||
struct dlopen_args *args = (struct dlopen_args *) a;
|
||||
|
||||
args->new = _dl_open (args->file ?: "", args->mode | __RTLD_DLOPEN,
|
||||
args->caller);
|
||||
args->caller, args->file == NULL ? LM_ID_BASE : NS);
|
||||
}
|
||||
|
||||
extern void *__dlopen_nocheck (const char *file, int mode);
|
||||
|
||||
+19
-3
@@ -82,7 +82,8 @@ distribute := rtld-Rules \
|
||||
tst-array1.exp tst-array2.exp tst-array4.exp \
|
||||
tst-array2dep.c tst-piemod1.c \
|
||||
tst-execstack-mod.c tst-dlmodcount.c \
|
||||
check-textrel.c dl-sysdep.h test-dlopenrpathmod.c
|
||||
check-textrel.c dl-sysdep.h test-dlopenrpathmod.c \
|
||||
tst-deep1mod1.c tst-deep1mod2.c tst-deep1mod3.c
|
||||
|
||||
CFLAGS-dl-runtime.c = -fexceptions -fasynchronous-unwind-tables
|
||||
CFLAGS-dl-lookup.c = -fexceptions -fasynchronous-unwind-tables
|
||||
@@ -152,7 +153,8 @@ tests += loadtest restest1 preloadtest loadfail multiload origtest resolvfail \
|
||||
restest2 next dblload dblunload reldep5 reldep6 reldep7 reldep8 \
|
||||
circleload1 tst-tls3 tst-tls4 tst-tls5 tst-tls6 tst-tls7 tst-tls8 \
|
||||
tst-tls10 tst-tls11 tst-tls12 tst-tls13 tst-tls14 tst-align \
|
||||
$(tests-execstack-$(have-z-execstack)) tst-dlmodcount tst-dlopenrpath
|
||||
$(tests-execstack-$(have-z-execstack)) tst-dlmodcount \
|
||||
tst-dlopenrpath tst-deep1 tst-dlmopen1 tst-dlmopen2
|
||||
# reldep9
|
||||
test-srcs = tst-pathopt
|
||||
tests-vis-yes = vismain
|
||||
@@ -185,7 +187,8 @@ modules-names = testobj1 testobj2 testobj3 testobj4 testobj5 testobj6 \
|
||||
reldep8mod1 reldep8mod2 reldep8mod3 \
|
||||
reldep9mod1 reldep9mod2 reldep9mod3 \
|
||||
tst-alignmod $(modules-execstack-$(have-z-execstack)) \
|
||||
tst-dlopenrpathmod
|
||||
tst-dlopenrpathmod tst-deep1mod1 tst-deep1mod2 tst-deep1mod3 \
|
||||
tst-dlmopen1mod
|
||||
ifeq (yes,$(have-initfini-array))
|
||||
modules-names += tst-array2dep
|
||||
endif
|
||||
@@ -754,3 +757,16 @@ $(objpfx)tst-dlopenrpath: $(objpfx)tst-dlopenrpathmod.so $(libdl)
|
||||
CFLAGS-tst-dlopenrpath.c += -DPFX=\"$(objpfx)\"
|
||||
LDFLAGS-tst-dlopenrpathmod.so += -Wl,-rpath,\$$ORIGIN/test-subdir
|
||||
$(objpfx)tst-dlopenrpath.out: $(objpfx)firstobj.so
|
||||
|
||||
$(objpfx)tst-deep1mod2.so: $(objpfx)tst-deep1mod3.so
|
||||
$(objpfx)tst-deep1: $(libdl) $(objpfx)tst-deep1mod1.so
|
||||
$(objpfx)tst-deep1.out: $(objpfx)tst-deep1mod2.so
|
||||
LDFLAGS-tst-deep1 += -rdynamic
|
||||
tst-deep1mod3.so-no-z-defs = yes
|
||||
|
||||
$(objpfx)tst-dlmopen1mod.so: $(libdl)
|
||||
$(objpfx)tst-dlmopen1: $(libdl)
|
||||
$(objpfx)tst-dlmopen1.out: $(objpfx)tst-dlmopen1mod.so
|
||||
|
||||
$(objpfx)tst-dlmopen2: $(libdl)
|
||||
$(objpfx)tst-dlmopen2.out: $(objpfx)tst-dlmopen1mod.so
|
||||
|
||||
+23
-22
@@ -28,7 +28,7 @@ _dl_addr (const void *address, Dl_info *info,
|
||||
struct link_map **mapp, const ElfW(Sym) **symbolp)
|
||||
{
|
||||
const ElfW(Addr) addr = DL_LOOKUP_ADDRESS (address);
|
||||
struct link_map *l, *match;
|
||||
struct link_map *match;
|
||||
const ElfW(Sym) *symtab, *matchsym, *symtabend;
|
||||
const char *strtab;
|
||||
ElfW(Word) strtabsize;
|
||||
@@ -38,26 +38,27 @@ _dl_addr (const void *address, Dl_info *info,
|
||||
|
||||
/* Find the highest-addressed object that ADDRESS is not below. */
|
||||
match = NULL;
|
||||
for (l = GL(dl_loaded); l; l = l->l_next)
|
||||
if (addr >= l->l_map_start && addr < l->l_map_end)
|
||||
{
|
||||
/* We know ADDRESS lies within L if in any shared object.
|
||||
Make sure it isn't past the end of L's segments. */
|
||||
size_t n = l->l_phnum;
|
||||
if (n > 0)
|
||||
{
|
||||
do
|
||||
--n;
|
||||
while (l->l_phdr[n].p_type != PT_LOAD);
|
||||
if (addr >= (l->l_addr +
|
||||
l->l_phdr[n].p_vaddr + l->l_phdr[n].p_memsz))
|
||||
/* Off the end of the highest-addressed shared object. */
|
||||
continue;
|
||||
}
|
||||
for (Lmid_t ns = 0; ns < DL_NNS; ++ns)
|
||||
for (struct link_map *l = GL(dl_ns)[ns]._ns_loaded; l; l = l->l_next)
|
||||
if (addr >= l->l_map_start && addr < l->l_map_end)
|
||||
{
|
||||
/* We know ADDRESS lies within L if in any shared object.
|
||||
Make sure it isn't past the end of L's segments. */
|
||||
size_t n = l->l_phnum;
|
||||
if (n > 0)
|
||||
{
|
||||
do
|
||||
--n;
|
||||
while (l->l_phdr[n].p_type != PT_LOAD);
|
||||
if (addr >= (l->l_addr +
|
||||
l->l_phdr[n].p_vaddr + l->l_phdr[n].p_memsz))
|
||||
/* Off the end of the highest-addressed shared object. */
|
||||
continue;
|
||||
}
|
||||
|
||||
match = l;
|
||||
break;
|
||||
}
|
||||
match = l;
|
||||
break;
|
||||
}
|
||||
|
||||
int result = 0;
|
||||
if (match != NULL)
|
||||
@@ -67,8 +68,8 @@ _dl_addr (const void *address, Dl_info *info,
|
||||
info->dli_fbase = (void *) match->l_map_start;
|
||||
|
||||
/* If this is the main program the information is incomplete. */
|
||||
if (__builtin_expect (l->l_name[0], 'a') == '\0'
|
||||
&& l->l_type == lt_executable)
|
||||
if (__builtin_expect (match->l_name[0], 'a') == '\0'
|
||||
&& match->l_type == lt_executable)
|
||||
info->dli_fname = _dl_argv[0];
|
||||
|
||||
symtab = (const void *) D_PTR (match, l_info[DT_SYMTAB]);
|
||||
|
||||
+32
-30
@@ -35,44 +35,46 @@ _dl_check_caller (const void *caller, enum allowmask mask)
|
||||
#endif
|
||||
static const char expected4[] = LD_SO;
|
||||
|
||||
for (struct link_map *l = GL(dl_loaded); l != NULL; l = l->l_next)
|
||||
if (caller >= (const void *) l->l_map_start
|
||||
&& caller < (const void *) l->l_text_end)
|
||||
{
|
||||
/* The address falls into this DSO's address range. Check the
|
||||
name. */
|
||||
if ((mask & allow_libc) && strcmp (expected1, l->l_name) == 0)
|
||||
return 0;
|
||||
if ((mask & allow_libdl) && strcmp (expected2, l->l_name) == 0)
|
||||
return 0;
|
||||
for (Lmid_t ns = 0; ns < DL_NNS; ++ns)
|
||||
for (struct link_map *l = GL(dl_ns)[ns]._ns_loaded; l != NULL;
|
||||
l = l->l_next)
|
||||
if (caller >= (const void *) l->l_map_start
|
||||
&& caller < (const void *) l->l_text_end)
|
||||
{
|
||||
/* The address falls into this DSO's address range. Check the
|
||||
name. */
|
||||
if ((mask & allow_libc) && strcmp (expected1, l->l_name) == 0)
|
||||
return 0;
|
||||
if ((mask & allow_libdl) && strcmp (expected2, l->l_name) == 0)
|
||||
return 0;
|
||||
#ifdef LIBPTHREAD_SO
|
||||
if ((mask & allow_libpthread) && strcmp (expected3, l->l_name) == 0)
|
||||
return 0;
|
||||
if ((mask & allow_libpthread) && strcmp (expected3, l->l_name) == 0)
|
||||
return 0;
|
||||
#endif
|
||||
if ((mask & allow_ldso) && strcmp (expected4, l->l_name) == 0)
|
||||
return 0;
|
||||
if ((mask & allow_ldso) && strcmp (expected4, l->l_name) == 0)
|
||||
return 0;
|
||||
|
||||
struct libname_list *runp = l->l_libname;
|
||||
struct libname_list *runp = l->l_libname;
|
||||
|
||||
while (runp != NULL)
|
||||
{
|
||||
if ((mask & allow_libc) && strcmp (expected1, runp->name) == 0)
|
||||
return 0;
|
||||
if ((mask & allow_libdl) && strcmp (expected2, runp->name) == 0)
|
||||
return 0;
|
||||
while (runp != NULL)
|
||||
{
|
||||
if ((mask & allow_libc) && strcmp (expected1, runp->name) == 0)
|
||||
return 0;
|
||||
if ((mask & allow_libdl) && strcmp (expected2, runp->name) == 0)
|
||||
return 0;
|
||||
#ifdef LIBPTHREAD_SO
|
||||
if ((mask & allow_libpthread)
|
||||
&& strcmp (expected3, runp->name) == 0)
|
||||
return 0;
|
||||
if ((mask & allow_libpthread)
|
||||
&& strcmp (expected3, runp->name) == 0)
|
||||
return 0;
|
||||
#endif
|
||||
if ((mask & allow_ldso) && strcmp (expected4, runp->name) == 0)
|
||||
return 0;
|
||||
if ((mask & allow_ldso) && strcmp (expected4, runp->name) == 0)
|
||||
return 0;
|
||||
|
||||
runp = runp->next;
|
||||
}
|
||||
runp = runp->next;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
/* Maybe the dynamic linker is not yet on the list. */
|
||||
if ((mask & allow_ldso) != 0
|
||||
|
||||
+98
-43
@@ -130,6 +130,10 @@ _dl_close (void *_map)
|
||||
/* Acquire the lock. */
|
||||
__rtld_lock_lock_recursive (GL(dl_load_lock));
|
||||
|
||||
/* One less direct use. */
|
||||
assert (map->l_direct_opencount > 0);
|
||||
--map->l_direct_opencount;
|
||||
|
||||
/* Decrement the reference count. */
|
||||
if (map->l_opencount > 1 || map->l_type != lt_loaded)
|
||||
{
|
||||
@@ -141,6 +145,12 @@ _dl_close (void *_map)
|
||||
/* Decrement the object's reference counter, not the dependencies'. */
|
||||
--map->l_opencount;
|
||||
|
||||
/* If the direct use counter reaches zero we have to decrement
|
||||
all the dependencies' usage counter. */
|
||||
if (map->l_direct_opencount == 0)
|
||||
for (i = 1; i < map->l_searchlist.r_nlist; ++i)
|
||||
--map->l_searchlist.r_list[i]->l_opencount;
|
||||
|
||||
__rtld_lock_unlock_recursive (GL(dl_load_lock));
|
||||
return;
|
||||
}
|
||||
@@ -167,12 +177,13 @@ _dl_close (void *_map)
|
||||
for (i = 1; list[i] != NULL; ++i)
|
||||
if ((list[i]->l_flags_1 & DF_1_NODELETE) == 0
|
||||
/* Decrement counter. */
|
||||
&& --new_opencount[i] == 0)
|
||||
&& (assert (new_opencount[i] > 0), --new_opencount[i] == 0))
|
||||
{
|
||||
void mark_removed (struct link_map *remmap)
|
||||
{
|
||||
/* Test whether this object was also loaded directly. */
|
||||
if (remmap->l_searchlist.r_list != NULL)
|
||||
if (remmap->l_searchlist.r_list != NULL
|
||||
&& remmap->l_direct_opencount > 0)
|
||||
{
|
||||
/* In this case we have to decrement all the dependencies of
|
||||
this object. They are all in MAP's dependency list. */
|
||||
@@ -184,6 +195,7 @@ _dl_close (void *_map)
|
||||
|| ! dep_list[j]->l_init_called)
|
||||
{
|
||||
assert (dep_list[j]->l_idx < map->l_searchlist.r_nlist);
|
||||
assert (new_opencount[dep_list[j]->l_idx] > 0);
|
||||
if (--new_opencount[dep_list[j]->l_idx] == 0)
|
||||
{
|
||||
assert (dep_list[j]->l_type == lt_loaded);
|
||||
@@ -197,17 +209,53 @@ _dl_close (void *_map)
|
||||
unsigned int j;
|
||||
for (j = 0; j < remmap->l_reldepsact; ++j)
|
||||
{
|
||||
struct link_map *depmap = remmap->l_reldeps[j];
|
||||
|
||||
/* Find out whether this object is in our list. */
|
||||
if (remmap->l_reldeps[j]->l_idx < nopencount
|
||||
&& (list[remmap->l_reldeps[j]->l_idx]
|
||||
== remmap->l_reldeps[j]))
|
||||
/* Yes, it is. */
|
||||
if (--new_opencount[remmap->l_reldeps[j]->l_idx] == 0)
|
||||
{
|
||||
/* This one is now gone, too. */
|
||||
assert (remmap->l_reldeps[j]->l_type == lt_loaded);
|
||||
mark_removed (remmap->l_reldeps[j]);
|
||||
}
|
||||
if (depmap->l_idx < nopencount
|
||||
&& list[depmap->l_idx] == depmap)
|
||||
{
|
||||
/* Yes, it is. If is has a search list, make a
|
||||
recursive call to handle this. */
|
||||
if (depmap->l_searchlist.r_list != NULL)
|
||||
{
|
||||
assert (new_opencount[depmap->l_idx] > 0);
|
||||
if (--new_opencount[depmap->l_idx] == 0)
|
||||
{
|
||||
/* This one is now gone, too. */
|
||||
assert (depmap->l_type == lt_loaded);
|
||||
mark_removed (depmap);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Otherwise we have to handle the dependency
|
||||
deallocation here. */
|
||||
unsigned int k;
|
||||
for (k = 0; depmap->l_initfini[k] != NULL; ++k)
|
||||
{
|
||||
struct link_map *rl = depmap->l_initfini[k];
|
||||
|
||||
if (rl->l_idx < nopencount
|
||||
&& list[rl->l_idx] == rl)
|
||||
{
|
||||
assert (new_opencount[rl->l_idx] > 0);
|
||||
if (--new_opencount[rl->l_idx] == 0)
|
||||
{
|
||||
/* Another module to remove. */
|
||||
assert (rl->l_type == lt_loaded);
|
||||
mark_removed (rl);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
assert (rl->l_opencount > 0);
|
||||
if (--rl->l_opencount == 0)
|
||||
mark_removed (rl);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -225,7 +273,8 @@ _dl_close (void *_map)
|
||||
{
|
||||
/* When debugging print a message first. */
|
||||
if (__builtin_expect (GLRO(dl_debug_mask) & DL_DEBUG_IMPCALLS, 0))
|
||||
GLRO(dl_debug_printf) ("\ncalling fini: %s\n\n", imap->l_name);
|
||||
GLRO(dl_debug_printf) ("\ncalling fini: %s [%lu]\n\n",
|
||||
imap->l_name, imap->l_ns);
|
||||
|
||||
/* Call its termination function. Do not do it for
|
||||
half-cooked objects. */
|
||||
@@ -340,18 +389,21 @@ _dl_close (void *_map)
|
||||
if (__builtin_expect (imap->l_global, 0))
|
||||
{
|
||||
/* This object is in the global scope list. Remove it. */
|
||||
unsigned int cnt = GL(dl_main_searchlist)->r_nlist;
|
||||
unsigned int cnt
|
||||
= GL(dl_ns)[imap->l_ns]._ns_main_searchlist->r_nlist;
|
||||
|
||||
do
|
||||
--cnt;
|
||||
while (GL(dl_main_searchlist)->r_list[cnt] != imap);
|
||||
while (GL(dl_ns)[imap->l_ns]._ns_main_searchlist->r_list[cnt]
|
||||
!= imap);
|
||||
|
||||
/* The object was already correctly registered. */
|
||||
while (++cnt < GL(dl_main_searchlist)->r_nlist)
|
||||
GL(dl_main_searchlist)->r_list[cnt - 1]
|
||||
= GL(dl_main_searchlist)->r_list[cnt];
|
||||
while (++cnt
|
||||
< GL(dl_ns)[imap->l_ns]._ns_main_searchlist->r_nlist)
|
||||
GL(dl_ns)[imap->l_ns]._ns_main_searchlist->r_list[cnt - 1]
|
||||
= GL(dl_ns)[imap->l_ns]._ns_main_searchlist->r_list[cnt];
|
||||
|
||||
--GL(dl_main_searchlist)->r_nlist;
|
||||
--GL(dl_ns)[imap->l_ns]._ns_main_searchlist->r_nlist;
|
||||
}
|
||||
|
||||
#ifdef USE_TLS
|
||||
@@ -442,19 +494,18 @@ _dl_close (void *_map)
|
||||
DL_UNMAP (imap);
|
||||
|
||||
/* Finally, unlink the data structure and free it. */
|
||||
#ifdef SHARED
|
||||
/* We will unlink the first object only if this is a statically
|
||||
linked program. */
|
||||
assert (imap->l_prev != NULL);
|
||||
imap->l_prev->l_next = imap->l_next;
|
||||
#else
|
||||
if (imap->l_prev != NULL)
|
||||
imap->l_prev->l_next = imap->l_next;
|
||||
else
|
||||
GL(dl_loaded) = imap->l_next;
|
||||
{
|
||||
#ifdef SHARED
|
||||
assert (imap->l_ns != LM_ID_BASE);
|
||||
#endif
|
||||
--GL(dl_nloaded);
|
||||
if (imap->l_next)
|
||||
GL(dl_ns)[imap->l_ns]._ns_loaded = imap->l_next;
|
||||
}
|
||||
|
||||
--GL(dl_ns)[imap->l_ns]._ns_nloaded;
|
||||
if (imap->l_next != NULL)
|
||||
imap->l_next->l_prev = imap->l_prev;
|
||||
|
||||
free (imap->l_versions);
|
||||
@@ -528,7 +579,7 @@ _dl_close (void *_map)
|
||||
if (any_tls)
|
||||
{
|
||||
if (__builtin_expect (++GL(dl_tls_generation) == 0, 0))
|
||||
__libc_fatal (_("TLS generation counter wrapped! Please send report with the 'glibcbug' script."));
|
||||
__libc_fatal (_("TLS generation counter wrapped! Please report as described in <http://www.gnu.org/software/libc/bugs.html>."));
|
||||
|
||||
if (tls_free_end == GL(dl_tls_static_used))
|
||||
GL(dl_tls_static_used) = tls_free_start;
|
||||
@@ -596,22 +647,26 @@ free_slotinfo (struct dtv_slotinfo_list **elemp)
|
||||
|
||||
libc_freeres_fn (free_mem)
|
||||
{
|
||||
if (__builtin_expect (GL(dl_global_scope_alloc), 0) != 0
|
||||
&& (GL(dl_main_searchlist)->r_nlist
|
||||
== GLRO(dl_initial_searchlist).r_nlist))
|
||||
{
|
||||
/* All object dynamically loaded by the program are unloaded. Free
|
||||
the memory allocated for the global scope variable. */
|
||||
struct link_map **old = GL(dl_main_searchlist)->r_list;
|
||||
for (Lmid_t ns = 0; ns < DL_NNS; ++ns)
|
||||
if (__builtin_expect (GL(dl_ns)[ns]._ns_global_scope_alloc, 0) != 0
|
||||
&& (GL(dl_ns)[ns]._ns_main_searchlist->r_nlist
|
||||
// XXX Check whether we need NS-specific initial_searchlist
|
||||
== GLRO(dl_initial_searchlist).r_nlist))
|
||||
{
|
||||
/* All object dynamically loaded by the program are unloaded. Free
|
||||
the memory allocated for the global scope variable. */
|
||||
struct link_map **old = GL(dl_ns)[ns]._ns_main_searchlist->r_list;
|
||||
|
||||
/* Put the old map in. */
|
||||
GL(dl_main_searchlist)->r_list = GLRO(dl_initial_searchlist).r_list;
|
||||
/* Signal that the original map is used. */
|
||||
GL(dl_global_scope_alloc) = 0;
|
||||
/* Put the old map in. */
|
||||
GL(dl_ns)[ns]._ns_main_searchlist->r_list
|
||||
// XXX Check whether we need NS-specific initial_searchlist
|
||||
= GLRO(dl_initial_searchlist).r_list;
|
||||
/* Signal that the original map is used. */
|
||||
GL(dl_ns)[ns]._ns_global_scope_alloc = 0;
|
||||
|
||||
/* Now free the old map. */
|
||||
free (old);
|
||||
}
|
||||
/* Now free the old map. */
|
||||
free (old);
|
||||
}
|
||||
|
||||
#ifdef USE_TLS
|
||||
if (USE___THREAD || GL(dl_tls_dtv_slotinfo_list) != NULL)
|
||||
|
||||
+3
-1
@@ -54,8 +54,10 @@ _dl_resolve_conflicts (struct link_map *l, ElfW(Rela) *conflict,
|
||||
(map) = resolve_conflict_map; \
|
||||
} while (0)
|
||||
|
||||
/* Prelinking makes no sense for anything but the main namespace. */
|
||||
assert (l->l_ns == LM_ID_BASE);
|
||||
struct link_map *resolve_conflict_map __attribute__ ((__unused__))
|
||||
= GL(dl_loaded);
|
||||
= GL(dl_ns)[LM_ID_BASE]._ns_loaded;
|
||||
|
||||
#include "dynamic-link.h"
|
||||
|
||||
|
||||
+3
-1
@@ -39,7 +39,9 @@ _dl_debug_initialize (ElfW(Addr) ldbase)
|
||||
/* Tell the debugger where to find the map of loaded objects. */
|
||||
_r_debug.r_version = 1 /* R_DEBUG_VERSION XXX */;
|
||||
_r_debug.r_ldbase = ldbase;
|
||||
_r_debug.r_map = GL(dl_loaded);
|
||||
// XXX This is problematic. It means we cannot tell the debugger
|
||||
// XXX about namespaces other than the main one.
|
||||
_r_debug.r_map = GL(dl_ns)[LM_ID_BASE]._ns_loaded;
|
||||
_r_debug.r_brk = (ElfW(Addr)) &_dl_debug_state;
|
||||
}
|
||||
|
||||
|
||||
+4
-3
@@ -63,7 +63,8 @@ openaux (void *a)
|
||||
args->aux = _dl_map_object (args->map, args->name, 0,
|
||||
(args->map->l_type == lt_executable
|
||||
? lt_library : args->map->l_type),
|
||||
args->trace_mode, args->open_mode);
|
||||
args->trace_mode, args->open_mode,
|
||||
args->map->l_ns);
|
||||
}
|
||||
|
||||
static ptrdiff_t
|
||||
@@ -509,8 +510,8 @@ _dl_map_object_deps (struct link_map *map,
|
||||
runp->map->l_reserved = 0;
|
||||
}
|
||||
|
||||
if (__builtin_expect(GLRO(dl_debug_mask) & DL_DEBUG_PRELINK, 0) != 0
|
||||
&& map == GL(dl_loaded))
|
||||
if (__builtin_expect (GLRO(dl_debug_mask) & DL_DEBUG_PRELINK, 0) != 0
|
||||
&& map == GL(dl_ns)[LM_ID_BASE]._ns_loaded)
|
||||
{
|
||||
/* If we are to compute conflicts, we have to build local scope
|
||||
for each library, not just the ultimate loader. */
|
||||
|
||||
+150
-111
@@ -32,10 +32,10 @@ internal_function
|
||||
_dl_fini (void)
|
||||
{
|
||||
/* Lots of fun ahead. We have to call the destructors for all still
|
||||
loaded objects. The problem is that the ELF specification now
|
||||
demands that dependencies between the modules are taken into account.
|
||||
I.e., the destructor for a module is called before the ones for any
|
||||
of its dependencies.
|
||||
loaded objects, in all namespaces. The problem is that the ELF
|
||||
specification now demands that dependencies between the modules
|
||||
are taken into account. I.e., the destructor for a module is
|
||||
called before the ones for any of its dependencies.
|
||||
|
||||
To make things more complicated, we cannot simply use the reverse
|
||||
order of the constructors. Since the user might have loaded objects
|
||||
@@ -45,140 +45,179 @@ _dl_fini (void)
|
||||
unsigned int i;
|
||||
unsigned int nloaded;
|
||||
struct link_map *l;
|
||||
struct link_map **maps;
|
||||
struct link_map **maps = NULL;
|
||||
size_t maps_size = 0;
|
||||
|
||||
/* Protect against concurrent loads and unloads. */
|
||||
__rtld_lock_lock_recursive (GL(dl_load_lock));
|
||||
|
||||
nloaded = GL(dl_nloaded);
|
||||
|
||||
/* XXX Could it be (in static binaries) that there is no object loaded? */
|
||||
assert (nloaded > 0);
|
||||
|
||||
/* Now we can allocate an array to hold all the pointers and copy
|
||||
the pointers in. */
|
||||
maps = (struct link_map **) alloca (nloaded * sizeof (struct link_map *));
|
||||
for (l = GL(dl_loaded), i = 0; l != NULL; l = l->l_next)
|
||||
/* We First run the destructors of the main namespaces, then the
|
||||
other ones. The order should not matter since the namespace
|
||||
content is supposed to be independent. But we can have auditing
|
||||
code in a auxiliaty namespace and we want it to monitor the
|
||||
destructors. */
|
||||
for (Lmid_t cnt = 0; cnt < DL_NNS; ++cnt)
|
||||
{
|
||||
assert (i < nloaded);
|
||||
/* Protect against concurrent loads and unloads. */
|
||||
__rtld_lock_lock_recursive (GL(dl_load_lock));
|
||||
|
||||
maps[i++] = l;
|
||||
nloaded = GL(dl_ns)[cnt]._ns_nloaded;
|
||||
|
||||
/* Bump l_opencount of all objects so that they are not dlclose()ed
|
||||
from underneath us. */
|
||||
++l->l_opencount;
|
||||
}
|
||||
assert (i == nloaded);
|
||||
/* XXX Could it be (in static binaries) that there is no object
|
||||
loaded? */
|
||||
assert (cnt != LM_ID_BASE || nloaded > 0);
|
||||
|
||||
/* Now we have to do the sorting. */
|
||||
for (l = GL(dl_loaded)->l_next; l != NULL; l = l->l_next)
|
||||
{
|
||||
unsigned int j;
|
||||
unsigned int k;
|
||||
|
||||
/* Find the place in the 'maps' array. */
|
||||
for (j = 1; maps[j] != l; ++j)
|
||||
;
|
||||
|
||||
/* Find all object for which the current one is a dependency and
|
||||
move the found object (if necessary) in front. */
|
||||
for (k = j + 1; k < nloaded; ++k)
|
||||
/* Now we can allocate an array to hold all the pointers and copy
|
||||
the pointers in. */
|
||||
if (maps_size < nloaded * sizeof (struct link_map *))
|
||||
{
|
||||
struct link_map **runp = maps[k]->l_initfini;
|
||||
if (runp != NULL)
|
||||
if (maps_size == 0)
|
||||
{
|
||||
while (*runp != NULL)
|
||||
if (*runp == l)
|
||||
{
|
||||
struct link_map *here = maps[k];
|
||||
|
||||
/* Move it now. */
|
||||
memmove (&maps[j] + 1,
|
||||
&maps[j],
|
||||
(k - j) * sizeof (struct link_map *));
|
||||
maps[j++] = here;
|
||||
|
||||
break;
|
||||
}
|
||||
else
|
||||
++runp;
|
||||
maps_size = nloaded * sizeof (struct link_map *);
|
||||
maps = (struct link_map **) alloca (maps_size);
|
||||
}
|
||||
else
|
||||
maps = (struct link_map **)
|
||||
extend_alloca (maps, maps_size,
|
||||
nloaded * sizeof (struct link_map *));
|
||||
}
|
||||
|
||||
if (__builtin_expect (maps[k]->l_reldeps != NULL, 0))
|
||||
for (l = GL(dl_ns)[cnt]._ns_loaded, i = 0; l != NULL; l = l->l_next)
|
||||
{
|
||||
assert (i < nloaded);
|
||||
|
||||
/* Do not handle ld.so in secondary namespaces. */
|
||||
if (l == l->l_real)
|
||||
{
|
||||
unsigned int m = maps[k]->l_reldepsact;
|
||||
struct link_map **relmaps = maps[k]->l_reldeps;
|
||||
maps[i++] = l;
|
||||
|
||||
while (m-- > 0)
|
||||
/* Bump l_opencount of all objects so that they are not
|
||||
dlclose()ed from underneath us. */
|
||||
++l->l_opencount;
|
||||
}
|
||||
}
|
||||
assert (cnt != LM_ID_BASE || i == nloaded);
|
||||
assert (cnt == LM_ID_BASE || i == nloaded || i == nloaded - 1);
|
||||
unsigned int nmaps = i;
|
||||
|
||||
if (nmaps != 0)
|
||||
{
|
||||
/* Now we have to do the sorting. */
|
||||
l = GL(dl_ns)[cnt]._ns_loaded;
|
||||
if (cnt == LM_ID_BASE)
|
||||
/* The main executable always comes first. */
|
||||
l = l->l_next;
|
||||
for (; l != NULL; l = l->l_next)
|
||||
{
|
||||
unsigned int j;
|
||||
unsigned int k;
|
||||
|
||||
/* Find the place in the 'maps' array. */
|
||||
for (j = 1; maps[j] != l; ++j)
|
||||
;
|
||||
|
||||
/* Find all object for which the current one is a dependency and
|
||||
move the found object (if necessary) in front. */
|
||||
for (k = j + 1; k < nmaps; ++k)
|
||||
{
|
||||
if (relmaps[m] == l)
|
||||
struct link_map **runp = maps[k]->l_initfini;
|
||||
if (runp != NULL)
|
||||
{
|
||||
struct link_map *here = maps[k];
|
||||
while (*runp != NULL)
|
||||
if (*runp == l)
|
||||
{
|
||||
struct link_map *here = maps[k];
|
||||
|
||||
/* Move it now. */
|
||||
memmove (&maps[j] + 1,
|
||||
&maps[j],
|
||||
(k - j) * sizeof (struct link_map *));
|
||||
maps[j] = here;
|
||||
/* Move it now. */
|
||||
memmove (&maps[j] + 1,
|
||||
&maps[j],
|
||||
(k - j) * sizeof (struct link_map *));
|
||||
maps[j++] = here;
|
||||
|
||||
break;
|
||||
break;
|
||||
}
|
||||
else
|
||||
++runp;
|
||||
}
|
||||
|
||||
if (__builtin_expect (maps[k]->l_reldeps != NULL, 0))
|
||||
{
|
||||
unsigned int m = maps[k]->l_reldepsact;
|
||||
struct link_map **relmaps = maps[k]->l_reldeps;
|
||||
|
||||
while (m-- > 0)
|
||||
{
|
||||
if (relmaps[m] == l)
|
||||
{
|
||||
struct link_map *here = maps[k];
|
||||
|
||||
/* Move it now. */
|
||||
memmove (&maps[j] + 1,
|
||||
&maps[j],
|
||||
(k - j) * sizeof (struct link_map *));
|
||||
maps[j] = here;
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* We do not rely on the linked list of loaded object anymore from
|
||||
this point on. We have our own list here (maps). The various
|
||||
members of this list cannot vanish since the open count is too
|
||||
high and will be decremented in this loop. So we release the
|
||||
lock so that some code which might be called from a destructor
|
||||
can directly or indirectly access the lock. */
|
||||
__rtld_lock_unlock_recursive (GL(dl_load_lock));
|
||||
/* We do not rely on the linked list of loaded object anymore from
|
||||
this point on. We have our own list here (maps). The various
|
||||
members of this list cannot vanish since the open count is too
|
||||
high and will be decremented in this loop. So we release the
|
||||
lock so that some code which might be called from a destructor
|
||||
can directly or indirectly access the lock. */
|
||||
__rtld_lock_unlock_recursive (GL(dl_load_lock));
|
||||
|
||||
/* 'maps' now contains the objects in the right order. Now call the
|
||||
destructors. We have to process this array from the front. */
|
||||
for (i = 0; i < nloaded; ++i)
|
||||
{
|
||||
l = maps[i];
|
||||
|
||||
if (l->l_init_called)
|
||||
/* 'maps' now contains the objects in the right order. Now call the
|
||||
destructors. We have to process this array from the front. */
|
||||
for (i = 0; i < nmaps; ++i)
|
||||
{
|
||||
/* Make sure nothing happens if we are called twice. */
|
||||
l->l_init_called = 0;
|
||||
l = maps[i];
|
||||
|
||||
/* Don't call the destructors for objects we are not supposed to. */
|
||||
if (l->l_name[0] == '\0' && l->l_type == lt_executable)
|
||||
continue;
|
||||
|
||||
/* Is there a destructor function? */
|
||||
if (l->l_info[DT_FINI_ARRAY] == NULL && l->l_info[DT_FINI] == NULL)
|
||||
continue;
|
||||
|
||||
/* When debugging print a message first. */
|
||||
if (__builtin_expect (GLRO(dl_debug_mask) & DL_DEBUG_IMPCALLS, 0))
|
||||
_dl_debug_printf ("\ncalling fini: %s\n\n",
|
||||
l->l_name[0] ? l->l_name : rtld_progname);
|
||||
|
||||
/* First see whether an array is given. */
|
||||
if (l->l_info[DT_FINI_ARRAY] != NULL)
|
||||
if (l->l_init_called)
|
||||
{
|
||||
ElfW(Addr) *array =
|
||||
(ElfW(Addr) *) (l->l_addr
|
||||
+ l->l_info[DT_FINI_ARRAY]->d_un.d_ptr);
|
||||
unsigned int i = (l->l_info[DT_FINI_ARRAYSZ]->d_un.d_val
|
||||
/ sizeof (ElfW(Addr)));
|
||||
while (i-- > 0)
|
||||
((fini_t) array[i]) ();
|
||||
/* Make sure nothing happens if we are called twice. */
|
||||
l->l_init_called = 0;
|
||||
|
||||
/* Don't call the destructors for objects we are not
|
||||
supposed to. */
|
||||
if (l->l_name[0] == '\0' && l->l_type == lt_executable)
|
||||
continue;
|
||||
|
||||
/* Is there a destructor function? */
|
||||
if (l->l_info[DT_FINI_ARRAY] == NULL
|
||||
&& l->l_info[DT_FINI] == NULL)
|
||||
continue;
|
||||
|
||||
/* When debugging print a message first. */
|
||||
if (__builtin_expect (GLRO(dl_debug_mask) & DL_DEBUG_IMPCALLS,
|
||||
0))
|
||||
_dl_debug_printf ("\ncalling fini: %s [%lu]\n\n",
|
||||
l->l_name[0] ? l->l_name : rtld_progname,
|
||||
cnt);
|
||||
|
||||
/* First see whether an array is given. */
|
||||
if (l->l_info[DT_FINI_ARRAY] != NULL)
|
||||
{
|
||||
ElfW(Addr) *array =
|
||||
(ElfW(Addr) *) (l->l_addr
|
||||
+ l->l_info[DT_FINI_ARRAY]->d_un.d_ptr);
|
||||
unsigned int i = (l->l_info[DT_FINI_ARRAYSZ]->d_un.d_val
|
||||
/ sizeof (ElfW(Addr)));
|
||||
while (i-- > 0)
|
||||
((fini_t) array[i]) ();
|
||||
}
|
||||
|
||||
/* Next try the old-style destructor. */
|
||||
if (l->l_info[DT_FINI] != NULL)
|
||||
((fini_t) DL_DT_FINI_ADDRESS (l, l->l_addr + l->l_info[DT_FINI]->d_un.d_ptr)) ();
|
||||
}
|
||||
|
||||
/* Next try the old-style destructor. */
|
||||
if (l->l_info[DT_FINI] != NULL)
|
||||
((fini_t) DL_DT_FINI_ADDRESS (l, l->l_addr + l->l_info[DT_FINI]->d_un.d_ptr)) ();
|
||||
/* Correct the previous increment. */
|
||||
--l->l_opencount;
|
||||
}
|
||||
|
||||
/* Correct the previous increment. */
|
||||
--l->l_opencount;
|
||||
}
|
||||
|
||||
if (__builtin_expect (GLRO(dl_debug_mask) & DL_DEBUG_STATISTICS, 0))
|
||||
|
||||
+21
-3
@@ -42,14 +42,32 @@ __dl_iterate_phdr (int (*callback) (struct dl_phdr_info *info,
|
||||
__rtld_lock_lock_recursive (GL(dl_load_lock));
|
||||
__libc_cleanup_push (cancel_handler, 0);
|
||||
|
||||
for (l = GL(dl_loaded); l != NULL; l = l->l_next)
|
||||
/* We have to determine the namespace of the caller since this determines
|
||||
which namespace is reported. */
|
||||
const void *caller = RETURN_ADDRESS (0);
|
||||
size_t nloaded = GL(dl_ns)[0]._ns_nloaded;
|
||||
Lmid_t ns = 0;
|
||||
for (Lmid_t cnt = DL_NNS - 1; cnt > 0; --cnt)
|
||||
for (struct link_map *l = GL(dl_ns)[cnt]._ns_loaded; l; l = l->l_next)
|
||||
{
|
||||
/* We have to count the total number of loaded objects. */
|
||||
nloaded += GL(dl_ns)[cnt]._ns_nloaded;
|
||||
|
||||
if (caller >= (const void *) l->l_map_start
|
||||
&& caller < (const void *) l->l_map_end)
|
||||
/* There must be exactly one DSO for the range of the virtual
|
||||
memory. Otherwise something is really broken. */
|
||||
ns = cnt;
|
||||
}
|
||||
|
||||
for (l = GL(dl_ns)[ns]._ns_loaded; l != NULL; l = l->l_next)
|
||||
{
|
||||
info.dlpi_addr = l->l_addr;
|
||||
info.dlpi_name = l->l_name;
|
||||
info.dlpi_phdr = l->l_phdr;
|
||||
info.dlpi_phnum = l->l_phnum;
|
||||
info.dlpi_adds = GL(dl_load_adds);
|
||||
info.dlpi_subs = GL(dl_load_adds) - GL(dl_nloaded);
|
||||
info.dlpi_subs = GL(dl_load_adds) - nloaded;
|
||||
ret = callback (&info, sizeof (struct dl_phdr_info), data);
|
||||
if (ret)
|
||||
break;
|
||||
@@ -87,7 +105,7 @@ dl_iterate_phdr (int (*callback) (struct dl_phdr_info *info,
|
||||
info.dlpi_phdr = _dl_phdr;
|
||||
info.dlpi_phnum = _dl_phnum;
|
||||
info.dlpi_adds = GL(dl_load_adds);
|
||||
info.dlpi_subs = GL(dl_load_adds) - GL(dl_nloaded);
|
||||
info.dlpi_subs = GL(dl_load_adds) - GL(dl_ns)[LM_ID_BASE]._ns_nloaded;
|
||||
ret = (*callback) (&info, sizeof (struct dl_phdr_info), data);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
+13
-12
@@ -77,7 +77,7 @@ do_dlopen (void *ptr)
|
||||
{
|
||||
struct do_dlopen_args *args = (struct do_dlopen_args *) ptr;
|
||||
/* Open and relocate the shared object. */
|
||||
args->map = _dl_open (args->name, args->mode, NULL);
|
||||
args->map = _dl_open (args->name, args->mode, NULL, __LM_ID_CALLER);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -217,18 +217,19 @@ libc_freeres_fn (free_mem)
|
||||
}
|
||||
|
||||
/* Remove all additional names added to the objects. */
|
||||
for (l = GL(dl_loaded); l != NULL; l = l->l_next)
|
||||
{
|
||||
struct libname_list *lnp = l->l_libname->next;
|
||||
for (Lmid_t ns = 0; ns < DL_NNS; ++ns)
|
||||
for (l = GL(dl_ns)[ns]._ns_loaded; l != NULL; l = l->l_next)
|
||||
{
|
||||
struct libname_list *lnp = l->l_libname->next;
|
||||
|
||||
l->l_libname->next = NULL;
|
||||
l->l_libname->next = NULL;
|
||||
|
||||
while (lnp != NULL)
|
||||
{
|
||||
struct libname_list *old = lnp;
|
||||
lnp = lnp->next;
|
||||
if (! old->dont_free)
|
||||
while (lnp != NULL)
|
||||
{
|
||||
struct libname_list *old = lnp;
|
||||
lnp = lnp->next;
|
||||
if (! old->dont_free)
|
||||
free (old);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+69
-33
@@ -699,7 +699,7 @@ _dl_init_paths (const char *llp)
|
||||
|
||||
#ifdef SHARED
|
||||
/* This points to the map of the main object. */
|
||||
l = GL(dl_loaded);
|
||||
l = GL(dl_ns)[LM_ID_BASE]._ns_loaded;
|
||||
if (l != NULL)
|
||||
{
|
||||
assert (l->l_type != lt_loaded);
|
||||
@@ -795,10 +795,10 @@ lose (int code, int fd, const char *name, char *realname, struct link_map *l,
|
||||
if (l->l_prev == NULL)
|
||||
/* No other module loaded. This happens only in the static library,
|
||||
or in rtld under --verify. */
|
||||
GL(dl_loaded) = NULL;
|
||||
GL(dl_ns)[l->l_ns]._ns_loaded = NULL;
|
||||
else
|
||||
l->l_prev->l_next = NULL;
|
||||
--GL(dl_nloaded);
|
||||
--GL(dl_ns)[l->l_ns]._ns_nloaded;
|
||||
free (l);
|
||||
}
|
||||
free (realname);
|
||||
@@ -815,7 +815,7 @@ static
|
||||
struct link_map *
|
||||
_dl_map_object_from_fd (const char *name, int fd, struct filebuf *fbp,
|
||||
char *realname, struct link_map *loader, int l_type,
|
||||
int mode, void **stack_endp)
|
||||
int mode, void **stack_endp, Lmid_t nsid)
|
||||
{
|
||||
struct link_map *l = NULL;
|
||||
const ElfW(Ehdr) *header;
|
||||
@@ -839,7 +839,7 @@ _dl_map_object_from_fd (const char *name, int fd, struct filebuf *fbp,
|
||||
}
|
||||
|
||||
/* Look again to see if the real name matched another already loaded. */
|
||||
for (l = GL(dl_loaded); l; l = l->l_next)
|
||||
for (l = GL(dl_ns)[nsid]._ns_loaded; l; l = l->l_next)
|
||||
if (l->l_ino == st.st_ino && l->l_dev == st.st_dev)
|
||||
{
|
||||
/* The object is already loaded.
|
||||
@@ -854,6 +854,31 @@ _dl_map_object_from_fd (const char *name, int fd, struct filebuf *fbp,
|
||||
return l;
|
||||
}
|
||||
|
||||
#ifdef SHARED
|
||||
/* When loading into a namespace other than the base one we must
|
||||
avoid loading ld.so since there can only be one copy. Ever. */
|
||||
if (__builtin_expect (nsid != LM_ID_BASE, 0)
|
||||
&& ((st.st_ino == GL(dl_rtld_map).l_ino
|
||||
&& st.st_dev == GL(dl_rtld_map).l_dev)
|
||||
|| _dl_name_match_p (name, &GL(dl_rtld_map))))
|
||||
{
|
||||
/* This is indeed ld.so. Create a new link_map which refers to
|
||||
the real one for almost everything. */
|
||||
l = _dl_new_object (realname, name, l_type, loader, mode, nsid);
|
||||
if (l == NULL)
|
||||
goto fail_new;
|
||||
|
||||
/* Refer to the real descriptor. */
|
||||
l->l_real = &GL(dl_rtld_map);
|
||||
|
||||
/* No need to bump the refcount of the real object, ld.so will
|
||||
never be unloaded. */
|
||||
__close (fd);
|
||||
|
||||
return l;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (mode & RTLD_NOLOAD)
|
||||
/* We are not supposed to load the object unless it is already
|
||||
loaded. So return now. */
|
||||
@@ -861,7 +886,7 @@ _dl_map_object_from_fd (const char *name, int fd, struct filebuf *fbp,
|
||||
|
||||
/* Print debugging message. */
|
||||
if (__builtin_expect (GLRO(dl_debug_mask) & DL_DEBUG_FILES, 0))
|
||||
_dl_debug_printf ("file=%s; generating link map\n", name);
|
||||
_dl_debug_printf ("file=%s [%lu]; generating link map\n", name, nsid);
|
||||
|
||||
/* This is the ELF header. We read it in `open_verify'. */
|
||||
header = (void *) fbp->buf;
|
||||
@@ -881,9 +906,12 @@ _dl_map_object_from_fd (const char *name, int fd, struct filebuf *fbp,
|
||||
#endif
|
||||
|
||||
/* Enter the new object in the list of loaded objects. */
|
||||
l = _dl_new_object (realname, name, l_type, loader);
|
||||
if (__builtin_expect (! l, 0))
|
||||
l = _dl_new_object (realname, name, l_type, loader, mode, nsid);
|
||||
if (__builtin_expect (l == NULL, 0))
|
||||
{
|
||||
#ifdef SHARED
|
||||
fail_new:
|
||||
#endif
|
||||
errstring = N_("cannot create shared object descriptor");
|
||||
goto call_lose_errno;
|
||||
}
|
||||
@@ -1355,15 +1383,12 @@ cannot enable executable stack as shared object requires");
|
||||
|
||||
/* If this object has DT_SYMBOLIC set modify now its scope. We don't
|
||||
have to do this for the main map. */
|
||||
if (__builtin_expect (l->l_info[DT_SYMBOLIC] != NULL, 0)
|
||||
if ((mode & RTLD_DEEPBIND) == 0
|
||||
&& __builtin_expect (l->l_info[DT_SYMBOLIC] != NULL, 0)
|
||||
&& &l->l_searchlist != l->l_scope[0])
|
||||
{
|
||||
/* Create an appropriate searchlist. It contains only this map.
|
||||
|
||||
XXX This is the definition of DT_SYMBOLIC in SysVr4. The old
|
||||
GNU ld.so implementation had a different interpretation which
|
||||
is more reasonable. We are prepared to add this possibility
|
||||
back as part of a GNU extension of the ELF format. */
|
||||
This is the definition of DT_SYMBOLIC in SysVr4. */
|
||||
l->l_symbolic_searchlist.r_list =
|
||||
(struct link_map **) malloc (sizeof (struct link_map *));
|
||||
|
||||
@@ -1774,7 +1799,7 @@ open_path (const char *name, size_t namelen, int preloaded,
|
||||
struct link_map *
|
||||
internal_function
|
||||
_dl_map_object (struct link_map *loader, const char *name, int preloaded,
|
||||
int type, int trace_mode, int mode)
|
||||
int type, int trace_mode, int mode, Lmid_t nsid)
|
||||
{
|
||||
int fd;
|
||||
char *realname;
|
||||
@@ -1782,8 +1807,11 @@ _dl_map_object (struct link_map *loader, const char *name, int preloaded,
|
||||
struct link_map *l;
|
||||
struct filebuf fb;
|
||||
|
||||
assert (nsid >= 0);
|
||||
assert (nsid < DL_NNS);
|
||||
|
||||
/* Look for this name among those already loaded. */
|
||||
for (l = GL(dl_loaded); l; l = l->l_next)
|
||||
for (l = GL(dl_ns)[nsid]._ns_loaded; l; l = l->l_next)
|
||||
{
|
||||
/* If the requested name matches the soname of a loaded object,
|
||||
use that object. Elide this check for names that have not
|
||||
@@ -1815,9 +1843,9 @@ _dl_map_object (struct link_map *loader, const char *name, int preloaded,
|
||||
/* Display information if we are debugging. */
|
||||
if (__builtin_expect (GLRO(dl_debug_mask) & DL_DEBUG_FILES, 0)
|
||||
&& loader != NULL)
|
||||
_dl_debug_printf ("\nfile=%s; needed by %s\n", name,
|
||||
_dl_debug_printf ("\nfile=%s [%lu]; needed by %s [%lu]\n", name, nsid,
|
||||
loader->l_name[0]
|
||||
? loader->l_name : rtld_progname);
|
||||
? loader->l_name : rtld_progname, loader->l_ns);
|
||||
|
||||
if (strchr (name, '/') == NULL)
|
||||
{
|
||||
@@ -1826,7 +1854,7 @@ _dl_map_object (struct link_map *loader, const char *name, int preloaded,
|
||||
size_t namelen = strlen (name) + 1;
|
||||
|
||||
if (__builtin_expect (GLRO(dl_debug_mask) & DL_DEBUG_LIBS, 0))
|
||||
_dl_debug_printf ("find library=%s; searching\n", name);
|
||||
_dl_debug_printf ("find library=%s [%lu]; searching\n", name, nsid);
|
||||
|
||||
fd = -1;
|
||||
|
||||
@@ -1842,12 +1870,15 @@ _dl_map_object (struct link_map *loader, const char *name, int preloaded,
|
||||
&realname, &fb);
|
||||
|
||||
/* If dynamically linked, try the DT_RPATH of the executable
|
||||
itself. */
|
||||
l = GL(dl_loaded);
|
||||
if (fd == -1 && l && l->l_type != lt_loaded && l != loader
|
||||
&& l->l_rpath_dirs.dirs != (void *) -1)
|
||||
fd = open_path (name, namelen, preloaded, &l->l_rpath_dirs,
|
||||
&realname, &fb);
|
||||
itself. NB: we do this for lookups in any namespace. */
|
||||
if (fd == -1)
|
||||
{
|
||||
l = GL(dl_ns)[LM_ID_BASE]._ns_loaded;
|
||||
if (l && l->l_type != lt_loaded && l != loader
|
||||
&& l->l_rpath_dirs.dirs != (void *) -1)
|
||||
fd = open_path (name, namelen, preloaded, &l->l_rpath_dirs,
|
||||
&realname, &fb);
|
||||
}
|
||||
}
|
||||
|
||||
/* Try the LD_LIBRARY_PATH environment variable. */
|
||||
@@ -1873,7 +1904,8 @@ _dl_map_object (struct link_map *loader, const char *name, int preloaded,
|
||||
if (cached != NULL)
|
||||
{
|
||||
#ifdef SHARED
|
||||
l = loader ?: GL(dl_loaded);
|
||||
// XXX Correct to unconditionally default to namespace 0?
|
||||
l = loader ?: GL(dl_ns)[LM_ID_BASE]._ns_loaded;
|
||||
#else
|
||||
l = loader;
|
||||
#endif
|
||||
@@ -1923,7 +1955,7 @@ _dl_map_object (struct link_map *loader, const char *name, int preloaded,
|
||||
|
||||
/* Finally, try the default path. */
|
||||
if (fd == -1
|
||||
&& ((l = loader ?: GL(dl_loaded)) == NULL
|
||||
&& ((l = loader ?: GL(dl_ns)[nsid]._ns_loaded) == NULL
|
||||
|| __builtin_expect (!(l->l_flags_1 & DF_1_NODEFLIB), 1))
|
||||
&& rtld_search_dirs.dirs != (void *) -1)
|
||||
fd = open_path (name, namelen, preloaded, &rtld_search_dirs,
|
||||
@@ -1968,7 +2000,8 @@ _dl_map_object (struct link_map *loader, const char *name, int preloaded,
|
||||
|
||||
/* Enter the new object in the list of loaded objects. */
|
||||
if ((name_copy = local_strdup (name)) == NULL
|
||||
|| (l = _dl_new_object (name_copy, name, type, loader)) == NULL)
|
||||
|| (l = _dl_new_object (name_copy, name, type, loader,
|
||||
mode, nsid)) == NULL)
|
||||
_dl_signal_error (ENOMEM, name, NULL,
|
||||
N_("cannot create shared object descriptor"));
|
||||
/* Signal that this is a faked entry. */
|
||||
@@ -1989,7 +2022,7 @@ _dl_map_object (struct link_map *loader, const char *name, int preloaded,
|
||||
|
||||
void *stack_end = __libc_stack_end;
|
||||
return _dl_map_object_from_fd (name, fd, &fb, realname, loader, type, mode,
|
||||
&stack_end);
|
||||
&stack_end, nsid);
|
||||
}
|
||||
|
||||
|
||||
@@ -2049,10 +2082,13 @@ _dl_rtld_di_serinfo (struct link_map *loader, Dl_serinfo *si, bool counting)
|
||||
while (l != NULL);
|
||||
|
||||
/* If dynamically linked, try the DT_RPATH of the executable itself. */
|
||||
l = GL(dl_loaded);
|
||||
if (l != NULL && l->l_type != lt_loaded && l != loader)
|
||||
if (cache_rpath (l, &l->l_rpath_dirs, DT_RPATH, "RPATH"))
|
||||
add_path (&l->l_rpath_dirs, XXX_RPATH);
|
||||
if (loader->l_ns == LM_ID_BASE)
|
||||
{
|
||||
l = GL(dl_ns)[LM_ID_BASE]._ns_loaded;
|
||||
if (l != NULL && l->l_type != lt_loaded && l != loader)
|
||||
if (cache_rpath (l, &l->l_rpath_dirs, DT_RPATH, "RPATH"))
|
||||
add_path (&l->l_rpath_dirs, XXX_RPATH);
|
||||
}
|
||||
}
|
||||
|
||||
/* Try the LD_LIBRARY_PATH environment variable. */
|
||||
|
||||
+12
-7
@@ -137,7 +137,7 @@ add_dependency (struct link_map *undef_map, struct link_map *map)
|
||||
reference is still available. There is a brief period in
|
||||
which the object could have been removed since we found the
|
||||
definition. */
|
||||
runp = GL(dl_loaded);
|
||||
runp = GL(dl_ns)[undef_map->l_ns]._ns_loaded;
|
||||
while (runp != NULL && runp != map)
|
||||
runp = runp->l_next;
|
||||
|
||||
@@ -182,13 +182,18 @@ add_dependency (struct link_map *undef_map, struct link_map *map)
|
||||
for (list = map->l_initfini; *list != NULL; ++list)
|
||||
++(*list)->l_opencount;
|
||||
|
||||
/* As if it is opened through _dl_open. */
|
||||
++map->l_direct_opencount;
|
||||
|
||||
/* Display information if we are debugging. */
|
||||
if (__builtin_expect (GLRO(dl_debug_mask) & DL_DEBUG_FILES, 0))
|
||||
_dl_debug_printf ("\
|
||||
\nfile=%s; needed by %s (relocation dependency)\n\n",
|
||||
\nfile=%s [%lu]; needed by %s [%lu] (relocation dependency)\n\n",
|
||||
map->l_name[0] ? map->l_name : rtld_progname,
|
||||
map->l_ns,
|
||||
undef_map->l_name[0]
|
||||
? undef_map->l_name : rtld_progname);
|
||||
? undef_map->l_name : rtld_progname,
|
||||
undef_map->l_ns);
|
||||
}
|
||||
else
|
||||
/* Whoa, that was bad luck. We have to search again. */
|
||||
@@ -408,8 +413,8 @@ _dl_debug_bindings (const char *undef_name, struct link_map *undef_map,
|
||||
struct sym_val val = { NULL, NULL };
|
||||
|
||||
if ((GLRO(dl_trace_prelink_map) == NULL
|
||||
|| GLRO(dl_trace_prelink_map) == GL(dl_loaded))
|
||||
&& undef_map != GL(dl_loaded))
|
||||
|| GLRO(dl_trace_prelink_map) == GL(dl_ns)[LM_ID_BASE]._ns_loaded)
|
||||
&& undef_map != GL(dl_ns)[LM_ID_BASE]._ns_loaded)
|
||||
{
|
||||
const unsigned long int hash = _dl_elf_hash (undef_name);
|
||||
|
||||
@@ -421,12 +426,12 @@ _dl_debug_bindings (const char *undef_name, struct link_map *undef_map,
|
||||
conflict = 1;
|
||||
}
|
||||
|
||||
#ifdef USE_TLS
|
||||
# ifdef USE_TLS
|
||||
if (value->s
|
||||
&& (__builtin_expect (ELFW(ST_TYPE) (value->s->st_info)
|
||||
== STT_TLS, 0)))
|
||||
type_class = 4;
|
||||
#endif
|
||||
# endif
|
||||
|
||||
if (conflict
|
||||
|| GLRO(dl_trace_prelink_map) == undef_map
|
||||
|
||||
+17
-7
@@ -32,7 +32,7 @@
|
||||
struct link_map *
|
||||
internal_function
|
||||
_dl_new_object (char *realname, const char *libname, int type,
|
||||
struct link_map *loader)
|
||||
struct link_map *loader, int mode, Lmid_t nsid)
|
||||
{
|
||||
struct link_map *l;
|
||||
int idx;
|
||||
@@ -45,6 +45,7 @@ _dl_new_object (char *realname, const char *libname, int type,
|
||||
if (new == NULL)
|
||||
return NULL;
|
||||
|
||||
new->l_real = new;
|
||||
new->l_libname = newname = (struct libname_list *) (new + 1);
|
||||
newname->name = (char *) memcpy (newname + 1, libname, libname_len);
|
||||
/* newname->next = NULL; We use calloc therefore not necessary. */
|
||||
@@ -56,6 +57,7 @@ _dl_new_object (char *realname, const char *libname, int type,
|
||||
#if defined USE_TLS && NO_TLS_OFFSET != 0
|
||||
new->l_tls_offset = NO_TLS_OFFSET;
|
||||
#endif
|
||||
new->l_ns = nsid;
|
||||
|
||||
/* new->l_global = 0; We use calloc therefore not necessary. */
|
||||
|
||||
@@ -68,9 +70,9 @@ _dl_new_object (char *realname, const char *libname, int type,
|
||||
/* Counter for the scopes we have to handle. */
|
||||
idx = 0;
|
||||
|
||||
if (GL(dl_loaded) != NULL)
|
||||
if (GL(dl_ns)[nsid]._ns_loaded != NULL)
|
||||
{
|
||||
l = GL(dl_loaded);
|
||||
l = GL(dl_ns)[nsid]._ns_loaded;
|
||||
while (l->l_next != NULL)
|
||||
l = l->l_next;
|
||||
new->l_prev = l;
|
||||
@@ -78,11 +80,11 @@ _dl_new_object (char *realname, const char *libname, int type,
|
||||
l->l_next = new;
|
||||
|
||||
/* Add the global scope. */
|
||||
new->l_scope[idx++] = &GL(dl_loaded)->l_searchlist;
|
||||
new->l_scope[idx++] = &GL(dl_ns)[nsid]._ns_loaded->l_searchlist;
|
||||
}
|
||||
else
|
||||
GL(dl_loaded) = new;
|
||||
++GL(dl_nloaded);
|
||||
GL(dl_ns)[nsid]._ns_loaded = new;
|
||||
++GL(dl_ns)[nsid]._ns_nloaded;
|
||||
++GL(dl_load_adds);
|
||||
|
||||
/* If we have no loader the new object acts as it. */
|
||||
@@ -95,7 +97,15 @@ _dl_new_object (char *realname, const char *libname, int type,
|
||||
|
||||
/* Insert the scope if it isn't the global scope we already added. */
|
||||
if (idx == 0 || &loader->l_searchlist != new->l_scope[0])
|
||||
new->l_scope[idx] = &loader->l_searchlist;
|
||||
{
|
||||
if ((mode & RTLD_DEEPBIND) != 0 && idx != 0)
|
||||
{
|
||||
new->l_scope[1] = new->l_scope[0];
|
||||
idx = 0;
|
||||
}
|
||||
|
||||
new->l_scope[idx] = &loader->l_searchlist;
|
||||
}
|
||||
|
||||
new->l_local_scope[0] = &new->l_searchlist;
|
||||
|
||||
|
||||
+86
-46
@@ -72,6 +72,8 @@ struct dl_open_args
|
||||
/* This is the caller if _dl_open(). */
|
||||
const void *caller_dl_open;
|
||||
struct link_map *map;
|
||||
/* Namespace ID. */
|
||||
Lmid_t nsid;
|
||||
};
|
||||
|
||||
|
||||
@@ -101,15 +103,17 @@ add_to_global (struct link_map *new)
|
||||
in an realloc() call. Therefore we allocate a completely new
|
||||
array the first time we have to add something to the locale scope. */
|
||||
|
||||
if (GL(dl_global_scope_alloc) == 0)
|
||||
if (GL(dl_ns)[new->l_ns]._ns_global_scope_alloc == 0)
|
||||
{
|
||||
/* This is the first dynamic object given global scope. */
|
||||
GL(dl_global_scope_alloc) = GL(dl_main_searchlist)->r_nlist + to_add + 8;
|
||||
GL(dl_ns)[new->l_ns]._ns_global_scope_alloc
|
||||
= GL(dl_ns)[new->l_ns]._ns_main_searchlist->r_nlist + to_add + 8;
|
||||
new_global = (struct link_map **)
|
||||
malloc (GL(dl_global_scope_alloc) * sizeof (struct link_map *));
|
||||
malloc (GL(dl_ns)[new->l_ns]._ns_global_scope_alloc
|
||||
* sizeof (struct link_map *));
|
||||
if (new_global == NULL)
|
||||
{
|
||||
GL(dl_global_scope_alloc) = 0;
|
||||
GL(dl_ns)[new->l_ns]._ns_global_scope_alloc = 0;
|
||||
nomem:
|
||||
GLRO(dl_signal_error) (ENOMEM, new->l_libname->name, NULL,
|
||||
N_("cannot extend global scope"));
|
||||
@@ -117,25 +121,26 @@ add_to_global (struct link_map *new)
|
||||
}
|
||||
|
||||
/* Copy over the old entries. */
|
||||
memcpy (new_global, GL(dl_main_searchlist)->r_list,
|
||||
(GL(dl_main_searchlist)->r_nlist * sizeof (struct link_map *)));
|
||||
|
||||
GL(dl_main_searchlist)->r_list = new_global;
|
||||
GL(dl_ns)[new->l_ns]._ns_main_searchlist->r_list
|
||||
= memcpy (new_global,
|
||||
GL(dl_ns)[new->l_ns]._ns_main_searchlist->r_list,
|
||||
(GL(dl_ns)[new->l_ns]._ns_main_searchlist->r_nlist
|
||||
* sizeof (struct link_map *)));
|
||||
}
|
||||
else if (GL(dl_main_searchlist)->r_nlist + to_add
|
||||
> GL(dl_global_scope_alloc))
|
||||
else if (GL(dl_ns)[new->l_ns]._ns_main_searchlist->r_nlist + to_add
|
||||
> GL(dl_ns)[new->l_ns]._ns_global_scope_alloc)
|
||||
{
|
||||
/* We have to extend the existing array of link maps in the
|
||||
main map. */
|
||||
new_global = (struct link_map **)
|
||||
realloc (GL(dl_main_searchlist)->r_list,
|
||||
((GL(dl_global_scope_alloc) + to_add + 8)
|
||||
realloc (GL(dl_ns)[new->l_ns]._ns_main_searchlist->r_list,
|
||||
((GL(dl_ns)[new->l_ns]._ns_global_scope_alloc + to_add + 8)
|
||||
* sizeof (struct link_map *)));
|
||||
if (new_global == NULL)
|
||||
goto nomem;
|
||||
|
||||
GL(dl_global_scope_alloc) += to_add + 8;
|
||||
GL(dl_main_searchlist)->r_list = new_global;
|
||||
GL(dl_ns)[new->l_ns]._ns_global_scope_alloc += to_add + 8;
|
||||
GL(dl_ns)[new->l_ns]._ns_main_searchlist->r_list = new_global;
|
||||
}
|
||||
|
||||
/* Now add the new entries. */
|
||||
@@ -146,9 +151,9 @@ add_to_global (struct link_map *new)
|
||||
if (map->l_global == 0)
|
||||
{
|
||||
map->l_global = 1;
|
||||
GL(dl_main_searchlist)->r_list[GL(dl_main_searchlist)->r_nlist]
|
||||
GL(dl_ns)[new->l_ns]._ns_main_searchlist->r_list[GL(dl_ns)[new->l_ns]._ns_main_searchlist->r_nlist]
|
||||
= map;
|
||||
++GL(dl_main_searchlist)->r_nlist;
|
||||
++GL(dl_ns)[new->l_ns]._ns_main_searchlist->r_nlist;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -175,28 +180,34 @@ dl_open_worker (void *a)
|
||||
GLRO(dl_signal_error) (0, "dlopen", NULL, N_("invalid caller"));
|
||||
|
||||
/* Determine the caller's map if necessary. This is needed in case
|
||||
we have a DST or when the file name has no path in which case we
|
||||
need to look along the RUNPATH/RPATH of the caller. */
|
||||
we have a DST, when we don't know the namespace ID we have to put
|
||||
the new object in, or when the file name has no path in which
|
||||
case we need to look along the RUNPATH/RPATH of the caller. */
|
||||
const char *dst = strchr (file, '$');
|
||||
if (dst != NULL || strchr (file, '/') == NULL)
|
||||
if (dst != NULL || args->nsid == __LM_ID_CALLER
|
||||
|| strchr (file, '/') == NULL)
|
||||
{
|
||||
const void *caller_dlopen = args->caller_dlopen;
|
||||
|
||||
/* We have to find out from which object the caller is calling. */
|
||||
call_map = NULL;
|
||||
for (l = GL(dl_loaded); l; l = l->l_next)
|
||||
if (caller_dlopen >= (const void *) l->l_map_start
|
||||
&& caller_dlopen < (const void *) l->l_map_end)
|
||||
{
|
||||
/* There must be exactly one DSO for the range of the virtual
|
||||
memory. Otherwise something is really broken. */
|
||||
call_map = l;
|
||||
break;
|
||||
}
|
||||
/* We have to find out from which object the caller is calling.
|
||||
By default we assume this is the main application. */
|
||||
call_map = GL(dl_ns)[LM_ID_BASE]._ns_loaded;
|
||||
|
||||
if (call_map == NULL)
|
||||
/* In this case we assume this is the main application. */
|
||||
call_map = GL(dl_loaded);
|
||||
for (Lmid_t ns = 0; ns < DL_NNS; ++ns)
|
||||
for (l = GL(dl_ns)[ns]._ns_loaded; l != NULL; l = l->l_next)
|
||||
if (caller_dlopen >= (const void *) l->l_map_start
|
||||
&& caller_dlopen < (const void *) l->l_map_end)
|
||||
{
|
||||
/* There must be exactly one DSO for the range of the virtual
|
||||
memory. Otherwise something is really broken. */
|
||||
assert (ns == l->l_ns);
|
||||
call_map = l;
|
||||
goto found_caller;
|
||||
}
|
||||
|
||||
found_caller:
|
||||
if (args->nsid == __LM_ID_CALLER)
|
||||
args->nsid = call_map->l_ns;
|
||||
}
|
||||
|
||||
/* Maybe we have to expand a DST. */
|
||||
@@ -238,7 +249,7 @@ dl_open_worker (void *a)
|
||||
|
||||
/* Load the named object. */
|
||||
args->map = new = GLRO(dl_map_object) (call_map, file, 0, lt_loaded, 0,
|
||||
mode | __RTLD_CALLMAP);
|
||||
mode | __RTLD_CALLMAP, args->nsid);
|
||||
|
||||
/* If the pointer returned is NULL this means the RTLD_NOLOAD flag is
|
||||
set and the object is not already loaded. */
|
||||
@@ -252,32 +263,43 @@ dl_open_worker (void *a)
|
||||
/* This happens only if we load a DSO for 'sprof'. */
|
||||
return;
|
||||
|
||||
/* This object is directly loaded. */
|
||||
++new->l_direct_opencount;
|
||||
|
||||
/* It was already open. */
|
||||
if (__builtin_expect (new->l_searchlist.r_list != NULL, 0))
|
||||
{
|
||||
/* Let the user know about the opencount. */
|
||||
if (__builtin_expect (GLRO(dl_debug_mask) & DL_DEBUG_FILES, 0))
|
||||
GLRO(dl_debug_printf) ("opening file=%s; opencount == %u\n\n",
|
||||
new->l_name, new->l_opencount);
|
||||
GLRO(dl_debug_printf) ("opening file=%s [%lu]; opencount=%u\n\n",
|
||||
new->l_name, new->l_ns, new->l_opencount);
|
||||
|
||||
/* If the user requested the object to be in the global namespace
|
||||
but it is not so far, add it now. */
|
||||
if ((mode & RTLD_GLOBAL) && new->l_global == 0)
|
||||
(void) add_to_global (new);
|
||||
|
||||
/* Increment just the reference counter of the object. */
|
||||
++new->l_opencount;
|
||||
if (new->l_direct_opencount == 1)
|
||||
/* This is the only direct reference. Increment all the
|
||||
dependencies' reference counter. */
|
||||
for (i = 0; i < new->l_searchlist.r_nlist; ++i)
|
||||
++new->l_searchlist.r_list[i]->l_opencount;
|
||||
else
|
||||
/* Increment just the reference counter of the object. */
|
||||
++new->l_opencount;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/* Load that object's dependencies. */
|
||||
GLRO(dl_map_object_deps) (new, NULL, 0, 0, mode & __RTLD_DLOPEN);
|
||||
GLRO(dl_map_object_deps) (new, NULL, 0, 0,
|
||||
mode & (__RTLD_DLOPEN | RTLD_DEEPBIND));
|
||||
|
||||
/* So far, so good. Now check the versions. */
|
||||
for (i = 0; i < new->l_searchlist.r_nlist; ++i)
|
||||
if (new->l_searchlist.r_list[i]->l_versions == NULL)
|
||||
(void) GLRO(dl_check_map_versions) (new->l_searchlist.r_list[i], 0, 0);
|
||||
if (new->l_searchlist.r_list[i]->l_real->l_versions == NULL)
|
||||
(void) GLRO(dl_check_map_versions) (new->l_searchlist.r_list[i]->l_real,
|
||||
0, 0);
|
||||
|
||||
#ifdef SCOPE_DEBUG
|
||||
show_scope (new);
|
||||
@@ -294,7 +316,7 @@ dl_open_worker (void *a)
|
||||
l = l->l_next;
|
||||
while (1)
|
||||
{
|
||||
if (! l->l_relocated)
|
||||
if (! l->l_real->l_relocated)
|
||||
{
|
||||
#ifdef SHARED
|
||||
if (GLRO(dl_profile) != NULL)
|
||||
@@ -348,7 +370,7 @@ dl_open_worker (void *a)
|
||||
loaded object to the scope. */
|
||||
for (i = 0; i < new->l_searchlist.r_nlist; ++i)
|
||||
if (++new->l_searchlist.r_list[i]->l_opencount > 1
|
||||
&& new->l_searchlist.r_list[i]->l_type == lt_loaded)
|
||||
&& new->l_real->l_searchlist.r_list[i]->l_type == lt_loaded)
|
||||
{
|
||||
struct link_map *imap = new->l_searchlist.r_list[i];
|
||||
struct r_scope_elem **runp = imap->l_scope;
|
||||
@@ -502,14 +524,14 @@ cannot create TLS data structures"));
|
||||
|
||||
/* Let the user know about the opencount. */
|
||||
if (__builtin_expect (GLRO(dl_debug_mask) & DL_DEBUG_FILES, 0))
|
||||
GLRO(dl_debug_printf) ("opening file=%s; opencount == %u\n\n",
|
||||
new->l_name, new->l_opencount);
|
||||
GLRO(dl_debug_printf) ("opening file=%s [%lu]; opencount=%u\n\n",
|
||||
new->l_name, new->l_ns, new->l_opencount);
|
||||
}
|
||||
|
||||
|
||||
void *
|
||||
internal_function
|
||||
_dl_open (const char *file, int mode, const void *caller_dlopen)
|
||||
_dl_open (const char *file, int mode, const void *caller_dlopen, Lmid_t nsid)
|
||||
{
|
||||
struct dl_open_args args;
|
||||
const char *objname;
|
||||
@@ -524,11 +546,29 @@ _dl_open (const char *file, int mode, const void *caller_dlopen)
|
||||
/* Make sure we are alone. */
|
||||
__rtld_lock_lock_recursive (GL(dl_load_lock));
|
||||
|
||||
if (nsid == LM_ID_NEWLM)
|
||||
{
|
||||
/* Find a new namespace. */
|
||||
for (nsid = 1; nsid < DL_NNS; ++nsid)
|
||||
if (GL(dl_ns)[nsid]._ns_loaded == NULL)
|
||||
break;
|
||||
|
||||
if (nsid == DL_NNS)
|
||||
{
|
||||
/* No more namespace available. */
|
||||
__rtld_lock_unlock_recursive (GL(dl_load_lock));
|
||||
|
||||
GLRO(dl_signal_error) (EINVAL, file, NULL, N_("\
|
||||
no more namespaces available for dlmopen()"));
|
||||
}
|
||||
}
|
||||
|
||||
args.file = file;
|
||||
args.mode = mode;
|
||||
args.caller_dlopen = caller_dlopen;
|
||||
args.caller_dl_open = RETURN_ADDRESS (0);
|
||||
args.map = NULL;
|
||||
args.nsid = nsid;
|
||||
errcode = GLRO(dl_catch_error) (&objname, &errstring, dl_open_worker, &args);
|
||||
|
||||
#ifndef MAP_COPY
|
||||
|
||||
+17
-25
@@ -67,10 +67,8 @@ const char *_dl_origin_path;
|
||||
/* Nonzero if runtime lookup should not update the .got/.plt. */
|
||||
int _dl_bind_not;
|
||||
|
||||
/* Initially empty list of loaded objects. */
|
||||
struct link_map *_dl_loaded;
|
||||
/* Number of object in the _dl_loaded list. */
|
||||
unsigned int _dl_nloaded;
|
||||
/* Namespace information. */
|
||||
struct link_namespaces _dl_ns[DL_NNS];
|
||||
|
||||
/* Incremented whenever something may have been added to dl_loaded. */
|
||||
unsigned long long _dl_load_adds;
|
||||
@@ -79,12 +77,6 @@ unsigned long long _dl_load_adds;
|
||||
main application but here we don't have something like this. So
|
||||
create a fake scope containing nothing. */
|
||||
struct r_scope_elem _dl_initial_searchlist;
|
||||
/* Variable which can be used in lookup to process the global scope. */
|
||||
struct r_scope_elem *_dl_global_scope[2] = { &_dl_initial_searchlist, NULL };
|
||||
/* This is a global pointer to this structure which is public. It is
|
||||
used by dlopen/dlclose to add and remove objects from what is regarded
|
||||
to be the global scope. */
|
||||
struct r_scope_elem *_dl_main_searchlist = &_dl_initial_searchlist;
|
||||
|
||||
#ifndef HAVE_INLINED_SYSCALLS
|
||||
/* Nonzero during startup. */
|
||||
@@ -109,11 +101,6 @@ hp_timing_t _dl_cpuclock_offset;
|
||||
void (*_dl_init_static_tls) (struct link_map *) = &_dl_nothread_init_static_tls;
|
||||
#endif
|
||||
|
||||
/* This is zero at program start to signal that the global scope map is
|
||||
allocated by rtld. Later it keeps the size of the map. It might be
|
||||
reset if in _dl_close if the last global object is removed. */
|
||||
size_t _dl_global_scope_alloc;
|
||||
|
||||
size_t _dl_pagesize;
|
||||
|
||||
unsigned int _dl_osversion;
|
||||
@@ -257,22 +244,22 @@ _dl_non_dynamic_init (void)
|
||||
|
||||
if (__libc_enable_secure)
|
||||
{
|
||||
static const char *unsecure_envvars[] =
|
||||
{
|
||||
UNSECURE_ENVVARS,
|
||||
static const char unsecure_envvars[] =
|
||||
UNSECURE_ENVVARS
|
||||
#ifdef EXTRA_UNSECURE_ENVVARS
|
||||
EXTRA_UNSECURE_ENVVARS
|
||||
#endif
|
||||
};
|
||||
size_t cnt;
|
||||
;
|
||||
const char *cp = unsecure_envvars;
|
||||
|
||||
for (cnt = 0;
|
||||
cnt < sizeof (unsecure_envvars) / sizeof (unsecure_envvars[0]);
|
||||
++cnt)
|
||||
unsetenv (unsecure_envvars[cnt]);
|
||||
while (cp < unsecure_envvars + sizeof (unsecure_envvars))
|
||||
{
|
||||
__unsetenv (cp);
|
||||
cp = (const char *) __rawmemchr (cp, '\0') + 1;
|
||||
}
|
||||
|
||||
if (__access ("/etc/suid-debug", F_OK) != 0)
|
||||
unsetenv ("MALLOC_CHECK_");
|
||||
__unsetenv ("MALLOC_CHECK_");
|
||||
}
|
||||
|
||||
#ifdef DL_PLATFORM_INIT
|
||||
@@ -287,6 +274,11 @@ _dl_non_dynamic_init (void)
|
||||
if (_dl_platform != NULL)
|
||||
_dl_platformlen = strlen (_dl_platform);
|
||||
|
||||
#if defined (__i386__) && !defined (USE_TLS)
|
||||
/* Load libs not using TLS. */
|
||||
_dl_osversion = 0x20205;
|
||||
#endif
|
||||
|
||||
/* Scan for a program header telling us the stack is nonexecutable. */
|
||||
if (_dl_phdr != NULL)
|
||||
for (uint_fast16_t i = 0; i < _dl_phnum; ++i)
|
||||
|
||||
+15
-13
@@ -69,17 +69,19 @@ do_sym (void *handle, const char *name, void *who,
|
||||
|
||||
/* If the address is not recognized the call comes from the main
|
||||
program (we hope). */
|
||||
struct link_map *match = GL(dl_loaded);
|
||||
struct link_map *match = GL(dl_ns)[LM_ID_BASE]._ns_loaded;
|
||||
|
||||
/* Find the highest-addressed object that CALLER is not below. */
|
||||
for (struct link_map *l = GL(dl_loaded); l != NULL; l = l->l_next)
|
||||
if (caller >= l->l_map_start && caller < l->l_map_end)
|
||||
{
|
||||
/* There must be exactly one DSO for the range of the virtual
|
||||
memory. Otherwise something is really broken. */
|
||||
match = l;
|
||||
break;
|
||||
}
|
||||
for (Lmid_t ns = 0; ns < DL_NNS; ++ns)
|
||||
for (struct link_map *l = GL(dl_ns)[ns]._ns_loaded; l != NULL;
|
||||
l = l->l_next)
|
||||
if (caller >= l->l_map_start && caller < l->l_map_end)
|
||||
{
|
||||
/* There must be exactly one DSO for the range of the virtual
|
||||
memory. Otherwise something is really broken. */
|
||||
match = l;
|
||||
break;
|
||||
}
|
||||
|
||||
if (handle == RTLD_DEFAULT)
|
||||
/* Search the global scope. */
|
||||
@@ -88,11 +90,11 @@ do_sym (void *handle, const char *name, void *who,
|
||||
NULL);
|
||||
else if (handle == RTLD_NEXT)
|
||||
{
|
||||
if (__builtin_expect (match == GL(dl_loaded), 0))
|
||||
if (__builtin_expect (match == GL(dl_ns)[LM_ID_BASE]._ns_loaded, 0))
|
||||
{
|
||||
if (! GL(dl_loaded)
|
||||
|| caller < GL(dl_loaded)->l_map_start
|
||||
|| caller >= GL(dl_loaded)->l_map_end)
|
||||
if (match == NULL
|
||||
|| caller < match->l_map_start
|
||||
|| caller >= match->l_map_end)
|
||||
GLRO(dl_signal_error) (0, NULL, NULL, N_("\
|
||||
RTLD_NEXT used in code not dynamically loaded"));
|
||||
}
|
||||
|
||||
+3
-2
@@ -59,7 +59,8 @@ find_needed (const char *name, struct link_map *map)
|
||||
struct link_map *tmap;
|
||||
unsigned int n;
|
||||
|
||||
for (tmap = GL(dl_loaded); tmap != NULL; tmap = tmap->l_next)
|
||||
for (tmap = GL(dl_ns)[map->l_ns]._ns_loaded; tmap != NULL;
|
||||
tmap = tmap->l_next)
|
||||
if (_dl_name_match_p (name, tmap))
|
||||
return tmap;
|
||||
|
||||
@@ -243,7 +244,7 @@ _dl_check_map_versions (struct link_map *map, int verbose, int trace_mode)
|
||||
? map->l_name : rtld_progname),
|
||||
aux->vna_hash,
|
||||
strtab + aux->vna_name,
|
||||
needed, verbose,
|
||||
needed->l_real, verbose,
|
||||
aux->vna_flags & VER_FLG_WEAK);
|
||||
|
||||
/* Compare the version index. */
|
||||
|
||||
+1
-1
@@ -42,7 +42,7 @@ do_lookup_x (const char *undef_name, unsigned long int hash,
|
||||
int num_versions = 0;
|
||||
const ElfW(Sym) *versioned_sym = NULL;
|
||||
|
||||
map = list[i];
|
||||
map = list[i]->l_real;
|
||||
|
||||
/* Here come the extra test needed for `_dl_lookup_symbol_skip'. */
|
||||
if (skip != NULL && map == skip)
|
||||
|
||||
+2
-2
@@ -1,5 +1,5 @@
|
||||
/* Do relocations for ELF dynamic linking.
|
||||
Copyright (C) 1995-2002, 2003 Free Software Foundation, Inc.
|
||||
Copyright (C) 1995-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
|
||||
@@ -49,7 +49,7 @@
|
||||
relocations; they should be set up to call _dl_runtime_resolve, rather
|
||||
than fully resolved now. */
|
||||
|
||||
static inline void __attribute__ ((always_inline))
|
||||
auto inline void __attribute__ ((always_inline))
|
||||
elf_dynamic_do_rel (struct link_map *map,
|
||||
ElfW(Addr) reladdr, ElfW(Addr) relsize,
|
||||
int lazy)
|
||||
|
||||
+6
-2
@@ -64,8 +64,12 @@ elf_machine_lazy_rel (struct link_map *map,
|
||||
|
||||
|
||||
/* Read the dynamic section at DYN and fill in INFO with indices DT_*. */
|
||||
|
||||
static inline void __attribute__ ((unused, always_inline))
|
||||
#ifndef RESOLVE
|
||||
static
|
||||
#else
|
||||
auto
|
||||
#endif
|
||||
inline void __attribute__ ((unused, always_inline))
|
||||
elf_get_dynamic_info (struct link_map *l, ElfW(Dyn) *temp)
|
||||
{
|
||||
ElfW(Dyn) *dyn = l->l_ld;
|
||||
|
||||
+19
-6
@@ -944,17 +944,19 @@ search_dirs (void)
|
||||
|
||||
|
||||
static void parse_conf_include (const char *config_file, unsigned int lineno,
|
||||
bool do_chroot, const char *pattern);
|
||||
const char *prefix, bool do_chroot,
|
||||
const char *pattern);
|
||||
|
||||
/* Parse configuration file. */
|
||||
static void
|
||||
parse_conf (const char *filename, bool do_chroot)
|
||||
parse_conf (const char *filename, const char *prefix, bool do_chroot)
|
||||
{
|
||||
FILE *file = NULL;
|
||||
char *line = NULL;
|
||||
const char *canon;
|
||||
size_t len = 0;
|
||||
unsigned int lineno;
|
||||
size_t prefix_len = prefix ? strlen (prefix) : 0;
|
||||
|
||||
if (do_chroot && opt_chroot)
|
||||
{
|
||||
@@ -1015,7 +1017,14 @@ parse_conf (const char *filename, bool do_chroot)
|
||||
cp += 8;
|
||||
while ((dir = strsep (&cp, " \t")) != NULL)
|
||||
if (dir[0] != '\0')
|
||||
parse_conf_include (filename, lineno, do_chroot, dir);
|
||||
parse_conf_include (filename, lineno, prefix, do_chroot, dir);
|
||||
}
|
||||
else if (prefix != NULL)
|
||||
{
|
||||
size_t cp_len = strlen (cp);
|
||||
char new_cp [prefix_len + cp_len + 1];
|
||||
memcpy (mempcpy (new_cp, prefix, prefix_len), cp, cp_len + 1);
|
||||
add_dir (new_cp);
|
||||
}
|
||||
else
|
||||
add_dir (cp);
|
||||
@@ -1031,7 +1040,7 @@ parse_conf (const char *filename, bool do_chroot)
|
||||
config files to read. */
|
||||
static void
|
||||
parse_conf_include (const char *config_file, unsigned int lineno,
|
||||
bool do_chroot, const char *pattern)
|
||||
const char *prefix, bool do_chroot, const char *pattern)
|
||||
{
|
||||
if (opt_chroot && pattern[0] != '/')
|
||||
error (EXIT_FAILURE, 0,
|
||||
@@ -1061,7 +1070,7 @@ parse_conf_include (const char *config_file, unsigned int lineno,
|
||||
{
|
||||
case 0:
|
||||
for (size_t i = 0; i < gl.gl_pathc; ++i)
|
||||
parse_conf (gl.gl_pathv[i], false);
|
||||
parse_conf (gl.gl_pathv[i], prefix, false);
|
||||
globfree64 (&gl);
|
||||
break;
|
||||
|
||||
@@ -1101,6 +1110,8 @@ main (int argc, char **argv)
|
||||
{
|
||||
int remaining;
|
||||
|
||||
arch_startup (argc, argv);
|
||||
|
||||
/* Parse and process arguments. */
|
||||
argp_parse (&argp, argc, argv, 0, &remaining, NULL);
|
||||
|
||||
@@ -1209,12 +1220,14 @@ main (int argc, char **argv)
|
||||
|
||||
if (!opt_only_cline)
|
||||
{
|
||||
parse_conf (config_file, true);
|
||||
parse_conf (config_file, NULL, true);
|
||||
|
||||
/* Always add the standard search paths. */
|
||||
add_system_dir (SLIBDIR);
|
||||
if (strcmp (SLIBDIR, LIBDIR))
|
||||
add_system_dir (LIBDIR);
|
||||
|
||||
add_arch_dirs (config_file);
|
||||
}
|
||||
|
||||
search_dirs ();
|
||||
|
||||
+9
-1
@@ -105,7 +105,15 @@ process_file (const char *real_file_name, const char *file_name,
|
||||
if ((size_t) statbuf.st_size < sizeof (struct exec)
|
||||
|| (size_t) statbuf.st_size < sizeof (ElfW(Ehdr)))
|
||||
{
|
||||
error (0, 0, _("File %s is too small, not checked."), file_name);
|
||||
if (statbuf.st_size == 0)
|
||||
error (0, 0, _("File %s is empty, not checked."), file_name);
|
||||
else
|
||||
{
|
||||
char buf[SELFMAG];
|
||||
size_t n = MIN (statbuf.st_size, SELFMAG);
|
||||
if (fread (buf, n, 1, file) == 1 && memcmp (buf, ELFMAG, n) == 0)
|
||||
error (0, 0, _("File %s is too small, not checked."), file_name);
|
||||
}
|
||||
fclose (file);
|
||||
return 1;
|
||||
}
|
||||
|
||||
+242
-119
@@ -269,6 +269,7 @@ _dl_start_final (void *arg, struct dl_start_final_info *info)
|
||||
GL(dl_rtld_map).l_mach = info->l.l_mach;
|
||||
#endif
|
||||
_dl_setup_hash (&GL(dl_rtld_map));
|
||||
GL(dl_rtld_map).l_real = &GL(dl_rtld_map);
|
||||
GL(dl_rtld_map).l_opencount = 1;
|
||||
GL(dl_rtld_map).l_map_start = (ElfW(Addr)) _begin;
|
||||
GL(dl_rtld_map).l_map_end = (ElfW(Addr)) _end;
|
||||
@@ -536,7 +537,7 @@ _dl_start (void *arg)
|
||||
# define ELF_MACHINE_START_ADDRESS(map, start) (start)
|
||||
#endif
|
||||
|
||||
return ELF_MACHINE_START_ADDRESS (GL(dl_loaded), entry);
|
||||
return ELF_MACHINE_START_ADDRESS (GL(dl_ns)[LM_ID_BASE]._ns_loaded, entry);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -585,14 +586,16 @@ map_doit (void *a)
|
||||
{
|
||||
struct map_args *args = (struct map_args *) a;
|
||||
args->map = _dl_map_object (args->loader, args->str,
|
||||
args->is_preloaded, lt_library, 0, args->mode);
|
||||
args->is_preloaded, lt_library, 0, args->mode,
|
||||
LM_ID_BASE);
|
||||
}
|
||||
|
||||
static void
|
||||
version_check_doit (void *a)
|
||||
{
|
||||
struct version_check_args *args = (struct version_check_args *) a;
|
||||
if (_dl_check_all_versions (GL(dl_loaded), 1, args->dotrace) && args->doexit)
|
||||
if (_dl_check_all_versions (GL(dl_ns)[LM_ID_BASE]._ns_loaded, 1,
|
||||
args->dotrace) && args->doexit)
|
||||
/* We cannot start the application. Abort now. */
|
||||
_exit (1);
|
||||
}
|
||||
@@ -601,11 +604,12 @@ version_check_doit (void *a)
|
||||
static inline struct link_map *
|
||||
find_needed (const char *name)
|
||||
{
|
||||
unsigned int n = GL(dl_loaded)->l_searchlist.r_nlist;
|
||||
struct r_scope_elem *scope = &GL(dl_ns)[LM_ID_BASE]._ns_loaded->l_searchlist;
|
||||
unsigned int n = scope->r_nlist;
|
||||
|
||||
while (n-- > 0)
|
||||
if (_dl_name_match_p (name, GL(dl_loaded)->l_searchlist.r_list[n]))
|
||||
return GL(dl_loaded)->l_searchlist.r_list[n];
|
||||
if (_dl_name_match_p (name, scope->r_list[n]))
|
||||
return scope->r_list[n];
|
||||
|
||||
/* Should never happen. */
|
||||
return NULL;
|
||||
@@ -685,6 +689,7 @@ dl_main (const ElfW(Phdr) *phdr,
|
||||
enum mode mode;
|
||||
struct link_map **preloads;
|
||||
unsigned int npreloads;
|
||||
struct link_map *main_map;
|
||||
size_t file_size;
|
||||
char *file;
|
||||
bool has_interp = false;
|
||||
@@ -860,31 +865,35 @@ of this helper program; chances are you did not intend to run this program.\n\
|
||||
{
|
||||
HP_TIMING_NOW (start);
|
||||
_dl_map_object (NULL, rtld_progname, 0, lt_library, 0,
|
||||
__RTLD_OPENEXEC);
|
||||
__RTLD_OPENEXEC, LM_ID_BASE);
|
||||
HP_TIMING_NOW (stop);
|
||||
|
||||
HP_TIMING_DIFF (load_time, start, stop);
|
||||
}
|
||||
|
||||
phdr = GL(dl_loaded)->l_phdr;
|
||||
phnum = GL(dl_loaded)->l_phnum;
|
||||
/* Now the map for the main executable is available. */
|
||||
main_map = GL(dl_ns)[LM_ID_BASE]._ns_loaded;
|
||||
|
||||
phdr = main_map->l_phdr;
|
||||
phnum = main_map->l_phnum;
|
||||
/* We overwrite here a pointer to a malloc()ed string. But since
|
||||
the malloc() implementation used at this point is the dummy
|
||||
implementations which has no real free() function it does not
|
||||
makes sense to free the old string first. */
|
||||
GL(dl_loaded)->l_name = (char *) "";
|
||||
*user_entry = GL(dl_loaded)->l_entry;
|
||||
main_map->l_name = (char *) "";
|
||||
*user_entry = main_map->l_entry;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Create a link_map for the executable itself.
|
||||
This will be what dlopen on "" returns. */
|
||||
_dl_new_object ((char *) "", "", lt_executable, NULL);
|
||||
if (GL(dl_loaded) == NULL)
|
||||
_dl_new_object ((char *) "", "", lt_executable, NULL, 0, LM_ID_BASE);
|
||||
main_map = GL(dl_ns)[LM_ID_BASE]._ns_loaded;
|
||||
if (main_map == NULL)
|
||||
_dl_fatal_printf ("cannot allocate memory for link map\n");
|
||||
GL(dl_loaded)->l_phdr = phdr;
|
||||
GL(dl_loaded)->l_phnum = phnum;
|
||||
GL(dl_loaded)->l_entry = *user_entry;
|
||||
main_map->l_phdr = phdr;
|
||||
main_map->l_phnum = phnum;
|
||||
main_map->l_entry = *user_entry;
|
||||
|
||||
/* At this point we are in a bit of trouble. We would have to
|
||||
fill in the values for l_dev and l_ino. But in general we
|
||||
@@ -905,12 +914,14 @@ of this helper program; chances are you did not intend to run this program.\n\
|
||||
information for the program. */
|
||||
}
|
||||
|
||||
GL(dl_loaded)->l_map_end = 0;
|
||||
GL(dl_loaded)->l_text_end = 0;
|
||||
main_map->l_map_end = 0;
|
||||
main_map->l_text_end = 0;
|
||||
/* Perhaps the executable has no PT_LOAD header entries at all. */
|
||||
GL(dl_loaded)->l_map_start = ~0;
|
||||
main_map->l_map_start = ~0;
|
||||
/* We opened the file, account for it. */
|
||||
++GL(dl_loaded)->l_opencount;
|
||||
++main_map->l_opencount;
|
||||
/* And it was opened directly. */
|
||||
++main_map->l_direct_opencount;
|
||||
|
||||
/* Scan the program header table for the dynamic section. */
|
||||
for (ph = phdr; ph < &phdr[phnum]; ++ph)
|
||||
@@ -918,12 +929,12 @@ of this helper program; chances are you did not intend to run this program.\n\
|
||||
{
|
||||
case PT_PHDR:
|
||||
/* Find out the load address. */
|
||||
GL(dl_loaded)->l_addr = (ElfW(Addr)) phdr - ph->p_vaddr;
|
||||
main_map->l_addr = (ElfW(Addr)) phdr - ph->p_vaddr;
|
||||
break;
|
||||
case PT_DYNAMIC:
|
||||
/* This tells us where to find the dynamic section,
|
||||
which tells us everything we need to do. */
|
||||
GL(dl_loaded)->l_ld = (void *) GL(dl_loaded)->l_addr + ph->p_vaddr;
|
||||
main_map->l_ld = (void *) main_map->l_addr + ph->p_vaddr;
|
||||
break;
|
||||
case PT_INTERP:
|
||||
/* This "interpreter segment" was used by the program loader to
|
||||
@@ -932,7 +943,7 @@ of this helper program; chances are you did not intend to run this program.\n\
|
||||
dlopen call or DT_NEEDED entry, for something that wants to link
|
||||
against the dynamic linker as a shared library, will know that
|
||||
the shared object is already loaded. */
|
||||
_dl_rtld_libname.name = ((const char *) GL(dl_loaded)->l_addr
|
||||
_dl_rtld_libname.name = ((const char *) main_map->l_addr
|
||||
+ ph->p_vaddr);
|
||||
/* _dl_rtld_libname.next = NULL; Already zero. */
|
||||
GL(dl_rtld_map).l_libname = &_dl_rtld_libname;
|
||||
@@ -968,17 +979,16 @@ of this helper program; chances are you did not intend to run this program.\n\
|
||||
ElfW(Addr) allocend;
|
||||
|
||||
/* Remember where the main program starts in memory. */
|
||||
mapstart = (GL(dl_loaded)->l_addr
|
||||
+ (ph->p_vaddr & ~(ph->p_align - 1)));
|
||||
if (GL(dl_loaded)->l_map_start > mapstart)
|
||||
GL(dl_loaded)->l_map_start = mapstart;
|
||||
mapstart = (main_map->l_addr + (ph->p_vaddr & ~(ph->p_align - 1)));
|
||||
if (main_map->l_map_start > mapstart)
|
||||
main_map->l_map_start = mapstart;
|
||||
|
||||
/* Also where it ends. */
|
||||
allocend = GL(dl_loaded)->l_addr + ph->p_vaddr + ph->p_memsz;
|
||||
if (GL(dl_loaded)->l_map_end < allocend)
|
||||
GL(dl_loaded)->l_map_end = allocend;
|
||||
if ((ph->p_flags & PF_X) && allocend > GL(dl_loaded)->l_text_end)
|
||||
GL(dl_loaded)->l_text_end = allocend;
|
||||
allocend = main_map->l_addr + ph->p_vaddr + ph->p_memsz;
|
||||
if (main_map->l_map_end < allocend)
|
||||
main_map->l_map_end = allocend;
|
||||
if ((ph->p_flags & PF_X) && allocend > main_map->l_text_end)
|
||||
main_map->l_text_end = allocend;
|
||||
}
|
||||
break;
|
||||
#ifdef USE_TLS
|
||||
@@ -989,18 +999,18 @@ of this helper program; chances are you did not intend to run this program.\n\
|
||||
here since we read the PT_TLS entry already in
|
||||
_dl_start_final. But the result is repeatable so do not
|
||||
check for this special but unimportant case. */
|
||||
GL(dl_loaded)->l_tls_blocksize = ph->p_memsz;
|
||||
GL(dl_loaded)->l_tls_align = ph->p_align;
|
||||
main_map->l_tls_blocksize = ph->p_memsz;
|
||||
main_map->l_tls_align = ph->p_align;
|
||||
if (ph->p_align == 0)
|
||||
GL(dl_loaded)->l_tls_firstbyte_offset = 0;
|
||||
main_map->l_tls_firstbyte_offset = 0;
|
||||
else
|
||||
GL(dl_loaded)->l_tls_firstbyte_offset = (ph->p_vaddr
|
||||
& (ph->p_align - 1));
|
||||
GL(dl_loaded)->l_tls_initimage_size = ph->p_filesz;
|
||||
GL(dl_loaded)->l_tls_initimage = (void *) ph->p_vaddr;
|
||||
main_map->l_tls_firstbyte_offset = (ph->p_vaddr
|
||||
& (ph->p_align - 1));
|
||||
main_map->l_tls_initimage_size = ph->p_filesz;
|
||||
main_map->l_tls_initimage = (void *) ph->p_vaddr;
|
||||
|
||||
/* This image gets the ID one. */
|
||||
GL(dl_tls_max_dtv_idx) = GL(dl_loaded)->l_tls_modid = 1;
|
||||
GL(dl_tls_max_dtv_idx) = main_map->l_tls_modid = 1;
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
@@ -1009,21 +1019,21 @@ of this helper program; chances are you did not intend to run this program.\n\
|
||||
break;
|
||||
|
||||
case PT_GNU_RELRO:
|
||||
GL(dl_loaded)->l_relro_addr = ph->p_vaddr;
|
||||
GL(dl_loaded)->l_relro_size = ph->p_memsz;
|
||||
main_map->l_relro_addr = ph->p_vaddr;
|
||||
main_map->l_relro_size = ph->p_memsz;
|
||||
break;
|
||||
}
|
||||
#ifdef USE_TLS
|
||||
/* Adjust the address of the TLS initialization image in case
|
||||
the executable is actually an ET_DYN object. */
|
||||
if (GL(dl_loaded)->l_tls_initimage != NULL)
|
||||
GL(dl_loaded)->l_tls_initimage
|
||||
= (char *) GL(dl_loaded)->l_tls_initimage + GL(dl_loaded)->l_addr;
|
||||
if (main_map->l_tls_initimage != NULL)
|
||||
main_map->l_tls_initimage
|
||||
= (char *) main_map->l_tls_initimage + main_map->l_addr;
|
||||
#endif
|
||||
if (! GL(dl_loaded)->l_map_end)
|
||||
GL(dl_loaded)->l_map_end = ~0;
|
||||
if (! GL(dl_loaded)->l_text_end)
|
||||
GL(dl_loaded)->l_text_end = ~0;
|
||||
if (! main_map->l_map_end)
|
||||
main_map->l_map_end = ~0;
|
||||
if (! main_map->l_text_end)
|
||||
main_map->l_text_end = ~0;
|
||||
if (! GL(dl_rtld_map).l_libname && GL(dl_rtld_map).l_name)
|
||||
{
|
||||
/* We were invoked directly, so the program might not have a
|
||||
@@ -1038,9 +1048,9 @@ of this helper program; chances are you did not intend to run this program.\n\
|
||||
if (! rtld_is_main)
|
||||
{
|
||||
/* Extract the contents of the dynamic section for easy access. */
|
||||
elf_get_dynamic_info (GL(dl_loaded), NULL);
|
||||
elf_get_dynamic_info (main_map, NULL);
|
||||
/* Set up our cache of pointers into the hash table. */
|
||||
_dl_setup_hash (GL(dl_loaded));
|
||||
_dl_setup_hash (main_map);
|
||||
}
|
||||
|
||||
if (__builtin_expect (mode, normal) == verify)
|
||||
@@ -1049,7 +1059,7 @@ of this helper program; chances are you did not intend to run this program.\n\
|
||||
executable using us as the program interpreter. Exit with an
|
||||
error if we were not able to load the binary or no interpreter
|
||||
is specified (i.e., this is no dynamically linked binary. */
|
||||
if (GL(dl_loaded)->l_ld == NULL)
|
||||
if (main_map->l_ld == NULL)
|
||||
_exit (1);
|
||||
|
||||
/* We allow here some platform specific code. */
|
||||
@@ -1072,16 +1082,63 @@ of this helper program; chances are you did not intend to run this program.\n\
|
||||
found by the PT_INTERP name. */
|
||||
GL(dl_rtld_map).l_name = (char *) GL(dl_rtld_map).l_libname->name;
|
||||
GL(dl_rtld_map).l_type = lt_library;
|
||||
GL(dl_loaded)->l_next = &GL(dl_rtld_map);
|
||||
GL(dl_rtld_map).l_prev = GL(dl_loaded);
|
||||
++GL(dl_nloaded);
|
||||
main_map->l_next = &GL(dl_rtld_map);
|
||||
GL(dl_rtld_map).l_prev = main_map;
|
||||
++GL(dl_ns)[LM_ID_BASE]._ns_nloaded;
|
||||
++GL(dl_load_adds);
|
||||
|
||||
#if defined(__i386__)
|
||||
/* Force non-TLS libraries for glibc 2.0 binaries
|
||||
or if a buggy binary references non-TLS errno or h_errno. */
|
||||
if (__builtin_expect (main_map->l_info[DT_NUM + DT_THISPROCNUM
|
||||
+ DT_VERSIONTAGIDX (DT_VERNEED)]
|
||||
== NULL, 0)
|
||||
&& main_map->l_info[DT_DEBUG])
|
||||
GLRO(dl_osversion) = 0x20205;
|
||||
else if ((__builtin_expect (mode, normal) != normal
|
||||
|| main_map->l_info[ADDRIDX (DT_GNU_LIBLIST)] == NULL)
|
||||
/* Only binaries have DT_DEBUG dynamic tags... */
|
||||
&& main_map->l_info[DT_DEBUG])
|
||||
{
|
||||
/* Workaround for buggy binaries. This doesn't handle buggy
|
||||
libraries. */
|
||||
bool buggy = false;
|
||||
const ElfW(Sym) *symtab = (const void *) D_PTR (main_map,
|
||||
l_info[DT_SYMTAB]);
|
||||
const char *strtab = (const void *) D_PTR (main_map,
|
||||
l_info[DT_STRTAB]);
|
||||
Elf_Symndx symidx;
|
||||
for (symidx = main_map->l_buckets[0x6c994f % main_map->l_nbuckets];
|
||||
symidx != STN_UNDEF;
|
||||
symidx = main_map->l_chain[symidx])
|
||||
{
|
||||
if (__builtin_expect (strcmp (strtab + symtab[symidx].st_name,
|
||||
"errno") == 0, 0)
|
||||
&& ELFW(ST_TYPE) (symtab[symidx].st_info) != STT_TLS)
|
||||
buggy = true;
|
||||
}
|
||||
for (symidx = main_map->l_buckets[0xe5c992f % main_map->l_nbuckets];
|
||||
symidx != STN_UNDEF;
|
||||
symidx = main_map->l_chain[symidx])
|
||||
{
|
||||
if (__builtin_expect (strcmp (strtab + symtab[symidx].st_name,
|
||||
"h_errno") == 0, 0)
|
||||
&& ELFW(ST_TYPE) (symtab[symidx].st_info) != STT_TLS)
|
||||
buggy = true;
|
||||
}
|
||||
if (__builtin_expect (buggy, false) && GLRO(dl_osversion) > 0x20401)
|
||||
{
|
||||
GLRO(dl_osversion) = 0x20401;
|
||||
_dl_error_printf ("Incorrectly built binary which accesses errno or h_errno directly. Needs to be fixed.\n");
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/* If LD_USE_LOAD_BIAS env variable has not been seen, default
|
||||
to not using bias for non-prelinked PIEs and libraries
|
||||
and using it for executables or prelinked PIEs or libraries. */
|
||||
if (GLRO(dl_use_load_bias) == (ElfW(Addr)) -2)
|
||||
GLRO(dl_use_load_bias) = (GL(dl_loaded)->l_addr == 0) ? -1 : 0;
|
||||
GLRO(dl_use_load_bias) = main_map->l_addr == 0 ? -1 : 0;
|
||||
|
||||
/* Set up the program header information for the dynamic linker
|
||||
itself. It is needed in the dl_iterate_phdr() callbacks. */
|
||||
@@ -1125,8 +1182,9 @@ of this helper program; chances are you did not intend to run this program.\n\
|
||||
&& (__builtin_expect (! INTUSE(__libc_enable_secure), 1)
|
||||
|| strchr (p, '/') == NULL))
|
||||
{
|
||||
struct link_map *new_map = _dl_map_object (GL(dl_loaded), p, 1,
|
||||
lt_library, 0, 0);
|
||||
struct link_map *new_map = _dl_map_object (main_map, p, 1,
|
||||
lt_library, 0, 0,
|
||||
LM_ID_BASE);
|
||||
if (++new_map->l_opencount == 1)
|
||||
/* It is no duplicate. */
|
||||
++npreloads;
|
||||
@@ -1208,7 +1266,7 @@ of this helper program; chances are you did not intend to run this program.\n\
|
||||
struct map_args args;
|
||||
|
||||
args.str = p;
|
||||
args.loader = GL(dl_loaded);
|
||||
args.loader = main_map;
|
||||
args.is_preloaded = 1;
|
||||
args.mode = 0;
|
||||
|
||||
@@ -1231,8 +1289,9 @@ ERROR: ld.so: object '%s' from %s cannot be preloaded: ignored.\n",
|
||||
if (problem != NULL)
|
||||
{
|
||||
char *p = strndupa (problem, file_size - (problem - file));
|
||||
struct link_map *new_map = _dl_map_object (GL(dl_loaded), p, 1,
|
||||
lt_library, 0, 0);
|
||||
struct link_map *new_map = _dl_map_object (main_map, p, 1,
|
||||
lt_library, 0, 0,
|
||||
LM_ID_BASE);
|
||||
if (++new_map->l_opencount == 1)
|
||||
/* It is no duplicate. */
|
||||
++npreloads;
|
||||
@@ -1247,6 +1306,67 @@ ERROR: ld.so: object '%s' from %s cannot be preloaded: ignored.\n",
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#if defined(__i386__) || defined(__alpha__) || (defined(__sparc__) && !defined(__arch64__))
|
||||
/*
|
||||
* Modifications by Red Hat Software
|
||||
*
|
||||
* Deal with the broken binaries from the non-versioned ages of glibc.
|
||||
* If a binary does not have version information enabled, we assume that
|
||||
* it is a glibc 2.0 binary and we load a compatibility library to try to
|
||||
* overcome binary incompatibilities.
|
||||
* Blame: gafton@redhat.com
|
||||
*/
|
||||
#define LIB_NOVERSION "/lib/libNoVersion.so.1"
|
||||
|
||||
if (__builtin_expect (main_map->l_info[DT_NUM + DT_THISPROCNUM
|
||||
+ DT_VERSIONTAGIDX (DT_VERNEED)]
|
||||
== NULL, 0)
|
||||
&& (main_map->l_info[DT_DEBUG]
|
||||
|| !(GLRO(dl_debug_mask) & DL_DEBUG_PRELINK)))
|
||||
{
|
||||
struct stat test_st;
|
||||
int test_fd;
|
||||
int can_load;
|
||||
|
||||
HP_TIMING_NOW (start);
|
||||
|
||||
/* _dl_sysdep_message("Loading compatibility library... ", NULL); */
|
||||
|
||||
can_load = 1;
|
||||
test_fd = __open (LIB_NOVERSION, O_RDONLY);
|
||||
if (test_fd < 0) {
|
||||
can_load = 0;
|
||||
/* _dl_sysdep_message(" Can't find " LIB_NOVERSION "\n", NULL); */
|
||||
} else {
|
||||
if (__fxstat (_STAT_VER, test_fd, &test_st) < 0 || test_st.st_size == 0) {
|
||||
can_load = 0;
|
||||
/* _dl_sysdep_message(" Can't stat " LIB_NOVERSION "\n", NULL); */
|
||||
}
|
||||
}
|
||||
|
||||
if (test_fd >= 0) /* open did no fail.. */
|
||||
__close(test_fd); /* avoid fd leaks */
|
||||
|
||||
if (can_load != 0) {
|
||||
struct link_map *new_map;
|
||||
new_map = _dl_map_object (main_map, LIB_NOVERSION,
|
||||
1, lt_library, 0, 0, LM_ID_BASE);
|
||||
if (++new_map->l_opencount == 1) {
|
||||
/* It is no duplicate. */
|
||||
++npreloads;
|
||||
/* _dl_sysdep_message(" DONE\n", NULL); */
|
||||
} else {
|
||||
/* _dl_sysdep_message(" FAILED\n", NULL); */
|
||||
}
|
||||
}
|
||||
|
||||
HP_TIMING_NOW (stop);
|
||||
HP_TIMING_DIFF (diff, start, stop);
|
||||
HP_TIMING_ACCUM_NT (load_time, diff);
|
||||
}
|
||||
#endif
|
||||
|
||||
if (__builtin_expect (npreloads, 0) != 0)
|
||||
{
|
||||
/* Set up PRELOADS with a vector of the preloaded libraries. */
|
||||
@@ -1271,7 +1391,8 @@ ERROR: ld.so: object '%s' from %s cannot be preloaded: ignored.\n",
|
||||
better be, since it's read-only and so we couldn't relocate it).
|
||||
We just want our data structures to describe it as if we had just
|
||||
mapped and relocated it normally. */
|
||||
struct link_map *l = _dl_new_object ((char *) "", "", lt_library, NULL);
|
||||
struct link_map *l = _dl_new_object ((char *) "", "", lt_library, NULL,
|
||||
0, LM_ID_BASE);
|
||||
if (__builtin_expect (l != NULL, 1))
|
||||
{
|
||||
static ElfW(Dyn) dyn_temp[DL_RO_DYN_TEMP_CNT] attribute_relro;
|
||||
@@ -1336,18 +1457,18 @@ ERROR: ld.so: object '%s' from %s cannot be preloaded: ignored.\n",
|
||||
specified some libraries to load, these are inserted before the actual
|
||||
dependencies in the executable's searchlist for symbol resolution. */
|
||||
HP_TIMING_NOW (start);
|
||||
_dl_map_object_deps (GL(dl_loaded), preloads, npreloads, mode == trace, 0);
|
||||
_dl_map_object_deps (main_map, preloads, npreloads, mode == trace, 0);
|
||||
HP_TIMING_NOW (stop);
|
||||
HP_TIMING_DIFF (diff, start, stop);
|
||||
HP_TIMING_ACCUM_NT (load_time, diff);
|
||||
|
||||
/* Mark all objects as being in the global scope and set the open
|
||||
counter. */
|
||||
for (i = GL(dl_loaded)->l_searchlist.r_nlist; i > 0; )
|
||||
for (i = main_map->l_searchlist.r_nlist; i > 0; )
|
||||
{
|
||||
--i;
|
||||
GL(dl_loaded)->l_searchlist.r_list[i]->l_global = 1;
|
||||
++GL(dl_loaded)->l_searchlist.r_list[i]->l_opencount;
|
||||
main_map->l_searchlist.r_list[i]->l_global = 1;
|
||||
++main_map->l_searchlist.r_list[i]->l_opencount;
|
||||
}
|
||||
|
||||
#ifndef MAP_ANON
|
||||
@@ -1368,13 +1489,13 @@ ERROR: ld.so: object '%s' from %s cannot be preloaded: ignored.\n",
|
||||
chain in symbol search order because gdb uses the chain's order as
|
||||
its symbol search order. */
|
||||
i = 1;
|
||||
while (GL(dl_loaded)->l_searchlist.r_list[i] != &GL(dl_rtld_map))
|
||||
while (main_map->l_searchlist.r_list[i] != &GL(dl_rtld_map))
|
||||
++i;
|
||||
GL(dl_rtld_map).l_prev = GL(dl_loaded)->l_searchlist.r_list[i - 1];
|
||||
GL(dl_rtld_map).l_prev = main_map->l_searchlist.r_list[i - 1];
|
||||
if (__builtin_expect (mode, normal) == normal)
|
||||
{
|
||||
GL(dl_rtld_map).l_next = (i + 1 < GL(dl_loaded)->l_searchlist.r_nlist
|
||||
? GL(dl_loaded)->l_searchlist.r_list[i + 1]
|
||||
GL(dl_rtld_map).l_next = (i + 1 < main_map->l_searchlist.r_nlist
|
||||
? main_map->l_searchlist.r_list[i + 1]
|
||||
: NULL);
|
||||
#ifdef NEED_DL_SYSINFO
|
||||
if (sysinfo_map != NULL
|
||||
@@ -1458,7 +1579,7 @@ ERROR: ld.so: object '%s' from %s cannot be preloaded: ignored.\n",
|
||||
GL(dl_tls_dtv_slotinfo_list)->next = NULL;
|
||||
|
||||
/* Fill in the information from the loaded modules. */
|
||||
for (l = GL(dl_loaded), i = 0; l != NULL; l = l->l_next)
|
||||
for (l = main_map, i = 0; l != NULL; l = l->l_next)
|
||||
if (l->l_tls_blocksize != 0)
|
||||
/* This is a module with TLS data. Store the map reference.
|
||||
The generation counter is zero. */
|
||||
@@ -1494,7 +1615,7 @@ cannot allocate TLS data structures for initial thread");
|
||||
|
||||
if (GLRO(dl_debug_mask) & DL_DEBUG_PRELINK)
|
||||
{
|
||||
struct r_scope_elem *scope = &GL(dl_loaded)->l_searchlist;
|
||||
struct r_scope_elem *scope = &main_map->l_searchlist;
|
||||
|
||||
for (i = 0; i < scope->r_nlist; i++)
|
||||
{
|
||||
@@ -1530,7 +1651,7 @@ cannot allocate TLS data structures for initial thread");
|
||||
/* Look through the dependencies of the main executable
|
||||
and determine which of them is not actually
|
||||
required. */
|
||||
struct link_map *l = GL(dl_loaded);
|
||||
struct link_map *l = main_map;
|
||||
|
||||
/* Relocate the main executable. */
|
||||
struct relocate_args args = { .l = l, .lazy = GLRO(dl_lazy) };
|
||||
@@ -1538,7 +1659,7 @@ cannot allocate TLS data structures for initial thread");
|
||||
|
||||
/* This loop depends on the dependencies of the executable to
|
||||
correspond in number and order to the DT_NEEDED entries. */
|
||||
ElfW(Dyn) *dyn = GL(dl_loaded)->l_ld;
|
||||
ElfW(Dyn) *dyn = main_map->l_ld;
|
||||
bool first = true;
|
||||
while (dyn->d_tag != DT_NULL)
|
||||
{
|
||||
@@ -1563,15 +1684,15 @@ cannot allocate TLS data structures for initial thread");
|
||||
|
||||
_exit (first != true);
|
||||
}
|
||||
else if (! GL(dl_loaded)->l_info[DT_NEEDED])
|
||||
else if (! main_map->l_info[DT_NEEDED])
|
||||
_dl_printf ("\tstatically linked\n");
|
||||
else
|
||||
{
|
||||
for (l = GL(dl_loaded)->l_next; l; l = l->l_next)
|
||||
for (l = main_map->l_next; l; l = l->l_next)
|
||||
if (l->l_faked)
|
||||
/* The library was not found. */
|
||||
_dl_printf ("\t%s => not found\n", l->l_libname->name);
|
||||
else if (l->l_libname->name[0] == '/')
|
||||
else if (strcmp (l->l_libname->name, l->l_name) == 0)
|
||||
_dl_printf ("\t%s (0x%0*Zx)\n", l->l_libname->name,
|
||||
(int) sizeof l->l_map_start * 2,
|
||||
(size_t) l->l_map_start);
|
||||
@@ -1588,8 +1709,8 @@ cannot allocate TLS data structures for initial thread");
|
||||
ElfW(Addr) loadbase;
|
||||
lookup_t result;
|
||||
|
||||
result = _dl_lookup_symbol_x (INTUSE(_dl_argv)[i], GL(dl_loaded),
|
||||
&ref, GL(dl_loaded)->l_scope, NULL,
|
||||
result = _dl_lookup_symbol_x (INTUSE(_dl_argv)[i], main_map,
|
||||
&ref, main_map->l_scope, NULL,
|
||||
ELF_RTYPE_CLASS_PLT,
|
||||
DL_LOOKUP_ADD_DEPENDENCY, NULL);
|
||||
|
||||
@@ -1612,7 +1733,7 @@ cannot allocate TLS data structures for initial thread");
|
||||
|
||||
args.lazy = GLRO(dl_lazy);
|
||||
|
||||
l = GL(dl_loaded);
|
||||
l = main_map;
|
||||
while (l->l_next)
|
||||
l = l->l_next;
|
||||
do
|
||||
@@ -1628,7 +1749,7 @@ cannot allocate TLS data structures for initial thread");
|
||||
|
||||
if ((GLRO(dl_debug_mask) & DL_DEBUG_PRELINK)
|
||||
&& GL(dl_rtld_map).l_opencount > 1)
|
||||
_dl_relocate_object (&GL(dl_rtld_map), GL(dl_loaded)->l_scope,
|
||||
_dl_relocate_object (&GL(dl_rtld_map), main_map->l_scope,
|
||||
0, 0);
|
||||
}
|
||||
|
||||
@@ -1638,9 +1759,9 @@ cannot allocate TLS data structures for initial thread");
|
||||
/* Print more information. This means here, print information
|
||||
about the versions needed. */
|
||||
int first = 1;
|
||||
struct link_map *map = GL(dl_loaded);
|
||||
struct link_map *map;
|
||||
|
||||
for (map = GL(dl_loaded); map != NULL; map = map->l_next)
|
||||
for (map = main_map; map != NULL; map = map->l_next)
|
||||
{
|
||||
const char *strtab;
|
||||
ElfW(Dyn) *dyn = map->l_info[VERNEEDTAG];
|
||||
@@ -1708,28 +1829,27 @@ cannot allocate TLS data structures for initial thread");
|
||||
_exit (0);
|
||||
}
|
||||
|
||||
if (GL(dl_loaded)->l_info [ADDRIDX (DT_GNU_LIBLIST)]
|
||||
if (main_map->l_info[ADDRIDX (DT_GNU_LIBLIST)]
|
||||
&& ! __builtin_expect (GLRO(dl_profile) != NULL, 0))
|
||||
{
|
||||
ElfW(Lib) *liblist, *liblistend;
|
||||
struct link_map **r_list, **r_listend, *l;
|
||||
const char *strtab = (const void *) D_PTR (GL(dl_loaded),
|
||||
l_info[DT_STRTAB]);
|
||||
const char *strtab = (const void *) D_PTR (main_map, l_info[DT_STRTAB]);
|
||||
|
||||
assert (GL(dl_loaded)->l_info [VALIDX (DT_GNU_LIBLISTSZ)] != NULL);
|
||||
assert (main_map->l_info[VALIDX (DT_GNU_LIBLISTSZ)] != NULL);
|
||||
liblist = (ElfW(Lib) *)
|
||||
GL(dl_loaded)->l_info [ADDRIDX (DT_GNU_LIBLIST)]->d_un.d_ptr;
|
||||
main_map->l_info[ADDRIDX (DT_GNU_LIBLIST)]->d_un.d_ptr;
|
||||
liblistend = (ElfW(Lib) *)
|
||||
((char *) liblist
|
||||
+ GL(dl_loaded)->l_info [VALIDX (DT_GNU_LIBLISTSZ)]->d_un.d_val);
|
||||
r_list = GL(dl_loaded)->l_searchlist.r_list;
|
||||
r_listend = r_list + GL(dl_loaded)->l_searchlist.r_nlist;
|
||||
((char *) liblist +
|
||||
main_map->l_info[VALIDX (DT_GNU_LIBLISTSZ)]->d_un.d_val);
|
||||
r_list = main_map->l_searchlist.r_list;
|
||||
r_listend = r_list + main_map->l_searchlist.r_nlist;
|
||||
|
||||
for (; r_list < r_listend && liblist < liblistend; r_list++)
|
||||
{
|
||||
l = *r_list;
|
||||
|
||||
if (l == GL(dl_loaded))
|
||||
if (l == main_map)
|
||||
continue;
|
||||
|
||||
/* If the library is not mapped where it should, fail. */
|
||||
@@ -1758,16 +1878,15 @@ cannot allocate TLS data structures for initial thread");
|
||||
prelinked = true;
|
||||
|
||||
if (__builtin_expect (GLRO(dl_debug_mask) & DL_DEBUG_LIBS, 0))
|
||||
_dl_printf ("\nprelink checking: %s\n", prelinked ? "ok" : "failed");
|
||||
_dl_debug_printf ("\nprelink checking: %s\n",
|
||||
prelinked ? "ok" : "failed");
|
||||
}
|
||||
|
||||
|
||||
/* Initialize _r_debug. */
|
||||
struct r_debug *r = _dl_debug_initialize (GL(dl_rtld_map).l_addr);
|
||||
{
|
||||
struct link_map *l;
|
||||
|
||||
l = GL(dl_loaded);
|
||||
struct link_map *l = main_map;
|
||||
|
||||
#ifdef ELF_MACHINE_DEBUG_SETUP
|
||||
|
||||
@@ -1791,18 +1910,18 @@ cannot allocate TLS data structures for initial thread");
|
||||
}
|
||||
|
||||
/* Now set up the variable which helps the assembler startup code. */
|
||||
GL(dl_main_searchlist) = &GL(dl_loaded)->l_searchlist;
|
||||
GL(dl_global_scope)[0] = &GL(dl_loaded)->l_searchlist;
|
||||
GL(dl_ns)[LM_ID_BASE]._ns_main_searchlist = &main_map->l_searchlist;
|
||||
GL(dl_ns)[LM_ID_BASE]._ns_global_scope[0] = &main_map->l_searchlist;
|
||||
|
||||
/* Save the information about the original global scope list since
|
||||
we need it in the memory handling later. */
|
||||
GLRO(dl_initial_searchlist) = *GL(dl_main_searchlist);
|
||||
GLRO(dl_initial_searchlist) = *GL(dl_ns)[LM_ID_BASE]._ns_main_searchlist;
|
||||
|
||||
if (prelinked)
|
||||
{
|
||||
struct link_map *l;
|
||||
|
||||
if (GL(dl_loaded)->l_info [ADDRIDX (DT_GNU_CONFLICT)] != NULL)
|
||||
if (main_map->l_info [ADDRIDX (DT_GNU_CONFLICT)] != NULL)
|
||||
{
|
||||
ElfW(Rela) *conflict, *conflictend;
|
||||
#ifndef HP_TIMING_NONAVAIL
|
||||
@@ -1811,20 +1930,20 @@ cannot allocate TLS data structures for initial thread");
|
||||
#endif
|
||||
|
||||
HP_TIMING_NOW (start);
|
||||
assert (GL(dl_loaded)->l_info [VALIDX (DT_GNU_CONFLICTSZ)] != NULL);
|
||||
assert (main_map->l_info [VALIDX (DT_GNU_CONFLICTSZ)] != NULL);
|
||||
conflict = (ElfW(Rela) *)
|
||||
GL(dl_loaded)->l_info [ADDRIDX (DT_GNU_CONFLICT)]->d_un.d_ptr;
|
||||
main_map->l_info [ADDRIDX (DT_GNU_CONFLICT)]->d_un.d_ptr;
|
||||
conflictend = (ElfW(Rela) *)
|
||||
((char *) conflict
|
||||
+ GL(dl_loaded)->l_info [VALIDX (DT_GNU_CONFLICTSZ)]->d_un.d_val);
|
||||
_dl_resolve_conflicts (GL(dl_loaded), conflict, conflictend);
|
||||
+ main_map->l_info [VALIDX (DT_GNU_CONFLICTSZ)]->d_un.d_val);
|
||||
_dl_resolve_conflicts (main_map, conflict, conflictend);
|
||||
HP_TIMING_NOW (stop);
|
||||
HP_TIMING_DIFF (relocate_time, start, stop);
|
||||
}
|
||||
|
||||
|
||||
/* Mark all the objects so we know they have been already relocated. */
|
||||
for (l = GL(dl_loaded); l != NULL; l = l->l_next)
|
||||
for (l = main_map; l != NULL; l = l->l_next)
|
||||
{
|
||||
l->l_relocated = 1;
|
||||
if (l->l_relro_size)
|
||||
@@ -1855,7 +1974,7 @@ cannot allocate TLS data structures for initial thread");
|
||||
/* If we are profiling we also must do lazy reloaction. */
|
||||
GLRO(dl_lazy) |= consider_profiling;
|
||||
|
||||
l = GL(dl_loaded);
|
||||
l = main_map;
|
||||
while (l->l_next)
|
||||
l = l->l_next;
|
||||
|
||||
@@ -1904,7 +2023,7 @@ cannot allocate TLS data structures for initial thread");
|
||||
/* There was an explicit ref to the dynamic linker as a shared lib.
|
||||
Re-relocate ourselves with user-controlled symbol definitions. */
|
||||
HP_TIMING_NOW (start);
|
||||
_dl_relocate_object (&GL(dl_rtld_map), GL(dl_loaded)->l_scope, 0, 0);
|
||||
_dl_relocate_object (&GL(dl_rtld_map), main_map->l_scope, 0, 0);
|
||||
HP_TIMING_NOW (stop);
|
||||
HP_TIMING_DIFF (add, start, stop);
|
||||
HP_TIMING_ACCUM_NT (relocate_time, add);
|
||||
@@ -2321,20 +2440,24 @@ print_statistics (hp_timing_t *rtld_total_timep)
|
||||
#endif
|
||||
|
||||
unsigned long int num_relative_relocations = 0;
|
||||
struct r_scope_elem *scope = &GL(dl_loaded)->l_searchlist;
|
||||
unsigned int i;
|
||||
|
||||
for (i = 0; i < scope->r_nlist; i++)
|
||||
for (Lmid_t ns = 0; ns < DL_NNS; ++ns)
|
||||
{
|
||||
struct link_map *l = scope->r_list [i];
|
||||
struct r_scope_elem *scope = &GL(dl_ns)[ns]._ns_loaded->l_searchlist;
|
||||
|
||||
if (!l->l_addr)
|
||||
continue;
|
||||
for (unsigned int i = 0; i < scope->r_nlist; i++)
|
||||
{
|
||||
struct link_map *l = scope->r_list [i];
|
||||
|
||||
if (l->l_info[VERSYMIDX (DT_RELCOUNT)])
|
||||
num_relative_relocations += l->l_info[VERSYMIDX (DT_RELCOUNT)]->d_un.d_val;
|
||||
if (l->l_info[VERSYMIDX (DT_RELACOUNT)])
|
||||
num_relative_relocations += l->l_info[VERSYMIDX (DT_RELACOUNT)]->d_un.d_val;
|
||||
if (!l->l_addr)
|
||||
continue;
|
||||
|
||||
if (l->l_info[VERSYMIDX (DT_RELCOUNT)])
|
||||
num_relative_relocations
|
||||
+= l->l_info[VERSYMIDX (DT_RELCOUNT)]->d_un.d_val;
|
||||
if (l->l_info[VERSYMIDX (DT_RELACOUNT)])
|
||||
num_relative_relocations
|
||||
+= l->l_info[VERSYMIDX (DT_RELACOUNT)]->d_un.d_val;
|
||||
}
|
||||
}
|
||||
|
||||
_dl_debug_printf (" number of relocations: %lu\n"
|
||||
|
||||
@@ -0,0 +1,36 @@
|
||||
#include <dlfcn.h>
|
||||
#include <stdio.h>
|
||||
|
||||
int
|
||||
xyzzy (void)
|
||||
{
|
||||
printf ("%s:%s\n", __FILE__, __func__);
|
||||
return 21;
|
||||
}
|
||||
|
||||
int
|
||||
back (void)
|
||||
{
|
||||
printf ("%s:%s\n", __FILE__, __func__);
|
||||
return 1;
|
||||
}
|
||||
|
||||
extern int foo (void);
|
||||
|
||||
static int
|
||||
do_test (void)
|
||||
{
|
||||
void *p = dlopen ("$ORIGIN/tst-deep1mod2.so", RTLD_LAZY|RTLD_DEEPBIND);
|
||||
|
||||
int (*f) (void) = dlsym (p, "bar");
|
||||
if (f == NULL)
|
||||
{
|
||||
puts (dlerror ());
|
||||
return 1;
|
||||
}
|
||||
|
||||
return foo () + f ();
|
||||
}
|
||||
|
||||
#define TEST_FUNCTION do_test ()
|
||||
#include "../test-skeleton.c"
|
||||
@@ -0,0 +1,14 @@
|
||||
#include <stdio.h>
|
||||
int
|
||||
foo (void)
|
||||
{
|
||||
printf ("%s:%s\n", __FILE__, __func__);
|
||||
return 1;
|
||||
}
|
||||
|
||||
int
|
||||
baz (void)
|
||||
{
|
||||
printf ("%s:%s\n", __FILE__, __func__);
|
||||
return 20;
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
#include <stdio.h>
|
||||
extern int baz (void);
|
||||
extern int xyzzy (void);
|
||||
int
|
||||
bar (void)
|
||||
{
|
||||
printf ("%s:%s\n", __FILE__, __func__);
|
||||
return baz () + xyzzy ();;
|
||||
}
|
||||
|
||||
int
|
||||
back (void)
|
||||
{
|
||||
printf ("%s:%s\n", __FILE__, __func__);
|
||||
return -1;
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
#include <stdio.h>
|
||||
|
||||
extern int back (void);
|
||||
|
||||
int
|
||||
baz (void)
|
||||
{
|
||||
printf ("%s:%s\n", __FILE__, __func__);
|
||||
return back ();
|
||||
}
|
||||
|
||||
int
|
||||
xyzzy (void)
|
||||
{
|
||||
printf ("%s:%s\n", __FILE__, __func__);
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,80 @@
|
||||
#include <dlfcn.h>
|
||||
#include <stdio.h>
|
||||
#include <gnu/lib-names.h>
|
||||
|
||||
|
||||
static int
|
||||
do_test (void)
|
||||
{
|
||||
void *h = dlopen (LIBC_SO, RTLD_LAZY|RTLD_NOLOAD);
|
||||
if (h == NULL)
|
||||
{
|
||||
printf ("cannot get handle for %s: %s\n", LIBC_SO, dlerror ());
|
||||
return 1;
|
||||
}
|
||||
|
||||
Lmid_t ns = -10;
|
||||
if (dlinfo (h, RTLD_DI_LMID, &ns) != 0)
|
||||
{
|
||||
printf ("dlinfo for %s in %s failed: %s\n",
|
||||
LIBC_SO, __func__, dlerror ());
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (ns != LM_ID_BASE)
|
||||
{
|
||||
printf ("namespace for %s not LM_ID_BASE\n", LIBC_SO);
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (dlclose (h) != 0)
|
||||
{
|
||||
printf ("dlclose for %s in %s failed: %s\n",
|
||||
LIBC_SO, __func__, dlerror ());
|
||||
return 1;
|
||||
}
|
||||
|
||||
h = dlmopen (LM_ID_NEWLM, "$ORIGIN/tst-dlmopen1mod.so", RTLD_LAZY);
|
||||
if (h == NULL)
|
||||
{
|
||||
printf ("cannot get handle for %s: %s\n",
|
||||
"tst-dlmopen1mod.so", dlerror ());
|
||||
return 1;
|
||||
}
|
||||
|
||||
ns = -10;
|
||||
if (dlinfo (h, RTLD_DI_LMID, &ns) != 0)
|
||||
{
|
||||
printf ("dlinfo for %s in %s failed: %s\n",
|
||||
"tst-dlmopen1mod.so", __func__, dlerror ());
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (ns == LM_ID_BASE)
|
||||
{
|
||||
printf ("namespace for %s is LM_ID_BASE\n", LIBC_SO);
|
||||
return 1;
|
||||
}
|
||||
|
||||
int (*fct) (Lmid_t) = dlsym (h, "foo");
|
||||
if (fct == NULL)
|
||||
{
|
||||
printf ("could not find %s: %s\n", "foo", dlerror ());
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (fct (ns) != 0)
|
||||
return 1;
|
||||
|
||||
if (dlclose (h) != 0)
|
||||
{
|
||||
printf ("dlclose for %s in %s failed: %s\n",
|
||||
LIBC_SO, __func__, dlerror ());
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#define TEST_FUNCTION do_test ()
|
||||
#include "../test-skeleton.c"
|
||||
@@ -0,0 +1,38 @@
|
||||
#include <dlfcn.h>
|
||||
#include <stdio.h>
|
||||
#include <gnu/lib-names.h>
|
||||
|
||||
|
||||
int
|
||||
foo (Lmid_t ns2)
|
||||
{
|
||||
void *h = dlopen (LIBC_SO, RTLD_LAZY|RTLD_NOLOAD);
|
||||
if (h == NULL)
|
||||
{
|
||||
printf ("cannot get handle for %s: %s\n", LIBC_SO, dlerror ());
|
||||
return 1;
|
||||
}
|
||||
|
||||
Lmid_t ns = -10;
|
||||
if (dlinfo (h, RTLD_DI_LMID, &ns) != 0)
|
||||
{
|
||||
printf ("dlinfo for %s in %s failed: %s\n",
|
||||
LIBC_SO, __func__, dlerror ());
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (ns != ns2)
|
||||
{
|
||||
printf ("namespace for %s not LM_ID_BASE\n", LIBC_SO);
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (dlclose (h) != 0)
|
||||
{
|
||||
printf ("dlclose for %s in %s failed: %s\n",
|
||||
LIBC_SO, __func__, dlerror ());
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,70 @@
|
||||
#include <dlfcn.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <gnu/lib-names.h>
|
||||
#include <ldsodefs.h>
|
||||
|
||||
|
||||
static int
|
||||
do_test (void)
|
||||
{
|
||||
int result = 0;
|
||||
|
||||
for (int i = 1; i <= 10; ++i)
|
||||
{
|
||||
void *h[DL_NNS - 1];
|
||||
char used[DL_NNS];
|
||||
|
||||
printf ("round %d\n", i);
|
||||
|
||||
memset (used, '\0', sizeof (used));
|
||||
used[LM_ID_BASE] = 1;
|
||||
|
||||
for (int j = 0; j < DL_NNS - 1; ++j)
|
||||
{
|
||||
h[j] = dlmopen (LM_ID_NEWLM, "$ORIGIN/tst-dlmopen1mod.so",
|
||||
RTLD_LAZY);
|
||||
if (h[j] == NULL)
|
||||
{
|
||||
printf ("round %d, namespace %d: load failed: %s\n",
|
||||
i, j, dlerror ());
|
||||
return 1;
|
||||
}
|
||||
Lmid_t ns;
|
||||
if (dlinfo (h[j], RTLD_DI_LMID, &ns) != 0)
|
||||
{
|
||||
printf ("round %d, namespace %d: dlinfo failed: %s\n",
|
||||
i, j, dlerror ());
|
||||
return 1;
|
||||
}
|
||||
if (ns < 0 || ns >= DL_NNS)
|
||||
{
|
||||
printf ("round %d, namespace %d: invalid namespace %ld",
|
||||
i, j, (long int) ns);
|
||||
result = 1;
|
||||
}
|
||||
else if (used[ns] != 0)
|
||||
{
|
||||
printf ("\
|
||||
round %d, namespace %d: duplicate allocate of namespace %ld",
|
||||
i, j, (long int) ns);
|
||||
result = 1;
|
||||
}
|
||||
else
|
||||
used[ns] = 1;
|
||||
}
|
||||
|
||||
for (int j = 0; j < DL_NNS - 1; ++j)
|
||||
if (dlclose (h[j]) != 0)
|
||||
{
|
||||
printf ("round %d, namespace %d: close failed: %s\n",
|
||||
i, j, dlerror ());
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
#define TEST_FUNCTION do_test ()
|
||||
#include "../test-skeleton.c"
|
||||
@@ -62,10 +62,8 @@ do_test (void)
|
||||
result = foo ();
|
||||
|
||||
out:
|
||||
#if 0
|
||||
unlink (PFX "test-subdir/in-subdir.so");
|
||||
rmdir (testsubdir);
|
||||
#endif
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
+2
-2
@@ -1,8 +1,8 @@
|
||||
#include <tls.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#if defined USE_TLS && defined HAVE___THREAD \
|
||||
&& defined HAVE_TLS_MODEL_ATTRIBUTE
|
||||
#if defined USE_TLS \
|
||||
&& (0 || (defined HAVE___THREAD && defined HAVE_TLS_MODEL_ATTRIBUTE))
|
||||
# define USE_TLS__THREAD
|
||||
|
||||
struct A
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
glibc-*.tar.bz2
|
||||
glibc-*.src.rpm
|
||||
glibc-fedora.patch
|
||||
glibc.spec
|
||||
update.log
|
||||
+107
@@ -0,0 +1,107 @@
|
||||
# Makefile for maintaining glibc fedora-branch and creating Fedora source RPMs.
|
||||
|
||||
glibc.spec: # The default target.
|
||||
|
||||
tag-prefix := fedora-
|
||||
|
||||
.PHONY: update commit-merge commit patch tag archive finish_archive srpm rpm
|
||||
|
||||
snapshot-date-fmt := +'%Y-%m-%d %H:%M %Z'
|
||||
snapshot-name-fmt := +'%Y%m%dT%H%M'
|
||||
|
||||
include branch.mk
|
||||
|
||||
|
||||
on-branch = $(filter-out HEAD,$(glibc-base))
|
||||
|
||||
snapshot-date := $($(glibc-branch)-sync-date)
|
||||
snapshot-name := $(shell date -u -d '$(snapshot-date)' $(snapshot-name-fmt))
|
||||
|
||||
tar-name := glibc$(subst _,.,$(patsubst glibc-%-branch,-%,\
|
||||
$(filter-out HEAD,$(glibc-base))))
|
||||
select-snapshot = -r '$($(glibc-branch)-sync-tag)'
|
||||
snapshot-id = $($(glibc-branch)-sync-tag)
|
||||
|
||||
|
||||
update:
|
||||
now=`date -u $(snapshot-date-fmt)`; \
|
||||
name=`date -u -d "$$now" $(snapshot-name-fmt)`; \
|
||||
new="$(tag-prefix)$(tar-name)-$$name"; \
|
||||
cvs -Q rtag $(if $(on-branch),-r $(glibc-base),-D "$$now") $$new libc;\
|
||||
(echo '# This file is updated automatically by Makefile.'; \
|
||||
echo 'glibc-branch := $(glibc-branch)'; \
|
||||
echo 'glibc-base := $(glibc-base)'; \
|
||||
echo "$(glibc-branch)-sync-date := $$now"; \
|
||||
echo "$(glibc-branch)-sync-tag := $$new"; \
|
||||
) > branch.mk; \
|
||||
cd ..; (set -x; cvs -q update -d -P \
|
||||
-j'$($(glibc-branch)-sync-tag)' -j"$$new") \
|
||||
2>&1 | tee fedora/update.log
|
||||
|
||||
commit-merge:
|
||||
cd ..; cvs -Q commit -m"Updated to $(snapshot-id)"
|
||||
|
||||
glibc.spec: glibc.spec.in ../version.h branch.mk
|
||||
(echo '%define glibcdate $(snapshot-name)'; \
|
||||
sed -n '/VERSION/s/^.*"\([^"]*\)"$$/%define glibcversion \1/p' \
|
||||
../version.h; \
|
||||
cat $<) > $@.new
|
||||
mv -f $@.new $@
|
||||
|
||||
ifeq (,$(wildcard glibc.spec))
|
||||
Makefile: glibc.spec ;
|
||||
else
|
||||
|
||||
spec-nvr := $(shell rpm -q --qf '%{NAME}-%{VERSION}-%{RELEASE}\n' \
|
||||
--specfile glibc.spec | sed 1q)
|
||||
spec-tag = $(subst .,_,$(spec-nvr))
|
||||
|
||||
tag: glibc.spec
|
||||
cd ..; cvs -Q tag -c $(tag-prefix)$(spec-tag)
|
||||
|
||||
$(tar-name)-$(glibc-branch).patch: makepatch.awk glibc.spec \
|
||||
../ChangeLog ../*/ChangeLog
|
||||
(cd ..; cvs -q diff -upN \
|
||||
$(select-snapshot) -r $(tag-prefix)$(spec-tag)) | \
|
||||
awk -v OLDVER=$(tar-name)-$(snapshot-name) \
|
||||
-v NEWVER=$(tar-name)-$(snapshot-name)-$(glibc-branch) \
|
||||
-f $< > patch.tmp
|
||||
mv -f patch.tmp $@
|
||||
|
||||
# makepatch.awk omits these files from the patch; we put them in a tar file.
|
||||
outside-patch = fedora c_stubs rtkaio glibc-compat \
|
||||
localedata/charmaps/GB18030 iconvdata/gb18030.c
|
||||
|
||||
$(tar-name)-$(glibc-branch)-$(snapshot-name).tar.bz2: Makefile branch.mk \
|
||||
../ChangeLog \
|
||||
../*/ChangeLog
|
||||
@rm -rf libc
|
||||
cvs -Q export -r$(tag-prefix)$(spec-tag) \
|
||||
$(addprefix libc/,$(outside-patch))
|
||||
tar cf - -C libc $(outside-patch) | bzip2 -9 > $@.new
|
||||
rm -rf libc
|
||||
mv -f $@.new $@
|
||||
|
||||
$(tar-name)-$(snapshot-name).tar.bz2: Makefile branch.mk
|
||||
@rm -rf $(tar-name)-$(snapshot-name)
|
||||
cvs -Q export -d $(tar-name)-$(snapshot-name) $(select-snapshot) libc
|
||||
tar cf - $(tar-name)-$(snapshot-name) | bzip2 -9 > $@.new
|
||||
rm -rf $(tar-name)-$(snapshot-name)
|
||||
mv -f $@.new $@
|
||||
|
||||
archives = $(tar-name)-$(snapshot-name).tar.bz2 \
|
||||
$(tar-name)-$(glibc-branch)-$(snapshot-name).tar.bz2 \
|
||||
$(tar-name)-$(glibc-branch).patch
|
||||
finish_archive: $(archives)
|
||||
|
||||
archive: glibc.spec
|
||||
$(MAKE) tag finish_archive
|
||||
|
||||
rpm srpm: $(spec-nvr).src.rpm
|
||||
$(spec-nvr).src.rpm: glibc.spec $(archives)
|
||||
rpmbuild --define "_sourcedir `pwd`" \
|
||||
--define "_specdir `pwd`" \
|
||||
--define "_srcrpmdir `pwd`" \
|
||||
--nodeps -bs $<
|
||||
|
||||
endif
|
||||
@@ -0,0 +1,5 @@
|
||||
# This file is updated automatically by Makefile.
|
||||
glibc-branch := fedora
|
||||
glibc-base := HEAD
|
||||
fedora-sync-date := 2004-10-14 05:48 UTC
|
||||
fedora-sync-tag := fedora-glibc-20041014T0548
|
||||
@@ -0,0 +1,160 @@
|
||||
#define _GNU_SOURCE
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <dirent.h>
|
||||
#include <errno.h>
|
||||
#include <string.h>
|
||||
#include <stdbool.h>
|
||||
#include <sys/stat.h>
|
||||
#include <stdio.h>
|
||||
#include <stdarg.h>
|
||||
#include "../locale/hashval.h"
|
||||
|
||||
const char *alias_file = DATADIR "/locale/locale.alias";
|
||||
const char *locar_file = PREFIX "/lib/locale/locale-archive";
|
||||
const char *loc_path = PREFIX "/lib/locale/";
|
||||
int be_quiet = 1;
|
||||
int verbose = 0;
|
||||
int max_locarchive_open_retry = 10;
|
||||
const char *output_prefix;
|
||||
|
||||
static int
|
||||
is_prime (unsigned long candidate)
|
||||
{
|
||||
/* No even number and none less than 10 will be passed here. */
|
||||
unsigned long int divn = 3;
|
||||
unsigned long int sq = divn * divn;
|
||||
|
||||
while (sq < candidate && candidate % divn != 0)
|
||||
{
|
||||
++divn;
|
||||
sq += 4 * divn;
|
||||
++divn;
|
||||
}
|
||||
|
||||
return candidate % divn != 0;
|
||||
}
|
||||
|
||||
unsigned long
|
||||
next_prime (unsigned long seed)
|
||||
{
|
||||
/* Make it definitely odd. */
|
||||
seed |= 1;
|
||||
|
||||
while (!is_prime (seed))
|
||||
seed += 2;
|
||||
|
||||
return seed;
|
||||
}
|
||||
|
||||
/* xmalloc is only used by show_archive_content. */
|
||||
void *
|
||||
xmalloc (size_t size)
|
||||
{
|
||||
exit (255);
|
||||
}
|
||||
|
||||
void
|
||||
error (int status, int errnum, const char *message, ...)
|
||||
{
|
||||
va_list args;
|
||||
|
||||
va_start (args, message);
|
||||
fflush (stdout);
|
||||
fprintf (stderr, "%s: ", program_invocation_name);
|
||||
vfprintf (stderr, message, args);
|
||||
va_end (args);
|
||||
if (errnum)
|
||||
fprintf (stderr, ": %s", strerror (errnum));
|
||||
putc ('\n', stderr);
|
||||
fflush (stderr);
|
||||
if (status)
|
||||
exit (errnum == EROFS ? 0 : status);
|
||||
}
|
||||
|
||||
extern int add_locales_to_archive (size_t nlist, char *list[], bool replace);
|
||||
|
||||
int main ()
|
||||
{
|
||||
char path[4096];
|
||||
DIR *dirp;
|
||||
struct dirent64 *d;
|
||||
struct stat64 st;
|
||||
char *list[16384], *primary;
|
||||
unsigned int cnt = 0;
|
||||
|
||||
unlink (locar_file);
|
||||
dirp = opendir (loc_path);
|
||||
if (dirp == NULL)
|
||||
error (EXIT_FAILURE, errno, "cannot open directory \"%s\"", loc_path);
|
||||
|
||||
primary = getenv ("LC_ALL");
|
||||
if (primary == NULL)
|
||||
primary = getenv ("LANG");
|
||||
if (primary != NULL)
|
||||
{
|
||||
if (strncmp (primary, "ja", 2) != 0
|
||||
&& strncmp (primary, "ko", 2) != 0
|
||||
&& strncmp (primary, "zh", 2) != 0)
|
||||
{
|
||||
char *ptr = malloc (strlen (primary) + strlen (".utf8") + 1), *p, *q;
|
||||
|
||||
if (ptr)
|
||||
{
|
||||
p = ptr;
|
||||
q = primary;
|
||||
while (*q && *q != '.' && *q != '@')
|
||||
*p++ = *q++;
|
||||
if (*q == '.')
|
||||
while (*q && *q != '@')
|
||||
q++;
|
||||
p = stpcpy (p, ".utf8");
|
||||
strcpy (p, q);
|
||||
primary = ptr;
|
||||
}
|
||||
else
|
||||
primary = ".....";
|
||||
}
|
||||
strcpy (stpcpy (path, loc_path), primary);
|
||||
if (stat64 (path, &st) >= 0 && S_ISDIR (st.st_mode))
|
||||
{
|
||||
list[cnt] = strdup (path);
|
||||
if (list[cnt] == NULL)
|
||||
error (0, errno, "cannot add file to list \"%s\"", path);
|
||||
else
|
||||
cnt++;
|
||||
}
|
||||
if (cnt == 0)
|
||||
primary = NULL;
|
||||
}
|
||||
|
||||
while ((d = readdir64 (dirp)) != NULL)
|
||||
{
|
||||
if (strcmp (d->d_name, ".") == 0 || strcmp (d->d_name, "..") == 0)
|
||||
continue;
|
||||
|
||||
if (primary && strcmp (d->d_name, primary) == 0)
|
||||
continue;
|
||||
|
||||
strcpy (stpcpy (path, loc_path), d->d_name);
|
||||
if (stat64 (path, &st) < 0)
|
||||
{
|
||||
error (0, errno, "cannot stat \"%s\"", path);
|
||||
continue;
|
||||
}
|
||||
if (! S_ISDIR (st.st_mode))
|
||||
continue;
|
||||
if (cnt == 16384)
|
||||
error (EXIT_FAILURE, 0, "too many directories in \"%s\"", loc_path);
|
||||
list[cnt] = strdup (path);
|
||||
if (list[cnt] == NULL)
|
||||
{
|
||||
error (0, errno, "cannot add file to list \"%s\"", path);
|
||||
continue;
|
||||
}
|
||||
cnt++;
|
||||
}
|
||||
closedir (dirp);
|
||||
add_locales_to_archive (cnt, list, 0);
|
||||
exit (0);
|
||||
}
|
||||
@@ -0,0 +1,92 @@
|
||||
2004-05-14 Jakub Jelinek <jakub@redhat.com>
|
||||
|
||||
* sysdeps/unix/sysv/linux/configure.in: Use */lib64 even for ia64.
|
||||
* sysdeps/unix/sysv/linux/configure: Rebuilt.
|
||||
* sysdeps/unix/sysv/linux/ia64/dl-procinfo.c: New file.
|
||||
* sysdeps/unix/sysv/linux/ia64/dl-procinfo.h: New file.
|
||||
* sysdeps/unix/sysv/linux/ia64/ldd-rewrite.sed: Change /lib64/ld*
|
||||
into /lib/ld*. Add LD_LIBRARY_VERSION.
|
||||
* sysdeps/unix/sysv/linux/ia64/ldconfig.h
|
||||
(SYSDEP_KNOWN_INTERPRETER_NAMES): Add /lib64/ld-linux-ia64.so.2.
|
||||
* sysdeps/unix/sysv/linux/ia64/dl-cache.h: Include sparc-linux
|
||||
dl-cache.h instead of generic dl-cache.h.
|
||||
|
||||
--- libc/sysdeps/unix/sysv/linux/configure.jj 2003-03-23 03:10:04.000000000 +0100
|
||||
+++ libc/sysdeps/unix/sysv/linux/configure 2004-05-14 15:54:35.669802684 +0200
|
||||
@@ -225,7 +225,7 @@ case "$prefix" in
|
||||
# 64-bit libraries on bi-arch platforms go in /lib64 instead of /lib
|
||||
case $machine in
|
||||
sparc/sparc64 | x86_64 | powerpc/powerpc64 | s390/s390-64 | \
|
||||
- mips/mips64/n64/* )
|
||||
+ mips/mips64/n64/* | ia64 )
|
||||
libc_cv_slibdir="/lib64"
|
||||
if test "$libdir" = '${exec_prefix}/lib'; then
|
||||
libdir='${exec_prefix}/lib64';
|
||||
--- libc/sysdeps/unix/sysv/linux/configure.in.jj 2003-03-23 03:10:04.000000000 +0100
|
||||
+++ libc/sysdeps/unix/sysv/linux/configure.in 2004-05-14 15:53:44.355998785 +0200
|
||||
@@ -158,7 +158,7 @@ case "$prefix" in
|
||||
# 64-bit libraries on bi-arch platforms go in /lib64 instead of /lib
|
||||
case $machine in
|
||||
sparc/sparc64 | x86_64 | powerpc/powerpc64 | s390/s390-64 | \
|
||||
- mips/mips64/n64/* )
|
||||
+ mips/mips64/n64/* | ia64 )
|
||||
libc_cv_slibdir="/lib64"
|
||||
if test "$libdir" = '${exec_prefix}/lib'; then
|
||||
libdir='${exec_prefix}/lib64';
|
||||
--- libc/sysdeps/unix/sysv/linux/ia64/dl-procinfo.c.jj 2004-05-14 15:42:09.307560515 +0200
|
||||
+++ libc/sysdeps/unix/sysv/linux/ia64/dl-procinfo.c 2003-09-30 00:23:24.000000000 +0200
|
||||
@@ -0,0 +1,5 @@
|
||||
+#ifdef IS_IN_ldconfig
|
||||
+#include <sysdeps/i386/dl-procinfo.c>
|
||||
+#else
|
||||
+#include <sysdeps/generic/dl-procinfo.c>
|
||||
+#endif
|
||||
--- libc/sysdeps/unix/sysv/linux/ia64/ldd-rewrite.sed.jj 2002-01-17 07:49:28.000000000 +0100
|
||||
+++ libc/sysdeps/unix/sysv/linux/ia64/ldd-rewrite.sed 2004-05-14 16:21:03.041325040 +0200
|
||||
@@ -1 +1,4 @@
|
||||
-s_^\(RTLDLIST=\)\([^ ]*\)-ia64\(\.so\.[0-9.]*\)[ ]*$_\1"\2-ia64\3 \2\3"_
|
||||
+/LD_TRACE_LOADED_OBJECTS=1/a\
|
||||
+add_env="$add_env LD_LIBRARY_VERSION=\\$verify_out"
|
||||
+s_^\(RTLDLIST=\)/lib64/ld\([^ ]*\)-ia64\(\.so\.[0-9.]*\)[ ]*$_\1"/lib/ld\2-ia64\3 /lib/ld\2\3"_
|
||||
+s_^\(RTLDLIST=\)\([^"][^ ]*\)-ia64\(\.so\.[0-9.]*\)[ ]*$_\1"\2-ia64\3 \2\3"_
|
||||
--- libc/sysdeps/unix/sysv/linux/ia64/ldconfig.h.jj 2001-07-06 06:56:17.000000000 +0200
|
||||
+++ libc/sysdeps/unix/sysv/linux/ia64/ldconfig.h 2004-05-14 15:45:40.103783087 +0200
|
||||
@@ -1,4 +1,4 @@
|
||||
-/* Copyright (C) 2001 Free Software Foundation, Inc.
|
||||
+/* Copyright (C) 2001, 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,7 +19,8 @@
|
||||
#include <sysdeps/generic/ldconfig.h>
|
||||
|
||||
#define SYSDEP_KNOWN_INTERPRETER_NAMES \
|
||||
- { "/lib/ld-linux.so.2", FLAG_ELF_LIBC6 },
|
||||
+ { "/lib/ld-linux.so.2", FLAG_ELF_LIBC6 }, \
|
||||
+ { "/lib64/ld-linux-ia64.so.2", FLAG_ELF_LIBC6 },
|
||||
#define SYSDEP_KNOWN_LIBRARY_NAMES \
|
||||
{ "libc.so.6", FLAG_ELF_LIBC6 }, \
|
||||
{ "libm.so.6", FLAG_ELF_LIBC6 },
|
||||
--- libc/sysdeps/unix/sysv/linux/ia64/dl-cache.h.jj 2001-07-06 06:56:17.000000000 +0200
|
||||
+++ libc/sysdeps/unix/sysv/linux/ia64/dl-cache.h 2004-05-14 15:41:11.658891907 +0200
|
||||
@@ -1,5 +1,5 @@
|
||||
/* Support for reading /etc/ld.so.cache files written by Linux ldconfig.
|
||||
- Copyright (C) 2000 Free Software Foundation, Inc.
|
||||
+ Copyright (C) 2000, 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
|
||||
@@ -22,4 +22,4 @@
|
||||
#define _dl_cache_check_flags(flags) \
|
||||
((flags) == _DL_CACHE_DEFAULT_ID)
|
||||
|
||||
-#include_next <dl-cache.h>
|
||||
+#include <sysdeps/unix/sysv/linux/sparc/dl-cache.h>
|
||||
--- libc/sysdeps/unix/sysv/linux/ia64/dl-procinfo.h.jj 2004-05-14 15:42:13.018895395 +0200
|
||||
+++ libc/sysdeps/unix/sysv/linux/ia64/dl-procinfo.h 2003-07-23 00:06:23.000000000 +0200
|
||||
@@ -0,0 +1,5 @@
|
||||
+#ifdef IS_IN_ldconfig
|
||||
+#include <sysdeps/unix/sysv/linux/i386/dl-procinfo.h>
|
||||
+#else
|
||||
+#include <sysdeps/generic/dl-procinfo.h>
|
||||
+#endif
|
||||
@@ -0,0 +1,48 @@
|
||||
--- libc/sysdeps/unix/sysv/linux/dl-osinfo.h.jj 2002-12-10 09:09:24.000000000 -0500
|
||||
+++ libc/sysdeps/unix/sysv/linux/dl-osinfo.h 2003-05-20 17:05:37.000000000 -0400
|
||||
@@ -22,6 +22,7 @@
|
||||
#include <sys/sysctl.h>
|
||||
#include <sys/utsname.h>
|
||||
#include "kernel-features.h"
|
||||
+#include <sysdep.h>
|
||||
|
||||
#ifndef MIN
|
||||
# define MIN(a,b) (((a)<(b))?(a):(b))
|
||||
@@ -37,8 +38,29 @@ dl_fatal (const char *str)
|
||||
_dl_dprintf (2, str);
|
||||
_exit (1);
|
||||
}
|
||||
-#endif
|
||||
|
||||
+static inline void
|
||||
+__attribute__ ((always_inline))
|
||||
+dl_redhat_nptl_check (const char *cp)
|
||||
+{
|
||||
+ cp = strchr (cp, 'n');
|
||||
+ if (__builtin_expect (cp == NULL || cp[1] != 'p'
|
||||
+ || cp[2] != 't' || cp[3] != 'l', 0)
|
||||
+ && GLRO(dl_osversion) < 0x20545
|
||||
+ && GLRO(dl_osversion) > 0x20413)
|
||||
+ {
|
||||
+#ifdef __NR_set_tid_address
|
||||
+ INTERNAL_SYSCALL_DECL (err);
|
||||
+ int ret;
|
||||
+ ret = INTERNAL_SYSCALL (set_tid_address, err, 1, NULL);
|
||||
+ if (INTERNAL_SYSCALL_ERROR_P (ret, err))
|
||||
+#endif
|
||||
+ GLRO(dl_osversion) = 0x20413;
|
||||
+ }
|
||||
+}
|
||||
+#else
|
||||
+#define dl_redhat_nptl_check(cp)
|
||||
+#endif
|
||||
|
||||
#define DL_SYSDEP_OSCHECK(FATAL) \
|
||||
do { \
|
||||
@@ -105,5 +127,6 @@ dl_fatal (const char *str)
|
||||
FATAL ("FATAL: kernel too old\n"); \
|
||||
\
|
||||
GLRO(dl_osversion) = version; \
|
||||
+ dl_redhat_nptl_check (cp); \
|
||||
} \
|
||||
} while (0)
|
||||
@@ -0,0 +1,18 @@
|
||||
--- libc/sysdeps/unix/sysv/linux/powerpc/kernel-features.h.jj 2003-01-30 05:24:37.000000000 -0500
|
||||
+++ libc/sysdeps/unix/sysv/linux/powerpc/kernel-features.h 2003-09-23 18:28:07.000000000 -0400
|
||||
@@ -0,0 +1,15 @@
|
||||
+/* In RHEL3, we can assume the shipped kernel, which is 2.4.21. */
|
||||
+#include_next <kernel-features.h>
|
||||
+
|
||||
+#if !defined __ASSUME_NEW_PRCTL_SYSCALL && defined __powerpc__
|
||||
+# define __ASSUME_NEW_PRCTL_SYSCALL 1
|
||||
+#endif
|
||||
+
|
||||
+#if !defined __ASSUME_FIXED_CLONE_SYSCALL && defined __powerpc__ \
|
||||
+ && !defined __powerpc64__
|
||||
+# define __ASSUME_FIXED_CLONE_SYSCALL 1
|
||||
+#endif
|
||||
+
|
||||
+#if !defined __ASSUME_NEW_RT_SIGRETURN_SYSCALL && defined __powerpc64__
|
||||
+# define __ASSUME_NEW_RT_SIGRETURN_SYSCALL 1
|
||||
+#endif
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,303 @@
|
||||
#if defined __sparc__ && defined __arch64__
|
||||
register void *__thread_self __asm ("g7");
|
||||
#endif
|
||||
#include <sys/types.h>
|
||||
#include <sys/wait.h>
|
||||
#include <stdio.h>
|
||||
#include <errno.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/time.h>
|
||||
#include <dirent.h>
|
||||
#include <stddef.h>
|
||||
#include <fcntl.h>
|
||||
#include <string.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
#define verbose_exec(failcode, path...) \
|
||||
do \
|
||||
{ \
|
||||
char *const arr[] = { path, NULL }; \
|
||||
vexec (failcode, arr); \
|
||||
} while (0)
|
||||
|
||||
__attribute__((noinline)) void vexec (int failcode, char *const path[]);
|
||||
__attribute__((noinline)) void says (const char *str);
|
||||
__attribute__((noinline)) void sayn (long num);
|
||||
__attribute__((noinline)) void message (char *const path[]);
|
||||
|
||||
int
|
||||
main (void)
|
||||
{
|
||||
int rerun_ldconfig = 0, rerun_cnt = 0;
|
||||
char initpath[256];
|
||||
|
||||
#ifdef __i386__
|
||||
char buffer[4096];
|
||||
struct pref {
|
||||
char *p;
|
||||
int len;
|
||||
} prefix[] = { { "libc-", 5 }, { "libm-", 5 },
|
||||
{ "librt-", 6 }, { "libpthread-", 11 },
|
||||
{ "librtkaio-", 10 }, { "libthread_db-", 13 } };
|
||||
int i, j, fd;
|
||||
off_t base;
|
||||
ssize_t ret;
|
||||
#ifdef ARCH_386
|
||||
const char *remove_dirs[] = { "/lib/i686", "/lib/tls" };
|
||||
#else
|
||||
const char *remove_dirs[] = { "/lib/tls/i686" };
|
||||
#endif
|
||||
for (j = 0; j < sizeof (remove_dirs) / sizeof (remove_dirs[0]); ++j)
|
||||
{
|
||||
size_t rmlen = strlen (remove_dirs[j]);
|
||||
fd = open (remove_dirs[j], O_RDONLY);
|
||||
if (fd >= 0
|
||||
&& (ret = getdirentries (fd, buffer, sizeof (buffer), &base))
|
||||
>= (ssize_t) offsetof (struct dirent, d_name))
|
||||
{
|
||||
for (base = 0; base + offsetof (struct dirent, d_name) < ret; )
|
||||
{
|
||||
struct dirent *d = (struct dirent *) (buffer + base);
|
||||
|
||||
for (i = 0; i < sizeof (prefix) / sizeof (prefix[0]); i++)
|
||||
if (! strncmp (d->d_name, prefix[i].p, prefix[i].len))
|
||||
{
|
||||
char *p = d->d_name + prefix[i].len;
|
||||
|
||||
while (*p == '.' || (*p >= '0' && *p <= '9')) p++;
|
||||
if (p[0] == 's' && p[1] == 'o' && p[2] == '\0'
|
||||
&& p + 3 - d->d_name
|
||||
< sizeof (initpath) - rmlen - 1)
|
||||
{
|
||||
memcpy (initpath, remove_dirs[j], rmlen);
|
||||
initpath[rmlen] = '/';
|
||||
strcpy (initpath + rmlen + 1, d->d_name);
|
||||
unlink (initpath);
|
||||
break;
|
||||
}
|
||||
}
|
||||
base += d->d_reclen;
|
||||
}
|
||||
close (fd);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
int ldsocfd = open (LD_SO_CONF, O_RDONLY);
|
||||
struct stat ldsocst;
|
||||
if (ldsocfd >= 0 && fstat (ldsocfd, &ldsocst) >= 0)
|
||||
{
|
||||
char p[ldsocst.st_size + 1];
|
||||
if (read (ldsocfd, p, ldsocst.st_size) == ldsocst.st_size)
|
||||
{
|
||||
p[ldsocst.st_size] = '\0';
|
||||
if (strstr (p, "include ld.so.conf.d/*.conf") == NULL)
|
||||
{
|
||||
close (ldsocfd);
|
||||
ldsocfd = open (LD_SO_CONF, O_WRONLY | O_TRUNC);
|
||||
if (ldsocfd >= 0)
|
||||
{
|
||||
size_t slen = strlen ("include ld.so.conf.d/*.conf\n");
|
||||
if (write (ldsocfd, "include ld.so.conf.d/*.conf\n", slen)
|
||||
!= slen
|
||||
|| write (ldsocfd, p, ldsocst.st_size) != ldsocst.st_size)
|
||||
_exit (109);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (ldsocfd >= 0)
|
||||
close (ldsocfd);
|
||||
}
|
||||
|
||||
do
|
||||
{
|
||||
char linkbuf[64], *linkp;
|
||||
int linklen;
|
||||
|
||||
verbose_exec (110, "/sbin/ldconfig", "/sbin/ldconfig");
|
||||
|
||||
rerun_ldconfig = 0;
|
||||
#ifdef LIBTLS
|
||||
linkp = linkbuf + strlen (LIBTLS);
|
||||
linklen = readlink (LIBTLS "librt.so.1", linkp,
|
||||
sizeof (linkbuf) - 1 - strlen (LIBTLS));
|
||||
if (linklen == strlen ("librtkaio-2.3.X.so")
|
||||
&& memcmp (linkp, "librtkaio-2.3.", 14) == 0
|
||||
&& strchr ("23", linkp[14])
|
||||
&& memcmp (linkp + 15, ".so", 4) == 0)
|
||||
{
|
||||
memcpy (linkbuf, LIBTLS, strlen (LIBTLS));
|
||||
unlink (linkbuf);
|
||||
rerun_ldconfig = 1;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef __i386__
|
||||
linkp = linkbuf + strlen ("/lib/i686/");
|
||||
linklen = readlink ("/lib/i686/librt.so.1", linkp,
|
||||
sizeof (linkbuf) - 1 - strlen ("/lib/i686/"));
|
||||
if (linklen == strlen ("librtkaio-2.3.X.so")
|
||||
&& memcmp (linkp, "librtkaio-2.3.", 14) == 0
|
||||
&& strchr ("23", linkp[14])
|
||||
&& memcmp (linkp + 15, ".so", 4) == 0)
|
||||
{
|
||||
memcpy (linkbuf, "/lib/i686/", strlen ("/lib/i686/"));
|
||||
unlink (linkbuf);
|
||||
rerun_ldconfig = 1;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
while (rerun_ldconfig && ++rerun_cnt < 2);
|
||||
|
||||
if (! utimes (GCONV_MODULES_CACHE, NULL))
|
||||
{
|
||||
verbose_exec (113, "/usr/sbin/iconvconfig", "/usr/sbin/iconvconfig");
|
||||
}
|
||||
|
||||
/* Check if telinit is available and the init fifo as well. */
|
||||
if (access ("/sbin/telinit", X_OK) || access ("/dev/initctl", F_OK))
|
||||
_exit (0);
|
||||
/* Check if we are not inside of some chroot, because we'd just
|
||||
timeout and leave /etc/initrunlvl. */
|
||||
if (readlink ("/proc/1/exe", initpath, 256) <= 0 ||
|
||||
readlink ("/proc/1/root", initpath, 256) <= 0)
|
||||
_exit (0);
|
||||
|
||||
verbose_exec (116, "/sbin/telinit", "/sbin/telinit", "u");
|
||||
|
||||
/* Check if we can safely condrestart sshd. */
|
||||
if (access ("/sbin/service", X_OK) == 0
|
||||
&& access ("/usr/sbin/sshd", X_OK) == 0
|
||||
&& access ("/bin/bash", X_OK) == 0)
|
||||
{
|
||||
verbose_exec (121, "/sbin/service", "/sbin/service", "sshd", "condrestart");
|
||||
}
|
||||
|
||||
_exit(0);
|
||||
}
|
||||
|
||||
int __libc_multiple_threads __attribute__((nocommon));
|
||||
int __libc_enable_asynccancel (void) { return 0; }
|
||||
void __libc_disable_asynccancel (int x) { }
|
||||
void __libc_csu_init (void) { }
|
||||
void __libc_csu_fini (void) { }
|
||||
pid_t __fork (void) { return -1; }
|
||||
char thr_buf[65536];
|
||||
|
||||
#ifndef __powerpc__
|
||||
int
|
||||
__libc_start_main (int (*main) (void), int argc, char **argv,
|
||||
void (*init) (void), void (*fini) (void),
|
||||
void (*rtld_fini) (void), void * stack_end)
|
||||
#else
|
||||
struct startup_info
|
||||
{
|
||||
void *sda_base;
|
||||
int (*main) (int, char **, char **, void *);
|
||||
int (*init) (int, char **, char **, void *);
|
||||
void (*fini) (void);
|
||||
};
|
||||
|
||||
int
|
||||
__libc_start_main (int argc, char **ubp_av, char **ubp_ev,
|
||||
void *auxvec, void (*rtld_fini) (void),
|
||||
struct startup_info *stinfo,
|
||||
char **stack_on_entry)
|
||||
#endif
|
||||
{
|
||||
#if defined __ia64__ || defined __powerpc64__
|
||||
register void *r13 __asm ("r13") = thr_buf + 32768;
|
||||
__asm ("" : : "r" (r13));
|
||||
#elif defined __sparc__
|
||||
register void *g6 __asm ("g6") = thr_buf + 32768;
|
||||
# ifdef __arch64__
|
||||
__thread_self = thr_buf + 32768;
|
||||
# else
|
||||
register void *__thread_self __asm ("g7") = thr_buf + 32768;
|
||||
# endif
|
||||
__asm ("" : : "r" (g6), "r" (__thread_self));
|
||||
#elif defined __s390__ && !defined __s390x__
|
||||
__asm ("sar %%a0,%0" : : "d" (thr_buf + 32768));
|
||||
#elif defined __s390x__
|
||||
__asm ("sar %%a1,%0; srlg 0,%0,32; sar %%a0,0" : : "d" (thr_buf + 32768) : "0");
|
||||
#elif defined __powerpc__ && !defined __powerpc64__
|
||||
register void *r2 __asm ("r2") = thr_buf + 32768;
|
||||
__asm ("" : : "r" (r2));
|
||||
#endif
|
||||
main();
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
vexec (int failcode, char *const path[])
|
||||
{
|
||||
pid_t pid;
|
||||
int status, save_errno;
|
||||
|
||||
pid = vfork ();
|
||||
if (pid == 0)
|
||||
{
|
||||
execv (path[0], path + 1);
|
||||
save_errno = errno;
|
||||
message (path);
|
||||
says (" exec failed with errno ");
|
||||
sayn (save_errno);
|
||||
says ("\n");
|
||||
_exit (failcode);
|
||||
}
|
||||
else if (pid < 0)
|
||||
{
|
||||
save_errno = errno;
|
||||
message (path);
|
||||
says (" fork failed with errno ");
|
||||
sayn (save_errno);
|
||||
says ("\n");
|
||||
_exit (failcode + 1);
|
||||
}
|
||||
if (waitpid (0, &status, 0) != pid || !WIFEXITED (status))
|
||||
{
|
||||
message (path);
|
||||
says (" child terminated abnormally\n");
|
||||
_exit (failcode + 2);
|
||||
}
|
||||
if (WEXITSTATUS (status))
|
||||
{
|
||||
message (path);
|
||||
says (" child exited with exit code ");
|
||||
sayn (WEXITSTATUS (status));
|
||||
says ("\n");
|
||||
_exit (WEXITSTATUS (status));
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
says (const char *str)
|
||||
{
|
||||
write (1, str, strlen (str));
|
||||
}
|
||||
|
||||
void
|
||||
sayn (long num)
|
||||
{
|
||||
char string[sizeof (long) * 3 + 1];
|
||||
char *p = string + sizeof (string) - 1;
|
||||
|
||||
*p = '\0';
|
||||
if (num == 0)
|
||||
*--p = '0';
|
||||
else
|
||||
while (num)
|
||||
{
|
||||
*--p = '0' + num % 10;
|
||||
num = num / 10;
|
||||
}
|
||||
|
||||
says (p);
|
||||
}
|
||||
|
||||
void
|
||||
message (char *const path[])
|
||||
{
|
||||
says ("/usr/sbin/glibc_post_upgrade: While trying to execute ");
|
||||
says (path[0]);
|
||||
}
|
||||
@@ -0,0 +1,344 @@
|
||||
/* Copyright (C) 2001 Red Hat, Inc.
|
||||
|
||||
Written by Jakub Jelinek <jakub@redhat.com>.
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License as
|
||||
published by the Free Software Foundation; either version 2 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
This program 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
|
||||
General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public
|
||||
License along with this program; see the file COPYING. If not,
|
||||
write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
Boston, MA 02111-1307, USA. */
|
||||
|
||||
/* Changes by Rémy Card to use constants and add option -n. */
|
||||
|
||||
#define _GNU_SOURCE
|
||||
#include <sys/types.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/mman.h>
|
||||
#include <string.h>
|
||||
#include <dirent.h>
|
||||
#include <fcntl.h>
|
||||
|
||||
#define NHASH 131072 /* Must be a power of 2! */
|
||||
#define NAMELEN 4096
|
||||
#define NBUF 64
|
||||
|
||||
struct _f;
|
||||
typedef struct _h {
|
||||
struct _h *next;
|
||||
struct _f *chain;
|
||||
off_t size;
|
||||
time_t mtime;
|
||||
} h;
|
||||
|
||||
typedef struct _d {
|
||||
struct _d *next;
|
||||
char name[0];
|
||||
} d;
|
||||
|
||||
d *dirs;
|
||||
|
||||
h *hps[NHASH];
|
||||
|
||||
int no_link = 0;
|
||||
int verbose = 0;
|
||||
int content_only = 0;
|
||||
|
||||
typedef struct _f {
|
||||
struct _f *next;
|
||||
ino_t ino;
|
||||
dev_t dev;
|
||||
unsigned int cksum;
|
||||
char name[0];
|
||||
} f;
|
||||
|
||||
inline unsigned int hash(off_t size, time_t mtime)
|
||||
{
|
||||
return (size ^ mtime) & (NHASH - 1);
|
||||
}
|
||||
|
||||
inline int stcmp(struct stat *st1, struct stat *st2, int content_only)
|
||||
{
|
||||
if (content_only)
|
||||
return st1->st_size != st2->st_size;
|
||||
return st1->st_mode != st2->st_mode || st1->st_uid != st2->st_uid ||
|
||||
st1->st_gid != st2->st_gid || st1->st_size != st2->st_size ||
|
||||
st1->st_mtime != st2->st_mtime;
|
||||
}
|
||||
|
||||
long long ndirs, nobjects, nregfiles, nmmap, ncomp, nlinks, nsaved;
|
||||
|
||||
void doexit(int i)
|
||||
{
|
||||
if (verbose) {
|
||||
fprintf(stderr, "\n\n");
|
||||
fprintf(stderr, "Directories %lld\n", ndirs);
|
||||
fprintf(stderr, "Objects %lld\n", nobjects);
|
||||
fprintf(stderr, "IFREG %lld\n", nregfiles);
|
||||
fprintf(stderr, "Mmaps %lld\n", nmmap);
|
||||
fprintf(stderr, "Comparisons %lld\n", ncomp);
|
||||
fprintf(stderr, "%s %lld\n", (no_link ? "Would link" : "Linked"), nlinks);
|
||||
fprintf(stderr, "%s %lld\n", (no_link ? "Would save" : "saved"), nsaved);
|
||||
}
|
||||
exit(i);
|
||||
}
|
||||
|
||||
void usage(prog)
|
||||
{
|
||||
fprintf (stderr, "Usage: %s [-cnv] directories...\n", prog);
|
||||
exit(255);
|
||||
}
|
||||
|
||||
unsigned int buf[NBUF];
|
||||
char nambuf1[NAMELEN], nambuf2[NAMELEN];
|
||||
|
||||
void rf (char *name)
|
||||
{
|
||||
struct stat st, st2, st3;
|
||||
nobjects++;
|
||||
if (lstat (name, &st))
|
||||
return;
|
||||
if (S_ISDIR (st.st_mode)) {
|
||||
d * dp = malloc(sizeof(d) + 1 + strlen (name));
|
||||
if (!dp) {
|
||||
fprintf(stderr, "\nOut of memory 3\n");
|
||||
doexit(3);
|
||||
}
|
||||
strcpy (dp->name, name);
|
||||
dp->next = dirs;
|
||||
dirs = dp;
|
||||
} else if (S_ISREG (st.st_mode)) {
|
||||
int fd, i;
|
||||
f * fp, * fp2;
|
||||
h * hp;
|
||||
char *p, *q;
|
||||
char *n1, *n2;
|
||||
int cksumsize = sizeof(buf);
|
||||
unsigned int cksum;
|
||||
time_t mtime = content_only ? 0 : st.st_mtime;
|
||||
unsigned int hsh = hash (st.st_size, mtime);
|
||||
nregfiles++;
|
||||
if (verbose > 1)
|
||||
fprintf(stderr, " %s", name);
|
||||
fd = open (name, O_RDONLY);
|
||||
if (fd < 0) return;
|
||||
if (st.st_size < sizeof(buf)) {
|
||||
cksumsize = st.st_size;
|
||||
memset (((char *)buf) + cksumsize, 0, (sizeof(buf) - cksumsize) % sizeof(buf[0]));
|
||||
}
|
||||
if (read (fd, buf, cksumsize) != cksumsize) {
|
||||
close(fd);
|
||||
if (verbose > 1)
|
||||
fprintf(stderr, "\r%*s\r", (int)strlen(name)+2, "");
|
||||
return;
|
||||
}
|
||||
cksumsize = (cksumsize + sizeof(buf[0]) - 1) / sizeof(buf[0]);
|
||||
for (i = 0, cksum = 0; i < cksumsize; i++) {
|
||||
if (cksum + buf[i] < cksum)
|
||||
cksum += buf[i] + 1;
|
||||
else
|
||||
cksum += buf[i];
|
||||
}
|
||||
for (hp = hps[hsh]; hp; hp = hp->next)
|
||||
if (hp->size == st.st_size && hp->mtime == mtime)
|
||||
break;
|
||||
if (!hp) {
|
||||
hp = malloc(sizeof(h));
|
||||
if (!hp) {
|
||||
fprintf(stderr, "\nOut of memory 1\n");
|
||||
doexit(1);
|
||||
}
|
||||
hp->size = st.st_size;
|
||||
hp->mtime = mtime;
|
||||
hp->chain = NULL;
|
||||
hp->next = hps[hsh];
|
||||
hps[hsh] = hp;
|
||||
}
|
||||
for (fp = hp->chain; fp; fp = fp->next)
|
||||
if (fp->cksum == cksum)
|
||||
break;
|
||||
for (fp2 = fp; fp2 && fp2->cksum == cksum; fp2 = fp2->next)
|
||||
if (fp2->ino == st.st_ino && fp2->dev == st.st_dev) {
|
||||
close(fd);
|
||||
if (verbose > 1)
|
||||
fprintf(stderr, "\r%*s\r", (int)strlen(name)+2, "");
|
||||
return;
|
||||
}
|
||||
if (fp) {
|
||||
p = mmap (NULL, st.st_size, PROT_READ, MAP_SHARED, fd, 0);
|
||||
nmmap++;
|
||||
if (p == (void *)-1) {
|
||||
close(fd);
|
||||
fprintf(stderr, "\nFailed to mmap %s\n", name);
|
||||
return;
|
||||
}
|
||||
}
|
||||
for (fp2 = fp; fp2 && fp2->cksum == cksum; fp2 = fp2->next)
|
||||
if (!lstat (fp2->name, &st2) && S_ISREG (st2.st_mode) &&
|
||||
!stcmp (&st, &st2, content_only) &&
|
||||
st2.st_ino != st.st_ino &&
|
||||
st2.st_dev == st.st_dev) {
|
||||
int fd2 = open (fp2->name, O_RDONLY);
|
||||
if (fd2 < 0) continue;
|
||||
if (fstat (fd2, &st2) || !S_ISREG (st2.st_mode)) {
|
||||
close (fd2);
|
||||
continue;
|
||||
}
|
||||
ncomp++;
|
||||
q = mmap (NULL, st.st_size, PROT_READ, MAP_SHARED, fd2, 0);
|
||||
if (q == (void *)-1) {
|
||||
close(fd2);
|
||||
fprintf(stderr, "\nFailed to mmap %s\n", fp2->name);
|
||||
continue;
|
||||
}
|
||||
if (memcmp (p, q, st.st_size)) {
|
||||
munmap (q, st.st_size);
|
||||
close(fd2);
|
||||
continue;
|
||||
}
|
||||
munmap (q, st.st_size);
|
||||
close(fd2);
|
||||
if (lstat (name, &st3)) {
|
||||
fprintf(stderr, "\nCould not stat %s again\n", name);
|
||||
munmap (p, st.st_size);
|
||||
close(fd);
|
||||
return;
|
||||
}
|
||||
st3.st_atime = st.st_atime;
|
||||
if (stcmp (&st, &st3, 0)) {
|
||||
fprintf(stderr, "\nFile %s changed underneath us\n", name);
|
||||
munmap (p, st.st_size);
|
||||
close(fd);
|
||||
return;
|
||||
}
|
||||
n1 = fp2->name;
|
||||
n2 = name;
|
||||
if (!no_link) {
|
||||
strcpy (stpcpy (nambuf2, n2), ".$$$___cleanit___$$$");
|
||||
if (rename (n2, nambuf2)) {
|
||||
fprintf(stderr, "\nFailed to rename %s to %s\n", n2, nambuf2);
|
||||
continue;
|
||||
}
|
||||
if (link (n1, n2)) {
|
||||
fprintf(stderr, "\nFailed to hardlink %s to %s\n", n1, n2);
|
||||
if (rename (nambuf2, n2)) {
|
||||
fprintf(stderr, "\nBad bad - failed to rename back %s to %s\n", nambuf2, n2);
|
||||
}
|
||||
munmap (p, st.st_size);
|
||||
close(fd);
|
||||
return;
|
||||
}
|
||||
unlink (nambuf2);
|
||||
}
|
||||
nlinks++;
|
||||
if (st3.st_nlink > 1) {
|
||||
/* We actually did not save anything this time, since the link second argument
|
||||
had some other links as well. */
|
||||
if (verbose > 1)
|
||||
fprintf(stderr, "\r%*s\r%s %s to %s\n", (int)strlen(name)+2, "", (no_link ? "Would link" : "Linked"), n1, n2);
|
||||
} else {
|
||||
nsaved+=st.st_size;
|
||||
if (verbose > 1)
|
||||
fprintf(stderr, "\r%*s\r%s %s to %s, %s %ld\n", (int)strlen(name)+2, "", (no_link ? "Would link" : "Linked"), n1, n2, (no_link ? "would save" : "saved"), st.st_size);
|
||||
}
|
||||
munmap (p, st.st_size);
|
||||
close(fd);
|
||||
return;
|
||||
}
|
||||
if (fp)
|
||||
munmap (p, st.st_size);
|
||||
fp2 = malloc(sizeof(f) + 1 + strlen (name));
|
||||
if (!fp2) {
|
||||
fprintf(stderr, "\nOut of memory 2\n");
|
||||
doexit(2);
|
||||
}
|
||||
close(fd);
|
||||
fp2->ino = st.st_ino;
|
||||
fp2->dev = st.st_dev;
|
||||
fp2->cksum = cksum;
|
||||
strcpy(fp2->name, name);
|
||||
if (fp) {
|
||||
fp2->next = fp->next;
|
||||
fp->next = fp2;
|
||||
} else {
|
||||
fp2->next = hp->chain;
|
||||
hp->chain = fp2;
|
||||
}
|
||||
if (verbose > 1)
|
||||
fprintf(stderr, "\r%*s\r", (int)strlen(name)+2, "");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
int ch;
|
||||
int i;
|
||||
char *p;
|
||||
d * dp;
|
||||
DIR *dh;
|
||||
struct dirent *di;
|
||||
while ((ch = getopt (argc, argv, "cnv")) != -1) {
|
||||
switch (ch) {
|
||||
case 'n':
|
||||
no_link++;
|
||||
break;
|
||||
case 'v':
|
||||
verbose++;
|
||||
break;
|
||||
case 'c':
|
||||
content_only++;
|
||||
break;
|
||||
default:
|
||||
usage(argv[0]);
|
||||
}
|
||||
}
|
||||
if (optind >= argc)
|
||||
usage(argv[0]);
|
||||
for (i = optind; i < argc; i++)
|
||||
rf(argv[i]);
|
||||
while (dirs) {
|
||||
dp = dirs;
|
||||
dirs = dp->next;
|
||||
strcpy (nambuf1, dp->name);
|
||||
free (dp);
|
||||
strcat (nambuf1, "/");
|
||||
p = strchr (nambuf1, 0);
|
||||
dh = opendir (nambuf1);
|
||||
if (dh == NULL)
|
||||
continue;
|
||||
ndirs++;
|
||||
while ((di = readdir (dh)) != NULL) {
|
||||
if (!di->d_name[0])
|
||||
continue;
|
||||
if (di->d_name[0] == '.') {
|
||||
char *q;
|
||||
if (!di->d_name[1] || !strcmp (di->d_name, "..") || !strncmp (di->d_name, ".in.", 4))
|
||||
continue;
|
||||
q = strrchr (di->d_name, '.');
|
||||
if (q && strlen (q) == 7 && q != di->d_name) {
|
||||
*p = 0;
|
||||
if (verbose)
|
||||
fprintf(stderr, "Skipping %s%s\n", nambuf1, di->d_name);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
strcpy (p, di->d_name);
|
||||
rf(nambuf1);
|
||||
}
|
||||
closedir(dh);
|
||||
}
|
||||
doexit(0);
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,58 @@
|
||||
#!/bin/awk -f
|
||||
/^cvs (diff|server): tag.*is not in file/ {
|
||||
print
|
||||
next
|
||||
}
|
||||
/^cvs (diff|server): Diffing/ {
|
||||
next
|
||||
}
|
||||
/^\? / {
|
||||
next
|
||||
}
|
||||
/^Index:/ {
|
||||
file=$2
|
||||
next
|
||||
}
|
||||
/^===============/ {
|
||||
next
|
||||
}
|
||||
/^RCS/ {
|
||||
next
|
||||
}
|
||||
/^retrieving/ {
|
||||
next
|
||||
}
|
||||
/^diff/ {
|
||||
next
|
||||
}
|
||||
/^---/ {
|
||||
if ($2 ~ /^\/dev\/null/ ||
|
||||
$2 ~ /^\/tmp\//)
|
||||
$2=file
|
||||
if ($2 ~ /.cvsignore$/ ||
|
||||
$2 ~ /^c_stubs/ ||
|
||||
$2 ~ /^rtkaio/ ||
|
||||
$2 ~ /^fedora/ ||
|
||||
$2 ~ /^localedata\/charmaps\/GB18030/ ||
|
||||
$2 ~ /^iconvdata\/gb18030\.c/ ||
|
||||
$2 ~ /^glibc-compat/) {
|
||||
hide = 1
|
||||
next
|
||||
} else {
|
||||
hide = 0
|
||||
}
|
||||
sub(/^---[ ]*/,"--- " OLDVER "/")
|
||||
}
|
||||
/^\+\+\+/ {
|
||||
if (hide)
|
||||
next
|
||||
if ($2 ~ /^\/dev\/null/ ||
|
||||
$2 ~ /^\/tmp\//)
|
||||
$2=file
|
||||
sub(/^\+\+\+[ ]*/,"+++ " NEWVER "/")
|
||||
}
|
||||
{
|
||||
if (hide)
|
||||
next
|
||||
print
|
||||
}
|
||||
@@ -0,0 +1,63 @@
|
||||
#
|
||||
# /etc/nsswitch.conf
|
||||
#
|
||||
# An example Name Service Switch config file. This file should be
|
||||
# sorted with the most-used services at the beginning.
|
||||
#
|
||||
# The entry '[NOTFOUND=return]' means that the search for an
|
||||
# entry should stop if the search in the previous entry turned
|
||||
# up nothing. Note that if the search failed due to some other reason
|
||||
# (like no NIS server responding) then the search continues with the
|
||||
# next entry.
|
||||
#
|
||||
# Legal entries are:
|
||||
#
|
||||
# nisplus or nis+ Use NIS+ (NIS version 3)
|
||||
# nis or yp Use NIS (NIS version 2), also called YP
|
||||
# dns Use DNS (Domain Name Service)
|
||||
# files Use the local files
|
||||
# db Use the local database (.db) files
|
||||
# compat Use NIS on compat mode
|
||||
# hesiod Use Hesiod for user lookups
|
||||
# [NOTFOUND=return] Stop searching if not found so far
|
||||
#
|
||||
|
||||
# To use db, put the "db" in front of "files" for entries you want to be
|
||||
# looked up first in the databases
|
||||
#
|
||||
# Example:
|
||||
#passwd: db files nisplus nis
|
||||
#shadow: db files nisplus nis
|
||||
#group: db files nisplus nis
|
||||
|
||||
passwd: files
|
||||
shadow: files
|
||||
group: files
|
||||
|
||||
#hosts: db files nisplus nis dns
|
||||
hosts: files dns
|
||||
|
||||
# Example - obey only what nisplus tells us...
|
||||
#services: nisplus [NOTFOUND=return] files
|
||||
#networks: nisplus [NOTFOUND=return] files
|
||||
#protocols: nisplus [NOTFOUND=return] files
|
||||
#rpc: nisplus [NOTFOUND=return] files
|
||||
#ethers: nisplus [NOTFOUND=return] files
|
||||
#netmasks: nisplus [NOTFOUND=return] files
|
||||
|
||||
bootparams: nisplus [NOTFOUND=return] files
|
||||
|
||||
ethers: files
|
||||
netmasks: files
|
||||
networks: files
|
||||
protocols: files
|
||||
rpc: files
|
||||
services: files
|
||||
|
||||
netgroup: nisplus
|
||||
|
||||
publickey: nisplus
|
||||
|
||||
automount: files nisplus
|
||||
aliases: files nisplus
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
glibc-compat*.tar.gz
|
||||
@@ -0,0 +1 @@
|
||||
Glibc-2.0 compatibility add-on by Cristian Gafton
|
||||
@@ -0,0 +1,37 @@
|
||||
2000-04-13 Jakub Jelinek <jakub@redhat.com>
|
||||
|
||||
* Makefile (services): revert last change.
|
||||
(libnss1_db-routines): Add db-open.
|
||||
(libnss1_db.so): Remove libdb dependencies, add libdl.
|
||||
* nss_db/db-open.c: New file.
|
||||
* nss_db/dummy-db.h: New file.
|
||||
* nss_db/nss_db.h: New file.
|
||||
* nss_db/db-XXX.c: Update from glibc 2.1.90 nss_db/db-XXX.c,
|
||||
remove errnop passing and EXTRA_ARGS.
|
||||
* nss_db/db-alias.c: Likewise.
|
||||
* nss_db/db-netgrp.c: Likewise.
|
||||
|
||||
2000-01-04 Cristian Gafton <gafton@redhat.com>
|
||||
|
||||
* Makefile (services): disable the compat NSS module for
|
||||
Berkeley DB (nss_db). Berkeley BD is not part of the glibc anymore.
|
||||
|
||||
1999-07-08 Cristian Gafton <gafton@redhat.com>
|
||||
|
||||
* stubs.c (__setfpucw): New function
|
||||
* Makefile: Use -include, not include
|
||||
(archive): New target.
|
||||
|
||||
1999-04-09 Andreas Jaeger <aj@arthur.rhein-neckar.de>
|
||||
* glibc-compat/Makefile: Add rules to link libnss_*.so.1 to libnss1_*.so.2.
|
||||
|
||||
1998-11-18 Cristian Gafton <gafton@redhat.com>
|
||||
|
||||
* shlib-versions: added alpha versions
|
||||
|
||||
* Makefile (services): Added libnss_dns
|
||||
|
||||
1998-11-16 Cristian Gafton <gafton@redhat.com>
|
||||
|
||||
* makedist (archive): remove old tar file just in case
|
||||
|
||||
@@ -0,0 +1,3 @@
|
||||
resolv
|
||||
nss
|
||||
nis
|
||||
@@ -0,0 +1,150 @@
|
||||
# Copyright (C) 1996, 1997, 1998 Free Software Foundation, Inc.
|
||||
|
||||
# This is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU Library General Public License as
|
||||
# published by the Free Software Foundation; either version 2 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
|
||||
# Library General Public License for more details.
|
||||
|
||||
# You should have received a copy of the GNU Library General Public
|
||||
# License along with the GNU C Library; see the file COPYING.LIB. If not,
|
||||
# write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
# Boston, MA 02111-1307, USA.
|
||||
|
||||
# $Id$
|
||||
|
||||
subdir := glibc-compat
|
||||
|
||||
distribute := nss-nis.h
|
||||
|
||||
# This is the trivial part which goes into libc itself.
|
||||
routines =
|
||||
|
||||
# These are the databases that go through nss dispatch.
|
||||
# Caution: if you add a database here, you must add its real name
|
||||
# in databases.def, too.
|
||||
databases = proto service hosts network grp pwd rpc ethers \
|
||||
spwd netgrp alias
|
||||
|
||||
# Specify rules for the nss_* modules. We have some services.
|
||||
services := files nis compat dns
|
||||
|
||||
extra-libs := $(services:%=libnss1_%) libNoVersion
|
||||
# These libraries will be built in the `others' pass rather than
|
||||
# the `lib' pass, because they depend on libc.so being built already.
|
||||
extra-libs-others = $(extra-libs)
|
||||
|
||||
# The sources are found in the appropriate subdir.
|
||||
subdir-dirs = $(services:%=nss_%)
|
||||
vpath %.c $(subdir-dirs)
|
||||
|
||||
libnss1_files-routines := $(addprefix files-,$(databases))
|
||||
libnss1_compat-routines := $(addprefix compat-,grp pwd spwd)
|
||||
libnss1_nis-routines := $(addprefix nis-,$(databases))
|
||||
libnss1_dns-routines := $(addprefix dns-, host network)
|
||||
|
||||
libcompat-routines := $(addprefix old, fileops iofdopen iopopen stdfiles \
|
||||
iofclose iofopen pclose tmpfile)
|
||||
libNoVersion-routines := stubs
|
||||
|
||||
libnss1_files-inhibit-o = $(filter-out .os,$(object-suffixes))
|
||||
libnss1_compat-inhibit-o = $(filter-out .os,$(object-suffixes))
|
||||
libnss1_nis-inhibit-o = $(filter-out .os,$(object-suffixes))
|
||||
libnss1_dns-inhibit-o = $(filter-out .os,$(object-suffixes))
|
||||
|
||||
-include ../Rules
|
||||
|
||||
# Force the soname to be libnss_*.so.1 for compatibility.
|
||||
LDFLAGS-nss1_files.so = -Wl,-soname=lib$(libprefix)nss_files.so$($(@F)-version)
|
||||
LDFLAGS-nss1_nis.so = -Wl,-soname=lib$(libprefix)nss_nis.so$($(@F)-version)
|
||||
LDFLAGS-nss1_compat.so = -Wl,-soname=lib$(libprefix)nss_compat.so$($(@F)-version)
|
||||
LDFLAGS-nss1_dns.so = -Wl,-soname=lib$(libprefix)nss_dns.so$($(@F)-version)
|
||||
|
||||
-include ../Makeconfig
|
||||
|
||||
ifeq (yes,$(build-shared))
|
||||
install-others += $(inst_slibdir)/libnss_files.so$(libnss1_files.so-version) \
|
||||
$(inst_slibdir)/libnss_nis.so$(libnss1_nis.so-version) \
|
||||
$(inst_slibdir)/libnss_compat.so$(libnss1_compat.so-version) \
|
||||
$(inst_slibdir)/libnss_dns.so$(libnss1_dns.so-version)
|
||||
endif
|
||||
|
||||
$(inst_slibdir)/libnss_files.so$(libnss1_files.so-version): $(inst_slibdir)/libnss1_files-$(version).so $(+force)
|
||||
rm -f $@
|
||||
$(LN_S) $(<F) $@
|
||||
|
||||
$(inst_slibdir)/libnss_nis.so$(libnss1_nis.so-version): $(inst_slibdir)/libnss1_nis-$(version).so $(+force)
|
||||
rm -f $@
|
||||
$(LN_S) $(<F) $@
|
||||
|
||||
$(inst_slibdir)/libnss_compat.so$(libnss1_compat.so-version): $(inst_slibdir)/libnss1_compat-$(version).so $(+force)
|
||||
rm -f $@
|
||||
$(LN_S) $(<F) $@
|
||||
|
||||
$(inst_slibdir)/libnss_dns.so$(libnss1_dns.so-version): $(inst_slibdir)/libnss1_dns-$(version).so $(+force)
|
||||
rm -f $@
|
||||
$(LN_S) $(<F) $@
|
||||
|
||||
|
||||
$(objpfx)libnss1_compat.so: $(common-objpfx)nis/libnsl.so$(libnsl.so-version) \
|
||||
$(objpfx)libnss1_files.so
|
||||
$(objpfx)libnss1_nis.so: $(common-objpfx)nis/libnsl.so$(libnsl.so-version) \
|
||||
$(objpfx)libnss1_files.so
|
||||
|
||||
# The DNS NSS modules needs the resolver.
|
||||
#$(objpfx)libnss1_dns.so: $(filter-out $(common-objpfx)resolv/stamp.os, \
|
||||
# $(wildcard $(common-objpfx)resolv/*.os)) \
|
||||
# $(common-objpfx)libc.so
|
||||
$(objpfx)libnss1_dns.so: $(common-objpfx)resolv/libresolv.so $(common-objpfx)libc.so
|
||||
|
||||
# Depend on libc.so so a DT_NEEDED is generated in the shared objects.
|
||||
# This ensures they will load libc.so for needed symbols if loaded by
|
||||
# a statically-linked program that hasn't already loaded it.
|
||||
$(objpfx)libnss1_compat.so: $(common-objpfx)nis/libnsl.so$(libnsl.so-version) \
|
||||
$(objpfx)libnss1_files.so $(common-objpfx)libc.so
|
||||
$(objpfx)libnss1_dns.so: $(common-objpfx)resolv/libresolv.so \
|
||||
$(common-objpfx)libc.so
|
||||
$(objpfs)libnss1_files.so: $(common-objpfx)libc.so
|
||||
$(objpfx)libnss1_nis.so: $(common-objpfx)nis/libnsl.so$(libnsl.so-version) \
|
||||
$(objpfx)libnss1_files.so $(common-objpfx)libc.so
|
||||
|
||||
check-abi-libNoVersion: $(..)scripts/extract-abilist.awk
|
||||
@:
|
||||
update-abi-libNoVersion: $(..)scripts/merge-abilist.awk
|
||||
@:
|
||||
check-abi-libnss1_compat: $(..)scripts/extract-abilist.awk
|
||||
@:
|
||||
update-abi-libnss1_compat: $(..)scripts/merge-abilist.awk
|
||||
@:
|
||||
check-abi-libnss1_dns: $(..)scripts/extract-abilist.awk
|
||||
@:
|
||||
update-abi-libnss1_dns: $(..)scripts/merge-abilist.awk
|
||||
@:
|
||||
check-abi-libnss1_files: $(..)scripts/extract-abilist.awk
|
||||
@:
|
||||
update-abi-libnss1_files: $(..)scripts/merge-abilist.awk
|
||||
@:
|
||||
check-abi-libnss1_nis: $(..)scripts/extract-abilist.awk
|
||||
@:
|
||||
update-abi-libnss1_nis: $(..)scripts/merge-abilist.awk
|
||||
@:
|
||||
|
||||
#
|
||||
# This is needed to build the separate tarball
|
||||
#
|
||||
pkgNAME = $(subdir)
|
||||
pkgVERSION = 2.1.3
|
||||
pkgCVSTAG = $(pkgNAME)_$(subst .,-,$(pkgVERSION))
|
||||
|
||||
archive:
|
||||
@rm -f *.tar.gz *~
|
||||
cvs tag -F $(pkgCVSTAG) .
|
||||
@rm -rf /tmp/$(pkgNAME)-$(pkgVERSION) /tmp/$(pkgNAME) $(pkgNAME)-$(pkgVERSION).tar.gz
|
||||
@cd /tmp; cvs export -r$(pkgCVSTAG) $(pkgNAME)
|
||||
@pkgDIR=$$PWD; cd /tmp; tar cvzf $$pkgDIR/$(pkgNAME)-$(pkgVERSION).tar.gz $(pkgNAME)
|
||||
@rm -rf /tmp/$(pkgNAME)
|
||||
@echo "The archive is in $(pkgNAME)-$(pkgVERSION).tar.gz"
|
||||
@@ -0,0 +1,106 @@
|
||||
libnss1_db {
|
||||
GLIBC_2.0 {
|
||||
_nss_db_endaliasent; _nss_db_endetherent; _nss_db_endgrent;
|
||||
_nss_db_endnetgrent; _nss_db_endprotoent; _nss_db_endpwent;
|
||||
_nss_db_endrpcent; _nss_db_endservent; _nss_db_endspent;
|
||||
_nss_db_getaliasbyname_r; _nss_db_getaliasent_r; _nss_db_getetherent_r;
|
||||
_nss_db_getgrent_r; _nss_db_getgrgid_r; _nss_db_getgrnam_r;
|
||||
_nss_db_gethostton_r; _nss_db_getnetgrent_r; _nss_db_getntohost_r;
|
||||
_nss_db_getprotobyname_r; _nss_db_getprotobynumber_r;
|
||||
_nss_db_getprotoent_r; _nss_db_getpwent_r; _nss_db_getpwnam_r;
|
||||
_nss_db_getpwuid_r; _nss_db_getrpcbyname_r; _nss_db_getrpcbynumber_r;
|
||||
_nss_db_getrpcent_r; _nss_db_getservbyname_r; _nss_db_getservbyport_r;
|
||||
_nss_db_getservent_r; _nss_db_getspent_r; _nss_db_getspnam_r;
|
||||
_nss_db_setaliasent; _nss_db_setetherent; _nss_db_setgrent;
|
||||
_nss_db_setnetgrent; _nss_db_setprotoent; _nss_db_setpwent;
|
||||
_nss_db_setrpcent; _nss_db_setservent; _nss_db_setspent;
|
||||
}
|
||||
}
|
||||
|
||||
libnss1_dns {
|
||||
GLIBC_2.0 {
|
||||
_nss_dns_gethostbyaddr_r; _nss_dns_gethostbyname2_r;
|
||||
_nss_dns_gethostbyname_r; _nss_dns_getnetbyaddr_r;
|
||||
_nss_dns_getnetbyname_r;
|
||||
}
|
||||
}
|
||||
|
||||
libnss1_files {
|
||||
GLIBC_2.0 {
|
||||
_nss_files_setaliasent; _nss_files_endaliasent;
|
||||
_nss_files_getaliasbyname_r; _nss_files_getaliasent_r;
|
||||
|
||||
_nss_files_setetherent; _nss_files_endetherent;
|
||||
_nss_files_getetherent_r; _nss_files_parse_etherent;
|
||||
|
||||
_nss_files_setgrent; _nss_files_endgrent;
|
||||
_nss_files_getgrent_r; _nss_files_getgrgid_r; _nss_files_getgrnam_r;
|
||||
|
||||
_nss_files_sethostent; _nss_files_endhostent;
|
||||
_nss_files_gethostbyaddr_r; _nss_files_gethostbyname2_r; _nss_files_gethostbyname_r;
|
||||
_nss_files_gethostent_r; _nss_files_gethostton_r;
|
||||
|
||||
_nss_files_setnetent; _nss_files_endnetent;
|
||||
_nss_files_getnetbyaddr_r; _nss_files_getnetbyname_r;
|
||||
_nss_files_getnetent_r; _nss_files_getntohost_r;
|
||||
_nss_files_parse_netent;
|
||||
|
||||
_nss_files_setnetgrent; _nss_files_endnetgrent; _nss_files_getnetgrent_r;
|
||||
|
||||
_nss_files_setprotoent; _nss_files_endprotoent;
|
||||
_nss_files_getprotobyname_r; _nss_files_getprotobynumber_r;
|
||||
_nss_files_getprotoent_r; _nss_files_parse_protoent;
|
||||
|
||||
_nss_files_setpwent; _nss_files_endpwent;
|
||||
_nss_files_getpwent_r; _nss_files_getpwnam_r; _nss_files_getpwuid_r;
|
||||
|
||||
_nss_files_setrpcent; _nss_files_endrpcent;
|
||||
_nss_files_getrpcbyname_r; _nss_files_getrpcbynumber_r;
|
||||
_nss_files_getrpcent_r;
|
||||
_nss_files_parse_rpcent;
|
||||
|
||||
_nss_files_setservent; _nss_files_endservent;
|
||||
_nss_files_getservbyname_r; _nss_files_getservbyport_r;
|
||||
_nss_files_getservent_r;
|
||||
_nss_files_parse_servent;
|
||||
|
||||
_nss_files_setspent; _nss_files_endspent;
|
||||
_nss_files_getspent_r; _nss_files_getspnam_r;
|
||||
|
||||
_nss_netgroup_parseline;
|
||||
}
|
||||
}
|
||||
|
||||
libnss1_compat {
|
||||
GLIBC_2.0 {
|
||||
_nss_compat_endgrent; _nss_compat_endpwent; _nss_compat_endspent;
|
||||
_nss_compat_getgrent_r; _nss_compat_getgrgid_r; _nss_compat_getgrnam_r;
|
||||
_nss_compat_getpwent_r; _nss_compat_getpwnam_r; _nss_compat_getpwuid_r;
|
||||
_nss_compat_getspent_r; _nss_compat_getspnam_r; _nss_compat_initgroups;
|
||||
_nss_compat_setgrent; _nss_compat_setpwent; _nss_compat_setspent;
|
||||
}
|
||||
}
|
||||
|
||||
libnss1_nis {
|
||||
GLIBC_2.0 {
|
||||
_nss_nis_endaliasent; _nss_nis_endetherent; _nss_nis_endgrent;
|
||||
_nss_nis_endhostent; _nss_nis_endnetent; _nss_nis_endnetgrent;
|
||||
_nss_nis_endprotoent; _nss_nis_endpwent; _nss_nis_endrpcent;
|
||||
_nss_nis_endservent; _nss_nis_endspent; _nss_nis_getaliasbyname_r;
|
||||
_nss_nis_getaliasent_r; _nss_nis_getetherent_r; _nss_nis_getgrent_r;
|
||||
_nss_nis_getgrgid_r; _nss_nis_getgrnam_r; _nss_nis_gethostbyaddr_r;
|
||||
_nss_nis_gethostbyname2_r; _nss_nis_gethostbyname_r; _nss_nis_gethostent_r;
|
||||
_nss_nis_gethostton_r; _nss_nis_getnetbyaddr_r; _nss_nis_getnetbyname_r;
|
||||
_nss_nis_getnetent_r; _nss_nis_getnetgrent_r; _nss_nis_getntohost_r;
|
||||
_nss_nis_getprotobyname_r; _nss_nis_getprotobynumber_r;
|
||||
_nss_nis_getprotoent_r; _nss_nis_getpublickey; _nss_nis_getpwent_r;
|
||||
_nss_nis_getpwnam_r; _nss_nis_getpwuid_r; _nss_nis_getrpcbyname_r;
|
||||
_nss_nis_getrpcbynumber_r; _nss_nis_getrpcent_r; _nss_nis_getsecretkey;
|
||||
_nss_nis_getservbyname_r; _nss_nis_getservbyport_r; _nss_nis_getservent_r;
|
||||
_nss_nis_getspent_r; _nss_nis_getspnam_r; _nss_nis_initgroups;
|
||||
_nss_nis_netname2user; _nss_nis_setaliasent; _nss_nis_setetherent;
|
||||
_nss_nis_setgrent; _nss_nis_sethostent; _nss_nis_setnetent;
|
||||
_nss_nis_setnetgrent; _nss_nis_setprotoent; _nss_nis_setpwent;
|
||||
_nss_nis_setrpcent; _nss_nis_setservent; _nss_nis_setspent;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
libnss1_files {
|
||||
GLIBC_2.0
|
||||
}
|
||||
libnss1_db {
|
||||
GLIBC_2.0
|
||||
}
|
||||
libnss1_dns {
|
||||
GLIBC_2.0
|
||||
}
|
||||
libnss1_nis {
|
||||
GLIBC_2.0
|
||||
}
|
||||
libnss1_compat {
|
||||
GLIBC_2.0
|
||||
}
|
||||
+3
@@ -0,0 +1,3 @@
|
||||
# This is only to keep the GNU C library configure mechanism happy.
|
||||
# This is a shell script fragment sourced by the main configure script.
|
||||
# We have nothing we need to add here.
|
||||
@@ -0,0 +1,20 @@
|
||||
#ifndef _ALIASES_H
|
||||
#include <inet/aliases.h>
|
||||
|
||||
extern int __getaliasent_r (struct aliasent *__restrict __result_buf,
|
||||
char *__restrict __buffer, size_t __buflen,
|
||||
struct aliasent **__restrict __result);
|
||||
extern int __old_getaliasent_r (struct aliasent *__restrict __result_buf,
|
||||
char *__restrict __buffer, size_t __buflen,
|
||||
struct aliasent **__restrict __result);
|
||||
|
||||
extern int __getaliasbyname_r (__const char *__restrict __name,
|
||||
struct aliasent *__restrict __result_buf,
|
||||
char *__restrict __buffer, size_t __buflen,
|
||||
struct aliasent **__restrict __result);
|
||||
extern int __old_getaliasbyname_r (__const char *__restrict __name,
|
||||
struct aliasent *__restrict __result_buf,
|
||||
char *__restrict __buffer, size_t __buflen,
|
||||
struct aliasent **__restrict __result);
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,29 @@
|
||||
#ifndef _GRP_H
|
||||
#include <grp/grp.h>
|
||||
|
||||
/* Now define the internal interfaces. */
|
||||
extern int __getgrent_r (struct group *__resultbuf, char *buffer,
|
||||
size_t __buflen, struct group **__result);
|
||||
extern int __old_getgrent_r (struct group *__resultbuf, char *buffer,
|
||||
size_t __buflen, struct group **__result);
|
||||
extern int __fgetgrent_r (FILE * __stream, struct group *__resultbuf,
|
||||
char *buffer, size_t __buflen,
|
||||
struct group **__result);
|
||||
|
||||
/* Search for an entry with a matching group ID. */
|
||||
extern int __getgrgid_r (__gid_t __gid, struct group *__resultbuf,
|
||||
char *__buffer, size_t __buflen,
|
||||
struct group **__result);
|
||||
extern int __old_getgrgid_r (__gid_t __gid, struct group *__resultbuf,
|
||||
char *__buffer, size_t __buflen,
|
||||
struct group **__result);
|
||||
|
||||
/* Search for an entry with a matching group name. */
|
||||
extern int __getgrnam_r (__const char *__name, struct group *__resultbuf,
|
||||
char *__buffer, size_t __buflen,
|
||||
struct group **__result);
|
||||
extern int __old_getgrnam_r (__const char *__name, struct group *__resultbuf,
|
||||
char *__buffer, size_t __buflen,
|
||||
struct group **__result);
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,178 @@
|
||||
#ifndef _NETDB_H
|
||||
#include <glibc-compat/include/rpc/netdb.h>
|
||||
#include <resolv/netdb.h>
|
||||
|
||||
/* Macros for accessing h_errno from inside libc. */
|
||||
# ifdef _LIBC_REENTRANT
|
||||
# include <tls.h>
|
||||
# if USE___THREAD
|
||||
# undef h_errno
|
||||
# ifndef NOT_IN_libc
|
||||
# define h_errno __libc_h_errno
|
||||
# else
|
||||
# define h_errno h_errno /* For #ifndef h_errno tests. */
|
||||
# endif
|
||||
extern __thread int h_errno attribute_tls_model_ie;
|
||||
# define __set_h_errno(x) (h_errno = (x))
|
||||
# else
|
||||
static inline int
|
||||
__set_h_errno (int __err)
|
||||
{
|
||||
return *__h_errno_location () = __err;
|
||||
}
|
||||
# endif
|
||||
# else
|
||||
# undef h_errno
|
||||
# define __set_h_errno(x) (h_errno = (x))
|
||||
extern int h_errno;
|
||||
# endif /* _LIBC_REENTRANT */
|
||||
|
||||
/* Document internal interfaces. */
|
||||
extern int __gethostent_r (struct hostent *__restrict __result_buf,
|
||||
char *__restrict __buf, size_t __buflen,
|
||||
struct hostent **__restrict __result,
|
||||
int *__restrict __h_errnop);
|
||||
extern int __old_gethostent_r (struct hostent *__restrict __result_buf,
|
||||
char *__restrict __buf, size_t __buflen,
|
||||
struct hostent **__restrict __result,
|
||||
int *__restrict __h_errnop);
|
||||
|
||||
extern int __gethostbyaddr_r (__const void *__restrict __addr,
|
||||
socklen_t __len, int __type,
|
||||
struct hostent *__restrict __result_buf,
|
||||
char *__restrict __buf, size_t __buflen,
|
||||
struct hostent **__restrict __result,
|
||||
int *__restrict __h_errnop);
|
||||
extern int __old_gethostbyaddr_r (__const void *__restrict __addr,
|
||||
socklen_t __len, int __type,
|
||||
struct hostent *__restrict __result_buf,
|
||||
char *__restrict __buf, size_t __buflen,
|
||||
struct hostent **__restrict __result,
|
||||
int *__restrict __h_errnop);
|
||||
|
||||
extern int __gethostbyname_r (__const char *__restrict __name,
|
||||
struct hostent *__restrict __result_buf,
|
||||
char *__restrict __buf, size_t __buflen,
|
||||
struct hostent **__restrict __result,
|
||||
int *__restrict __h_errnop);
|
||||
extern int __old_gethostbyname_r (__const char *__restrict __name,
|
||||
struct hostent *__restrict __result_buf,
|
||||
char *__restrict __buf, size_t __buflen,
|
||||
struct hostent **__restrict __result,
|
||||
int *__restrict __h_errnop);
|
||||
|
||||
extern int __gethostbyname2_r (__const char *__restrict __name, int __af,
|
||||
struct hostent *__restrict __result_buf,
|
||||
char *__restrict __buf, size_t __buflen,
|
||||
struct hostent **__restrict __result,
|
||||
int *__restrict __h_errnop);
|
||||
extern int __old_gethostbyname2_r (__const char *__restrict __name, int __af,
|
||||
struct hostent *__restrict __result_buf,
|
||||
char *__restrict __buf, size_t __buflen,
|
||||
struct hostent **__restrict __result,
|
||||
int *__restrict __h_errnop);
|
||||
|
||||
extern int __getnetent_r (struct netent *__restrict __result_buf,
|
||||
char *__restrict __buf, size_t __buflen,
|
||||
struct netent **__restrict __result,
|
||||
int *__restrict __h_errnop);
|
||||
extern int __old_getnetent_r (struct netent *__restrict __result_buf,
|
||||
char *__restrict __buf, size_t __buflen,
|
||||
struct netent **__restrict __result,
|
||||
int *__restrict __h_errnop);
|
||||
|
||||
extern int __getnetbyaddr_r (uint32_t __net, int __type,
|
||||
struct netent *__restrict __result_buf,
|
||||
char *__restrict __buf, size_t __buflen,
|
||||
struct netent **__restrict __result,
|
||||
int *__restrict __h_errnop);
|
||||
extern int __old_getnetbyaddr_r (uint32_t __net, int __type,
|
||||
struct netent *__restrict __result_buf,
|
||||
char *__restrict __buf, size_t __buflen,
|
||||
struct netent **__restrict __result,
|
||||
int *__restrict __h_errnop);
|
||||
|
||||
extern int __getnetbyname_r (__const char *__restrict __name,
|
||||
struct netent *__restrict __result_buf,
|
||||
char *__restrict __buf, size_t __buflen,
|
||||
struct netent **__restrict __result,
|
||||
int *__restrict __h_errnop);
|
||||
extern int __old_getnetbyname_r (__const char *__restrict __name,
|
||||
struct netent *__restrict __result_buf,
|
||||
char *__restrict __buf, size_t __buflen,
|
||||
struct netent **__restrict __result,
|
||||
int *__restrict __h_errnop);
|
||||
|
||||
extern int __getservent_r (struct servent *__restrict __result_buf,
|
||||
char *__restrict __buf, size_t __buflen,
|
||||
struct servent **__restrict __result);
|
||||
extern int __old_getservent_r (struct servent *__restrict __result_buf,
|
||||
char *__restrict __buf, size_t __buflen,
|
||||
struct servent **__restrict __result);
|
||||
|
||||
extern int __getservbyname_r (__const char *__restrict __name,
|
||||
__const char *__restrict __proto,
|
||||
struct servent *__restrict __result_buf,
|
||||
char *__restrict __buf, size_t __buflen,
|
||||
struct servent **__restrict __result);
|
||||
extern int __old_getservbyname_r (__const char *__restrict __name,
|
||||
__const char *__restrict __proto,
|
||||
struct servent *__restrict __result_buf,
|
||||
char *__restrict __buf, size_t __buflen,
|
||||
struct servent **__restrict __result);
|
||||
|
||||
extern int __getservbyport_r (int __port,
|
||||
__const char *__restrict __proto,
|
||||
struct servent *__restrict __result_buf,
|
||||
char *__restrict __buf, size_t __buflen,
|
||||
struct servent **__restrict __result);
|
||||
extern int __old_getservbyport_r (int __port,
|
||||
__const char *__restrict __proto,
|
||||
struct servent *__restrict __result_buf,
|
||||
char *__restrict __buf, size_t __buflen,
|
||||
struct servent **__restrict __result);
|
||||
|
||||
extern int __getprotoent_r (struct protoent *__restrict __result_buf,
|
||||
char *__restrict __buf, size_t __buflen,
|
||||
struct protoent **__restrict __result);
|
||||
extern int __old_getprotoent_r (struct protoent *__restrict __result_buf,
|
||||
char *__restrict __buf, size_t __buflen,
|
||||
struct protoent **__restrict __result);
|
||||
|
||||
extern int __getprotobyname_r (__const char *__restrict __name,
|
||||
struct protoent *__restrict __result_buf,
|
||||
char *__restrict __buf, size_t __buflen,
|
||||
struct protoent **__restrict __result);
|
||||
extern int __old_getprotobyname_r (__const char *__restrict __name,
|
||||
struct protoent *__restrict __result_buf,
|
||||
char *__restrict __buf, size_t __buflen,
|
||||
struct protoent **__restrict __result);
|
||||
|
||||
extern int __getprotobynumber_r (int __proto,
|
||||
struct protoent *__restrict __res_buf,
|
||||
char *__restrict __buf, size_t __buflen,
|
||||
struct protoent **__restrict __result);
|
||||
extern int __old_getprotobynumber_r (int __proto,
|
||||
struct protoent *__restrict __res_buf,
|
||||
char *__restrict __buf, size_t __buflen,
|
||||
struct protoent **__restrict __result);
|
||||
|
||||
extern int __getnetgrent_r (char **__restrict __hostp,
|
||||
char **__restrict __userp,
|
||||
char **__restrict __domainp,
|
||||
char *__restrict __buffer, size_t __buflen);
|
||||
|
||||
extern int ruserpass (const char *host, const char **aname,
|
||||
const char **apass);
|
||||
|
||||
|
||||
/* The following declarations and definitions have been removed from
|
||||
the public header since we don't want people to use them. */
|
||||
|
||||
#define AI_V4MAPPED 0x0008 /* IPv4-mapped addresses are acceptable. */
|
||||
#define AI_ALL 0x0010 /* Return both IPv4 and IPv6 addresses. */
|
||||
#define AI_ADDRCONFIG 0x0020 /* Use configuration of this host to choose
|
||||
returned address type. */
|
||||
#define AI_DEFAULT (AI_V4MAPPED | AI_ADDRCONFIG)
|
||||
|
||||
#endif /* !_NETDB_H */
|
||||
@@ -0,0 +1,25 @@
|
||||
#ifndef _PWD_H
|
||||
#include <pwd/pwd.h>
|
||||
|
||||
/* Now define the internal interfaces. */
|
||||
extern int __getpwent_r (struct passwd *__resultbuf, char *__buffer,
|
||||
size_t __buflen, struct passwd **__result);
|
||||
extern int __old_getpwent_r (struct passwd *__resultbuf, char *__buffer,
|
||||
size_t __buflen, struct passwd **__result);
|
||||
extern int __getpwuid_r (__uid_t __uid, struct passwd *__resultbuf,
|
||||
char *__buffer, size_t __buflen,
|
||||
struct passwd **__result);
|
||||
extern int __old_getpwuid_r (__uid_t __uid, struct passwd *__resultbuf,
|
||||
char *__buffer, size_t __buflen,
|
||||
struct passwd **__result);
|
||||
extern int __getpwnam_r (__const char *__name, struct passwd *__resultbuf,
|
||||
char *__buffer, size_t __buflen,
|
||||
struct passwd **__result);
|
||||
extern int __old_getpwnam_r (__const char *__name, struct passwd *__resultbuf,
|
||||
char *__buffer, size_t __buflen,
|
||||
struct passwd **__result);
|
||||
extern int __fgetpwent_r (FILE * __stream, struct passwd *__resultbuf,
|
||||
char *__buffer, size_t __buflen,
|
||||
struct passwd **__result);
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,24 @@
|
||||
#ifndef _RPC_NETDB_H
|
||||
#include <sunrpc/rpc/netdb.h>
|
||||
|
||||
extern int __getrpcbyname_r (__const char *__name, struct rpcent *__result_buf,
|
||||
char *__buffer, size_t __buflen,
|
||||
struct rpcent **__result);
|
||||
extern int __old_getrpcbyname_r (__const char *__name,
|
||||
struct rpcent *__result_buf,
|
||||
char *__buffer, size_t __buflen,
|
||||
struct rpcent **__result);
|
||||
|
||||
extern int __getrpcbynumber_r (int __number, struct rpcent *__result_buf,
|
||||
char *__buffer, size_t __buflen,
|
||||
struct rpcent **__result);
|
||||
extern int __old_getrpcbynumber_r (int __number, struct rpcent *__result_buf,
|
||||
char *__buffer, size_t __buflen,
|
||||
struct rpcent **__result);
|
||||
|
||||
extern int __getrpcent_r (struct rpcent *__result_buf, char *__buffer,
|
||||
size_t __buflen, struct rpcent **__result);
|
||||
extern int __old_getrpcent_r (struct rpcent *__result_buf, char *__buffer,
|
||||
size_t __buflen, struct rpcent **__result);
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,24 @@
|
||||
#ifndef _SHADOW_H
|
||||
#include <shadow/shadow.h>
|
||||
|
||||
/* Now define the internal interfaces. */
|
||||
extern int __getspent_r (struct spwd *__result_buf, char *__buffer,
|
||||
size_t __buflen, struct spwd **__result);
|
||||
extern int __old_getspent_r (struct spwd *__result_buf, char *__buffer,
|
||||
size_t __buflen, struct spwd **__result);
|
||||
extern int __getspnam_r (__const char *__name, struct spwd *__result_buf,
|
||||
char *__buffer, size_t __buflen,
|
||||
struct spwd **__result);
|
||||
extern int __old_getspnam_r (__const char *__name, struct spwd *__result_buf,
|
||||
char *__buffer, size_t __buflen,
|
||||
struct spwd **__result);
|
||||
extern int __sgetspent_r (__const char *__string,
|
||||
struct spwd *__result_buf, char *__buffer,
|
||||
size_t __buflen, struct spwd **__result);
|
||||
extern int __fgetspent_r (FILE *__stream, struct spwd *__result_buf,
|
||||
char *__buffer, size_t __buflen,
|
||||
struct spwd **__result);
|
||||
extern int __lckpwdf (void);
|
||||
extern int __ulckpwdf (void);
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,58 @@
|
||||
/* Copyright (C) 1996 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 Library General Public License as
|
||||
published by the Free Software Foundation; either version 2 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
|
||||
Library General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Library General Public
|
||||
License along with the GNU C Library; see the file COPYING.LIB. If not,
|
||||
write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
Boston, MA 02111-1307, USA. */
|
||||
|
||||
#ifndef _NIS_NSS_NIS_H
|
||||
#define _NIS_NSS_NIS_H 1
|
||||
|
||||
#include <rpcsvc/ypclnt.h>
|
||||
|
||||
#include "nsswitch.h"
|
||||
|
||||
|
||||
/* Convert YP error number to NSS error number. */
|
||||
static enum nss_status yperr2nss_tab[] =
|
||||
{
|
||||
[YPERR_SUCCESS] = NSS_STATUS_SUCCESS,
|
||||
[YPERR_BADARGS] = NSS_STATUS_UNAVAIL,
|
||||
[YPERR_RPC] = NSS_STATUS_UNAVAIL,
|
||||
[YPERR_DOMAIN] = NSS_STATUS_UNAVAIL,
|
||||
[YPERR_MAP] = NSS_STATUS_UNAVAIL,
|
||||
[YPERR_KEY] = NSS_STATUS_NOTFOUND,
|
||||
[YPERR_YPERR] = NSS_STATUS_UNAVAIL,
|
||||
[YPERR_RESRC] = NSS_STATUS_TRYAGAIN,
|
||||
[YPERR_NOMORE] = NSS_STATUS_NOTFOUND,
|
||||
[YPERR_PMAP] = NSS_STATUS_UNAVAIL,
|
||||
[YPERR_YPBIND] = NSS_STATUS_UNAVAIL,
|
||||
[YPERR_YPSERV] = NSS_STATUS_UNAVAIL,
|
||||
[YPERR_NODOM] = NSS_STATUS_UNAVAIL,
|
||||
[YPERR_BADDB] = NSS_STATUS_UNAVAIL,
|
||||
[YPERR_VERS] = NSS_STATUS_UNAVAIL,
|
||||
[YPERR_ACCESS] = NSS_STATUS_UNAVAIL,
|
||||
[YPERR_BUSY] = NSS_STATUS_TRYAGAIN
|
||||
};
|
||||
#define YPERR_COUNT (sizeof (yperr2nss_tab) / sizeof (yperr2nss_tab[0]))
|
||||
|
||||
static inline enum nss_status
|
||||
yperr2nss (int errval)
|
||||
{
|
||||
if ((unsigned int) errval > YPERR_COUNT)
|
||||
return NSS_STATUS_UNAVAIL;
|
||||
return yperr2nss_tab[errval];
|
||||
}
|
||||
|
||||
#endif /* nis/nss-nis.h */
|
||||
@@ -0,0 +1,769 @@
|
||||
/* Copyright (C) 1996, 1997, 1998 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
Contributed by Thorsten Kukuk <kukuk@vt.uni-paderborn.de>, 1996.
|
||||
|
||||
The GNU C Library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Library General Public License as
|
||||
published by the Free Software Foundation; either version 2 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
|
||||
Library General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Library General Public
|
||||
License along with the GNU C Library; see the file COPYING.LIB. If not,
|
||||
write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
Boston, MA 02111-1307, USA. */
|
||||
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <nss.h>
|
||||
#include <glibc-compat/include/grp.h>
|
||||
#include <ctype.h>
|
||||
#include <bits/libc-lock.h>
|
||||
#include <string.h>
|
||||
#include <rpcsvc/yp.h>
|
||||
#include <rpcsvc/ypclnt.h>
|
||||
#include <nsswitch.h>
|
||||
|
||||
/* Get the declaration of the parser function. */
|
||||
#define ENTNAME grent
|
||||
#define STRUCTURE group
|
||||
#define EXTERN_PARSER
|
||||
#include "../nss_files/files-parse.c"
|
||||
|
||||
/* Structure for remembering -group members ... */
|
||||
#define BLACKLIST_INITIAL_SIZE 512
|
||||
#define BLACKLIST_INCREMENT 256
|
||||
struct blacklist_t
|
||||
{
|
||||
char *data;
|
||||
int current;
|
||||
int size;
|
||||
};
|
||||
|
||||
struct ent_t
|
||||
{
|
||||
bool_t nis;
|
||||
bool_t nis_first;
|
||||
char *oldkey;
|
||||
int oldkeylen;
|
||||
FILE *stream;
|
||||
struct blacklist_t blacklist;
|
||||
};
|
||||
typedef struct ent_t ent_t;
|
||||
|
||||
static ent_t ext_ent = {0, 0, NULL, 0, NULL, {NULL, 0, 0}};
|
||||
|
||||
/* Protect global state against multiple changers. */
|
||||
__libc_lock_define_initialized (static, lock)
|
||||
|
||||
/* Prototypes for local functions. */
|
||||
static void blacklist_store_name (const char *, ent_t *);
|
||||
static int in_blacklist (const char *, int, ent_t *);
|
||||
|
||||
static enum nss_status
|
||||
internal_setgrent (ent_t *ent)
|
||||
{
|
||||
enum nss_status status = NSS_STATUS_SUCCESS;
|
||||
|
||||
ent->nis = ent->nis_first = 0;
|
||||
|
||||
if (ent->oldkey != NULL)
|
||||
{
|
||||
free (ent->oldkey);
|
||||
ent->oldkey = NULL;
|
||||
ent->oldkeylen = 0;
|
||||
}
|
||||
|
||||
if (ent->blacklist.data != NULL)
|
||||
{
|
||||
ent->blacklist.current = 1;
|
||||
ent->blacklist.data[0] = '|';
|
||||
ent->blacklist.data[1] = '\0';
|
||||
}
|
||||
else
|
||||
ent->blacklist.current = 0;
|
||||
|
||||
if (ent->stream == NULL)
|
||||
{
|
||||
ent->stream = fopen ("/etc/group", "r");
|
||||
|
||||
if (ent->stream == NULL)
|
||||
status = errno == EAGAIN ? NSS_STATUS_TRYAGAIN : NSS_STATUS_UNAVAIL;
|
||||
else
|
||||
{
|
||||
/* We have to make sure the file is `closed on exec'. */
|
||||
int result, flags;
|
||||
|
||||
result = flags = fcntl (fileno (ent->stream), F_GETFD, 0);
|
||||
if (result >= 0)
|
||||
{
|
||||
flags |= FD_CLOEXEC;
|
||||
result = fcntl (fileno (ent->stream), F_SETFD, flags);
|
||||
}
|
||||
if (result < 0)
|
||||
{
|
||||
/* Something went wrong. Close the stream and return a
|
||||
failure. */
|
||||
fclose (ent->stream);
|
||||
ent->stream = NULL;
|
||||
status = NSS_STATUS_UNAVAIL;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
rewind (ent->stream);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
|
||||
enum nss_status
|
||||
_nss_compat_setgrent (void)
|
||||
{
|
||||
enum nss_status result;
|
||||
|
||||
__libc_lock_lock (lock);
|
||||
|
||||
result = internal_setgrent (&ext_ent);
|
||||
|
||||
__libc_lock_unlock (lock);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
static enum nss_status
|
||||
internal_endgrent (ent_t *ent)
|
||||
{
|
||||
if (ent->stream != NULL)
|
||||
{
|
||||
fclose (ent->stream);
|
||||
ent->stream = NULL;
|
||||
}
|
||||
|
||||
ent->nis = ent->nis_first = 0;
|
||||
|
||||
if (ent->oldkey != NULL)
|
||||
{
|
||||
free (ent->oldkey);
|
||||
ent->oldkey = NULL;
|
||||
ent->oldkeylen = 0;
|
||||
}
|
||||
|
||||
if (ent->blacklist.data != NULL)
|
||||
{
|
||||
ent->blacklist.current = 1;
|
||||
ent->blacklist.data[0] = '|';
|
||||
ent->blacklist.data[1] = '\0';
|
||||
}
|
||||
else
|
||||
ent->blacklist.current = 0;
|
||||
|
||||
return NSS_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
enum nss_status
|
||||
_nss_compat_endgrent (void)
|
||||
{
|
||||
enum nss_status result;
|
||||
|
||||
__libc_lock_lock (lock);
|
||||
|
||||
result = internal_endgrent (&ext_ent);
|
||||
|
||||
__libc_lock_unlock (lock);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static enum nss_status
|
||||
getgrent_next_nis (struct group *result, ent_t *ent, char *buffer,
|
||||
size_t buflen)
|
||||
{
|
||||
struct parser_data *data = (void *) buffer;
|
||||
char *domain;
|
||||
char *outkey, *outval;
|
||||
int outkeylen, outvallen, parse_res;
|
||||
char *p;
|
||||
|
||||
if (yp_get_default_domain (&domain) != YPERR_SUCCESS)
|
||||
{
|
||||
ent->nis = 0;
|
||||
return NSS_STATUS_NOTFOUND;
|
||||
}
|
||||
|
||||
do
|
||||
{
|
||||
char *save_oldkey;
|
||||
int save_oldlen;
|
||||
bool_t save_nis_first;
|
||||
|
||||
if (ent->nis_first)
|
||||
{
|
||||
if (yp_first (domain, "group.byname", &outkey, &outkeylen,
|
||||
&outval, &outvallen) != YPERR_SUCCESS)
|
||||
{
|
||||
ent->nis = 0;
|
||||
return NSS_STATUS_UNAVAIL;
|
||||
}
|
||||
save_oldkey = ent->oldkey;
|
||||
save_oldlen = ent->oldkeylen;
|
||||
save_nis_first = TRUE;
|
||||
ent->oldkey = outkey;
|
||||
ent->oldkeylen = outkeylen;
|
||||
ent->nis_first = FALSE;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (yp_next (domain, "group.byname", ent->oldkey, ent->oldkeylen,
|
||||
&outkey, &outkeylen, &outval, &outvallen)
|
||||
!= YPERR_SUCCESS)
|
||||
{
|
||||
ent->nis = 0;
|
||||
return NSS_STATUS_NOTFOUND;
|
||||
}
|
||||
|
||||
save_oldkey = ent->oldkey;
|
||||
save_oldlen = ent->oldkeylen;
|
||||
save_nis_first = FALSE;
|
||||
ent->oldkey = outkey;
|
||||
ent->oldkeylen = outkeylen;
|
||||
}
|
||||
|
||||
/* Copy the found data to our buffer */
|
||||
p = strncpy (buffer, outval, buflen);
|
||||
|
||||
/* ...and free the data. */
|
||||
free (outval);
|
||||
|
||||
while (isspace (*p))
|
||||
++p;
|
||||
|
||||
if ((parse_res = _nss_files_parse_grent (p, result, data, buflen)) == -1)
|
||||
{
|
||||
free (ent->oldkey);
|
||||
ent->oldkey = save_oldkey;
|
||||
ent->oldkeylen = save_oldlen;
|
||||
ent->nis_first = save_nis_first;
|
||||
__set_errno (ERANGE);
|
||||
return NSS_STATUS_TRYAGAIN;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!save_nis_first)
|
||||
free (save_oldkey);
|
||||
}
|
||||
|
||||
if (parse_res &&
|
||||
in_blacklist (result->gr_name, strlen (result->gr_name), ent))
|
||||
parse_res = 0; /* if result->gr_name in blacklist,search next entry */
|
||||
}
|
||||
while (!parse_res);
|
||||
|
||||
return NSS_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
/* This function handle the +group entrys in /etc/group */
|
||||
static enum nss_status
|
||||
getgrnam_plusgroup (const char *name, struct group *result, char *buffer,
|
||||
size_t buflen)
|
||||
{
|
||||
struct parser_data *data = (void *) buffer;
|
||||
int parse_res;
|
||||
char *domain, *outval, *p;
|
||||
int outvallen;
|
||||
|
||||
if (yp_get_default_domain (&domain) != YPERR_SUCCESS)
|
||||
return NSS_STATUS_NOTFOUND;
|
||||
|
||||
if (yp_match (domain, "group.byname", name, strlen (name),
|
||||
&outval, &outvallen) != YPERR_SUCCESS)
|
||||
return NSS_STATUS_NOTFOUND;
|
||||
p = strncpy (buffer, outval,
|
||||
buflen < (size_t) outvallen ? buflen : (size_t) outvallen);
|
||||
free (outval);
|
||||
while (isspace (*p))
|
||||
p++;
|
||||
if ((parse_res = _nss_files_parse_grent (p, result, data, buflen)) == -1)
|
||||
{
|
||||
__set_errno (ERANGE);
|
||||
return NSS_STATUS_TRYAGAIN;
|
||||
}
|
||||
|
||||
if (parse_res)
|
||||
/* We found the entry. */
|
||||
return NSS_STATUS_SUCCESS;
|
||||
else
|
||||
return NSS_STATUS_RETURN;
|
||||
}
|
||||
|
||||
static enum nss_status
|
||||
getgrent_next_file (struct group *result, ent_t *ent,
|
||||
char *buffer, size_t buflen)
|
||||
{
|
||||
struct parser_data *data = (void *) buffer;
|
||||
while (1)
|
||||
{
|
||||
fpos_t pos;
|
||||
int parse_res = 0;
|
||||
char *p;
|
||||
|
||||
do
|
||||
{
|
||||
fgetpos (ent->stream, &pos);
|
||||
buffer[buflen - 1] = '\xff';
|
||||
p = fgets (buffer, buflen, ent->stream);
|
||||
if (p == NULL && feof (ent->stream))
|
||||
return NSS_STATUS_NOTFOUND;
|
||||
if (p == NULL || buffer[buflen - 1] != '\xff')
|
||||
{
|
||||
fsetpos (ent->stream, &pos);
|
||||
__set_errno (ERANGE);
|
||||
return NSS_STATUS_TRYAGAIN;
|
||||
}
|
||||
|
||||
/* Terminate the line for any case. */
|
||||
buffer[buflen - 1] = '\0';
|
||||
|
||||
/* Skip leading blanks. */
|
||||
while (isspace (*p))
|
||||
++p;
|
||||
}
|
||||
while (*p == '\0' || *p == '#' || /* Ignore empty and comment lines. */
|
||||
/* Parse the line. If it is invalid, loop to
|
||||
get the next line of the file to parse. */
|
||||
!(parse_res = _nss_files_parse_grent (p, result, data, buflen)));
|
||||
|
||||
if (parse_res == -1)
|
||||
{
|
||||
/* The parser ran out of space. */
|
||||
fsetpos (ent->stream, &pos);
|
||||
__set_errno (ERANGE);
|
||||
return NSS_STATUS_TRYAGAIN;
|
||||
}
|
||||
|
||||
if (result->gr_name[0] != '+' && result->gr_name[0] != '-')
|
||||
/* This is a real entry. */
|
||||
break;
|
||||
|
||||
/* -group */
|
||||
if (result->gr_name[0] == '-' && result->gr_name[1] != '\0'
|
||||
&& result->gr_name[1] != '@')
|
||||
{
|
||||
blacklist_store_name (&result->gr_name[1], ent);
|
||||
continue;
|
||||
}
|
||||
|
||||
/* +group */
|
||||
if (result->gr_name[0] == '+' && result->gr_name[1] != '\0'
|
||||
&& result->gr_name[1] != '@')
|
||||
{
|
||||
enum nss_status status;
|
||||
|
||||
/* Store the group in the blacklist for the "+" at the end of
|
||||
/etc/group */
|
||||
blacklist_store_name (&result->gr_name[1], ent);
|
||||
status = getgrnam_plusgroup (&result->gr_name[1], result, buffer,
|
||||
buflen);
|
||||
if (status == NSS_STATUS_SUCCESS) /* We found the entry. */
|
||||
break;
|
||||
else
|
||||
if (status == NSS_STATUS_RETURN /* We couldn't parse the entry */
|
||||
|| status == NSS_STATUS_NOTFOUND) /* No group in NIS */
|
||||
continue;
|
||||
else
|
||||
{
|
||||
if (status == NSS_STATUS_TRYAGAIN)
|
||||
/* The parser ran out of space. */
|
||||
fsetpos (ent->stream, &pos);
|
||||
return status;
|
||||
}
|
||||
}
|
||||
|
||||
/* +:... */
|
||||
if (result->gr_name[0] == '+' && result->gr_name[1] == '\0')
|
||||
{
|
||||
ent->nis = TRUE;
|
||||
ent->nis_first = TRUE;
|
||||
|
||||
return getgrent_next_nis (result, ent, buffer, buflen);
|
||||
}
|
||||
}
|
||||
|
||||
return NSS_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
static enum nss_status
|
||||
internal_getgrent_r (struct group *gr, ent_t *ent, char *buffer,
|
||||
size_t buflen)
|
||||
{
|
||||
if (ent->nis)
|
||||
{
|
||||
return getgrent_next_nis (gr, ent, buffer, buflen);
|
||||
}
|
||||
else
|
||||
return getgrent_next_file (gr, ent, buffer, buflen);
|
||||
}
|
||||
|
||||
enum nss_status
|
||||
_nss_compat_getgrent_r (struct group *grp, char *buffer, size_t buflen)
|
||||
{
|
||||
enum nss_status status = NSS_STATUS_SUCCESS;
|
||||
|
||||
__libc_lock_lock (lock);
|
||||
|
||||
/* Be prepared that the setgrent function was not called before. */
|
||||
if (ext_ent.stream == NULL)
|
||||
status = internal_setgrent (&ext_ent);
|
||||
|
||||
if (status == NSS_STATUS_SUCCESS)
|
||||
status = internal_getgrent_r (grp, &ext_ent, buffer, buflen);
|
||||
|
||||
__libc_lock_unlock (lock);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
/* Searches in /etc/group and the NIS/NIS+ map for a special group */
|
||||
static enum nss_status
|
||||
internal_getgrnam_r (const char *name, struct group *result, ent_t *ent,
|
||||
char *buffer, size_t buflen)
|
||||
{
|
||||
struct parser_data *data = (void *) buffer;
|
||||
while (1)
|
||||
{
|
||||
fpos_t pos;
|
||||
int parse_res = 0;
|
||||
char *p;
|
||||
|
||||
do
|
||||
{
|
||||
fgetpos (ent->stream, &pos);
|
||||
buffer[buflen - 1] = '\xff';
|
||||
p = fgets (buffer, buflen, ent->stream);
|
||||
if (p == NULL && feof (ent->stream))
|
||||
return NSS_STATUS_NOTFOUND;
|
||||
if (p == NULL || buffer[buflen - 1] != '\xff')
|
||||
{
|
||||
fsetpos (ent->stream, &pos);
|
||||
__set_errno (ERANGE);
|
||||
return NSS_STATUS_TRYAGAIN;
|
||||
}
|
||||
|
||||
/* Terminate the line for any case. */
|
||||
buffer[buflen - 1] = '\0';
|
||||
|
||||
/* Skip leading blanks. */
|
||||
while (isspace (*p))
|
||||
++p;
|
||||
}
|
||||
while (*p == '\0' || *p == '#' || /* Ignore empty and comment lines. */
|
||||
/* Parse the line. If it is invalid, loop to
|
||||
get the next line of the file to parse. */
|
||||
!(parse_res = _nss_files_parse_grent (p, result, data, buflen)));
|
||||
|
||||
if (parse_res == -1)
|
||||
{
|
||||
/* The parser ran out of space. */
|
||||
fsetpos (ent->stream, &pos);
|
||||
__set_errno (ERANGE);
|
||||
return NSS_STATUS_TRYAGAIN;
|
||||
}
|
||||
|
||||
/* This is a real entry. */
|
||||
if (result->gr_name[0] != '+' && result->gr_name[0] != '-')
|
||||
{
|
||||
if (strcmp (result->gr_name, name) == 0)
|
||||
return NSS_STATUS_SUCCESS;
|
||||
else
|
||||
continue;
|
||||
}
|
||||
|
||||
/* -group */
|
||||
if (result->gr_name[0] == '-' && result->gr_name[1] != '\0')
|
||||
{
|
||||
if (strcmp (&result->gr_name[1], name) == 0)
|
||||
return NSS_STATUS_NOTFOUND;
|
||||
else
|
||||
continue;
|
||||
}
|
||||
|
||||
/* +group */
|
||||
if (result->gr_name[0] == '+' && result->gr_name[1] != '\0')
|
||||
{
|
||||
if (strcmp (name, &result->gr_name[1]) == 0)
|
||||
{
|
||||
enum nss_status status;
|
||||
|
||||
status = getgrnam_plusgroup (name, result, buffer, buflen);
|
||||
if (status == NSS_STATUS_RETURN)
|
||||
/* We couldn't parse the entry */
|
||||
continue;
|
||||
else
|
||||
return status;
|
||||
}
|
||||
}
|
||||
/* +:... */
|
||||
if (result->gr_name[0] == '+' && result->gr_name[1] == '\0')
|
||||
{
|
||||
enum nss_status status;
|
||||
|
||||
status = getgrnam_plusgroup (name, result, buffer, buflen);
|
||||
if (status == NSS_STATUS_RETURN)
|
||||
/* We couldn't parse the entry */
|
||||
continue;
|
||||
else
|
||||
return status;
|
||||
}
|
||||
}
|
||||
|
||||
return NSS_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
enum nss_status
|
||||
_nss_compat_getgrnam_r (const char *name, struct group *grp,
|
||||
char *buffer, size_t buflen)
|
||||
{
|
||||
ent_t ent = {0, 0, NULL, 0, NULL, {NULL, 0, 0}};
|
||||
enum nss_status status;
|
||||
|
||||
if (name[0] == '-' || name[0] == '+')
|
||||
return NSS_STATUS_NOTFOUND;
|
||||
|
||||
__libc_lock_lock (lock);
|
||||
|
||||
status = internal_setgrent (&ent);
|
||||
|
||||
__libc_lock_unlock (lock);
|
||||
|
||||
if (status != NSS_STATUS_SUCCESS)
|
||||
return status;
|
||||
|
||||
status = internal_getgrnam_r (name, grp, &ent, buffer, buflen);
|
||||
|
||||
internal_endgrent (&ent);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
/* This function handle the + entry in /etc/group */
|
||||
static enum nss_status
|
||||
getgrgid_plusgroup (gid_t gid, struct group *result, char *buffer,
|
||||
size_t buflen)
|
||||
{
|
||||
struct parser_data *data = (void *) buffer;
|
||||
int parse_res;
|
||||
char buf[1024];
|
||||
char *domain, *outval, *p;
|
||||
int outvallen;
|
||||
|
||||
if (yp_get_default_domain (&domain) != YPERR_SUCCESS)
|
||||
return NSS_STATUS_TRYAGAIN;
|
||||
|
||||
snprintf (buf, sizeof (buf), "%d", gid);
|
||||
|
||||
if (yp_match (domain, "group.bygid", buf, strlen (buf),
|
||||
&outval, &outvallen) != YPERR_SUCCESS)
|
||||
return NSS_STATUS_TRYAGAIN;
|
||||
p = strncpy (buffer, outval,
|
||||
buflen < (size_t) outvallen ? buflen : (size_t) outvallen);
|
||||
free (outval);
|
||||
while (isspace (*p))
|
||||
p++;
|
||||
if ((parse_res = _nss_files_parse_grent (p, result, data, buflen)) == -1)
|
||||
{
|
||||
__set_errno (ERANGE);
|
||||
return NSS_STATUS_TRYAGAIN;
|
||||
}
|
||||
|
||||
if (parse_res)
|
||||
/* We found the entry. */
|
||||
return NSS_STATUS_SUCCESS;
|
||||
else
|
||||
return NSS_STATUS_RETURN;
|
||||
}
|
||||
|
||||
/* Searches in /etc/group and the NIS/NIS+ map for a special group id */
|
||||
static enum nss_status
|
||||
internal_getgrgid_r (gid_t gid, struct group *result, ent_t *ent,
|
||||
char *buffer, size_t buflen)
|
||||
{
|
||||
struct parser_data *data = (void *) buffer;
|
||||
while (1)
|
||||
{
|
||||
fpos_t pos;
|
||||
int parse_res = 0;
|
||||
char *p;
|
||||
|
||||
do
|
||||
{
|
||||
fgetpos (ent->stream, &pos);
|
||||
buffer[buflen - 1] = '\xff';
|
||||
p = fgets (buffer, buflen, ent->stream);
|
||||
if (p == NULL && feof (ent->stream))
|
||||
return NSS_STATUS_NOTFOUND;
|
||||
if (p == NULL || buffer[buflen - 1] != '\xff')
|
||||
{
|
||||
fsetpos (ent->stream, &pos);
|
||||
__set_errno (ERANGE);
|
||||
return NSS_STATUS_TRYAGAIN;
|
||||
}
|
||||
|
||||
/* Terminate the line for any case. */
|
||||
buffer[buflen - 1] = '\0';
|
||||
|
||||
/* Skip leading blanks. */
|
||||
while (isspace (*p))
|
||||
++p;
|
||||
}
|
||||
while (*p == '\0' || *p == '#' || /* Ignore empty and comment lines. */
|
||||
/* Parse the line. If it is invalid, loop to
|
||||
get the next line of the file to parse. */
|
||||
!(parse_res = _nss_files_parse_grent (p, result, data, buflen)));
|
||||
|
||||
if (parse_res == -1)
|
||||
{
|
||||
/* The parser ran out of space. */
|
||||
fsetpos (ent->stream, &pos);
|
||||
__set_errno (ERANGE);
|
||||
return NSS_STATUS_TRYAGAIN;
|
||||
}
|
||||
|
||||
/* This is a real entry. */
|
||||
if (result->gr_name[0] != '+' && result->gr_name[0] != '-')
|
||||
{
|
||||
if (result->gr_gid == gid)
|
||||
return NSS_STATUS_SUCCESS;
|
||||
else
|
||||
continue;
|
||||
}
|
||||
|
||||
/* -group */
|
||||
if (result->gr_name[0] == '-' && result->gr_name[1] != '\0')
|
||||
{
|
||||
blacklist_store_name (&result->gr_name[1], ent);
|
||||
continue;
|
||||
}
|
||||
|
||||
/* +group */
|
||||
if (result->gr_name[0] == '+' && result->gr_name[1] != '\0')
|
||||
{
|
||||
enum nss_status status;
|
||||
|
||||
/* Store the group in the blacklist for the "+" at the end of
|
||||
/etc/group */
|
||||
blacklist_store_name (&result->gr_name[1], ent);
|
||||
status = getgrnam_plusgroup (&result->gr_name[1], result, buffer,
|
||||
buflen);
|
||||
if (status == NSS_STATUS_SUCCESS && result->gr_gid == gid)
|
||||
break;
|
||||
else
|
||||
continue;
|
||||
}
|
||||
/* +:... */
|
||||
if (result->gr_name[0] == '+' && result->gr_name[1] == '\0')
|
||||
{
|
||||
enum nss_status status;
|
||||
|
||||
status = getgrgid_plusgroup (gid, result, buffer, buflen);
|
||||
if (status == NSS_STATUS_RETURN) /* We couldn't parse the entry */
|
||||
return NSS_STATUS_NOTFOUND;
|
||||
else
|
||||
return status;
|
||||
}
|
||||
}
|
||||
|
||||
return NSS_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
enum nss_status
|
||||
_nss_compat_getgrgid_r (gid_t gid, struct group *grp,
|
||||
char *buffer, size_t buflen)
|
||||
{
|
||||
ent_t ent = {0, 0, NULL, 0, NULL, {NULL, 0, 0}};
|
||||
enum nss_status status;
|
||||
|
||||
__libc_lock_lock (lock);
|
||||
|
||||
status = internal_setgrent (&ent);
|
||||
|
||||
__libc_lock_unlock (lock);
|
||||
|
||||
if (status != NSS_STATUS_SUCCESS)
|
||||
return status;
|
||||
|
||||
status = internal_getgrgid_r (gid, grp, &ent, buffer, buflen);
|
||||
|
||||
internal_endgrent (&ent);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
|
||||
/* Support routines for remembering -@netgroup and -user entries.
|
||||
The names are stored in a single string with `|' as separator. */
|
||||
static void
|
||||
blacklist_store_name (const char *name, ent_t *ent)
|
||||
{
|
||||
int namelen = strlen (name);
|
||||
char *tmp;
|
||||
|
||||
/* first call, setup cache */
|
||||
if (ent->blacklist.size == 0)
|
||||
{
|
||||
ent->blacklist.size = MAX (BLACKLIST_INITIAL_SIZE, 2 * namelen);
|
||||
ent->blacklist.data = malloc (ent->blacklist.size);
|
||||
if (ent->blacklist.data == NULL)
|
||||
return;
|
||||
ent->blacklist.data[0] = '|';
|
||||
ent->blacklist.data[1] = '\0';
|
||||
ent->blacklist.current = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (in_blacklist (name, namelen, ent))
|
||||
return; /* no duplicates */
|
||||
|
||||
if (ent->blacklist.current + namelen + 1 >= ent->blacklist.size)
|
||||
{
|
||||
ent->blacklist.size += MAX (BLACKLIST_INCREMENT, 2 * namelen);
|
||||
tmp = realloc (ent->blacklist.data, ent->blacklist.size);
|
||||
if (tmp == NULL)
|
||||
{
|
||||
free (ent->blacklist.data);
|
||||
ent->blacklist.size = 0;
|
||||
return;
|
||||
}
|
||||
ent->blacklist.data = tmp;
|
||||
}
|
||||
}
|
||||
|
||||
tmp = stpcpy (ent->blacklist.data + ent->blacklist.current, name);
|
||||
*tmp++ = '|';
|
||||
*tmp = '\0';
|
||||
ent->blacklist.current += namelen + 1;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/* returns TRUE if ent->blacklist contains name, else FALSE */
|
||||
static bool_t
|
||||
in_blacklist (const char *name, int namelen, ent_t *ent)
|
||||
{
|
||||
char buf[namelen + 3];
|
||||
char *cp;
|
||||
|
||||
if (ent->blacklist.data == NULL)
|
||||
return FALSE;
|
||||
|
||||
buf[0] = '|';
|
||||
cp = stpcpy (&buf[1], name);
|
||||
*cp++= '|';
|
||||
*cp = '\0';
|
||||
return strstr (ent->blacklist.data, buf) != NULL;
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,915 @@
|
||||
/* Copyright (C) 1996, 1997, 1998 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
Contributed by Thorsten Kukuk <kukuk@vt.uni-paderborn.de>, 1996.
|
||||
|
||||
The GNU C Library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Library General Public License as
|
||||
published by the Free Software Foundation; either version 2 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
|
||||
Library General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Library General Public
|
||||
License along with the GNU C Library; see the file COPYING.LIB. If not,
|
||||
write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
Boston, MA 02111-1307, USA. */
|
||||
|
||||
#include <nss.h>
|
||||
#include <errno.h>
|
||||
#include <ctype.h>
|
||||
#include <fcntl.h>
|
||||
#include <glibc-compat/include/netdb.h>
|
||||
#include <glibc-compat/include/shadow.h>
|
||||
#include <string.h>
|
||||
#include <bits/libc-lock.h>
|
||||
#include <rpcsvc/yp.h>
|
||||
#include <rpcsvc/ypclnt.h>
|
||||
#include <nsswitch.h>
|
||||
|
||||
#include "netgroup.h"
|
||||
|
||||
/* Get the declaration of the parser function. */
|
||||
#define ENTNAME spent
|
||||
#define STRUCTURE spwd
|
||||
#define EXTERN_PARSER
|
||||
#include "../nss_files/files-parse.c"
|
||||
|
||||
/* Structure for remembering -@netgroup and -user members ... */
|
||||
#define BLACKLIST_INITIAL_SIZE 512
|
||||
#define BLACKLIST_INCREMENT 256
|
||||
struct blacklist_t
|
||||
{
|
||||
char *data;
|
||||
int current;
|
||||
int size;
|
||||
};
|
||||
|
||||
struct ent_t
|
||||
{
|
||||
bool_t netgroup;
|
||||
bool_t nis;
|
||||
bool_t first;
|
||||
char *oldkey;
|
||||
int oldkeylen;
|
||||
FILE *stream;
|
||||
struct blacklist_t blacklist;
|
||||
struct spwd pwd;
|
||||
struct __netgrent netgrdata;
|
||||
};
|
||||
typedef struct ent_t ent_t;
|
||||
|
||||
static ent_t ext_ent = {0, 0, 0, NULL, 0, NULL, {NULL, 0, 0},
|
||||
{NULL, NULL, 0, 0, 0, 0, 0, 0, 0}};
|
||||
|
||||
/* Protect global state against multiple changers. */
|
||||
__libc_lock_define_initialized (static, lock)
|
||||
|
||||
/* Prototypes for local functions. */
|
||||
static void blacklist_store_name (const char *, ent_t *);
|
||||
static int in_blacklist (const char *, int, ent_t *);
|
||||
|
||||
static void
|
||||
give_spwd_free (struct spwd *pwd)
|
||||
{
|
||||
if (pwd->sp_namp != NULL)
|
||||
free (pwd->sp_namp);
|
||||
if (pwd->sp_pwdp != NULL)
|
||||
free (pwd->sp_pwdp);
|
||||
|
||||
memset (pwd, '\0', sizeof (struct spwd));
|
||||
}
|
||||
|
||||
static int
|
||||
spwd_need_buflen (struct spwd *pwd)
|
||||
{
|
||||
int len = 0;
|
||||
|
||||
if (pwd->sp_pwdp != NULL)
|
||||
len += strlen (pwd->sp_pwdp) + 1;
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
static void
|
||||
copy_spwd_changes (struct spwd *dest, struct spwd *src,
|
||||
char *buffer, size_t buflen)
|
||||
{
|
||||
if (src->sp_pwdp != NULL && strlen (src->sp_pwdp))
|
||||
{
|
||||
if (buffer == NULL)
|
||||
dest->sp_pwdp = strdup (src->sp_pwdp);
|
||||
else if (dest->sp_pwdp &&
|
||||
strlen (dest->sp_pwdp) >= strlen (src->sp_pwdp))
|
||||
strcpy (dest->sp_pwdp, src->sp_pwdp);
|
||||
else
|
||||
{
|
||||
dest->sp_pwdp = buffer;
|
||||
strcpy (dest->sp_pwdp, src->sp_pwdp);
|
||||
buffer += strlen (dest->sp_pwdp) + 1;
|
||||
buflen = buflen - (strlen (dest->sp_pwdp) + 1);
|
||||
}
|
||||
}
|
||||
if (src->sp_lstchg != 0)
|
||||
dest->sp_lstchg = src->sp_lstchg;
|
||||
if (src->sp_min != 0)
|
||||
dest->sp_min = src->sp_min;
|
||||
if (src->sp_max != 0)
|
||||
dest->sp_max = src->sp_max;
|
||||
if (src->sp_warn != 0)
|
||||
dest->sp_warn = src->sp_warn;
|
||||
if (src->sp_inact != 0)
|
||||
dest->sp_inact = src->sp_inact;
|
||||
if (src->sp_expire != 0)
|
||||
dest->sp_expire = src->sp_expire;
|
||||
if (src->sp_flag != 0)
|
||||
dest->sp_flag = src->sp_flag;
|
||||
}
|
||||
|
||||
static enum nss_status
|
||||
internal_setspent (ent_t *ent)
|
||||
{
|
||||
enum nss_status status = NSS_STATUS_SUCCESS;
|
||||
|
||||
ent->nis = ent->first = ent->netgroup = 0;
|
||||
|
||||
/* If something was left over free it. */
|
||||
if (ent->netgroup)
|
||||
__internal_endnetgrent (&ent->netgrdata);
|
||||
|
||||
if (ent->oldkey != NULL)
|
||||
{
|
||||
free (ent->oldkey);
|
||||
ent->oldkey = NULL;
|
||||
ent->oldkeylen = 0;
|
||||
}
|
||||
|
||||
if (ent->blacklist.data != NULL)
|
||||
{
|
||||
ent->blacklist.current = 1;
|
||||
ent->blacklist.data[0] = '|';
|
||||
ent->blacklist.data[1] = '\0';
|
||||
}
|
||||
else
|
||||
ent->blacklist.current = 0;
|
||||
|
||||
if (ent->stream == NULL)
|
||||
{
|
||||
ent->stream = fopen ("/etc/shadow", "r");
|
||||
|
||||
if (ent->stream == NULL)
|
||||
status = errno == EAGAIN ? NSS_STATUS_TRYAGAIN : NSS_STATUS_UNAVAIL;
|
||||
else
|
||||
{
|
||||
/* We have to make sure the file is `closed on exec'. */
|
||||
int result, flags;
|
||||
|
||||
result = flags = fcntl (fileno (ent->stream), F_GETFD, 0);
|
||||
if (result >= 0)
|
||||
{
|
||||
flags |= FD_CLOEXEC;
|
||||
result = fcntl (fileno (ent->stream), F_SETFD, flags);
|
||||
}
|
||||
if (result < 0)
|
||||
{
|
||||
/* Something went wrong. Close the stream and return a
|
||||
failure. */
|
||||
fclose (ent->stream);
|
||||
ent->stream = NULL;
|
||||
status = NSS_STATUS_UNAVAIL;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
rewind (ent->stream);
|
||||
|
||||
give_spwd_free (&ent->pwd);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
|
||||
enum nss_status
|
||||
_nss_compat_setspent (void)
|
||||
{
|
||||
enum nss_status result;
|
||||
|
||||
__libc_lock_lock (lock);
|
||||
|
||||
result = internal_setspent (&ext_ent);
|
||||
|
||||
__libc_lock_unlock (lock);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
static enum nss_status
|
||||
internal_endspent (ent_t *ent)
|
||||
{
|
||||
if (ent->stream != NULL)
|
||||
{
|
||||
fclose (ent->stream);
|
||||
ent->stream = NULL;
|
||||
}
|
||||
|
||||
if (ent->netgroup)
|
||||
__internal_endnetgrent (&ent->netgrdata);
|
||||
|
||||
ent->nis = ent->first = ent->netgroup = 0;
|
||||
|
||||
if (ent->oldkey != NULL)
|
||||
{
|
||||
free (ent->oldkey);
|
||||
ent->oldkey = NULL;
|
||||
ent->oldkeylen = 0;
|
||||
}
|
||||
|
||||
if (ent->blacklist.data != NULL)
|
||||
{
|
||||
ent->blacklist.current = 1;
|
||||
ent->blacklist.data[0] = '|';
|
||||
ent->blacklist.data[1] = '\0';
|
||||
}
|
||||
else
|
||||
ent->blacklist.current = 0;
|
||||
|
||||
give_spwd_free (&ent->pwd);
|
||||
|
||||
return NSS_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
enum nss_status
|
||||
_nss_compat_endspent (void)
|
||||
{
|
||||
enum nss_status result;
|
||||
|
||||
__libc_lock_lock (lock);
|
||||
|
||||
result = internal_endspent (&ext_ent);
|
||||
|
||||
__libc_lock_unlock (lock);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
static enum nss_status
|
||||
getspent_next_nis_netgr (const char *name, struct spwd *result, ent_t *ent,
|
||||
char *group, char *buffer, size_t buflen)
|
||||
{
|
||||
struct parser_data *data = (void *) buffer;
|
||||
char *ypdomain, *host, *user, *domain, *outval, *p, *p2;
|
||||
int status, outvallen;
|
||||
size_t p2len;
|
||||
|
||||
if (yp_get_default_domain (&ypdomain) != YPERR_SUCCESS)
|
||||
{
|
||||
ent->netgroup = 0;
|
||||
ent->first = 0;
|
||||
give_spwd_free (&ent->pwd);
|
||||
return NSS_STATUS_UNAVAIL;
|
||||
}
|
||||
|
||||
if (ent->first == TRUE)
|
||||
{
|
||||
bzero (&ent->netgrdata, sizeof (struct __netgrent));
|
||||
__internal_setnetgrent (group, &ent->netgrdata);
|
||||
ent->first = FALSE;
|
||||
}
|
||||
|
||||
while (1)
|
||||
{
|
||||
char *saved_cursor;
|
||||
int parse_res;
|
||||
|
||||
saved_cursor = ent->netgrdata.cursor;
|
||||
status = __internal_getnetgrent_r (&host, &user, &domain,
|
||||
&ent->netgrdata, buffer, buflen,
|
||||
&errno);
|
||||
if (status != 1)
|
||||
{
|
||||
__internal_endnetgrent (&ent->netgrdata);
|
||||
ent->netgroup = 0;
|
||||
give_spwd_free (&ent->pwd);
|
||||
return NSS_STATUS_RETURN;
|
||||
}
|
||||
|
||||
if (user == NULL || user[0] == '-')
|
||||
continue;
|
||||
|
||||
if (domain != NULL && strcmp (ypdomain, domain) != 0)
|
||||
continue;
|
||||
|
||||
/* If name != NULL, we are called from getpwnam */
|
||||
if (name != NULL)
|
||||
if (strcmp (user, name) != 0)
|
||||
continue;
|
||||
|
||||
if (yp_match (ypdomain, "shadow.byname", user,
|
||||
strlen (user), &outval, &outvallen)
|
||||
!= YPERR_SUCCESS)
|
||||
continue;
|
||||
|
||||
p2len = spwd_need_buflen (&ent->pwd);
|
||||
if (p2len > buflen)
|
||||
{
|
||||
__set_errno (ERANGE);
|
||||
return NSS_STATUS_TRYAGAIN;
|
||||
}
|
||||
p2 = buffer + (buflen - p2len);
|
||||
buflen -= p2len;
|
||||
p = strncpy (buffer, outval, buflen);
|
||||
while (isspace (*p))
|
||||
p++;
|
||||
free (outval);
|
||||
if ((parse_res = _nss_files_parse_spent (p, result, data, buflen)) == -1)
|
||||
{
|
||||
ent->netgrdata.cursor = saved_cursor;
|
||||
return NSS_STATUS_TRYAGAIN;
|
||||
}
|
||||
|
||||
if (parse_res)
|
||||
{
|
||||
/* Store the User in the blacklist for the "+" at the end of
|
||||
/etc/passwd */
|
||||
blacklist_store_name (result->sp_namp, ent);
|
||||
copy_spwd_changes (result, &ent->pwd, p2, p2len);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return NSS_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
static enum nss_status
|
||||
getspent_next_nis (struct spwd *result, ent_t *ent,
|
||||
char *buffer, size_t buflen)
|
||||
{
|
||||
struct parser_data *data = (void *) buffer;
|
||||
char *domain, *outkey, *outval, *p, *p2;
|
||||
int outkeylen, outvallen, parse_res;
|
||||
size_t p2len;
|
||||
|
||||
if (yp_get_default_domain (&domain) != YPERR_SUCCESS)
|
||||
{
|
||||
ent->nis = 0;
|
||||
give_spwd_free (&ent->pwd);
|
||||
return NSS_STATUS_UNAVAIL;
|
||||
}
|
||||
|
||||
p2len = spwd_need_buflen (&ent->pwd);
|
||||
if (p2len > buflen)
|
||||
{
|
||||
__set_errno (ERANGE);
|
||||
return NSS_STATUS_TRYAGAIN;
|
||||
}
|
||||
p2 = buffer + (buflen - p2len);
|
||||
buflen -= p2len;
|
||||
do
|
||||
{
|
||||
bool_t saved_first;
|
||||
char *saved_oldkey;
|
||||
int saved_oldlen;
|
||||
|
||||
if (ent->first)
|
||||
{
|
||||
if (yp_first (domain, "shadow.byname", &outkey, &outkeylen,
|
||||
&outval, &outvallen) != YPERR_SUCCESS)
|
||||
{
|
||||
ent->nis = 0;
|
||||
give_spwd_free (&ent->pwd);
|
||||
return NSS_STATUS_UNAVAIL;
|
||||
}
|
||||
saved_first = TRUE;
|
||||
saved_oldkey = ent->oldkey;
|
||||
saved_oldlen = ent->oldkeylen;
|
||||
ent->oldkey = outkey;
|
||||
ent->oldkeylen = outkeylen;
|
||||
ent->first = FALSE;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (yp_next (domain, "shadow.byname", ent->oldkey, ent->oldkeylen,
|
||||
&outkey, &outkeylen, &outval, &outvallen)
|
||||
!= YPERR_SUCCESS)
|
||||
{
|
||||
ent->nis = 0;
|
||||
give_spwd_free (&ent->pwd);
|
||||
return NSS_STATUS_NOTFOUND;
|
||||
}
|
||||
|
||||
saved_first = FALSE;
|
||||
saved_oldkey = ent->oldkey;
|
||||
saved_oldlen = ent->oldkeylen;
|
||||
ent->oldkey = outkey;
|
||||
ent->oldkeylen = outkeylen;
|
||||
}
|
||||
|
||||
/* Copy the found data to our buffer */
|
||||
p = strncpy (buffer, outval, buflen);
|
||||
|
||||
/* ...and free the data. */
|
||||
free (outval);
|
||||
|
||||
while (isspace (*p))
|
||||
++p;
|
||||
if ((parse_res = _nss_files_parse_spent (p, result, data, buflen)) == -1)
|
||||
{
|
||||
free (ent->oldkey);
|
||||
ent->oldkey = saved_oldkey;
|
||||
ent->oldkeylen = saved_oldlen;
|
||||
ent->first = saved_first;
|
||||
__set_errno (ERANGE);
|
||||
return NSS_STATUS_TRYAGAIN;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!saved_first)
|
||||
free (saved_oldkey);
|
||||
}
|
||||
if (parse_res &&
|
||||
in_blacklist (result->sp_namp, strlen (result->sp_namp), ent))
|
||||
parse_res = 0;
|
||||
}
|
||||
while (!parse_res);
|
||||
|
||||
copy_spwd_changes (result, &ent->pwd, p2, p2len);
|
||||
|
||||
return NSS_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
/* This function handle the +user entrys in /etc/shadow */
|
||||
static enum nss_status
|
||||
getspnam_plususer (const char *name, struct spwd *result, char *buffer,
|
||||
size_t buflen)
|
||||
{
|
||||
struct parser_data *data = (void *) buffer;
|
||||
struct spwd pwd;
|
||||
int parse_res;
|
||||
char *p;
|
||||
size_t plen;
|
||||
char *domain, *outval, *ptr;
|
||||
int outvallen;
|
||||
|
||||
|
||||
memset (&pwd, '\0', sizeof (struct spwd));
|
||||
|
||||
copy_spwd_changes (&pwd, result, NULL, 0);
|
||||
|
||||
plen = spwd_need_buflen (&pwd);
|
||||
if (plen > buflen)
|
||||
{
|
||||
__set_errno (ERANGE);
|
||||
return NSS_STATUS_TRYAGAIN;
|
||||
}
|
||||
p = buffer + (buflen - plen);
|
||||
buflen -= plen;
|
||||
|
||||
if (yp_get_default_domain (&domain) != YPERR_SUCCESS)
|
||||
return NSS_STATUS_NOTFOUND;
|
||||
|
||||
if (yp_match (domain, "shadow.byname", name, strlen (name),
|
||||
&outval, &outvallen) != YPERR_SUCCESS)
|
||||
return NSS_STATUS_NOTFOUND;
|
||||
ptr = strncpy (buffer, outval, buflen < (size_t) outvallen ?
|
||||
buflen : (size_t) outvallen);
|
||||
buffer[buflen < (size_t) outvallen ? buflen : (size_t) outvallen] = '\0';
|
||||
free (outval);
|
||||
while (isspace (*ptr))
|
||||
ptr++;
|
||||
if ((parse_res = _nss_files_parse_spent (ptr, result, data, buflen)) == -1)
|
||||
{
|
||||
__set_errno (ERANGE);
|
||||
return NSS_STATUS_TRYAGAIN;
|
||||
}
|
||||
|
||||
if (parse_res)
|
||||
{
|
||||
copy_spwd_changes (result, &pwd, p, plen);
|
||||
give_spwd_free (&pwd);
|
||||
/* We found the entry. */
|
||||
return NSS_STATUS_SUCCESS;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Give buffer the old len back */
|
||||
buflen += plen;
|
||||
give_spwd_free (&pwd);
|
||||
}
|
||||
return NSS_STATUS_RETURN;
|
||||
}
|
||||
|
||||
static enum nss_status
|
||||
getspent_next_file (struct spwd *result, ent_t *ent,
|
||||
char *buffer, size_t buflen)
|
||||
{
|
||||
struct parser_data *data = (void *) buffer;
|
||||
while (1)
|
||||
{
|
||||
fpos_t pos;
|
||||
int parse_res = 0;
|
||||
char *p;
|
||||
|
||||
do
|
||||
{
|
||||
fgetpos (ent->stream, &pos);
|
||||
buffer[buflen - 1] = '\xff';
|
||||
p = fgets (buffer, buflen, ent->stream);
|
||||
if (p == NULL && feof (ent->stream))
|
||||
return NSS_STATUS_NOTFOUND;
|
||||
if (p == NULL || buffer[buflen - 1] != '\xff')
|
||||
{
|
||||
fsetpos (ent->stream, &pos);
|
||||
__set_errno (ERANGE);
|
||||
return NSS_STATUS_TRYAGAIN;
|
||||
}
|
||||
|
||||
/* Terminate the line for any case. */
|
||||
buffer[buflen - 1] = '\0';
|
||||
|
||||
/* Skip leading blanks. */
|
||||
while (isspace (*p))
|
||||
++p;
|
||||
}
|
||||
while (*p == '\0' || *p == '#' /* Ignore empty and comment lines. */
|
||||
/* Parse the line. If it is invalid, loop to
|
||||
get the next line of the file to parse. */
|
||||
|| !(parse_res = _nss_files_parse_spent (p, result, data,
|
||||
buflen)));
|
||||
|
||||
if (parse_res == -1)
|
||||
{
|
||||
/* The parser ran out of space. */
|
||||
fsetpos (ent->stream, &pos);
|
||||
__set_errno (ERANGE);
|
||||
return NSS_STATUS_TRYAGAIN;
|
||||
}
|
||||
|
||||
if (result->sp_namp[0] != '+' && result->sp_namp[0] != '-')
|
||||
/* This is a real entry. */
|
||||
break;
|
||||
|
||||
/* -@netgroup */
|
||||
if (result->sp_namp[0] == '-' && result->sp_namp[1] == '@'
|
||||
&& result->sp_namp[2] != '\0')
|
||||
{
|
||||
char buf2[1024];
|
||||
char *user, *host, *domain;
|
||||
struct __netgrent netgrdata;
|
||||
|
||||
bzero (&netgrdata, sizeof (struct __netgrent));
|
||||
__internal_setnetgrent (&result->sp_namp[2], &netgrdata);
|
||||
while (__internal_getnetgrent_r (&host, &user, &domain,
|
||||
&netgrdata, buf2, sizeof (buf2),
|
||||
&errno))
|
||||
{
|
||||
if (user != NULL && user[0] != '-')
|
||||
blacklist_store_name (user, ent);
|
||||
}
|
||||
__internal_endnetgrent (&netgrdata);
|
||||
continue;
|
||||
}
|
||||
|
||||
/* +@netgroup */
|
||||
if (result->sp_namp[0] == '+' && result->sp_namp[1] == '@'
|
||||
&& result->sp_namp[2] != '\0')
|
||||
{
|
||||
int status;
|
||||
|
||||
ent->netgroup = TRUE;
|
||||
ent->first = TRUE;
|
||||
copy_spwd_changes (&ent->pwd, result, NULL, 0);
|
||||
|
||||
status = getspent_next_nis_netgr (NULL, result, ent,
|
||||
&result->sp_namp[2],
|
||||
buffer, buflen);
|
||||
if (status == NSS_STATUS_RETURN)
|
||||
continue;
|
||||
else
|
||||
return status;
|
||||
}
|
||||
|
||||
/* -user */
|
||||
if (result->sp_namp[0] == '-' && result->sp_namp[1] != '\0'
|
||||
&& result->sp_namp[1] != '@')
|
||||
{
|
||||
blacklist_store_name (&result->sp_namp[1], ent);
|
||||
continue;
|
||||
}
|
||||
|
||||
/* +user */
|
||||
if (result->sp_namp[0] == '+' && result->sp_namp[1] != '\0'
|
||||
&& result->sp_namp[1] != '@')
|
||||
{
|
||||
enum nss_status status;
|
||||
|
||||
/* Store the User in the blacklist for the "+" at the end of
|
||||
/etc/passwd */
|
||||
blacklist_store_name (&result->sp_namp[1], ent);
|
||||
status = getspnam_plususer (&result->sp_namp[1], result, buffer,
|
||||
buflen);
|
||||
if (status == NSS_STATUS_SUCCESS) /* We found the entry. */
|
||||
break;
|
||||
else
|
||||
if (status == NSS_STATUS_RETURN /* We couldn't parse the entry */
|
||||
|| status == NSS_STATUS_NOTFOUND) /* entry doesn't exist */
|
||||
continue;
|
||||
else
|
||||
{
|
||||
if (status == NSS_STATUS_TRYAGAIN)
|
||||
fsetpos (ent->stream, &pos);
|
||||
return status;
|
||||
}
|
||||
}
|
||||
|
||||
/* +:... */
|
||||
if (result->sp_namp[0] == '+' && result->sp_namp[1] == '\0')
|
||||
{
|
||||
ent->nis = TRUE;
|
||||
ent->first = TRUE;
|
||||
copy_spwd_changes (&ent->pwd, result, NULL, 0);
|
||||
|
||||
return getspent_next_nis (result, ent, buffer, buflen);
|
||||
}
|
||||
}
|
||||
|
||||
return NSS_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
static enum nss_status
|
||||
internal_getspent_r (struct spwd *pw, ent_t *ent,
|
||||
char *buffer, size_t buflen)
|
||||
{
|
||||
if (ent->netgroup)
|
||||
{
|
||||
int status;
|
||||
|
||||
/* We are searching members in a netgroup */
|
||||
/* Since this is not the first call, we don't need the group name */
|
||||
status = getspent_next_nis_netgr (NULL, pw, ent, NULL, buffer, buflen);
|
||||
if (status == NSS_STATUS_RETURN)
|
||||
return getspent_next_file (pw, ent, buffer, buflen);
|
||||
else
|
||||
return status;
|
||||
}
|
||||
else
|
||||
if (ent->nis)
|
||||
{
|
||||
return getspent_next_nis (pw, ent, buffer, buflen);
|
||||
}
|
||||
else
|
||||
return getspent_next_file (pw, ent, buffer, buflen);
|
||||
}
|
||||
|
||||
enum nss_status
|
||||
_nss_compat_getspent_r (struct spwd *pwd, char *buffer, size_t buflen)
|
||||
{
|
||||
enum nss_status status = NSS_STATUS_SUCCESS;
|
||||
|
||||
__libc_lock_lock (lock);
|
||||
|
||||
if (ext_ent.stream == NULL)
|
||||
status = internal_setspent (&ext_ent);
|
||||
|
||||
if (status == NSS_STATUS_SUCCESS)
|
||||
status = internal_getspent_r (pwd, &ext_ent, buffer, buflen);
|
||||
|
||||
__libc_lock_unlock (lock);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
/* Searches in /etc/passwd and the NIS/NIS+ map for a special user */
|
||||
static enum nss_status
|
||||
internal_getspnam_r (const char *name, struct spwd *result, ent_t *ent,
|
||||
char *buffer, size_t buflen)
|
||||
{
|
||||
struct parser_data *data = (void *) buffer;
|
||||
|
||||
while (1)
|
||||
{
|
||||
fpos_t pos;
|
||||
char *p;
|
||||
int parse_res;
|
||||
|
||||
do
|
||||
{
|
||||
fgetpos (ent->stream, &pos);
|
||||
buffer[buflen - 1] = '\xff';
|
||||
p = fgets (buffer, buflen, ent->stream);
|
||||
if (p == NULL && feof (ent->stream))
|
||||
return NSS_STATUS_NOTFOUND;
|
||||
if (p == NULL || buffer[buflen - 1] != '\xff')
|
||||
{
|
||||
fsetpos (ent->stream, &pos);
|
||||
__set_errno (ERANGE);
|
||||
return NSS_STATUS_TRYAGAIN;
|
||||
}
|
||||
|
||||
/* Terminate the line for any case. */
|
||||
buffer[buflen - 1] = '\0';
|
||||
|
||||
/* Skip leading blanks. */
|
||||
while (isspace (*p))
|
||||
++p;
|
||||
}
|
||||
while (*p == '\0' || *p == '#' || /* Ignore empty and comment lines. */
|
||||
/* Parse the line. If it is invalid, loop to
|
||||
get the next line of the file to parse. */
|
||||
!(parse_res = _nss_files_parse_spent (p, result, data, buflen)));
|
||||
|
||||
if (parse_res == -1)
|
||||
{
|
||||
/* The parser ran out of space. */
|
||||
fsetpos (ent->stream, &pos);
|
||||
__set_errno (ERANGE);
|
||||
return NSS_STATUS_TRYAGAIN;
|
||||
}
|
||||
|
||||
/* This is a real entry. */
|
||||
if (result->sp_namp[0] != '+' && result->sp_namp[0] != '-')
|
||||
{
|
||||
if (strcmp (result->sp_namp, name) == 0)
|
||||
return NSS_STATUS_SUCCESS;
|
||||
else
|
||||
continue;
|
||||
}
|
||||
|
||||
/* -@netgroup */
|
||||
if (result->sp_namp[0] == '-' && result->sp_namp[1] == '@'
|
||||
&& result->sp_namp[2] != '\0')
|
||||
{
|
||||
char buf2[1024];
|
||||
char *user, *host, *domain;
|
||||
struct __netgrent netgrdata;
|
||||
|
||||
bzero (&netgrdata, sizeof (struct __netgrent));
|
||||
__internal_setnetgrent (&result->sp_namp[2], &netgrdata);
|
||||
while (__internal_getnetgrent_r (&host, &user, &domain,
|
||||
&netgrdata, buf2, sizeof (buf2),
|
||||
&errno))
|
||||
{
|
||||
if (user != NULL && user[0] != '-')
|
||||
if (strcmp (user, name) == 0)
|
||||
return NSS_STATUS_NOTFOUND;
|
||||
}
|
||||
__internal_endnetgrent (&netgrdata);
|
||||
continue;
|
||||
}
|
||||
|
||||
/* +@netgroup */
|
||||
if (result->sp_namp[0] == '+' && result->sp_namp[1] == '@'
|
||||
&& result->sp_namp[2] != '\0')
|
||||
{
|
||||
char buf[strlen (result->sp_namp)];
|
||||
int status;
|
||||
|
||||
strcpy (buf, &result->sp_namp[2]);
|
||||
ent->netgroup = TRUE;
|
||||
ent->first = TRUE;
|
||||
copy_spwd_changes (&ent->pwd, result, NULL, 0);
|
||||
|
||||
do
|
||||
{
|
||||
status = getspent_next_nis_netgr (name, result, ent, buf,
|
||||
buffer, buflen);
|
||||
if (status == NSS_STATUS_RETURN)
|
||||
continue;
|
||||
|
||||
if (status == NSS_STATUS_SUCCESS &&
|
||||
strcmp (result->sp_namp, name) == 0)
|
||||
return NSS_STATUS_SUCCESS;
|
||||
} while (status == NSS_STATUS_SUCCESS);
|
||||
continue;
|
||||
}
|
||||
|
||||
/* -user */
|
||||
if (result->sp_namp[0] == '-' && result->sp_namp[1] != '\0'
|
||||
&& result->sp_namp[1] != '@')
|
||||
{
|
||||
if (strcmp (&result->sp_namp[1], name) == 0)
|
||||
return NSS_STATUS_NOTFOUND;
|
||||
else
|
||||
continue;
|
||||
}
|
||||
|
||||
/* +user */
|
||||
if (result->sp_namp[0] == '+' && result->sp_namp[1] != '\0'
|
||||
&& result->sp_namp[1] != '@')
|
||||
{
|
||||
if (strcmp (name, &result->sp_namp[1]) == 0)
|
||||
{
|
||||
enum nss_status status;
|
||||
|
||||
status = getspnam_plususer (name, result, buffer, buflen);
|
||||
if (status == NSS_STATUS_RETURN)
|
||||
/* We couldn't parse the entry */
|
||||
return NSS_STATUS_NOTFOUND;
|
||||
else
|
||||
return status;
|
||||
}
|
||||
}
|
||||
|
||||
/* +:... */
|
||||
if (result->sp_namp[0] == '+' && result->sp_namp[1] == '\0')
|
||||
{
|
||||
enum nss_status status;
|
||||
|
||||
status = getspnam_plususer (name, result, buffer, buflen);
|
||||
if (status == NSS_STATUS_RETURN) /* We couldn't parse the entry */
|
||||
return NSS_STATUS_NOTFOUND;
|
||||
else
|
||||
return status;
|
||||
}
|
||||
}
|
||||
return NSS_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
enum nss_status
|
||||
_nss_compat_getspnam_r (const char *name, struct spwd *pwd,
|
||||
char *buffer, size_t buflen)
|
||||
{
|
||||
ent_t ent = {0, 0, 0, NULL, 0, NULL, {NULL, 0, 0},
|
||||
{NULL, NULL, 0, 0, 0, 0, 0, 0, 0}};
|
||||
enum nss_status status;
|
||||
|
||||
if (name[0] == '-' || name[0] == '+')
|
||||
return NSS_STATUS_NOTFOUND;
|
||||
|
||||
status = internal_setspent (&ent);
|
||||
if (status != NSS_STATUS_SUCCESS)
|
||||
return status;
|
||||
|
||||
status = internal_getspnam_r (name, pwd, &ent, buffer, buflen);
|
||||
|
||||
internal_endspent (&ent);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
/* Support routines for remembering -@netgroup and -user entries.
|
||||
The names are stored in a single string with `|' as separator. */
|
||||
static void
|
||||
blacklist_store_name (const char *name, ent_t *ent)
|
||||
{
|
||||
int namelen = strlen (name);
|
||||
char *tmp;
|
||||
|
||||
/* first call, setup cache */
|
||||
if (ent->blacklist.size == 0)
|
||||
{
|
||||
ent->blacklist.size = MAX (BLACKLIST_INITIAL_SIZE, 2 * namelen);
|
||||
ent->blacklist.data = malloc (ent->blacklist.size);
|
||||
if (ent->blacklist.data == NULL)
|
||||
return;
|
||||
ent->blacklist.data[0] = '|';
|
||||
ent->blacklist.data[1] = '\0';
|
||||
ent->blacklist.current = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (in_blacklist (name, namelen, ent))
|
||||
return; /* no duplicates */
|
||||
|
||||
if (ent->blacklist.current + namelen + 1 >= ent->blacklist.size)
|
||||
{
|
||||
ent->blacklist.size += MAX (BLACKLIST_INCREMENT, 2 * namelen);
|
||||
tmp = realloc (ent->blacklist.data, ent->blacklist.size);
|
||||
if (tmp == NULL)
|
||||
{
|
||||
free (ent->blacklist.data);
|
||||
ent->blacklist.size = 0;
|
||||
return;
|
||||
}
|
||||
ent->blacklist.data = tmp;
|
||||
}
|
||||
}
|
||||
|
||||
tmp = stpcpy (ent->blacklist.data + ent->blacklist.current, name);
|
||||
*tmp++ = '|';
|
||||
*tmp = '\0';
|
||||
ent->blacklist.current += namelen + 1;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/* Returns TRUE if ent->blacklist contains name, else FALSE. */
|
||||
static bool_t
|
||||
in_blacklist (const char *name, int namelen, ent_t *ent)
|
||||
{
|
||||
char buf[namelen + 3];
|
||||
char *cp;
|
||||
|
||||
if (ent->blacklist.data == NULL)
|
||||
return FALSE;
|
||||
|
||||
buf[0] = '|';
|
||||
cp = stpcpy (&buf[1], name);
|
||||
*cp++= '|';
|
||||
*cp = '\0';
|
||||
return strstr (ent->blacklist.data, buf) != NULL;
|
||||
}
|
||||
@@ -0,0 +1,257 @@
|
||||
/* Common code for DB-based databases in nss_db module.
|
||||
Copyright (C) 1996, 1997, 1998, 1999, 2000 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 Library General Public License as
|
||||
published by the Free Software Foundation; either version 2 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
|
||||
Library General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Library General Public
|
||||
License along with the GNU C Library; see the file COPYING.LIB. If not,
|
||||
write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
Boston, MA 02111-1307, USA. */
|
||||
|
||||
#include <dlfcn.h>
|
||||
#include <fcntl.h>
|
||||
#include <bits/libc-lock.h>
|
||||
#include "nsswitch.h"
|
||||
#include "nss_db.h"
|
||||
|
||||
/* These symbols are defined by the including source file:
|
||||
|
||||
ENTNAME -- database name of the structure and functions (hostent, pwent).
|
||||
STRUCTURE -- struct name, define only if not ENTNAME (passwd, group).
|
||||
DATABASE -- database file name, ("hosts", "passwd")
|
||||
|
||||
NEED_H_ERRNO - defined iff an arg `int *herrnop' is used.
|
||||
*/
|
||||
|
||||
#define ENTNAME_r CONCAT(ENTNAME,_r)
|
||||
|
||||
#include <paths.h>
|
||||
#define DBFILE _PATH_VARDB DATABASE ".db"
|
||||
|
||||
#ifdef NEED_H_ERRNO
|
||||
#define H_ERRNO_PROTO , int *herrnop
|
||||
#define H_ERRNO_ARG , herrnop
|
||||
#define H_ERRNO_SET(val) (*herrnop = (val))
|
||||
#else
|
||||
#define H_ERRNO_PROTO
|
||||
#define H_ERRNO_ARG
|
||||
#define H_ERRNO_SET(val) ((void) 0)
|
||||
#endif
|
||||
|
||||
/* Locks the static variables in this file. */
|
||||
__libc_lock_define_initialized (static, lock)
|
||||
|
||||
/* Maintenance of the shared handle open on the database. */
|
||||
|
||||
static NSS_DB *db;
|
||||
static int keep_db;
|
||||
static int entidx;
|
||||
|
||||
|
||||
/* Open the database. */
|
||||
enum nss_status
|
||||
CONCAT(_nss_db_set,ENTNAME) (int stayopen)
|
||||
{
|
||||
enum nss_status status;
|
||||
|
||||
__libc_lock_lock (lock);
|
||||
|
||||
status = internal_setent (DBFILE, &db);
|
||||
|
||||
/* Remember STAYOPEN flag. */
|
||||
if (db != NULL)
|
||||
keep_db |= stayopen;
|
||||
/* Reset the sequential index. */
|
||||
entidx = 0;
|
||||
|
||||
__libc_lock_unlock (lock);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
|
||||
/* Close it again. */
|
||||
enum nss_status
|
||||
CONCAT(_nss_db_end,ENTNAME) (void)
|
||||
{
|
||||
__libc_lock_lock (lock);
|
||||
|
||||
internal_endent (&db);
|
||||
|
||||
/* Reset STAYOPEN flag. */
|
||||
keep_db = 0;
|
||||
|
||||
__libc_lock_unlock (lock);
|
||||
|
||||
return NSS_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
/* Do a database lookup for KEY. */
|
||||
static enum nss_status
|
||||
lookup (DBT *key, struct STRUCTURE *result,
|
||||
void *buffer, int buflen H_ERRNO_PROTO)
|
||||
{
|
||||
char *p;
|
||||
enum nss_status status;
|
||||
int err;
|
||||
DBT value;
|
||||
|
||||
/* Open the database. */
|
||||
if (db == NULL)
|
||||
{
|
||||
status = internal_setent (DBFILE, &db);
|
||||
if (status != NSS_STATUS_SUCCESS)
|
||||
{
|
||||
H_ERRNO_SET (NETDB_INTERNAL);
|
||||
return status;
|
||||
}
|
||||
}
|
||||
|
||||
/* Succeed iff it matches a value that parses correctly. */
|
||||
value.flags = 0;
|
||||
err = DL_CALL_FCT (db->get, (db->db, NULL, key, &value, 0));
|
||||
if (err != 0)
|
||||
{
|
||||
if (err == db_notfound)
|
||||
{
|
||||
H_ERRNO_SET (HOST_NOT_FOUND);
|
||||
status = NSS_STATUS_NOTFOUND;
|
||||
}
|
||||
else
|
||||
{
|
||||
H_ERRNO_SET (NETDB_INTERNAL);
|
||||
status = NSS_STATUS_UNAVAIL;
|
||||
}
|
||||
}
|
||||
else if (buflen < value.size)
|
||||
{
|
||||
/* No room to copy the data to. */
|
||||
__set_errno (ERANGE);
|
||||
H_ERRNO_SET (NETDB_INTERNAL);
|
||||
status = NSS_STATUS_TRYAGAIN;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Copy the result to a safe place. */
|
||||
p = (char *) memcpy (buffer, value.data, value.size);
|
||||
|
||||
/* Skip leading blanks. */
|
||||
while (isspace (*p))
|
||||
++p;
|
||||
|
||||
err = parse_line (p, result, buffer, buflen);
|
||||
|
||||
if (err == 0)
|
||||
{
|
||||
/* If the key begins with '0' we are trying to get the next
|
||||
entry. We want to ignore unparsable lines in this case. */
|
||||
if (((char *) key->data)[0] == '0')
|
||||
{
|
||||
/* Super magical return value. We need to tell our caller
|
||||
that it should continue looping. This value cannot
|
||||
happen in other cases. */
|
||||
status = NSS_STATUS_RETURN;
|
||||
}
|
||||
else
|
||||
{
|
||||
H_ERRNO_SET (HOST_NOT_FOUND);
|
||||
status = NSS_STATUS_NOTFOUND;
|
||||
}
|
||||
}
|
||||
else if (err < 0)
|
||||
{
|
||||
H_ERRNO_SET (NETDB_INTERNAL);
|
||||
status = NSS_STATUS_TRYAGAIN;
|
||||
}
|
||||
else
|
||||
status = NSS_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
if (! keep_db)
|
||||
internal_endent (&db);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
|
||||
/* Macro for defining lookup functions for this DB-based database.
|
||||
|
||||
NAME is the name of the lookup; e.g. `pwnam'.
|
||||
|
||||
KEYPATTERN gives `printf' args to construct a key string;
|
||||
e.g. `(".%s", name)'.
|
||||
|
||||
KEYSIZE gives the allocation size of a buffer to construct it in;
|
||||
e.g. `1 + strlen (name)'.
|
||||
|
||||
PROTO describes the arguments for the lookup key;
|
||||
e.g. `const char *name'.
|
||||
|
||||
BREAK_IF_MATCH is ignored, but used by ../nss_files/files-XXX.c. */
|
||||
|
||||
#define DB_LOOKUP(name, keysize, keypattern, break_if_match, proto...) \
|
||||
enum nss_status \
|
||||
_nss_db_get##name##_r (proto, \
|
||||
struct STRUCTURE *result, \
|
||||
char *buffer, size_t buflen H_ERRNO_PROTO)\
|
||||
{ \
|
||||
DBT key; \
|
||||
enum nss_status status; \
|
||||
const size_t size = (keysize) + 1; \
|
||||
key.data = __alloca (size); \
|
||||
key.size = KEYPRINTF keypattern; \
|
||||
key.flags = 0; \
|
||||
__libc_lock_lock (lock); \
|
||||
status = lookup (&key, result, buffer, buflen H_ERRNO_ARG); \
|
||||
__libc_lock_unlock (lock); \
|
||||
return status; \
|
||||
}
|
||||
|
||||
#define KEYPRINTF(pattern, args...) snprintf (key.data, size, pattern ,##args)
|
||||
|
||||
|
||||
|
||||
|
||||
/* Return the next entry from the database file, doing locking. */
|
||||
enum nss_status
|
||||
CONCAT(_nss_db_get,ENTNAME_r) (struct STRUCTURE *result, char *buffer,
|
||||
size_t buflen H_ERRNO_PROTO)
|
||||
{
|
||||
/* Return next entry in host file. */
|
||||
enum nss_status status;
|
||||
char buf[20];
|
||||
DBT key;
|
||||
|
||||
__libc_lock_lock (lock);
|
||||
|
||||
/* Loop until we find a valid entry or hit EOF. See above for the
|
||||
special meaning of the status value. */
|
||||
do
|
||||
{
|
||||
key.size = snprintf (key.data = buf, sizeof buf, "0%u", entidx++);
|
||||
key.flags = 0;
|
||||
status = lookup (&key, result, buffer, buflen H_ERRNO_ARG);
|
||||
if (status == NSS_STATUS_TRYAGAIN
|
||||
#ifdef NEED_H_ERRNO
|
||||
&& *herrnop == NETDB_INTERNAL
|
||||
#endif
|
||||
&& errno == ERANGE)
|
||||
/* Give the user a chance to get the same entry with a larger
|
||||
buffer. */
|
||||
--entidx;
|
||||
}
|
||||
while (status == NSS_STATUS_RETURN);
|
||||
|
||||
__libc_lock_unlock (lock);
|
||||
|
||||
return status;
|
||||
}
|
||||
@@ -0,0 +1,208 @@
|
||||
/* Mail alias file parser in nss_db module.
|
||||
Copyright (C) 1996, 1997, 1998, 1999, 2000 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
Contributed by Ulrich Drepper <drepper@cygnus.com>, 1996.
|
||||
|
||||
The GNU C Library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Library General Public License as
|
||||
published by the Free Software Foundation; either version 2 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
|
||||
Library General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Library General Public
|
||||
License along with the GNU C Library; see the file COPYING.LIB. If not,
|
||||
write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
Boston, MA 02111-1307, USA. */
|
||||
|
||||
#include <glibc-compat/include/aliases.h>
|
||||
#include <alloca.h>
|
||||
#include <ctype.h>
|
||||
#include <dlfcn.h>
|
||||
#include <errno.h>
|
||||
#include <bits/libc-lock.h>
|
||||
#include <paths.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "nsswitch.h"
|
||||
#include "nss_db.h"
|
||||
|
||||
/* Locks the static variables in this file. */
|
||||
__libc_lock_define_initialized (static, lock)
|
||||
|
||||
/* Maintenance of the shared handle open on the database. */
|
||||
|
||||
static NSS_DB *db;
|
||||
static int keep_db;
|
||||
static unsigned int entidx; /* Index for `getaliasent_r'. */
|
||||
|
||||
|
||||
/* Open database. */
|
||||
enum nss_status
|
||||
_nss_db_setaliasent (int stayopen)
|
||||
{
|
||||
enum nss_status status;
|
||||
|
||||
__libc_lock_lock (lock);
|
||||
|
||||
status = internal_setent (_PATH_VARDB "aliases.db", &db);
|
||||
|
||||
/* Remember STAYOPEN flag. */
|
||||
if (db != NULL)
|
||||
keep_db |= stayopen;
|
||||
|
||||
/* Reset the sequential index. */
|
||||
entidx = 0;
|
||||
|
||||
__libc_lock_unlock (lock);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
|
||||
/* Close it again. */
|
||||
enum nss_status
|
||||
_nss_db_endaliasent (void)
|
||||
{
|
||||
__libc_lock_lock (lock);
|
||||
|
||||
internal_endent (&db);
|
||||
|
||||
/* Reset STAYOPEN flag. */
|
||||
keep_db = 0;
|
||||
|
||||
__libc_lock_unlock (lock);
|
||||
|
||||
return NSS_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
/* We provide the parse function here. The parser in libnss_files
|
||||
cannot be used. The generation of the db file already resolved all
|
||||
:include: statements so we simply have to parse the list and store
|
||||
the result. */
|
||||
static enum nss_status
|
||||
lookup (DBT *key, struct aliasent *result, char *buffer,
|
||||
size_t buflen)
|
||||
{
|
||||
enum nss_status status;
|
||||
DBT value;
|
||||
|
||||
/* Open the database. */
|
||||
if (db == NULL)
|
||||
{
|
||||
status = internal_setent (_PATH_VARDB "aliases.db", &db);
|
||||
if (status != NSS_STATUS_SUCCESS)
|
||||
return status;
|
||||
}
|
||||
|
||||
value.flags = 0;
|
||||
if (DL_CALL_FCT (db->get, (db->db, NULL, key, &value, 0)) == 0)
|
||||
{
|
||||
const char *src = value.data;
|
||||
char *cp;
|
||||
size_t cnt;
|
||||
|
||||
result->alias_members_len = 0;
|
||||
|
||||
/* We now have to fill the BUFFER with all the information. */
|
||||
if (buflen < key->size + 1)
|
||||
{
|
||||
no_more_room:
|
||||
__set_errno (ERANGE);
|
||||
return NSS_STATUS_TRYAGAIN;
|
||||
}
|
||||
|
||||
buffer = stpncpy (buffer, key->data, key->size) + 1;
|
||||
buflen -= key->size + 1;
|
||||
|
||||
while (*src != '\0')
|
||||
{
|
||||
const char *end, *upto;
|
||||
while (isspace (*src))
|
||||
++src;
|
||||
|
||||
end = strchr (src, ',');
|
||||
if (end == NULL)
|
||||
end = strchr (src, '\0');
|
||||
for (upto = end; upto > src && isspace (upto[-1]); --upto);
|
||||
|
||||
if (upto != src)
|
||||
{
|
||||
if ((upto - src) + __alignof__ (char *) > buflen)
|
||||
goto no_more_room;
|
||||
buffer = stpncpy (buffer, src, upto - src) + 1;
|
||||
buflen -= (upto - src) + __alignof (char *);
|
||||
++result->alias_members_len;
|
||||
}
|
||||
src = end + (*end != '\0');
|
||||
}
|
||||
|
||||
/* Now prepare the return. Provide string pointers for the
|
||||
currently selected aliases. */
|
||||
|
||||
/* Adjust the pointer so it is aligned for storing pointers. */
|
||||
buffer += __alignof__ (char *) - 1;
|
||||
buffer -= ((buffer - (char *) 0) % __alignof__ (char *));
|
||||
result->alias_members = (char **) buffer;
|
||||
|
||||
/* Compute addresses of alias entry strings. */
|
||||
cp = result->alias_name;
|
||||
for (cnt = 0; cnt < result->alias_members_len; ++cnt)
|
||||
{
|
||||
cp = strchr (cp, '\0') + 1;
|
||||
result->alias_members[cnt] = cp;
|
||||
}
|
||||
|
||||
status = (result->alias_members_len == 0
|
||||
? NSS_STATUS_RETURN : NSS_STATUS_SUCCESS);
|
||||
}
|
||||
else
|
||||
status = NSS_STATUS_NOTFOUND;
|
||||
|
||||
if (! keep_db)
|
||||
internal_endent (&db);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
enum nss_status
|
||||
_nss_db_getaliasent_r (struct aliasent *result, char *buffer, size_t buflen)
|
||||
{
|
||||
/* Return next entry in alias file. */
|
||||
enum nss_status status;
|
||||
char buf[20];
|
||||
DBT key;
|
||||
|
||||
__libc_lock_lock (lock);
|
||||
key.size = snprintf (key.data = buf, sizeof buf, "0%u", entidx++);
|
||||
key.flags = 0;
|
||||
status = lookup (&key, result, buffer, buflen);
|
||||
__libc_lock_unlock (lock);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
|
||||
enum nss_status
|
||||
_nss_db_getaliasbyname_r (const char *name, struct aliasent *result,
|
||||
char *buffer, size_t buflen)
|
||||
{
|
||||
DBT key;
|
||||
enum nss_status status;
|
||||
|
||||
key.size = 1 + strlen (name);
|
||||
|
||||
key.data = __alloca (key.size);
|
||||
((char *) key.data)[0] = '.';
|
||||
memcpy (&((char *) key.data)[1], name, key.size - 1);
|
||||
key.flags = 0;
|
||||
|
||||
__libc_lock_lock (lock);
|
||||
status = lookup (&key, result, buffer, buflen);
|
||||
__libc_lock_unlock (lock);
|
||||
|
||||
return status;
|
||||
}
|
||||
@@ -0,0 +1,101 @@
|
||||
/* Netgroup file parser in nss_db modules.
|
||||
Copyright (C) 1996, 1997, 1999, 2000 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
Contributed by Ulrich Drepper <drepper@cygnus.com>, 1996.
|
||||
|
||||
The GNU C Library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Library General Public License as
|
||||
published by the Free Software Foundation; either version 2 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
|
||||
Library General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Library General Public
|
||||
License along with the GNU C Library; see the file COPYING.LIB. If not,
|
||||
write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
Boston, MA 02111-1307, USA. */
|
||||
|
||||
#include <dlfcn.h>
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <netgroup.h>
|
||||
#include <string.h>
|
||||
#include <bits/libc-lock.h>
|
||||
#include <paths.h>
|
||||
|
||||
#include "nsswitch.h"
|
||||
#include "nss_db.h"
|
||||
|
||||
|
||||
#define DBFILE _PATH_VARDB "netgroup.db"
|
||||
|
||||
|
||||
/* Locks the static variables in this file. */
|
||||
__libc_lock_define_initialized (static, lock)
|
||||
|
||||
/* Maintenance of the shared handle open on the database. */
|
||||
static NSS_DB *db;
|
||||
static char *entry;
|
||||
static char *cursor;
|
||||
|
||||
enum nss_status
|
||||
_nss_db_setnetgrent (const char *group)
|
||||
{
|
||||
enum nss_status status;
|
||||
|
||||
__libc_lock_lock (lock);
|
||||
|
||||
status = internal_setent (DBFILE, &db);
|
||||
|
||||
if (status == NSS_STATUS_SUCCESS)
|
||||
{
|
||||
DBT key = { data: (void *) group, size: strlen (group), flags: 0 };
|
||||
DBT value;
|
||||
|
||||
value.flags = 0;
|
||||
if (DL_CALL_FCT (db->get, (db->db, NULL, &key, &value, 0)) != 0)
|
||||
status = NSS_STATUS_NOTFOUND;
|
||||
else
|
||||
cursor = entry = value.data;
|
||||
}
|
||||
|
||||
__libc_lock_unlock (lock);
|
||||
|
||||
return status;
|
||||
|
||||
}
|
||||
|
||||
|
||||
enum nss_status
|
||||
_nss_db_endnetgrent (void)
|
||||
{
|
||||
__libc_lock_lock (lock);
|
||||
|
||||
internal_endent (&db);
|
||||
|
||||
__libc_lock_unlock (lock);
|
||||
|
||||
return NSS_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
extern enum nss_status _nss_netgroup_parseline (char **cursor,
|
||||
struct __netgrent *result,
|
||||
char *buffer, int buflen);
|
||||
|
||||
enum nss_status
|
||||
_nss_db_getnetgrent_r (struct __netgrent *result, char *buffer, size_t buflen)
|
||||
{
|
||||
int status;
|
||||
|
||||
__libc_lock_lock (lock);
|
||||
|
||||
status = _nss_netgroup_parseline (&cursor, result, buffer, buflen);
|
||||
|
||||
__libc_lock_unlock (lock);
|
||||
|
||||
return status;
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
#include <nss/nss_db/db-open.c>
|
||||
@@ -0,0 +1 @@
|
||||
#include <nss/nss_db/dummy-db.h>
|
||||
@@ -0,0 +1 @@
|
||||
#include <nss/nss_db/nss_db.h>
|
||||
@@ -0,0 +1,641 @@
|
||||
/* Copyright (C) 1996, 1997, 1998 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
Extended from original form by Ulrich Drepper <drepper@cygnus.com>, 1996.
|
||||
|
||||
The GNU C Library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Library General Public License as
|
||||
published by the Free Software Foundation; either version 2 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
|
||||
Library General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Library General Public
|
||||
License along with the GNU C Library; see the file COPYING.LIB. If not,
|
||||
write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
Boston, MA 02111-1307, USA. */
|
||||
|
||||
/* Parts of this file are plain copies of the file `gethtnamadr.c' from
|
||||
the bind package and it has the following copyright. */
|
||||
|
||||
/*
|
||||
* ++Copyright++ 1985, 1988, 1993
|
||||
* -
|
||||
* Copyright (c) 1985, 1988, 1993
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by the University of
|
||||
* California, Berkeley and its contributors.
|
||||
* 4. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
* -
|
||||
* Portions Copyright (c) 1993 by Digital Equipment Corporation.
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies, and that
|
||||
* the name of Digital Equipment Corporation not be used in advertising or
|
||||
* publicity pertaining to distribution of the document or software without
|
||||
* specific, written prior permission.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND DIGITAL EQUIPMENT CORP. DISCLAIMS ALL
|
||||
* WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL DIGITAL EQUIPMENT
|
||||
* CORPORATION BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
|
||||
* DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
|
||||
* PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
|
||||
* ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
|
||||
* SOFTWARE.
|
||||
* -
|
||||
* --Copyright--
|
||||
*/
|
||||
|
||||
#include <ctype.h>
|
||||
#include <errno.h>
|
||||
#include <glibc-compat/include/netdb.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <stddef.h>
|
||||
#include <string.h>
|
||||
#include <sys/syslog.h>
|
||||
|
||||
#include "nsswitch.h"
|
||||
|
||||
/* Get implementation for some internal functions. */
|
||||
#include "../resolv/mapv4v6addr.h"
|
||||
#include "../resolv/mapv4v6hostent.h"
|
||||
|
||||
/* Maximum number of aliases we allow. */
|
||||
#define MAX_NR_ALIASES 48
|
||||
#define MAX_NR_ADDRS 48
|
||||
|
||||
#if PACKETSZ > 65536
|
||||
# define MAXPACKET PACKETSZ
|
||||
#else
|
||||
# define MAXPACKET 65536
|
||||
#endif
|
||||
/* As per RFC 1034 and 1035 a host name cannot exceed 255 octets in length. */
|
||||
#ifdef MAXHOSTNAMELEN
|
||||
# undef MAXHOSTNAMELEN
|
||||
#endif
|
||||
#define MAXHOSTNAMELEN 256
|
||||
|
||||
static const char AskedForGot[] = "\
|
||||
gethostby*.getanswer: asked for \"%s\", got \"%s\"";
|
||||
|
||||
|
||||
/* We need this time later. */
|
||||
typedef union querybuf
|
||||
{
|
||||
HEADER hdr;
|
||||
u_char buf[MAXPACKET];
|
||||
} querybuf;
|
||||
|
||||
|
||||
static enum nss_status getanswer_r (const querybuf *answer, int anslen,
|
||||
const char *qname, int qtype,
|
||||
struct hostent *result, char *buffer,
|
||||
size_t buflen, int *h_errnop);
|
||||
|
||||
enum nss_status
|
||||
_nss_dns_gethostbyname2_r (const char *name, int af, struct hostent *result,
|
||||
char *buffer, size_t buflen, int *h_errnop)
|
||||
{
|
||||
union
|
||||
{
|
||||
querybuf *buf;
|
||||
u_char *ptr;
|
||||
} host_buffer;
|
||||
querybuf *orig_host_buffer;
|
||||
int size, type, n;
|
||||
const char *cp;
|
||||
enum nss_status status;
|
||||
|
||||
if ((_res.options & RES_INIT) == 0 && res_init() == -1)
|
||||
{
|
||||
*h_errnop = NETDB_INTERNAL;
|
||||
return NSS_STATUS_UNAVAIL;
|
||||
}
|
||||
|
||||
switch (af) {
|
||||
case AF_INET:
|
||||
size = INADDRSZ;
|
||||
type = T_A;
|
||||
break;
|
||||
case AF_INET6:
|
||||
size = IN6ADDRSZ;
|
||||
type = T_AAAA;
|
||||
break;
|
||||
default:
|
||||
*h_errnop = NETDB_INTERNAL;
|
||||
__set_errno (EAFNOSUPPORT);
|
||||
return NSS_STATUS_UNAVAIL;
|
||||
}
|
||||
|
||||
result->h_addrtype = af;
|
||||
result->h_length = size;
|
||||
|
||||
/*
|
||||
* if there aren't any dots, it could be a user-level alias.
|
||||
* this is also done in res_query() since we are not the only
|
||||
* function that looks up host names.
|
||||
*/
|
||||
if (strchr (name, '.') == NULL && (cp = __hostalias (name)) != NULL)
|
||||
name = cp;
|
||||
|
||||
host_buffer.buf = orig_host_buffer = (querybuf *) alloca (1024);
|
||||
|
||||
n = __libc_res_nsearch (&_res, name, C_IN, type, host_buffer.buf->buf, 1024,
|
||||
&host_buffer.ptr);
|
||||
if (n < 0)
|
||||
{
|
||||
*h_errnop = h_errno;
|
||||
if (host_buffer.buf != orig_host_buffer)
|
||||
free (host_buffer.buf);
|
||||
return errno == ECONNREFUSED ? NSS_STATUS_UNAVAIL : NSS_STATUS_NOTFOUND;
|
||||
}
|
||||
|
||||
status = getanswer_r (host_buffer.buf, n, name, type, result, buffer, buflen,
|
||||
h_errnop);
|
||||
if (host_buffer.buf != orig_host_buffer)
|
||||
free (host_buffer.buf);
|
||||
return status;
|
||||
}
|
||||
|
||||
|
||||
enum nss_status
|
||||
_nss_dns_gethostbyname_r (const char *name, struct hostent *result,
|
||||
char *buffer, size_t buflen, int *h_errnop)
|
||||
{
|
||||
enum nss_status status = NSS_STATUS_NOTFOUND;
|
||||
|
||||
if (_res.options & RES_USE_INET6)
|
||||
status = _nss_dns_gethostbyname2_r (name, AF_INET6, result, buffer,
|
||||
buflen, h_errnop);
|
||||
if (status == NSS_STATUS_NOTFOUND)
|
||||
status = _nss_dns_gethostbyname2_r (name, AF_INET, result, buffer,
|
||||
buflen, h_errnop);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
|
||||
enum nss_status
|
||||
_nss_dns_gethostbyaddr_r (const char *addr, int len, int af,
|
||||
struct hostent *result, char *buffer, size_t buflen,
|
||||
int *h_errnop)
|
||||
{
|
||||
static const u_char mapped[] = { 0,0, 0,0, 0,0, 0,0, 0,0, 0xff,0xff };
|
||||
static const u_char tunnelled[] = { 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 };
|
||||
const u_char *uaddr = (const u_char *)addr;
|
||||
struct host_data
|
||||
{
|
||||
char *aliases[MAX_NR_ALIASES];
|
||||
unsigned char host_addr[16]; /* IPv4 or IPv6 */
|
||||
char *h_addr_ptrs[MAX_NR_ADDRS + 1];
|
||||
char linebuffer[0];
|
||||
} *host_data = (struct host_data *) buffer;
|
||||
union
|
||||
{
|
||||
querybuf *buf;
|
||||
u_char *ptr;
|
||||
} host_buffer;
|
||||
querybuf *orig_host_buffer;
|
||||
char qbuf[MAXDNAME+1], *qp;
|
||||
int size, n, status;
|
||||
|
||||
if ((_res.options & RES_INIT) == 0 && res_init() == -1)
|
||||
{
|
||||
*h_errnop = NETDB_INTERNAL;
|
||||
return NSS_STATUS_UNAVAIL;
|
||||
}
|
||||
|
||||
if (af == AF_INET6 && len == IN6ADDRSZ &&
|
||||
(memcmp (uaddr, mapped, sizeof mapped) == 0
|
||||
|| memcmp (uaddr, tunnelled, sizeof tunnelled) == 0))
|
||||
{
|
||||
/* Unmap. */
|
||||
addr += sizeof mapped;
|
||||
uaddr += sizeof mapped;
|
||||
af = AF_INET;
|
||||
len = INADDRSZ;
|
||||
}
|
||||
|
||||
switch (af)
|
||||
{
|
||||
case AF_INET:
|
||||
size = INADDRSZ;
|
||||
break;
|
||||
case AF_INET6:
|
||||
size = IN6ADDRSZ;
|
||||
break;
|
||||
default:
|
||||
__set_errno (EAFNOSUPPORT);
|
||||
*h_errnop = NETDB_INTERNAL;
|
||||
return NSS_STATUS_UNAVAIL;
|
||||
}
|
||||
if (size != len)
|
||||
{
|
||||
__set_errno (EAFNOSUPPORT);
|
||||
*h_errnop = NETDB_INTERNAL;
|
||||
return NSS_STATUS_UNAVAIL;
|
||||
}
|
||||
|
||||
switch (af)
|
||||
{
|
||||
case AF_INET:
|
||||
sprintf (qbuf, "%u.%u.%u.%u.in-addr.arpa", (uaddr[3] & 0xff),
|
||||
(uaddr[2] & 0xff), (uaddr[1] & 0xff), (uaddr[0] & 0xff));
|
||||
break;
|
||||
case AF_INET6:
|
||||
qp = qbuf;
|
||||
for (n = IN6ADDRSZ - 1; n >= 0; n--)
|
||||
qp += sprintf (qp, "%x.%x.", uaddr[n] & 0xf, (uaddr[n] >> 4) & 0xf);
|
||||
strcpy(qp, "ip6.int");
|
||||
break;
|
||||
default:
|
||||
/* Cannot happen. */
|
||||
break;
|
||||
}
|
||||
|
||||
host_buffer.buf = orig_host_buffer = (querybuf *) alloca (1024);
|
||||
|
||||
n = __libc_res_nquery (&_res, qbuf, C_IN, T_PTR, host_buffer.buf->buf,
|
||||
1024, &host_buffer.ptr);
|
||||
if (n < 0)
|
||||
{
|
||||
*h_errnop = h_errno;
|
||||
if (host_buffer.buf != orig_host_buffer)
|
||||
free (host_buffer.buf);
|
||||
return errno == ECONNREFUSED ? NSS_STATUS_UNAVAIL : NSS_STATUS_NOTFOUND;
|
||||
}
|
||||
|
||||
status = getanswer_r (host_buffer.buf, n, qbuf, T_PTR, result, buffer, buflen,
|
||||
h_errnop);
|
||||
if (host_buffer.buf != orig_host_buffer)
|
||||
free (host_buffer.buf);
|
||||
if (status != NSS_STATUS_SUCCESS)
|
||||
{
|
||||
*h_errnop = h_errno;
|
||||
return status;
|
||||
}
|
||||
|
||||
#ifdef SUNSECURITY
|
||||
This is not implemented because it is not possible to use the current
|
||||
source from bind in a multi-threaded program.
|
||||
#endif
|
||||
|
||||
result->h_addrtype = af;
|
||||
result->h_length = len;
|
||||
memcpy (host_data->host_addr, addr, len);
|
||||
host_data->h_addr_ptrs[0] = (char *) host_data->host_addr;
|
||||
host_data->h_addr_ptrs[1] = NULL;
|
||||
if (af == AF_INET && (_res.options & RES_USE_INET6))
|
||||
{
|
||||
map_v4v6_address ((char *) host_data->host_addr,
|
||||
(char *) host_data->host_addr);
|
||||
result->h_addrtype = AF_INET6;
|
||||
result->h_length = IN6ADDRSZ;
|
||||
}
|
||||
*h_errnop = NETDB_SUCCESS;
|
||||
return NSS_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
static enum nss_status
|
||||
getanswer_r (const querybuf *answer, int anslen, const char *qname, int qtype,
|
||||
struct hostent *result, char *buffer, size_t buflen,
|
||||
int *h_errnop)
|
||||
{
|
||||
struct host_data
|
||||
{
|
||||
char *aliases[MAX_NR_ALIASES];
|
||||
unsigned char host_addr[16]; /* IPv4 or IPv6 */
|
||||
char *h_addr_ptrs[MAX_NR_ADDRS + 1];
|
||||
char linebuffer[0];
|
||||
} *host_data = (struct host_data *) buffer;
|
||||
int linebuflen = buflen - offsetof (struct host_data, linebuffer);
|
||||
register const HEADER *hp;
|
||||
const u_char *end_of_message, *cp;
|
||||
int n, ancount, qdcount;
|
||||
int haveanswer, had_error;
|
||||
char *bp, **ap, **hap;
|
||||
char tbuf[MAXDNAME];
|
||||
const char *tname;
|
||||
int (*name_ok) (const char *);
|
||||
|
||||
tname = qname;
|
||||
result->h_name = NULL;
|
||||
end_of_message = answer->buf + anslen;
|
||||
switch (qtype)
|
||||
{
|
||||
case T_A:
|
||||
case T_AAAA:
|
||||
name_ok = res_hnok;
|
||||
break;
|
||||
case T_PTR:
|
||||
name_ok = res_dnok;
|
||||
break;
|
||||
default:
|
||||
return NSS_STATUS_UNAVAIL; /* XXX should be abort(); */
|
||||
}
|
||||
|
||||
/*
|
||||
* find first satisfactory answer
|
||||
*/
|
||||
hp = &answer->hdr;
|
||||
bp = host_data->linebuffer;
|
||||
ancount = ntohs (hp->ancount);
|
||||
qdcount = ntohs (hp->qdcount);
|
||||
cp = answer->buf + HFIXEDSZ;
|
||||
if (qdcount != 1)
|
||||
{
|
||||
*h_errnop = NO_RECOVERY;
|
||||
return NSS_STATUS_UNAVAIL;
|
||||
}
|
||||
|
||||
n = dn_expand (answer->buf, end_of_message, cp, bp, linebuflen);
|
||||
if (n < 0 || (*name_ok) (bp) == 0)
|
||||
{
|
||||
*h_errnop = NO_RECOVERY;
|
||||
return NSS_STATUS_UNAVAIL;
|
||||
}
|
||||
cp += n + QFIXEDSZ;
|
||||
|
||||
if (qtype == T_A || qtype == T_AAAA)
|
||||
{
|
||||
/* res_send() has already verified that the query name is the
|
||||
* same as the one we sent; this just gets the expanded name
|
||||
* (i.e., with the succeeding search-domain tacked on).
|
||||
*/
|
||||
n = strlen (bp) + 1; /* for the \0 */
|
||||
if (n >= MAXHOSTNAMELEN)
|
||||
{
|
||||
__set_h_errno (NO_RECOVERY);
|
||||
return NSS_STATUS_TRYAGAIN;
|
||||
}
|
||||
result->h_name = bp;
|
||||
bp += n;
|
||||
linebuflen -= n;
|
||||
/* The qname can be abbreviated, but h_name is now absolute. */
|
||||
qname = result->h_name;
|
||||
}
|
||||
|
||||
ap = host_data->aliases;
|
||||
*ap = NULL;
|
||||
result->h_aliases = host_data->aliases;
|
||||
hap = host_data->h_addr_ptrs;
|
||||
*hap = NULL;
|
||||
result->h_addr_list = host_data->h_addr_ptrs;
|
||||
haveanswer = 0;
|
||||
had_error = 0;
|
||||
|
||||
while (ancount-- > 0 && cp < end_of_message && had_error == 0)
|
||||
{
|
||||
int type, class;
|
||||
|
||||
n = dn_expand (answer->buf, end_of_message, cp, bp, linebuflen);
|
||||
if (n < 0 || (*name_ok) (bp) == 0)
|
||||
{
|
||||
++had_error;
|
||||
continue;
|
||||
}
|
||||
cp += n; /* name */
|
||||
type = _getshort (cp);
|
||||
cp += INT16SZ; /* type */
|
||||
class = _getshort(cp);
|
||||
cp += INT16SZ + INT32SZ; /* class, TTL */
|
||||
n = _getshort(cp);
|
||||
cp += INT16SZ; /* len */
|
||||
if (class != C_IN)
|
||||
{
|
||||
/* XXX - debug? syslog? */
|
||||
cp += n;
|
||||
continue; /* XXX - had_error++ ? */
|
||||
}
|
||||
|
||||
if ((qtype ==T_A || qtype == T_AAAA) && type == T_CNAME)
|
||||
{
|
||||
if (ap >= &host_data->aliases[MAX_NR_ALIASES - 1])
|
||||
continue;
|
||||
n = dn_expand (answer->buf, end_of_message, cp, tbuf, sizeof tbuf);
|
||||
if (n < 0 || (*name_ok) (tbuf) == 0)
|
||||
{
|
||||
++had_error;
|
||||
continue;
|
||||
}
|
||||
cp += n;
|
||||
/* Store alias. */
|
||||
*ap++ = bp;
|
||||
n = strlen (bp) + 1; /* For the \0. */
|
||||
if (n >= MAXHOSTNAMELEN)
|
||||
{
|
||||
++had_error;
|
||||
continue;
|
||||
}
|
||||
bp += n;
|
||||
linebuflen -= n;
|
||||
/* Get canonical name. */
|
||||
n = strlen (tbuf) + 1; /* For the \0. */
|
||||
if ((size_t) n > linebuflen || n >= MAXHOSTNAMELEN)
|
||||
{
|
||||
++had_error;
|
||||
continue;
|
||||
}
|
||||
strcpy (bp, tbuf); /* Cannot overflow. */
|
||||
result->h_name = bp;
|
||||
bp += n;
|
||||
linebuflen -= n;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (qtype == T_PTR && type == T_CNAME)
|
||||
{
|
||||
n = dn_expand (answer->buf, end_of_message, cp, tbuf, sizeof tbuf);
|
||||
if (n < 0 || res_dnok (tbuf) == 0)
|
||||
{
|
||||
++had_error;
|
||||
continue;
|
||||
}
|
||||
cp += n;
|
||||
/* Get canonical name. */
|
||||
n = strlen (tbuf) + 1; /* For the \0. */
|
||||
if ((size_t) n > linebuflen || n >= MAXHOSTNAMELEN)
|
||||
{
|
||||
++had_error;
|
||||
continue;
|
||||
}
|
||||
strcpy (bp, tbuf); /* Cannot overflow. */
|
||||
tname = bp;
|
||||
bp += n;
|
||||
linebuflen -= n;
|
||||
continue;
|
||||
}
|
||||
if (type != qtype)
|
||||
{
|
||||
syslog (LOG_NOTICE | LOG_AUTH,
|
||||
"gethostby*.getanswer: asked for \"%s %s %s\", got type \"%s\"",
|
||||
qname, p_class (C_IN), p_type (qtype), p_type (type));
|
||||
cp += n;
|
||||
continue; /* XXX - had_error++ ? */
|
||||
}
|
||||
|
||||
switch (type)
|
||||
{
|
||||
case T_PTR:
|
||||
if (strcasecmp (tname, bp) != 0)
|
||||
{
|
||||
syslog (LOG_NOTICE | LOG_AUTH, AskedForGot, qname, bp);
|
||||
cp += n;
|
||||
continue; /* XXX - had_error++ ? */
|
||||
}
|
||||
n = dn_expand (answer->buf, end_of_message, cp, bp, linebuflen);
|
||||
if (n < 0 || res_hnok (bp) == 0)
|
||||
{
|
||||
++had_error;
|
||||
break;
|
||||
}
|
||||
#if MULTI_PTRS_ARE_ALIASES
|
||||
cp += n;
|
||||
if (haveanswer == 0)
|
||||
result->h_name = bp;
|
||||
else if (ap < &host_data->aliases[MAXALIASES-1])
|
||||
*ap++ = bp;
|
||||
else
|
||||
n = -1;
|
||||
if (n != -1)
|
||||
{
|
||||
n = strlen (bp) + 1; /* for the \0 */
|
||||
if (n >= MAXHOSTNAMELEN)
|
||||
{
|
||||
++had_error;
|
||||
break;
|
||||
}
|
||||
bp += n;
|
||||
linebuflen -= n;
|
||||
}
|
||||
break;
|
||||
#else
|
||||
result->h_name = bp;
|
||||
if (_res.options & RES_USE_INET6)
|
||||
{
|
||||
n = strlen (bp) + 1; /* for the \0 */
|
||||
if (n >= MAXHOSTNAMELEN)
|
||||
{
|
||||
++had_error;
|
||||
break;
|
||||
}
|
||||
bp += n;
|
||||
linebuflen -= n;
|
||||
map_v4v6_hostent (result, &bp, &linebuflen);
|
||||
}
|
||||
*h_errnop = NETDB_SUCCESS;
|
||||
return NSS_STATUS_SUCCESS;
|
||||
#endif
|
||||
case T_A:
|
||||
case T_AAAA:
|
||||
if (strcasecmp (result->h_name, bp) != 0)
|
||||
{
|
||||
syslog (LOG_NOTICE | LOG_AUTH, AskedForGot, result->h_name, bp);
|
||||
cp += n;
|
||||
continue; /* XXX - had_error++ ? */
|
||||
}
|
||||
if (n != result->h_length)
|
||||
{
|
||||
cp += n;
|
||||
continue;
|
||||
}
|
||||
if (!haveanswer)
|
||||
{
|
||||
register int nn;
|
||||
|
||||
result->h_name = bp;
|
||||
nn = strlen (bp) + 1; /* for the \0 */
|
||||
bp += nn;
|
||||
linebuflen -= nn;
|
||||
}
|
||||
|
||||
linebuflen -= sizeof (align) - ((u_long) bp % sizeof (align));
|
||||
bp += sizeof (align) - ((u_long) bp % sizeof (align));
|
||||
|
||||
if (n >= linebuflen)
|
||||
{
|
||||
++had_error;
|
||||
continue;
|
||||
}
|
||||
if (hap >= &host_data->h_addr_ptrs[MAX_NR_ADDRS-1])
|
||||
{
|
||||
cp += n;
|
||||
continue;
|
||||
}
|
||||
memcpy (*hap++ = bp, cp, n);
|
||||
bp += n;
|
||||
cp += n;
|
||||
linebuflen -= n;
|
||||
break;
|
||||
default:
|
||||
abort ();
|
||||
}
|
||||
if (had_error == 0)
|
||||
++haveanswer;
|
||||
}
|
||||
|
||||
if (haveanswer > 0)
|
||||
{
|
||||
*ap = NULL;
|
||||
*hap = NULL;
|
||||
#if defined(RESOLVSORT)
|
||||
/*
|
||||
* Note: we sort even if host can take only one address
|
||||
* in its return structures - should give it the "best"
|
||||
* address in that case, not some random one
|
||||
*/
|
||||
if (_res.nsort && haveanswer > 1 && qtype == T_A)
|
||||
addrsort (host_data->h_addr_ptrs, haveanswer);
|
||||
#endif /*RESOLVSORT*/
|
||||
|
||||
if (result->h_name == NULL)
|
||||
{
|
||||
n = strlen (qname) + 1; /* For the \0. */
|
||||
if (n > linebuflen || n >= MAXHOSTNAMELEN)
|
||||
goto no_recovery;
|
||||
strcpy (bp, qname); /* Cannot overflow. */
|
||||
result->h_name = bp;
|
||||
bp += n;
|
||||
linebuflen -= n;
|
||||
}
|
||||
|
||||
if (_res.options & RES_USE_INET6)
|
||||
map_v4v6_hostent (result, &bp, &linebuflen);
|
||||
*h_errnop = NETDB_SUCCESS;
|
||||
return NSS_STATUS_SUCCESS;
|
||||
}
|
||||
no_recovery:
|
||||
*h_errnop = NO_RECOVERY;
|
||||
return NSS_STATUS_TRYAGAIN;
|
||||
}
|
||||
@@ -0,0 +1,420 @@
|
||||
/* Copyright (C) 1996, 1997 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
Extended from original form by Ulrich Drepper <drepper@cygnus.com>, 1996.
|
||||
|
||||
The GNU C Library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Library General Public License as
|
||||
published by the Free Software Foundation; either version 2 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
|
||||
Library General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Library General Public
|
||||
License along with the GNU C Library; see the file COPYING.LIB. If not,
|
||||
write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
Boston, MA 02111-1307, USA. */
|
||||
|
||||
/* Parts of this file are plain copies of the file `getnetnamadr.c' from
|
||||
the bind package and it has the following copyright. */
|
||||
|
||||
/* Copyright (c) 1993 Carlos Leandro and Rui Salgueiro
|
||||
* Dep. Matematica Universidade de Coimbra, Portugal, Europe
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*/
|
||||
/*
|
||||
* Copyright (c) 1983, 1993
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by the University of
|
||||
* California, Berkeley and its contributors.
|
||||
* 4. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <ctype.h>
|
||||
#include <errno.h>
|
||||
#include <glibc-compat/include/netdb.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "nsswitch.h"
|
||||
#include <arpa/inet.h>
|
||||
|
||||
/* Maximum number of aliases we allow. */
|
||||
#define MAX_NR_ALIASES 48
|
||||
|
||||
|
||||
#if PACKETSZ > 65536
|
||||
#define MAXPACKET PACKETSZ
|
||||
#else
|
||||
#define MAXPACKET 65536
|
||||
#endif
|
||||
|
||||
|
||||
typedef enum
|
||||
{
|
||||
BYADDR,
|
||||
BYNAME
|
||||
} lookup_method;
|
||||
|
||||
|
||||
/* We need this time later. */
|
||||
typedef union querybuf
|
||||
{
|
||||
HEADER hdr;
|
||||
u_char buf[MAXPACKET];
|
||||
} querybuf;
|
||||
|
||||
|
||||
/* Prototypes for local functions. */
|
||||
static enum nss_status getanswer_r (const querybuf *answer, int anslen,
|
||||
struct netent *result, char *buffer,
|
||||
size_t buflen, lookup_method net_i);
|
||||
|
||||
|
||||
enum nss_status
|
||||
_nss_dns_getnetbyname_r (const char *name, struct netent *result,
|
||||
char *buffer, size_t buflen)
|
||||
{
|
||||
/* Return entry for network with NAME. */
|
||||
union
|
||||
{
|
||||
querybuf *buf;
|
||||
u_char *ptr;
|
||||
} net_buffer;
|
||||
querybuf *orig_net_buffer;
|
||||
int anslen;
|
||||
char *qbuf;
|
||||
enum nss_status status;
|
||||
|
||||
if ((_res.options & RES_INIT) == 0 && res_init() == -1)
|
||||
return NSS_STATUS_UNAVAIL;
|
||||
|
||||
qbuf = strdupa (name);
|
||||
|
||||
net_buffer.buf = orig_net_buffer = (querybuf *) alloca (1024);
|
||||
|
||||
anslen = __libc_res_nsearch (&_res, qbuf, C_IN, T_PTR, net_buffer.buf->buf,
|
||||
1024, &net_buffer.ptr);
|
||||
if (anslen < 0)
|
||||
{
|
||||
if (net_buffer.buf != orig_net_buffer)
|
||||
free (net_buffer.buf);
|
||||
/* Nothing found. */
|
||||
return (errno == ECONNREFUSED
|
||||
|| errno == EPFNOSUPPORT
|
||||
|| errno == EAFNOSUPPORT)
|
||||
? NSS_STATUS_UNAVAIL : NSS_STATUS_NOTFOUND;
|
||||
}
|
||||
|
||||
status = getanswer_r (net_buffer.buf, anslen, result, buffer, buflen, BYNAME);
|
||||
if (net_buffer.buf != orig_net_buffer)
|
||||
free (net_buffer.buf);
|
||||
return status;
|
||||
}
|
||||
|
||||
|
||||
enum nss_status
|
||||
_nss_dns_getnetbyaddr_r (long net, int type, struct netent *result,
|
||||
char *buffer, size_t buflen)
|
||||
{
|
||||
/* Return entry for network with NAME. */
|
||||
enum nss_status status;
|
||||
union
|
||||
{
|
||||
querybuf *buf;
|
||||
u_char *ptr;
|
||||
} net_buffer;
|
||||
querybuf *orig_net_buffer;
|
||||
unsigned int net_bytes[4];
|
||||
char qbuf[MAXDNAME];
|
||||
int cnt, anslen;
|
||||
u_int32_t net2;
|
||||
|
||||
if ((_res.options & RES_INIT) == 0 && res_init() == -1)
|
||||
return NSS_STATUS_UNAVAIL;
|
||||
|
||||
/* No net address lookup for IPv6 yet. */
|
||||
if (type != AF_INET)
|
||||
return NSS_STATUS_UNAVAIL;
|
||||
|
||||
net2 = (u_int32_t) net;
|
||||
for (cnt = 4; net2 != 0; net2 >>= 8)
|
||||
net_bytes[--cnt] = net2 & 0xff;
|
||||
|
||||
switch (cnt)
|
||||
{
|
||||
case 3:
|
||||
/* Class A network. */
|
||||
sprintf (qbuf, "0.0.0.%u.in-addr.arpa", net_bytes[3]);
|
||||
break;
|
||||
case 2:
|
||||
/* Class B network. */
|
||||
sprintf (qbuf, "0.0.%u.%u.in-addr.arpa", net_bytes[3], net_bytes[2]);
|
||||
break;
|
||||
case 1:
|
||||
/* Class C network. */
|
||||
sprintf (qbuf, "0.%u.%u.%u.in-addr.arpa", net_bytes[3], net_bytes[2],
|
||||
net_bytes[1]);
|
||||
break;
|
||||
case 0:
|
||||
/* Class D - E network. */
|
||||
sprintf (qbuf, "%u.%u.%u.%u.in-addr.arpa", net_bytes[3], net_bytes[2],
|
||||
net_bytes[1], net_bytes[0]);
|
||||
break;
|
||||
}
|
||||
|
||||
net_buffer.buf = orig_net_buffer = (querybuf *) alloca (1024);
|
||||
|
||||
anslen = __libc_res_nquery (&_res, qbuf, C_IN, T_PTR, net_buffer.buf->buf,
|
||||
1024, &net_buffer.ptr);
|
||||
if (anslen < 0)
|
||||
{
|
||||
if (net_buffer.buf != orig_net_buffer)
|
||||
free (net_buffer.buf);
|
||||
/* Nothing found. */
|
||||
return (errno == ECONNREFUSED
|
||||
|| errno == EPFNOSUPPORT
|
||||
|| errno == EAFNOSUPPORT)
|
||||
? NSS_STATUS_UNAVAIL : NSS_STATUS_NOTFOUND;
|
||||
}
|
||||
|
||||
status = getanswer_r (net_buffer.buf, anslen, result, buffer, buflen, BYADDR);
|
||||
if (net_buffer.buf != orig_net_buffer)
|
||||
free (net_buffer.buf);
|
||||
if (status == NSS_STATUS_SUCCESS)
|
||||
{
|
||||
/* Strip trailing zeros. */
|
||||
unsigned int u_net = net; /* Maybe net should be unsigned? */
|
||||
|
||||
while ((u_net & 0xff) == 0 && u_net != 0)
|
||||
u_net >>= 8;
|
||||
result->n_net = u_net;
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
|
||||
#undef offsetof
|
||||
#define offsetof(Type, Member) ((size_t) &((Type *) NULL)->Member)
|
||||
|
||||
static enum nss_status
|
||||
getanswer_r (const querybuf *answer, int anslen, struct netent *result,
|
||||
char *buffer, size_t buflen, lookup_method net_i)
|
||||
{
|
||||
/*
|
||||
* Find first satisfactory answer
|
||||
*
|
||||
* answer --> +------------+ ( MESSAGE )
|
||||
* | Header |
|
||||
* +------------+
|
||||
* | Question | the question for the name server
|
||||
* +------------+
|
||||
* | Answer | RRs answering the question
|
||||
* +------------+
|
||||
* | Authority | RRs pointing toward an authority
|
||||
* | Additional | RRs holding additional information
|
||||
* +------------+
|
||||
*/
|
||||
struct net_data
|
||||
{
|
||||
char *aliases[MAX_NR_ALIASES];
|
||||
char linebuffer[0];
|
||||
} *net_data = (struct net_data *) buffer;
|
||||
int linebuflen = buflen - offsetof (struct net_data, linebuffer);
|
||||
const char *end_of_message = &answer->buf[anslen];
|
||||
const HEADER *header_pointer = &answer->hdr;
|
||||
/* #/records in the answer section. */
|
||||
int answer_count = ntohs (header_pointer->ancount);
|
||||
/* #/entries in the question section. */
|
||||
int question_count = ntohs (header_pointer->qdcount);
|
||||
char *bp = net_data->linebuffer;
|
||||
const char *cp = &answer->buf[HFIXEDSZ];
|
||||
char **alias_pointer;
|
||||
int have_answer;
|
||||
char *ans;
|
||||
|
||||
if (question_count == 0)
|
||||
{
|
||||
/* FIXME: the Sun version uses for host name lookup an additional
|
||||
parameter for pointing to h_errno. this is missing here.
|
||||
OSF/1 has a per-thread h_errno variable. */
|
||||
if (header_pointer->aa != 0)
|
||||
{
|
||||
__set_h_errno (HOST_NOT_FOUND);
|
||||
return NSS_STATUS_NOTFOUND;
|
||||
}
|
||||
else
|
||||
{
|
||||
__set_h_errno (TRY_AGAIN);
|
||||
return NSS_STATUS_TRYAGAIN;
|
||||
}
|
||||
}
|
||||
|
||||
/* Skip the question part. */
|
||||
while (question_count-- > 0)
|
||||
{
|
||||
int n = __dn_skipname (cp, end_of_message);
|
||||
if (n < 0 || end_of_message - (cp + n) < QFIXEDSZ)
|
||||
{
|
||||
__set_h_errno (NO_RECOVERY);
|
||||
return NSS_STATUS_UNAVAIL;
|
||||
}
|
||||
cp += n + QFIXEDSZ;
|
||||
}
|
||||
|
||||
alias_pointer = result->n_aliases = &net_data->aliases[0];
|
||||
*alias_pointer = NULL;
|
||||
have_answer = 0;
|
||||
ans = NULL;
|
||||
|
||||
while (--answer_count >= 0 && cp < end_of_message)
|
||||
{
|
||||
int n = dn_expand (answer->buf, end_of_message, cp, bp, linebuflen);
|
||||
int type, class;
|
||||
|
||||
if (n < 0 || res_dnok (bp) == 0)
|
||||
break;
|
||||
cp += n;
|
||||
ans = strdupa (bp);
|
||||
GETSHORT (type, cp);
|
||||
GETSHORT (class, cp);
|
||||
cp += INT32SZ; /* TTL */
|
||||
GETSHORT (n, cp);
|
||||
|
||||
if (class == C_IN && type == T_PTR)
|
||||
{
|
||||
n = dn_expand (answer->buf, end_of_message, cp, bp, linebuflen);
|
||||
if (n < 0 || !res_hnok (bp))
|
||||
{
|
||||
/* XXX What does this mean? The original form from bind
|
||||
returns NULL. Incrementing cp has no effect in any case.
|
||||
What should I return here. ??? */
|
||||
cp += n;
|
||||
return NSS_STATUS_UNAVAIL;
|
||||
}
|
||||
cp += n;
|
||||
if (alias_pointer + 2 < &net_data->aliases[MAX_NR_ALIASES])
|
||||
{
|
||||
*alias_pointer++ = bp;
|
||||
n = strlen (bp) + 1;
|
||||
bp += n;
|
||||
linebuflen -= n;
|
||||
result->n_addrtype = class == C_IN ? AF_INET : AF_UNSPEC;
|
||||
++have_answer;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (have_answer)
|
||||
{
|
||||
*alias_pointer = NULL;
|
||||
switch (net_i)
|
||||
{
|
||||
case BYADDR:
|
||||
result->n_name = *result->n_aliases++;
|
||||
result->n_net = 0L;
|
||||
return NSS_STATUS_SUCCESS;
|
||||
|
||||
case BYNAME:
|
||||
{
|
||||
char **ap = result->n_aliases++;
|
||||
while (*ap != NULL)
|
||||
{
|
||||
/* Check each alias name for being of the forms:
|
||||
4.3.2.1.in-addr.arpa = net 1.2.3.4
|
||||
3.2.1.in-addr.arpa = net 0.1.2.3
|
||||
2.1.in-addr.arpa = net 0.0.1.2
|
||||
1.in-addr.arpa = net 0.0.0.1
|
||||
*/
|
||||
uint32_t val = 0; /* Accumulator for n_net value. */
|
||||
unsigned int shift = 0; /* Which part we are parsing now. */
|
||||
const char *p = *ap; /* Consuming the string. */
|
||||
do
|
||||
{
|
||||
/* Match the leading 0 or 0[xX] base indicator. */
|
||||
unsigned int base = 10;
|
||||
if (*p == '0' && p[1] != '.')
|
||||
{
|
||||
base = 8;
|
||||
++p;
|
||||
if (*p == 'x' || *p == 'X')
|
||||
{
|
||||
base = 16;
|
||||
++p;
|
||||
if (*p == '.')
|
||||
break; /* No digit here. Give up on alias. */
|
||||
}
|
||||
if (*p == '\0')
|
||||
break;
|
||||
}
|
||||
|
||||
uint32_t part = 0; /* Accumulates this part's number. */
|
||||
do
|
||||
{
|
||||
if (isdigit (*p) && (*p - '0' < base))
|
||||
part = (part * base) + (*p - '0');
|
||||
else if (base == 16 && isxdigit (*p))
|
||||
part = (part << 4) + 10 + (tolower (*p) - 'a');
|
||||
++p;
|
||||
} while (*p != '\0' && *p != '.');
|
||||
|
||||
if (*p != '.')
|
||||
break; /* Bad form. Give up on this name. */
|
||||
|
||||
/* Install this as the next more significant byte. */
|
||||
val |= part << shift;
|
||||
shift += 8;
|
||||
++p;
|
||||
|
||||
/* If we are out of digits now, there are two cases:
|
||||
1. We are done with digits and now see "in-addr.arpa".
|
||||
2. This is not the droid we are looking for. */
|
||||
if (!isdigit (*p) && !strcasecmp (p, "in-addr.arpa"))
|
||||
{
|
||||
result->n_net = val;
|
||||
return NSS_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
/* Keep going when we have seen fewer than 4 parts. */
|
||||
} while (shift < 32);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
__set_h_errno (TRY_AGAIN);
|
||||
return NSS_STATUS_TRYAGAIN;
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user