mirror of
git://sourceware.org/git/glibc.git
synced 2026-09-08 23:58:31 +08:00
Compare commits
42
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
7799b7b335 | ||
|
|
9d8067d8f2 | ||
|
|
6355131153 | ||
|
|
c131718ccc | ||
|
|
26dee9c49c | ||
|
|
fe7bdd630f | ||
|
|
22d57dd369 | ||
|
|
5929563ff2 | ||
|
|
3075e0e37c | ||
|
|
993b3242cd | ||
|
|
e7fd8a39ab | ||
|
|
34b402e5a9 | ||
|
|
4e1101a7da | ||
|
|
3e5f555752 | ||
|
|
bc9f6000f6 | ||
|
|
5ae9d168f6 | ||
|
|
f752bfe379 | ||
|
|
c57abfa735 | ||
|
|
e61abf8398 | ||
|
|
6465cfc9cf | ||
|
|
81e9dad672 | ||
|
|
0d8733c4fc | ||
|
|
1ed4222e57 | ||
|
|
f166d86530 | ||
|
|
4cca6b868f | ||
|
|
f5f52655ce | ||
|
|
377a515b4c | ||
|
|
d1a2b102df | ||
|
|
f6b38b9a39 | ||
|
|
ced858d05f | ||
|
|
ceb2d9aaa8 | ||
|
|
867a8743a4 | ||
|
|
2f6d1f1be9 | ||
|
|
6bac11d993 | ||
|
|
4dea6fa212 | ||
|
|
5a97622d5e | ||
|
|
1fb05e3db1 | ||
|
|
c84142e8fe | ||
|
|
7434ccadbb | ||
|
|
795fbc9aa1 | ||
|
|
00de59a632 | ||
|
|
7cc27f440c |
+10
-2
@@ -1,10 +1,10 @@
|
||||
*.d *.o *.so *.po *.go stamp.* *.stamp *.ustamp *.udeps
|
||||
*.d *.o *.so *.po *.go *.bo stamp.* *.stamp *.ustamp *.udeps
|
||||
*.gz *.Z *.tar *.tgz
|
||||
=*
|
||||
TODO COPYING* AUTHORS copyr-* copying.*
|
||||
glibc-*
|
||||
|
||||
configparms
|
||||
configparms
|
||||
|
||||
sun[43]* i[345]86* hp300*
|
||||
|
||||
@@ -13,3 +13,11 @@ ieeetest hppa-sysdeps regex
|
||||
gpl2lgpl.sed
|
||||
distinfo
|
||||
distinfo
|
||||
|
||||
analysis
|
||||
docs
|
||||
|
||||
crypt
|
||||
linuxthreads
|
||||
localedata
|
||||
secure_rpc
|
||||
|
||||
@@ -0,0 +1,62 @@
|
||||
List of known bugs (certainly very incomplete)
|
||||
----------------------------------------------
|
||||
|
||||
Time-stamp: <1997-03-22T04:31:41+0100 drepper>
|
||||
|
||||
This following list contains those bugs which I'm aware of. Please
|
||||
make sure that bugs you report are not listed here. If you can fix one
|
||||
of these bugs/limitations I'll certainly be glad to receive a patch.
|
||||
|
||||
Another source of information about bugs is the problem data base of the
|
||||
GNU project. There is an easy to use WWW interface is available at
|
||||
|
||||
http://pogo.gnu.ai.mit.edu:8080/cgi-bin/wwwgnats.pl
|
||||
|
||||
I would appreciate it very much if you could verify the problem was not
|
||||
reported before by looking though the database. To make the information
|
||||
in this data as useful as possible please report bugs always using the
|
||||
`glibcbug' shell script which gets installed with GNU libc.
|
||||
|
||||
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Severity: [ *] to [***]
|
||||
|
||||
|
||||
[ **] For GNU libc on Linux, there is still no solution for the UTMP
|
||||
problem.
|
||||
[Among others: PR libc/39]
|
||||
|
||||
[ **] There are problems with signal handling when using LinuxThreads.
|
||||
|
||||
[ **] The `cbrtl' function is inaccurate. The algorithm used for `double'
|
||||
and `float' is not usable for `long double'.
|
||||
|
||||
[ **] Not really a bug, but it could lead to such:
|
||||
The RPC code is ugly ugly ugly. It's more or less verbatim taken
|
||||
from Sun's code and therefore mostly lacks complete prototypes and
|
||||
(more important) the use of `const'. It *definitely* needs to be
|
||||
cleaned.
|
||||
|
||||
[ *] The precision of the `sinhl' and/or `asinhl' function do not seem
|
||||
to be the best.
|
||||
|
||||
[ *] The syslog function should print to the console if the LOG_CONS
|
||||
flag was given.
|
||||
[PR libc/72]
|
||||
|
||||
[ *] On Linux, the <linux/posix_types.h> is not clean enough to satisfy
|
||||
the C++ namespace rules. Declaring `struct fd_set' also makes
|
||||
`fd_set' available in the global namespace which conflicts with
|
||||
the definition of `fd_set' in glibc.
|
||||
[PR libc/79]
|
||||
|
||||
[ *] On Linux, there should be a way to prevent defining the symbol
|
||||
NGROUPS_MAX in the <linux/limits.h> header file. In glibc it
|
||||
is defined in <posix1_lim.h> which must not make the other
|
||||
symbols in <linux/limits.h> available.
|
||||
[PR libc/140]
|
||||
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
Ulrich Drepper
|
||||
drepper@cygnus.com
|
||||
@@ -77,6 +77,16 @@ please let me know.
|
||||
|
||||
[Q21] ``On Linux I've got problems with the declarations in Linux
|
||||
kernel headers.''
|
||||
|
||||
[Q22] ``When I try to compile code which uses IPv6 header and
|
||||
definitions on my Linux 2.x.y system I am in trouble.
|
||||
Nothing seems to work.''
|
||||
|
||||
[Q23] ``When compiling GNU libc I get lots of errors saying functions
|
||||
in glibc are duplicated in libgcc.''
|
||||
|
||||
[Q24] ``I have set up /etc/nis.conf, and the Linux libc 5 with NYS
|
||||
works great. But the glibc NIS+ doesn't seem to work.''
|
||||
|
||||
~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~
|
||||
[Q1] ``What systems does the GNU C Library run on?''
|
||||
@@ -550,7 +560,8 @@ by
|
||||
|
||||
in the above example specs file to make it work for other systems.
|
||||
|
||||
Future versions of GCC will automatically provide the correct specs.
|
||||
Version 2.7.2.2 does and future versions of GCC will automatically
|
||||
provide the correct specs.
|
||||
|
||||
|
||||
~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~
|
||||
@@ -568,12 +579,6 @@ something like this:
|
||||
GROUP ( libc.so.6 ld.so.1 libc.a )
|
||||
|
||||
|
||||
{UD} The Linux ldconfig file probably generates a link libc.so ->
|
||||
libc.so.6 in /lib. This is not correct. There must not be such a
|
||||
link. The linker script with the above contents is placed in
|
||||
/usr/lib which is enough for the linker.
|
||||
|
||||
|
||||
~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~
|
||||
[Q18] ``The prototypes for `connect', `accept', `getsockopt',
|
||||
`setsockopt', `getsockname', `getpeername', `send',
|
||||
@@ -603,10 +608,22 @@ invalid. I.e., an emulated FPU is for the libc as good as a real one.
|
||||
[Q20] ``How can I compile gcc 2.7.2.1 from the gcc source code using
|
||||
glibc 2.x?
|
||||
|
||||
[A20] {HJL} There is no support in gcc for glibc 2.0 before gcc 2.8. It
|
||||
is very tricky to compile gcc 2.7.2.1 using glibc 2.x. You have to
|
||||
build it manually or with one pass only. You also have to use the
|
||||
specs file in this FAQ while compiling gcc.
|
||||
[A20] {AJ} There's only support for glibc 2.0 in gcc 2.7.2.2 or later.
|
||||
For 2.7.2.2 you should use the following patch and configure for
|
||||
e.g. i486-linux.
|
||||
-----------------------------------------------------------------------
|
||||
--- configure Tue Feb 11 15:57:17 1997
|
||||
+++ configure Wed Feb 12 23:09:29 1997
|
||||
@@ -1021,7 +1021,7 @@
|
||||
gnu_ld=yes
|
||||
# GNU libc version 2 does not supply these;
|
||||
# we want them from GCC.
|
||||
- extra_parts="crtbegin.o crtend.o"
|
||||
+ extra_parts="crtbegin.o crtbeginS.o crtend.o crtendS.o"
|
||||
;;
|
||||
i[3456]86-go32-msdos | i[3456]86-*-go32)
|
||||
cpu_type=i386
|
||||
-----------------------------------------------------------------------
|
||||
|
||||
|
||||
~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~
|
||||
@@ -629,6 +646,52 @@ glibc has defined a replacement. Otherwise you might get undefined
|
||||
results because of type conflicts.
|
||||
|
||||
|
||||
~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~
|
||||
[Q22] ``When I try to compile code which uses IPv6 header and
|
||||
definitions on my Linux 2.x.y system I am in trouble.
|
||||
Nothing seems to work.''
|
||||
|
||||
[A22] {UD} The problem is that the IPv6 development still has not reached
|
||||
a point where it is stable. There are still lots of incompatible changes
|
||||
made and the libc headers have to follow.
|
||||
|
||||
Currently (as of 970401) according to Philip Blundell <pjb27@cam.ac.uk>
|
||||
the required kernel version is 2.1.30.
|
||||
|
||||
|
||||
~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~
|
||||
[Q23] ``When compiling GNU libc I get lots of errors saying functions
|
||||
in glibc are duplicated in libgcc.''
|
||||
|
||||
[A23] {EY} This is *exactly* the same problem that I was having. The
|
||||
problem was due to the fact that the autoconfigure didn't correctly
|
||||
detect that linker flag --no-whole-archive was supported in my linker.
|
||||
In my case it was because I had run ./configure with bogus CFLAGS, and
|
||||
the test failed.
|
||||
|
||||
One thing that is particularly annoying about this problem is that
|
||||
once this is misdetected, running configure again won't fix it unless
|
||||
you first delete config.cache.
|
||||
|
||||
{UD} Starting with glibc-2.0.3 there should be a better test to avoid
|
||||
some problems of this kind. The setting of CFLAGS is checked at the
|
||||
very beginning and if it is not usable `configure' will bark.
|
||||
|
||||
|
||||
|
||||
~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~
|
||||
[Q24] ``I have set up /etc/nis.conf, and the Linux libc 5 with NYS
|
||||
works great. But the glibc NIS+ doesn't seem to work.''
|
||||
|
||||
[A24] The glibc NIS+ implementation uses a /var/nis/NIS_COLD_START
|
||||
file for storing information about the NIS+ server and their
|
||||
public keys, because the nis.conf file do not contain all
|
||||
necessary information. You have to copy a NIS_COLD_START file
|
||||
from a Solaris client (the NIS_COLD_START file is byte order
|
||||
independend) or generate it new with nisinit from the nis-tools
|
||||
(look at http://www-vt.uni-paderborn.de/~kukuk/linux/nisplus.html).
|
||||
|
||||
|
||||
~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~
|
||||
|
||||
Answers were given by:
|
||||
@@ -637,6 +700,7 @@ Answers were given by:
|
||||
{RM} Roland McGrath, <roland@gnu.ai.mit.edu>
|
||||
{HJL} H.J. Lu, <hjl@gnu.ai.mit.edu>
|
||||
{AJ} Andreas Jaeger, <aj@arthur.pfalz.de>
|
||||
{EY} Eric Youngdale, <eric@andante.jic.com>
|
||||
|
||||
Local Variables:
|
||||
mode:text
|
||||
|
||||
@@ -76,6 +76,23 @@ you run `configure':
|
||||
static library is compiled with no optimization and full debugging
|
||||
information, and installed as `-lc_g'.
|
||||
|
||||
`--enable-bounded'
|
||||
`--disable-bounded'
|
||||
Enable or disable building of the C library with support for bounded
|
||||
pointers. To do this one need the enhanced version of the GNU CC
|
||||
with can generate code for bounded pointers. This version of the
|
||||
C library is necessary to run code which is also compiled using the
|
||||
enhanced gcc for debugging purposes.
|
||||
|
||||
There are two more options:
|
||||
|
||||
`--with-gmp'
|
||||
`--with-gettext'
|
||||
These options are not of much use for the normal installer of the
|
||||
GNU libc. Only maintainers need this to get automatic updates of
|
||||
the files from these packages in the GNU C library source tree.
|
||||
|
||||
|
||||
The simplest way to run `configure' is to do it in the directory
|
||||
that contains the library sources. This prepares to build the library
|
||||
in that very directory.
|
||||
@@ -182,6 +199,9 @@ following patterns:
|
||||
iX86-ANYTHING-gnu
|
||||
iX86-ANYTHING-linux
|
||||
m68k-ANYTHING-linux
|
||||
mips-ANYTHING-linux
|
||||
sparc-ANYTHING-linux
|
||||
powerpc-ANYTHING-linux
|
||||
|
||||
Former versions of this library used to support the following
|
||||
configurations but the current status is unknown:
|
||||
@@ -208,7 +228,7 @@ configurations but the current status is unknown:
|
||||
sparc-sun-solaris2.N
|
||||
sparc-sun-sunos4.N
|
||||
|
||||
Each case of `iX86' can be `i386', `i486', `i586', or `i686'.. All
|
||||
Each case of `iX86' can be `i386', `i486', `i586', or `i686'. All
|
||||
of those configurations produce a library that can run on any of these
|
||||
processors. The library will be optimized for the specified processor,
|
||||
but will not use instructions not available on all of them.
|
||||
@@ -652,10 +672,10 @@ level of the `sysdeps' hierarchy. This directory contains
|
||||
subdirectories (and subdirectory trees) for various Unix variants.
|
||||
|
||||
The functions which are system calls in most Unix systems are
|
||||
implemented in assembly code in files in `sysdeps/unix'. These files
|
||||
are named with a suffix of `.S'; for example, `__open.S'. Files ending
|
||||
in `.S' are run through the C preprocessor before being fed to the
|
||||
assembler.
|
||||
automatically generated from the `syscalls.list' files for the appropriate
|
||||
archirecture. The format of the syscalls.list files is quite easy: only
|
||||
a few informations are necessary line the system call name, the number of
|
||||
arguments and such. The files are run through the C preprocessor.
|
||||
|
||||
These files all use a set of macros that should be defined in
|
||||
`sysdep.h'. The `sysdep.h' file in `sysdeps/unix' partially defines
|
||||
|
||||
@@ -142,10 +142,10 @@ ifdef subdir
|
||||
|
||||
foo:=$(shell echo subdir foo >&2)
|
||||
|
||||
+tsrcs := Makefile $(+tsrcs) \
|
||||
$(addsuffix .c,$(others) $(tests)) \
|
||||
$(wildcard $(addsuffix .input,$(tests)) \
|
||||
$(addsuffix .args,$(tests)))
|
||||
+tsrcs := Makefile $(+tsrcs) \
|
||||
$(addsuffix .c,$(others) $(tests) $(test-srcs)) \
|
||||
$(wildcard $(addsuffix .input,$(tests) $(test-srcs)) \
|
||||
$(addsuffix .args,$(tests) $(test-srcs)))
|
||||
+tardeps := $(strip $(+tsrcs))
|
||||
|
||||
verbose = v
|
||||
|
||||
@@ -87,8 +87,8 @@ sources += $(foreach lib,$(extra-libs),$($(lib)-routines:=.c))
|
||||
# Files that are found in the current directory cannot occur in
|
||||
# sysdep directories, so don't bother searching them.
|
||||
sysdep-sources := $(filter-out $(wildcard $(sources)), $(sources))
|
||||
all-sources = $(wildcard $(sort $(sources) $(sources:.c=.S) $(sources:.c=.s) \
|
||||
$(others:=.c) $(tests:=.c))) \
|
||||
all-sources = $(wildcard $(sort $(sources) $(sources:.c=.S) $(sources:.c=.s) \
|
||||
$(others:=.c) $(tests:=.c) $(test-srcs:=.c))) \
|
||||
$(foreach dir,$(all-dirs),\
|
||||
$(wildcard \
|
||||
$(addprefix $(dir)/,\
|
||||
|
||||
+27
-5
@@ -23,6 +23,8 @@ ifneq (,)
|
||||
This makefile requires GNU Make.
|
||||
endif
|
||||
|
||||
all: # Make this the default goal
|
||||
|
||||
ifneq "$(origin +included-Makeconfig)" "file"
|
||||
|
||||
+included-Makeconfig := yes
|
||||
@@ -239,7 +241,8 @@ endif
|
||||
# other than there, so the zoneinfo directory contains only universal data,
|
||||
# localizing the configuration data elsewhere.
|
||||
ifndef localtime-file
|
||||
localtime-file = $(inst_sysconfdir)/localtime
|
||||
localtime-file = $(sysconfdir)/localtime
|
||||
inst_localtime-file = $(install_root)$(localtime-file)
|
||||
endif
|
||||
|
||||
# What to use for leap second specifications in compiling the default
|
||||
@@ -319,10 +322,10 @@ endif
|
||||
ifndef +link
|
||||
+link = $(CC) -nostdlib -nostartfiles -o $@ \
|
||||
$(sysdep-LDFLAGS) $(config-LDFLAGS) $(LDFLAGS) \
|
||||
$(addprefix $(csu-objpfx),start.o) $(+preinit) \
|
||||
$(addprefix $(csu-objpfx),start.o) $(+preinit) $(+prector) \
|
||||
$(filter-out $(addprefix $(csu-objpfx),start.o) $(+preinit) \
|
||||
$(link-extra-libs) $(common-objpfx)libc% $(+postinit),$^) \
|
||||
$(link-extra-libs) $(link-libc) $(+postinit)
|
||||
$(link-extra-libs) $(link-libc) $(+postctor) $(+postinit)
|
||||
endif
|
||||
ifndef config-LDFLAGS
|
||||
ifeq (yes,$(build-shared))
|
||||
@@ -346,7 +349,8 @@ else
|
||||
default-rpath = $(libdir)
|
||||
endif
|
||||
# This is how to find at build-time things that will be installed there.
|
||||
rpath-link = $(common-objdir):$(elfobjdir):$(nssobjdir)
|
||||
rpath-link = $(common-objdir):$(mathobjdir):$(elfobjdir):$(nssobjdir)
|
||||
mathobjdir := $(patsubst ../$(subdir),.,$(common-objpfx)math)
|
||||
elfobjdir := $(patsubst ../$(subdir),.,$(common-objpfx)elf)
|
||||
nssobjdir := $(patsubst ../$(subdir),.,$(common-objpfx)nss)
|
||||
else
|
||||
@@ -355,7 +359,13 @@ endif
|
||||
endif
|
||||
ifndef link-extra-libs
|
||||
ifeq (yes,$(build-shared))
|
||||
ifneq ($(common-objpfx),$(objpfx))
|
||||
link-extra-libs = $(foreach lib,$(LDLIBS-$(@F)),\
|
||||
$(wildcard $(common-objpfx)$(lib).so$($(notdir $(lib)).so-version) \
|
||||
$(objpfx)$(lib).so$($(notdir $(lib)).so-version)))
|
||||
else
|
||||
link-extra-libs = $(foreach lib,$(LDLIBS-$(@F)),$(common-objpfx)$(lib).so$($(notdir $(lib)).so-version))
|
||||
endif
|
||||
else
|
||||
link-extra-libs = $(foreach lib,$(LDLIBS-$(@F)),$(common-objpfx)$(lib).a)
|
||||
endif
|
||||
@@ -366,6 +376,8 @@ endif
|
||||
ifeq ($(elf),yes)
|
||||
+preinit = $(addprefix $(csu-objpfx),crti.o)
|
||||
+postinit = $(addprefix $(csu-objpfx),crtn.o)
|
||||
+prector = `$(CC) --print-file-name=crtbegin.o`
|
||||
+postctor = `$(CC) --print-file-name=crtend.o`
|
||||
endif
|
||||
csu-objpfx = $(common-objpfx)csu/
|
||||
elf-objpfx = $(common-objpfx)elf/
|
||||
@@ -481,6 +493,7 @@ endif
|
||||
# to pass different flags for each flavor.
|
||||
libtypes = $(foreach o,$(object-suffixes),$(libtype$o))
|
||||
object-suffixes := .o
|
||||
all-object-suffixes := .o .so .po .go .bo
|
||||
libtype.o := lib%.a
|
||||
ifeq (yes,$(build-shared))
|
||||
# Under --enable-shared, we will build a shared library of PIC objects.
|
||||
@@ -508,6 +521,14 @@ CFLAGS-.o = -g0 -O99 -fomit-frame-pointer
|
||||
CFLAGS-.so += $(CFLAGS-.o)
|
||||
libtype.go = lib%_g.a
|
||||
endif
|
||||
ifeq (yes,$(build-bounded))
|
||||
# Under --enable-bounded, we build the library with `-fbounded-pointers -g'
|
||||
# to runtime bounds checking. The bounded-pointer objects are named foo.bo.
|
||||
object-suffixes += .bo
|
||||
CPPFLAGS-.bo = -DBOUNDED_POINTERS
|
||||
CFLAGS-.bo = -g -fbounded-pointers
|
||||
libtype.bo = lib%_b.a
|
||||
endif
|
||||
|
||||
|
||||
+gnu-stabs = $(shell echo>&2 '*** BARF ON ME')
|
||||
@@ -582,7 +603,8 @@ $(common-objpfx)gnu/lib-names.stmp: $(common-objpfx)soversions.mk
|
||||
(libs='$(all-sonames)';\
|
||||
for l in $$libs; do \
|
||||
upname=`echo $$l | sed 's/[.]so.*//' | \
|
||||
tr '[:lower:]-' '[:upper:]_'`; \
|
||||
tr 'abcdefghijklmnopqrstuvwxyz-' \
|
||||
'ABCDEFGHIJKLMNOPQRSTUVWXYZ_'`; \
|
||||
echo "#define $${upname}_SO \"$$l\""; \
|
||||
done;) | sort; \
|
||||
echo; \
|
||||
|
||||
@@ -54,7 +54,7 @@ endif
|
||||
subdirs = csu assert ctype db locale intl catgets math setjmp signal stdlib \
|
||||
stdio-common $(stdio) malloc string wcsmbs time dirent grp pwd \
|
||||
posix io termios resource misc login socket sysvipc gmon gnulib \
|
||||
wctype manual shadow md5-crypt nss $(sysdep-subdirs) po \
|
||||
wctype manual shadow md5-crypt nss $(sysdep-subdirs) po argp \
|
||||
$(add-ons) elf
|
||||
export subdirs := $(subdirs) # Benign, useless in GNU make before 3.63.
|
||||
|
||||
@@ -85,7 +85,7 @@ subdirs := $(filter mach,$(subdirs)) $(filter hurd,$(subdirs)) \
|
||||
headers := errno.h sys/errno.h errnos.h limits.h values.h \
|
||||
features.h gnu-versions.h libc-lock.h xopen_lim.h
|
||||
aux = sysdep $(libc-init) version
|
||||
before-compile = $(objpfx)version-info.h
|
||||
before-compile += $(objpfx)version-info.h
|
||||
|
||||
echo-headers: subdir_echo-headers
|
||||
|
||||
@@ -94,7 +94,6 @@ install-others = $(inst_includedir)/gnu/stubs.h
|
||||
install-bin = glibcbug
|
||||
|
||||
ifeq (yes,$(build-shared))
|
||||
before-compile += $(objpfx)gnu/lib-names.h
|
||||
install-others += $(inst_includedir)/gnu/lib-names.h
|
||||
endif
|
||||
|
||||
@@ -115,10 +114,11 @@ include Makerules
|
||||
install: subdir_install
|
||||
|
||||
# Create linkfs for shared libraries using the `ldconfig' program is possible.
|
||||
# Ignore the error if we cannot update /etc/ld.so.cache.
|
||||
ifeq (no,$(cross-compiling))
|
||||
ifeq (yes,$(build-shared))
|
||||
install:
|
||||
test ! -x $(common-objpfx)elf/ldconfig || \
|
||||
-test ! -x $(common-objpfx)elf/ldconfig || \
|
||||
$(common-objpfx)elf/ldconfig -d $(inst_slibdir) $(inst_libdir)
|
||||
endif
|
||||
endif
|
||||
@@ -131,6 +131,9 @@ ifeq (yes,$(build-shared))
|
||||
lib: $(common-objpfx)libc.so
|
||||
endif
|
||||
|
||||
# We have a versioning file for libc.so.
|
||||
#libc-map = libc.map
|
||||
|
||||
all-Subdirs-files = $(wildcard $(addsuffix /Subdirs, $(config-sysdirs)))
|
||||
$(objpfx)sysd-dirs: $(+sysdir_pfx)config.make $(all-Subdirs-files)
|
||||
(echo define sysdep-subdirs; \
|
||||
@@ -277,19 +280,28 @@ parent_echo-distinfo:
|
||||
$(addprefix +nodist+,$(generated))
|
||||
|
||||
|
||||
.PHONY: parent-tests
|
||||
tests: parent-tests
|
||||
|
||||
# Run a test on the header files we use.
|
||||
parent-tests: $(objpfx)isomac
|
||||
$(dir $<)$(notdir $<) '$(CC)' '$(+sysdep-includes)' > $<.out
|
||||
|
||||
$(objpfx)isomac: isomac.c
|
||||
$(native-compile)
|
||||
|
||||
# Make the distribution tarfile.
|
||||
|
||||
distribute := README INSTALL FAQ NOTES NEWS PROJECTS \
|
||||
distribute := README INSTALL FAQ NOTES NEWS PROJECTS BUGS \
|
||||
COPYING.LIB COPYING ChangeLog ChangeLog.[0-9] \
|
||||
Makefile Makeconfig Makerules Rules Make-dist MakeTAGS \
|
||||
extra-lib.mk o-iterator.mk \
|
||||
extra-lib.mk o-iterator.mk isomac.c \
|
||||
ansidecl.h mkinstalldirs move-if-change install-sh \
|
||||
configure configure.in aclocal.m4 config.sub config.guess\
|
||||
config.h.in config.make.in config-name.in Makefile.in \
|
||||
autolock.sh rellns-sh munch-tmpl.c munch.awk interp.c \
|
||||
sysdep.h set-hooks.h libc-symbols.h version.h shlib-versions \
|
||||
rpm/Makefile rpm/template rpm/rpmrc nsswitch.h netgroup.h \
|
||||
mcheck.h glibcbug.in
|
||||
rpm/Makefile rpm/template rpm/rpmrc glibcbug.in
|
||||
|
||||
distribute := $(strip $(distribute))
|
||||
generated := $(generated) stubs.h version-info.h
|
||||
@@ -303,6 +315,8 @@ makeinfo --no-validate --no-warn --no-headers $< -o $@
|
||||
endef
|
||||
INSTALL: manual/maint.texi; $(format-me)
|
||||
NOTES: manual/creature.texi; $(format-me)
|
||||
manual/dir-add.texi:
|
||||
$(MAKE) $(PARALLELMFLAGS) -C $(@D) $(@F)
|
||||
|
||||
rpm/%: subdir_distinfo
|
||||
$(MAKE) $(PARALLELMFLAGS) -C $(@D) subdirs='$(subdirs)' $(@F)
|
||||
|
||||
@@ -80,6 +80,12 @@ ar-symtab-name = __.SYMDEF
|
||||
else
|
||||
ar-symtab-name = # The null name is used in ELF archives.
|
||||
endif
|
||||
|
||||
# This variable is used in ``include $(o-iterator)'' after defining
|
||||
# $(o-iterator-doit) to produce some desired rule using $o for the object
|
||||
# suffix, and setting $(object-suffixes-left) to $(object-suffixes); a copy
|
||||
# is produced for each object suffix in use.
|
||||
o-iterator = $(patsubst %,$(..)o-iterator.mk,$(object-suffixes-left))
|
||||
|
||||
# Include any system-specific makefiles.
|
||||
|
||||
@@ -167,20 +173,25 @@ $(common-objpfx)dummy.d:
|
||||
# generated sysdep rules in included from sysd-rules below. When
|
||||
# compiling in the source tree, generated sources go into the current
|
||||
# directory, and those should be chosen before any sources in sysdeps.
|
||||
$(objpfx)%.o: %.S $(before-compile); $(compile-command.S)
|
||||
$(objpfx)%.so: %.S $(before-compile); $(compile-command.S)
|
||||
$(objpfx)%.po: %.S $(before-compile); $(compile-command.S)
|
||||
$(objpfx)%.go: %.S $(before-compile); $(compile-command.S)
|
||||
define o-iterator-doit
|
||||
$(objpfx)%$o: %.S $(before-compile); $$(compile-command.S)
|
||||
endef
|
||||
object-suffixes-left := $(object-suffixes)
|
||||
include $(o-iterator)
|
||||
$(objpfx)%.d: %.S $(before-compile); $(+make-deps)
|
||||
$(objpfx)%.o: %.s $(before-compile); $(compile-command.s)
|
||||
$(objpfx)%.so: %.s $(before-compile); $(compile-command.s)
|
||||
$(objpfx)%.po: %.s $(before-compile); $(compile-command.s)
|
||||
$(objpfx)%.go: %.s $(before-compile); $(compile-command.s)
|
||||
|
||||
define o-iterator-doit
|
||||
$(objpfx)%$o: %.s $(before-compile); $$(compile-command.s)
|
||||
endef
|
||||
object-suffixes-left := $(object-suffixes)
|
||||
include $(o-iterator)
|
||||
$(objpfx)%.d: %.s $(common-objpfx)dummy.d; $(make-dummy-dep)
|
||||
$(objpfx)%.o: %.c $(before-compile); $(compile-command.c)
|
||||
$(objpfx)%.so: %.c $(before-compile); $(compile-command.c)
|
||||
$(objpfx)%.po: %.c $(before-compile); $(compile-command.c)
|
||||
$(objpfx)%.go: %.c $(before-compile); $(compile-command.c)
|
||||
|
||||
define o-iterator-doit
|
||||
$(objpfx)%$o: %.c $(before-compile); $$(compile-command.c)
|
||||
endef
|
||||
object-suffixes-left := $(object-suffixes)
|
||||
include $(o-iterator)
|
||||
$(objpfx)%.d: %.c $(before-compile); $(+make-deps)
|
||||
|
||||
# Omit the objpfx rules when building in the source tree, because
|
||||
@@ -188,20 +199,25 @@ $(objpfx)%.d: %.c $(before-compile); $(+make-deps)
|
||||
ifdef objpfx
|
||||
# Define first rules to find the source files in $(objpfx).
|
||||
# Generated source files will end up there.
|
||||
$(objpfx)%.o: $(objpfx)%.S $(before-compile); $(compile-command.S)
|
||||
$(objpfx)%.so: $(objpfx)%.S $(before-compile); $(compile-command.S)
|
||||
$(objpfx)%.po: $(objpfx)%.S $(before-compile); $(compile-command.S)
|
||||
$(objpfx)%.go: $(objpfx)%.S $(before-compile); $(compile-command.S)
|
||||
define o-iterator-doit
|
||||
$(objpfx)%$o: $(objpfx)%.S $(before-compile); $$(compile-command.S)
|
||||
endef
|
||||
object-suffixes-left := $(object-suffixes)
|
||||
include $(o-iterator)
|
||||
$(objpfx)%.d: $(objpfx)%.S $(before-compile); $(+make-deps)
|
||||
$(objpfx)%.o: $(objpfx)%.s $(before-compile); $(compile-command.s)
|
||||
$(objpfx)%.so: $(objpfx)%.s $(before-compile); $(compile-command.s)
|
||||
$(objpfx)%.po: $(objpfx)%.s $(before-compile); $(compile-command.s)
|
||||
$(objpfx)%.go: $(objpfx)%.s $(before-compile); $(compile-command.s)
|
||||
|
||||
define o-iterator-doit
|
||||
$(objpfx)%$o: $(objpfx)%.s $(before-compile); $$(compile-command.s)
|
||||
endef
|
||||
object-suffixes-left := $(object-suffixes)
|
||||
include $(o-iterator)
|
||||
$(objpfx)%.d: $(objpfx)%.s $(common-objpfx)dummy.d; $(make-dummy-dep)
|
||||
$(objpfx)%.o: $(objpfx)%.c $(before-compile); $(compile-command.c)
|
||||
$(objpfx)%.so: $(objpfx)%.c $(before-compile); $(compile-command.c)
|
||||
$(objpfx)%.po: $(objpfx)%.c $(before-compile); $(compile-command.c)
|
||||
$(objpfx)%.go: $(objpfx)%.c $(before-compile); $(compile-command.c)
|
||||
|
||||
define o-iterator-doit
|
||||
$(objpfx)%$o: $(objpfx)%.c $(before-compile); $$(compile-command.c)
|
||||
endef
|
||||
object-suffixes-left := $(object-suffixes)
|
||||
include $(o-iterator)
|
||||
$(objpfx)%.d: $(objpfx)%.c $(before-compile); $(+make-deps)
|
||||
endif
|
||||
|
||||
@@ -238,7 +254,7 @@ $(+sysdir_pfx)sysd-rules: $(+sysdir_pfx)config.make $(..)Makerules \
|
||||
/*) dir=$$sysdir ;; \
|
||||
*) dir="\$$(..)$$sysdir" ;; \
|
||||
esac; \
|
||||
for o in $(object-suffixes); do \
|
||||
for o in $(all-object-suffixes); do \
|
||||
$(open-check-inhibit-asm) \
|
||||
echo "\$$(objpfx)%$$o: $$dir/%.S \$$(before-compile); \
|
||||
\$$(compile-command.S)"; \
|
||||
@@ -278,8 +294,10 @@ endif
|
||||
|
||||
# GCC can grok options after the file name, and it looks nicer that way.
|
||||
compile.c = $(CC) $< -c $(CFLAGS) $(CPPFLAGS)
|
||||
compile.S = $(CC) $< -c $(CPPFLAGS) -DASSEMBLER $(asm-CPPFLAGS)
|
||||
COMPILE.S = $(CC) -c $(CPPFLAGS) -DASSEMBLER $(asm-CPPFLAGS)
|
||||
compile.S = \
|
||||
$(CC) $< -c $(CPPFLAGS) -DASSEMBLER $(asm-CPPFLAGS) $(ASFLAGS-$(suffix $@))
|
||||
COMPILE.S = \
|
||||
$(CC) -c $(CPPFLAGS) -DASSEMBLER $(asm-CPPFLAGS) $(ASFLAGS-$(suffix $@))
|
||||
COMPILE.s = $(filter-out -pipe,$(CC)) -c $(ASFLAGS)
|
||||
|
||||
# We need this for the output to go in the right place. It will default to
|
||||
@@ -292,7 +310,8 @@ define +make-deps
|
||||
$(make-target-directory)
|
||||
-@rm -f $@
|
||||
$(+mkdep) $< $(CPPFLAGS) $($(<:$*.%=%)-CPPFLAGS) | \
|
||||
sed -e 's,$(subst .,\.,$*)\.o,$(foreach o,$(object-suffixes),$(@:.d=$o)) $@,' \
|
||||
sed \
|
||||
-e 's,$(subst .,\.,$*)\.o,$(foreach o,$(all-object-suffixes),$(@:.d=$o)) $@,' \
|
||||
$(sed-remove-objpfx) > $(@:.d=.T)
|
||||
mv -f $(@:.d=.T) $@
|
||||
endef
|
||||
@@ -321,6 +340,12 @@ else
|
||||
no-whole-archive =
|
||||
endif
|
||||
|
||||
ifeq ($(versioning),yes)
|
||||
load-map-file = $($(@F:%.so=%)-map:%=-Wl,--version-script=%)
|
||||
else
|
||||
load-map-file =
|
||||
endif
|
||||
|
||||
interp-obj = $(common-objpfx)interp.so
|
||||
$(interp-obj): $(common-objpfx)%.so: $(..)%.c
|
||||
$(compile-command.c)
|
||||
@@ -332,12 +357,14 @@ $(patsubst %,$(objpfx)%.so,$(extra-libs)): $(interp-obj)
|
||||
|
||||
define build-shlib
|
||||
$(LINK.o) -shared -o $@ $(sysdep-LDFLAGS) $(config-LDFLAGS) \
|
||||
-B$(csu-objpfx) \
|
||||
-B$(csu-objpfx) $(load-map-file) \
|
||||
-Wl,-soname=lib$(libprefix)$(@F:lib%.so=%).so$($(@F)-version) \
|
||||
$(LDFLAGS.so) $(LDFLAGS-$(@F:lib%.so=%).so) \
|
||||
-L$(subst :, -L,$(rpath-link)) -Wl,-rpath-link=$(rpath-link) \
|
||||
-Wl,--whole-archive $^ $(no-whole-archive) \
|
||||
$(LDLIBS-$(@F:lib%.so=%).so)
|
||||
test -z "$($(@F)-version)" || \
|
||||
(rm -f $@$($(@F)-version); $(LN_S) $(@F) $@$($(@F)-version))
|
||||
endef
|
||||
|
||||
# Don't try to use -lc when making libc.so itself.
|
||||
@@ -353,12 +380,6 @@ $(common-objpfx)libc.so: $(elfobjdir)/soinit.so \
|
||||
$(common-objpfx)libc_pic.a \
|
||||
$(elfobjdir)/sofini.so $(elfobjdir)/ld.so
|
||||
$(build-shlib)
|
||||
|
||||
ifdef libc.so-version
|
||||
$(common-objpfx)libc.so$(libc.so-version): $(common-objpfx)libc.so
|
||||
rm -f $@
|
||||
ln -s $(<F) $@ || ln $< $@
|
||||
endif
|
||||
endif
|
||||
|
||||
# Some files must not be compiled with the exception handler mechanism
|
||||
@@ -384,12 +405,6 @@ headers := $(headers) $(sysdep_headers)
|
||||
override objects := $(addprefix $(objpfx),$(sources:.c=.o))
|
||||
|
||||
|
||||
# This variable is used in ``include $(o-iterator)'' after defining
|
||||
# $(o-iterator-doit) to produce some desired rule using $o for the object
|
||||
# suffix, and setting $(object-suffixes-left) to $(object-suffixes); a copy
|
||||
# is produced for each object suffix in use.
|
||||
o-iterator = $(patsubst %,$(..)o-iterator.mk,$(object-suffixes-left))
|
||||
|
||||
# The makefile may define $(extra-libs) with `libfoo libbar'
|
||||
# to build libfoo.a et al from the modules listed in $(libfoo-routines).
|
||||
ifdef extra-libs
|
||||
@@ -798,19 +813,23 @@ install: install-no-libc.a-nosubdir
|
||||
|
||||
# Command to compile $< in $(objdir) using the native libraries.
|
||||
define native-compile
|
||||
cwd=`pwd`; cd $(@D); $(BUILD_CC) $(BUILD_CFLAGS) \
|
||||
$(addprefix $$cwd/,$^) -o $(@F)
|
||||
$(make-target-directory)
|
||||
$(patsubst %/,cd %;,$(objpfx)) \
|
||||
$(BUILD_CC) $($(basename $(<F))-CFLAGS) $(ALL_BUILD_CFLAGS) \
|
||||
$(firstword $(filter /%,$< $(shell pwd)/$<)) -o $(@F)
|
||||
endef
|
||||
|
||||
# Command to compile $< in $(common-objdir) using the native libraries.
|
||||
# We must cd to $(objdir) anyway so that $(..)config.h is valid.
|
||||
define common-objdir-compile
|
||||
cd $(objpfx).; \
|
||||
$(BUILD_CC) $(BUILD_CFLAGS) $(<:$(common-objpfx)%=$(..)%) -o $(..)$(@F)
|
||||
$(patsubst %/,cd %;,$(objpfx)) \
|
||||
$(BUILD_CC) $($(basename $(<F))-CFLAGS) $(ALL_BUILD_CFLAGS) \
|
||||
$(firstword $(filter /%,$< $(shell pwd)/$<)) -o $(..)$(@F)
|
||||
endef
|
||||
|
||||
# We always want to use configuration definitions.
|
||||
BUILD_CFLAGS = -include $(..)config.h
|
||||
# Note that this is only used for commands running in $(objpfx).
|
||||
ALL_BUILD_CFLAGS = $(BUILD_CFLAGS) -include $(..)config.h
|
||||
|
||||
# Support the GNU standard name for this target.
|
||||
.PHONY: check
|
||||
@@ -838,9 +857,10 @@ mostlyclean: common-mostlyclean
|
||||
|
||||
# Remove the object files.
|
||||
common-mostlyclean:
|
||||
-rm -f $(addprefix $(objpfx),$(tests) $(others) \
|
||||
$(addsuffix .o,$(tests) $(others)) \
|
||||
$(addsuffix .out,$(tests)))
|
||||
-rm -f $(addprefix $(objpfx),$(tests) $(test-srcs) $(others) \
|
||||
$(addsuffix .o,$(tests) $(test-srcs) \
|
||||
$(others)) \
|
||||
$(addsuffix .out,$(tests) $(test-srcs)))
|
||||
-rm -f $(addprefix $(objpfx),$(extra-objs) $(install-lib))
|
||||
-rm -f core $(common-objpfx)stub-$(subdir)
|
||||
$(rmobjs)
|
||||
@@ -888,7 +908,9 @@ dist: $(filter-out %.c %.S %.s,$(distribute))
|
||||
# environment get too large. Instead, we write all the information into
|
||||
# a generated makefile fragment `distinfo', and then include it with -f in
|
||||
# the sub-make that makes the distribution (above).
|
||||
$(common-objpfx)distinfo-$(subdir): Makefile $(..)Makerules
|
||||
$(common-objpfx)distinfo-$(subdir): Makefile $(..)Makerules \
|
||||
$(wildcard $(foreach dir,$(sysdirs),\
|
||||
$(dir)/Makefile))
|
||||
$(distinfo-vars)
|
||||
mv -f $@.new $@
|
||||
.PHONY: subdir_distinfo distinfo
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
GNU C Library NEWS -- history of user-visible changes. 26 January 1997
|
||||
GNU C Library NEWS -- history of user-visible changes. 1997-03-18
|
||||
|
||||
Copyright (C) 1992, 93, 94, 95, 96, 97 Free Software Foundation, Inc.
|
||||
See the end for copying conditions.
|
||||
@@ -7,6 +7,57 @@ Please send GNU C library bug reports using the `glibcbug' script to
|
||||
<bugs@gnu.ai.mit.edu>. Questions and suggestions should be send to
|
||||
<bug-glibc@prep.ai.mit.edu>.
|
||||
|
||||
Version 2.1
|
||||
|
||||
* An additional locale model to support C++ Standard Library locale
|
||||
model and probably more was implemented by Ulrich Drepper.
|
||||
|
||||
* Eric Youngdale and Ulrich Drepper implemented versioning of objects on
|
||||
symbol level.
|
||||
|
||||
* Miles Bader provided the `argp' function family to support hierachical
|
||||
command line argument parsing, layered on top of getopt.
|
||||
|
||||
* strtod accepts new hexadecimal floating-point format from ISO C 9X
|
||||
|
||||
* printf has two new specifiers %a and %A to print hexadecimal flaoting-point
|
||||
numbers
|
||||
|
||||
* scanf recognizes the %A format for scanning floating point numbers
|
||||
|
||||
* the new header <inttypes.h> from ISO C 9X provides information and
|
||||
interfaces for the available integer types
|
||||
|
||||
* the new header <complex.h> contains definitions of the complex math
|
||||
functions from ISO C 9X
|
||||
|
||||
* Thorsten Kukuk provided an implementation for NIS+, securelevel 0 and 1.
|
||||
The implementation for securelevel 2 will follow as soon as the Diffie-
|
||||
Hellman patent expired.
|
||||
|
||||
* Andreas Jaeger provided a test suite for the math library
|
||||
|
||||
Version 2.0.2
|
||||
|
||||
* more bug fixes
|
||||
|
||||
* add atoll function
|
||||
|
||||
* fix complex problems in Berkeley DB code
|
||||
|
||||
* fix math functions
|
||||
|
||||
Version 2.0.1
|
||||
|
||||
* fixed lots of header problems (especially Linux/GNU specific)
|
||||
|
||||
* dynamic loader preserves all registers
|
||||
|
||||
* Roland McGrath provided support for handling of auxiliary objects in
|
||||
the ELF dynamic loader.
|
||||
|
||||
* support for parallel builds is improved
|
||||
|
||||
Version 2.0
|
||||
|
||||
* GNU extensions are no longer declared by default. To enable them you
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
Open jobs for finishing GNU libc:
|
||||
---------------------------------
|
||||
Status: January 1997
|
||||
Status: April 1997
|
||||
|
||||
If you have time and talent to take over any of the jobs below please
|
||||
contact <bug-glibc@prep.ai.mit.edu>
|
||||
@@ -19,7 +19,16 @@ contact <bug-glibc@prep.ai.mit.edu>
|
||||
standards if they do not contradict each other.
|
||||
|
||||
|
||||
[ 3] Write translations for the GNU libc message for the so far
|
||||
[ 3] The IMHO opinion most important task is to write a more complete
|
||||
test suite. We cannot get too many people working on this. It is
|
||||
not difficult to write a test, find a definition of the function
|
||||
which I normally can provide, if necessary, and start writing tests
|
||||
to test for compliance. Beside this, take a look at the sources
|
||||
and write tests which in total test as many paths of execution as
|
||||
possible.
|
||||
|
||||
|
||||
[ 4] Write translations for the GNU libc message for the so far
|
||||
unsupported languages. GNU libc is fully internationalized and
|
||||
users can immediately benefit from this.
|
||||
|
||||
@@ -28,7 +37,7 @@ contact <bug-glibc@prep.ai.mit.edu>
|
||||
for the current status (of course better use a mirror of prep).
|
||||
|
||||
|
||||
[ 4] Write wordexp() function; this is described in POSIX.2, the
|
||||
[ 5] Write wordexp() function; this is described in POSIX.2, the
|
||||
header <wordexp.h> already exists.
|
||||
|
||||
Implementation idea: use some functions from bash.
|
||||
@@ -36,7 +45,7 @@ contact <bug-glibc@prep.ai.mit.edu>
|
||||
**** Somebody is working on this. Help may or may not be appreciated.
|
||||
|
||||
|
||||
[ 5] Write `long double' versions of the math functions. This should be
|
||||
[ 6] Write `long double' versions of the math functions. This should be
|
||||
done in collaboration with the NetBSD and FreeBSD people.
|
||||
|
||||
The libm is in fact fdlibm (not the same as in Linux libc).
|
||||
@@ -45,7 +54,18 @@ contact <bug-glibc@prep.ai.mit.edu>
|
||||
the rest.
|
||||
|
||||
|
||||
[ 6] If you enjoy assembler programming (as I do --drepper :-) you might
|
||||
[ 7] Several math functions have to be written:
|
||||
|
||||
- exp2
|
||||
|
||||
each with float, double, and long double arguments.
|
||||
|
||||
Beside this most of the complex math functions which are new in
|
||||
ISO C 9X should be improved. Writing some of them in assembler is
|
||||
useful to exploit the parallelism which often is available.
|
||||
|
||||
|
||||
[ 8] If you enjoy assembler programming (as I do --drepper :-) you might
|
||||
be interested in writing optimized versions for some functions.
|
||||
Especially the string handling functions can be optimized a lot.
|
||||
|
||||
@@ -60,42 +80,55 @@ contact <bug-glibc@prep.ai.mit.edu>
|
||||
work.
|
||||
|
||||
|
||||
[ 7] Write nftw() function. Perhaps it might be good to reimplement the
|
||||
[ 9] Write nftw() function. Perhaps it might be good to reimplement the
|
||||
ftw() function as well to share most of the code.
|
||||
|
||||
**** Almost done!
|
||||
|
||||
|
||||
[ 8] Write AVL-tree based tsearch() et.al. functions. Currently only
|
||||
a very simple algorithm is used.
|
||||
There is a public domain version but using this would cause problems
|
||||
with the assignment.
|
||||
|
||||
|
||||
[ 9] Extend regex and/or rx to work with wide characters and complete
|
||||
[10] Extend regex and/or rx to work with wide characters and complete
|
||||
implementation of character class and collation class handling.
|
||||
|
||||
It is planed to do a complete rewrite.
|
||||
|
||||
|
||||
[10] Write access function for netmasks, bootparams, and automount
|
||||
[11] Write access function for netmasks, bootparams, and automount
|
||||
databases for nss_files and nss_db module.
|
||||
The functions should be embedded in the nss scheme. This is not
|
||||
hard and not all services must be supported at once.
|
||||
|
||||
|
||||
[11] Rewrite utmp/wtmp functions to use database functions. This is much
|
||||
[12] Rewrite utmp/wtmp functions to use database functions. This is much
|
||||
better than the normal flat file format.
|
||||
|
||||
**** There are plans for a new approach to this problem. Please contact
|
||||
bug-glibc@prep.ai.mit.edu before starting to work.)
|
||||
|
||||
|
||||
[12] Several more or less small functions have to be written:
|
||||
[13] Several more or less small functions have to be written:
|
||||
|
||||
+ tcgetid() and waitid() from XPG4.2
|
||||
+ grantpt(), ptsname(), unlockpt() from XPG4.2
|
||||
+ getdate() from XPG4.2
|
||||
*** Probably underway
|
||||
+ fmtmsg() from SVID
|
||||
*** Probably underway
|
||||
|
||||
More information are available on request.
|
||||
|
||||
|
||||
[14] We need to write a library for on-the-fly transformation of streams
|
||||
of text. In fact, this would be a recode-library (you know, GNU recode).
|
||||
This is needed in several places in the GNU libc and I already have
|
||||
rather concrete plans but so far no possibility to start this.
|
||||
|
||||
|
||||
[15] Cleaning up the header files. Ideally, each header style should
|
||||
follow the "good examples". Each variable and function should have
|
||||
a short description of the function and its parameters. The prototypes
|
||||
should always contain variable names which can help to identify their
|
||||
meaning; better than
|
||||
|
||||
int foo __P ((int, int, int, int));
|
||||
|
||||
Blargh!
|
||||
|
||||
@@ -83,19 +83,19 @@ common-generated := $(common-generated) dummy.o dummy.c empty.c empty.o
|
||||
.PHONY: others tests
|
||||
others: $(addprefix $(objpfx),$(others) $(extra-objs))
|
||||
ifeq ($(cross-compiling),yes)
|
||||
tests: $(addprefix $(objpfx),$(tests))
|
||||
tests: $(addprefix $(objpfx),$(tests) $(test-srcs))
|
||||
else
|
||||
tests: $(tests:%=$(objpfx)%.out)
|
||||
endif
|
||||
|
||||
ifneq "$(strip $(others) $(tests))" ""
|
||||
$(addprefix $(objpfx),$(others) $(tests)): %: %.o \
|
||||
ifneq "$(strip $(others) $(tests) $(test-srcs))" ""
|
||||
$(addprefix $(objpfx),$(others) $(tests) $(test-srcs)): %: %.o \
|
||||
$(sort $(filter $(common-objpfx)libc%,$(link-libc))) \
|
||||
$(addprefix $(csu-objpfx),start.o) $(+preinit) $(+postinit)
|
||||
$(+link)
|
||||
endif
|
||||
|
||||
ifneq "$(strip $(tests))" ""
|
||||
ifneq "$(strip $(tests) $(test-srcs))" ""
|
||||
# These are the implicit rules for making test outputs
|
||||
# from the test programs and whatever input files are present.
|
||||
$(objpfx)%.out: %.args $(objpfx)% %.input
|
||||
|
||||
@@ -0,0 +1,31 @@
|
||||
# Copyright (C) 1997 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.
|
||||
|
||||
#
|
||||
# Makefile for argp.
|
||||
#
|
||||
subdir := argp
|
||||
|
||||
headers = argp.h
|
||||
distribute = argp-fmtstream.h argp-namefrob.h
|
||||
routines = $(addprefix argp-, ba fmtstream fs-xinl help parse pv \
|
||||
pvh xinl eexst)
|
||||
|
||||
tests = argp-test
|
||||
|
||||
include ../Rules
|
||||
@@ -0,0 +1,26 @@
|
||||
/* Default definition for ARGP_PROGRAM_BUG_ADDRESS.
|
||||
Copyright (C) 1996, 1997 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
Written by Miles Bader <miles@gnu.ai.mit.edu>.
|
||||
|
||||
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. */
|
||||
|
||||
/* If set by the user program, it should point to string that is the
|
||||
bug-reporting address for the program. It will be printed by argp_help if
|
||||
the ARGP_HELP_BUG_ADDR flag is set (as it is by various standard help
|
||||
messages), embedded in a sentence that says something like `Report bugs to
|
||||
ADDR.'. */
|
||||
const char *argp_program_bug_address = 0;
|
||||
@@ -0,0 +1,29 @@
|
||||
/* Default definition for ARGP_ERR_EXIT_STATUS
|
||||
Copyright (C) 1997 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
Written by Miles Bader <miles@gnu.ai.mit.edu>.
|
||||
|
||||
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. */
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <config.h>
|
||||
#endif
|
||||
|
||||
#include "argp.h"
|
||||
|
||||
/* The exit status that argp will use when exiting due to a parsing error.
|
||||
If not defined or set by the user program, this defaults to 1. */
|
||||
error_t argp_err_exit_status = 1;
|
||||
@@ -0,0 +1,382 @@
|
||||
/* Word-wrapping and line-truncating streams
|
||||
Copyright (C) 1997 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
Written by Miles Bader <miles@gnu.ai.mit.edu>.
|
||||
|
||||
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. */
|
||||
|
||||
/* This package emulates glibc `line_wrap_stream' semantics for systems that
|
||||
don't have that. */
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <config.h>
|
||||
#endif
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <stdarg.h>
|
||||
#include <ctype.h>
|
||||
|
||||
#include "argp-fmtstream.h"
|
||||
#include "argp-namefrob.h"
|
||||
|
||||
#ifndef ARGP_FMTSTREAM_USE_LINEWRAP
|
||||
|
||||
#ifndef isblank
|
||||
#define isblank(ch) ((ch)==' ' || (ch)=='\t')
|
||||
#endif
|
||||
|
||||
#define INIT_BUF_SIZE 200
|
||||
#define PRINTF_SIZE_GUESS 150
|
||||
|
||||
/* Return an argp_fmtstream that outputs to STREAM, and which prefixes lines
|
||||
written on it with LMARGIN spaces and limits them to RMARGIN columns
|
||||
total. If WMARGIN >= 0, words that extend past RMARGIN are wrapped by
|
||||
replacing the whitespace before them with a newline and WMARGIN spaces.
|
||||
Otherwise, chars beyond RMARGIN are simply dropped until a newline.
|
||||
Returns NULL if there was an error. */
|
||||
argp_fmtstream_t
|
||||
__argp_make_fmtstream (FILE *stream,
|
||||
size_t lmargin, size_t rmargin, ssize_t wmargin)
|
||||
{
|
||||
argp_fmtstream_t fs = malloc (sizeof (struct argp_fmtstream));
|
||||
if (fs)
|
||||
{
|
||||
fs->stream = stream;
|
||||
|
||||
fs->lmargin = lmargin;
|
||||
fs->rmargin = rmargin;
|
||||
fs->wmargin = wmargin;
|
||||
fs->point_col = 0;
|
||||
fs->point_offs = 0;
|
||||
|
||||
fs->buf = malloc (INIT_BUF_SIZE);
|
||||
if (! fs->buf)
|
||||
{
|
||||
free (fs);
|
||||
fs = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
fs->p = fs->buf;
|
||||
fs->end = fs->buf + INIT_BUF_SIZE;
|
||||
}
|
||||
}
|
||||
|
||||
return fs;
|
||||
}
|
||||
#ifdef weak_alias
|
||||
weak_alias (__argp_make_fmtstream, argp_make_fmtstream)
|
||||
#endif
|
||||
|
||||
/* Flush FS to its stream, and free it (but don't close the stream). */
|
||||
void
|
||||
__argp_fmtstream_free (argp_fmtstream_t fs)
|
||||
{
|
||||
__argp_fmtstream_update (fs);
|
||||
if (fs->p > fs->buf)
|
||||
fwrite (fs->buf, 1, fs->p - fs->buf, fs->stream);
|
||||
free (fs->buf);
|
||||
free (fs);
|
||||
}
|
||||
#ifdef weak_alias
|
||||
weak_alias (__argp_fmtstream_free, argp_fmtstream_free)
|
||||
#endif
|
||||
|
||||
/* Process FS's buffer so that line wrapping is done from POINT_OFFS to the
|
||||
end of its buffer. This code is mostly from glibc stdio/linewrap.c. */
|
||||
void
|
||||
__argp_fmtstream_update (argp_fmtstream_t fs)
|
||||
{
|
||||
char *buf, *nl;
|
||||
size_t len;
|
||||
|
||||
/* Scan the buffer for newlines. */
|
||||
buf = fs->buf + fs->point_offs;
|
||||
while (buf < fs->p)
|
||||
{
|
||||
size_t r;
|
||||
|
||||
if (fs->point_col == 0 && fs->lmargin != 0)
|
||||
{
|
||||
/* We are starting a new line. Print spaces to the left margin. */
|
||||
const size_t pad = fs->lmargin;
|
||||
if (fs->p + pad < fs->end)
|
||||
{
|
||||
/* We can fit in them in the buffer by moving the
|
||||
buffer text up and filling in the beginning. */
|
||||
memmove (buf + pad, buf, fs->p - buf);
|
||||
fs->p += pad; /* Compensate for bigger buffer. */
|
||||
memset (buf, ' ', pad); /* Fill in the spaces. */
|
||||
buf += pad; /* Don't bother searching them. */
|
||||
}
|
||||
else
|
||||
{
|
||||
/* No buffer space for spaces. Must flush. */
|
||||
size_t i;
|
||||
for (i = 0; i < pad; i++)
|
||||
putc (' ', fs->stream);
|
||||
}
|
||||
fs->point_col = pad;
|
||||
}
|
||||
|
||||
len = fs->p - buf;
|
||||
nl = memchr (buf, '\n', len);
|
||||
|
||||
if (fs->point_col < 0)
|
||||
fs->point_col = 0;
|
||||
|
||||
if (!nl)
|
||||
{
|
||||
/* The buffer ends in a partial line. */
|
||||
|
||||
if (fs->point_col + len < fs->rmargin)
|
||||
{
|
||||
/* The remaining buffer text is a partial line and fits
|
||||
within the maximum line width. Advance point for the
|
||||
characters to be written and stop scanning. */
|
||||
fs->point_col += len;
|
||||
break;
|
||||
}
|
||||
else
|
||||
/* Set the end-of-line pointer for the code below to
|
||||
the end of the buffer. */
|
||||
nl = fs->p;
|
||||
}
|
||||
else if (fs->point_col + (nl - buf) < (ssize_t) fs->rmargin)
|
||||
{
|
||||
/* The buffer contains a full line that fits within the maximum
|
||||
line width. Reset point and scan the next line. */
|
||||
fs->point_col = 0;
|
||||
buf = nl + 1;
|
||||
continue;
|
||||
}
|
||||
|
||||
/* This line is too long. */
|
||||
r = fs->rmargin - 1;
|
||||
|
||||
if (fs->wmargin < 0)
|
||||
{
|
||||
/* Truncate the line by overwriting the excess with the
|
||||
newline and anything after it in the buffer. */
|
||||
if (nl < fs->p)
|
||||
{
|
||||
memmove (buf + (r - fs->point_col), nl, fs->p - nl);
|
||||
fs->p -= buf + (r - fs->point_col) - nl;
|
||||
/* Reset point for the next line and start scanning it. */
|
||||
fs->point_col = 0;
|
||||
buf += r + 1; /* Skip full line plus \n. */
|
||||
}
|
||||
else
|
||||
{
|
||||
/* The buffer ends with a partial line that is beyond the
|
||||
maximum line width. Advance point for the characters
|
||||
written, and discard those past the max from the buffer. */
|
||||
fs->point_col += len;
|
||||
fs->p -= fs->point_col - r;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Do word wrap. Go to the column just past the maximum line
|
||||
width and scan back for the beginning of the word there.
|
||||
Then insert a line break. */
|
||||
|
||||
char *p, *nextline;
|
||||
int i;
|
||||
|
||||
p = buf + (r + 1 - fs->point_col);
|
||||
while (p >= buf && !isblank (*p))
|
||||
--p;
|
||||
nextline = p + 1; /* This will begin the next line. */
|
||||
|
||||
if (nextline > buf)
|
||||
{
|
||||
/* Swallow separating blanks. */
|
||||
if (p > buf)
|
||||
do
|
||||
--p;
|
||||
while (p > buf && isblank (*p));
|
||||
nl = p + 1; /* The newline will replace the first blank. */
|
||||
}
|
||||
else
|
||||
{
|
||||
/* A single word that is greater than the maximum line width.
|
||||
Oh well. Put it on an overlong line by itself. */
|
||||
p = buf + (r + 1 - fs->point_col);
|
||||
/* Find the end of the long word. */
|
||||
do
|
||||
++p;
|
||||
while (p < nl && !isblank (*p));
|
||||
if (p == nl)
|
||||
{
|
||||
/* It already ends a line. No fussing required. */
|
||||
fs->point_col = 0;
|
||||
buf = nl + 1;
|
||||
continue;
|
||||
}
|
||||
/* We will move the newline to replace the first blank. */
|
||||
nl = p;
|
||||
/* Swallow separating blanks. */
|
||||
do
|
||||
++p;
|
||||
while (isblank (*p));
|
||||
/* The next line will start here. */
|
||||
nextline = p;
|
||||
}
|
||||
|
||||
/* Note: There are a bunch of tests below for
|
||||
NEXTLINE == BUF + LEN + 1; this case is where NL happens to fall
|
||||
at the end of the buffer, and NEXTLINE is in fact empty (and so
|
||||
we need not be careful to maintain its contents). */
|
||||
|
||||
if (nextline == buf + len + 1
|
||||
? fs->end - nl < fs->wmargin + 1
|
||||
: nextline - (nl + 1) < fs->wmargin)
|
||||
/* The margin needs more blanks than we removed. */
|
||||
if (fs->end - fs->p > fs->wmargin + 1)
|
||||
/* Make some space for them. */
|
||||
{
|
||||
size_t mv = fs->p - nextline;
|
||||
memmove (nl + 1 + fs->wmargin, nextline, mv);
|
||||
nextline = nl + 1 + fs->wmargin;
|
||||
len = nextline + mv - buf;
|
||||
*nl++ = '\n';
|
||||
}
|
||||
else
|
||||
/* Output the first line so we can use the space. */
|
||||
{
|
||||
if (nl > fs->buf)
|
||||
fwrite (fs->buf, 1, nl - fs->buf, fs->stream);
|
||||
putc ('\n', fs->stream);
|
||||
len += buf - fs->buf;
|
||||
nl = buf = fs->buf;
|
||||
}
|
||||
else
|
||||
/* We can fit the newline and blanks in before
|
||||
the next word. */
|
||||
*nl++ = '\n';
|
||||
|
||||
if (nextline - nl >= fs->wmargin
|
||||
|| (nextline == buf + len + 1 && fs->end - nextline >= fs->wmargin))
|
||||
/* Add blanks up to the wrap margin column. */
|
||||
for (i = 0; i < fs->wmargin; ++i)
|
||||
*nl++ = ' ';
|
||||
else
|
||||
for (i = 0; i < fs->wmargin; ++i)
|
||||
putc (' ', fs->stream);
|
||||
|
||||
/* Copy the tail of the original buffer into the current buffer
|
||||
position. */
|
||||
if (nl < nextline)
|
||||
memmove (nl, nextline, buf + len - nextline);
|
||||
len -= nextline - buf;
|
||||
|
||||
/* Continue the scan on the remaining lines in the buffer. */
|
||||
buf = nl;
|
||||
|
||||
/* Restore bufp to include all the remaining text. */
|
||||
fs->p = nl + len;
|
||||
|
||||
/* Reset the counter of what has been output this line. If wmargin
|
||||
is 0, we want to avoid the lmargin getting added, so we set
|
||||
point_col to a magic value of -1 in that case. */
|
||||
fs->point_col = fs->wmargin ? fs->wmargin : -1;
|
||||
}
|
||||
}
|
||||
|
||||
/* Remember that we've scanned as far as the end of the buffer. */
|
||||
fs->point_offs = fs->p - fs->buf;
|
||||
}
|
||||
|
||||
/* Ensure that FS has space for AMOUNT more bytes in its buffer, either by
|
||||
growing the buffer, or by flushing it. True is returned iff we succeed. */
|
||||
int
|
||||
__argp_fmtstream_ensure (struct argp_fmtstream *fs, size_t amount)
|
||||
{
|
||||
if ((size_t) (fs->end - fs->p) < amount)
|
||||
{
|
||||
ssize_t wrote;
|
||||
|
||||
/* Flush FS's buffer. */
|
||||
__argp_fmtstream_update (fs);
|
||||
|
||||
wrote = fwrite (fs->buf, 1, fs->p - fs->buf, fs->stream);
|
||||
if (wrote == fs->p - fs->buf)
|
||||
{
|
||||
fs->p = fs->buf;
|
||||
fs->point_offs = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
fs->p -= wrote;
|
||||
fs->point_offs -= wrote;
|
||||
memmove (fs->buf, fs->buf + wrote, fs->p - fs->buf);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if ((size_t) (fs->end - fs->buf) < amount)
|
||||
/* Gotta grow the buffer. */
|
||||
{
|
||||
size_t new_size = fs->end - fs->buf + amount;
|
||||
char *new_buf = realloc (fs->buf, new_size);
|
||||
|
||||
if (! new_buf)
|
||||
{
|
||||
__set_errno (ENOMEM);
|
||||
return 0;
|
||||
}
|
||||
|
||||
fs->buf = new_buf;
|
||||
fs->end = new_buf + new_size;
|
||||
fs->p = fs->buf;
|
||||
}
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
ssize_t
|
||||
__argp_fmtstream_printf (struct argp_fmtstream *fs, const char *fmt, ...)
|
||||
{
|
||||
int out;
|
||||
size_t size_guess = PRINTF_SIZE_GUESS; /* How much space to reserve. */
|
||||
|
||||
do
|
||||
{
|
||||
va_list args;
|
||||
|
||||
if (! __argp_fmtstream_ensure (fs, size_guess))
|
||||
return -1;
|
||||
size_guess += size_guess;
|
||||
|
||||
va_start (args, fmt);
|
||||
out = __vsnprintf (fs->p, fs->end - fs->p, fmt, args);
|
||||
va_end (args);
|
||||
}
|
||||
while (out == -1);
|
||||
|
||||
fs->p += out;
|
||||
|
||||
return out;
|
||||
}
|
||||
#ifdef weak_alias
|
||||
weak_alias (__argp_fmtstream_printf, argp_fmtstream_printf)
|
||||
#endif
|
||||
|
||||
#endif /* !ARGP_FMTSTREAM_USE_LINEWRAP */
|
||||
@@ -0,0 +1,297 @@
|
||||
/* Word-wrapping and line-truncating streams.
|
||||
Copyright (C) 1997 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
Written by Miles Bader <miles@gnu.ai.mit.edu>.
|
||||
|
||||
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. */
|
||||
|
||||
/* This package emulates glibc `line_wrap_stream' semantics for systems that
|
||||
don't have that. If the system does have it, it is just a wrapper for
|
||||
that. This header file is only used internally while compiling argp, and
|
||||
shouldn't be installed. */
|
||||
|
||||
#ifndef __ARGP_FMTSTREAM_H__
|
||||
#define __ARGP_FMTSTREAM_H__
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <config.h>
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#if (_LIBC - 0 && !defined (USE_IN_LIBIO)) \
|
||||
|| (defined (__GNU_LIBRARY__) && defined (HAVE_LINEWRAP_H))
|
||||
/* line_wrap_stream is available, so use that. */
|
||||
#define ARGP_FMTSTREAM_USE_LINEWRAP
|
||||
#endif
|
||||
|
||||
#ifdef ARGP_FMTSTREAM_USE_LINEWRAP
|
||||
/* Just be a simple wrapper for line_wrap_stream; the semantics are
|
||||
*slightly* different, as line_wrap_stream doesn't actually make a new
|
||||
object, it just modifies the given stream (reversibly) to do
|
||||
line-wrapping. Since we control who uses this code, it doesn't matter. */
|
||||
|
||||
#include <linewrap.h>
|
||||
|
||||
typedef FILE *argp_fmtstream_t;
|
||||
|
||||
#define argp_make_fmtstream line_wrap_stream
|
||||
#define __argp_make_fmtstream line_wrap_stream
|
||||
#define argp_fmtstream_free line_unwrap_stream
|
||||
#define __argp_fmtstream_free line_unwrap_stream
|
||||
|
||||
#define __argp_fmtstream_putc(fs,ch) putc(ch,fs)
|
||||
#define argp_fmtstream_putc(fs,ch) putc(ch,fs)
|
||||
#define __argp_fmtstream_puts(fs,str) fputs(str,fs)
|
||||
#define argp_fmtstream_puts(fs,str) fputs(str,fs)
|
||||
#define __argp_fmtstream_write(fs,str,len) fwrite(str,1,len,fs)
|
||||
#define argp_fmtstream_write(fs,str,len) fwrite(str,1,len,fs)
|
||||
#define __argp_fmtstream_printf fprintf
|
||||
#define argp_fmtstream_printf fprintf
|
||||
|
||||
#define __argp_fmtstream_lmargin line_wrap_lmargin
|
||||
#define argp_fmtstream_lmargin line_wrap_lmargin
|
||||
#define __argp_fmtstream_set_lmargin line_wrap_set_lmargin
|
||||
#define argp_fmtstream_set_lmargin line_wrap_set_lmargin
|
||||
#define __argp_fmtstream_rmargin line_wrap_rmargin
|
||||
#define argp_fmtstream_rmargin line_wrap_rmargin
|
||||
#define __argp_fmtstream_set_rmargin line_wrap_set_rmargin
|
||||
#define argp_fmtstream_set_rmargin line_wrap_set_rmargin
|
||||
#define __argp_fmtstream_wmargin line_wrap_wmargin
|
||||
#define argp_fmtstream_wmargin line_wrap_wmargin
|
||||
#define __argp_fmtstream_set_wmargin line_wrap_set_wmargin
|
||||
#define argp_fmtstream_set_wmargin line_wrap_set_wmargin
|
||||
#define __argp_fmtstream_point line_wrap_point
|
||||
#define argp_fmtstream_point line_wrap_point
|
||||
|
||||
#else /* !ARGP_FMTSTREAM_USE_LINEWRAP */
|
||||
/* Guess we have to define our own version. */
|
||||
|
||||
#ifndef __const
|
||||
#define __const const
|
||||
#endif
|
||||
|
||||
struct argp_fmtstream
|
||||
{
|
||||
FILE *stream; /* The stream we're outputting to. */
|
||||
|
||||
size_t lmargin, rmargin; /* Left and right margins. */
|
||||
ssize_t wmargin; /* Margin to wrap to, or -1 to truncate. */
|
||||
|
||||
/* Point in buffer to which we've processed for wrapping, but not output. */
|
||||
size_t point_offs;
|
||||
/* Output column at POINT_OFFS, or -1 meaning 0 but don't add lmargin. */
|
||||
ssize_t point_col;
|
||||
|
||||
char *buf; /* Output buffer. */
|
||||
char *p; /* Current end of text in BUF. */
|
||||
char *end; /* Absolute end of BUF. */
|
||||
};
|
||||
|
||||
typedef struct argp_fmtstream *argp_fmtstream_t;
|
||||
|
||||
/* Return an argp_fmtstream that outputs to STREAM, and which prefixes lines
|
||||
written on it with LMARGIN spaces and limits them to RMARGIN columns
|
||||
total. If WMARGIN >= 0, words that extend past RMARGIN are wrapped by
|
||||
replacing the whitespace before them with a newline and WMARGIN spaces.
|
||||
Otherwise, chars beyond RMARGIN are simply dropped until a newline.
|
||||
Returns NULL if there was an error. */
|
||||
extern argp_fmtstream_t __argp_make_fmtstream (FILE *__stream,
|
||||
size_t __lmargin,
|
||||
size_t __rmargin,
|
||||
ssize_t __wmargin);
|
||||
extern argp_fmtstream_t argp_make_fmtstream (FILE *__stream,
|
||||
size_t __lmargin,
|
||||
size_t __rmargin,
|
||||
ssize_t __wmargin);
|
||||
|
||||
/* Flush __FS to its stream, and free it (but don't close the stream). */
|
||||
extern void __argp_fmtstream_free (argp_fmtstream_t __fs);
|
||||
extern void argp_fmtstream_free (argp_fmtstream_t __fs);
|
||||
|
||||
extern ssize_t __argp_fmtstream_printf (argp_fmtstream_t __fs,
|
||||
__const char *__fmt, ...)
|
||||
__attribute__ ((__format__ (printf, 2, 3)));
|
||||
extern ssize_t argp_fmtstream_printf (argp_fmtstream_t __fs,
|
||||
__const char *__fmt, ...)
|
||||
__attribute__ ((__format__ (printf, 2, 3)));
|
||||
|
||||
extern int __argp_fmtstream_putc (argp_fmtstream_t __fs, int __ch);
|
||||
extern int argp_fmtstream_putc (argp_fmtstream_t __fs, int __ch);
|
||||
|
||||
extern int __argp_fmtstream_puts (argp_fmtstream_t __fs, __const char *__str);
|
||||
extern int argp_fmtstream_puts (argp_fmtstream_t __fs, __const char *__str);
|
||||
|
||||
extern size_t __argp_fmtstream_write (argp_fmtstream_t __fs,
|
||||
__const char *__str, size_t __len);
|
||||
extern size_t argp_fmtstream_write (argp_fmtstream_t __fs,
|
||||
__const char *__str, size_t __len);
|
||||
|
||||
/* Access macros for various bits of state. */
|
||||
#define argp_fmtstream_lmargin(__fs) ((__fs)->lmargin)
|
||||
#define argp_fmtstream_rmargin(__fs) ((__fs)->rmargin)
|
||||
#define argp_fmtstream_wmargin(__fs) ((__fs)->wmargin)
|
||||
#define __argp_fmtstream_lmargin argp_fmtstream_lmargin
|
||||
#define __argp_fmtstream_rmargin argp_fmtstream_rmargin
|
||||
#define __argp_fmtstream_wmargin argp_fmtstream_wmargin
|
||||
|
||||
/* Set __FS's left margin to LMARGIN and return the old value. */
|
||||
extern size_t argp_fmtstream_set_lmargin (argp_fmtstream_t __fs,
|
||||
size_t __lmargin);
|
||||
extern size_t __argp_fmtstream_set_lmargin (argp_fmtstream_t __fs,
|
||||
size_t __lmargin);
|
||||
|
||||
/* Set __FS's right margin to __RMARGIN and return the old value. */
|
||||
extern size_t argp_fmtstream_set_rmargin (argp_fmtstream_t __fs,
|
||||
size_t __rmargin);
|
||||
extern size_t __argp_fmtstream_set_rmargin (argp_fmtstream_t __fs,
|
||||
size_t __rmargin);
|
||||
|
||||
/* Set __FS's wrap margin to __WMARGIN and return the old value. */
|
||||
extern size_t argp_fmtstream_set_wmargin (argp_fmtstream_t __fs,
|
||||
size_t __wmargin);
|
||||
extern size_t __argp_fmtstream_set_wmargin (argp_fmtstream_t __fs,
|
||||
size_t __wmargin);
|
||||
|
||||
/* Return the column number of the current output point in __FS. */
|
||||
extern size_t argp_fmtstream_point (argp_fmtstream_t __fs);
|
||||
extern size_t __argp_fmtstream_point (argp_fmtstream_t __fs);
|
||||
|
||||
/* Internal routines. */
|
||||
extern void _argp_fmtstream_update (argp_fmtstream_t __fs);
|
||||
extern void __argp_fmtstream_update (argp_fmtstream_t __fs);
|
||||
extern int _argp_fmtstream_ensure (argp_fmtstream_t __fs, size_t __amount);
|
||||
extern int __argp_fmtstream_ensure (argp_fmtstream_t __fs, size_t __amount);
|
||||
|
||||
#ifdef __OPTIMIZE__
|
||||
/* Inline versions of above routines. */
|
||||
|
||||
#if !_LIBC
|
||||
#define __argp_fmtstream_putc argp_fmtstream_putc
|
||||
#define __argp_fmtstream_puts argp_fmtstream_puts
|
||||
#define __argp_fmtstream_write argp_fmtstream_write
|
||||
#define __argp_fmtstream_set_lmargin argp_fmtstream_set_lmargin
|
||||
#define __argp_fmtstream_set_rmargin argp_fmtstream_set_rmargin
|
||||
#define __argp_fmtstream_set_wmargin argp_fmtstream_set_wmargin
|
||||
#define __argp_fmtstream_point argp_fmtstream_point
|
||||
#define __argp_fmtstream_update _argp_fmtstream_update
|
||||
#define __argp_fmtstream_ensure _argp_fmtstream_ensure
|
||||
#endif
|
||||
|
||||
#ifndef ARGP_FS_EI
|
||||
#define ARGP_FS_EI extern inline
|
||||
#endif
|
||||
|
||||
ARGP_FS_EI size_t
|
||||
__argp_fmtstream_write (argp_fmtstream_t __fs,
|
||||
__const char *__str, size_t __len)
|
||||
{
|
||||
if (__fs->p + __len <= __fs->end || __argp_fmtstream_ensure (__fs, __len))
|
||||
{
|
||||
memcpy (__fs->p, __str, __len);
|
||||
__fs->p += __len;
|
||||
return __len;
|
||||
}
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
ARGP_FS_EI int
|
||||
__argp_fmtstream_puts (argp_fmtstream_t __fs, __const char *__str)
|
||||
{
|
||||
size_t __len = strlen (__str);
|
||||
if (__len)
|
||||
{
|
||||
size_t __wrote = __argp_fmtstream_write (__fs, __str, __len);
|
||||
return __wrote == __len ? 0 : -1;
|
||||
}
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
ARGP_FS_EI int
|
||||
__argp_fmtstream_putc (argp_fmtstream_t __fs, int __ch)
|
||||
{
|
||||
if (__fs->p < __fs->end || __argp_fmtstream_ensure (__fs, 1))
|
||||
return *__fs->p++ = __ch;
|
||||
else
|
||||
return EOF;
|
||||
}
|
||||
|
||||
/* Set __FS's left margin to __LMARGIN and return the old value. */
|
||||
ARGP_FS_EI size_t
|
||||
__argp_fmtstream_set_lmargin (argp_fmtstream_t __fs, size_t __lmargin)
|
||||
{
|
||||
size_t __old;
|
||||
if ((size_t) (__fs->p - __fs->buf) > __fs->point_offs)
|
||||
__argp_fmtstream_update (__fs);
|
||||
__old = __fs->lmargin;
|
||||
__fs->lmargin = __lmargin;
|
||||
return __old;
|
||||
}
|
||||
|
||||
/* Set __FS's right margin to __RMARGIN and return the old value. */
|
||||
ARGP_FS_EI size_t
|
||||
__argp_fmtstream_set_rmargin (argp_fmtstream_t __fs, size_t __rmargin)
|
||||
{
|
||||
size_t __old;
|
||||
if ((size_t) (__fs->p - __fs->buf) > __fs->point_offs)
|
||||
__argp_fmtstream_update (__fs);
|
||||
__old = __fs->rmargin;
|
||||
__fs->rmargin = __rmargin;
|
||||
return __old;
|
||||
}
|
||||
|
||||
/* Set FS's wrap margin to __WMARGIN and return the old value. */
|
||||
ARGP_FS_EI size_t
|
||||
__argp_fmtstream_set_wmargin (argp_fmtstream_t __fs, size_t __wmargin)
|
||||
{
|
||||
size_t __old;
|
||||
if ((size_t) (__fs->p - __fs->buf) > __fs->point_offs)
|
||||
__argp_fmtstream_update (__fs);
|
||||
__old = __fs->wmargin;
|
||||
__fs->wmargin = __wmargin;
|
||||
return __old;
|
||||
}
|
||||
|
||||
/* Return the column number of the current output point in __FS. */
|
||||
ARGP_FS_EI size_t
|
||||
__argp_fmtstream_point (argp_fmtstream_t __fs)
|
||||
{
|
||||
if ((size_t) (__fs->p - __fs->buf) > __fs->point_offs)
|
||||
__argp_fmtstream_update (__fs);
|
||||
return __fs->point_col >= 0 ? __fs->point_col : 0;
|
||||
}
|
||||
|
||||
#if !_LIBC
|
||||
#undef __argp_fmtstream_putc
|
||||
#undef __argp_fmtstream_puts
|
||||
#undef __argp_fmtstream_write
|
||||
#undef __argp_fmtstream_set_lmargin
|
||||
#undef __argp_fmtstream_set_rmargin
|
||||
#undef __argp_fmtstream_set_wmargin
|
||||
#undef __argp_fmtstream_point
|
||||
#undef __argp_fmtstream_update
|
||||
#undef __argp_fmtstream_ensure
|
||||
#endif
|
||||
|
||||
#endif /* __OPTIMIZE__ */
|
||||
|
||||
#endif /* ARGP_FMTSTREAM_USE_LINEWRAP */
|
||||
|
||||
#endif /* __ARGP_FMTSTREAM_H__ */
|
||||
@@ -0,0 +1,41 @@
|
||||
/* Real definitions for extern inline functions in argp-fmtstream.h
|
||||
Copyright (C) 1997 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
Written by Miles Bader <miles@gnu.ai.mit.edu>.
|
||||
|
||||
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. */
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <config.h>
|
||||
#endif
|
||||
|
||||
#define ARGP_FS_EI
|
||||
#undef __OPTIMIZE__
|
||||
#define __OPTIMIZE__
|
||||
#include "argp-fmtstream.h"
|
||||
|
||||
/* Add weak aliases. */
|
||||
#if _LIBC - 0 && !defined (ARGP_FMTSTREAM_USE_LINEWRAP) && defined (weak_alias)
|
||||
|
||||
weak_alias (__argp_fmtstream_putc, argp_fmtstream_putc)
|
||||
weak_alias (__argp_fmtstream_puts, argp_fmtstream_puts)
|
||||
weak_alias (__argp_fmtstream_write, argp_fmtstream_write)
|
||||
weak_alias (__argp_fmtstream_set_lmargin, argp_fmtstream_set_lmargin)
|
||||
weak_alias (__argp_fmtstream_set_rmargin, argp_fmtstream_set_rmargin)
|
||||
weak_alias (__argp_fmtstream_set_wmargin, argp_fmtstream_set_wmargin)
|
||||
weak_alias (__argp_fmtstream_point, argp_fmtstream_point)
|
||||
|
||||
#endif
|
||||
+1693
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,92 @@
|
||||
/* Name frobnication for compiling argp outside of glibc
|
||||
Copyright (C) 1997 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
Written by Miles Bader <miles@gnu.ai.mit.edu>.
|
||||
|
||||
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. */
|
||||
|
||||
#if !_LIBC
|
||||
/* This code is written for inclusion in gnu-libc, and uses names in the
|
||||
namespace reserved for libc. If we're not compiling in libc, define those
|
||||
names to be the normal ones instead. */
|
||||
|
||||
/* argp-parse functions */
|
||||
#undef __argp_parse
|
||||
#define __argp_parse argp_parse
|
||||
#undef __option_is_end
|
||||
#define __option_is_end _option_is_end
|
||||
#undef __option_is_short
|
||||
#define __option_is_short _option_is_short
|
||||
#undef __argp_input
|
||||
#define __argp_input _argp_input
|
||||
|
||||
/* argp-help functions */
|
||||
#undef __argp_help
|
||||
#define __argp_help argp_help
|
||||
#undef __argp_error
|
||||
#define __argp_error argp_error
|
||||
#undef __argp_failure
|
||||
#define __argp_failure argp_failure
|
||||
#undef __argp_state_help
|
||||
#define __argp_state_help argp_state_help
|
||||
#undef __argp_usage
|
||||
#define __argp_usage argp_usage
|
||||
|
||||
/* argp-fmtstream functions */
|
||||
#undef __argp_make_fmtstream
|
||||
#define __argp_make_fmtstream argp_make_fmtstream
|
||||
#undef __argp_fmtstream_free
|
||||
#define __argp_fmtstream_free argp_fmtstream_free
|
||||
#undef __argp_fmtstream_putc
|
||||
#define __argp_fmtstream_putc argp_fmtstream_putc
|
||||
#undef __argp_fmtstream_puts
|
||||
#define __argp_fmtstream_puts argp_fmtstream_puts
|
||||
#undef __argp_fmtstream_write
|
||||
#define __argp_fmtstream_write argp_fmtstream_write
|
||||
#undef __argp_fmtstream_printf
|
||||
#define __argp_fmtstream_printf argp_fmtstream_printf
|
||||
#undef __argp_fmtstream_set_lmargin
|
||||
#define __argp_fmtstream_set_lmargin argp_fmtstream_set_lmargin
|
||||
#undef __argp_fmtstream_set_rmargin
|
||||
#define __argp_fmtstream_set_rmargin argp_fmtstream_set_rmargin
|
||||
#undef __argp_fmtstream_set_wmargin
|
||||
#define __argp_fmtstream_set_wmargin argp_fmtstream_set_wmargin
|
||||
#undef __argp_fmtstream_point
|
||||
#define __argp_fmtstream_point argp_fmtstream_point
|
||||
#undef __argp_fmtstream_update
|
||||
#define __argp_fmtstream_update _argp_fmtstream_update
|
||||
#undef __argp_fmtstream_ensure
|
||||
#define __argp_fmtstream_ensure _argp_fmtstream_ensure
|
||||
#undef __argp_fmtstream_lmargin
|
||||
#define __argp_fmtstream_lmargin argp_fmtstream_lmargin
|
||||
#undef __argp_fmtstream_rmargin
|
||||
#define __argp_fmtstream_rmargin argp_fmtstream_rmargin
|
||||
#undef __argp_fmtstream_wmargin
|
||||
#define __argp_fmtstream_wmargin argp_fmtstream_wmargin
|
||||
|
||||
/* normal libc functions we call */
|
||||
#undef __sleep
|
||||
#define __sleep sleep
|
||||
#undef __strcasecmp
|
||||
#define __strcasecmp strcasecmp
|
||||
#undef __vsnprintf
|
||||
#define __vsnprintf vsnprintf
|
||||
|
||||
#endif /* !_LIBC */
|
||||
|
||||
#ifndef __set_errno
|
||||
#define __set_errno(e) (errno = (e))
|
||||
#endif
|
||||
@@ -0,0 +1,888 @@
|
||||
/* Hierarchial argument parsing, layered over getopt
|
||||
Copyright (C) 1995, 1996, 1997 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
Written by Miles Bader <miles@gnu.ai.mit.edu>.
|
||||
|
||||
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. */
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <config.h>
|
||||
#endif
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <limits.h>
|
||||
#include <getopt.h>
|
||||
|
||||
#ifndef _
|
||||
/* This is for other GNU distributions with internationalized messages.
|
||||
When compiling libc, the _ macro is predefined. */
|
||||
#ifdef HAVE_LIBINTL_H
|
||||
# include <libintl.h>
|
||||
# define _(msgid) gettext (msgid)
|
||||
#else
|
||||
# define _(msgid) (msgid)
|
||||
# define gettext(msgid) (msgid)
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if _LIBC - 0
|
||||
#include <libc-lock.h>
|
||||
#else
|
||||
#ifdef HAVE_CTHREADS_H
|
||||
#include <cthreads.h>
|
||||
#endif
|
||||
#endif /* _LIBC */
|
||||
|
||||
#include "argp.h"
|
||||
#include "argp-namefrob.h"
|
||||
|
||||
/* Getopt return values. */
|
||||
#define KEY_END (-1) /* The end of the options. */
|
||||
#define KEY_ARG 1 /* A non-option argument. */
|
||||
#define KEY_ERR '?' /* An error parsing the options. */
|
||||
|
||||
/* The meta-argument used to prevent any further arguments being interpreted
|
||||
as options. */
|
||||
#define QUOTE "--"
|
||||
|
||||
/* The number of bits we steal in a long-option value for our own use. */
|
||||
#define GROUP_BITS CHAR_BIT
|
||||
|
||||
/* The number of bits available for the user value. */
|
||||
#define USER_BITS ((sizeof ((struct option *)0)->val * CHAR_BIT) - GROUP_BITS)
|
||||
#define USER_MASK ((1 << USER_BITS) - 1)
|
||||
|
||||
/* EZ alias for ARGP_ERR_UNKNOWN. */
|
||||
#define EBADKEY ARGP_ERR_UNKNOWN
|
||||
|
||||
/* Default options. */
|
||||
|
||||
/* When argp is given the --HANG switch, _ARGP_HANG is set and argp will sleep
|
||||
for one second intervals, decrementing _ARGP_HANG until it's zero. Thus
|
||||
you can force the program to continue by attaching a debugger and setting
|
||||
it to 0 yourself. */
|
||||
volatile int _argp_hang = 0;
|
||||
|
||||
#define OPT_PROGNAME -2
|
||||
#define OPT_USAGE -3
|
||||
#define OPT_HANG -4
|
||||
|
||||
static const struct argp_option argp_default_options[] =
|
||||
{
|
||||
{"help", '?', 0, 0, "Give this help list", -1},
|
||||
{"usage", OPT_USAGE, 0, 0, "Give a short usage message"},
|
||||
{"program-name",OPT_PROGNAME,"NAME", OPTION_HIDDEN, "Set the program name"},
|
||||
{"HANG", OPT_HANG, "SECS", OPTION_ARG_OPTIONAL | OPTION_HIDDEN,
|
||||
"Hang for SECS seconds (default 3600)"},
|
||||
{0, 0}
|
||||
};
|
||||
|
||||
static error_t
|
||||
argp_default_parser (int key, char *arg, struct argp_state *state)
|
||||
{
|
||||
switch (key)
|
||||
{
|
||||
case '?':
|
||||
__argp_state_help (state, state->out_stream, ARGP_HELP_STD_HELP);
|
||||
break;
|
||||
case OPT_USAGE:
|
||||
__argp_state_help (state, state->out_stream,
|
||||
ARGP_HELP_USAGE | ARGP_HELP_EXIT_OK);
|
||||
break;
|
||||
|
||||
case OPT_PROGNAME: /* Set the program name. */
|
||||
program_invocation_name = arg;
|
||||
|
||||
/* [Note that some systems only have PROGRAM_INVOCATION_SHORT_NAME (aka
|
||||
__PROGNAME), in which case, PROGRAM_INVOCATION_NAME is just defined
|
||||
to be that, so we have to be a bit careful here.] */
|
||||
arg = strrchr (arg, '/');
|
||||
if (arg)
|
||||
program_invocation_short_name = arg + 1;
|
||||
else
|
||||
program_invocation_short_name = program_invocation_name;
|
||||
|
||||
/* Update what we use for messages. */
|
||||
state->name = program_invocation_short_name;
|
||||
|
||||
if ((state->flags & (ARGP_PARSE_ARGV0 | ARGP_NO_ERRS))
|
||||
== ARGP_PARSE_ARGV0)
|
||||
/* Update what getopt uses too. */
|
||||
state->argv[0] = program_invocation_name;
|
||||
|
||||
break;
|
||||
|
||||
case OPT_HANG:
|
||||
_argp_hang = atoi (arg ? arg : "3600");
|
||||
while (_argp_hang-- > 0)
|
||||
__sleep (1);
|
||||
break;
|
||||
|
||||
default:
|
||||
return EBADKEY;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct argp argp_default_argp =
|
||||
{argp_default_options, &argp_default_parser};
|
||||
|
||||
|
||||
static const struct argp_option argp_version_options[] =
|
||||
{
|
||||
{"version", 'V', 0, 0, "Print program version", -1},
|
||||
{0, 0}
|
||||
};
|
||||
|
||||
static error_t
|
||||
argp_version_parser (int key, char *arg, struct argp_state *state)
|
||||
{
|
||||
switch (key)
|
||||
{
|
||||
case 'V':
|
||||
if (argp_program_version_hook)
|
||||
(*argp_program_version_hook) (state->out_stream, state);
|
||||
else if (argp_program_version)
|
||||
fprintf (state->out_stream, "%s\n", argp_program_version);
|
||||
else
|
||||
__argp_error (state, _("No version known!?"));
|
||||
if (! (state->flags & ARGP_NO_EXIT))
|
||||
exit (0);
|
||||
break;
|
||||
default:
|
||||
return EBADKEY;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct argp argp_version_argp =
|
||||
{argp_version_options, &argp_version_parser};
|
||||
|
||||
/* Returns the offset into the getopt long options array LONG_OPTIONS of a
|
||||
long option with called NAME, or -1 if none is found. Passing NULL as
|
||||
NAME will return the number of options. */
|
||||
static int
|
||||
find_long_option (struct option *long_options, const char *name)
|
||||
{
|
||||
struct option *l = long_options;
|
||||
while (l->name != NULL)
|
||||
if (name != NULL && strcmp (l->name, name) == 0)
|
||||
return l - long_options;
|
||||
else
|
||||
l++;
|
||||
if (name == NULL)
|
||||
return l - long_options;
|
||||
else
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* If we can, we regulate access to getopt, which is non-reentrant, with a
|
||||
mutex. Since the case we're trying to guard against is two different
|
||||
threads interfering, and it's possible that someone might want to call
|
||||
argp_parse recursively (they're careful), we use a recursive lock if
|
||||
possible. */
|
||||
|
||||
#if _LIBC - 0
|
||||
|
||||
__libc_lock_define_initialized_recursive (static, getopt_lock)
|
||||
#define LOCK_GETOPT __libc_lock_lock_recursive (getopt_lock)
|
||||
#define UNLOCK_GETOPT __libc_lock_unlock_recursive (getopt_lock)
|
||||
|
||||
#else /* !_LIBC */
|
||||
#ifdef HAVE_CTHREADS_H
|
||||
|
||||
static struct mutex getopt_lock = MUTEX_INITIALIZER;
|
||||
#define LOCK_GETOPT mutex_lock (&getopt_lock)
|
||||
#define UNLOCK_GETOPT mutex_unlock (&getopt_lock)
|
||||
|
||||
#else /* !HAVE_CTHREADS_H */
|
||||
|
||||
#define LOCK_GETOPT (void)0
|
||||
#define UNLOCK_GETOPT (void)0
|
||||
|
||||
#endif /* HAVE_CTHREADS_H */
|
||||
#endif /* _LIBC */
|
||||
|
||||
/* This hack to allow programs that know what's going on to call argp
|
||||
recursively. If someday argp is changed not to use the non-reentrant
|
||||
getopt interface, we can get rid of this shit. XXX */
|
||||
void
|
||||
_argp_unlock_xxx (void)
|
||||
{
|
||||
UNLOCK_GETOPT;
|
||||
}
|
||||
|
||||
/* The state of a `group' during parsing. Each group corresponds to a
|
||||
particular argp structure from the tree of such descending from the top
|
||||
level argp passed to argp_parse. */
|
||||
struct group
|
||||
{
|
||||
/* This group's parsing function. */
|
||||
argp_parser_t parser;
|
||||
|
||||
/* Which argp this group is from. */
|
||||
const struct argp *argp;
|
||||
|
||||
/* Points to the point in SHORT_OPTS corresponding to the end of the short
|
||||
options for this group. We use it to determine from which group a
|
||||
particular short options is from. */
|
||||
char *short_end;
|
||||
|
||||
/* The number of non-option args sucessfully handled by this parser. */
|
||||
unsigned args_processed;
|
||||
|
||||
/* This group's parser's parent's group. */
|
||||
struct group *parent;
|
||||
unsigned parent_index; /* And the our position in the parent. */
|
||||
|
||||
/* These fields are swapped into and out of the state structure when
|
||||
calling this group's parser. */
|
||||
void *input, **child_inputs;
|
||||
void *hook;
|
||||
};
|
||||
|
||||
/* Call GROUP's parser with KEY and ARG, swapping any group-specific info
|
||||
from STATE before calling, and back into state afterwards. If GROUP has
|
||||
no parser, EBADKEY is returned. */
|
||||
static error_t
|
||||
group_parse (struct group *group, struct argp_state *state, int key, char *arg)
|
||||
{
|
||||
if (group->parser)
|
||||
{
|
||||
error_t err;
|
||||
state->hook = group->hook;
|
||||
state->input = group->input;
|
||||
state->child_inputs = group->child_inputs;
|
||||
state->arg_num = group->args_processed;
|
||||
err = (*group->parser)(key, arg, state);
|
||||
group->hook = state->hook;
|
||||
return err;
|
||||
}
|
||||
else
|
||||
return EBADKEY;
|
||||
}
|
||||
|
||||
struct parser
|
||||
{
|
||||
const struct argp *argp;
|
||||
|
||||
/* SHORT_OPTS is the getopt short options string for the union of all the
|
||||
groups of options. */
|
||||
char *short_opts;
|
||||
/* LONG_OPTS is the array of getop long option structures for the union of
|
||||
all the groups of options. */
|
||||
struct option *long_opts;
|
||||
|
||||
/* States of the various parsing groups. */
|
||||
struct group *groups;
|
||||
/* The end of the GROUPS array. */
|
||||
struct group *egroup;
|
||||
/* An vector containing storage for the CHILD_INPUTS field in all groups. */
|
||||
void **child_inputs;
|
||||
|
||||
/* True if we think using getopt is still useful; if false, then
|
||||
remaining arguments are just passed verbatim with ARGP_KEY_ARG. This is
|
||||
cleared whenever getopt returns KEY_END, but may be set again if the user
|
||||
moves the next argument pointer backwards. */
|
||||
int try_getopt;
|
||||
|
||||
/* State block supplied to parsing routines. */
|
||||
struct argp_state state;
|
||||
|
||||
/* Memory used by this parser. */
|
||||
void *storage;
|
||||
};
|
||||
|
||||
/* The next usable entries in the various parser tables being filled in by
|
||||
convert_options. */
|
||||
struct parser_convert_state
|
||||
{
|
||||
struct parser *parser;
|
||||
char *short_end;
|
||||
struct option *long_end;
|
||||
void **child_inputs_end;
|
||||
};
|
||||
|
||||
/* Converts all options in ARGP (which is put in GROUP) and ancestors
|
||||
into getopt options stored in SHORT_OPTS and LONG_OPTS; SHORT_END and
|
||||
CVT->LONG_END are the points at which new options are added. Returns the
|
||||
next unused group entry. CVT holds state used during the conversion. */
|
||||
static struct group *
|
||||
convert_options (const struct argp *argp,
|
||||
struct group *parent, unsigned parent_index,
|
||||
struct group *group, struct parser_convert_state *cvt)
|
||||
{
|
||||
/* REAL is the most recent non-alias value of OPT. */
|
||||
const struct argp_option *real = argp->options;
|
||||
const struct argp_child *children = argp->children;
|
||||
|
||||
if (real || argp->parser)
|
||||
{
|
||||
const struct argp_option *opt;
|
||||
|
||||
if (real)
|
||||
for (opt = real; !__option_is_end (opt); opt++)
|
||||
{
|
||||
if (! (opt->flags & OPTION_ALIAS))
|
||||
/* OPT isn't an alias, so we can use values from it. */
|
||||
real = opt;
|
||||
|
||||
if (! (real->flags & OPTION_DOC))
|
||||
/* A real option (not just documentation). */
|
||||
{
|
||||
if (__option_is_short (opt))
|
||||
/* OPT can be used as a short option. */
|
||||
{
|
||||
*cvt->short_end++ = opt->key;
|
||||
if (real->arg)
|
||||
{
|
||||
*cvt->short_end++ = ':';
|
||||
if (real->flags & OPTION_ARG_OPTIONAL)
|
||||
*cvt->short_end++ = ':';
|
||||
}
|
||||
*cvt->short_end = '\0'; /* keep 0 terminated */
|
||||
}
|
||||
|
||||
if (opt->name
|
||||
&& find_long_option (cvt->parser->long_opts, opt->name) < 0)
|
||||
/* OPT can be used as a long option. */
|
||||
{
|
||||
cvt->long_end->name = opt->name;
|
||||
cvt->long_end->has_arg =
|
||||
(real->arg
|
||||
? (real->flags & OPTION_ARG_OPTIONAL
|
||||
? optional_argument
|
||||
: required_argument)
|
||||
: no_argument);
|
||||
cvt->long_end->flag = 0;
|
||||
/* we add a disambiguating code to all the user's
|
||||
values (which is removed before we actually call
|
||||
the function to parse the value); this means that
|
||||
the user loses use of the high 8 bits in all his
|
||||
values (the sign of the lower bits is preserved
|
||||
however)... */
|
||||
cvt->long_end->val =
|
||||
((opt->key | real->key) & USER_MASK)
|
||||
+ (((group - cvt->parser->groups) + 1) << USER_BITS);
|
||||
|
||||
/* Keep the LONG_OPTS list terminated. */
|
||||
(++cvt->long_end)->name = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
group->parser = argp->parser;
|
||||
group->argp = argp;
|
||||
group->short_end = cvt->short_end;
|
||||
group->args_processed = 0;
|
||||
group->parent = parent;
|
||||
group->parent_index = parent_index;
|
||||
group->input = 0;
|
||||
group->hook = 0;
|
||||
group->child_inputs = 0;
|
||||
|
||||
if (children)
|
||||
/* Assign GROUP's CHILD_INPUTS field some space from
|
||||
CVT->child_inputs_end.*/
|
||||
{
|
||||
unsigned num_children = 0;
|
||||
while (children[num_children].argp)
|
||||
num_children++;
|
||||
group->child_inputs = cvt->child_inputs_end;
|
||||
cvt->child_inputs_end += num_children;
|
||||
}
|
||||
|
||||
parent = group++;
|
||||
}
|
||||
else
|
||||
parent = 0;
|
||||
|
||||
if (children)
|
||||
{
|
||||
unsigned index = 0;
|
||||
while (children->argp)
|
||||
group =
|
||||
convert_options (children++->argp, parent, index++, group, cvt);
|
||||
}
|
||||
|
||||
return group;
|
||||
}
|
||||
|
||||
/* Find the merged set of getopt options, with keys appropiately prefixed. */
|
||||
static void
|
||||
parser_convert (struct parser *parser, const struct argp *argp, int flags)
|
||||
{
|
||||
struct parser_convert_state cvt;
|
||||
|
||||
cvt.parser = parser;
|
||||
cvt.short_end = parser->short_opts;
|
||||
cvt.long_end = parser->long_opts;
|
||||
cvt.child_inputs_end = parser->child_inputs;
|
||||
|
||||
if (flags & ARGP_IN_ORDER)
|
||||
*cvt.short_end++ = '-';
|
||||
else if (flags & ARGP_NO_ARGS)
|
||||
*cvt.short_end++ = '+';
|
||||
*cvt.short_end = '\0';
|
||||
|
||||
cvt.long_end->name = NULL;
|
||||
|
||||
parser->argp = argp;
|
||||
|
||||
if (argp)
|
||||
parser->egroup = convert_options (argp, 0, 0, parser->groups, &cvt);
|
||||
else
|
||||
parser->egroup = parser->groups; /* No parsers at all! */
|
||||
}
|
||||
|
||||
/* Lengths of various parser fields which we will allocated. */
|
||||
struct parser_sizes
|
||||
{
|
||||
size_t short_len; /* Getopt short options string. */
|
||||
size_t long_len; /* Getopt long options vector. */
|
||||
size_t num_groups; /* Group structures we allocate. */
|
||||
size_t num_child_inputs; /* Child input slots. */
|
||||
};
|
||||
|
||||
/* For ARGP, increments the NUM_GROUPS field in SZS by the total number of
|
||||
argp structures descended from it, and the SHORT_LEN & LONG_LEN fields by
|
||||
the maximum lengths of the resulting merged getopt short options string and
|
||||
long-options array, respectively. */
|
||||
static void
|
||||
calc_sizes (const struct argp *argp, struct parser_sizes *szs)
|
||||
{
|
||||
const struct argp_child *child = argp->children;
|
||||
const struct argp_option *opt = argp->options;
|
||||
|
||||
if (opt || argp->parser)
|
||||
{
|
||||
szs->num_groups++;
|
||||
if (opt)
|
||||
{
|
||||
int num_opts = 0;
|
||||
while (!__option_is_end (opt++))
|
||||
num_opts++;
|
||||
szs->short_len += num_opts * 3; /* opt + up to 2 `:'s */
|
||||
szs->long_len += num_opts;
|
||||
}
|
||||
}
|
||||
|
||||
if (child)
|
||||
while (child->argp)
|
||||
{
|
||||
calc_sizes ((child++)->argp, szs);
|
||||
szs->num_child_inputs++;
|
||||
}
|
||||
}
|
||||
|
||||
/* Initializes PARSER to parse ARGP in a manner described by FLAGS. */
|
||||
static error_t
|
||||
parser_init (struct parser *parser, const struct argp *argp,
|
||||
int argc, char **argv, int flags, void *input)
|
||||
{
|
||||
error_t err = 0;
|
||||
struct group *group;
|
||||
struct parser_sizes szs;
|
||||
|
||||
szs.short_len = (flags & ARGP_NO_ARGS) ? 0 : 1;
|
||||
szs.long_len = 0;
|
||||
szs.num_groups = 0;
|
||||
szs.num_child_inputs = 0;
|
||||
|
||||
if (argp)
|
||||
calc_sizes (argp, &szs);
|
||||
|
||||
/* Lengths of the various bits of storage used by PARSER. */
|
||||
#define GLEN (szs.num_groups + 1) * sizeof (struct group)
|
||||
#define CLEN (szs.num_child_inputs * sizeof (void *))
|
||||
#define LLEN ((szs.long_len + 1) * sizeof (struct option))
|
||||
#define SLEN (szs.short_len + 1)
|
||||
|
||||
parser->storage = malloc (GLEN + CLEN + LLEN + SLEN);
|
||||
if (! parser->storage)
|
||||
return ENOMEM;
|
||||
|
||||
parser->groups = parser->storage;
|
||||
parser->child_inputs = parser->storage + GLEN;
|
||||
parser->long_opts = parser->storage + GLEN + CLEN;
|
||||
parser->short_opts = parser->storage + GLEN + CLEN + LLEN;
|
||||
|
||||
memset (parser->child_inputs, 0, szs.num_child_inputs * sizeof (void *));
|
||||
parser_convert (parser, argp, flags);
|
||||
|
||||
memset (&parser->state, 0, sizeof (struct argp_state));
|
||||
parser->state.argp = parser->argp;
|
||||
parser->state.argc = argc;
|
||||
parser->state.argv = argv;
|
||||
parser->state.flags = flags;
|
||||
parser->state.err_stream = stderr;
|
||||
parser->state.out_stream = stdout;
|
||||
parser->state.next = 0; /* Tell getopt to initialize. */
|
||||
parser->state.pstate = parser;
|
||||
|
||||
parser->try_getopt = 1;
|
||||
|
||||
/* Call each parser for the first time, giving it a chance to propagate
|
||||
values to child parsers. */
|
||||
if (parser->groups < parser->egroup)
|
||||
parser->groups->input = input;
|
||||
for (group = parser->groups;
|
||||
group < parser->egroup && (!err || err == EBADKEY);
|
||||
group++)
|
||||
{
|
||||
if (group->parent)
|
||||
/* If a child parser, get the initial input value from the parent. */
|
||||
group->input = group->parent->child_inputs[group->parent_index];
|
||||
err = group_parse (group, &parser->state, ARGP_KEY_INIT, 0);
|
||||
}
|
||||
if (err == EBADKEY)
|
||||
err = 0; /* Some parser didn't understand. */
|
||||
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
/* Getopt is (currently) non-reentrant. */
|
||||
LOCK_GETOPT;
|
||||
|
||||
if (parser->state.flags & ARGP_NO_ERRS)
|
||||
{
|
||||
opterr = 0;
|
||||
if (parser->state.flags & ARGP_PARSE_ARGV0)
|
||||
/* getopt always skips ARGV[0], so we have to fake it out. As long
|
||||
as OPTERR is 0, then it shouldn't actually try to access it. */
|
||||
parser->state.argv--, parser->state.argc++;
|
||||
}
|
||||
else
|
||||
opterr = 1; /* Print error messages. */
|
||||
|
||||
if (parser->state.argv == argv && argv[0])
|
||||
/* There's an argv[0]; use it for messages. */
|
||||
{
|
||||
char *short_name = strrchr (argv[0], '/');
|
||||
parser->state.name = short_name ? short_name + 1 : argv[0];
|
||||
}
|
||||
else
|
||||
parser->state.name = program_invocation_short_name;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Free any storage consumed by PARSER (but not PARSER itself). */
|
||||
static error_t
|
||||
parser_finalize (struct parser *parser,
|
||||
error_t err, int arg_ebadkey, int *end_index)
|
||||
{
|
||||
struct group *group;
|
||||
|
||||
UNLOCK_GETOPT;
|
||||
|
||||
if (err == EBADKEY && arg_ebadkey)
|
||||
/* Suppress errors generated by unparsed arguments. */
|
||||
err = 0;
|
||||
|
||||
if (! err)
|
||||
if (parser->state.next == parser->state.argc)
|
||||
/* We successfully parsed all arguments! Call all the parsers again,
|
||||
just a few more times... */
|
||||
{
|
||||
for (group = parser->groups;
|
||||
group < parser->egroup && (!err || err==EBADKEY);
|
||||
group++)
|
||||
if (group->args_processed == 0)
|
||||
err = group_parse (group, &parser->state, ARGP_KEY_NO_ARGS, 0);
|
||||
for (group = parser->groups;
|
||||
group < parser->egroup && (!err || err==EBADKEY);
|
||||
group++)
|
||||
err = group_parse (group, &parser->state, ARGP_KEY_END, 0);
|
||||
|
||||
if (err == EBADKEY)
|
||||
err = 0; /* Some parser didn't understand. */
|
||||
|
||||
/* Tell the user that all arguments are parsed. */
|
||||
if (end_index)
|
||||
*end_index = parser->state.next;
|
||||
}
|
||||
else if (end_index)
|
||||
/* Return any remaining arguments to the user. */
|
||||
*end_index = parser->state.next;
|
||||
else
|
||||
/* No way to return the remaining arguments, they must be bogus. */
|
||||
{
|
||||
if (!(parser->state.flags & ARGP_NO_ERRS) && parser->state.err_stream)
|
||||
fprintf (parser->state.err_stream,
|
||||
_("%s: Too many arguments\n"), parser->state.name);
|
||||
err = EBADKEY;
|
||||
}
|
||||
|
||||
/* Okay, we're all done, with either an error or success. We only call the
|
||||
parsers once more, to indicate which one. */
|
||||
|
||||
if (err)
|
||||
{
|
||||
/* Maybe print an error message. */
|
||||
if (err == EBADKEY)
|
||||
/* An appropriate message describing what the error was should have
|
||||
been printed earlier. */
|
||||
__argp_state_help (&parser->state, parser->state.err_stream,
|
||||
ARGP_HELP_STD_ERR);
|
||||
|
||||
/* Since we didn't exit, give each parser an error indication. */
|
||||
for (group = parser->groups; group < parser->egroup; group++)
|
||||
group_parse (group, &parser->state, ARGP_KEY_ERROR, 0);
|
||||
}
|
||||
else
|
||||
/* Do final cleanup, including propagating back values from parsers. */
|
||||
{
|
||||
/* We pass over the groups in reverse order so that child groups are
|
||||
given a chance to do there processing before passing back a value to
|
||||
the parent. */
|
||||
for (group = parser->egroup - 1
|
||||
; group >= parser->groups && (!err || err == EBADKEY)
|
||||
; group--)
|
||||
err = group_parse (group, &parser->state, ARGP_KEY_SUCCESS, 0);
|
||||
if (err == EBADKEY)
|
||||
err = 0; /* Some parser didn't understand. */
|
||||
}
|
||||
|
||||
if (err == EBADKEY)
|
||||
err = EINVAL;
|
||||
|
||||
free (parser->storage);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
/* Call the user parsers to parse the non-option argument VAL, at the current
|
||||
position, returning any error. */
|
||||
static error_t
|
||||
parser_parse_arg (struct parser *parser, char *val)
|
||||
{
|
||||
int index = parser->state.next;
|
||||
error_t err = EBADKEY;
|
||||
struct group *group;
|
||||
|
||||
for (group = parser->groups
|
||||
; group < parser->egroup && err == EBADKEY
|
||||
; group++)
|
||||
err = group_parse (group, &parser->state, ARGP_KEY_ARG, val);
|
||||
|
||||
if (!err)
|
||||
if (parser->state.next >= index)
|
||||
/* Remember that we successfully processed a non-option
|
||||
argument -- but only if the user hasn't gotten tricky and set
|
||||
the clock back. */
|
||||
(--group)->args_processed++;
|
||||
else
|
||||
/* The user wants to reparse some args, give getopt another try. */
|
||||
parser->try_getopt = 1;
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
/* Call the user parsers to parse the option OPT, with argument VAL, at the
|
||||
current position, returning any error. */
|
||||
static error_t
|
||||
parser_parse_opt (struct parser *parser, int opt, char *val)
|
||||
{
|
||||
/* The group key encoded in the high bits; 0 for short opts or
|
||||
group_number + 1 for long opts. */
|
||||
int group_key = opt >> USER_BITS;
|
||||
|
||||
if (group_key == 0)
|
||||
/* A short option. By comparing OPT's position in SHORT_OPTS to the
|
||||
various starting positions in each group's SHORT_END field, we can
|
||||
determine which group OPT came from. */
|
||||
{
|
||||
struct group *group;
|
||||
char *short_index = strchr (parser->short_opts, opt);
|
||||
|
||||
if (short_index)
|
||||
for (group = parser->groups; group < parser->egroup; group++)
|
||||
if (group->short_end > short_index)
|
||||
return group_parse (group, &parser->state, opt, optarg);
|
||||
|
||||
return EBADKEY; /* until otherwise asserted */
|
||||
}
|
||||
else
|
||||
/* A long option. We use shifts instead of masking for extracting
|
||||
the user value in order to preserve the sign. */
|
||||
return
|
||||
group_parse (&parser->groups[group_key - 1], &parser->state,
|
||||
(opt << GROUP_BITS) >> GROUP_BITS, optarg);
|
||||
}
|
||||
|
||||
/* Parse the next argument in PARSER (as indicated by PARSER->state.next).
|
||||
Any error from the parsers is returned, and *ARGP_EBADKEY indicates
|
||||
whether a value of EBADKEY is due to an unrecognized argument (which is
|
||||
generally not fatal). */
|
||||
static error_t
|
||||
parser_parse_next (struct parser *parser, int *arg_ebadkey)
|
||||
{
|
||||
int opt;
|
||||
error_t err = 0;
|
||||
|
||||
if (parser->state.quoted && parser->state.next < parser->state.quoted)
|
||||
/* The next argument pointer has been moved to before the quoted
|
||||
region, so pretend we never saw the quoting `--', and give getopt
|
||||
another chance. If the user hasn't removed it, getopt will just
|
||||
process it again. */
|
||||
parser->state.quoted = 0;
|
||||
|
||||
if (parser->try_getopt && !parser->state.quoted)
|
||||
/* Give getopt a chance to parse this. */
|
||||
{
|
||||
optind = parser->state.next; /* Put it back in OPTIND for getopt. */
|
||||
optopt = KEY_END; /* Distinguish KEY_ERR from a real option. */
|
||||
if (parser->state.flags & ARGP_LONG_ONLY)
|
||||
opt = getopt_long_only (parser->state.argc, parser->state.argv,
|
||||
parser->short_opts, parser->long_opts, 0);
|
||||
else
|
||||
opt = getopt_long (parser->state.argc, parser->state.argv,
|
||||
parser->short_opts, parser->long_opts, 0);
|
||||
parser->state.next = optind; /* And see what getopt did. */
|
||||
|
||||
if (opt == KEY_END)
|
||||
/* Getopt says there are no more options, so stop using
|
||||
getopt; we'll continue if necessary on our own. */
|
||||
{
|
||||
parser->try_getopt = 0;
|
||||
if (parser->state.next > 1
|
||||
&& strcmp (parser->state.argv[parser->state.next - 1], QUOTE)
|
||||
== 0)
|
||||
/* Not only is this the end of the options, but it's a
|
||||
`quoted' region, which may have args that *look* like
|
||||
options, so we definitely shouldn't try to use getopt past
|
||||
here, whatever happens. */
|
||||
parser->state.quoted = parser->state.next;
|
||||
}
|
||||
else if (opt == KEY_ERR && optopt != KEY_END)
|
||||
/* KEY_ERR can have the same value as a valid user short
|
||||
option, but in the case of a real error, getopt sets OPTOPT
|
||||
to the offending character, which can never be KEY_END. */
|
||||
{
|
||||
*arg_ebadkey = 0;
|
||||
return EBADKEY;
|
||||
}
|
||||
}
|
||||
else
|
||||
opt = KEY_END;
|
||||
|
||||
if (opt == KEY_END)
|
||||
/* We're past what getopt considers the options. */
|
||||
if (parser->state.next >= parser->state.argc
|
||||
|| (parser->state.flags & ARGP_NO_ARGS))
|
||||
/* Indicate that we're done. */
|
||||
{
|
||||
*arg_ebadkey = 1;
|
||||
return EBADKEY;
|
||||
}
|
||||
else
|
||||
/* A non-option arg. */
|
||||
err =
|
||||
parser_parse_arg (parser, parser->state.argv[parser->state.next++]);
|
||||
else if (opt == KEY_ARG)
|
||||
/* A non-option argument; try each parser in turn. */
|
||||
err = parser_parse_arg (parser, optarg);
|
||||
else
|
||||
err = parser_parse_opt (parser, opt, optarg);
|
||||
|
||||
if (err == EBADKEY)
|
||||
{
|
||||
*arg_ebadkey = (opt == KEY_END || opt == KEY_ARG);
|
||||
parser->state.next--; /* Put back the unused argument. */
|
||||
}
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
/* Parse the options strings in ARGC & ARGV according to the argp in ARGP.
|
||||
FLAGS is one of the ARGP_ flags above. If END_INDEX is non-NULL, the
|
||||
index in ARGV of the first unparsed option is returned in it. If an
|
||||
unknown option is present, EINVAL is returned; if some parser routine
|
||||
returned a non-zero value, it is returned; otherwise 0 is returned. */
|
||||
error_t
|
||||
__argp_parse (const struct argp *argp, int argc, char **argv, unsigned flags,
|
||||
int *end_index, void *input)
|
||||
{
|
||||
error_t err;
|
||||
struct parser parser;
|
||||
|
||||
/* If true, then err == EBADKEY is a result of a non-option argument failing
|
||||
to be parsed (which in some cases isn't actually an error). */
|
||||
int arg_ebadkey = 0;
|
||||
|
||||
if (! (flags & ARGP_NO_HELP))
|
||||
/* Add our own options. */
|
||||
{
|
||||
struct argp_child *child = alloca (4 * sizeof (struct argp_child));
|
||||
struct argp *top_argp = alloca (sizeof (struct argp));
|
||||
|
||||
/* TOP_ARGP has no options, it just serves to group the user & default
|
||||
argps. */
|
||||
memset (top_argp, 0, sizeof (*top_argp));
|
||||
top_argp->children = child;
|
||||
|
||||
memset (child, 0, 4 * sizeof (struct argp_child));
|
||||
|
||||
if (argp)
|
||||
(child++)->argp = argp;
|
||||
(child++)->argp = &argp_default_argp;
|
||||
if (argp_program_version || argp_program_version_hook)
|
||||
(child++)->argp = &argp_version_argp;
|
||||
child->argp = 0;
|
||||
|
||||
argp = top_argp;
|
||||
}
|
||||
|
||||
/* Construct a parser for these arguments. */
|
||||
err = parser_init (&parser, argp, argc, argv, flags, input);
|
||||
|
||||
if (! err)
|
||||
/* Parse! */
|
||||
{
|
||||
while (! err)
|
||||
err = parser_parse_next (&parser, &arg_ebadkey);
|
||||
err = parser_finalize (&parser, err, arg_ebadkey, end_index);
|
||||
}
|
||||
|
||||
return err;
|
||||
}
|
||||
#ifdef weak_alias
|
||||
weak_alias (__argp_parse, argp_parse)
|
||||
#endif
|
||||
|
||||
/* Return the input field for ARGP in the parser corresponding to STATE; used
|
||||
by the help routines. */
|
||||
void *
|
||||
__argp_input (const struct argp *argp, const struct argp_state *state)
|
||||
{
|
||||
if (state)
|
||||
{
|
||||
struct group *group;
|
||||
struct parser *parser = state->pstate;
|
||||
|
||||
for (group = parser->groups; group < parser->egroup; group++)
|
||||
if (group->argp == argp)
|
||||
return group->input;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
#ifdef weak_alias
|
||||
weak_alias (__argp_input, _argp_input)
|
||||
#endif
|
||||
@@ -0,0 +1,25 @@
|
||||
/* Default definition for ARGP_PROGRAM_VERSION.
|
||||
Copyright (C) 1996, 1997 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
Written by Miles Bader <miles@gnu.ai.mit.edu>.
|
||||
|
||||
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. */
|
||||
|
||||
/* If set by the user program to a non-zero value, then a default option
|
||||
--version is added (unless the ARGP_NO_HELP flag is used), which will
|
||||
print this this string followed by a newline and exit (unless the
|
||||
ARGP_NO_EXIT flag is used). Overridden by ARGP_PROGRAM_VERSION_HOOK. */
|
||||
const char *argp_program_version = 0;
|
||||
@@ -0,0 +1,32 @@
|
||||
/* Default definition for ARGP_PROGRAM_VERSION_HOOK.
|
||||
Copyright (C) 1996, 1997 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
Written by Miles Bader <miles@gnu.ai.mit.edu>.
|
||||
|
||||
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. */
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <config.h>
|
||||
#endif
|
||||
|
||||
#include "argp.h"
|
||||
|
||||
/* If set by the user program to a non-zero value, then a default option
|
||||
--version is added (unless the ARGP_NO_HELP flag is used), which calls
|
||||
this function with a stream to print the version to and a pointer to the
|
||||
current parsing state, and then exits (unless the ARGP_NO_EXIT flag is
|
||||
used). This variable takes precedent over ARGP_PROGRAM_VERSION. */
|
||||
void (*argp_program_version_hook) (FILE *stream, struct argp_state *state) = 0;
|
||||
@@ -0,0 +1,209 @@
|
||||
/* Test program for argp argument parser
|
||||
Copyright (C) 1997 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
Written by Miles Bader <miles@gnu.ai.mit.edu>.
|
||||
|
||||
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. */
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <config.h>
|
||||
#endif
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <time.h>
|
||||
#include <string.h>
|
||||
#include <argp.h>
|
||||
|
||||
const char *argp_program_version = "argp-test 1.0";
|
||||
|
||||
struct argp_option sub_options[] =
|
||||
{
|
||||
{"subopt1", 's', 0, 0, "Nested option 1"},
|
||||
{"subopt2", 'S', 0, 0, "Nested option 2"},
|
||||
|
||||
{ 0, 0, 0, 0, "Some more nested options:", 10},
|
||||
{"subopt3", 'p', 0, 0, "Nested option 3"},
|
||||
|
||||
{"subopt4", 'q', 0, 0, "Nested option 4", 1},
|
||||
|
||||
{0}
|
||||
};
|
||||
|
||||
static const char sub_args_doc[] = "STRING...\n-";
|
||||
static const char sub_doc[] = "\vThis is the doc string from the sub-arg-parser.";
|
||||
|
||||
static error_t
|
||||
sub_parse_opt (int key, char *arg, struct argp_state *state)
|
||||
{
|
||||
switch (key)
|
||||
{
|
||||
case ARGP_KEY_NO_ARGS:
|
||||
printf ("NO SUB ARGS\n");
|
||||
break;
|
||||
case ARGP_KEY_ARG:
|
||||
printf ("SUB ARG: %s\n", arg);
|
||||
break;
|
||||
|
||||
case 's' : case 'S': case 'p': case 'q':
|
||||
printf ("SUB KEY %c\n", key);
|
||||
break;
|
||||
|
||||
default:
|
||||
return ARGP_ERR_UNKNOWN;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static char *
|
||||
sub_help_filter (int key, const char *text, void *input)
|
||||
{
|
||||
if (key == ARGP_KEY_HELP_EXTRA)
|
||||
return strdup ("This is some extra text from the sub parser (note that it \
|
||||
is preceded by a blank line).");
|
||||
else
|
||||
return (char *)text;
|
||||
}
|
||||
|
||||
static struct argp sub_argp = {
|
||||
sub_options, sub_parse_opt, sub_args_doc, sub_doc, 0, sub_help_filter
|
||||
};
|
||||
|
||||
/* Structure used to communicate with the parsing functions. */
|
||||
struct params
|
||||
{
|
||||
unsigned foonly; /* Value parsed for foonly. */
|
||||
unsigned foonly_default; /* Default value for it. */
|
||||
};
|
||||
|
||||
#define OPT_PGRP 1
|
||||
#define OPT_SESS 2
|
||||
|
||||
struct argp_option options[] =
|
||||
{
|
||||
{"pid", 'p', "PID", 0, "List the process PID"},
|
||||
{"pgrp", OPT_PGRP,"PGRP",0, "List processes in the process group PGRP"},
|
||||
{"no-parent", 'P', 0, 0, "Include processes without parents"},
|
||||
{0, 'x', 0, OPTION_ALIAS},
|
||||
{"all-fields",'Q', 0, 0, "Don't elide unusable fields (normally"
|
||||
" if there's some reason ps can't"
|
||||
" print a field for any process, it's"
|
||||
" removed from the output entirely)" },
|
||||
{"reverse", 'r', 0, 0, "Reverse the order of any sort"},
|
||||
{"gratuitously-long-reverse-option", 0, 0, OPTION_ALIAS},
|
||||
{"session", OPT_SESS,"SID", OPTION_ARG_OPTIONAL,
|
||||
"Add the processes from the session"
|
||||
" SID (which defaults to the sid of"
|
||||
" the current process)" },
|
||||
|
||||
{0,0,0,0, "Here are some more options:"},
|
||||
{"foonly", 'f', "ZOT", OPTION_ARG_OPTIONAL, "Glork a foonly"},
|
||||
{"zaza", 'z', 0, 0, "Snit a zar"},
|
||||
|
||||
{0}
|
||||
};
|
||||
|
||||
static const char args_doc[] = "STRING";
|
||||
static const char doc[] = "Test program for argp."
|
||||
"\vThis doc string comes after the options."
|
||||
"\nHey! Some manual formatting!"
|
||||
"\nThe current time is: %s";
|
||||
|
||||
static void
|
||||
popt (int key, char *arg)
|
||||
{
|
||||
char buf[10];
|
||||
if (isprint (key))
|
||||
sprintf (buf, "%c", key);
|
||||
else
|
||||
sprintf (buf, "%d", key);
|
||||
if (arg)
|
||||
printf ("KEY %s: %s\n", buf, arg);
|
||||
else
|
||||
printf ("KEY %s\n", buf);
|
||||
}
|
||||
|
||||
static error_t
|
||||
parse_opt (int key, char *arg, struct argp_state *state)
|
||||
{
|
||||
struct params *params = state->input;
|
||||
|
||||
switch (key)
|
||||
{
|
||||
case ARGP_KEY_NO_ARGS:
|
||||
printf ("NO ARGS\n");
|
||||
break;
|
||||
|
||||
case ARGP_KEY_ARG:
|
||||
if (state->arg_num > 0)
|
||||
return ARGP_ERR_UNKNOWN; /* Leave it for the sub-arg parser. */
|
||||
printf ("ARG: %s\n", arg);
|
||||
break;
|
||||
|
||||
case 'f':
|
||||
if (arg)
|
||||
params->foonly = atoi (arg);
|
||||
else
|
||||
params->foonly = params->foonly_default;
|
||||
popt (key, arg);
|
||||
break;
|
||||
|
||||
case 'p': case 'P': case OPT_PGRP: case 'x': case 'Q':
|
||||
case 'r': case OPT_SESS: case 'z':
|
||||
popt (key, arg);
|
||||
break;
|
||||
|
||||
default:
|
||||
return ARGP_ERR_UNKNOWN;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static char *
|
||||
help_filter (int key, const char *text, void *input)
|
||||
{
|
||||
char *new_text;
|
||||
struct params *params = input;
|
||||
|
||||
if (key == ARGP_KEY_HELP_POST_DOC && text)
|
||||
{
|
||||
time_t now = time (0);
|
||||
asprintf (&new_text, text, ctime (&now));
|
||||
}
|
||||
else if (key == 'f')
|
||||
/* Show the default for the --foonly option. */
|
||||
asprintf (&new_text, "%s (ZOT defaults to %x)",
|
||||
text, params->foonly_default);
|
||||
else
|
||||
new_text = (char *)text;
|
||||
|
||||
return new_text;
|
||||
}
|
||||
|
||||
static struct argp_child argp_children[] = { { &sub_argp }, { 0 } };
|
||||
static struct argp argp = {
|
||||
options, parse_opt, args_doc, doc, argp_children, help_filter
|
||||
};
|
||||
|
||||
int
|
||||
main (int argc, char **argv)
|
||||
{
|
||||
struct params params;
|
||||
params.foonly = 0;
|
||||
params.foonly_default = random ();
|
||||
argp_parse (&argp, argc, argv, 0, 0, ¶ms);
|
||||
printf ("After parsing: foonly = %x\n", params.foonly);
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
/* Real definitions for extern inline functions in argp.h
|
||||
Copyright (C) 1997 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
Written by Miles Bader <miles@gnu.ai.mit.edu>.
|
||||
|
||||
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. */
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <config.h>
|
||||
#endif
|
||||
|
||||
#define ARGP_EI
|
||||
#undef __OPTIMIZE__
|
||||
#define __OPTIMIZE__
|
||||
#include "argp.h"
|
||||
|
||||
/* Add weak aliases. */
|
||||
#if _LIBC - 0 && defined (weak_alias)
|
||||
|
||||
weak_alias (__argp_usage, argp_usage)
|
||||
weak_alias (__option_is_short, _option_is_short)
|
||||
weak_alias (__option_is_end, _option_is_end)
|
||||
|
||||
#endif
|
||||
+551
@@ -0,0 +1,551 @@
|
||||
/* Hierarchial argument parsing, layered over getopt.
|
||||
Copyright (C) 1995, 1996, 1997 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
Written by Miles Bader <miles@gnu.ai.mit.edu>.
|
||||
|
||||
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 __ARGP_H__
|
||||
#define __ARGP_H__
|
||||
|
||||
#include <stdio.h>
|
||||
#include <ctype.h>
|
||||
#include <getopt.h>
|
||||
|
||||
#define __need_error_t
|
||||
#include <errno.h>
|
||||
|
||||
#ifndef __const
|
||||
#define __const const
|
||||
#endif
|
||||
|
||||
#ifndef __error_t_defined
|
||||
typedef int error_t;
|
||||
#endif
|
||||
|
||||
#ifndef __P
|
||||
# if (defined (__STDC__) && __STDC__) || defined (__cplusplus)
|
||||
# define __P(args) args
|
||||
# else
|
||||
# define __P(args) ()
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* A description of a particular option. A pointer to an array of
|
||||
these is passed in the OPTIONS field of an argp structure. Each option
|
||||
entry can correspond to one long option and/or one short option; more
|
||||
names for the same option can be added by following an entry in an option
|
||||
array with options having the OPTION_ALIAS flag set. */
|
||||
struct argp_option
|
||||
{
|
||||
/* The long option name. For more than one name for the same option, you
|
||||
can use following options with the OPTION_ALIAS flag set. */
|
||||
__const char *name;
|
||||
|
||||
/* What key is returned for this option. If > 0 and printable, then it's
|
||||
also accepted as a short option. */
|
||||
int key;
|
||||
|
||||
/* If non-NULL, this is the name of the argument associated with this
|
||||
option, which is required unless the OPTION_ARG_OPTIONAL flag is set. */
|
||||
__const char *arg;
|
||||
|
||||
/* OPTION_ flags. */
|
||||
int flags;
|
||||
|
||||
/* The doc string for this option. If both NAME and KEY are 0, This string
|
||||
will be printed outdented from the normal option column, making it
|
||||
useful as a group header (it will be the first thing printed in its
|
||||
group); in this usage, it's conventional to end the string with a `:'. */
|
||||
__const char *doc;
|
||||
|
||||
/* The group this option is in. In a long help message, options are sorted
|
||||
alphabetically within each group, and the groups presented in the order
|
||||
0, 1, 2, ..., n, -m, ..., -2, -1. Every entry in an options array with
|
||||
if this field 0 will inherit the group number of the previous entry, or
|
||||
zero if it's the first one, unless its a group header (NAME and KEY both
|
||||
0), in which case, the previous entry + 1 is the default. Automagic
|
||||
options such as --help are put into group -1. */
|
||||
int group;
|
||||
};
|
||||
|
||||
/* The argument associated with this option is optional. */
|
||||
#define OPTION_ARG_OPTIONAL 0x1
|
||||
|
||||
/* This option isn't displayed in any help messages. */
|
||||
#define OPTION_HIDDEN 0x2
|
||||
|
||||
/* This option is an alias for the closest previous non-alias option. This
|
||||
means that it will be displayed in the same help entry, and will inherit
|
||||
fields other than NAME and KEY from the aliased option. */
|
||||
#define OPTION_ALIAS 0x4
|
||||
|
||||
/* This option isn't actually an option (and so should be ignored by the
|
||||
actual option parser), but rather an arbitrary piece of documentation that
|
||||
should be displayed in much the same manner as the options. If this flag
|
||||
is set, then the option NAME field is displayed unmodified (e.g., no `--'
|
||||
prefix is added) at the left-margin (where a *short* option would normally
|
||||
be displayed), and the documentation string in the normal place. For
|
||||
purposes of sorting, any leading whitespace and puncuation is ignored,
|
||||
except that if the first non-whitespace character is not `-', this entry
|
||||
is displayed after all options (and OPTION_DOC entries with a leading `-')
|
||||
in the same group. */
|
||||
#define OPTION_DOC 0x8
|
||||
|
||||
/* This option shouldn't be included in `long' usage messages (but is still
|
||||
included in help messages). This is mainly intended for options that are
|
||||
completely documented in an argp's ARGS_DOC field, in which case including
|
||||
the option in the generic usage list would be redundant. For instance,
|
||||
if ARGS_DOC is "FOO BAR\n-x BLAH", and the `-x' option's purpose is to
|
||||
distinguish these two cases, -x should probably be marked
|
||||
OPTION_NO_USAGE. */
|
||||
#define OPTION_NO_USAGE 0x10
|
||||
|
||||
struct argp; /* fwd declare this type */
|
||||
struct argp_state; /* " */
|
||||
struct argp_child; /* " */
|
||||
|
||||
/* The type of a pointer to an argp parsing function. */
|
||||
typedef error_t (*argp_parser_t)(int key, char *arg, struct argp_state *state);
|
||||
|
||||
/* What to return for unrecognized keys. For special ARGP_KEY_ keys, such
|
||||
returns will simply be ignored. For user keys, this error will be turned
|
||||
into EINVAL (if the call to argp_parse is such that errors are propagated
|
||||
back to the user instead of exiting); returning EINVAL itself would result
|
||||
in an immediate stop to parsing in *all* cases. */
|
||||
#define ARGP_ERR_UNKNOWN E2BIG /* Hurd should never need E2BIG. XXX */
|
||||
|
||||
/* Special values for the KEY argument to an argument parsing function.
|
||||
ARGP_ERR_UNKNOWN should be returned if they aren't understood.
|
||||
|
||||
The sequence of keys to a parsing function is either (where each
|
||||
uppercased word should be prefixed by `ARGP_KEY_' and opt is a user key):
|
||||
|
||||
INIT opt... NO_ARGS END SUCCESS -- No non-option arguments at all
|
||||
or INIT (opt | ARG)... END SUCCESS -- All non-option args parsed
|
||||
or INIT (opt | ARG)... SUCCESS -- Some non-option arg unrecognized
|
||||
|
||||
The third case is where every parser returned ARGP_KEY_UNKNOWN for an
|
||||
argument, in which case parsing stops at that argument (returning the
|
||||
unparsed arguments to the caller of argp_parse if requested, or stopping
|
||||
with an error message if not).
|
||||
|
||||
If an error occurs (either detected by argp, or because the parsing
|
||||
function returned an error value), then the parser is called with
|
||||
ARGP_KEY_ERROR, and no further calls are made. */
|
||||
|
||||
/* This is not an option at all, but rather a command line argument. If a
|
||||
parser receiving this key returns success, the fact is recorded, and the
|
||||
ARGP_KEY_NO_ARGS case won't be used. HOWEVER, if while processing the
|
||||
argument, a parser function decrements the NEXT field of the state it's
|
||||
passed, the option won't be considered processed; this is to allow you to
|
||||
actually modify the argument (perhaps into an option), and have it
|
||||
processed again. */
|
||||
#define ARGP_KEY_ARG 0
|
||||
/* There are no more command line arguments at all. */
|
||||
#define ARGP_KEY_END 0x1000001
|
||||
/* Because it's common to want to do some special processing if there aren't
|
||||
any non-option args, user parsers are called with this key if they didn't
|
||||
successfully process any non-option arguments. Called just before
|
||||
ARGP_KEY_END (where more general validity checks on previously parsed
|
||||
arguments can take place). */
|
||||
#define ARGP_KEY_NO_ARGS 0x1000002
|
||||
/* Passed in before any parsing is done. Afterwards, the values of each
|
||||
element of the CHILD_INPUT field, if any, in the state structure is
|
||||
copied to each child's state to be the initial value of the INPUT field. */
|
||||
#define ARGP_KEY_INIT 0x1000003
|
||||
/* Passed in when parsing has successfully been completed (even if there are
|
||||
still arguments remaining). */
|
||||
#define ARGP_KEY_SUCCESS 0x1000004
|
||||
/* Passed in if an error occurs (in which case a call with ARGP_KEY_SUCCESS is
|
||||
never made, so any cleanup must be done here). */
|
||||
#define ARGP_KEY_ERROR 0x1000005
|
||||
|
||||
/* An argp structure contains a set of options declarations, a function to
|
||||
deal with parsing one, documentation string, a possible vector of child
|
||||
argp's, and perhaps a function to filter help output. When actually
|
||||
parsing options, getopt is called with the union of all the argp
|
||||
structures chained together through their CHILD pointers, with conflicts
|
||||
being resolved in favor of the first occurance in the chain. */
|
||||
struct argp
|
||||
{
|
||||
/* An array of argp_option structures, terminated by an entry with both
|
||||
NAME and KEY having a value of 0. */
|
||||
__const struct argp_option *options;
|
||||
|
||||
/* What to do with an option from this structure. KEY is the key
|
||||
associated with the option, and ARG is any associated argument (NULL if
|
||||
none was supplied). If KEY isn't understood, ARGP_ERR_UNKNOWN should be
|
||||
returned. If a non-zero, non-ARGP_ERR_UNKNOWN value is returned, then
|
||||
parsing is stopped immediately, and that value is returned from
|
||||
argp_parse(). For special (non-user-supplied) values of KEY, see the
|
||||
ARGP_KEY_ definitions below. */
|
||||
argp_parser_t parser;
|
||||
|
||||
/* A string describing what other arguments are wanted by this program. It
|
||||
is only used by argp_usage to print the `Usage:' message. If it
|
||||
contains newlines, the strings separated by them are considered
|
||||
alternative usage patterns, and printed on separate lines (lines after
|
||||
the first are prefix by ` or: ' instead of `Usage:'). */
|
||||
__const char *args_doc;
|
||||
|
||||
/* If non-NULL, a string containing extra text to be printed before and
|
||||
after the options in a long help message (separated by a vertical tab
|
||||
`\v' character). */
|
||||
__const char *doc;
|
||||
|
||||
/* A vector of argp_children structures, terminated by a member with a 0
|
||||
argp field, pointing to child argps should be parsed with this one. Any
|
||||
conflicts are resolved in favor of this argp, or early argps in the
|
||||
CHILDREN list. This field is useful if you use libraries that supply
|
||||
their own argp structure, which you want to use in conjunction with your
|
||||
own. */
|
||||
__const struct argp_child *children;
|
||||
|
||||
/* If non-zero, this should be a function to filter the output of help
|
||||
messages. KEY is either a key from an option, in which case TEXT is
|
||||
that option's help text, or a special key from the ARGP_KEY_HELP_
|
||||
defines, below, describing which other help text TEXT is. The function
|
||||
should return either TEXT, if it should be used as-is, a replacement
|
||||
string, which should be malloced, and will be freed by argp, or NULL,
|
||||
meaning `print nothing'. The value for TEXT is *after* any translation
|
||||
has been done, so if any of the replacement text also needs translation,
|
||||
that should be done by the filter function. INPUT is either the input
|
||||
supplied to argp_parse, or NULL, if argp_help was called directly. */
|
||||
char *(*help_filter)(int __key, __const char *__text, void *__input);
|
||||
};
|
||||
|
||||
/* Possible KEY arguments to a help filter function. */
|
||||
#define ARGP_KEY_HELP_PRE_DOC 0x2000001 /* Help text preceeding options. */
|
||||
#define ARGP_KEY_HELP_POST_DOC 0x2000002 /* Help text following options. */
|
||||
#define ARGP_KEY_HELP_HEADER 0x2000003 /* Option header string. */
|
||||
#define ARGP_KEY_HELP_EXTRA 0x2000004 /* After all other documentation;
|
||||
TEXT is NULL for this key. */
|
||||
/* Explanatory note emitted when duplicate option arguments have been
|
||||
suppressed. */
|
||||
#define ARGP_KEY_HELP_DUP_ARGS_NOTE 0x2000005
|
||||
|
||||
/* When an argp has a non-zero CHILDREN field, it should point to a vector of
|
||||
argp_child structures, each of which describes a subsidiary argp. */
|
||||
struct argp_child
|
||||
{
|
||||
/* The child parser. */
|
||||
__const struct argp *argp;
|
||||
|
||||
/* Flags for this child. */
|
||||
int flags;
|
||||
|
||||
/* If non-zero, an optional header to be printed in help output before the
|
||||
child options. As a side-effect, a non-zero value forces the child
|
||||
options to be grouped together; to achieve this effect without actually
|
||||
printing a header string, use a value of "". */
|
||||
__const char *header;
|
||||
|
||||
/* Where to group the child options relative to the other (`consolidated')
|
||||
options in the parent argp; the values are the same as the GROUP field
|
||||
in argp_option structs, but all child-groupings follow parent options at
|
||||
a particular group level. If both this field and HEADER are zero, then
|
||||
they aren't grouped at all, but rather merged with the parent options
|
||||
(merging the child's grouping levels with the parents). */
|
||||
int group;
|
||||
};
|
||||
|
||||
/* Parsing state. This is provided to parsing functions called by argp,
|
||||
which may examine and, as noted, modify fields. */
|
||||
struct argp_state
|
||||
{
|
||||
/* The top level ARGP being parsed. */
|
||||
__const struct argp *argp;
|
||||
|
||||
/* The argument vector being parsed. May be modified. */
|
||||
int argc;
|
||||
char **argv;
|
||||
|
||||
/* The index in ARGV of the next arg that to be parsed. May be modified. */
|
||||
int next;
|
||||
|
||||
/* The flags supplied to argp_parse. May be modified. */
|
||||
unsigned flags;
|
||||
|
||||
/* While calling a parsing function with a key of ARGP_KEY_ARG, this is the
|
||||
number of the current arg, starting at zero, and incremented after each
|
||||
such call returns. At all other times, this is the number of such
|
||||
arguments that have been processed. */
|
||||
unsigned arg_num;
|
||||
|
||||
/* If non-zero, the index in ARGV of the first argument following a special
|
||||
`--' argument (which prevents anything following being interpreted as an
|
||||
option). Only set once argument parsing has proceeded past this point. */
|
||||
int quoted;
|
||||
|
||||
/* An arbitrary pointer passed in from the user. */
|
||||
void *input;
|
||||
/* Values to pass to child parsers. This vector will be the same length as
|
||||
the number of children for the current parser. */
|
||||
void **child_inputs;
|
||||
|
||||
/* For the parser's use. Initialized to 0. */
|
||||
void *hook;
|
||||
|
||||
/* The name used when printing messages. This is initialized to ARGV[0],
|
||||
or PROGRAM_INVOCATION_NAME if that is unavailable. */
|
||||
char *name;
|
||||
|
||||
/* Streams used when argp prints something. */
|
||||
FILE *err_stream; /* For errors; initialized to stderr. */
|
||||
FILE *out_stream; /* For information; initialized to stdout. */
|
||||
|
||||
void *pstate; /* Private, for use by argp. */
|
||||
};
|
||||
|
||||
/* Flags for argp_parse (note that the defaults are those that are
|
||||
convenient for program command line parsing): */
|
||||
|
||||
/* Don't ignore the first element of ARGV. Normally (and always unless
|
||||
ARGP_NO_ERRS is set) the first element of the argument vector is
|
||||
skipped for option parsing purposes, as it corresponds to the program name
|
||||
in a command line. */
|
||||
#define ARGP_PARSE_ARGV0 0x01
|
||||
|
||||
/* Don't print error messages for unknown options to stderr; unless this flag
|
||||
is set, ARGP_PARSE_ARGV0 is ignored, as ARGV[0] is used as the program
|
||||
name in the error messages. This flag implies ARGP_NO_EXIT (on the
|
||||
assumption that silent exiting upon errors is bad behaviour). */
|
||||
#define ARGP_NO_ERRS 0x02
|
||||
|
||||
/* Don't parse any non-option args. Normally non-option args are parsed by
|
||||
calling the parse functions with a key of ARGP_KEY_ARG, and the actual arg
|
||||
as the value. Since it's impossible to know which parse function wants to
|
||||
handle it, each one is called in turn, until one returns 0 or an error
|
||||
other than ARGP_ERR_UNKNOWN; if an argument is handled by no one, the
|
||||
argp_parse returns prematurely (but with a return value of 0). If all
|
||||
args have been parsed without error, all parsing functions are called one
|
||||
last time with a key of ARGP_KEY_END. This flag needn't normally be set,
|
||||
as the normal behavior is to stop parsing as soon as some argument can't
|
||||
be handled. */
|
||||
#define ARGP_NO_ARGS 0x04
|
||||
|
||||
/* Parse options and arguments in the same order they occur on the command
|
||||
line -- normally they're rearranged so that all options come first. */
|
||||
#define ARGP_IN_ORDER 0x08
|
||||
|
||||
/* Don't provide the standard long option --help, which causes usage and
|
||||
option help information to be output to stdout, and exit (0) called. */
|
||||
#define ARGP_NO_HELP 0x10
|
||||
|
||||
/* Don't exit on errors (they may still result in error messages). */
|
||||
#define ARGP_NO_EXIT 0x20
|
||||
|
||||
/* Use the gnu getopt `long-only' rules for parsing arguments. */
|
||||
#define ARGP_LONG_ONLY 0x40
|
||||
|
||||
/* Turns off any message-printing/exiting options. */
|
||||
#define ARGP_SILENT (ARGP_NO_EXIT | ARGP_NO_ERRS | ARGP_NO_HELP)
|
||||
|
||||
/* Parse the options strings in ARGC & ARGV according to the options in ARGP.
|
||||
FLAGS is one of the ARGP_ flags above. If ARG_INDEX is non-NULL, the
|
||||
index in ARGV of the first unparsed option is returned in it. If an
|
||||
unknown option is present, ARGP_ERR_UNKNOWN is returned; if some parser
|
||||
routine returned a non-zero value, it is returned; otherwise 0 is
|
||||
returned. This function may also call exit unless the ARGP_NO_HELP flag
|
||||
is set. INPUT is a pointer to a value to be passed in to the parser. */
|
||||
extern error_t argp_parse __P ((__const struct argp *__argp,
|
||||
int __argc, char **__argv, unsigned __flags,
|
||||
int *__arg_index, void *__input));
|
||||
extern error_t __argp_parse __P ((__const struct argp *__argp,
|
||||
int __argc, char **__argv, unsigned __flags,
|
||||
int *__arg_index, void *__input));
|
||||
|
||||
/* Global variables. */
|
||||
|
||||
/* If defined or set by the user program to a non-zero value, then a default
|
||||
option --version is added (unless the ARGP_NO_HELP flag is used), which
|
||||
will print this string followed by a newline and exit (unless the
|
||||
ARGP_NO_EXIT flag is used). Overridden by ARGP_PROGRAM_VERSION_HOOK. */
|
||||
extern __const char *argp_program_version;
|
||||
|
||||
/* If defined or set by the user program to a non-zero value, then a default
|
||||
option --version is added (unless the ARGP_NO_HELP flag is used), which
|
||||
calls this function with a stream to print the version to and a pointer to
|
||||
the current parsing state, and then exits (unless the ARGP_NO_EXIT flag is
|
||||
used). This variable takes precedent over ARGP_PROGRAM_VERSION. */
|
||||
extern void (*argp_program_version_hook) __P ((FILE *__stream,
|
||||
struct argp_state *__state));
|
||||
|
||||
/* If defined or set by the user program, it should point to string that is
|
||||
the bug-reporting address for the program. It will be printed by
|
||||
argp_help if the ARGP_HELP_BUG_ADDR flag is set (as it is by various
|
||||
standard help messages), embedded in a sentence that says something like
|
||||
`Report bugs to ADDR.'. */
|
||||
__const extern char *argp_program_bug_address;
|
||||
|
||||
/* The exit status that argp will use when exiting due to a parsing error.
|
||||
If not defined or set by the user program, this defaults to 1. */
|
||||
extern error_t argp_err_exit_status;
|
||||
|
||||
/* Flags for argp_help. */
|
||||
#define ARGP_HELP_USAGE 0x01 /* a Usage: message. */
|
||||
#define ARGP_HELP_SHORT_USAGE 0x02 /* " but don't actually print options. */
|
||||
#define ARGP_HELP_SEE 0x04 /* a `Try ... for more help' message. */
|
||||
#define ARGP_HELP_LONG 0x08 /* a long help message. */
|
||||
#define ARGP_HELP_PRE_DOC 0x10 /* doc string preceding long help. */
|
||||
#define ARGP_HELP_POST_DOC 0x20 /* doc string following long help. */
|
||||
#define ARGP_HELP_DOC (ARGP_HELP_PRE_DOC | ARGP_HELP_POST_DOC)
|
||||
#define ARGP_HELP_BUG_ADDR 0x40 /* bug report address */
|
||||
#define ARGP_HELP_LONG_ONLY 0x80 /* modify output appropriately to
|
||||
reflect ARGP_LONG_ONLY mode. */
|
||||
|
||||
/* These ARGP_HELP flags are only understood by argp_state_help. */
|
||||
#define ARGP_HELP_EXIT_ERR 0x100 /* Call exit(1) instead of returning. */
|
||||
#define ARGP_HELP_EXIT_OK 0x200 /* Call exit(0) instead of returning. */
|
||||
|
||||
/* The standard thing to do after a program command line parsing error, if an
|
||||
error message has already been printed. */
|
||||
#define ARGP_HELP_STD_ERR \
|
||||
(ARGP_HELP_SEE | ARGP_HELP_EXIT_ERR)
|
||||
/* The standard thing to do after a program command line parsing error, if no
|
||||
more specific error message has been printed. */
|
||||
#define ARGP_HELP_STD_USAGE \
|
||||
(ARGP_HELP_SHORT_USAGE | ARGP_HELP_SEE | ARGP_HELP_EXIT_ERR)
|
||||
/* The standard thing to do in response to a --help option. */
|
||||
#define ARGP_HELP_STD_HELP \
|
||||
(ARGP_HELP_SHORT_USAGE | ARGP_HELP_LONG | ARGP_HELP_EXIT_OK \
|
||||
| ARGP_HELP_DOC | ARGP_HELP_BUG_ADDR)
|
||||
|
||||
/* Output a usage message for ARGP to STREAM. FLAGS are from the set
|
||||
ARGP_HELP_*. */
|
||||
extern void argp_help __P ((__const struct argp *__argp, FILE *__stream,
|
||||
unsigned __flags, char *__name));
|
||||
extern void __argp_help __P ((__const struct argp *__argp, FILE *__stream,
|
||||
unsigned __flags, char *__name));
|
||||
|
||||
/* The following routines are intended to be called from within an argp
|
||||
parsing routine (thus taking an argp_state structure as the first
|
||||
argument). They may or may not print an error message and exit, depending
|
||||
on the flags in STATE -- in any case, the caller should be prepared for
|
||||
them *not* to exit, and should return an appropiate error after calling
|
||||
them. [argp_usage & argp_error should probably be called argp_state_...,
|
||||
but they're used often enough that they should be short] */
|
||||
|
||||
/* Output, if appropriate, a usage message for STATE to STREAM. FLAGS are
|
||||
from the set ARGP_HELP_*. */
|
||||
extern void argp_state_help __P ((__const struct argp_state *__state,
|
||||
FILE *__stream, unsigned __flags));
|
||||
extern void __argp_state_help __P ((__const struct argp_state *__state,
|
||||
FILE *__stream, unsigned __flags));
|
||||
|
||||
/* Possibly output the standard usage message for ARGP to stderr and exit. */
|
||||
extern void argp_usage __P ((__const struct argp_state *__state));
|
||||
extern void __argp_usage __P ((__const struct argp_state *__state));
|
||||
|
||||
/* If appropriate, print the printf string FMT and following args, preceded
|
||||
by the program name and `:', to stderr, and followed by a `Try ... --help'
|
||||
message, then exit (1). */
|
||||
extern void argp_error __P ((__const struct argp_state *__state,
|
||||
__const char *__fmt, ...))
|
||||
__attribute__ ((__format__ (__printf__, 2, 3)));
|
||||
extern void __argp_error __P ((__const struct argp_state *__state,
|
||||
__const char *__fmt, ...))
|
||||
__attribute__ ((__format__ (__printf__, 2, 3)));
|
||||
|
||||
/* Similar to the standard gnu error-reporting function error(), but will
|
||||
respect the ARGP_NO_EXIT and ARGP_NO_ERRS flags in STATE, and will print
|
||||
to STATE->err_stream. This is useful for argument parsing code that is
|
||||
shared between program startup (when exiting is desired) and runtime
|
||||
option parsing (when typically an error code is returned instead). The
|
||||
difference between this function and argp_error is that the latter is for
|
||||
*parsing errors*, and the former is for other problems that occur during
|
||||
parsing but don't reflect a (syntactic) problem with the input. */
|
||||
extern void argp_failure __P ((__const struct argp_state *__state,
|
||||
int __status, int __errnum,
|
||||
__const char *__fmt, ...))
|
||||
__attribute__ ((__format__ (__printf__, 4, 5)));
|
||||
extern void __argp_failure __P ((__const struct argp_state *__state,
|
||||
int __status, int __errnum,
|
||||
__const char *__fmt, ...))
|
||||
__attribute__ ((__format__ (__printf__, 4, 5)));
|
||||
|
||||
/* Returns true if the option OPT is a valid short option. */
|
||||
extern int _option_is_short __P ((__const struct argp_option *__opt));
|
||||
extern int __option_is_short __P ((__const struct argp_option *__opt));
|
||||
|
||||
/* Returns true if the option OPT is in fact the last (unused) entry in an
|
||||
options array. */
|
||||
extern int _option_is_end __P ((__const struct argp_option *__opt));
|
||||
extern int __option_is_end __P ((__const struct argp_option *__opt));
|
||||
|
||||
/* Return the input field for ARGP in the parser corresponding to STATE; used
|
||||
by the help routines. */
|
||||
extern void *_argp_input __P ((__const struct argp *argp,
|
||||
__const struct argp_state *state));
|
||||
extern void *__argp_input __P ((__const struct argp *argp,
|
||||
__const struct argp_state *state));
|
||||
|
||||
#ifdef __OPTIMIZE__
|
||||
|
||||
#if !_LIBC
|
||||
# define __argp_usage argp_usage
|
||||
# define __argp_state_help argp_state_help
|
||||
# define __option_is_short _option_is_short
|
||||
# define __option_is_end _option_is_end
|
||||
#endif
|
||||
|
||||
#ifndef ARGP_EI
|
||||
# define ARGP_EI extern inline
|
||||
#endif
|
||||
|
||||
ARGP_EI void
|
||||
__argp_usage (__const struct argp_state *__state)
|
||||
{
|
||||
__argp_state_help (__state, stderr, ARGP_HELP_STD_USAGE);
|
||||
}
|
||||
|
||||
ARGP_EI int
|
||||
__option_is_short (__const struct argp_option *__opt)
|
||||
{
|
||||
if (__opt->flags & OPTION_DOC)
|
||||
return 0;
|
||||
else
|
||||
{
|
||||
int __key = __opt->key;
|
||||
return __key > 0 && isprint (__key);
|
||||
}
|
||||
}
|
||||
|
||||
ARGP_EI int
|
||||
__option_is_end (__const struct argp_option *__opt)
|
||||
{
|
||||
return !__opt->key && !__opt->name && !__opt->doc && !__opt->group;
|
||||
}
|
||||
|
||||
#if !_LIBC
|
||||
# undef __argp_usage
|
||||
# undef __argp_state_help
|
||||
# undef __option_is_short
|
||||
# undef __option_is_end
|
||||
#endif
|
||||
|
||||
#endif /* __OPTIMIZE__ */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __ARGP_H__ */
|
||||
+12
-3
@@ -1,4 +1,4 @@
|
||||
/* Copyright (C) 1996 Free Software Foundation, Inc.
|
||||
/* Copyright (C) 1996, 1997 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
Contributed by Ulrich Drepper, <drepper@gnu.ai.mit.edu>.
|
||||
|
||||
@@ -34,6 +34,7 @@ catopen (const char *cat_name, int flag)
|
||||
{
|
||||
__nl_catd result;
|
||||
const char *env_var;
|
||||
const char *nlspath;
|
||||
|
||||
result = (__nl_catd) malloc (sizeof (*result));
|
||||
if (result == NULL)
|
||||
@@ -82,8 +83,16 @@ catopen (const char *cat_name, int flag)
|
||||
return (nl_catd) -1;
|
||||
}
|
||||
|
||||
if (__secure_getenv ("NLSPATH") != NULL)
|
||||
result->nlspath = __strdup (getenv ("NLSPATH"));
|
||||
nlspath = __secure_getenv ("NLSPATH");
|
||||
if (nlspath != NULL && *nlspath != '\0')
|
||||
{
|
||||
/* Append the system dependent directory. */
|
||||
size_t len = strlen (nlspath + 1 + sizeof NLSPATH);
|
||||
char *tmp = alloca (len);
|
||||
|
||||
__stpcpy (__stpcpy (__stpcpy (tmp, nlspath), ":"), NLSPATH);
|
||||
nlspath = tmp;
|
||||
}
|
||||
else
|
||||
result->nlspath = __strdup (NLSPATH);
|
||||
|
||||
|
||||
+94
-83
@@ -21,12 +21,12 @@
|
||||
# include <config.h>
|
||||
#endif
|
||||
|
||||
#include <argp.h>
|
||||
#include <ctype.h>
|
||||
#include <endian.h>
|
||||
#include <errno.h>
|
||||
#include <error.h>
|
||||
#include <fcntl.h>
|
||||
#include <getopt.h>
|
||||
#include <locale.h>
|
||||
#include <libintl.h>
|
||||
#include <limits.h>
|
||||
@@ -88,22 +88,55 @@ struct catalog
|
||||
/* If non-zero force creation of new file, not using existing one. */
|
||||
static int force_new;
|
||||
|
||||
/* Long options. */
|
||||
static const struct option long_options[] =
|
||||
/* Name of output file. */
|
||||
static const char *output_name;
|
||||
|
||||
/* Name of generated C header file. */
|
||||
static const char *header_name;
|
||||
|
||||
/* Name and version of program. */
|
||||
static void print_version (FILE *stream, struct argp_state *state);
|
||||
void (*argp_program_version_hook) (FILE *, struct argp_state *) = print_version;
|
||||
|
||||
#define OPT_NEW 1
|
||||
|
||||
/* Definitions of arguments for argp functions. */
|
||||
static const struct argp_option options[] =
|
||||
{
|
||||
{ "header", required_argument, NULL, 'H' },
|
||||
{ "help", no_argument, NULL, 'h' },
|
||||
{ "new", no_argument, &force_new, 1 },
|
||||
{ "output", required_argument, NULL, 'o' },
|
||||
{ "version", no_argument, NULL, 'V' },
|
||||
{ NULL, 0, NULL, 0 }
|
||||
{ "header", 'H', N_("NAME"), 0,
|
||||
N_("Create C header file NAME containing symbol definitions") },
|
||||
{ "new", OPT_NEW, NULL, 0,
|
||||
N_("Do not use existing catalog, force new output file") },
|
||||
{ "output", 'o', N_("NAME"), 0, N_("Write output to file NAME") },
|
||||
{ NULL, 0, NULL, 0, NULL }
|
||||
};
|
||||
|
||||
/* Short description of program. */
|
||||
static const char doc[] = N_("Generate message catalog.\
|
||||
\vIf INPUT-FILE is -, input is read from standard input. If OUTPUT-FILE\n\
|
||||
is -, output is written to standard output.\n");
|
||||
|
||||
/* Strings for arguments in help texts. */
|
||||
static const char args_doc[] = N_("\
|
||||
-o OUTPUT-FILE [INPUT-FILE]...\n[OUTPUT-FILE [INPUT-FILE]...]");
|
||||
|
||||
/* Prototype for option handler. */
|
||||
static error_t parse_opt (int key, char *arg, struct argp_state *state);
|
||||
|
||||
/* Function to print some extra text in the help message. */
|
||||
static char *more_help (int key, const char *text, void *input);
|
||||
|
||||
/* Data structure to communicate with argp functions. */
|
||||
static struct argp argp =
|
||||
{
|
||||
options, parse_opt, args_doc, doc, NULL, more_help
|
||||
};
|
||||
|
||||
|
||||
/* Wrapper functions with error checking for standard functions. */
|
||||
extern void *xmalloc (size_t n);
|
||||
|
||||
/* Prototypes for local functions. */
|
||||
static void usage (int status) __attribute__ ((noreturn));
|
||||
static void error_print (void);
|
||||
static struct catalog *read_input_file (struct catalog *current,
|
||||
const char *fname);
|
||||
@@ -119,11 +152,7 @@ int
|
||||
main (int argc, char *argv[])
|
||||
{
|
||||
struct catalog *result;
|
||||
const char *output_name;
|
||||
const char *header_name;
|
||||
int do_help;
|
||||
int do_version;
|
||||
int opt;
|
||||
int remaining;
|
||||
|
||||
/* Set program name for messages. */
|
||||
error_print_progname = error_print;
|
||||
@@ -135,61 +164,21 @@ main (int argc, char *argv[])
|
||||
textdomain (PACKAGE);
|
||||
|
||||
/* Initialize local variables. */
|
||||
do_help = 0;
|
||||
do_version = 0;
|
||||
output_name = NULL;
|
||||
header_name = NULL;
|
||||
result = NULL;
|
||||
|
||||
while ((opt = getopt_long (argc, argv, "hH:o:V", long_options, NULL)) != -1)
|
||||
switch (opt)
|
||||
{
|
||||
case '\0': /* Long option. */
|
||||
break;
|
||||
case 'h':
|
||||
do_help = 1;
|
||||
break;
|
||||
case 'H':
|
||||
header_name = optarg;
|
||||
break;
|
||||
case 'o':
|
||||
output_name = optarg;
|
||||
break;
|
||||
case 'V':
|
||||
do_version = 1;
|
||||
break;
|
||||
default:
|
||||
usage (EXIT_FAILURE);
|
||||
}
|
||||
|
||||
/* Version information is requested. */
|
||||
if (do_version)
|
||||
{
|
||||
printf ("gencat (GNU %s) %s\n", PACKAGE, VERSION);
|
||||
printf (_("\
|
||||
Copyright (C) %s Free Software Foundation, Inc.\n\
|
||||
This is free software; see the source for copying conditions. There is NO\n\
|
||||
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n\
|
||||
"), "1996, 1997");
|
||||
printf (_("Written by %s.\n"), "Ulrich Drepper");
|
||||
|
||||
exit (EXIT_SUCCESS);
|
||||
}
|
||||
|
||||
/* Help is requested. */
|
||||
if (do_help)
|
||||
usage (EXIT_SUCCESS);
|
||||
/* Parse and process arguments. */
|
||||
argp_parse (&argp, argc, argv, 0, &remaining, NULL);
|
||||
|
||||
/* Determine output file. */
|
||||
if (output_name == NULL)
|
||||
output_name = optind < argc ? argv[optind++] : "-";
|
||||
output_name = remaining < argc ? argv[remaining++] : "-";
|
||||
|
||||
/* Process all input files. */
|
||||
setlocale (LC_CTYPE, "C");
|
||||
if (optind < argc)
|
||||
if (remaining < argc)
|
||||
do
|
||||
result = read_input_file (result, argv[optind]);
|
||||
while (++optind < argc);
|
||||
result = read_input_file (result, argv[remaining]);
|
||||
while (++remaining < argc);
|
||||
else
|
||||
result = read_input_file (NULL, "-");
|
||||
|
||||
@@ -201,32 +190,54 @@ warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n\
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
usage (int status)
|
||||
/* Handle program arguments. */
|
||||
static error_t
|
||||
parse_opt (int key, char *arg, struct argp_state *state)
|
||||
{
|
||||
if (status != EXIT_SUCCESS)
|
||||
fprintf (stderr, gettext ("Try `%s --help' for more information.\n"),
|
||||
program_invocation_name);
|
||||
else
|
||||
switch (key)
|
||||
{
|
||||
printf (gettext ("\
|
||||
Usage: %s [OPTION]... -o OUTPUT-FILE [INPUT-FILE]...\n\
|
||||
%s [OPTION]... [OUTPUT-FILE [INPUT-FILE]...]\n\
|
||||
Mandatory arguments to long options are mandatory for short options too.\n\
|
||||
-H, --header create C header file containing symbol definitions\n\
|
||||
-h, --help display this help and exit\n\
|
||||
--new do not use existing catalog, force new output file\n\
|
||||
-o, --output=NAME write output to file NAME\n\
|
||||
-V, --version output version information and exit\n\
|
||||
If INPUT-FILE is -, input is read from standard input. If OUTPUT-FILE\n\
|
||||
is -, output is written to standard output.\n"),
|
||||
program_invocation_name, program_invocation_name);
|
||||
fputs (gettext ("\
|
||||
Report bugs using the `glibcbug' script to <bugs@gnu.ai.mit.edu>.\n"),
|
||||
stdout);
|
||||
case 'H':
|
||||
header_name = arg;
|
||||
break;
|
||||
case OPT_NEW:
|
||||
force_new = 1;
|
||||
break;
|
||||
case 'o':
|
||||
output_name = arg;
|
||||
break;
|
||||
default:
|
||||
return ARGP_ERR_UNKNOWN;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
exit (status);
|
||||
|
||||
static char *
|
||||
more_help (int key, const char *text, void *input)
|
||||
{
|
||||
switch (key)
|
||||
{
|
||||
case ARGP_KEY_HELP_EXTRA:
|
||||
/* We print some extra information. */
|
||||
return strdup (gettext ("\
|
||||
Report bugs using the `glibcbug' script to <bugs@gnu.ai.mit.edu>.\n"));
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return (char *) text;
|
||||
}
|
||||
|
||||
/* Print the version information. */
|
||||
static void
|
||||
print_version (FILE *stream, struct argp_state *state)
|
||||
{
|
||||
fprintf (stream, "gencat (GNU %s) %s\n", PACKAGE, VERSION);
|
||||
fprintf (stream, gettext ("\
|
||||
Copyright (C) %s Free Software Foundation, Inc.\n\
|
||||
This is free software; see the source for copying conditions. There is NO\n\
|
||||
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n\
|
||||
"), "1996, 1997");
|
||||
fprintf (stream, gettext ("Written by %s.\n"), "Ulrich Drepper");
|
||||
}
|
||||
|
||||
|
||||
|
||||
Vendored
+25
-7
@@ -68,8 +68,20 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
|
||||
echo m68k-cbm-netbsd${UNAME_RELEASE}
|
||||
exit 0 ;;
|
||||
amiga:OpenBSD:*:*)
|
||||
echo m68k-cbm-openbsd${UNAME_RELEASE}
|
||||
exit 0 ;;
|
||||
echo m68k-unknown-openbsd${UNAME_RELEASE}
|
||||
exit 0 ;;
|
||||
arc:OpenBSD:*:*)
|
||||
echo mips64el-unknown-openbsd${UNAME_RELEASE}
|
||||
exit 0 ;;
|
||||
laguna:OpenBSD:*:*)
|
||||
echo mips64-unknown-openbsd${UNAME_RELEASE}
|
||||
exit 0 ;;
|
||||
pmax:OpenBSD:*:*)
|
||||
echo mips64el-unknown-openbsd${UNAME_RELEASE}
|
||||
exit 0 ;;
|
||||
wgrisc:OpenBSD:*:*)
|
||||
echo mips64el-unknown-openbsd${UNAME_RELEASE}
|
||||
exit 0 ;;
|
||||
arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*)
|
||||
echo arm-acorn-riscix${UNAME_RELEASE}
|
||||
exit 0;;
|
||||
@@ -118,19 +130,25 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
|
||||
echo m68k-atari-netbsd${UNAME_RELEASE}
|
||||
exit 0 ;;
|
||||
atari*:OpenBSD:*:*)
|
||||
echo m68k-atari-openbsd${UNAME_RELEASE}
|
||||
echo m68k-unknown-openbsd${UNAME_RELEASE}
|
||||
exit 0 ;;
|
||||
sun3*:NetBSD:*:*)
|
||||
echo m68k-sun-netbsd${UNAME_RELEASE}
|
||||
exit 0 ;;
|
||||
sun3*:OpenBSD:*:*)
|
||||
echo m68k-sun-openbsd${UNAME_RELEASE}
|
||||
echo m68k-unknown-openbsd${UNAME_RELEASE}
|
||||
exit 0 ;;
|
||||
mac68k:NetBSD:*:*)
|
||||
echo m68k-apple-netbsd${UNAME_RELEASE}
|
||||
exit 0 ;;
|
||||
mac68k:OpenBSD:*:*)
|
||||
echo m68k-apple-openbsd${UNAME_RELEASE}
|
||||
echo m68k-unknown-openbsd${UNAME_RELEASE}
|
||||
exit 0 ;;
|
||||
mvme68k:OpenBSD:*:*)
|
||||
echo m68k-unknown-openbsd${UNAME_RELEASE}
|
||||
exit 0 ;;
|
||||
mvme88k:OpenBSD:*:*)
|
||||
echo m88k-unknown-openbsd${UNAME_RELEASE}
|
||||
exit 0 ;;
|
||||
powerpc:machten:*:*)
|
||||
echo powerpc-apple-machten${UNAME_RELEASE}
|
||||
@@ -378,8 +396,8 @@ EOF
|
||||
hp3[0-9][05]:NetBSD:*:*)
|
||||
echo m68k-hp-netbsd${UNAME_RELEASE}
|
||||
exit 0 ;;
|
||||
hp3[0-9][05]:OpenBSD:*:*)
|
||||
echo m68k-hp-openbsd${UNAME_RELEASE}
|
||||
hp300:OpenBSD:*:*)
|
||||
echo m68k-unknown-openbsd${UNAME_RELEASE}
|
||||
exit 0 ;;
|
||||
i?86:BSD/386:*:* | *:BSD/OS:*:*)
|
||||
echo ${UNAME_MACHINE}-pc-bsdi${UNAME_RELEASE}
|
||||
|
||||
@@ -43,6 +43,9 @@
|
||||
directive. */
|
||||
#undef HAVE_ASM_POPSECTION_DIRECTIVE
|
||||
|
||||
/* Define if versioning of the library is wanted. */
|
||||
#undef DO_VERSIONING
|
||||
|
||||
/*
|
||||
*/
|
||||
|
||||
|
||||
@@ -26,6 +26,8 @@ defines = @DEFINES@
|
||||
elf = @elf@
|
||||
have-initfini = @libc_cv_have_initfini@
|
||||
|
||||
versioning = @VERSIONING@
|
||||
|
||||
have-no-whole-archive = @libc_cv_ld_no_whole_archive@
|
||||
have-no-exceptions = @libc_cv_gcc_no_exceptions@
|
||||
have-bash2 = @libc_cv_have_bash2@
|
||||
@@ -37,6 +39,7 @@ gnu-ld = @gnu_ld@
|
||||
build-shared = @shared@
|
||||
build-profile = @profile@
|
||||
build-omitfp = @omitfp@
|
||||
build-bounded = @bounded@
|
||||
stdio = @stdio@
|
||||
add-ons = @subdirs@
|
||||
|
||||
|
||||
@@ -37,6 +37,8 @@ ac_help="$ac_help
|
||||
--enable-profile build profiled library [default=yes]"
|
||||
ac_help="$ac_help
|
||||
--enable-omitfp build undebuggable optimized library [default=no]"
|
||||
ac_help="$ac_help
|
||||
--enable-bounded build with runtime bounds checking [default=no]"
|
||||
ac_help="$ac_help
|
||||
--enable-add-ons=DIR... configure and build named extra directories"
|
||||
|
||||
@@ -676,6 +678,14 @@ else
|
||||
omitfp=no
|
||||
fi
|
||||
|
||||
# Check whether --enable-bounded or --disable-bounded was given.
|
||||
if test "${enable_bounded+set}" = set; then
|
||||
enableval="$enable_bounded"
|
||||
bounded=$enableval
|
||||
else
|
||||
bounded=no
|
||||
fi
|
||||
|
||||
|
||||
# Check whether --enable-add-ons or --disable-add-ons was given.
|
||||
if test "${enable_add_ons+set}" = set; then
|
||||
@@ -720,7 +730,7 @@ else { echo "configure: error: can not run $ac_config_sub" 1>&2; exit 1; }
|
||||
fi
|
||||
|
||||
echo $ac_n "checking host system type""... $ac_c" 1>&6
|
||||
echo "configure:724: checking host system type" >&5
|
||||
echo "configure:734: checking host system type" >&5
|
||||
|
||||
host_alias=$host
|
||||
case "$host_alias" in
|
||||
@@ -766,7 +776,8 @@ gnu* | linux* | bsd4.4* | netbsd* | freebsd*)
|
||||
gnu_ld=yes gnu_as=yes ;;
|
||||
esac
|
||||
case "$host_os" in
|
||||
linux*ecoff*)
|
||||
# i586-linuxaout is mangled into i586-pc-linux-gnuaout
|
||||
linux*ecoff* | linux*aout* | gnu*aout* | gnu*ecoff*)
|
||||
;;
|
||||
gnu* | linux* | sysv4* | solaris2*)
|
||||
# These systems (almost) always use the ELF format.
|
||||
@@ -783,6 +794,7 @@ os=$config_os
|
||||
case "$machine" in
|
||||
a29k | am29000) base_machine=a29k machine=a29k ;;
|
||||
alpha*) base_machine=alpha machine=alpha/$machine ;;
|
||||
arm*) base_machine=arm machine=arm/$machine ;;
|
||||
hppa*) base_machine=hppa machine=hppa/$machine ;;
|
||||
i[3456]86) base_machine=i386 machine=i386/$machine ;;
|
||||
m680?0) base_machine=m68k machine=m68k/$machine ;;
|
||||
@@ -800,7 +812,7 @@ esac
|
||||
# This can take a while to compute.
|
||||
sysdep_dir=$srcdir/sysdeps
|
||||
echo $ac_n "checking sysdep dirs""... $ac_c" 1>&6
|
||||
echo "configure:804: checking sysdep dirs" >&5
|
||||
echo "configure:816: checking sysdep dirs" >&5
|
||||
# Make sco3.2v4 become sco3.2.4 and sunos4.1.1_U1 become sunos4.1.1.U1.
|
||||
os="`echo $os | sed 's/\([0-9A-Z]\)[v_]\([0-9A-Z]\)/\1.\2/g'`"
|
||||
|
||||
@@ -1001,7 +1013,7 @@ echo "$ac_t""sysdeps/generic sysdeps/stub" 1>&6
|
||||
# SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff"
|
||||
# ./install, which can be erroneously created by make from ./install.sh.
|
||||
echo $ac_n "checking for a BSD compatible install""... $ac_c" 1>&6
|
||||
echo "configure:1005: checking for a BSD compatible install" >&5
|
||||
echo "configure:1017: checking for a BSD compatible install" >&5
|
||||
if test -z "$INSTALL"; then
|
||||
if eval "test \"`echo '$''{'ac_cv_path_install'+set}'`\" = set"; then
|
||||
echo $ac_n "(cached) $ac_c" 1>&6
|
||||
@@ -1055,7 +1067,7 @@ if test "$INSTALL" = "${srcdir}/install-sh -c"; then
|
||||
INSTALL='$(..)./install-sh -c'
|
||||
fi
|
||||
echo $ac_n "checking whether ln -s works""... $ac_c" 1>&6
|
||||
echo "configure:1059: checking whether ln -s works" >&5
|
||||
echo "configure:1071: checking whether ln -s works" >&5
|
||||
if eval "test \"`echo '$''{'ac_cv_prog_LN_S'+set}'`\" = set"; then
|
||||
echo $ac_n "(cached) $ac_c" 1>&6
|
||||
else
|
||||
@@ -1080,7 +1092,7 @@ do
|
||||
# Extract the first word of "$ac_prog", so it can be a program name with args.
|
||||
set dummy $ac_prog; ac_word=$2
|
||||
echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
|
||||
echo "configure:1084: checking for $ac_word" >&5
|
||||
echo "configure:1096: checking for $ac_word" >&5
|
||||
if eval "test \"`echo '$''{'ac_cv_prog_MSGFMT'+set}'`\" = set"; then
|
||||
echo $ac_n "(cached) $ac_c" 1>&6
|
||||
else
|
||||
@@ -1110,8 +1122,178 @@ done
|
||||
test -n "$MSGFMT" || MSGFMT=":"
|
||||
|
||||
|
||||
# Extract the first word of "gcc", so it can be a program name with args.
|
||||
set dummy gcc; ac_word=$2
|
||||
echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
|
||||
echo "configure:1129: checking for $ac_word" >&5
|
||||
if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then
|
||||
echo $ac_n "(cached) $ac_c" 1>&6
|
||||
else
|
||||
if test -n "$CC"; then
|
||||
ac_cv_prog_CC="$CC" # Let the user override the test.
|
||||
else
|
||||
IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:"
|
||||
for ac_dir in $PATH; do
|
||||
test -z "$ac_dir" && ac_dir=.
|
||||
if test -f $ac_dir/$ac_word; then
|
||||
ac_cv_prog_CC="gcc"
|
||||
break
|
||||
fi
|
||||
done
|
||||
IFS="$ac_save_ifs"
|
||||
fi
|
||||
fi
|
||||
CC="$ac_cv_prog_CC"
|
||||
if test -n "$CC"; then
|
||||
echo "$ac_t""$CC" 1>&6
|
||||
else
|
||||
echo "$ac_t""no" 1>&6
|
||||
fi
|
||||
|
||||
if test -z "$CC"; then
|
||||
# Extract the first word of "cc", so it can be a program name with args.
|
||||
set dummy cc; ac_word=$2
|
||||
echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
|
||||
echo "configure:1158: checking for $ac_word" >&5
|
||||
if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then
|
||||
echo $ac_n "(cached) $ac_c" 1>&6
|
||||
else
|
||||
if test -n "$CC"; then
|
||||
ac_cv_prog_CC="$CC" # Let the user override the test.
|
||||
else
|
||||
IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:"
|
||||
ac_prog_rejected=no
|
||||
for ac_dir in $PATH; do
|
||||
test -z "$ac_dir" && ac_dir=.
|
||||
if test -f $ac_dir/$ac_word; then
|
||||
if test "$ac_dir/$ac_word" = "/usr/ucb/cc"; then
|
||||
ac_prog_rejected=yes
|
||||
continue
|
||||
fi
|
||||
ac_cv_prog_CC="cc"
|
||||
break
|
||||
fi
|
||||
done
|
||||
IFS="$ac_save_ifs"
|
||||
if test $ac_prog_rejected = yes; then
|
||||
# We found a bogon in the path, so make sure we never use it.
|
||||
set dummy $ac_cv_prog_CC
|
||||
shift
|
||||
if test $# -gt 0; then
|
||||
# We chose a different compiler from the bogus one.
|
||||
# However, it has the same basename, so the bogon will be chosen
|
||||
# first if we set CC to just the basename; use the full file name.
|
||||
shift
|
||||
set dummy "$ac_dir/$ac_word" "$@"
|
||||
shift
|
||||
ac_cv_prog_CC="$@"
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
CC="$ac_cv_prog_CC"
|
||||
if test -n "$CC"; then
|
||||
echo "$ac_t""$CC" 1>&6
|
||||
else
|
||||
echo "$ac_t""no" 1>&6
|
||||
fi
|
||||
|
||||
test -z "$CC" && { echo "configure: error: no acceptable cc found in \$PATH" 1>&2; exit 1; }
|
||||
fi
|
||||
|
||||
echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works""... $ac_c" 1>&6
|
||||
echo "configure:1206: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works" >&5
|
||||
|
||||
ac_ext=c
|
||||
# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options.
|
||||
ac_cpp='$CPP $CPPFLAGS'
|
||||
ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5'
|
||||
ac_link='${CC-cc} -o conftest $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5'
|
||||
cross_compiling=$ac_cv_prog_cc_cross
|
||||
|
||||
cat > conftest.$ac_ext <<EOF
|
||||
#line 1216 "configure"
|
||||
#include "confdefs.h"
|
||||
main(){return(0);}
|
||||
EOF
|
||||
if { (eval echo configure:1220: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
|
||||
ac_cv_prog_cc_works=yes
|
||||
# If we can't run a trivial program, we are probably using a cross compiler.
|
||||
if (./conftest; exit) 2>/dev/null; then
|
||||
ac_cv_prog_cc_cross=no
|
||||
else
|
||||
ac_cv_prog_cc_cross=yes
|
||||
fi
|
||||
else
|
||||
echo "configure: failed program was:" >&5
|
||||
cat conftest.$ac_ext >&5
|
||||
ac_cv_prog_cc_works=no
|
||||
fi
|
||||
rm -fr conftest*
|
||||
|
||||
echo "$ac_t""$ac_cv_prog_cc_works" 1>&6
|
||||
if test $ac_cv_prog_cc_works = no; then
|
||||
{ echo "configure: error: installation or configuration problem: C compiler cannot create executables." 1>&2; exit 1; }
|
||||
fi
|
||||
echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler""... $ac_c" 1>&6
|
||||
echo "configure:1240: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler" >&5
|
||||
echo "$ac_t""$ac_cv_prog_cc_cross" 1>&6
|
||||
cross_compiling=$ac_cv_prog_cc_cross
|
||||
|
||||
echo $ac_n "checking whether we are using GNU C""... $ac_c" 1>&6
|
||||
echo "configure:1245: checking whether we are using GNU C" >&5
|
||||
if eval "test \"`echo '$''{'ac_cv_prog_gcc'+set}'`\" = set"; then
|
||||
echo $ac_n "(cached) $ac_c" 1>&6
|
||||
else
|
||||
cat > conftest.c <<EOF
|
||||
#ifdef __GNUC__
|
||||
yes;
|
||||
#endif
|
||||
EOF
|
||||
if { ac_try='${CC-cc} -E conftest.c'; { (eval echo configure:1254: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; } | egrep yes >/dev/null 2>&1; then
|
||||
ac_cv_prog_gcc=yes
|
||||
else
|
||||
ac_cv_prog_gcc=no
|
||||
fi
|
||||
fi
|
||||
|
||||
echo "$ac_t""$ac_cv_prog_gcc" 1>&6
|
||||
|
||||
if test $ac_cv_prog_gcc = yes; then
|
||||
GCC=yes
|
||||
ac_test_CFLAGS="${CFLAGS+set}"
|
||||
ac_save_CFLAGS="$CFLAGS"
|
||||
CFLAGS=
|
||||
echo $ac_n "checking whether ${CC-cc} accepts -g""... $ac_c" 1>&6
|
||||
echo "configure:1269: checking whether ${CC-cc} accepts -g" >&5
|
||||
if eval "test \"`echo '$''{'ac_cv_prog_cc_g'+set}'`\" = set"; then
|
||||
echo $ac_n "(cached) $ac_c" 1>&6
|
||||
else
|
||||
echo 'void f(){}' > conftest.c
|
||||
if test -z "`${CC-cc} -g -c conftest.c 2>&1`"; then
|
||||
ac_cv_prog_cc_g=yes
|
||||
else
|
||||
ac_cv_prog_cc_g=no
|
||||
fi
|
||||
rm -f conftest*
|
||||
|
||||
fi
|
||||
|
||||
echo "$ac_t""$ac_cv_prog_cc_g" 1>&6
|
||||
if test "$ac_test_CFLAGS" = set; then
|
||||
CFLAGS="$ac_save_CFLAGS"
|
||||
elif test $ac_cv_prog_cc_g = yes; then
|
||||
CFLAGS="-g -O2"
|
||||
else
|
||||
CFLAGS="-O2"
|
||||
fi
|
||||
else
|
||||
GCC=
|
||||
test "${CFLAGS+set}" = set || CFLAGS="-g"
|
||||
fi
|
||||
|
||||
echo $ac_n "checking build system type""... $ac_c" 1>&6
|
||||
echo "configure:1115: checking build system type" >&5
|
||||
echo "configure:1297: checking build system type" >&5
|
||||
|
||||
build_alias=$build
|
||||
case "$build_alias" in
|
||||
@@ -1129,47 +1311,12 @@ build_os=`echo $build | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'`
|
||||
echo "$ac_t""$build" 1>&6
|
||||
|
||||
if test $host != $build; then
|
||||
ac_tool_prefix=${host_alias}-
|
||||
else
|
||||
ac_tool_prefix=
|
||||
fi
|
||||
|
||||
# Extract the first word of "${ac_tool_prefix}gcc", so it can be a program name with args.
|
||||
set dummy ${ac_tool_prefix}gcc; ac_word=$2
|
||||
for ac_prog in gcc cc
|
||||
do
|
||||
# Extract the first word of "$ac_prog", so it can be a program name with args.
|
||||
set dummy $ac_prog; ac_word=$2
|
||||
echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
|
||||
echo "configure:1141: checking for $ac_word" >&5
|
||||
if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then
|
||||
echo $ac_n "(cached) $ac_c" 1>&6
|
||||
else
|
||||
if test -n "$CC"; then
|
||||
ac_cv_prog_CC="$CC" # Let the user override the test.
|
||||
else
|
||||
IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:"
|
||||
for ac_dir in $PATH; do
|
||||
test -z "$ac_dir" && ac_dir=.
|
||||
if test -f $ac_dir/$ac_word; then
|
||||
ac_cv_prog_CC="${ac_tool_prefix}gcc"
|
||||
break
|
||||
fi
|
||||
done
|
||||
IFS="$ac_save_ifs"
|
||||
test -z "$ac_cv_prog_CC" && ac_cv_prog_CC="gcc"
|
||||
fi
|
||||
fi
|
||||
CC="$ac_cv_prog_CC"
|
||||
if test -n "$CC"; then
|
||||
echo "$ac_t""$CC" 1>&6
|
||||
else
|
||||
echo "$ac_t""no" 1>&6
|
||||
fi
|
||||
|
||||
|
||||
|
||||
if test $host != $build; then
|
||||
# Extract the first word of "gcc cc", so it can be a program name with args.
|
||||
set dummy gcc cc; ac_word=$2
|
||||
echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
|
||||
echo "configure:1173: checking for $ac_word" >&5
|
||||
echo "configure:1320: checking for $ac_word" >&5
|
||||
if eval "test \"`echo '$''{'ac_cv_prog_BUILD_CC'+set}'`\" = set"; then
|
||||
echo $ac_n "(cached) $ac_c" 1>&6
|
||||
else
|
||||
@@ -1180,7 +1327,7 @@ else
|
||||
for ac_dir in $PATH; do
|
||||
test -z "$ac_dir" && ac_dir=.
|
||||
if test -f $ac_dir/$ac_word; then
|
||||
ac_cv_prog_BUILD_CC=""
|
||||
ac_cv_prog_BUILD_CC="$ac_prog"
|
||||
break
|
||||
fi
|
||||
done
|
||||
@@ -1194,9 +1341,12 @@ else
|
||||
echo "$ac_t""no" 1>&6
|
||||
fi
|
||||
|
||||
test -n "$BUILD_CC" && break
|
||||
done
|
||||
|
||||
fi
|
||||
echo $ac_n "checking how to run the C preprocessor""... $ac_c" 1>&6
|
||||
echo "configure:1200: checking how to run the C preprocessor" >&5
|
||||
echo "configure:1350: checking how to run the C preprocessor" >&5
|
||||
# On Suns, sometimes $CPP names a directory.
|
||||
if test -n "$CPP" && test -d "$CPP"; then
|
||||
CPP=
|
||||
@@ -1211,13 +1361,13 @@ else
|
||||
# On the NeXT, cc -E runs the code through the compiler's parser,
|
||||
# not just through cpp.
|
||||
cat > conftest.$ac_ext <<EOF
|
||||
#line 1215 "configure"
|
||||
#line 1365 "configure"
|
||||
#include "confdefs.h"
|
||||
#include <assert.h>
|
||||
Syntax Error
|
||||
EOF
|
||||
ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
|
||||
{ (eval echo configure:1221: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
|
||||
{ (eval echo configure:1371: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
|
||||
ac_err=`grep -v '^ *+' conftest.out`
|
||||
if test -z "$ac_err"; then
|
||||
:
|
||||
@@ -1228,13 +1378,13 @@ else
|
||||
rm -rf conftest*
|
||||
CPP="${CC-cc} -E -traditional-cpp"
|
||||
cat > conftest.$ac_ext <<EOF
|
||||
#line 1232 "configure"
|
||||
#line 1382 "configure"
|
||||
#include "confdefs.h"
|
||||
#include <assert.h>
|
||||
Syntax Error
|
||||
EOF
|
||||
ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
|
||||
{ (eval echo configure:1238: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
|
||||
{ (eval echo configure:1388: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
|
||||
ac_err=`grep -v '^ *+' conftest.out`
|
||||
if test -z "$ac_err"; then
|
||||
:
|
||||
@@ -1256,10 +1406,16 @@ else
|
||||
fi
|
||||
echo "$ac_t""$CPP" 1>&6
|
||||
|
||||
if test $host != $build; then
|
||||
ac_tool_prefix=${host_alias}-
|
||||
else
|
||||
ac_tool_prefix=
|
||||
fi
|
||||
|
||||
# Extract the first word of "${ac_tool_prefix}ar", so it can be a program name with args.
|
||||
set dummy ${ac_tool_prefix}ar; ac_word=$2
|
||||
echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
|
||||
echo "configure:1263: checking for $ac_word" >&5
|
||||
echo "configure:1419: checking for $ac_word" >&5
|
||||
if eval "test \"`echo '$''{'ac_cv_prog_AR'+set}'`\" = set"; then
|
||||
echo $ac_n "(cached) $ac_c" 1>&6
|
||||
else
|
||||
@@ -1290,7 +1446,7 @@ fi
|
||||
# Extract the first word of "${ac_tool_prefix}ranlib", so it can be a program name with args.
|
||||
set dummy ${ac_tool_prefix}ranlib; ac_word=$2
|
||||
echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
|
||||
echo "configure:1294: checking for $ac_word" >&5
|
||||
echo "configure:1450: checking for $ac_word" >&5
|
||||
if eval "test \"`echo '$''{'ac_cv_prog_RANLIB'+set}'`\" = set"; then
|
||||
echo $ac_n "(cached) $ac_c" 1>&6
|
||||
else
|
||||
@@ -1321,7 +1477,7 @@ if test -n "$ac_tool_prefix"; then
|
||||
# Extract the first word of "ranlib", so it can be a program name with args.
|
||||
set dummy ranlib; ac_word=$2
|
||||
echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
|
||||
echo "configure:1325: checking for $ac_word" >&5
|
||||
echo "configure:1481: checking for $ac_word" >&5
|
||||
if eval "test \"`echo '$''{'ac_cv_prog_RANLIB'+set}'`\" = set"; then
|
||||
echo $ac_n "(cached) $ac_c" 1>&6
|
||||
else
|
||||
@@ -1356,7 +1512,7 @@ fi
|
||||
# Extract the first word of "bash", so it can be a program name with args.
|
||||
set dummy bash; ac_word=$2
|
||||
echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
|
||||
echo "configure:1360: checking for $ac_word" >&5
|
||||
echo "configure:1516: checking for $ac_word" >&5
|
||||
if eval "test \"`echo '$''{'ac_cv_path_BASH'+set}'`\" = set"; then
|
||||
echo $ac_n "(cached) $ac_c" 1>&6
|
||||
else
|
||||
@@ -1397,7 +1553,7 @@ if test "$BASH" = no; then
|
||||
# Extract the first word of "ksh", so it can be a program name with args.
|
||||
set dummy ksh; ac_word=$2
|
||||
echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
|
||||
echo "configure:1401: checking for $ac_word" >&5
|
||||
echo "configure:1557: checking for $ac_word" >&5
|
||||
if eval "test \"`echo '$''{'ac_cv_path_KSH'+set}'`\" = set"; then
|
||||
echo $ac_n "(cached) $ac_c" 1>&6
|
||||
else
|
||||
@@ -1439,7 +1595,7 @@ fi
|
||||
|
||||
|
||||
echo $ac_n "checking for signed size_t type""... $ac_c" 1>&6
|
||||
echo "configure:1443: checking for signed size_t type" >&5
|
||||
echo "configure:1599: checking for signed size_t type" >&5
|
||||
if eval "test \"`echo '$''{'libc_cv_signed_size_t'+set}'`\" = set"; then
|
||||
echo $ac_n "(cached) $ac_c" 1>&6
|
||||
else
|
||||
@@ -1463,12 +1619,12 @@ EOF
|
||||
fi
|
||||
|
||||
echo $ac_n "checking for libc-friendly stddef.h""... $ac_c" 1>&6
|
||||
echo "configure:1467: checking for libc-friendly stddef.h" >&5
|
||||
echo "configure:1623: checking for libc-friendly stddef.h" >&5
|
||||
if eval "test \"`echo '$''{'libc_cv_friendly_stddef'+set}'`\" = set"; then
|
||||
echo $ac_n "(cached) $ac_c" 1>&6
|
||||
else
|
||||
cat > conftest.$ac_ext <<EOF
|
||||
#line 1472 "configure"
|
||||
#line 1628 "configure"
|
||||
#include "confdefs.h"
|
||||
#define __need_size_t
|
||||
#define __need_wchar_t
|
||||
@@ -1483,7 +1639,7 @@ size_t size; wchar_t wchar;
|
||||
if (&size == NULL || &wchar == NULL) abort ();
|
||||
; return 0; }
|
||||
EOF
|
||||
if { (eval echo configure:1487: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
|
||||
if { (eval echo configure:1643: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
|
||||
rm -rf conftest*
|
||||
libc_cv_friendly_stddef=yes
|
||||
else
|
||||
@@ -1502,7 +1658,7 @@ override stddef.h = # The installed <stddef.h> seems to be libc-friendly."
|
||||
fi
|
||||
|
||||
echo $ac_n "checking whether we need to use -P to assemble .S files""... $ac_c" 1>&6
|
||||
echo "configure:1506: checking whether we need to use -P to assemble .S files" >&5
|
||||
echo "configure:1662: checking whether we need to use -P to assemble .S files" >&5
|
||||
if eval "test \"`echo '$''{'libc_cv_need_minus_P'+set}'`\" = set"; then
|
||||
echo $ac_n "(cached) $ac_c" 1>&6
|
||||
else
|
||||
@@ -1525,7 +1681,7 @@ asm-CPPFLAGS = -P # The assembler can't grok cpp's # line directives."
|
||||
fi
|
||||
|
||||
echo $ac_n "checking for assembler global-symbol directive""... $ac_c" 1>&6
|
||||
echo "configure:1529: checking for assembler global-symbol directive" >&5
|
||||
echo "configure:1685: checking for assembler global-symbol directive" >&5
|
||||
if eval "test \"`echo '$''{'libc_cv_asm_global_directive'+set}'`\" = set"; then
|
||||
echo $ac_n "(cached) $ac_c" 1>&6
|
||||
else
|
||||
@@ -1555,7 +1711,7 @@ EOF
|
||||
fi
|
||||
|
||||
echo $ac_n "checking for .set assembler directive""... $ac_c" 1>&6
|
||||
echo "configure:1559: checking for .set assembler directive" >&5
|
||||
echo "configure:1715: checking for .set assembler directive" >&5
|
||||
if eval "test \"`echo '$''{'libc_cv_asm_set_directive'+set}'`\" = set"; then
|
||||
echo $ac_n "(cached) $ac_c" 1>&6
|
||||
else
|
||||
@@ -1588,9 +1744,74 @@ EOF
|
||||
|
||||
fi
|
||||
|
||||
echo $ac_n "checking for .symver assembler directive""... $ac_c" 1>&6
|
||||
echo "configure:1749: checking for .symver assembler directive" >&5
|
||||
if eval "test \"`echo '$''{'libc_cv_asm_symver_directive'+set}'`\" = set"; then
|
||||
echo $ac_n "(cached) $ac_c" 1>&6
|
||||
else
|
||||
cat > conftest.s <<EOF
|
||||
.text
|
||||
_sym:
|
||||
.symver _sym,sym@VERS
|
||||
EOF
|
||||
if ${CC-cc} -c $CFLAGS $CPPFLAGS conftest.s 1>&5 2>&5; then
|
||||
libc_cv_asm_symver_directive=yes
|
||||
else
|
||||
libc_cv_asm_symver_directive=no
|
||||
fi
|
||||
rm -f conftest*
|
||||
fi
|
||||
|
||||
echo "$ac_t""$libc_cv_asm_symver_directive" 1>&6
|
||||
echo $ac_n "checking for ld --version-script""... $ac_c" 1>&6
|
||||
echo "configure:1768: checking for ld --version-script" >&5
|
||||
if eval "test \"`echo '$''{'libc_cv_ld_version_script_option'+set}'`\" = set"; then
|
||||
echo $ac_n "(cached) $ac_c" 1>&6
|
||||
else
|
||||
if test $libc_cv_asm_symver_directive = yes; then
|
||||
cat > conftest.s <<EOF
|
||||
.text
|
||||
_sym:
|
||||
.symver _sym,sym@VERS
|
||||
EOF
|
||||
cat > conftest.map <<EOF
|
||||
VERS {
|
||||
global: sym;
|
||||
};
|
||||
EOF
|
||||
if ${CC-cc} -c $CFLAGS $CPPFLAGS conftest.s 1>&5 2>&5; then
|
||||
if { ac_try='${CC-cc} $CFLAGS --shared -o conftest.so conftest.o
|
||||
-Wl,--version-script,conftest.map'; { (eval echo configure:1785: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; };
|
||||
then
|
||||
libc_cv_ld_version_script_option=yes
|
||||
else
|
||||
libc_cv_ld_version_script_option=no
|
||||
fi
|
||||
else
|
||||
libc_cv_ld_version_script_option=no
|
||||
fi
|
||||
else
|
||||
libc_cv_ld_version_script_option=no
|
||||
fi
|
||||
rm -f conftest*
|
||||
fi
|
||||
|
||||
echo "$ac_t""$libc_cv_ld_version_script_option" 1>&6
|
||||
if test $libc_cv_asm_symver_directive = yes &&
|
||||
test $libc_cv_ld_version_script_option = yes; then
|
||||
VERSIONING=yes
|
||||
cat >> confdefs.h <<\EOF
|
||||
#define DO_VERSIONING 1
|
||||
EOF
|
||||
|
||||
else
|
||||
VERSIONING=no
|
||||
fi
|
||||
|
||||
|
||||
if test $elf = yes; then
|
||||
echo $ac_n "checking for .previous assembler directive""... $ac_c" 1>&6
|
||||
echo "configure:1594: checking for .previous assembler directive" >&5
|
||||
echo "configure:1815: checking for .previous assembler directive" >&5
|
||||
if eval "test \"`echo '$''{'libc_cv_asm_previous_directive'+set}'`\" = set"; then
|
||||
echo $ac_n "(cached) $ac_c" 1>&6
|
||||
else
|
||||
@@ -1598,7 +1819,7 @@ else
|
||||
.section foo_section
|
||||
.previous
|
||||
EOF
|
||||
if { ac_try='${CC-cc} -c $CFLAGS conftest.s 1>&5'; { (eval echo configure:1602: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; }; then
|
||||
if { ac_try='${CC-cc} -c $CFLAGS conftest.s 1>&5'; { (eval echo configure:1823: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; }; then
|
||||
libc_cv_asm_previous_directive=yes
|
||||
else
|
||||
libc_cv_asm_previous_directive=no
|
||||
@@ -1614,7 +1835,7 @@ EOF
|
||||
|
||||
else
|
||||
echo $ac_n "checking for .popsection assembler directive""... $ac_c" 1>&6
|
||||
echo "configure:1618: checking for .popsection assembler directive" >&5
|
||||
echo "configure:1839: checking for .popsection assembler directive" >&5
|
||||
if eval "test \"`echo '$''{'libc_cv_asm_popsection_directive'+set}'`\" = set"; then
|
||||
echo $ac_n "(cached) $ac_c" 1>&6
|
||||
else
|
||||
@@ -1622,7 +1843,7 @@ else
|
||||
.pushsection foo_section
|
||||
.popsection
|
||||
EOF
|
||||
if { ac_try='${CC-cc} -c $CFLAGS conftest.s 1>&5'; { (eval echo configure:1626: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; }; then
|
||||
if { ac_try='${CC-cc} -c $CFLAGS conftest.s 1>&5'; { (eval echo configure:1847: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; }; then
|
||||
libc_cv_asm_popsection_directive=yes
|
||||
else
|
||||
libc_cv_asm_popsection_directive=no
|
||||
@@ -1642,12 +1863,12 @@ fi
|
||||
|
||||
if test $elf != yes; then
|
||||
echo $ac_n "checking for .init and .fini sections""... $ac_c" 1>&6
|
||||
echo "configure:1646: checking for .init and .fini sections" >&5
|
||||
echo "configure:1867: checking for .init and .fini sections" >&5
|
||||
if eval "test \"`echo '$''{'libc_cv_have_initfini'+set}'`\" = set"; then
|
||||
echo $ac_n "(cached) $ac_c" 1>&6
|
||||
else
|
||||
cat > conftest.$ac_ext <<EOF
|
||||
#line 1651 "configure"
|
||||
#line 1872 "configure"
|
||||
#include "confdefs.h"
|
||||
|
||||
int main() {
|
||||
@@ -1656,7 +1877,7 @@ asm (".section .init");
|
||||
asm (".text");
|
||||
; return 0; }
|
||||
EOF
|
||||
if { (eval echo configure:1660: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
|
||||
if { (eval echo configure:1881: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
|
||||
rm -rf conftest*
|
||||
libc_cv_have_initfini=yes
|
||||
else
|
||||
@@ -1681,19 +1902,19 @@ if test $elf = yes; then
|
||||
libc_cv_asm_underscores=no
|
||||
else
|
||||
echo $ac_n "checking for _ prefix on C symbol names""... $ac_c" 1>&6
|
||||
echo "configure:1685: checking for _ prefix on C symbol names" >&5
|
||||
echo "configure:1906: checking for _ prefix on C symbol names" >&5
|
||||
if eval "test \"`echo '$''{'libc_cv_asm_underscores'+set}'`\" = set"; then
|
||||
echo $ac_n "(cached) $ac_c" 1>&6
|
||||
else
|
||||
cat > conftest.$ac_ext <<EOF
|
||||
#line 1690 "configure"
|
||||
#line 1911 "configure"
|
||||
#include "confdefs.h"
|
||||
asm ("_glibc_foobar:");
|
||||
int main() {
|
||||
glibc_foobar ();
|
||||
; return 0; }
|
||||
EOF
|
||||
if { (eval echo configure:1697: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
|
||||
if { (eval echo configure:1918: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
|
||||
rm -rf conftest*
|
||||
libc_cv_asm_underscores=yes
|
||||
else
|
||||
@@ -1720,7 +1941,7 @@ if test $elf = yes; then
|
||||
libc_cv_asm_weakext_directive=no
|
||||
else
|
||||
echo $ac_n "checking for assembler .weak directive""... $ac_c" 1>&6
|
||||
echo "configure:1724: checking for assembler .weak directive" >&5
|
||||
echo "configure:1945: checking for assembler .weak directive" >&5
|
||||
if eval "test \"`echo '$''{'libc_cv_asm_weak_directive'+set}'`\" = set"; then
|
||||
echo $ac_n "(cached) $ac_c" 1>&6
|
||||
else
|
||||
@@ -1743,7 +1964,7 @@ echo "$ac_t""$libc_cv_asm_weak_directive" 1>&6
|
||||
|
||||
if test $libc_cv_asm_weak_directive = no; then
|
||||
echo $ac_n "checking for assembler .weakext directive""... $ac_c" 1>&6
|
||||
echo "configure:1747: checking for assembler .weakext directive" >&5
|
||||
echo "configure:1968: checking for assembler .weakext directive" >&5
|
||||
if eval "test \"`echo '$''{'libc_cv_asm_weakext_directive'+set}'`\" = set"; then
|
||||
echo $ac_n "(cached) $ac_c" 1>&6
|
||||
else
|
||||
@@ -1780,7 +2001,7 @@ EOF
|
||||
fi
|
||||
|
||||
echo $ac_n "checking for ld --no-whole-archive""... $ac_c" 1>&6
|
||||
echo "configure:1784: checking for ld --no-whole-archive" >&5
|
||||
echo "configure:2005: checking for ld --no-whole-archive" >&5
|
||||
if eval "test \"`echo '$''{'libc_cv_ld_no_whole_archive'+set}'`\" = set"; then
|
||||
echo $ac_n "(cached) $ac_c" 1>&6
|
||||
else
|
||||
@@ -1791,7 +2012,7 @@ __throw () {}
|
||||
EOF
|
||||
if { ac_try='${CC-cc} $CFLAGS
|
||||
-nostdlib -nostartfiles -Wl,--no-whole-archive
|
||||
-o conftest conftest.c'; { (eval echo configure:1795: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; }; then
|
||||
-o conftest conftest.c'; { (eval echo configure:2016: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; }; then
|
||||
libc_cv_ld_no_whole_archive=yes
|
||||
else
|
||||
libc_cv_ld_no_whole_archive=no
|
||||
@@ -1802,7 +2023,7 @@ fi
|
||||
echo "$ac_t""$libc_cv_ld_no_whole_archive" 1>&6
|
||||
|
||||
echo $ac_n "checking for gcc -fno-exceptions""... $ac_c" 1>&6
|
||||
echo "configure:1806: checking for gcc -fno-exceptions" >&5
|
||||
echo "configure:2027: checking for gcc -fno-exceptions" >&5
|
||||
if eval "test \"`echo '$''{'libc_cv_gcc_no_exceptions'+set}'`\" = set"; then
|
||||
echo $ac_n "(cached) $ac_c" 1>&6
|
||||
else
|
||||
@@ -1813,7 +2034,7 @@ __throw () {}
|
||||
EOF
|
||||
if { ac_try='${CC-cc} $CFLAGS
|
||||
-nostdlib -nostartfiles -fno-exceptions
|
||||
-o conftest conftest.c'; { (eval echo configure:1817: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; }; then
|
||||
-o conftest conftest.c'; { (eval echo configure:2038: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; }; then
|
||||
libc_cv_gcc_no_exceptions=yes
|
||||
else
|
||||
libc_cv_gcc_no_exceptions=no
|
||||
@@ -1865,7 +2086,7 @@ if test "$uname" = generic; then
|
||||
fi
|
||||
|
||||
echo $ac_n "checking OS release for uname""... $ac_c" 1>&6
|
||||
echo "configure:1869: checking OS release for uname" >&5
|
||||
echo "configure:2090: checking OS release for uname" >&5
|
||||
if eval "test \"`echo '$''{'libc_cv_uname_release'+set}'`\" = set"; then
|
||||
echo $ac_n "(cached) $ac_c" 1>&6
|
||||
else
|
||||
@@ -1887,7 +2108,7 @@ echo "$ac_t""$libc_cv_uname_release" 1>&6
|
||||
uname_release="$libc_cv_uname_release"
|
||||
|
||||
echo $ac_n "checking OS version for uname""... $ac_c" 1>&6
|
||||
echo "configure:1891: checking OS version for uname" >&5
|
||||
echo "configure:2112: checking OS version for uname" >&5
|
||||
if eval "test \"`echo '$''{'libc_cv_uname_version'+set}'`\" = set"; then
|
||||
echo $ac_n "(cached) $ac_c" 1>&6
|
||||
else
|
||||
@@ -1909,7 +2130,7 @@ else
|
||||
fi
|
||||
|
||||
echo $ac_n "checking stdio selection""... $ac_c" 1>&6
|
||||
echo "configure:1913: checking stdio selection" >&5
|
||||
echo "configure:2134: checking stdio selection" >&5
|
||||
|
||||
case $stdio in
|
||||
libio) cat >> confdefs.h <<\EOF
|
||||
@@ -1961,6 +2182,7 @@ fi
|
||||
|
||||
|
||||
|
||||
|
||||
if test "`(cd $srcdir; pwd)`" = "`pwd`"; then
|
||||
config_makefile=
|
||||
else
|
||||
@@ -1993,7 +2215,7 @@ EOF
|
||||
# Ultrix sh set writes to stderr and can't be redirected directly,
|
||||
# and sets the high bit in the cache file unless we assign to the vars.
|
||||
(set) 2>&1 |
|
||||
case `(ac_space=' '; set | grep ac_space) 2>&1` in
|
||||
case `(ac_space=' '; set) 2>&1` in
|
||||
*ac_space=\ *)
|
||||
# `set' does not quote correctly, so add quotes (double-quote substitution
|
||||
# turns \\\\ into \\, and sed turns \\ into \).
|
||||
@@ -2113,12 +2335,12 @@ s%@INSTALL_PROGRAM@%$INSTALL_PROGRAM%g
|
||||
s%@INSTALL_DATA@%$INSTALL_DATA%g
|
||||
s%@LN_S@%$LN_S%g
|
||||
s%@MSGFMT@%$MSGFMT%g
|
||||
s%@CC@%$CC%g
|
||||
s%@build@%$build%g
|
||||
s%@build_alias@%$build_alias%g
|
||||
s%@build_cpu@%$build_cpu%g
|
||||
s%@build_vendor@%$build_vendor%g
|
||||
s%@build_os@%$build_os%g
|
||||
s%@CC@%$CC%g
|
||||
s%@BUILD_CC@%$BUILD_CC%g
|
||||
s%@CPP@%$CPP%g
|
||||
s%@AR@%$AR%g
|
||||
@@ -2127,6 +2349,7 @@ s%@BASH@%$BASH%g
|
||||
s%@libc_cv_have_bash2@%$libc_cv_have_bash2%g
|
||||
s%@KSH@%$KSH%g
|
||||
s%@libc_cv_have_ksh@%$libc_cv_have_ksh%g
|
||||
s%@VERSIONING@%$VERSIONING%g
|
||||
s%@libc_cv_have_initfini@%$libc_cv_have_initfini%g
|
||||
s%@libc_cv_ld_no_whole_archive@%$libc_cv_ld_no_whole_archive%g
|
||||
s%@libc_cv_gcc_no_exceptions@%$libc_cv_gcc_no_exceptions%g
|
||||
@@ -2144,6 +2367,7 @@ s%@elf@%$elf%g
|
||||
s%@shared@%$shared%g
|
||||
s%@profile@%$profile%g
|
||||
s%@omitfp@%$omitfp%g
|
||||
s%@bounded@%$bounded%g
|
||||
s%@DEFINES@%$DEFINES%g
|
||||
s%@VERSION@%$VERSION%g
|
||||
|
||||
|
||||
+58
-3
@@ -75,6 +75,9 @@ AC_ARG_ENABLE(profile, dnl
|
||||
AC_ARG_ENABLE(omitfp, dnl
|
||||
[ --enable-omitfp build undebuggable optimized library [default=no]],
|
||||
omitfp=$enableval, omitfp=no)
|
||||
AC_ARG_ENABLE(bounded, dnl
|
||||
[ --enable-bounded build with runtime bounds checking [default=no]],
|
||||
bounded=$enableval, bounded=no)
|
||||
|
||||
dnl Generic infrastructure for drop-in additions to libc.
|
||||
AC_ARG_ENABLE(add-ons, dnl
|
||||
@@ -116,7 +119,8 @@ gnu* | linux* | bsd4.4* | netbsd* | freebsd*)
|
||||
gnu_ld=yes gnu_as=yes ;;
|
||||
esac
|
||||
case "$host_os" in
|
||||
linux*ecoff*)
|
||||
# i586-linuxaout is mangled into i586-pc-linux-gnuaout
|
||||
linux*ecoff* | linux*aout* | gnu*aout* | gnu*ecoff*)
|
||||
;;
|
||||
gnu* | linux* | sysv4* | solaris2*)
|
||||
# These systems (almost) always use the ELF format.
|
||||
@@ -135,6 +139,7 @@ changequote(,)dnl
|
||||
case "$machine" in
|
||||
a29k | am29000) base_machine=a29k machine=a29k ;;
|
||||
alpha*) base_machine=alpha machine=alpha/$machine ;;
|
||||
arm*) base_machine=arm machine=arm/$machine ;;
|
||||
hppa*) base_machine=hppa machine=hppa/$machine ;;
|
||||
i[3456]86) base_machine=i386 machine=i386/$machine ;;
|
||||
m680?0) base_machine=m68k machine=m68k/$machine ;;
|
||||
@@ -356,9 +361,10 @@ fi
|
||||
AC_PROG_LN_S
|
||||
AC_CHECK_PROGS(MSGFMT, msgfmt gmsgfmt, :)
|
||||
|
||||
AC_CHECK_TOOL(CC, gcc)
|
||||
AC_PROG_CC
|
||||
AC_CANONICAL_BUILD
|
||||
if test $host != $build; then
|
||||
AC_CHECK_PROG(BUILD_CC, gcc cc)
|
||||
AC_CHECK_PROGS(BUILD_CC, gcc cc)
|
||||
fi
|
||||
AC_PROG_CPP
|
||||
AC_CHECK_TOOL(AR, ar)
|
||||
@@ -486,6 +492,54 @@ if test $libc_cv_asm_set_directive = yes; then
|
||||
AC_DEFINE(HAVE_ASM_SET_DIRECTIVE)
|
||||
fi
|
||||
|
||||
AC_CACHE_CHECK(for .symver assembler directive, libc_cv_asm_symver_directive,
|
||||
[cat > conftest.s <<EOF
|
||||
.text
|
||||
_sym:
|
||||
.symver _sym,sym@VERS
|
||||
EOF
|
||||
if ${CC-cc} -c $CFLAGS $CPPFLAGS conftest.s 1>&AC_FD_CC 2>&AC_FD_CC; then
|
||||
libc_cv_asm_symver_directive=yes
|
||||
else
|
||||
libc_cv_asm_symver_directive=no
|
||||
fi
|
||||
rm -f conftest*])
|
||||
AC_CACHE_CHECK(for ld --version-script, libc_cv_ld_version_script_option, [dnl
|
||||
if test $libc_cv_asm_symver_directive = yes; then
|
||||
cat > conftest.s <<EOF
|
||||
.text
|
||||
_sym:
|
||||
.symver _sym,sym@VERS
|
||||
EOF
|
||||
cat > conftest.map <<EOF
|
||||
VERS {
|
||||
global: sym;
|
||||
};
|
||||
EOF
|
||||
if ${CC-cc} -c $CFLAGS $CPPFLAGS conftest.s 1>&AC_FD_CC 2>&AC_FD_CC; then
|
||||
if AC_TRY_COMMAND([${CC-cc} $CFLAGS --shared -o conftest.so conftest.o
|
||||
-Wl,--version-script,conftest.map]);
|
||||
then
|
||||
libc_cv_ld_version_script_option=yes
|
||||
else
|
||||
libc_cv_ld_version_script_option=no
|
||||
fi
|
||||
else
|
||||
libc_cv_ld_version_script_option=no
|
||||
fi
|
||||
else
|
||||
libc_cv_ld_version_script_option=no
|
||||
fi
|
||||
rm -f conftest*])
|
||||
if test $libc_cv_asm_symver_directive = yes &&
|
||||
test $libc_cv_ld_version_script_option = yes; then
|
||||
VERSIONING=yes
|
||||
AC_DEFINE(DO_VERSIONING)
|
||||
else
|
||||
VERSIONING=no
|
||||
fi
|
||||
AC_SUBST(VERSIONING)
|
||||
|
||||
if test $elf = yes; then
|
||||
AC_CACHE_CHECK(for .previous assembler directive,
|
||||
libc_cv_asm_previous_directive, [dnl
|
||||
@@ -755,6 +809,7 @@ if test $shared = default; then
|
||||
fi
|
||||
AC_SUBST(profile)
|
||||
AC_SUBST(omitfp)
|
||||
AC_SUBST(bounded)
|
||||
|
||||
AC_SUBST(DEFINES)
|
||||
|
||||
|
||||
@@ -4,3 +4,4 @@
|
||||
TODO COPYING* AUTHORS copyr-* copying.*
|
||||
glibc-*
|
||||
distinfo
|
||||
specs
|
||||
|
||||
+1
-1
@@ -21,7 +21,7 @@
|
||||
#
|
||||
subdir := ctype
|
||||
|
||||
routines := ctype ctype-extn
|
||||
routines := ctype ctype-extn ctype_l
|
||||
aux := ctype-info
|
||||
|
||||
tests := test_ctype
|
||||
|
||||
+57
-21
@@ -1,32 +1,68 @@
|
||||
/* Copyright (C) 1991 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
/* Copyright (C) 1991, 1997 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 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.
|
||||
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., 675 Mass Ave,
|
||||
Cambridge, MA 02139, USA. */
|
||||
|
||||
#include <ansidecl.h>
|
||||
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. */
|
||||
|
||||
#define __NO_CTYPE
|
||||
#include <ctype.h>
|
||||
|
||||
/* Real function versions of the non-ANSI ctype functions. */
|
||||
|
||||
int DEFUN(isblank, (c), int c) { return __isctype ((c), _ISblank); }
|
||||
int
|
||||
isblank (int c)
|
||||
{
|
||||
return __isctype (c, _ISblank);
|
||||
}
|
||||
|
||||
int DEFUN(_tolower, (c), int c) { return __tolower(c); }
|
||||
int DEFUN(_toupper, (c), int c) { return __toupper(c); }
|
||||
int
|
||||
_tolower (int c)
|
||||
{
|
||||
return __tolower (c);
|
||||
}
|
||||
int
|
||||
_toupper (int c)
|
||||
{
|
||||
return __toupper (c);
|
||||
}
|
||||
|
||||
int DEFUN(toascii, (c), int c) { return __toascii(c); }
|
||||
int DEFUN(isascii, (c), int c) { return __isascii(c); }
|
||||
int
|
||||
toascii (int c)
|
||||
{
|
||||
return __toascii (c);
|
||||
}
|
||||
int
|
||||
isascii (int c)
|
||||
{
|
||||
return __isascii (c);
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
__isblank_l (int c, __locale_t l)
|
||||
{
|
||||
return __isctype_l (c, _ISblank, l);
|
||||
}
|
||||
|
||||
int
|
||||
__toascii_l (int c, __locale_t l)
|
||||
{
|
||||
return __toascii (c);
|
||||
}
|
||||
int
|
||||
__isascii_l (int c, __locale_t l)
|
||||
{
|
||||
return __isascii (c);
|
||||
}
|
||||
|
||||
+14
-14
@@ -1,20 +1,20 @@
|
||||
/* Copyright (C) 1991, 1992, 1995, 1996 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
/* Copyright (C) 1991, 1992, 1995, 1996, 1997 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 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.
|
||||
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., 675 Mass Ave,
|
||||
Cambridge, MA 02139, USA. */
|
||||
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 <ctype.h>
|
||||
#include "../locale/localeinfo.h"
|
||||
|
||||
+28
-30
@@ -1,22 +1,20 @@
|
||||
/* Copyright (C) 1991, 1992 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
/* Copyright (C) 1991, 1992, 1997 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 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.
|
||||
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., 675 Mass Ave,
|
||||
Cambridge, MA 02139, USA. */
|
||||
|
||||
#include <ansidecl.h>
|
||||
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. */
|
||||
|
||||
#define __NO_CTYPE
|
||||
#include <ctype.h>
|
||||
@@ -24,28 +22,28 @@ Cambridge, MA 02139, USA. */
|
||||
/* Provide real-function versions of all the ctype macros. */
|
||||
|
||||
#define func(name, type) \
|
||||
int DEFUN(name, (c), int c) { return __isctype(c, type); }
|
||||
int name (int c) { return __isctype (c, type); }
|
||||
|
||||
func(isalnum, _ISalnum)
|
||||
func(isalpha, _ISalpha)
|
||||
func(iscntrl, _IScntrl)
|
||||
func(isdigit, _ISdigit)
|
||||
func(islower, _ISlower)
|
||||
func(isgraph, _ISgraph)
|
||||
func(isprint, _ISprint)
|
||||
func(ispunct, _ISpunct)
|
||||
func(isspace, _ISspace)
|
||||
func(isupper, _ISupper)
|
||||
func(isxdigit, _ISxdigit)
|
||||
func (isalnum, _ISalnum)
|
||||
func (isalpha, _ISalpha)
|
||||
func (iscntrl, _IScntrl)
|
||||
func (isdigit, _ISdigit)
|
||||
func (islower, _ISlower)
|
||||
func (isgraph, _ISgraph)
|
||||
func (isprint, _ISprint)
|
||||
func (ispunct, _ISpunct)
|
||||
func (isspace, _ISspace)
|
||||
func (isupper, _ISupper)
|
||||
func (isxdigit, _ISxdigit)
|
||||
|
||||
int
|
||||
DEFUN(tolower, (c), int c)
|
||||
tolower (int c)
|
||||
{
|
||||
return __tolower (c);
|
||||
}
|
||||
|
||||
int
|
||||
DEFUN(toupper, (c), int c)
|
||||
toupper (int c)
|
||||
{
|
||||
return __toupper (c);
|
||||
}
|
||||
|
||||
+78
-1
@@ -1,4 +1,4 @@
|
||||
/* Copyright (C) 1991, 92, 93, 95, 96 Free Software Foundation, Inc.
|
||||
/* Copyright (C) 1991, 92, 93, 95, 96, 97 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
|
||||
@@ -159,6 +159,83 @@ __exctype (_tolower);
|
||||
|
||||
#endif /* Not __NO_CTYPE. */
|
||||
|
||||
|
||||
#ifdef __USE_GNU
|
||||
/* The concept of one static locale per category is not very well
|
||||
thought out. Many applications will need to process its data using
|
||||
information from several different locales. Another application is
|
||||
the implementation of the internationalization handling in the
|
||||
upcoming ISO C++ standard library. To support this another set of
|
||||
the functions using locale data exist which have an additional
|
||||
argument.
|
||||
|
||||
Attention: all these functions are *not* standardized in any form.
|
||||
This is a proof-of-concept implementation. */
|
||||
|
||||
/* Structure for reentrant locale using functions. This is an
|
||||
(almost) opaque type for the user level programs. */
|
||||
# include <xlocale.h>
|
||||
|
||||
/* These definitions are similar to the ones above but all functions
|
||||
take as an argument a handle for the locale which shall be used. */
|
||||
#define __isctype_l(c, type, locale) \
|
||||
((locale)->__ctype_b[(int) (c)] & (unsigned short int) type)
|
||||
|
||||
#define __tolower_l(c, locale) ((int) (locale)->__ctype_tolower[(int) (c)])
|
||||
#define __toupper_l(c, locale) ((int) (locale)->__ctype_toupper[(int) (c)])
|
||||
|
||||
#define __exctype_l(name) extern int name __P ((int, __locale_t))
|
||||
|
||||
/* The following names are all functions:
|
||||
int isCHARACTERISTIC(int c, locale_t *locale);
|
||||
which return nonzero iff C has CHARACTERISTIC.
|
||||
For the meaning of the characteristic names, see the `enum' above. */
|
||||
__exctype_l (__isalnum_l);
|
||||
__exctype_l (__isalpha_l);
|
||||
__exctype_l (__iscntrl_l);
|
||||
__exctype_l (__isdigit_l);
|
||||
__exctype_l (__islower_l);
|
||||
__exctype_l (__isgraph_l);
|
||||
__exctype_l (__isprint_l);
|
||||
__exctype_l (__ispunct_l);
|
||||
__exctype_l (__isspace_l);
|
||||
__exctype_l (__isupper_l);
|
||||
__exctype_l (__isxdigit_l);
|
||||
|
||||
__exctype_l (__isblank_l);
|
||||
|
||||
|
||||
/* Return the lowercase version of C in locale L. */
|
||||
extern int __tolower_l __P ((int __c, __locale_t __l));
|
||||
|
||||
/* Return the uppercase version of C. */
|
||||
extern int __toupper_l __P ((int __c, __locale_t __l));
|
||||
|
||||
|
||||
#ifndef __NO_CTYPE
|
||||
#define __isalnum_l(c,l) __isctype_l((c), _ISalnum, (l))
|
||||
#define __isalpha_l(c,l) __isctype_l((c), _ISalpha, (l))
|
||||
#define __iscntrl_l(c,l) __isctype_l((c), _IScntrl, (l))
|
||||
#define __isdigit_l(c,l) __isctype_l((c), _ISdigit, (l))
|
||||
#define __islower_l(c,l) __isctype_l((c), _ISlower, (l))
|
||||
#define __isgraph_l(c,l) __isctype_l((c), _ISgraph, (l))
|
||||
#define __isprint_l(c,l) __isctype_l((c), _ISprint, (l))
|
||||
#define __ispunct_l(c,l) __isctype_l((c), _ISpunct, (l))
|
||||
#define __isspace_l(c,l) __isctype_l((c), _ISspace, (l))
|
||||
#define __isupper_l(c,l) __isctype_l((c), _ISupper, (l))
|
||||
#define __isxdigit_l(c,l) __isctype_l((c), _ISxdigit, (l))
|
||||
|
||||
#define __isblank_l(c,l) __isctype_l((c), _ISblank, (l))
|
||||
|
||||
#if defined(__USE_SVID) || defined(__USE_MISC) || defined(__USE_XOPEN)
|
||||
#define __isascii_l(c,l) __isascii(c)
|
||||
#define __toascii_l(c,l) __toascii(c)
|
||||
#endif
|
||||
|
||||
#endif /* Not __NO_CTYPE. */
|
||||
|
||||
#endif /* Use GNU. */
|
||||
|
||||
__END_DECLS
|
||||
|
||||
#endif /* ctype.h */
|
||||
|
||||
@@ -0,0 +1,49 @@
|
||||
/* Copyright (C) 1991, 1992, 1997 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. */
|
||||
|
||||
#define __NO_CTYPE
|
||||
#include <ctype.h>
|
||||
|
||||
/* Provide real-function versions of all the ctype macros. */
|
||||
|
||||
#define func(name, type) \
|
||||
int name (int c, __locale_t l) { return __isctype_l (c, type, l); }
|
||||
|
||||
func (__isalnum_l, _ISalnum)
|
||||
func (__isalpha_l, _ISalpha)
|
||||
func (__iscntrl_l, _IScntrl)
|
||||
func (__isdigit_l, _ISdigit)
|
||||
func (__islower_l, _ISlower)
|
||||
func (__isgraph_l, _ISgraph)
|
||||
func (__isprint_l, _ISprint)
|
||||
func (__ispunct_l, _ISpunct)
|
||||
func (__isspace_l, _ISspace)
|
||||
func (__isupper_l, _ISupper)
|
||||
func (__isxdigit_l, _ISxdigit)
|
||||
|
||||
int
|
||||
(__tolower_l) (int c, __locale_t l)
|
||||
{
|
||||
return __tolower_l (c, l);
|
||||
}
|
||||
|
||||
int
|
||||
(__toupper_l) (int c, __locale_t l)
|
||||
{
|
||||
return __toupper_l (c, l);
|
||||
}
|
||||
+17
-18
@@ -1,22 +1,21 @@
|
||||
/* Copyright (C) 1991, 1994, 1996 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
/* Copyright (C) 1991, 1994, 1996, 1997 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 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.
|
||||
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., 675 Mass Ave,
|
||||
Cambridge, MA 02139, USA. */
|
||||
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 <ansidecl.h>
|
||||
#include <limits.h>
|
||||
#include <ctype.h>
|
||||
#include <stdio.h>
|
||||
@@ -30,7 +29,7 @@ Cambridge, MA 02139, USA. */
|
||||
__inline
|
||||
#endif
|
||||
static void
|
||||
DEFUN(print_char, (c), unsigned char c)
|
||||
print_char (unsigned char c)
|
||||
{
|
||||
printf("%d/", (int) c);
|
||||
if (isgraph(c))
|
||||
@@ -40,9 +39,9 @@ DEFUN(print_char, (c), unsigned char c)
|
||||
}
|
||||
|
||||
int
|
||||
DEFUN(main, (argc, argv), int argc AND char **argv)
|
||||
main (int argc, char **argv)
|
||||
{
|
||||
register unsigned short int c;
|
||||
unsigned short int c;
|
||||
int lose = 0;
|
||||
|
||||
#define TRYEM do { \
|
||||
|
||||
+3
-2
@@ -674,7 +674,8 @@ bt_psplit(t, h, l, r, pskip, ilen)
|
||||
* where we decide to try and copy too much onto the left page.
|
||||
* Make sure that doesn't happen.
|
||||
*/
|
||||
if (skip <= off && used + nbytes >= full) {
|
||||
if (skip <= off &&
|
||||
used + nbytes + sizeof(indx_t) >= full || nxt == top - 1) {
|
||||
--off;
|
||||
break;
|
||||
}
|
||||
@@ -687,7 +688,7 @@ bt_psplit(t, h, l, r, pskip, ilen)
|
||||
memmove((char *)l + l->upper, src, nbytes);
|
||||
}
|
||||
|
||||
used += nbytes;
|
||||
used += nbytes + sizeof(indx_t);
|
||||
if (used >= half) {
|
||||
if (!isbigkey || bigkeycnt == 3)
|
||||
break;
|
||||
|
||||
@@ -43,6 +43,18 @@
|
||||
|
||||
#include <mpool.h>
|
||||
|
||||
#ifdef _LIBC
|
||||
/* In the GNU C library we must not pollute the namespace because libdb is
|
||||
needed by libnss_db. */
|
||||
#define mpool_open __mpool_open
|
||||
#define mpool_filter __mpool_filter
|
||||
#define mpool_new __mpool_new
|
||||
#define mpool_get __mpool_get
|
||||
#define mpool_put __mpool_put
|
||||
#define mpool_sync __mpool_sync
|
||||
#define mpool_close __mpool_close
|
||||
#endif
|
||||
|
||||
#define DEFMINKEYPAGE (2) /* Minimum keys per page */
|
||||
#define MINCACHE (5) /* Minimum cached pages */
|
||||
#define MINPSIZE (512) /* Minimum page size */
|
||||
|
||||
@@ -224,6 +224,7 @@ typedef struct {
|
||||
#endif
|
||||
|
||||
__BEGIN_DECLS
|
||||
DB *__dbopen __P((const char *, int, int, DBTYPE, const void *));
|
||||
DB *dbopen __P((const char *, int, int, DBTYPE, const void *));
|
||||
|
||||
#ifdef __DBINTERFACE_PRIVATE
|
||||
|
||||
+10
@@ -44,6 +44,12 @@ static char sccsid[] = "@(#)db.c 8.4 (Berkeley) 2/21/94";
|
||||
|
||||
#include <db.h>
|
||||
|
||||
#ifdef _LIBC
|
||||
/* In the GNU C library we must not pollute the namespace, because libdb
|
||||
is needed by libnss_db. */
|
||||
#define dbopen __dbopen
|
||||
#endif
|
||||
|
||||
DB *
|
||||
dbopen(fname, flags, mode, type, openinfo)
|
||||
const char *fname;
|
||||
@@ -72,6 +78,10 @@ dbopen(fname, flags, mode, type, openinfo)
|
||||
errno = EINVAL;
|
||||
return (NULL);
|
||||
}
|
||||
#ifdef _LIBC
|
||||
#undef dbopen
|
||||
weak_alias (__dbopen, dbopen)
|
||||
#endif
|
||||
|
||||
static int
|
||||
__dberr __P((void))
|
||||
|
||||
@@ -249,7 +249,7 @@ __big_delete(hashp, bufp)
|
||||
bufp->flags |= BUF_MOD;
|
||||
if (rbufp)
|
||||
__free_ovflpage(hashp, rbufp);
|
||||
if (last_bfp != rbufp)
|
||||
if (last_bfp && last_bfp != rbufp)
|
||||
__free_ovflpage(hashp, last_bfp);
|
||||
|
||||
hashp->NKEYS--;
|
||||
|
||||
+106
-103
@@ -1,4 +1,4 @@
|
||||
/* makedb -- create simple DB database from textual input.
|
||||
/* Create simple DB database from textual input.
|
||||
Copyright (C) 1996, 1997 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
Contributed by Ulrich Drepper <drepper@cygnus.com>, 1996.
|
||||
@@ -18,12 +18,12 @@
|
||||
write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
Boston, MA 02111-1307, USA. */
|
||||
|
||||
#include <db.h>
|
||||
#include <argp.h>
|
||||
#include <ctype.h>
|
||||
#include <db.h>
|
||||
#include <errno.h>
|
||||
#include <error.h>
|
||||
#include <fcntl.h>
|
||||
#include <getopt.h>
|
||||
#include <libintl.h>
|
||||
#include <locale.h>
|
||||
#include <stdio.h>
|
||||
@@ -35,20 +35,55 @@
|
||||
|
||||
#define PACKAGE _libc_intl_domainname
|
||||
|
||||
/* Long options. */
|
||||
static const struct option long_options[] =
|
||||
/* If non-zero convert key to lower case. */
|
||||
static int to_lowercase;
|
||||
|
||||
/* If non-zero print content of input file, one entry per line. */
|
||||
static int do_undo;
|
||||
|
||||
/* If non-zero do not print informational messages. */
|
||||
static int be_quiet;
|
||||
|
||||
/* Name of output file. */
|
||||
static const char *output_name;
|
||||
|
||||
/* Name and version of program. */
|
||||
static void print_version (FILE *stream, struct argp_state *state);
|
||||
void (*argp_program_version_hook) (FILE *, struct argp_state *) = print_version;
|
||||
|
||||
/* Definitions of arguments for argp functions. */
|
||||
static const struct argp_option options[] =
|
||||
{
|
||||
{ "help", no_argument, NULL, 'h' },
|
||||
{ "fold-case", no_argument, NULL, 'f' },
|
||||
{ "output", required_argument, NULL, 'o' },
|
||||
{ "quiet", no_argument, NULL, 'q' },
|
||||
{ "undo", no_argument, NULL, 'u' },
|
||||
{ "version", no_argument, NULL, 'V' },
|
||||
{ NULL, 0, NULL, 0}
|
||||
{ "fold-case", 'f', NULL, 0, N_("Convert key to lower case") },
|
||||
{ "output", 'o', N_("NAME"), 0, N_("Write output to file NAME") },
|
||||
{ "quiet", 'q', NULL, 0,
|
||||
N_("Do not print messages while building database") },
|
||||
{ "undo", 'u', NULL, 0,
|
||||
N_("Print content of database file, one entry a line") },
|
||||
{ NULL, 0, NULL, 0, NULL }
|
||||
};
|
||||
|
||||
/* Short description of program. */
|
||||
static const char doc[] = N_("Create simple DB database from textual input.");
|
||||
|
||||
/* Strings for arguments in help texts. */
|
||||
static const char args_doc[] = N_("\
|
||||
INPUT-FILE OUTPUT-FILE\n-o OUTPUT-FILE INPUT-FILE\n-u INPUT-FILE");
|
||||
|
||||
/* Prototype for option handler. */
|
||||
static error_t parse_opt __P ((int key, char *arg, struct argp_state *state));
|
||||
|
||||
/* Function to print some extra text in the help message. */
|
||||
static char *more_help __P ((int key, const char *text, void *input));
|
||||
|
||||
/* Data structure to communicate with argp functions. */
|
||||
static struct argp argp =
|
||||
{
|
||||
options, parse_opt, args_doc, doc, NULL, more_help
|
||||
};
|
||||
|
||||
|
||||
/* Prototypes for local functions. */
|
||||
static void usage __P ((int status)) __attribute__ ((noreturn));
|
||||
static int process_input __P ((FILE *input, const char *inname, DB *output,
|
||||
int to_lowercase, int be_quiet));
|
||||
static int print_database __P ((DB *db));
|
||||
@@ -60,17 +95,11 @@ main (argc, argv)
|
||||
int argc;
|
||||
char *argv[];
|
||||
{
|
||||
const char *output_name;
|
||||
const char *input_name;
|
||||
FILE *input_file;
|
||||
DB *db_file;
|
||||
int do_help;
|
||||
int do_version;
|
||||
int to_lowercase;
|
||||
int do_undo;
|
||||
int be_quiet;
|
||||
int status;
|
||||
int opt;
|
||||
int remaining;
|
||||
|
||||
/* Set locale via LC_ALL. */
|
||||
setlocale (LC_ALL, "");
|
||||
@@ -79,78 +108,30 @@ main (argc, argv)
|
||||
textdomain (_libc_intl_domainname);
|
||||
|
||||
/* Initialize local variables. */
|
||||
do_help = 0;
|
||||
do_version = 0;
|
||||
to_lowercase = 0;
|
||||
do_undo = 0;
|
||||
be_quiet = 0;
|
||||
output_name = NULL;
|
||||
input_name = NULL;
|
||||
|
||||
while ((opt = getopt_long (argc, argv, "fho:uV", long_options, NULL)) != -1)
|
||||
switch (opt)
|
||||
{
|
||||
case '\0': /* Long option. */
|
||||
break;
|
||||
case 'h':
|
||||
do_help = 1;
|
||||
break;
|
||||
case 'f':
|
||||
to_lowercase = 1;
|
||||
break;
|
||||
case 'o':
|
||||
output_name = optarg;
|
||||
break;
|
||||
case 'q':
|
||||
be_quiet = 1;
|
||||
break;
|
||||
case 'u':
|
||||
do_undo = 1;
|
||||
break;
|
||||
case 'V':
|
||||
do_version = 1;
|
||||
break;
|
||||
default:
|
||||
usage (EXIT_FAILURE);
|
||||
}
|
||||
|
||||
/* Version information is requested. */
|
||||
if (do_version)
|
||||
{
|
||||
printf ("makedb (GNU %s) %s\n", PACKAGE, VERSION);
|
||||
printf (_("\
|
||||
Copyright (C) %s Free Software Foundation, Inc.\n\
|
||||
This is free software; see the source for copying conditions. There is NO\n\
|
||||
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n\
|
||||
"), "1996, 1997");
|
||||
printf (_("Written by %s.\n"), "Ulrich Drepper");
|
||||
|
||||
exit (EXIT_SUCCESS);
|
||||
}
|
||||
|
||||
/* Help is requested. */
|
||||
if (do_help)
|
||||
usage (EXIT_SUCCESS);
|
||||
else if (do_version)
|
||||
exit (EXIT_SUCCESS);
|
||||
/* Parse and process arguments. */
|
||||
argp_parse (&argp, argc, argv, 0, &remaining, NULL);
|
||||
|
||||
/* Determine file names. */
|
||||
if (do_undo || output_name != NULL)
|
||||
{
|
||||
if (optind + 1 != argc)
|
||||
if (remaining + 1 != argc)
|
||||
{
|
||||
wrong_arguments:
|
||||
error (0, 0, gettext ("wrong number of arguments"));
|
||||
usage (EXIT_FAILURE);
|
||||
argp_help (&argp, stdout, ARGP_HELP_SEE,
|
||||
program_invocation_short_name);
|
||||
}
|
||||
input_name = argv[optind];
|
||||
input_name = argv[remaining];
|
||||
}
|
||||
else
|
||||
{
|
||||
if (optind + 2 != argc)
|
||||
if (remaining + 2 != argc)
|
||||
goto wrong_arguments;
|
||||
|
||||
input_name = argv[optind++];
|
||||
output_name = argv[optind];
|
||||
input_name = argv[remaining++];
|
||||
output_name = argv[remaining];
|
||||
}
|
||||
|
||||
/* Special handling if we are asked to print the database. */
|
||||
@@ -201,35 +182,57 @@ warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n\
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
usage (status)
|
||||
int status;
|
||||
/* Handle program arguments. */
|
||||
static error_t
|
||||
parse_opt (int key, char *arg, struct argp_state *state)
|
||||
{
|
||||
if (status != EXIT_SUCCESS)
|
||||
fprintf (stderr, gettext ("Try `%s --help' for more information.\n"),
|
||||
program_invocation_name);
|
||||
else
|
||||
switch (key)
|
||||
{
|
||||
printf (gettext ("\
|
||||
Usage: %s [OPTION]... INPUT-FILE OUTPUT-FILE\n\
|
||||
%s [OPTION]... -o OUTPUT-FILE INPUT-FILE\n\
|
||||
%s [OPTION]... -u INPUT-FILE\n\
|
||||
Mandatory arguments to long options are mandatory for short options too.\n\
|
||||
-f, --fold-case convert key to lower case\n\
|
||||
-h, --help display this help and exit\n\
|
||||
-o, --output=NAME write output to file NAME\n\
|
||||
--quiet don't print messages while building database\n\
|
||||
-u, --undo print content of database file, one entry a line\n\
|
||||
-V, --version output version information and exit\n\
|
||||
If INPUT-FILE is -, input is read from standard input.\n"),
|
||||
program_invocation_name, program_invocation_name,
|
||||
program_invocation_name);
|
||||
fputs (gettext ("\
|
||||
Report bugs using the `glibcbug' script to <bugs@gnu.ai.mit.edu>.\n"),
|
||||
stdout);
|
||||
case 'f':
|
||||
to_lowercase = 1;
|
||||
break;
|
||||
case 'o':
|
||||
output_name = arg;
|
||||
break;
|
||||
case 'q':
|
||||
be_quiet = 1;
|
||||
break;
|
||||
case 'u':
|
||||
do_undo = 1;
|
||||
break;
|
||||
default:
|
||||
return ARGP_ERR_UNKNOWN;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
exit (status);
|
||||
|
||||
static char *
|
||||
more_help (int key, const char *text, void *input)
|
||||
{
|
||||
switch (key)
|
||||
{
|
||||
case ARGP_KEY_HELP_EXTRA:
|
||||
/* We print some extra information. */
|
||||
return strdup (gettext ("\
|
||||
Report bugs using the `glibcbug' script to <bugs@gnu.ai.mit.edu>.\n"));
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return (char *) text;
|
||||
}
|
||||
|
||||
/* Print the version information. */
|
||||
static void
|
||||
print_version (FILE *stream, struct argp_state *state)
|
||||
{
|
||||
fprintf (stream, "makedb (GNU %s) %s\n", PACKAGE, VERSION);
|
||||
fprintf (stream, gettext ("\
|
||||
Copyright (C) %s Free Software Foundation, Inc.\n\
|
||||
This is free software; see the source for copying conditions. There is NO\n\
|
||||
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n\
|
||||
"), "1996, 1997");
|
||||
fprintf (stream, gettext ("Written by %s.\n"), "Ulrich Drepper");
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -85,13 +85,21 @@ typedef struct MPOOL {
|
||||
} MPOOL;
|
||||
|
||||
__BEGIN_DECLS
|
||||
MPOOL *__mpool_open __P((void *, int, pgno_t, pgno_t));
|
||||
MPOOL *mpool_open __P((void *, int, pgno_t, pgno_t));
|
||||
void __mpool_filter __P((MPOOL *, void (*)(void *, pgno_t, void *),
|
||||
void (*)(void *, pgno_t, void *), void *));
|
||||
void mpool_filter __P((MPOOL *, void (*)(void *, pgno_t, void *),
|
||||
void (*)(void *, pgno_t, void *), void *));
|
||||
void *__mpool_new __P((MPOOL *, pgno_t *));
|
||||
void *mpool_new __P((MPOOL *, pgno_t *));
|
||||
void *__mpool_get __P((MPOOL *, pgno_t, u_int));
|
||||
void *mpool_get __P((MPOOL *, pgno_t, u_int));
|
||||
int __mpool_put __P((MPOOL *, void *, u_int));
|
||||
int mpool_put __P((MPOOL *, void *, u_int));
|
||||
int __mpool_sync __P((MPOOL *));
|
||||
int mpool_sync __P((MPOOL *));
|
||||
int __mpool_close __P((MPOOL *));
|
||||
int mpool_close __P((MPOOL *));
|
||||
#ifdef STATISTICS
|
||||
void mpool_stat __P((MPOOL *));
|
||||
|
||||
@@ -50,6 +50,18 @@ static char sccsid[] = "@(#)mpool.c 8.5 (Berkeley) 7/26/94";
|
||||
#define __MPOOLINTERFACE_PRIVATE
|
||||
#include <mpool.h>
|
||||
|
||||
#ifdef _LIBC
|
||||
/* In the GNU C library we must not pollute the namespace because libdb is
|
||||
needed by libnss_db. */
|
||||
#define mpool_open __mpool_open
|
||||
#define mpool_filter __mpool_filter
|
||||
#define mpool_new __mpool_new
|
||||
#define mpool_get __mpool_get
|
||||
#define mpool_put __mpool_put
|
||||
#define mpool_sync __mpool_sync
|
||||
#define mpool_close __mpool_close
|
||||
#endif
|
||||
|
||||
static BKT *mpool_bkt __P((MPOOL *));
|
||||
static BKT *mpool_look __P((MPOOL *, pgno_t));
|
||||
static int mpool_write __P((MPOOL *, BKT *));
|
||||
@@ -301,6 +313,23 @@ mpool_sync(mp)
|
||||
return (fsync(mp->fd) ? RET_ERROR : RET_SUCCESS);
|
||||
}
|
||||
|
||||
#ifdef _LIBC
|
||||
#undef mpool_open
|
||||
#undef mpool_filter
|
||||
#undef mpool_new
|
||||
#undef mpool_get
|
||||
#undef mpool_put
|
||||
#undef mpool_close
|
||||
#undef mpool_sync
|
||||
weak_alias (__mpool_open, mpool_open)
|
||||
weak_alias (__mpool_filter, mpool_filter)
|
||||
weak_alias (__mpool_new, mpool_new)
|
||||
weak_alias (__mpool_get, mpool_get)
|
||||
weak_alias (__mpool_put, mpool_put)
|
||||
weak_alias (__mpool_close, mpool_close)
|
||||
weak_alias (__mpool_sync, mpool_sync)
|
||||
#endif
|
||||
|
||||
/*
|
||||
* mpool_bkt
|
||||
* Get a page from the cache (or create one).
|
||||
|
||||
+17
-19
@@ -1,29 +1,27 @@
|
||||
/* Copyright (C) 1992 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
/* Copyright (C) 1992, 1997 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 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.
|
||||
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., 675 Mass Ave,
|
||||
Cambridge, MA 02139, USA. */
|
||||
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 <ansidecl.h>
|
||||
#include <dirent.h>
|
||||
#include <string.h>
|
||||
|
||||
int
|
||||
DEFUN(alphasort, (a, b),
|
||||
CONST PTR a AND CONST PTR b)
|
||||
alphasort (const void *a, const void *b)
|
||||
{
|
||||
return strcmp (((struct dirent *) a)->d_name,
|
||||
((struct dirent *) b)->d_name);
|
||||
return strcmp ((*(const struct dirent **) a)->d_name,
|
||||
(*(const struct dirent **) b)->d_name);
|
||||
}
|
||||
|
||||
+28
-29
@@ -1,22 +1,21 @@
|
||||
/* Copyright (C) 1991, 1993 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
/* Copyright (C) 1991, 1993, 1997 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 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.
|
||||
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., 675 Mass Ave,
|
||||
Cambridge, MA 02139, USA. */
|
||||
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 <ansidecl.h>
|
||||
#include <errno.h>
|
||||
#include <stddef.h>
|
||||
#include <stdio.h>
|
||||
@@ -25,44 +24,44 @@ Cambridge, MA 02139, USA. */
|
||||
|
||||
|
||||
void
|
||||
DEFUN(test, (name), CONST char *name)
|
||||
test (const char *name)
|
||||
{
|
||||
DIR *dirp;
|
||||
struct dirent *entp;
|
||||
|
||||
puts(name);
|
||||
puts (name);
|
||||
|
||||
dirp = opendir(name);
|
||||
dirp = opendir (name);
|
||||
if (dirp == NULL)
|
||||
{
|
||||
perror("opendir");
|
||||
perror ("opendir");
|
||||
return;
|
||||
}
|
||||
|
||||
errno = 0;
|
||||
while ((entp = readdir(dirp)) != NULL)
|
||||
printf("%s\tfile number %lu\n",
|
||||
entp->d_name, (unsigned long int) entp->d_fileno);
|
||||
while ((entp = readdir (dirp)) != NULL)
|
||||
printf ("%s\tfile number %lu\n",
|
||||
entp->d_name, (unsigned long int) entp->d_fileno);
|
||||
|
||||
if (errno)
|
||||
perror ("readdir");
|
||||
|
||||
if (closedir(dirp) < 0)
|
||||
perror("closedir");
|
||||
if (closedir (dirp) < 0)
|
||||
perror ("closedir");
|
||||
}
|
||||
|
||||
int
|
||||
DEFUN(main, (argc, argv), int argc AND char **argv)
|
||||
main (int argc, char **argv)
|
||||
{
|
||||
--argc;
|
||||
++argv;
|
||||
|
||||
if (argc == 0)
|
||||
test(".");
|
||||
test (".");
|
||||
else
|
||||
while (argc-- > 0)
|
||||
test(*argv++);
|
||||
test (*argv++);
|
||||
|
||||
exit(0);
|
||||
return(0);
|
||||
exit (0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
+3
-3
@@ -22,7 +22,7 @@ subdir := elf
|
||||
|
||||
headers = elf.h elfclass.h link.h dlfcn.h
|
||||
routines = $(dl-routines) dl-open dl-close dl-symbol dl-support \
|
||||
enbl-secure
|
||||
dl-version enbl-secure
|
||||
|
||||
# The core dynamic linking functions are in libc for the static and
|
||||
# profiled libraries.
|
||||
@@ -39,7 +39,7 @@ distribute = $(rtld-routines:=.c) dynamic-link.h do-rel.h dl-machine.h \
|
||||
|
||||
extra-libs = libdl
|
||||
extra-libs-others = $(extra-libs)
|
||||
libdl-routines := dlopen dlclose dlsym dlerror dladdr
|
||||
libdl-routines := dlopen dlclose dlsym dlvsym dlerror dladdr
|
||||
|
||||
before-compile = $(objpfx)trusted-dirs.h
|
||||
|
||||
@@ -56,7 +56,7 @@ install-bin = ldd
|
||||
endif
|
||||
|
||||
ifeq (yes,$(has-ldconfig))
|
||||
extra-objs = ldconfig.o
|
||||
extra-objs += ldconfig.o
|
||||
install-rootsbin = ldconfig
|
||||
|
||||
$(objpfx)ldconfig: $(objpfx)ldconfig.o
|
||||
|
||||
+31
-14
@@ -22,6 +22,29 @@
|
||||
#include <dlfcn.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
struct openaux_args
|
||||
{
|
||||
/* The arguments to openaux. */
|
||||
struct link_map *map;
|
||||
int trace_mode;
|
||||
const char *strtab;
|
||||
ElfW(Dyn) *d;
|
||||
|
||||
/* The return value of openaux. */
|
||||
struct link_map *aux;
|
||||
};
|
||||
|
||||
static void
|
||||
openaux (void *a)
|
||||
{
|
||||
struct openaux_args *args = (struct openaux_args *) a;
|
||||
|
||||
args->aux = _dl_map_object (args->map, args->strtab + args->d->d_un.d_val,
|
||||
(args->map->l_type == lt_executable
|
||||
? lt_library : args->map->l_type),
|
||||
args->trace_mode);
|
||||
}
|
||||
|
||||
void
|
||||
_dl_map_object_deps (struct link_map *map,
|
||||
struct link_map **preloads, unsigned int npreloads,
|
||||
@@ -75,27 +98,21 @@ _dl_map_object_deps (struct link_map *map,
|
||||
/* There is at least one auxiliary library specified. We try to
|
||||
load it, and if we can, use its symbols in preference to our
|
||||
own. But if we can't load it, we just silently ignore it. */
|
||||
const char *strtab
|
||||
struct openaux_args args;
|
||||
args.strtab
|
||||
= ((void *) map->l_addr + map->l_info[DT_STRTAB]->d_un.d_ptr);
|
||||
ElfW(Dyn) *d;
|
||||
args.map = map;
|
||||
args.trace_mode = trace_mode;
|
||||
|
||||
for (d = map->l_ld; d->d_tag != DT_NULL; ++d)
|
||||
if (d->d_tag == DT_AUXILIARY)
|
||||
for (args.d = map->l_ld; args.d->d_tag != DT_NULL; ++args.d)
|
||||
if (args.d->d_tag == DT_AUXILIARY)
|
||||
{
|
||||
struct link_map *aux;
|
||||
void openaux (void)
|
||||
{
|
||||
aux = _dl_map_object (map, strtab + d->d_un.d_val,
|
||||
(map->l_type == lt_executable
|
||||
? lt_library : map->l_type),
|
||||
trace_mode);
|
||||
}
|
||||
char *errstring;
|
||||
const char *objname;
|
||||
if (! _dl_catch_error (&errstring, &objname, openaux))
|
||||
if (! _dl_catch_error (&errstring, &objname, openaux, &args))
|
||||
/* The auxiliary object is actually there. Use it as
|
||||
the first search element, even before MAP itself. */
|
||||
preload (aux);
|
||||
preload (args.aux);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+14
-8
@@ -66,9 +66,9 @@ _dl_signal_error (int errcode,
|
||||
else if (receiver)
|
||||
{
|
||||
/* We are inside _dl_receive_error. Call the user supplied
|
||||
handler and resume the work. The receiver will still
|
||||
handler and resume the work. The receiver will still be
|
||||
installed. */
|
||||
(*receiver) (errstring, objname);
|
||||
(*receiver) (errcode, objname, errstring);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -85,19 +85,25 @@ _dl_signal_error (int errcode,
|
||||
int
|
||||
_dl_catch_error (char **errstring,
|
||||
const char **objname,
|
||||
void (*operate) (void))
|
||||
void (*operate) (void *),
|
||||
void *args)
|
||||
{
|
||||
int errcode;
|
||||
struct catch *old, c = { errstring: NULL, objname: NULL };
|
||||
/* We need not handle `receiver' since setting a `catch' is handle
|
||||
struct catch *old, c;
|
||||
/* We need not handle `receiver' since setting a `catch' is handled
|
||||
before it. */
|
||||
|
||||
/* Some systems (.e.g, SPARC) handle constructors to local variables
|
||||
inefficient. So we initialize `c' by hand. */
|
||||
c.errstring = NULL;
|
||||
c.objname = NULL;
|
||||
|
||||
old = catch;
|
||||
errcode = setjmp (c.env);
|
||||
if (errcode == 0)
|
||||
{
|
||||
catch = &c;
|
||||
(*operate) ();
|
||||
(*operate) (args);
|
||||
catch = old;
|
||||
*errstring = NULL;
|
||||
*objname = NULL;
|
||||
@@ -112,7 +118,7 @@ _dl_catch_error (char **errstring,
|
||||
}
|
||||
|
||||
void
|
||||
_dl_receive_error (receiver_fct fct, void (*operate) (void))
|
||||
_dl_receive_error (receiver_fct fct, void (*operate) (void *), void *args)
|
||||
{
|
||||
struct catch *old_catch;
|
||||
receiver_fct old_receiver;
|
||||
@@ -124,7 +130,7 @@ _dl_receive_error (receiver_fct fct, void (*operate) (void))
|
||||
catch = NULL;
|
||||
receiver = fct;
|
||||
|
||||
(*operate) ();
|
||||
(*operate) (args);
|
||||
|
||||
catch = old_catch;
|
||||
receiver = old_receiver;
|
||||
|
||||
@@ -0,0 +1,69 @@
|
||||
/* Compute hash alue for given string according to ELF standard.
|
||||
Copyright (C) 1995, 1996, 1997 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 _DL_HASH_H
|
||||
#define _DL_HASH_H 1
|
||||
|
||||
|
||||
/* This is the hashing function specified by the ELF ABI. In the
|
||||
first five operations now overflow is possible so we optimized it a
|
||||
bit. */
|
||||
static inline unsigned
|
||||
_dl_elf_hash (const char *name)
|
||||
{
|
||||
unsigned long int hash = 0;
|
||||
if (*name != '\0')
|
||||
{
|
||||
hash = (hash << 4) + *name++;
|
||||
if (*name != '\0')
|
||||
{
|
||||
hash = (hash << 4) + *name++;
|
||||
if (*name != '\0')
|
||||
{
|
||||
hash = (hash << 4) + *name++;
|
||||
if (*name != '\0')
|
||||
{
|
||||
hash = (hash << 4) + *name++;
|
||||
if (*name != '\0')
|
||||
{
|
||||
hash = (hash << 4) + *name++;
|
||||
while (*name != '\0')
|
||||
{
|
||||
unsigned long int hi;
|
||||
hash = (hash << 4) + *name++;
|
||||
hi = hash & 0xf0000000;
|
||||
if (hi != 0)
|
||||
{
|
||||
hash ^= hi >> 24;
|
||||
/* The ELF ABI says `hash &= ~hi', but
|
||||
this is equivalent in this case and
|
||||
on some machines one insn instead of
|
||||
two. */
|
||||
hash ^= hi;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return hash;
|
||||
}
|
||||
|
||||
#endif /* dl-hash.h */
|
||||
+56
-9
@@ -67,6 +67,18 @@ int _dl_zerofd = -1;
|
||||
#define ANONFD _dl_zerofd
|
||||
#endif
|
||||
|
||||
/* Handle situations where we have a preferred location in memory for
|
||||
the shared objects. */
|
||||
#ifdef ELF_PREFERRED_ADDRESS_DATA
|
||||
ELF_PREFERRED_ADDRESS_DATA;
|
||||
#endif
|
||||
#ifndef ELF_PREFERRED_ADDRESS
|
||||
#define ELF_PREFERRED_ADDRESS(loader, maplength, mapstartpref) (mapstartpref)
|
||||
#endif
|
||||
#ifndef ELF_FIXED_ADDRESS
|
||||
#define ELF_FIXED_ADDRESS(loader, mapstart) ((void) 0)
|
||||
#endif
|
||||
|
||||
size_t _dl_pagesize;
|
||||
|
||||
|
||||
@@ -154,11 +166,34 @@ _dl_map_object_from_fd (char *name, int fd, char *realname,
|
||||
for (l = _dl_loaded; l; l = l->l_next)
|
||||
if (! strcmp (realname, l->l_name))
|
||||
{
|
||||
struct libname_list *lnp, *lastp;
|
||||
/* The object is already loaded.
|
||||
Just bump its reference count and return it. */
|
||||
__close (fd);
|
||||
free (name);
|
||||
|
||||
/* If the name is not in the list of names for this object add
|
||||
it. */
|
||||
free (realname);
|
||||
lastp = NULL;
|
||||
for (lnp = l->l_libname; lnp != NULL; lastp = lnp, lnp = lnp->next)
|
||||
if (strcmp (name, lnp->name) == 0)
|
||||
{
|
||||
free (name);
|
||||
break;
|
||||
}
|
||||
if (lnp == NULL)
|
||||
{
|
||||
struct libname_list *newname = malloc (sizeof *newname);
|
||||
if (newname == NULL)
|
||||
/* No more memory. */
|
||||
lose (ENOMEM, "cannot allocate name record");
|
||||
/* The object should have a libname set. */
|
||||
assert (lastp != NULL);
|
||||
|
||||
newname->name = name;
|
||||
newname->next = NULL;
|
||||
lastp->next = newname;
|
||||
}
|
||||
++l->l_opencount;
|
||||
return l;
|
||||
}
|
||||
@@ -292,11 +327,16 @@ _dl_map_object_from_fd (char *name, int fd, char *realname,
|
||||
So we map the first segment without MAP_FIXED, but with its
|
||||
extent increased to cover all the segments. Then we remove
|
||||
access from excess portion, and there is known sufficient space
|
||||
there to remap from the later segments. */
|
||||
there to remap from the later segments.
|
||||
|
||||
As a refinement, sometimes we have an address that we would
|
||||
prefer to map such objects at; but this is only a preference,
|
||||
the OS can do whatever it likes. */
|
||||
caddr_t mapat;
|
||||
mapat = map_segment (c->mapstart,
|
||||
loadcmds[nloadcmds - 1].allocend - c->mapstart,
|
||||
c->prot, 0, c->mapoff);
|
||||
ElfW(Addr) mappref;
|
||||
size_t maplength = loadcmds[nloadcmds - 1].allocend - c->mapstart;
|
||||
mappref = ELF_PREFERRED_ADDRESS (loader, maplength, c->mapstart);
|
||||
mapat = map_segment (mappref, maplength, c->prot, 0, c->mapoff);
|
||||
l->l_addr = (ElfW(Addr)) mapat - c->mapstart;
|
||||
|
||||
/* Change protection on the excess portion to disallow all access;
|
||||
@@ -309,6 +349,12 @@ _dl_map_object_from_fd (char *name, int fd, char *realname,
|
||||
0);
|
||||
goto postmap;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Notify ELF_PREFERRED_ADDRESS that we have to load this one
|
||||
fixed. */
|
||||
ELF_FIXED_ADDRESS (loader, c->mapstart);
|
||||
}
|
||||
|
||||
while (c < &loadcmds[nloadcmds])
|
||||
{
|
||||
@@ -517,8 +563,7 @@ _dl_map_object (struct link_map *loader, const char *name, int type,
|
||||
|
||||
/* Look for this name among those already loaded. */
|
||||
for (l = _dl_loaded; l; l = l->l_next)
|
||||
if (! strcmp (name, l->l_libname) || /* NAME was requested before. */
|
||||
! strcmp (name, l->l_name) || /* NAME was found before. */
|
||||
if (_dl_name_match_p (name, l) ||
|
||||
/* If the requested name matches the soname of a loaded object,
|
||||
use that object. */
|
||||
(l->l_info[DT_SONAME] &&
|
||||
@@ -559,15 +604,17 @@ _dl_map_object (struct link_map *loader, const char *name, int type,
|
||||
l->l_info[DT_STRTAB]->d_un.d_ptr +
|
||||
l->l_info[DT_RPATH]->d_un.d_val), NULL);
|
||||
/* Try an environment variable (unless setuid). */
|
||||
if (fd == -1 && ! __libc_enable_secure)
|
||||
if (fd == -1)
|
||||
{
|
||||
static const char *trusted_dirs[] =
|
||||
{
|
||||
#include "trusted-dirs.h"
|
||||
NULL
|
||||
};
|
||||
const char *ld_library_path = getenv ("LD_LIBRARY_PATH");
|
||||
|
||||
trypath (getenv ("LD_LIBRARY_PATH"), trusted_dirs);
|
||||
if (ld_library_path != NULL && *ld_library_path != '\0')
|
||||
trypath (ld_library_path, trusted_dirs);
|
||||
}
|
||||
if (fd == -1)
|
||||
{
|
||||
|
||||
+176
-50
@@ -1,5 +1,5 @@
|
||||
/* Look up a symbol in the loaded objects.
|
||||
Copyright (C) 1995, 1996 Free Software Foundation, Inc.
|
||||
Copyright (C) 1995, 1996, 1997 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,6 +22,11 @@
|
||||
#include <assert.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "dl-hash.h"
|
||||
#include <dl-machine.h>
|
||||
#include "../stdio-common/_itoa.h"
|
||||
|
||||
#define VERSTAG(tag) (DT_NUM + DT_PROCNUM + DT_VERSIONTAGIDX (tag))
|
||||
|
||||
struct sym_val
|
||||
{
|
||||
@@ -30,34 +35,33 @@ struct sym_val
|
||||
};
|
||||
|
||||
|
||||
/* This is the hashing function specified by the ELF ABI. */
|
||||
static inline unsigned
|
||||
_dl_elf_hash (const char *name)
|
||||
{
|
||||
unsigned long int hash = 0;
|
||||
while (*name != '\0')
|
||||
{
|
||||
unsigned long int hi;
|
||||
hash = (hash << 4) + *name++;
|
||||
hi = hash & 0xf0000000;
|
||||
if (hi != 0)
|
||||
{
|
||||
hash ^= hi >> 24;
|
||||
/* The ELF ABI says `hash &= ~hi', but this is equivalent
|
||||
in this case and on some machines one insn instead of two. */
|
||||
hash ^= hi;
|
||||
}
|
||||
}
|
||||
return hash;
|
||||
}
|
||||
#define make_string(string, rest...) \
|
||||
({ \
|
||||
const char *all[] = { string, ## rest }; \
|
||||
size_t len, cnt; \
|
||||
char *result, *cp; \
|
||||
\
|
||||
len = 1; \
|
||||
for (cnt = 0; cnt < sizeof (all) / sizeof (all[0]); ++cnt) \
|
||||
len += strlen (all[cnt]); \
|
||||
\
|
||||
cp = result = alloca (len); \
|
||||
for (cnt = 0; cnt < sizeof (all) / sizeof (all[0]); ++cnt) \
|
||||
cp = stpcpy (cp, all[cnt]); \
|
||||
\
|
||||
result; \
|
||||
})
|
||||
|
||||
|
||||
/* Inner part of the lookup functions. */
|
||||
static inline ElfW(Addr)
|
||||
/* Inner part of the lookup functions. We return a value > 0 if we
|
||||
found the symbol, the value 0 if nothing is found and < 0 if
|
||||
something bad happened. */
|
||||
static inline int
|
||||
do_lookup (const char *undef_name, unsigned long int hash,
|
||||
const ElfW(Sym) **ref, struct sym_val *result,
|
||||
const ElfW(Sym) *ref, struct sym_val *result,
|
||||
struct link_map *list[], size_t i, size_t n,
|
||||
const char *reference_name, struct link_map *skip, int flags)
|
||||
const char *reference_name, const struct r_found_version *version,
|
||||
struct link_map *skip, int reloc_type)
|
||||
{
|
||||
struct link_map *map;
|
||||
|
||||
@@ -65,6 +69,7 @@ do_lookup (const char *undef_name, unsigned long int hash,
|
||||
{
|
||||
const ElfW(Sym) *symtab;
|
||||
const char *strtab;
|
||||
const ElfW(Half) *verstab;
|
||||
ElfW(Symndx) symidx;
|
||||
|
||||
map = list[i];
|
||||
@@ -74,11 +79,17 @@ do_lookup (const char *undef_name, unsigned long int hash,
|
||||
continue;
|
||||
|
||||
/* Don't search the executable when resolving a copy reloc. */
|
||||
if (flags & DL_LOOKUP_NOEXEC && map->l_type == lt_executable)
|
||||
if (elf_machine_lookup_noexec_p (reloc_type) &&
|
||||
map->l_type == lt_executable)
|
||||
continue;
|
||||
|
||||
symtab = ((void *) map->l_addr + map->l_info[DT_SYMTAB]->d_un.d_ptr);
|
||||
strtab = ((void *) map->l_addr + map->l_info[DT_STRTAB]->d_un.d_ptr);
|
||||
if (map->l_nversions > 0 && map->l_info[VERSTAG (DT_VERSYM)] != NULL)
|
||||
verstab = ((void *) map->l_addr
|
||||
+ map->l_info[VERSTAG (DT_VERSYM)]->d_un.d_ptr);
|
||||
else
|
||||
verstab = NULL;
|
||||
|
||||
/* Search the appropriate hash bucket in this object's symbol table
|
||||
for a definition for the same symbol name. */
|
||||
@@ -89,7 +100,7 @@ do_lookup (const char *undef_name, unsigned long int hash,
|
||||
const ElfW(Sym) *sym = &symtab[symidx];
|
||||
|
||||
if (sym->st_value == 0 || /* No value. */
|
||||
((flags & DL_LOOKUP_NOPLT) != 0 /* Reject PLT entry. */
|
||||
(elf_machine_lookup_noplt_p (reloc_type) /* Reject PLT entry. */
|
||||
&& sym->st_shndx == SHN_UNDEF))
|
||||
continue;
|
||||
|
||||
@@ -104,10 +115,47 @@ do_lookup (const char *undef_name, unsigned long int hash,
|
||||
continue;
|
||||
}
|
||||
|
||||
if (sym != *ref && strcmp (strtab + sym->st_name, undef_name))
|
||||
if (sym != ref && strcmp (strtab + sym->st_name, undef_name))
|
||||
/* Not the symbol we are looking for. */
|
||||
continue;
|
||||
|
||||
if (version == NULL)
|
||||
{
|
||||
/* No specific version is selected. When the object
|
||||
file also does not define a version we have a match.
|
||||
Otherwise we only accept the default version, i.e.,
|
||||
the version which name is "". */
|
||||
if (verstab != NULL)
|
||||
{
|
||||
ElfW(Half) ndx = verstab[symidx] & 0x7fff;
|
||||
if (map->l_versions[ndx].hash != 0)
|
||||
continue;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (verstab == NULL)
|
||||
{
|
||||
/* We need a versioned system but haven't found any.
|
||||
If this is the object which is referenced in the
|
||||
verneed entry it is a bug in the library since a
|
||||
symbol must not simply disappear. */
|
||||
if (version->filename != NULL
|
||||
&& _dl_name_match_p (version->filename, map))
|
||||
return -1;
|
||||
/* Otherwise we accept the symbol. */
|
||||
}
|
||||
else
|
||||
{
|
||||
/* We can match the version information. */
|
||||
ElfW(Half) ndx = verstab[symidx] & 0x7fff;
|
||||
if (map->l_versions[ndx].hash != version->hash
|
||||
|| strcmp (map->l_versions[ndx].name, version->name))
|
||||
/* It's not the version we want. */
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
switch (ELFW(ST_BIND) (sym->st_info))
|
||||
{
|
||||
case STB_GLOBAL:
|
||||
@@ -129,6 +177,12 @@ do_lookup (const char *undef_name, unsigned long int hash,
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* If this current is the one mentioned in the verneed entry it
|
||||
is a bug. */
|
||||
if (version != NULL && version->filename != NULL
|
||||
&& _dl_name_match_p (version->filename, map))
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* We have not found anything until now. */
|
||||
@@ -136,16 +190,13 @@ do_lookup (const char *undef_name, unsigned long int hash,
|
||||
}
|
||||
|
||||
/* Search loaded objects' symbol tables for a definition of the symbol
|
||||
UNDEF_NAME. FLAGS is a set of flags. If DL_LOOKUP_NOEXEC is set,
|
||||
then don't search the executable for a definition; this used for
|
||||
copy relocs. If DL_LOOKUP_NOPLT is set, then a PLT entry cannot
|
||||
satisfy the reference; some different binding must be found. */
|
||||
UNDEF_NAME. */
|
||||
|
||||
ElfW(Addr)
|
||||
_dl_lookup_symbol (const char *undef_name, const ElfW(Sym) **ref,
|
||||
struct link_map *symbol_scope[],
|
||||
const char *reference_name,
|
||||
int flags)
|
||||
int reloc_type)
|
||||
{
|
||||
const unsigned long int hash = _dl_elf_hash (undef_name);
|
||||
struct sym_val current_value = { 0, NULL };
|
||||
@@ -153,22 +204,16 @@ _dl_lookup_symbol (const char *undef_name, const ElfW(Sym) **ref,
|
||||
|
||||
/* Search the relevant loaded objects for a definition. */
|
||||
for (scope = symbol_scope; *scope; ++scope)
|
||||
if (do_lookup (undef_name, hash, ref, ¤t_value,
|
||||
if (do_lookup (undef_name, hash, *ref, ¤t_value,
|
||||
(*scope)->l_searchlist, 0, (*scope)->l_nsearchlist,
|
||||
reference_name, NULL, flags))
|
||||
reference_name, NULL, NULL, reloc_type))
|
||||
break;
|
||||
|
||||
if (current_value.s == NULL &&
|
||||
(*ref == NULL || ELFW(ST_BIND) ((*ref)->st_info) != STB_WEAK))
|
||||
{
|
||||
/* We could find no value for a strong reference. */
|
||||
const char msg[] = "undefined symbol: ";
|
||||
const size_t len = strlen (undef_name);
|
||||
char buf[sizeof msg + len];
|
||||
memcpy (buf, msg, sizeof msg - 1);
|
||||
memcpy (&buf[sizeof msg - 1], undef_name, len + 1);
|
||||
_dl_signal_error (0, reference_name, buf);
|
||||
}
|
||||
/* We could find no value for a strong reference. */
|
||||
_dl_signal_error (0, reference_name,
|
||||
make_string ("undefined symbol: ", undef_name));
|
||||
|
||||
*ref = current_value.s;
|
||||
return current_value.a;
|
||||
@@ -184,8 +229,7 @@ ElfW(Addr)
|
||||
_dl_lookup_symbol_skip (const char *undef_name, const ElfW(Sym) **ref,
|
||||
struct link_map *symbol_scope[],
|
||||
const char *reference_name,
|
||||
struct link_map *skip_map,
|
||||
int flags)
|
||||
struct link_map *skip_map)
|
||||
{
|
||||
const unsigned long int hash = _dl_elf_hash (undef_name);
|
||||
struct sym_val current_value = { 0, NULL };
|
||||
@@ -197,13 +241,95 @@ _dl_lookup_symbol_skip (const char *undef_name, const ElfW(Sym) **ref,
|
||||
for (i = 0; (*scope)->l_dupsearchlist[i] != skip_map; ++i)
|
||||
assert (i < (*scope)->l_ndupsearchlist);
|
||||
|
||||
if (! do_lookup (undef_name, hash, ref, ¤t_value,
|
||||
if (! do_lookup (undef_name, hash, *ref, ¤t_value,
|
||||
(*scope)->l_dupsearchlist, i, (*scope)->l_ndupsearchlist,
|
||||
reference_name, skip_map, flags))
|
||||
reference_name, NULL, skip_map, 0))
|
||||
while (*++scope)
|
||||
if (do_lookup (undef_name, hash, ref, ¤t_value,
|
||||
if (do_lookup (undef_name, hash, *ref, ¤t_value,
|
||||
(*scope)->l_dupsearchlist, 0, (*scope)->l_ndupsearchlist,
|
||||
reference_name, skip_map, flags))
|
||||
reference_name, NULL, skip_map, 0))
|
||||
break;
|
||||
|
||||
*ref = current_value.s;
|
||||
return current_value.a;
|
||||
}
|
||||
|
||||
|
||||
/* This function works like _dl_lookup_symbol but it takes an
|
||||
additional arguement with the version number of the requested
|
||||
symbol.
|
||||
|
||||
XXX We'll see whether we need this separate function. */
|
||||
ElfW(Addr)
|
||||
_dl_lookup_versioned_symbol (const char *undef_name, const ElfW(Sym) **ref,
|
||||
struct link_map *symbol_scope[],
|
||||
const char *reference_name,
|
||||
const struct r_found_version *version,
|
||||
int reloc_type)
|
||||
{
|
||||
const unsigned long int hash = _dl_elf_hash (undef_name);
|
||||
struct sym_val current_value = { 0, NULL };
|
||||
struct link_map **scope;
|
||||
|
||||
/* Search the relevant loaded objects for a definition. */
|
||||
for (scope = symbol_scope; *scope; ++scope)
|
||||
{
|
||||
int res = do_lookup (undef_name, hash, *ref, ¤t_value,
|
||||
(*scope)->l_searchlist, 0, (*scope)->l_nsearchlist,
|
||||
reference_name, version, NULL, reloc_type);
|
||||
if (res > 0)
|
||||
break;
|
||||
|
||||
if (res < 0)
|
||||
/* Oh, oh. The file named in the relocation entry does not
|
||||
contain the needed symbol. */
|
||||
_dl_signal_error (0, *reference_name ? reference_name : NULL,
|
||||
make_string ("symbol ", undef_name, ", version ",
|
||||
version->name,
|
||||
" not defined in file ",
|
||||
version->filename,
|
||||
" with link time reference"));
|
||||
}
|
||||
|
||||
if (current_value.s == NULL &&
|
||||
(*ref == NULL || ELFW(ST_BIND) ((*ref)->st_info) != STB_WEAK))
|
||||
/* We could find no value for a strong reference. */
|
||||
_dl_signal_error (0, reference_name,
|
||||
make_string ("undefined symbol: ", undef_name,
|
||||
", version ", version->name ?: NULL));
|
||||
|
||||
*ref = current_value.s;
|
||||
return current_value.a;
|
||||
}
|
||||
|
||||
|
||||
/* Similar to _dl_lookup_symbol_skip but takes an additional argument
|
||||
with the version we are looking for. */
|
||||
ElfW(Addr)
|
||||
_dl_lookup_versioned_symbol_skip (const char *undef_name,
|
||||
const ElfW(Sym) **ref,
|
||||
struct link_map *symbol_scope[],
|
||||
const char *reference_name,
|
||||
const struct r_found_version *version,
|
||||
struct link_map *skip_map)
|
||||
{
|
||||
const unsigned long int hash = _dl_elf_hash (undef_name);
|
||||
struct sym_val current_value = { 0, NULL };
|
||||
struct link_map **scope;
|
||||
size_t i;
|
||||
|
||||
/* Search the relevant loaded objects for a definition. */
|
||||
scope = symbol_scope;
|
||||
for (i = 0; (*scope)->l_dupsearchlist[i] != skip_map; ++i)
|
||||
assert (i < (*scope)->l_ndupsearchlist);
|
||||
|
||||
if (! do_lookup (undef_name, hash, *ref, ¤t_value,
|
||||
(*scope)->l_dupsearchlist, i, (*scope)->l_ndupsearchlist,
|
||||
reference_name, version, skip_map, 0))
|
||||
while (*++scope)
|
||||
if (do_lookup (undef_name, hash, *ref, ¤t_value,
|
||||
(*scope)->l_dupsearchlist, 0, (*scope)->l_ndupsearchlist,
|
||||
reference_name, version, skip_map, 0))
|
||||
break;
|
||||
|
||||
*ref = current_value.s;
|
||||
|
||||
+12
-1
@@ -1,5 +1,5 @@
|
||||
/* Minimal replacements for basic facilities used in the dynamic linker.
|
||||
Copyright (C) 1995, 1996 Free Software Foundation, Inc.
|
||||
Copyright (C) 1995, 1996, 1997 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
|
||||
@@ -77,6 +77,17 @@ malloc (size_t n)
|
||||
return alloc_last_block;
|
||||
}
|
||||
|
||||
/* We use this function occasionally since the real implementation may
|
||||
be optimized when it can assume the memory it returns already is
|
||||
set to NUL. */
|
||||
void * weak_function
|
||||
calloc (size_t nmemb, size_t size)
|
||||
{
|
||||
size_t total = nmemb * size;
|
||||
void *result = malloc (total);
|
||||
return memset (result, '\0', total);
|
||||
}
|
||||
|
||||
/* This will rarely be called. */
|
||||
void weak_function
|
||||
free (void *ptr)
|
||||
|
||||
+6
-3
@@ -1,5 +1,5 @@
|
||||
/* Storage management for the chain of loaded shared objects.
|
||||
Copyright (C) 1995, 1996 Free Software Foundation, Inc.
|
||||
Copyright (C) 1995, 1996, 1997 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
|
||||
@@ -34,12 +34,15 @@ struct link_map *
|
||||
_dl_new_object (char *realname, const char *libname, int type)
|
||||
{
|
||||
struct link_map *new = malloc (sizeof *new);
|
||||
if (! new)
|
||||
struct libname_list *newname = malloc (sizeof *newname);
|
||||
if (! new || ! newname)
|
||||
return NULL;
|
||||
|
||||
memset (new, 0, sizeof *new);
|
||||
new->l_name = realname;
|
||||
new->l_libname = libname;
|
||||
newname->name = libname;
|
||||
newname->next = NULL;
|
||||
new->l_libname = newname;
|
||||
new->l_type = type;
|
||||
|
||||
if (_dl_loaded == NULL)
|
||||
|
||||
+3
-1
@@ -1,5 +1,5 @@
|
||||
/* Load a shared object at runtime, relocate it, and run its initializer.
|
||||
Copyright (C) 1996 Free Software Foundation, Inc.
|
||||
Copyright (C) 1996, 1997 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
|
||||
@@ -54,6 +54,8 @@ _dl_open (const char *file, int mode)
|
||||
/* Load that object's dependencies. */
|
||||
_dl_map_object_deps (new, NULL, 0, 0);
|
||||
|
||||
/* So far, so good. Now check the versions. */
|
||||
(void) _dl_check_map_versions (new, 0);
|
||||
|
||||
/* Relocate the objects loaded. We do this in reverse order so that copy
|
||||
relocs of earlier objects overwrite the data written by later objects. */
|
||||
|
||||
+7
-4
@@ -1,5 +1,5 @@
|
||||
/* Relocate a shared object and resolve its references to other loaded objects.
|
||||
Copyright (C) 1995, 1996 Free Software Foundation, Inc.
|
||||
Copyright (C) 1995, 1996, 1997 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
|
||||
@@ -57,9 +57,12 @@ _dl_relocate_object (struct link_map *l, struct link_map *scope[], int lazy)
|
||||
= ((void *) l->l_addr + l->l_info[DT_STRTAB]->d_un.d_ptr);
|
||||
|
||||
/* This macro is used as a callback from the ELF_DYNAMIC_RELOCATE code. */
|
||||
#define RESOLVE(ref, flags) \
|
||||
(_dl_lookup_symbol (strtab + (*ref)->st_name, ref, scope, \
|
||||
l->l_name, flags))
|
||||
#define RESOLVE(ref, version, flags) \
|
||||
((version) != NULL && (version)->hash != 0 \
|
||||
? _dl_lookup_versioned_symbol (strtab + (*ref)->st_name, (ref), scope, \
|
||||
l->l_name, (version), (flags)) \
|
||||
: _dl_lookup_symbol (strtab + (*ref)->st_name, (ref), scope, \
|
||||
l->l_name, (flags)))
|
||||
|
||||
#include "dynamic-link.h"
|
||||
ELF_DYNAMIC_RELOCATE (l, lazy);
|
||||
|
||||
+31
-8
@@ -1,5 +1,5 @@
|
||||
/* On-demand PLT fixup for shared objects.
|
||||
Copyright (C) 1995, 1996 Free Software Foundation, Inc.
|
||||
Copyright (C) 1995, 1996, 1997 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
|
||||
@@ -74,15 +74,19 @@ _dl_object_relocation_scope (struct link_map *l)
|
||||
#define elf_machine_rel 1
|
||||
#define elf_machine_rela 2
|
||||
#if elf_machine_relplt == elf_machine_rel
|
||||
#define PLTREL ElfW(Rel)
|
||||
# define PLTREL ElfW(Rel)
|
||||
#elif elf_machine_relplt == elf_machine_rela
|
||||
#define PLTREL ElfW(Rela)
|
||||
# define PLTREL ElfW(Rela)
|
||||
#else
|
||||
#error "dl-machine.h bug: elf_machine_relplt not rel or rela"
|
||||
# error "dl-machine.h bug: elf_machine_relplt not rel or rela"
|
||||
#endif
|
||||
#undef elf_machine_rel
|
||||
#undef elf_machine_rela
|
||||
|
||||
#ifndef VERSYMIDX
|
||||
# define VERSYMIDX(sym) (DT_NUM + DT_PROCNUM + DT_VERSIONTAGIDX (sym))
|
||||
#endif
|
||||
|
||||
/* We need to define the function as a local symbol so that the reference
|
||||
in the trampoline code will be a local PC-relative call. Tell the
|
||||
compiler not to worry that the function appears not to be called. */
|
||||
@@ -122,19 +126,38 @@ fixup (
|
||||
|
||||
{
|
||||
/* This macro is used as a callback from the elf_machine_relplt code. */
|
||||
#define RESOLVE(ref, flags) \
|
||||
(_dl_lookup_symbol (strtab + (*ref)->st_name, ref, scope, \
|
||||
l->l_name, flags))
|
||||
#define RESOLVE(ref, version, flags) \
|
||||
((version) != NULL && (version)->hash != 0 \
|
||||
? _dl_lookup_versioned_symbol (strtab + (*ref)->st_name, (ref), scope, \
|
||||
l->l_name, (version), (flags)) \
|
||||
: _dl_lookup_symbol (strtab + (*ref)->st_name, (ref), scope, \
|
||||
l->l_name, (flags)))
|
||||
#include "dynamic-link.h"
|
||||
|
||||
/* Perform the specified relocation. */
|
||||
elf_machine_relplt (l, reloc, &symtab[ELFW(R_SYM) (reloc->r_info)]);
|
||||
if (l->l_info[VERSYMIDX (DT_VERNEEDNUM)])
|
||||
{
|
||||
const ElfW(Half) * version =
|
||||
(const ElfW(Half) *) (l->l_addr +
|
||||
l->l_info[VERSYMIDX (DT_VERSYM)]->d_un.d_ptr);
|
||||
ElfW(Half) ndx = version[ELFW(R_SYM) (reloc->r_info)];
|
||||
|
||||
elf_machine_relplt (l, reloc, &symtab[ELFW(R_SYM) (reloc->r_info)],
|
||||
&l->l_versions[ndx]);
|
||||
}
|
||||
else
|
||||
elf_machine_relplt (l, reloc, &symtab[ELFW(R_SYM) (reloc->r_info)],
|
||||
NULL);
|
||||
}
|
||||
|
||||
*_dl_global_scope_end = NULL;
|
||||
|
||||
/* Return the address that was written by the relocation. */
|
||||
#ifdef ELF_FIXUP_RETURNS_ADDRESS
|
||||
return (ElfW(Addr))(l->l_addr + reloc->r_offset);
|
||||
#else
|
||||
return *(ElfW(Addr) *) (l->l_addr + reloc->r_offset);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
|
||||
+2
-2
@@ -1,5 +1,5 @@
|
||||
/* Support for dynamic linking code in static libc.
|
||||
Copyright (C) 1996 Free Software Foundation, Inc.
|
||||
Copyright (C) 1996, 1997 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
|
||||
@@ -62,7 +62,7 @@ _dl_sysdep_read_whole_file (const char *file, size_t *sizep, int prot)
|
||||
int fd = __open (file, O_RDONLY);
|
||||
if (fd < 0)
|
||||
return NULL;
|
||||
if (__fstat (fd, &st) < 0)
|
||||
if (__fxstat (_STAT_VER, fd, &st) < 0)
|
||||
result = NULL;
|
||||
else
|
||||
{
|
||||
|
||||
@@ -0,0 +1,338 @@
|
||||
/* Handle symbol and library versioning.
|
||||
Copyright (C) 1997 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997.
|
||||
|
||||
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 <elf.h>
|
||||
#include <errno.h>
|
||||
#include <link.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <assert.h>
|
||||
|
||||
#include "../stdio-common/_itoa.h"
|
||||
|
||||
|
||||
/* Set in rtld.c at startup. */
|
||||
extern char **_dl_argv;
|
||||
|
||||
#define VERSTAG(tag) (DT_NUM + DT_PROCNUM + DT_VERSIONTAGIDX (tag))
|
||||
|
||||
|
||||
#define make_string(string, rest...) \
|
||||
({ \
|
||||
const char *all[] = { string, ## rest }; \
|
||||
size_t len, cnt; \
|
||||
char *result, *cp; \
|
||||
\
|
||||
len = 1; \
|
||||
for (cnt = 0; cnt < sizeof (all) / sizeof (all[0]); ++cnt) \
|
||||
len += strlen (all[cnt]); \
|
||||
\
|
||||
cp = result = alloca (len); \
|
||||
for (cnt = 0; cnt < sizeof (all) / sizeof (all[0]); ++cnt) \
|
||||
cp = stpcpy (cp, all[cnt]); \
|
||||
\
|
||||
result; \
|
||||
})
|
||||
|
||||
|
||||
static inline struct link_map *
|
||||
find_needed (struct link_map *map, const char *name)
|
||||
{
|
||||
unsigned int n;
|
||||
|
||||
for (n = 0; n < map->l_nsearchlist; ++n)
|
||||
if (_dl_name_match_p (name, map->l_searchlist[n]))
|
||||
return map->l_searchlist[n];
|
||||
|
||||
/* Should never happen. */
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
match_symbol (const char *name, ElfW(Word) hash, const char *string,
|
||||
struct link_map *map, int verbose, int weak)
|
||||
{
|
||||
const char *strtab = (const char *) (map->l_addr
|
||||
+ map->l_info[DT_STRTAB]->d_un.d_ptr);
|
||||
ElfW(Addr) def_offset = map->l_info[VERSTAG (DT_VERDEF)]->d_un.d_ptr;
|
||||
ElfW(Verdef) *def;
|
||||
|
||||
if (def_offset == 0)
|
||||
{
|
||||
/* The file has no symbol versioning. I.e., the dependent
|
||||
object was linked against another version of this file. We
|
||||
only print a message if verbose output is requested. */
|
||||
if (verbose)
|
||||
_dl_signal_error (0, map->l_name, make_string ("\
|
||||
no version information available (required by ",
|
||||
name, ")"));
|
||||
return 0;
|
||||
}
|
||||
|
||||
def = (ElfW(Verdef) *) (map->l_addr + def_offset);
|
||||
while (1)
|
||||
{
|
||||
/* Currently the version number of the definition entry is 1.
|
||||
Make sure all we see is this version. */
|
||||
if (def->vd_version != 1)
|
||||
{
|
||||
char buf[20];
|
||||
buf[sizeof (buf) - 1] = '\0';
|
||||
_dl_signal_error (0, map->l_name,
|
||||
make_string ("unsupported version ",
|
||||
_itoa_word (def->vd_version,
|
||||
&buf[sizeof (buf) - 1],
|
||||
10, 0),
|
||||
" of Verdef record"));
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Compare the hash values. */
|
||||
if (hash == def->vd_hash)
|
||||
{
|
||||
ElfW(Verdaux) *aux = (ElfW(Verdaux) *) ((char *) def + def->vd_aux);
|
||||
|
||||
/* To be safe, compare the string as well. */
|
||||
if (strcmp (string, strtab + aux->vda_name) == 0)
|
||||
/* Bingo! */
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* If no more definitions we failed to find what we want. */
|
||||
if (def->vd_next == 0)
|
||||
break;
|
||||
|
||||
/* Next definition. */
|
||||
def = (ElfW(Verdef) *) ((char *) def + def->vd_next);
|
||||
}
|
||||
|
||||
/* Symbol not found. If it was a weak reference it is not fatal. */
|
||||
if (weak)
|
||||
{
|
||||
if (verbose)
|
||||
_dl_signal_error (0, map->l_name,
|
||||
make_string ("weak version `", string,
|
||||
"' not found (required by ", name,
|
||||
")"));
|
||||
return 0;
|
||||
}
|
||||
|
||||
_dl_signal_error (0, map->l_name,
|
||||
make_string ("version `", string,
|
||||
"' not found (required by ", name, ")"));
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
_dl_check_map_versions (struct link_map *map, int verbose)
|
||||
{
|
||||
int result = 0;
|
||||
const char *strtab = (const char *) (map->l_addr
|
||||
+ map->l_info[DT_STRTAB]->d_un.d_ptr);
|
||||
/* Pointer to section with needed versions. */
|
||||
ElfW(Dyn) *dyn = map->l_info[VERSTAG (DT_VERNEED)];
|
||||
/* Pointer to dynamic section with definitions. */
|
||||
ElfW(Dyn) *def = map->l_info[VERSTAG (DT_VERDEF)];
|
||||
/* We need to find out which is the highest version index used
|
||||
in a dependecy. */
|
||||
unsigned int ndx_high = 0;
|
||||
|
||||
if (dyn != NULL)
|
||||
{
|
||||
/* This file requires special versions from its dependencies. */
|
||||
ElfW(Verneed) *ent = (ElfW(Verneed) *) (map->l_addr + dyn->d_un.d_ptr);
|
||||
|
||||
/* Currently the version number of the needed entry is 1.
|
||||
Make sure all we see is this version. */
|
||||
if (ent->vn_version != 1)
|
||||
{
|
||||
char buf[20];
|
||||
buf[sizeof (buf) - 1] = '\0';
|
||||
_dl_signal_error (0, (*map->l_name ? map->l_name : _dl_argv[0]),
|
||||
make_string ("unsupported version ",
|
||||
_itoa_word (ent->vn_version,
|
||||
&buf[sizeof (buf) - 1],
|
||||
10, 0),
|
||||
" of Verneed record\n"));
|
||||
return 1;
|
||||
}
|
||||
|
||||
while (1)
|
||||
{
|
||||
ElfW(Vernaux) *aux;
|
||||
struct link_map *needed = find_needed (map, strtab + ent->vn_file);
|
||||
|
||||
/* If NEEDED is NULL this means a dependency was not found
|
||||
and no stub entry was created. This should never happen. */
|
||||
assert (needed != NULL);
|
||||
|
||||
/* NEEDED is the map for the file we need. Now look for the
|
||||
dependency symbols. */
|
||||
aux = (ElfW(Vernaux) *) ((char *) ent + ent->vn_aux);
|
||||
while (1)
|
||||
{
|
||||
/* Match the symbol. */
|
||||
result |= match_symbol ((*map->l_name
|
||||
? map->l_name : _dl_argv[0]),
|
||||
aux->vna_hash,
|
||||
strtab + aux->vna_name,
|
||||
needed, verbose,
|
||||
aux->vna_flags & VER_FLG_WEAK);
|
||||
|
||||
/* Compare the version index. */
|
||||
if ((unsigned int) (aux->vna_other & 0x7fff) > ndx_high)
|
||||
ndx_high = aux->vna_other & 0x7fff;
|
||||
|
||||
if (aux->vna_next == 0)
|
||||
/* No more symbols. */
|
||||
break;
|
||||
|
||||
/* Next symbol. */
|
||||
aux = (ElfW(Vernaux) *) ((char *) aux + aux->vna_next);
|
||||
}
|
||||
|
||||
if (ent->vn_next == 0)
|
||||
/* No more dependencies. */
|
||||
break;
|
||||
|
||||
/* Next dependency. */
|
||||
ent = (ElfW(Verneed) *) ((char *) ent + ent->vn_next);
|
||||
}
|
||||
}
|
||||
|
||||
/* We also must store the names of the defined versions. Determine
|
||||
the maximum index here as well.
|
||||
|
||||
XXX We could avoid the loop by just taking the number of definitions
|
||||
as an upper bound of new indeces. */
|
||||
if (def != NULL)
|
||||
{
|
||||
ElfW(Verdef) *ent;
|
||||
ent = (ElfW(Verdef) *) (map->l_addr + def->d_un.d_ptr);
|
||||
while (1)
|
||||
{
|
||||
if ((unsigned int) (ent->vd_ndx & 0x7fff) > ndx_high)
|
||||
ndx_high = ent->vd_ndx & 0x7fff;
|
||||
|
||||
if (ent->vd_next == 0)
|
||||
/* No more definitions. */
|
||||
break;
|
||||
|
||||
ent = (ElfW(Verdef) *) ((char *) ent + ent->vd_next);
|
||||
}
|
||||
}
|
||||
|
||||
if (ndx_high > 0)
|
||||
{
|
||||
/* Now we are ready to build the array with the version names
|
||||
which can be indexed by the version index in the VERSYM
|
||||
section. */
|
||||
map->l_versions = (struct r_found_version *)
|
||||
calloc (ndx_high + 1, sizeof (*map->l_versions));
|
||||
if (map->l_versions == NULL)
|
||||
{
|
||||
_dl_signal_error (ENOMEM, (*map->l_name ? map->l_name : _dl_argv[0]),
|
||||
"cannot allocate version reference table");
|
||||
result = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Store the number of available symbols. */
|
||||
map->l_nversions = ndx_high + 1;
|
||||
|
||||
if (dyn != NULL)
|
||||
{
|
||||
ElfW(Verneed) *ent;
|
||||
ent = (ElfW(Verneed) *) (map->l_addr + dyn->d_un.d_ptr);
|
||||
while (1)
|
||||
{
|
||||
ElfW(Vernaux) *aux;
|
||||
aux = (ElfW(Vernaux) *) ((char *) ent + ent->vn_aux);
|
||||
while (1)
|
||||
{
|
||||
ElfW(Half) ndx = aux->vna_other & 0x7fff;
|
||||
map->l_versions[ndx].hash = aux->vna_hash;
|
||||
map->l_versions[ndx].name = &strtab[aux->vna_name];
|
||||
map->l_versions[ndx].filename = &strtab[ent->vn_file];
|
||||
|
||||
if (aux->vna_next == 0)
|
||||
/* No more symbols. */
|
||||
break;
|
||||
|
||||
/* Advance to next symbol. */
|
||||
aux = (ElfW(Vernaux) *) ((char *) aux + aux->vna_next);
|
||||
}
|
||||
|
||||
if (ent->vn_next == 0)
|
||||
/* No more dependencies. */
|
||||
break;
|
||||
|
||||
/* Advance to next dependency. */
|
||||
ent = (ElfW(Verneed) *) ((char *) ent + ent->vn_next);
|
||||
}
|
||||
}
|
||||
|
||||
/* And insert the defined versions. */
|
||||
if (def != NULL)
|
||||
{
|
||||
ElfW(Verdef) *ent;
|
||||
ent = (ElfW(Verdef) *) (map->l_addr + def->d_un.d_ptr);
|
||||
while (1)
|
||||
{
|
||||
ElfW(Verdaux) *aux;
|
||||
aux = (ElfW(Verdaux) *) ((char *) ent + ent->vd_aux);
|
||||
|
||||
if ((ent->vd_flags & VER_FLG_BASE) == 0)
|
||||
{
|
||||
/* The name of the base version should not be
|
||||
available for matching a versioned symbol. */
|
||||
ElfW(Half) ndx = ent->vd_ndx & 0x7fff;
|
||||
map->l_versions[ndx].hash = ent->vd_hash;
|
||||
map->l_versions[ndx].name = &strtab[aux->vda_name];
|
||||
map->l_versions[ndx].filename = NULL;
|
||||
}
|
||||
|
||||
if (ent->vd_next == 0)
|
||||
/* No more definitions. */
|
||||
break;
|
||||
|
||||
ent = (ElfW(Verdef) *) ((char *) ent + ent->vd_next);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
_dl_check_all_versions (struct link_map *map, int verbose)
|
||||
{
|
||||
struct link_map *l;
|
||||
int result = 0;
|
||||
|
||||
for (l = map; l != NULL; l = l->l_next)
|
||||
result |= l->l_opencount != 0 && _dl_check_map_versions (l, verbose);
|
||||
|
||||
return result;
|
||||
}
|
||||
+7
-6
@@ -20,13 +20,14 @@
|
||||
#include <link.h>
|
||||
#include <dlfcn.h>
|
||||
|
||||
static void
|
||||
dlclose_doit (void *handle)
|
||||
{
|
||||
_dl_close (handle);
|
||||
}
|
||||
|
||||
int
|
||||
dlclose (void *handle)
|
||||
{
|
||||
void doit (void)
|
||||
{
|
||||
_dl_close (handle);
|
||||
}
|
||||
|
||||
return _dlerror_run (doit) ? -1 : 0;
|
||||
return _dlerror_run (dlclose_doit, handle) ? -1 : 0;
|
||||
}
|
||||
|
||||
+4
-4
@@ -1,5 +1,5 @@
|
||||
/* dlerror -- Return error detail for failing <dlfcn.h> functions.
|
||||
Copyright (C) 1995, 1996 Free Software Foundation, Inc.
|
||||
/* Return error detail for failing <dlfcn.h> functions.
|
||||
Copyright (C) 1995, 1996, 1997 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
|
||||
@@ -64,7 +64,7 @@ dlerror (void)
|
||||
}
|
||||
|
||||
int
|
||||
_dlerror_run (void (*operate) (void))
|
||||
_dlerror_run (void (*operate) (void *), void *args)
|
||||
{
|
||||
if (last_errstring != NULL)
|
||||
/* Free the error string from the last failed command. This can
|
||||
@@ -72,6 +72,6 @@ _dlerror_run (void (*operate) (void))
|
||||
free (last_errstring);
|
||||
|
||||
last_errcode = _dl_catch_error (&last_errstring, &last_object_name,
|
||||
operate);
|
||||
operate, args);
|
||||
return last_errstring != NULL;
|
||||
}
|
||||
|
||||
+11
-2
@@ -1,5 +1,5 @@
|
||||
/* dlfcn.h -- User functions for run-time dynamic loading.
|
||||
Copyright (C) 1995, 1996 Free Software Foundation, Inc.
|
||||
/* User functions for run-time dynamic loading.
|
||||
Copyright (C) 1995, 1996, 1997 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
|
||||
@@ -52,6 +52,15 @@ extern int dlclose __P ((void *__handle));
|
||||
of the symbol called NAME. */
|
||||
extern void *dlsym __P ((void *__handle, __const char *__name));
|
||||
|
||||
#ifdef __USE_GNU
|
||||
/* Find the run-time address in the shared object HANDLE refers to
|
||||
of the symbol called NAME with VERSION. */
|
||||
extern void *__dlvsym __P ((void *__handle, __const char *__name,
|
||||
__const char *__version));
|
||||
extern void *dlvsym __P ((void *__handle, __const char *__name,
|
||||
__const char *__version));
|
||||
#endif
|
||||
|
||||
/* When any of the above functions fails, call this function
|
||||
to return a string describing the error. Each call resets
|
||||
the error string so that a following call returns null. */
|
||||
|
||||
+25
-9
@@ -1,5 +1,5 @@
|
||||
/* dlopen -- Load a shared object at run time.
|
||||
Copyright (C) 1995, 1996 Free Software Foundation, Inc.
|
||||
/* Load a shared object at run time.
|
||||
Copyright (C) 1995, 1996, 1997 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
|
||||
@@ -21,15 +21,31 @@
|
||||
#include <link.h>
|
||||
#include <dlfcn.h>
|
||||
|
||||
struct dlopen_args
|
||||
{
|
||||
/* The arguments for dlopen_doit. */
|
||||
const char *file;
|
||||
int mode;
|
||||
/* The return value of dlopen_doit. */
|
||||
struct link_map *new;
|
||||
};
|
||||
|
||||
|
||||
static void
|
||||
dlopen_doit (void *a)
|
||||
{
|
||||
struct dlopen_args *args = (struct dlopen_args *) a;
|
||||
|
||||
args->new = _dl_open (args->file ?: "", args->mode);
|
||||
}
|
||||
|
||||
|
||||
void *
|
||||
dlopen (const char *file, int mode)
|
||||
{
|
||||
struct link_map *new;
|
||||
struct dlopen_args args;
|
||||
args.file = file;
|
||||
args.mode = mode;
|
||||
|
||||
void doit (void)
|
||||
{
|
||||
new = _dl_open (file ?: "", mode);
|
||||
}
|
||||
|
||||
return _dlerror_run (doit) ? NULL : new;
|
||||
return _dlerror_run (dlopen_doit, &args) ? NULL : args.new;
|
||||
}
|
||||
|
||||
+64
-41
@@ -1,5 +1,5 @@
|
||||
/* dlsym -- Look up a symbol in a shared object loaded by `dlopen'.
|
||||
Copyright (C) 1995, 1996 Free Software Foundation, Inc.
|
||||
/* Look up a symbol in a shared object loaded by `dlopen'.
|
||||
Copyright (C) 1995, 1996, 1997 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,48 +22,71 @@
|
||||
#include <dlfcn.h>
|
||||
#include <setjmp.h>
|
||||
|
||||
struct dlsym_args
|
||||
{
|
||||
/* The arguments to dlsym_doit. */
|
||||
void *handle;
|
||||
const char *name;
|
||||
struct r_found_version version;
|
||||
ElfW(Addr) caller;
|
||||
/* The return values of dlsym_doit. */
|
||||
ElfW(Addr) loadbase;
|
||||
const ElfW(Sym) *ref;
|
||||
};
|
||||
|
||||
|
||||
static void
|
||||
dlsym_doit (void *a)
|
||||
{
|
||||
struct dlsym_args *args = (struct dlsym_args *) a;
|
||||
args->ref = NULL;
|
||||
|
||||
if (args->handle == NULL)
|
||||
/* Search the global scope. */
|
||||
args->loadbase = _dl_lookup_symbol (args->name, &args->ref,
|
||||
&(_dl_global_scope
|
||||
?: _dl_default_scope)[2],
|
||||
NULL, 0);
|
||||
else if (args->handle == RTLD_NEXT)
|
||||
{
|
||||
struct link_map *l, *match;
|
||||
|
||||
/* Find the highest-addressed object that CALLER is not below. */
|
||||
match = NULL;
|
||||
for (l = _dl_loaded; l; l = l->l_next)
|
||||
if (args->caller >= l->l_addr && (!match || match->l_addr < l->l_addr))
|
||||
match = l;
|
||||
|
||||
if (! match)
|
||||
_dl_signal_error (0, NULL, _("\
|
||||
RTLD_NEXT used in code not dynamically loaded"));
|
||||
|
||||
l = match;
|
||||
while (l->l_loader)
|
||||
l = l->l_loader;
|
||||
|
||||
args->loadbase = _dl_lookup_symbol_skip (args->name, &args->ref,
|
||||
&_dl_loaded, NULL, l);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Search the scope of the given object. */
|
||||
struct link_map *map = args->handle;
|
||||
struct link_map *mapscope[2] = { map, NULL };
|
||||
args->loadbase = _dl_lookup_symbol (args->name, &args->ref, mapscope,
|
||||
map->l_name, 0);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void *
|
||||
dlsym (void *handle, const char *name)
|
||||
{
|
||||
ElfW(Addr) caller = (ElfW(Addr)) __builtin_return_address (0);
|
||||
ElfW(Addr) loadbase;
|
||||
const ElfW(Sym) *ref = NULL;
|
||||
void doit (void)
|
||||
{
|
||||
if (handle == NULL)
|
||||
/* Search the global scope. */
|
||||
loadbase = _dl_lookup_symbol
|
||||
(name, &ref, &(_dl_global_scope ?: _dl_default_scope)[2], NULL, 0);
|
||||
else if (handle == RTLD_NEXT)
|
||||
{
|
||||
struct link_map *l, *match;
|
||||
struct dlsym_args args;
|
||||
args.caller = (ElfW(Addr)) __builtin_return_address (0);
|
||||
args.handle = handle;
|
||||
args.name = name;
|
||||
|
||||
/* Find the highest-addressed object that CALLER is not below. */
|
||||
match = NULL;
|
||||
for (l = _dl_loaded; l; l = l->l_next)
|
||||
if (caller >= l->l_addr && (!match || match->l_addr < l->l_addr))
|
||||
match = l;
|
||||
|
||||
if (! match)
|
||||
_dl_signal_error (0, NULL, _("\
|
||||
RTLD_NEXT used in code not dynamically loaded"));
|
||||
|
||||
l = match;
|
||||
while (l->l_loader)
|
||||
l = l->l_loader;
|
||||
|
||||
loadbase = _dl_lookup_symbol_skip
|
||||
(name, &ref, &_dl_loaded, NULL, l, 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Search the scope of the given object. */
|
||||
struct link_map *map = handle;
|
||||
struct link_map *mapscope[2] = { map, NULL };
|
||||
loadbase = _dl_lookup_symbol (name, &ref, mapscope, map->l_name, 0);
|
||||
}
|
||||
}
|
||||
|
||||
return _dlerror_run (doit) ? NULL : (void *) (loadbase + ref->st_value);
|
||||
return (_dlerror_run (dlsym_doit, &args)
|
||||
? NULL : (void *) (args.loadbase + args.ref->st_value));
|
||||
}
|
||||
|
||||
+105
@@ -0,0 +1,105 @@
|
||||
/* Look up a versioned symbol in a shared object loaded by `dlopen'.
|
||||
Copyright (C) 1995, 1996, 1997 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 <stddef.h>
|
||||
#include <link.h>
|
||||
#include <dlfcn.h>
|
||||
#include <setjmp.h>
|
||||
|
||||
#include <dl-hash.h>
|
||||
|
||||
struct dlvsym_args
|
||||
{
|
||||
/* The arguments to dlvsym_doit. */
|
||||
void *handle;
|
||||
const char *name;
|
||||
struct r_found_version version;
|
||||
ElfW(Addr) caller;
|
||||
/* The return values of dlvsym_doit. */
|
||||
ElfW(Addr) loadbase;
|
||||
const ElfW(Sym) *ref;
|
||||
};
|
||||
|
||||
|
||||
static void
|
||||
dlvsym_doit (void *a)
|
||||
{
|
||||
struct dlvsym_args *args = (struct dlvsym_args *)a;
|
||||
args->ref = NULL;
|
||||
|
||||
if (args->handle == NULL)
|
||||
/* Search the global scope. */
|
||||
args->loadbase = _dl_lookup_versioned_symbol (args->name, &args->ref,
|
||||
&(_dl_global_scope
|
||||
?: _dl_default_scope)[2],
|
||||
NULL, &args->version, 0);
|
||||
else if (args->handle == RTLD_NEXT)
|
||||
{
|
||||
struct link_map *l, *match;
|
||||
|
||||
/* Find the highest-addressed object that CALLER is not below. */
|
||||
match = NULL;
|
||||
for (l = _dl_loaded; l; l = l->l_next)
|
||||
if (args->caller >= l->l_addr && (!match || match->l_addr < l->l_addr))
|
||||
match = l;
|
||||
|
||||
if (! match)
|
||||
_dl_signal_error (0, NULL, _("\
|
||||
RTLD_NEXT used in code not dynamically loaded"));
|
||||
|
||||
l = match;
|
||||
while (l->l_loader)
|
||||
l = l->l_loader;
|
||||
|
||||
args->loadbase = _dl_lookup_versioned_symbol_skip (args->name,
|
||||
&args->ref,
|
||||
&_dl_loaded,
|
||||
NULL, &args->version,
|
||||
l);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Search the scope of the given object. */
|
||||
struct link_map *map = args->handle;
|
||||
struct link_map *mapscope[2] = { map, NULL };
|
||||
args->loadbase = _dl_lookup_versioned_symbol (args->name, &args->ref,
|
||||
mapscope, map->l_name,
|
||||
&args->version, 0);
|
||||
}
|
||||
}
|
||||
|
||||
void *
|
||||
__dlvsym (void *handle, const char *name, const char *version_str)
|
||||
{
|
||||
struct dlvsym_args args;
|
||||
|
||||
args.handle = handle;
|
||||
args.name = name;
|
||||
args.caller = (ElfW(Addr)) __builtin_return_address (0);
|
||||
|
||||
/* Compute hash value to the version string. */
|
||||
args.version.name = version_str;
|
||||
args.version.hash = _dl_elf_hash (version_str);
|
||||
/* We don't have a specific file where the symbol can be found. */
|
||||
args.version.filename = NULL;
|
||||
|
||||
return (_dlerror_run (dlvsym_doit, &args)
|
||||
? NULL : (void *) (args.loadbase + args.ref->st_value));
|
||||
}
|
||||
weak_alias (__dlvsym, dlvsym)
|
||||
+28
-8
@@ -1,5 +1,5 @@
|
||||
/* Do relocations for ELF dynamic linking.
|
||||
Copyright (C) 1995, 1996 Free Software Foundation, Inc.
|
||||
Copyright (C) 1995, 1996, 1997 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
|
||||
@@ -21,11 +21,14 @@
|
||||
`elf_dynamic_do_rel' and `elf_dynamic_do_rela'. */
|
||||
|
||||
#ifdef DO_RELA
|
||||
#define elf_dynamic_do_rel elf_dynamic_do_rela
|
||||
#define Rel Rela
|
||||
#define elf_machine_rel elf_machine_rela
|
||||
# define elf_dynamic_do_rel elf_dynamic_do_rela
|
||||
# define Rel Rela
|
||||
# define elf_machine_rel elf_machine_rela
|
||||
#endif
|
||||
|
||||
#ifndef VERSYMIDX
|
||||
# define VERSYMIDX(sym) (DT_NUM + DT_PROCNUM + DT_VERSIONTAGIDX (sym))
|
||||
#endif
|
||||
|
||||
/* Perform the relocations in MAP on the running program image as specified
|
||||
by RELTAG, SZTAG. If LAZY is nonzero, this is the first pass on PLT
|
||||
@@ -37,8 +40,6 @@ elf_dynamic_do_rel (struct link_map *map,
|
||||
int reltag, int sztag,
|
||||
int lazy)
|
||||
{
|
||||
const ElfW(Sym) *const symtab
|
||||
= (const ElfW(Sym) *) (map->l_addr + map->l_info[DT_SYMTAB]->d_un.d_ptr);
|
||||
const ElfW(Rel) *r
|
||||
= (const ElfW(Rel) *) (map->l_addr + map->l_info[reltag]->d_un.d_ptr);
|
||||
const ElfW(Rel) *end = &r[map->l_info[sztag]->d_un.d_val / sizeof *r];
|
||||
@@ -48,8 +49,27 @@ elf_dynamic_do_rel (struct link_map *map,
|
||||
for (; r < end; ++r)
|
||||
elf_machine_lazy_rel (map, r);
|
||||
else
|
||||
for (; r < end; ++r)
|
||||
elf_machine_rel (map, r, &symtab[ELFW(R_SYM) (r->r_info)]);
|
||||
{
|
||||
const ElfW(Sym) *const symtab =
|
||||
(const ElfW(Sym) *) (map->l_addr + map->l_info[DT_SYMTAB]->d_un.d_ptr);
|
||||
|
||||
if (map->l_info[VERSYMIDX (DT_VERNEEDNUM)])
|
||||
{
|
||||
const ElfW(Half) *const version =
|
||||
(const ElfW(Half) *) (map->l_addr
|
||||
+ map->l_info[VERSYMIDX (DT_VERSYM)]->d_un.d_ptr);
|
||||
|
||||
for (; r < end; ++r)
|
||||
{
|
||||
ElfW(Half) ndx = version[ELFW(R_SYM) (r->r_info)];
|
||||
elf_machine_rel (map, r, &symtab[ELFW(R_SYM) (r->r_info)],
|
||||
&map->l_versions[ndx]);
|
||||
}
|
||||
}
|
||||
else
|
||||
for (; r < end; ++r)
|
||||
elf_machine_rel (map, r, &symtab[ELFW(R_SYM) (r->r_info)], NULL);
|
||||
}
|
||||
}
|
||||
|
||||
#undef elf_dynamic_do_rel
|
||||
|
||||
@@ -504,6 +504,20 @@ typedef struct
|
||||
entry */
|
||||
} Elf32_Verdef;
|
||||
|
||||
/* XXX We have no information what types should be used for 64 bit
|
||||
architectures. What is following is only an intelligent guess. */
|
||||
typedef struct
|
||||
{
|
||||
Elf64_Half vd_version; /* Version revision */
|
||||
Elf64_Half vd_flags; /* Version information */
|
||||
Elf64_Half vd_ndx; /* Version Index */
|
||||
Elf64_Half vd_cnt; /* Number of associated aux entries */
|
||||
Elf64_Word vd_hash; /* Version name hash value */
|
||||
Elf64_Word vd_aux; /* Offset in bytes to verdaux array */
|
||||
Elf64_Word vd_next; /* Offset in bytes to next verdef
|
||||
entry */
|
||||
} Elf64_Verdef;
|
||||
|
||||
/* Legal values for vd_version (version revision). */
|
||||
#define VER_DEF_NONE 0 /* No version */
|
||||
#define VER_DEF_CURRENT 1 /* Current version */
|
||||
@@ -522,6 +536,15 @@ typedef struct
|
||||
entry */
|
||||
} Elf32_Verdaux;
|
||||
|
||||
/* XXX We have no information what types should be used for 64 bit
|
||||
architectures. What is following is only an intelligent guess. */
|
||||
typedef struct
|
||||
{
|
||||
Elf64_Addr vda_name; /* Version or dependency names */
|
||||
Elf64_Word vda_next; /* Offset in bytes to next verdaux
|
||||
entry */
|
||||
} Elf64_Verdaux;
|
||||
|
||||
/* Version dependency section. */
|
||||
|
||||
typedef struct
|
||||
@@ -535,6 +558,19 @@ typedef struct
|
||||
entry */
|
||||
} Elf32_Verneed;
|
||||
|
||||
/* XXX We have no information what types should be used for 64 bit
|
||||
architectures. What is following is only an intelligent guess. */
|
||||
typedef struct
|
||||
{
|
||||
Elf64_Half vn_version; /* Version of structure */
|
||||
Elf64_Half vn_cnt; /* Number of associated aux entries */
|
||||
Elf64_Addr vn_file; /* Offset of filename for this
|
||||
dependency */
|
||||
Elf64_Word vn_aux; /* Offset in bytes to vernaux array */
|
||||
Elf64_Word vn_next; /* Offset in bytes to next verneed
|
||||
entry */
|
||||
} Elf64_Verneed;
|
||||
|
||||
/* Legal values for vn_version (version revision). */
|
||||
#define VER_NEED_NONE 0 /* No version */
|
||||
#define VER_NEED_CURRENT 1 /* Current version */
|
||||
@@ -552,6 +588,18 @@ typedef struct
|
||||
entry */
|
||||
} Elf32_Vernaux;
|
||||
|
||||
/* XXX We have no information what types should be used for 64 bit
|
||||
architectures. What is following is only an intelligent guess. */
|
||||
typedef struct
|
||||
{
|
||||
Elf64_Word vna_hash; /* Hash value of dependency name */
|
||||
Elf64_Half vna_flags; /* Dependency specific information */
|
||||
Elf64_Half vna_other; /* Unused */
|
||||
Elf64_Addr vna_name; /* Dependency name string offset */
|
||||
Elf64_Word vna_next; /* Offset in bytes to next vernaux
|
||||
entry */
|
||||
} Elf64_Vernaux;
|
||||
|
||||
/* Legal values for vna_flags. */
|
||||
#define VER_FLG_WEAK 0x2 /* Weak verison identifier */
|
||||
|
||||
@@ -867,6 +915,71 @@ typedef Elf32_Addr Elf32_Conflict;
|
||||
#define R_ALPHA_JMP_SLOT 26 /* Create PLT entry */
|
||||
#define R_ALPHA_RELATIVE 27 /* Adjust by program base */
|
||||
|
||||
|
||||
/* PowerPC specific declarations */
|
||||
|
||||
/* PowerPC relocations defined by the ABIs */
|
||||
#define R_PPC_NONE 0
|
||||
#define R_PPC_ADDR32 1
|
||||
#define R_PPC_ADDR24 2
|
||||
#define R_PPC_ADDR16 3
|
||||
#define R_PPC_ADDR16_LO 4
|
||||
#define R_PPC_ADDR16_HI 5
|
||||
#define R_PPC_ADDR16_HA 6
|
||||
#define R_PPC_ADDR14 7
|
||||
#define R_PPC_ADDR14_BRTAKEN 8
|
||||
#define R_PPC_ADDR14_BRNTAKEN 9
|
||||
#define R_PPC_REL24 10
|
||||
#define R_PPC_REL14 11
|
||||
#define R_PPC_REL14_BRTAKEN 12
|
||||
#define R_PPC_REL14_BRNTAKEN 13
|
||||
#define R_PPC_GOT16 14
|
||||
#define R_PPC_GOT16_LO 15
|
||||
#define R_PPC_GOT16_HI 16
|
||||
#define R_PPC_GOT16_HA 17
|
||||
#define R_PPC_PLTREL24 18
|
||||
#define R_PPC_COPY 19
|
||||
#define R_PPC_GLOB_DAT 20
|
||||
#define R_PPC_JMP_SLOT 21
|
||||
#define R_PPC_RELATIVE 22
|
||||
#define R_PPC_LOCAL24PC 23
|
||||
#define R_PPC_UADDR32 24
|
||||
#define R_PPC_UADDR16 25
|
||||
#define R_PPC_REL32 26
|
||||
#define R_PPC_PLT32 27
|
||||
#define R_PPC_PLTREL32 28
|
||||
#define R_PPC_PLT16_LO 29
|
||||
#define R_PPC_PLT16_HI 30
|
||||
#define R_PPC_PLT16_HA 31
|
||||
#define R_PPC_SDAREL16 32
|
||||
#define R_PPC_SECTOFF 33
|
||||
#define R_PPC_SECTOFF_LO 34
|
||||
#define R_PPC_SECTOFF_HI 35
|
||||
#define R_PPC_SECTOFF_HA 36
|
||||
|
||||
/* The remaining relocs are from the Embedded ELF ABI, and are not
|
||||
in the SVR4 ELF ABI. */
|
||||
#define R_PPC_EMB_NADDR32 101
|
||||
#define R_PPC_EMB_NADDR16 102
|
||||
#define R_PPC_EMB_NADDR16_LO 103
|
||||
#define R_PPC_EMB_NADDR16_HI 104
|
||||
#define R_PPC_EMB_NADDR16_HA 105
|
||||
#define R_PPC_EMB_SDAI16 106
|
||||
#define R_PPC_EMB_SDA2I16 107
|
||||
#define R_PPC_EMB_SDA2REL 108
|
||||
#define R_PPC_EMB_SDA21 109
|
||||
#define R_PPC_EMB_MRKREF 110
|
||||
#define R_PPC_EMB_RELSEC16 111
|
||||
#define R_PPC_EMB_RELST_LO 112
|
||||
#define R_PPC_EMB_RELST_HI 113
|
||||
#define R_PPC_EMB_RELST_HA 114
|
||||
#define R_PPC_EMB_BIT_FLD 115
|
||||
#define R_PPC_EMB_RELSDA 116
|
||||
|
||||
/* This is a phony reloc to handle any old fashioned TOC16 references
|
||||
that may still be in object files. */
|
||||
#define R_PPC_TOC16 255
|
||||
|
||||
__END_DECLS
|
||||
|
||||
#endif /* elf.h */
|
||||
|
||||
+49
-19
@@ -29,7 +29,8 @@ TEXTDOMAIN=libc
|
||||
TEXTDOMAINDIR=@TEXTDOMAINDIR@
|
||||
|
||||
RTLD=@RTLD@
|
||||
RELOCS=
|
||||
warn=
|
||||
bind_now=
|
||||
|
||||
while test $# -gt 0; do
|
||||
case "$1" in
|
||||
@@ -49,12 +50,13 @@ Report bugs using the \`glibcbug' script to <bugs@gnu.ai.mit.edu>."
|
||||
exit 0 ;;
|
||||
-d | --d | --da | --dat | --data | --data- | --data-r | --data-re | \
|
||||
--data-rel | --data-relo | --data-reloc | --data-relocs)
|
||||
RELOCS='--data-relocs'
|
||||
warn=yes
|
||||
shift ;;
|
||||
-r | --f | --fu | --fun | --func | --funct | --functi | --functio | \
|
||||
--function | --function- | --function-r | --function-re | --function-rel | \
|
||||
--function-relo | --function-reloc | --function-relocs)
|
||||
RELOCS='--function-relocs'
|
||||
warn=yes
|
||||
bind_now=yes
|
||||
shift ;;
|
||||
--) # Stop option processing.
|
||||
shift; break ;;
|
||||
@@ -67,6 +69,7 @@ Report bugs using the \`glibcbug' script to <bugs@gnu.ai.mit.edu>."
|
||||
esac
|
||||
done
|
||||
|
||||
add_env="LD_TRACE_LOADED_OBJECTS=1 LD_WARN=$warn LD_BIND_NOW=$bind_now"
|
||||
case $# in
|
||||
0)
|
||||
echo >&2 $"ldd: missing file arguments"
|
||||
@@ -79,21 +82,34 @@ case $# in
|
||||
*) file="./$1" ;;
|
||||
esac
|
||||
if test ! -f "$file"; then
|
||||
echo "${file}:" $"no such file"
|
||||
echo "ldd: ${file}:" $"no such file"
|
||||
exit 1
|
||||
else
|
||||
elif test -r "$file"; then
|
||||
test -x "$file" ||
|
||||
echo $"warning: you do not have execution permission for" "\`$file'"
|
||||
if ${RTLD} --verify "$file"; then
|
||||
LD_TRACE_LOADED_OBJECTS=1 exec ${RTLD} ${RELOCS} "$file" || exit 1
|
||||
else
|
||||
echo $"ldd: warning: you do not have execution permission for" "\`$file'"
|
||||
${RTLD} --verify "$file"
|
||||
case $? in
|
||||
0)
|
||||
eval $add_env exec '"$file"' || exit 1
|
||||
;;
|
||||
1)
|
||||
echo $" not a dynamic executable"
|
||||
exit 1
|
||||
fi
|
||||
;;
|
||||
2)
|
||||
eval $add_env exec \${RTLD} '"$file"' || exit 1
|
||||
;;
|
||||
*)
|
||||
echo $"ldd: ${RTLD} exited with unknown exit code ($?)" >&2
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
else
|
||||
echo $"ldd: error: you do not have read permission for" "\`$file'"
|
||||
exit 1
|
||||
fi
|
||||
exit ;;
|
||||
*)
|
||||
set -e # Bail out immediately if ${RTLD} loses on any argument.
|
||||
result=0
|
||||
for file; do
|
||||
echo "${file}:"
|
||||
@@ -102,17 +118,31 @@ case $# in
|
||||
*) file="./$file" ;;
|
||||
esac
|
||||
if test ! -f "$file"; then
|
||||
echo "${file}:" $"no such file"
|
||||
echo "ldd: ${file}:" $"no such file"
|
||||
result=1
|
||||
else
|
||||
test -x "$file" ||
|
||||
echo $"warning: you do not have execution permission for" "\`$file'"
|
||||
if ${RTLD} --verify "$file"; then
|
||||
LD_TRACE_LOADED_OBJECTS=1 ${RTLD} ${RELOCS} "$file" || result=1
|
||||
else
|
||||
elif test -r "$file"; then
|
||||
test -x "$file" || echo $"\
|
||||
ldd: warning: you do not have execution permission for" "\`$file'"
|
||||
${RTLD} --verify "$file"
|
||||
case $? in
|
||||
0)
|
||||
eval $add_env '"$file"' || result=1
|
||||
;;
|
||||
1)
|
||||
echo $" not a dynamic executable"
|
||||
result=1
|
||||
fi
|
||||
;;
|
||||
2)
|
||||
eval $add_env ${RTLD} '"$file"' || result=1
|
||||
;;
|
||||
*)
|
||||
echo $"ldd: ${RTLD} exited with unknown exit code ($?)" >&2
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
else
|
||||
echo $"ldd: error: you do not have read permission for" "\`$file'"
|
||||
result=1
|
||||
fi
|
||||
done
|
||||
esac
|
||||
|
||||
+50
-15
@@ -25,7 +25,8 @@
|
||||
# variable LD_TRACE_LOADED_OBJECTS to a non-empty value.
|
||||
|
||||
RTLD=@RTLD@
|
||||
RELOCS=
|
||||
warn=
|
||||
bind_now=
|
||||
|
||||
while test $# -gt 0; do
|
||||
case "$1" in
|
||||
@@ -45,12 +46,13 @@ Report bugs using the \`glibcbug' script to <bugs@gnu.ai.mit.edu>."
|
||||
exit 0 ;;
|
||||
-d | --d | --da | --dat | --data | --data- | --data-r | --data-re | \
|
||||
--data-rel | --data-relo | --data-reloc | --data-relocs)
|
||||
RELOCS='--data-relocs'
|
||||
warn=yes
|
||||
shift ;;
|
||||
-r | --f | --fu | --fun | --func | --funct | --functi | --functio | \
|
||||
--function | --function- | --function-r | --function-re | --function-rel | \
|
||||
--function-relo | --function-reloc | --function-relocs)
|
||||
RELOCS='--function-relocs'
|
||||
warn=yes
|
||||
bind_now=yes
|
||||
shift ;;
|
||||
--) # Stop option processing.
|
||||
shift; break ;;
|
||||
@@ -64,6 +66,7 @@ Try \`ldd --help' for more information."
|
||||
esac
|
||||
done
|
||||
|
||||
add_env="LD_TRACE_LOADED_OBJECTS=1 LD_WARN=$warn LD_BIND_NOW=$bind_now"
|
||||
case $# in
|
||||
0)
|
||||
echo >&2 "\
|
||||
@@ -77,15 +80,31 @@ Try \`ldd --help' for more information."
|
||||
*) file="./$1" ;;
|
||||
esac
|
||||
if test ! -f "$file"; then
|
||||
echo "${file}: no such file"
|
||||
echo "ldd: ${file}: no such file"
|
||||
exit 1
|
||||
else
|
||||
test -x "$file" ||
|
||||
echo "warning: you do not have execution permission for \`$file'"
|
||||
if ${RTLD} --verify "$file"; then
|
||||
LD_TRACE_LOADED_OBJECTS=1 exec ${RTLD} ${RELOCS} "$file" || exit 1
|
||||
if test -r "$file"; then
|
||||
test -x "$file" ||
|
||||
echo "ldd: warning: you do not have execution permission for \`$file'"
|
||||
${RTLD} --verify "$file"
|
||||
case $? in
|
||||
0)
|
||||
eval $add_env exec '"$file"' || exit 1
|
||||
;;
|
||||
1)
|
||||
echo ' not a dynamic executable'
|
||||
exit 1
|
||||
;;
|
||||
2)
|
||||
eval $add_env exec \${RTLD} '"$file"' || exit 1
|
||||
;;
|
||||
*)
|
||||
echo "ldd: ${RTLD} exited with unknown exit code ($?)" >&2
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
else
|
||||
echo ' not a dynamic executable'
|
||||
echo "ldd: error: you do not have read permission for \`$file'"
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
@@ -100,15 +119,31 @@ Try \`ldd --help' for more information."
|
||||
*) file="./$file" ;;
|
||||
esac
|
||||
if test ! -f "$file"; then
|
||||
echo "${file}: no such file"
|
||||
echo "ldd: ${file}: no such file"
|
||||
result=1
|
||||
else
|
||||
test -x "$file" ||
|
||||
echo "warning: you do not have execution permission for \`$file'"
|
||||
if ${RTLD} --verify "$file"; then
|
||||
LD_TRACE_LOADED_OBJECTS=1 ${RTLD} ${RELOCS} "$file" || result=1
|
||||
if test -r "$file"; then
|
||||
test -x "$file" || echo "\
|
||||
ldd: warning: you do not have execution permission for \`$file'"
|
||||
${RTLD} --verify "$file"
|
||||
case $? in
|
||||
0)
|
||||
eval $add_env '"$file"' || result=1
|
||||
;;
|
||||
1)
|
||||
echo ' not a dynamic executable'
|
||||
result=1
|
||||
;;
|
||||
2)
|
||||
eval $add_env ${RTLD} '"$file"' || result=1
|
||||
;;
|
||||
*)
|
||||
echo "ldd: ${RTLD} exited with unknown exit code ($?)" >&2
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
else
|
||||
echo ' not a dynamic executable'
|
||||
echo "ldd: error: you do not have read permission for \`$file'"
|
||||
result=1
|
||||
fi
|
||||
fi
|
||||
|
||||
+86
-20
@@ -18,13 +18,18 @@
|
||||
Boston, MA 02111-1307, USA. */
|
||||
|
||||
#ifndef _LINK_H
|
||||
|
||||
#define _LINK_H 1
|
||||
#include <features.h>
|
||||
|
||||
#define __need_size_t
|
||||
#define __need_NULL
|
||||
#include <stddef.h>
|
||||
|
||||
#include <elf.h>
|
||||
|
||||
__BEGIN_DECLS
|
||||
|
||||
/* We use this macro to refer to ELF types independent of the native wordsize.
|
||||
`ElfW(TYPE)' is used in place of `Elf32_TYPE' or `Elf64_TYPE'. */
|
||||
#define ElfW(type) _ElfW (Elf, __ELF_NATIVE_CLASS, type)
|
||||
@@ -74,6 +79,15 @@ extern struct r_debug _r_debug;
|
||||
|
||||
extern ElfW(Dyn) _DYNAMIC[];
|
||||
|
||||
/* For the version handling we need an array with only names and their
|
||||
hash values. */
|
||||
struct r_found_version
|
||||
{
|
||||
const char *name;
|
||||
ElfW(Word) hash;
|
||||
|
||||
const char *filename;
|
||||
};
|
||||
|
||||
/* Structure describing a loaded shared object. The `l_next' and `l_prev'
|
||||
members form a chain of all the shared objects loaded at startup.
|
||||
@@ -94,7 +108,11 @@ struct link_map
|
||||
/* All following members are internal to the dynamic linker.
|
||||
They may change without notice. */
|
||||
|
||||
const char *l_libname; /* Name requested (before search). */
|
||||
struct libname_list
|
||||
{
|
||||
const char *name; /* Name requested (before search). */
|
||||
struct libname_list *next; /* Link to next name for this object. */
|
||||
} *l_libname;
|
||||
/* Indexed pointers to dynamic section.
|
||||
[0,DT_NUM) are indexed by the processor-independent tags.
|
||||
[DT_NUM,DT_NUM+DT_PROCNUM) are indexed by the tag minus DT_LOPROC.
|
||||
@@ -139,13 +157,34 @@ struct link_map
|
||||
unsigned int l_init_running:1; /* Nonzero while DT_INIT function runs. */
|
||||
unsigned int l_global:1; /* Nonzero if object in _dl_global_scope. */
|
||||
unsigned int l_reserved:2; /* Reserved for internal use. */
|
||||
|
||||
/* Array with version names. */
|
||||
unsigned int l_nversions;
|
||||
struct r_found_version *l_versions;
|
||||
};
|
||||
|
||||
|
||||
/* Test whether given NAME matches any of the names of the given object. */
|
||||
static inline int
|
||||
__attribute__ ((unused))
|
||||
_dl_name_match_p (const char *__name, struct link_map *__map)
|
||||
{
|
||||
int __found = strcmp (__name, __map->l_name) == 0;
|
||||
struct libname_list *__runp = __map->l_libname;
|
||||
|
||||
while (! __found && __runp != NULL)
|
||||
if (strcmp (__name, __runp->name) == 0)
|
||||
__found = 1;
|
||||
else
|
||||
__runp = __runp->next;
|
||||
|
||||
return __found;
|
||||
}
|
||||
|
||||
/* Function used as argument for `_dl_receive_error' function. The
|
||||
arguments are the error string and the objname the error occurred
|
||||
in. */
|
||||
typedef void (*receiver_fct) (const char *, const char *);
|
||||
arguments are the error code, error string, and the objname the
|
||||
error occurred in. */
|
||||
typedef void (*receiver_fct) (int, const char *, const char *);
|
||||
|
||||
/* Internal functions of the run-time dynamic linker.
|
||||
These can be accessed if you link again the dynamic linker
|
||||
@@ -199,21 +238,26 @@ extern void _dl_signal_error (int errcode,
|
||||
error, *ERRSTRING is set to null. If there is an error, *ERRSTRING and
|
||||
*OBJECT are set to the strings passed to _dl_signal_error, and the error
|
||||
code passed is the return value. ERRSTRING if nonzero points to a
|
||||
malloc'ed string which the caller has to free after use. */
|
||||
malloc'ed string which the caller has to free after use.
|
||||
ARGS is passed as argument to OPERATE. */
|
||||
extern int _dl_catch_error (char **errstring,
|
||||
const char **object,
|
||||
void (*operate) (void));
|
||||
void (*operate) (void *),
|
||||
void *args);
|
||||
|
||||
/* Call OPERATE, receiving errors from `dl_signal_error'. Unlike
|
||||
`_dl_catch_error' the operation is resumed after the OPERATE
|
||||
function returns. */
|
||||
extern void _dl_receive_error (receiver_fct fct, void (*operate) (void));
|
||||
function returns.
|
||||
ARGS is passed as argument to OPERATE. */
|
||||
extern void _dl_receive_error (receiver_fct fct, void (*operate) (void *),
|
||||
void *args);
|
||||
|
||||
|
||||
/* Helper function for <dlfcn.h> functions. Runs the OPERATE function via
|
||||
_dl_catch_error. Returns zero for success, nonzero for failure; and
|
||||
arranges for `dlerror' to return the error details. */
|
||||
extern int _dlerror_run (void (*operate) (void));
|
||||
arranges for `dlerror' to return the error details.
|
||||
ARGS is passed as argument to OPERATE. */
|
||||
extern int _dlerror_run (void (*operate) (void *), void *args);
|
||||
|
||||
|
||||
/* Open the shared object NAME and map in its segments.
|
||||
@@ -251,26 +295,39 @@ extern void _dl_close (struct link_map *map);
|
||||
null-terminated list of object scopes to search; each object's
|
||||
l_searchlist (i.e. the segment of the dependency tree starting at that
|
||||
object) is searched in turn. REFERENCE_NAME should name the object
|
||||
containing the reference; it is used in error messages. FLAGS is a
|
||||
set of flags: */
|
||||
#define DL_LOOKUP_NOEXEC 1 /* Don't search the executable for a
|
||||
definition; this is used for copy
|
||||
relocs. */
|
||||
#define DL_LOOKUP_NOPLT 2 /* The reference must not be resolved
|
||||
to a PLT entry. */
|
||||
containing the reference; it is used in error messages.
|
||||
RELOC_TYPE is a machine-dependent reloc type, which is passed to
|
||||
the `elf_machine_lookup_*_p' macros in dl-machine.h to affect which
|
||||
symbols can be chosen. */
|
||||
extern ElfW(Addr) _dl_lookup_symbol (const char *undef,
|
||||
const ElfW(Sym) **sym,
|
||||
struct link_map *symbol_scope[],
|
||||
const char *reference_name,
|
||||
int flags);
|
||||
int reloc_type);
|
||||
|
||||
/* Lookup versioned symbol. */
|
||||
extern ElfW(Addr) _dl_lookup_versioned_symbol (const char *undef,
|
||||
const ElfW(Sym) **sym,
|
||||
struct link_map *symbol_scope[],
|
||||
const char *reference_name,
|
||||
const struct r_found_version *version,
|
||||
int reloc_type);
|
||||
|
||||
/* For handling RTLD_NEXT we must be able to skip shared objects. */
|
||||
extern ElfW(Addr) _dl_lookup_symbol_skip (const char *undef,
|
||||
const ElfW(Sym) **sym,
|
||||
struct link_map *symbol_scope[],
|
||||
const char *reference_name,
|
||||
struct link_map *skip_this,
|
||||
int flags);
|
||||
struct link_map *skip_this);
|
||||
|
||||
/* For handling RTLD_NEXT with versioned symbols we must be able to
|
||||
skip shared objects. */
|
||||
extern ElfW(Addr) _dl_lookup_versioned_symbol_skip (const char *undef,
|
||||
const ElfW(Sym) **sym,
|
||||
struct link_map *symbol_scope[],
|
||||
const char *reference_name,
|
||||
const struct r_found_version *version,
|
||||
struct link_map *skip_this);
|
||||
|
||||
/* Look up symbol NAME in MAP's scope and return its run-time address. */
|
||||
extern ElfW(Addr) _dl_symbol_value (struct link_map *map, const char *name);
|
||||
@@ -319,6 +376,14 @@ extern void _dl_relocate_object (struct link_map *map,
|
||||
struct link_map *scope[],
|
||||
int lazy);
|
||||
|
||||
/* Check the version dependencies of all objects available through
|
||||
MAP. If VERBOSE print some more diagnostics. */
|
||||
extern int _dl_check_all_versions (struct link_map *map, int verbose);
|
||||
|
||||
/* Check the version dependencies for MAP. If VERBOSE print some more
|
||||
diagnostics. */
|
||||
extern int _dl_check_map_versions (struct link_map *map, int verbose);
|
||||
|
||||
/* Return the address of the next initializer function for MAP or one of
|
||||
its dependencies that has not yet been run. When there are no more
|
||||
initializers to be run, this returns zero. The functions are returned
|
||||
@@ -340,5 +405,6 @@ extern void _dl_debug_state (void);
|
||||
in the `r_ldbase' member. Returns the address of the structure. */
|
||||
extern struct r_debug *_dl_debug_initialize (ElfW(Addr) ldbase);
|
||||
|
||||
__END_DECLS
|
||||
|
||||
#endif /* link.h */
|
||||
|
||||
+154
-93
@@ -45,7 +45,12 @@ extern void *_dl_sysdep_read_whole_file (const char *filename,
|
||||
int mmap_prot);
|
||||
|
||||
/* Helper function to handle errors while resolving symbols. */
|
||||
static void print_unresolved (const char *errstring, const char *objname);
|
||||
static void print_unresolved (int errcode, const char *objname,
|
||||
const char *errsting);
|
||||
|
||||
/* Helper function to handle errors when a version is missing. */
|
||||
static void print_missing_version (int errcode, const char *objname,
|
||||
const char *errsting);
|
||||
|
||||
|
||||
int _dl_argc;
|
||||
@@ -66,6 +71,7 @@ static void dl_main (const ElfW(Phdr) *phdr,
|
||||
ElfW(Addr) *user_entry);
|
||||
|
||||
struct link_map _dl_rtld_map;
|
||||
struct libname_list _dl_rtld_libname;
|
||||
|
||||
#ifdef RTLD_START
|
||||
RTLD_START
|
||||
@@ -73,7 +79,7 @@ RTLD_START
|
||||
#error "sysdeps/MACHINE/dl-machine.h fails to define RTLD_START"
|
||||
#endif
|
||||
|
||||
ElfW(Addr)
|
||||
static ElfW(Addr)
|
||||
_dl_start (void *arg)
|
||||
{
|
||||
struct link_map bootstrap_map;
|
||||
@@ -81,7 +87,7 @@ _dl_start (void *arg)
|
||||
/* This #define produces dynamic linking inline functions for
|
||||
bootstrap relocation instead of general-purpose relocation. */
|
||||
#define RTLD_BOOTSTRAP
|
||||
#define RESOLVE(sym, flags) bootstrap_map.l_addr
|
||||
#define RESOLVE(sym, version, flags) bootstrap_map.l_addr
|
||||
#include "dynamic-link.h"
|
||||
|
||||
/* Figure out the run-time load address of the dynamic linker itself. */
|
||||
@@ -100,6 +106,7 @@ _dl_start (void *arg)
|
||||
|
||||
ELF_DYNAMIC_RELOCATE (&bootstrap_map, 0);
|
||||
|
||||
elf_machine_runtime_setup (&bootstrap_map, 0);
|
||||
|
||||
/* Now life is sane; we can call functions and access global data.
|
||||
Set up to use the operating system facilities, and find out from
|
||||
@@ -133,6 +140,55 @@ _dl_start (void *arg)
|
||||
|
||||
void _start (void);
|
||||
|
||||
/* Some helper functions. */
|
||||
|
||||
/* Arguments to relocate_doit. */
|
||||
struct relocate_args
|
||||
{
|
||||
struct link_map *l;
|
||||
int lazy;
|
||||
};
|
||||
|
||||
struct map_args
|
||||
{
|
||||
/* Argument to map_doit. */
|
||||
char *str;
|
||||
/* Return value of map_doit. */
|
||||
struct link_map *main_map;
|
||||
};
|
||||
|
||||
/* Arguments to version_check_doit. */
|
||||
struct version_check_args
|
||||
{
|
||||
struct link_map *main_map;
|
||||
int doexit;
|
||||
};
|
||||
|
||||
static void
|
||||
relocate_doit (void *a)
|
||||
{
|
||||
struct relocate_args *args = (struct relocate_args *) a;
|
||||
|
||||
_dl_relocate_object (args->l, _dl_object_relocation_scope (args->l),
|
||||
args->lazy);
|
||||
}
|
||||
|
||||
static void
|
||||
map_doit (void *a)
|
||||
{
|
||||
struct map_args *args = (struct map_args *)a;
|
||||
args->main_map = _dl_map_object (NULL, args->str, lt_library, 0);
|
||||
}
|
||||
|
||||
static void
|
||||
version_check_doit (void *a)
|
||||
{
|
||||
struct version_check_args *args = (struct version_check_args *)a;
|
||||
if (_dl_check_all_versions (args->main_map, 1) && args->doexit)
|
||||
/* We cannot start the application. Abort now. */
|
||||
_exit (1);
|
||||
}
|
||||
|
||||
unsigned int _dl_skip_args; /* Nonzero if we were run directly. */
|
||||
|
||||
static void
|
||||
@@ -141,7 +197,7 @@ dl_main (const ElfW(Phdr) *phdr,
|
||||
ElfW(Addr) *user_entry)
|
||||
{
|
||||
const ElfW(Phdr) *ph;
|
||||
struct link_map *l;
|
||||
struct link_map *main_map;
|
||||
int lazy;
|
||||
enum { normal, list, verify, trace } mode;
|
||||
struct link_map **preloads;
|
||||
@@ -149,13 +205,15 @@ dl_main (const ElfW(Phdr) *phdr,
|
||||
const char *preloadlist;
|
||||
size_t file_size;
|
||||
char *file;
|
||||
int has_interp = 0;
|
||||
|
||||
mode = getenv ("LD_TRACE_LOADED_OBJECTS") != NULL ? trace : normal;
|
||||
|
||||
/* LAZY is determined by the parameters --datadeps and --function-deps
|
||||
if we trace the binary. */
|
||||
if (mode == trace)
|
||||
lazy = -1;
|
||||
lazy = (*(getenv ("LD_WARN") ?: "") == '\0' ? -1
|
||||
: (*(getenv ("LD_BIND_NOW") ?: "") == '\0' ? 1 : 0));
|
||||
else
|
||||
lazy = !__libc_enable_secure && *(getenv ("LD_BIND_NOW") ?: "") == '\0';
|
||||
|
||||
@@ -212,24 +270,6 @@ of this helper program; chances are you did not intend to run this program.\n",
|
||||
{
|
||||
mode = verify;
|
||||
|
||||
++_dl_skip_args;
|
||||
--_dl_argc;
|
||||
++_dl_argv;
|
||||
}
|
||||
else if (! strcmp (_dl_argv[1], "--data-relocs"))
|
||||
{
|
||||
mode = trace;
|
||||
lazy = 1; /* This means do only data relocation analysis. */
|
||||
|
||||
++_dl_skip_args;
|
||||
--_dl_argc;
|
||||
++_dl_argv;
|
||||
}
|
||||
else if (! strcmp (_dl_argv[1], "--function-relocs"))
|
||||
{
|
||||
mode = trace;
|
||||
lazy = 0; /* This means do also function relocation analysis. */
|
||||
|
||||
++_dl_skip_args;
|
||||
--_dl_argc;
|
||||
++_dl_argv;
|
||||
@@ -243,14 +283,13 @@ of this helper program; chances are you did not intend to run this program.\n",
|
||||
|
||||
if (mode == verify)
|
||||
{
|
||||
void doit (void)
|
||||
{
|
||||
l = _dl_map_object (NULL, _dl_argv[0], lt_library, 0);
|
||||
}
|
||||
char *err_str = NULL;
|
||||
const char *obj_name __attribute__ ((unused));
|
||||
struct map_args args;
|
||||
|
||||
(void) _dl_catch_error (&err_str, &obj_name, doit);
|
||||
args.str = _dl_argv[0];
|
||||
(void) _dl_catch_error (&err_str, &obj_name, map_doit, &args);
|
||||
main_map = args.main_map;
|
||||
if (err_str != NULL)
|
||||
{
|
||||
free (err_str);
|
||||
@@ -258,37 +297,24 @@ of this helper program; chances are you did not intend to run this program.\n",
|
||||
}
|
||||
}
|
||||
else
|
||||
l = _dl_map_object (NULL, _dl_argv[0], lt_library, 0);
|
||||
main_map = _dl_map_object (NULL, _dl_argv[0], lt_library, 0);
|
||||
|
||||
phdr = l->l_phdr;
|
||||
phent = l->l_phnum;
|
||||
l->l_name = (char *) "";
|
||||
*user_entry = l->l_entry;
|
||||
phdr = main_map->l_phdr;
|
||||
phent = main_map->l_phnum;
|
||||
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. */
|
||||
l = _dl_new_object ((char *) "", "", lt_executable);
|
||||
if (l == NULL)
|
||||
main_map = _dl_new_object ((char *) "", "", lt_executable);
|
||||
if (main_map == NULL)
|
||||
_dl_sysdep_fatal ("cannot allocate memory for link map", NULL);
|
||||
l->l_phdr = phdr;
|
||||
l->l_phnum = phent;
|
||||
l->l_entry = *user_entry;
|
||||
}
|
||||
|
||||
if (l != _dl_loaded)
|
||||
{
|
||||
/* GDB assumes that the first element on the chain is the
|
||||
link_map for the executable itself, and always skips it.
|
||||
Make sure the first one is indeed that one. */
|
||||
l->l_prev->l_next = l->l_next;
|
||||
if (l->l_next)
|
||||
l->l_next->l_prev = l->l_prev;
|
||||
l->l_prev = NULL;
|
||||
l->l_next = _dl_loaded;
|
||||
_dl_loaded->l_prev = l;
|
||||
_dl_loaded = l;
|
||||
main_map->l_phdr = phdr;
|
||||
main_map->l_phnum = phent;
|
||||
main_map->l_entry = *user_entry;
|
||||
main_map->l_opencount = 1;
|
||||
}
|
||||
|
||||
/* Scan the program header table for the dynamic section. */
|
||||
@@ -298,7 +324,7 @@ of this helper program; chances are you did not intend to run this program.\n",
|
||||
case PT_DYNAMIC:
|
||||
/* This tells us where to find the dynamic section,
|
||||
which tells us everything we need to do. */
|
||||
l->l_ld = (void *) l->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
|
||||
@@ -307,37 +333,44 @@ 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_map.l_libname = (const char *) l->l_addr + ph->p_vaddr;
|
||||
_dl_rtld_libname.name = (const char *) main_map->l_addr + ph->p_vaddr;
|
||||
_dl_rtld_libname.next = NULL;
|
||||
_dl_rtld_map.l_libname = &_dl_rtld_libname;
|
||||
has_interp = 1;
|
||||
break;
|
||||
}
|
||||
if (! _dl_rtld_map.l_libname && _dl_rtld_map.l_name)
|
||||
/* We were invoked directly, so the program might not have a PT_INTERP. */
|
||||
_dl_rtld_map.l_libname = _dl_rtld_map.l_name;
|
||||
{
|
||||
/* We were invoked directly, so the program might not have a
|
||||
PT_INTERP. */
|
||||
_dl_rtld_libname.name = _dl_rtld_map.l_name;
|
||||
_dl_rtld_libname.next = NULL;
|
||||
_dl_rtld_map.l_libname = &_dl_rtld_libname;
|
||||
}
|
||||
else
|
||||
assert (_dl_rtld_map.l_libname); /* How else did we get here? */
|
||||
|
||||
if (mode == verify)
|
||||
/* We were called just to verify that this is a dynamic executable
|
||||
using us as the program interpreter. */
|
||||
_exit (l->l_ld == NULL ? EXIT_FAILURE : EXIT_SUCCESS);
|
||||
_exit (main_map->l_ld == NULL ? 1 : has_interp ? 0 : 2);
|
||||
|
||||
/* Extract the contents of the dynamic section for easy access. */
|
||||
elf_get_dynamic_info (l->l_ld, l->l_info);
|
||||
if (l->l_info[DT_HASH])
|
||||
elf_get_dynamic_info (main_map->l_ld, main_map->l_info);
|
||||
if (main_map->l_info[DT_HASH])
|
||||
/* Set up our cache of pointers into the hash table. */
|
||||
_dl_setup_hash (l);
|
||||
_dl_setup_hash (main_map);
|
||||
|
||||
/* Put the link_map for ourselves on the chain so it can be found by
|
||||
name. */
|
||||
name. Note that at this point the global chain of link maps contains
|
||||
exactly one element, which is pointed to by main_map. */
|
||||
if (! _dl_rtld_map.l_name)
|
||||
/* If not invoked directly, the dynamic linker shared object file was
|
||||
found by the PT_INTERP name. */
|
||||
_dl_rtld_map.l_name = (char *) _dl_rtld_map.l_libname;
|
||||
_dl_rtld_map.l_name = (char *) _dl_rtld_map.l_libname->name;
|
||||
_dl_rtld_map.l_type = lt_library;
|
||||
while (l->l_next)
|
||||
l = l->l_next;
|
||||
l->l_next = &_dl_rtld_map;
|
||||
_dl_rtld_map.l_prev = l;
|
||||
main_map->l_next = &_dl_rtld_map;
|
||||
_dl_rtld_map.l_prev = main_map;
|
||||
|
||||
/* We have two ways to specify objects to preload: via environment
|
||||
variable and via the file /etc/ld.so.preload. The later can also
|
||||
@@ -447,7 +480,7 @@ of this helper program; chances are you did not intend to run this program.\n",
|
||||
/* Load all the libraries specified by DT_NEEDED entries. If LD_PRELOAD
|
||||
specified some libraries to load, these are inserted before the actual
|
||||
dependencies in the executable's searchlist for symbol resolution. */
|
||||
_dl_map_object_deps (l, preloads, npreloads, mode == trace);
|
||||
_dl_map_object_deps (main_map, preloads, npreloads, mode == trace);
|
||||
|
||||
#ifndef MAP_ANON
|
||||
/* We are done mapping things, so close the zero-fill descriptor. */
|
||||
@@ -467,11 +500,11 @@ of this helper program; chances are you did not intend to run this program.\n",
|
||||
chain in symbol search order because gdb uses the chain's order as
|
||||
its symbol search order. */
|
||||
unsigned int i = 1;
|
||||
while (l->l_searchlist[i] != &_dl_rtld_map)
|
||||
while (main_map->l_searchlist[i] != &_dl_rtld_map)
|
||||
++i;
|
||||
_dl_rtld_map.l_prev = l->l_searchlist[i - 1];
|
||||
_dl_rtld_map.l_next = (i + 1 < l->l_nsearchlist ?
|
||||
l->l_searchlist[i + 1] : NULL);
|
||||
_dl_rtld_map.l_prev = main_map->l_searchlist[i - 1];
|
||||
_dl_rtld_map.l_next = (i + 1 < main_map->l_nsearchlist ?
|
||||
main_map->l_searchlist[i + 1] : NULL);
|
||||
assert (_dl_rtld_map.l_prev->l_next == _dl_rtld_map.l_next);
|
||||
_dl_rtld_map.l_prev->l_next = &_dl_rtld_map;
|
||||
if (_dl_rtld_map.l_next)
|
||||
@@ -481,6 +514,15 @@ of this helper program; chances are you did not intend to run this program.\n",
|
||||
}
|
||||
}
|
||||
|
||||
/* Now let us see whether all libraries are available in the
|
||||
versions we need. */
|
||||
{
|
||||
struct version_check_args args;
|
||||
args.doexit = mode == normal;
|
||||
args.main_map = main_map;
|
||||
_dl_receive_error (print_missing_version, version_check_doit, &args);
|
||||
}
|
||||
|
||||
if (mode != normal)
|
||||
{
|
||||
/* We were run just to list the shared libraries. It is
|
||||
@@ -493,21 +535,26 @@ of this helper program; chances are you did not intend to run this program.\n",
|
||||
if (! _dl_loaded->l_info[DT_NEEDED])
|
||||
_dl_sysdep_message ("\t", "statically linked\n", NULL);
|
||||
else
|
||||
for (l = _dl_loaded->l_next; l; l = l->l_next)
|
||||
if (l->l_opencount == 0)
|
||||
/* The library was not found. */
|
||||
_dl_sysdep_message ("\t", l->l_libname, " => not found\n", NULL);
|
||||
else
|
||||
{
|
||||
char buf[20], *bp;
|
||||
buf[sizeof buf - 1] = '\0';
|
||||
bp = _itoa (l->l_addr, &buf[sizeof buf - 1], 16, 0);
|
||||
while ((size_t) (&buf[sizeof buf - 1] - bp)
|
||||
< sizeof l->l_addr * 2)
|
||||
*--bp = '0';
|
||||
_dl_sysdep_message ("\t", l->l_libname, " => ", l->l_name,
|
||||
" (0x", bp, ")\n", NULL);
|
||||
}
|
||||
{
|
||||
struct link_map *l;
|
||||
|
||||
for (l = _dl_loaded->l_next; l; l = l->l_next)
|
||||
if (l->l_opencount == 0)
|
||||
/* The library was not found. */
|
||||
_dl_sysdep_message ("\t", l->l_libname->name, " => not found\n",
|
||||
NULL);
|
||||
else
|
||||
{
|
||||
char buf[20], *bp;
|
||||
buf[sizeof buf - 1] = '\0';
|
||||
bp = _itoa (l->l_addr, &buf[sizeof buf - 1], 16, 0);
|
||||
while ((size_t) (&buf[sizeof buf - 1] - bp)
|
||||
< sizeof l->l_addr * 2)
|
||||
*--bp = '0';
|
||||
_dl_sysdep_message ("\t", l->l_libname->name, " => ",
|
||||
l->l_name, " (0x", bp, ")\n", NULL);
|
||||
}
|
||||
}
|
||||
|
||||
if (mode != trace)
|
||||
for (i = 1; i < _dl_argc; ++i)
|
||||
@@ -516,7 +563,7 @@ of this helper program; chances are you did not intend to run this program.\n",
|
||||
ElfW(Addr) loadbase = _dl_lookup_symbol (_dl_argv[i], &ref,
|
||||
&_dl_default_scope[2],
|
||||
"argument",
|
||||
DL_LOOKUP_NOPLT);
|
||||
ELF_MACHINE_RELOC_NOPLT);
|
||||
char buf[20], *bp;
|
||||
buf[sizeof buf - 1] = '\0';
|
||||
bp = _itoa (ref->st_value, &buf[sizeof buf - 1], 16, 0);
|
||||
@@ -532,10 +579,10 @@ of this helper program; chances are you did not intend to run this program.\n",
|
||||
else if (lazy >= 0)
|
||||
{
|
||||
/* We have to do symbol dependency testing. */
|
||||
void doit (void)
|
||||
{
|
||||
_dl_relocate_object (l, _dl_object_relocation_scope (l), lazy);
|
||||
}
|
||||
struct relocate_args args;
|
||||
struct link_map *l;
|
||||
|
||||
args.lazy = lazy;
|
||||
|
||||
l = _dl_loaded;
|
||||
while (l->l_next)
|
||||
@@ -544,7 +591,8 @@ of this helper program; chances are you did not intend to run this program.\n",
|
||||
{
|
||||
if (l != &_dl_rtld_map && l->l_opencount > 0)
|
||||
{
|
||||
_dl_receive_error (print_unresolved, doit);
|
||||
args.l = l;
|
||||
_dl_receive_error (print_unresolved, relocate_doit, &args);
|
||||
*_dl_global_scope_end = NULL;
|
||||
}
|
||||
l = l->l_prev;
|
||||
@@ -564,6 +612,7 @@ of this helper program; chances are you did not intend to run this program.\n",
|
||||
the dynamic linker out of order because it has no copy relocs (we
|
||||
know that because it is self-contained). */
|
||||
|
||||
struct link_map *l;
|
||||
l = _dl_loaded;
|
||||
while (l->l_next)
|
||||
l = l->l_next;
|
||||
@@ -593,6 +642,7 @@ of this helper program; chances are you did not intend to run this program.\n",
|
||||
{
|
||||
/* Initialize _r_debug. */
|
||||
struct r_debug *r = _dl_debug_initialize (_dl_rtld_map.l_addr);
|
||||
struct link_map *l;
|
||||
|
||||
l = _dl_loaded;
|
||||
|
||||
@@ -629,7 +679,18 @@ of this helper program; chances are you did not intend to run this program.\n",
|
||||
/* This is a little helper function for resolving symbols while
|
||||
tracing the binary. */
|
||||
static void
|
||||
print_unresolved (const char *errstring, const char *objname)
|
||||
print_unresolved (int errcode __attribute__ ((unused)), const char *objname,
|
||||
const char *errstring)
|
||||
{
|
||||
_dl_sysdep_error (errstring, " (", objname, ")\n", NULL);
|
||||
}
|
||||
|
||||
/* This is a little helper function for resolving symbols while
|
||||
tracing the binary. */
|
||||
static void
|
||||
print_missing_version (int errcode __attribute__ ((unused)),
|
||||
const char *objname, const char *errstring)
|
||||
{
|
||||
_dl_sysdep_error (_dl_argv[0] ?: "<program name unknown>", ": ",
|
||||
objname, ": ", errstring, "\n", NULL);
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* Copyright (C) 1991, 92, 93, 94, 95, 96 Free Software Foundation, Inc.
|
||||
/* Copyright (C) 1991, 92, 93, 94, 95, 96, 97 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,13 +49,6 @@ extern int errno;
|
||||
|
||||
#ifdef __USE_GNU
|
||||
|
||||
/* The Hurd <errnos.h> defines `error_t' as an enumerated type
|
||||
so that printing `error_t' values in the debugger shows the names. */
|
||||
#ifndef __error_t_defined
|
||||
typedef int error_t;
|
||||
#define __error_t_defined 1
|
||||
#endif
|
||||
|
||||
/* The full and simple forms of the name with which the program was
|
||||
invoked. These variables are set up automatically at startup based on
|
||||
the value of ARGV[0] (this works only if you use GNU ld). */
|
||||
@@ -65,4 +58,16 @@ extern char *program_invocation_name, *program_invocation_short_name;
|
||||
|
||||
__END_DECLS
|
||||
|
||||
#endif /* errno.h */
|
||||
#endif /* _ERRNO_H */
|
||||
|
||||
/* The Hurd <errnos.h> defines `error_t' as an enumerated type so that
|
||||
printing `error_t' values in the debugger shows the names. We
|
||||
might need this definition sometimes even if this file was included
|
||||
before. */
|
||||
#if defined __USE_GNU || defined __need_error_t
|
||||
# ifndef __error_t_defined
|
||||
typedef int error_t;
|
||||
# define __error_t_defined 1
|
||||
# endif
|
||||
# undef __need_error_t
|
||||
#endif
|
||||
|
||||
+16
-5
@@ -24,6 +24,7 @@
|
||||
to specify the desired environment:
|
||||
|
||||
__STRICT_ANSI__ ISO Standard C.
|
||||
_ISOC9X_SOURCE Extensions to ISO C 89 from ISO C 9x.
|
||||
_POSIX_SOURCE IEEE Std 1003.1.
|
||||
_POSIX_C_SOURCE If ==1, like _POSIX_SOURCE; if >=2 add IEEE Std 1003.2;
|
||||
if >=199309L, add IEEE Std 1003.1b-1993
|
||||
@@ -44,6 +45,7 @@
|
||||
These are defined by this file and are used by the
|
||||
header files to decide what to declare or define:
|
||||
|
||||
__USE_ISOC9X Define ISO C 9X things.
|
||||
__USE_POSIX Define IEEE Std 1003.1 things.
|
||||
__USE_POSIX2 Define IEEE Std 1003.2 things.
|
||||
__USE_POSIX199309 Define IEEE Std 1003.1b things.
|
||||
@@ -69,6 +71,7 @@
|
||||
|
||||
|
||||
/* Undefine everything, so we get a clean slate. */
|
||||
#undef __USE_ISOC9X
|
||||
#undef __USE_POSIX
|
||||
#undef __USE_POSIX2
|
||||
#undef __USE_POSIX199309
|
||||
@@ -102,6 +105,8 @@
|
||||
|
||||
/* If _GNU_SOURCE was defined by the user, turn on all the other features. */
|
||||
#ifdef _GNU_SOURCE
|
||||
#undef _ISOC9X_SOURCE
|
||||
#define _ISOC9X_SOURCE 1
|
||||
#undef _POSIX_SOURCE
|
||||
#define _POSIX_SOURCE 1
|
||||
#undef _POSIX_C_SOURCE
|
||||
@@ -118,14 +123,20 @@
|
||||
|
||||
/* If nothing (other than _GNU_SOURCE) is defined,
|
||||
define _BSD_SOURCE and _SVID_SOURCE. */
|
||||
#if (!defined __STRICT_ANSI__ && !defined _POSIX_SOURCE && \
|
||||
!defined _POSIX_C_SOURCE && !defined _XOPEN_SOURCE && \
|
||||
!defined _XOPEN_SOURCE_EXTENDED && !defined _BSD_SOURCE && \
|
||||
!defined _SVID_SOURCE)
|
||||
#if (!defined __STRICT_ANSI__ && !defined _ISOC9X_SOURCE && \
|
||||
!defined _POSIX_SOURCE && !defined _POSIX_C_SOURCE && \
|
||||
!defined _XOPEN_SOURCE && !defined _XOPEN_SOURCE_EXTENDED && \
|
||||
!defined _BSD_SOURCE && !defined _SVID_SOURCE)
|
||||
#define _BSD_SOURCE 1
|
||||
#define _SVID_SOURCE 1
|
||||
#endif
|
||||
|
||||
/* This is to enable the ISO C 9x extension. It will go away as soon
|
||||
as this standard is officially released. */
|
||||
#ifdef _ISOC9X_SOURCE
|
||||
#define __USE_ISOC9X 1
|
||||
#endif
|
||||
|
||||
/* If none of the ANSI/POSIX macros are defined, use POSIX.1 and POSIX.2
|
||||
(and IEEE Std 1003.1b-1993 unless _XOPEN_SOURCE is defined). */
|
||||
#if (!defined __STRICT_ANSI__ && !defined _POSIX_SOURCE && \
|
||||
@@ -190,7 +201,7 @@
|
||||
/* Major and minor version number of the GNU C library package. Use
|
||||
these macros to test for features in specific releases. */
|
||||
#define __GLIBC__ 2
|
||||
#define __GLIBC_MINOR__ 0
|
||||
#define __GLIBC_MINOR__ 1
|
||||
|
||||
|
||||
#if !defined __GNUC__ || __GNUC__ < 2
|
||||
|
||||
+1
-1
@@ -232,7 +232,7 @@ sed -e "
|
||||
/^>Fix:/,/^>[A-Za-z-]*:/s;$FIX_C;;
|
||||
" $TEMP > $TEMP.x
|
||||
|
||||
if $MAIL_AGENT $BUGGLIBC < $TEMP.x; then
|
||||
if $MAIL_AGENT < $TEMP.x; then
|
||||
echo "$COMMAND: problem report sent"
|
||||
xs=0; exit
|
||||
else
|
||||
|
||||
+42
-41
@@ -1,22 +1,21 @@
|
||||
/* Copyright (C) 1996 Free Software Foundation, Inc.
|
||||
/* Copyright (C) 1996, 1997 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
Contributed by David Mosberger (davidm@cs.arizona.edu).
|
||||
|
||||
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 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.
|
||||
|
||||
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., 675 Mass Ave,
|
||||
Cambridge, MA 02139, USA. */
|
||||
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. */
|
||||
|
||||
/* __bb_exit_func() dumps all the basic-block statistics linked into
|
||||
the bb_head chain to .d files. */
|
||||
@@ -24,19 +23,19 @@ Cambridge, MA 02139, USA. */
|
||||
#include <sys/gmon_out.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
#include <ansidecl.h>
|
||||
#include <stdio.h>
|
||||
#include <strings.h>
|
||||
|
||||
/* structure emitted by -a */
|
||||
struct bb {
|
||||
long zero_word;
|
||||
const char *filename;
|
||||
long *counts;
|
||||
long ncounts;
|
||||
struct bb *next;
|
||||
const unsigned long *addresses;
|
||||
};
|
||||
struct bb
|
||||
{
|
||||
long int zero_word;
|
||||
const char *filename;
|
||||
long int *counts;
|
||||
long int ncounts;
|
||||
struct bb *next;
|
||||
const unsigned long int *addresses;
|
||||
};
|
||||
|
||||
extern struct bb *__bb_head; /* from gmon.c */
|
||||
|
||||
@@ -44,35 +43,37 @@ extern struct bb *__bb_head; /* from gmon.c */
|
||||
|
||||
|
||||
void
|
||||
DEFUN_VOID(__bb_exit_func)
|
||||
__bb_exit_func (void)
|
||||
{
|
||||
const int version = GMON_VERSION;
|
||||
struct gmon_hdr ghdr;
|
||||
struct bb *ptr;
|
||||
FILE *fp;
|
||||
fp = fopen(OUT_NAME, "wb");
|
||||
fp = fopen (OUT_NAME, "wb");
|
||||
if (!fp)
|
||||
{
|
||||
perror(OUT_NAME);
|
||||
perror (OUT_NAME);
|
||||
return;
|
||||
}
|
||||
bcopy(GMON_MAGIC, &ghdr.cookie[0], 4);
|
||||
bcopy(&version, &ghdr.version, sizeof(version));
|
||||
fwrite(&ghdr, sizeof(ghdr), 1, fp);
|
||||
bcopy (GMON_MAGIC, &ghdr.cookie[0], 4);
|
||||
bcopy (&version, &ghdr.version, sizeof (version));
|
||||
fwrite (&ghdr, sizeof (ghdr), 1, fp);
|
||||
|
||||
for (ptr = __bb_head; ptr != 0; ptr = ptr->next) {
|
||||
u_int ncounts = ptr->ncounts;
|
||||
u_char tag;
|
||||
u_int i;
|
||||
for (ptr = __bb_head; ptr != 0; ptr = ptr->next)
|
||||
{
|
||||
u_int ncounts = ptr->ncounts;
|
||||
u_char tag;
|
||||
u_int i;
|
||||
|
||||
tag = GMON_TAG_BB_COUNT;
|
||||
fwrite(&tag, sizeof(tag), 1, fp);
|
||||
fwrite(&ncounts, sizeof(ncounts), 1, fp);
|
||||
tag = GMON_TAG_BB_COUNT;
|
||||
fwrite (&tag, sizeof (tag), 1, fp);
|
||||
fwrite (&ncounts, sizeof (ncounts), 1, fp);
|
||||
|
||||
for (i = 0; i < ncounts; ++i) {
|
||||
fwrite(&ptr->addresses[i], sizeof(ptr->addresses[0]), 1, fp);
|
||||
fwrite(&ptr->counts[i], sizeof(ptr->counts[0]), 1, fp);
|
||||
for (i = 0; i < ncounts; ++i)
|
||||
{
|
||||
fwrite (&ptr->addresses[i], sizeof (ptr->addresses[0]), 1, fp);
|
||||
fwrite (&ptr->counts[i], sizeof (ptr->counts[0]), 1, fp);
|
||||
}
|
||||
}
|
||||
}
|
||||
fclose (fp);
|
||||
}
|
||||
|
||||
+87
-40
@@ -34,6 +34,7 @@
|
||||
#include <sys/time.h>
|
||||
#include <sys/gmon.h>
|
||||
#include <sys/gmon_out.h>
|
||||
#include <sys/uio.h>
|
||||
|
||||
#include <stdio.h>
|
||||
#include <fcntl.h>
|
||||
@@ -124,7 +125,7 @@ monstartup (lowpc, highpc)
|
||||
cp = malloc (p->kcountsize + p->fromssize + p->tossize);
|
||||
if (! cp)
|
||||
{
|
||||
ERR("monstartup: out of memory\n");
|
||||
ERR(_("monstartup: out of memory\n"));
|
||||
return;
|
||||
}
|
||||
bzero(cp, p->kcountsize + p->fromssize + p->tossize);
|
||||
@@ -165,21 +166,26 @@ static void
|
||||
write_hist (fd)
|
||||
int fd;
|
||||
{
|
||||
const u_char tag = GMON_TAG_TIME_HIST;
|
||||
struct gmon_hist_hdr thdr;
|
||||
u_char tag = GMON_TAG_TIME_HIST;
|
||||
struct gmon_hist_hdr thdr __attribute__ ((aligned (__alignof__ (char *))));
|
||||
|
||||
if (_gmonparam.kcountsize > 0)
|
||||
{
|
||||
thdr.low_pc = _gmonparam.lowpc;
|
||||
thdr.high_pc = _gmonparam.highpc;
|
||||
thdr.hist_size = _gmonparam.kcountsize / sizeof(HISTCOUNTER);
|
||||
thdr.prof_rate = __profile_frequency();
|
||||
strncpy(thdr.dimen, "seconds", sizeof(thdr.dimen));
|
||||
struct iovec iov[3] =
|
||||
{
|
||||
{ &tag, sizeof (tag) },
|
||||
{ &thdr, sizeof (struct gmon_hist_hdr) },
|
||||
{ _gmonparam.kcount, _gmonparam.kcountsize }
|
||||
};
|
||||
|
||||
*(char **) thdr.low_pc = (char *) _gmonparam.lowpc;
|
||||
*(char **) thdr.high_pc = (char *) _gmonparam.highpc;
|
||||
*(int *) thdr.hist_size = _gmonparam.kcountsize / sizeof (HISTCOUNTER);
|
||||
*(int *) thdr.prof_rate = __profile_frequency ();
|
||||
strncpy (thdr.dimen, "seconds", sizeof (thdr.dimen));
|
||||
thdr.dimen_abbrev = 's';
|
||||
|
||||
write(fd, &tag, sizeof(tag));
|
||||
write(fd, &thdr, sizeof(thdr));
|
||||
write(fd, _gmonparam.kcount, _gmonparam.kcountsize);
|
||||
__writev (fd, iov, 3);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -188,12 +194,26 @@ static void
|
||||
write_call_graph (fd)
|
||||
int fd;
|
||||
{
|
||||
const u_char tag = GMON_TAG_CG_ARC;
|
||||
struct gmon_cg_arc_record raw_arc;
|
||||
#define NARCS_PER_WRITEV 32
|
||||
u_char tag = GMON_TAG_CG_ARC;
|
||||
struct gmon_cg_arc_record raw_arc[NARCS_PER_WRITEV]
|
||||
__attribute__ ((aligned (__alignof__ (char*))));
|
||||
int from_index, to_index, from_len;
|
||||
u_long frompc;
|
||||
struct iovec iov[2 * NARCS_PER_WRITEV];
|
||||
int nfilled;
|
||||
|
||||
from_len = _gmonparam.fromssize / sizeof(*_gmonparam.froms);
|
||||
for (nfilled = 0; nfilled < NARCS_PER_WRITEV; ++nfilled)
|
||||
{
|
||||
iov[2 * nfilled].iov_base = &tag;
|
||||
iov[2 * nfilled].iov_len = sizeof (tag);
|
||||
|
||||
iov[2 * nfilled + 1].iov_base = &raw_arc[nfilled];
|
||||
iov[2 * nfilled + 1].iov_len = sizeof (struct gmon_cg_arc_record);
|
||||
}
|
||||
|
||||
nfilled = 0;
|
||||
from_len = _gmonparam.fromssize / sizeof (*_gmonparam.froms);
|
||||
for (from_index = 0; from_index < from_len; ++from_index)
|
||||
{
|
||||
if (_gmonparam.froms[from_index] == 0)
|
||||
@@ -201,19 +221,25 @@ write_call_graph (fd)
|
||||
|
||||
frompc = _gmonparam.lowpc;
|
||||
frompc += (from_index * _gmonparam.hashfraction
|
||||
* sizeof(*_gmonparam.froms));
|
||||
* sizeof (*_gmonparam.froms));
|
||||
for (to_index = _gmonparam.froms[from_index];
|
||||
to_index != 0;
|
||||
to_index = _gmonparam.tos[to_index].link)
|
||||
{
|
||||
raw_arc.from_pc = frompc;
|
||||
raw_arc.self_pc = _gmonparam.tos[to_index].selfpc;
|
||||
raw_arc.count = _gmonparam.tos[to_index].count;
|
||||
*(char **) raw_arc[nfilled].from_pc = (char *) frompc;
|
||||
*(char **) raw_arc[nfilled].self_pc =
|
||||
(char *)_gmonparam.tos[to_index].selfpc;
|
||||
*(int *) raw_arc[nfilled].count = _gmonparam.tos[to_index].count;
|
||||
|
||||
write(fd, &tag, sizeof(tag));
|
||||
write(fd, &raw_arc, sizeof(raw_arc));
|
||||
if (++nfilled == NARCS_PER_WRITEV)
|
||||
{
|
||||
__writev (fd, iov, 2 * nfilled);
|
||||
nfilled = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (nfilled > 0)
|
||||
__writev (fd, iov, 2 * nfilled);
|
||||
}
|
||||
|
||||
|
||||
@@ -222,9 +248,23 @@ write_bb_counts (fd)
|
||||
int fd;
|
||||
{
|
||||
struct __bb *grp;
|
||||
const u_char tag = GMON_TAG_BB_COUNT;
|
||||
int ncounts;
|
||||
int i;
|
||||
u_char tag = GMON_TAG_BB_COUNT;
|
||||
size_t ncounts;
|
||||
size_t i;
|
||||
|
||||
struct iovec bbhead[2] =
|
||||
{
|
||||
{ &tag, sizeof (tag) },
|
||||
{ &ncounts, sizeof (ncounts) }
|
||||
};
|
||||
struct iovec bbbody[8];
|
||||
size_t nfilled;
|
||||
|
||||
for (i = 0; i < (sizeof (bbbody) / sizeof (bbbody[0])); i += 2)
|
||||
{
|
||||
bbbody[i].iov_len = sizeof (grp->addresses[0]);
|
||||
bbbody[i + 1].iov_len = sizeof (grp->counts[0]);
|
||||
}
|
||||
|
||||
/* Write each group of basic-block info (all basic-blocks in a
|
||||
compilation unit form a single group). */
|
||||
@@ -232,13 +272,20 @@ write_bb_counts (fd)
|
||||
for (grp = __bb_head; grp; grp = grp->next)
|
||||
{
|
||||
ncounts = grp->ncounts;
|
||||
write(fd, &tag, sizeof(tag));
|
||||
write(fd, &ncounts, sizeof(ncounts));
|
||||
for (i = 0; i < ncounts; ++i)
|
||||
__writev (fd, bbhead, 2);
|
||||
for (nfilled = i = 0; i < ncounts; ++i)
|
||||
{
|
||||
write(fd, &grp->addresses[i], sizeof(grp->addresses[0]));
|
||||
write(fd, &grp->counts[i], sizeof(grp->counts[0]));
|
||||
if (nfilled > (sizeof (bbbody) / sizeof (bbbody[0])) - 2)
|
||||
{
|
||||
__writev (fd, bbbody, nfilled);
|
||||
nfilled = 0;
|
||||
}
|
||||
|
||||
bbbody[nfilled++].iov_base = (char *) &grp->addresses[i];
|
||||
bbbody[nfilled++].iov_base = &grp->counts[i];
|
||||
}
|
||||
if (nfilled > 0)
|
||||
__writev (fd, bbbody, nfilled);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -246,31 +293,31 @@ write_bb_counts (fd)
|
||||
void
|
||||
_mcleanup ()
|
||||
{
|
||||
struct gmon_hdr ghdr;
|
||||
struct gmon_hdr ghdr __attribute__ ((aligned (__alignof__ (int))));
|
||||
int fd;
|
||||
|
||||
moncontrol(0);
|
||||
fd = open("gmon.out", O_CREAT|O_TRUNC|O_WRONLY, 0666);
|
||||
moncontrol (0);
|
||||
fd = __open ("gmon.out", O_CREAT|O_TRUNC|O_WRONLY, 0666);
|
||||
if (fd < 0)
|
||||
{
|
||||
perror("_mcleanup: gmon.out");
|
||||
perror ("_mcleanup: gmon.out");
|
||||
return;
|
||||
}
|
||||
|
||||
/* write gmon.out header: */
|
||||
memset(&ghdr, 0, sizeof(ghdr));
|
||||
memcpy(&ghdr.cookie[0], GMON_MAGIC, sizeof(ghdr.cookie));
|
||||
ghdr.version = GMON_VERSION;
|
||||
write(fd, &ghdr, sizeof(ghdr));
|
||||
memset (&ghdr, 0, sizeof (struct gmon_hdr));
|
||||
memcpy (&ghdr.cookie[0], GMON_MAGIC, sizeof (ghdr.cookie));
|
||||
*(int *) ghdr.version = GMON_VERSION;
|
||||
__write (fd, &ghdr, sizeof (struct gmon_hdr));
|
||||
|
||||
/* write PC histogram: */
|
||||
write_hist(fd);
|
||||
write_hist (fd);
|
||||
|
||||
/* write call-graph: */
|
||||
write_call_graph(fd);
|
||||
write_call_graph (fd);
|
||||
|
||||
/* write basic-block execution counts: */
|
||||
write_bb_counts(fd);
|
||||
write_bb_counts (fd);
|
||||
|
||||
close(fd);
|
||||
__close (fd);
|
||||
}
|
||||
|
||||
+27
-21
@@ -1,4 +1,4 @@
|
||||
/* Copyright (C) 1996 Free Software Foundation, Inc.
|
||||
/* Copyright (C) 1996, 1997 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
Contributed by David Mosberger <davidm@cs.arizona.edu>.
|
||||
|
||||
@@ -40,30 +40,36 @@ __BEGIN_DECLS
|
||||
* always comes first in gmon.out and is then followed by a series
|
||||
* records defined below.
|
||||
*/
|
||||
struct gmon_hdr {
|
||||
char cookie[4];
|
||||
int version;
|
||||
int spare[3];
|
||||
};
|
||||
struct gmon_hdr
|
||||
{
|
||||
char cookie[4];
|
||||
char version[4];
|
||||
char spare[3 * 4];
|
||||
};
|
||||
|
||||
/* types of records in this file: */
|
||||
typedef enum {
|
||||
GMON_TAG_TIME_HIST = 0, GMON_TAG_CG_ARC = 1, GMON_TAG_BB_COUNT = 2
|
||||
} GMON_Record_Tag;
|
||||
typedef enum
|
||||
{
|
||||
GMON_TAG_TIME_HIST = 0,
|
||||
GMON_TAG_CG_ARC = 1,
|
||||
GMON_TAG_BB_COUNT = 2
|
||||
} GMON_Record_Tag;
|
||||
|
||||
struct gmon_hist_hdr {
|
||||
unsigned long low_pc; /* base pc address of sample buffer */
|
||||
unsigned long high_pc; /* max pc address of sampled buffer */
|
||||
int hist_size; /* size of sample buffer */
|
||||
int prof_rate; /* profiling clock rate */
|
||||
char dimen[15]; /* phys. dim., usually "seconds" */
|
||||
char dimen_abbrev; /* usually 's' for "seconds" */
|
||||
};
|
||||
struct gmon_hist_hdr
|
||||
{
|
||||
char low_pc[sizeof (char *)]; /* base pc address of sample buffer */
|
||||
char high_pc[sizeof (char *)]; /* max pc address of sampled buffer */
|
||||
char hist_size[4]; /* size of sample buffer */
|
||||
char prof_rate[4]; /* profiling clock rate */
|
||||
char dimen[15]; /* phys. dim., usually "seconds" */
|
||||
char dimen_abbrev; /* usually 's' for "seconds" */
|
||||
};
|
||||
|
||||
struct gmon_cg_arc_record {
|
||||
unsigned long from_pc; /* address within caller's body */
|
||||
unsigned long self_pc; /* address within callee's body */
|
||||
int count; /* number of arc traversals */
|
||||
struct gmon_cg_arc_record
|
||||
{
|
||||
char from_pc[sizeof (char *)]; /* address within caller's body */
|
||||
char self_pc[sizeof (char *)]; /* address within callee's body */
|
||||
char count[4]; /* number of arc traversals */
|
||||
};
|
||||
|
||||
__END_DECLS
|
||||
|
||||
+58
-18
@@ -1,35 +1,75 @@
|
||||
/* Copyright (C) 1991, 1996 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
/* Copyright (C) 1991, 1996, 1997 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 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.
|
||||
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., 675 Mass Ave,
|
||||
Cambridge, MA 02139, USA. */
|
||||
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 <grp.h>
|
||||
#include <stdio.h>
|
||||
#include <libc-lock.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
|
||||
/* We need to protect the dynamic buffer handling. */
|
||||
__libc_lock_define_initialized (static, lock);
|
||||
|
||||
/* Read one entry from the given stream. */
|
||||
struct group *
|
||||
fgetgrent (FILE *stream)
|
||||
{
|
||||
static char buffer[BUFSIZ];
|
||||
static char *buffer;
|
||||
static size_t buffer_size;
|
||||
static struct group resbuf;
|
||||
struct group *result;
|
||||
int save;
|
||||
|
||||
if (__fgetgrent_r (stream, &resbuf, buffer, sizeof buffer, &result) != 0)
|
||||
return NULL;
|
||||
/* Get lock. */
|
||||
__libc_lock_lock (lock);
|
||||
|
||||
/* Allocate buffer if not yet available. */
|
||||
if (buffer == NULL)
|
||||
{
|
||||
buffer_size = NSS_BUFLEN_GROUP;
|
||||
buffer = malloc (buffer_size);
|
||||
}
|
||||
|
||||
while (buffer != NULL
|
||||
&& __fgetgrent_r (stream, &resbuf, buffer, buffer_size, &result) != 0
|
||||
&& errno == ERANGE)
|
||||
{
|
||||
char *new_buf;
|
||||
buffer_size += NSS_BUFLEN_GROUP;
|
||||
new_buf = realloc (buffer, buffer_size);
|
||||
if (new_buf == NULL)
|
||||
{
|
||||
/* We are out of memory. Free the current buffer so that the
|
||||
process gets a chance for a normal termination. */
|
||||
save = errno;
|
||||
free (buffer);
|
||||
__set_errno (save);
|
||||
}
|
||||
buffer = new_buf;
|
||||
}
|
||||
|
||||
if (buffer == NULL)
|
||||
result = NULL;
|
||||
|
||||
/* Release lock. Preserve error value. */
|
||||
save = errno;
|
||||
__libc_lock_unlock (lock);
|
||||
__set_errno (save);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
+12
-3
@@ -1,4 +1,4 @@
|
||||
/* Copyright (C) 1991, 1996 Free Software Foundation, Inc.
|
||||
/* Copyright (C) 1991, 1996, 1997 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
|
||||
@@ -56,6 +56,7 @@ __fgetgrent_r (FILE *stream, struct group *resbuf, char *buffer, size_t buflen,
|
||||
struct group **result)
|
||||
{
|
||||
char *p;
|
||||
int parse_result;
|
||||
|
||||
do
|
||||
{
|
||||
@@ -69,10 +70,18 @@ __fgetgrent_r (FILE *stream, struct group *resbuf, char *buffer, size_t buflen,
|
||||
/* Skip leading blanks. */
|
||||
while (isspace (*p))
|
||||
++p;
|
||||
} while (*p == '\0' || *p == '#' || /* Ignore empty and comment lines. */
|
||||
} 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_line (p, resbuf, (void *) buffer, buflen));
|
||||
|| ! (parse_result = parse_line (p, resbuf,
|
||||
(void *) buffer, buflen)));
|
||||
|
||||
if (parse_result == -1)
|
||||
{
|
||||
/* The parser ran out of space. */
|
||||
*result = NULL;
|
||||
return errno;
|
||||
}
|
||||
|
||||
*result = resbuf;
|
||||
return 0;
|
||||
|
||||
+15
-15
@@ -1,21 +1,21 @@
|
||||
/* Copyright (C) 1996 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
Contributed by Ulrich Drepper <drepper@cygnus.com>, 1996.
|
||||
/* Copyright (C) 1996, 1997 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 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.
|
||||
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. */
|
||||
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 <grp.h>
|
||||
|
||||
|
||||
+15
-15
@@ -1,21 +1,21 @@
|
||||
/* Copyright (C) 1996 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
Contributed by Ulrich Drepper <drepper@cygnus.com>, 1996.
|
||||
/* Copyright (C) 1996, 1997 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 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.
|
||||
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. */
|
||||
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 <grp.h>
|
||||
|
||||
|
||||
+15
-15
@@ -1,21 +1,21 @@
|
||||
/* Copyright (C) 1996 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
Contributed by Ulrich Drepper <drepper@cygnus.com>, 1996.
|
||||
/* Copyright (C) 1996, 1997 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 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.
|
||||
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. */
|
||||
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 <grp.h>
|
||||
|
||||
|
||||
+15
-15
@@ -1,21 +1,21 @@
|
||||
/* Copyright (C) 1996 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
Contributed by Ulrich Drepper <drepper@cygnus.com>, 1996.
|
||||
/* Copyright (C) 1996, 1997 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 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.
|
||||
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. */
|
||||
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 <grp.h>
|
||||
|
||||
|
||||
+15
-15
@@ -1,21 +1,21 @@
|
||||
/* Copyright (C) 1996 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
Contributed by Ulrich Drepper <drepper@cygnus.com>, 1996.
|
||||
/* Copyright (C) 1996, 1997 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 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.
|
||||
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. */
|
||||
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 <grp.h>
|
||||
|
||||
|
||||
+15
-15
@@ -1,21 +1,21 @@
|
||||
/* Copyright (C) 1996 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
Contributed by Ulrich Drepper <drepper@cygnus.com>, 1996.
|
||||
/* Copyright (C) 1996, 1997 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 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.
|
||||
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. */
|
||||
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 <grp.h>
|
||||
|
||||
|
||||
@@ -32,9 +32,6 @@ __BEGIN_DECLS
|
||||
#define __need_size_t
|
||||
#include <stddef.h>
|
||||
|
||||
#define __need_size_t
|
||||
#include <stddef.h>
|
||||
|
||||
|
||||
/* The group structure. */
|
||||
struct group
|
||||
|
||||
+1
-1
@@ -73,7 +73,7 @@ include ../Rules
|
||||
# from $(subdirs), and this rule arranges for the headers in question
|
||||
# to get installed.
|
||||
sunrpc-headers = netdb.h pmap_prot.h xdr.h types.h auth.h \
|
||||
rpc_msg.h auth_unix.h
|
||||
rpc_msg.h auth_unix.h clnt.h
|
||||
installed-sunrpc-headers = $(addprefix $(inst_includedir)/rpc/, \
|
||||
$(sunrpc-headers))
|
||||
install-headers-nosubdir: $(installed-sunrpc-headers)
|
||||
|
||||
+14
-14
@@ -1,20 +1,20 @@
|
||||
/* Copyright (C) 1994, 1995, 1996 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
/* Copyright (C) 1994, 1995, 1996, 1997 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 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.
|
||||
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., 675 Mass Ave,
|
||||
Cambridge, MA 02139, USA. */
|
||||
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 <hurd.h>
|
||||
#include <hurd/fd.h>
|
||||
|
||||
+14
-14
@@ -1,20 +1,20 @@
|
||||
/* Copyright (C) 1994, 1995, 1996 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
/* Copyright (C) 1994, 1995, 1996, 1997 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 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.
|
||||
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., 675 Mass Ave,
|
||||
Cambridge, MA 02139, USA. */
|
||||
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 <mach/exc_server.h>
|
||||
#include <hurd/signal.h>
|
||||
|
||||
+15
-15
@@ -1,21 +1,21 @@
|
||||
/* _hurd_ctty_input -- Do an input RPC and generate SIGTTIN if necessary.
|
||||
Copyright (C) 1995 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
Copyright (C) 1995, 1997 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 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.
|
||||
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., 675 Mass Ave,
|
||||
Cambridge, MA 02139, USA. */
|
||||
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 <hurd.h>
|
||||
#include <hurd/signal.h>
|
||||
@@ -52,7 +52,7 @@ _hurd_ctty_input (io_t port, io_t ctty, error_t (*rpc) (io_t))
|
||||
if (err == EBACKGROUND)
|
||||
{
|
||||
/* Send a SIGTTIN signal to our process group.
|
||||
|
||||
|
||||
We must remember here not to clobber ERR, since
|
||||
the loop condition below uses it to recall that
|
||||
we should retry after a stop. */
|
||||
|
||||
+15
-15
@@ -1,21 +1,21 @@
|
||||
/* _hurd_ctty_output -- Do an output RPC and generate SIGTTOU if necessary.
|
||||
Copyright (C) 1995 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
Copyright (C) 1995, 1997 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 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.
|
||||
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., 675 Mass Ave,
|
||||
Cambridge, MA 02139, USA. */
|
||||
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 <hurd.h>
|
||||
#include <hurd/signal.h>
|
||||
@@ -57,7 +57,7 @@ _hurd_ctty_output (io_t port, io_t ctty, error_t (*rpc) (io_t))
|
||||
else
|
||||
{
|
||||
/* Send a SIGTTOU signal to our process group.
|
||||
|
||||
|
||||
We must remember here not to clobber ERR, since
|
||||
the loop condition below uses it to recall that
|
||||
we should retry after a stop. */
|
||||
|
||||
+14
-14
@@ -1,20 +1,20 @@
|
||||
/* Copyright (C) 1991, 1992, 1993, 1994, 1995, 1996 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
/* Copyright (C) 1991, 92, 93, 94, 95, 96, 97 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 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.
|
||||
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., 675 Mass Ave,
|
||||
Cambridge, MA 02139, USA. */
|
||||
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 <ansidecl.h>
|
||||
#include <hurd.h>
|
||||
|
||||
+22
-17
@@ -1,22 +1,21 @@
|
||||
/* Copyright (C) 1991, 92, 93, 94, 95, 96 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
/* Copyright (C) 1991, 92, 93, 94, 95, 96, 97 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 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.
|
||||
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., 675 Mass Ave,
|
||||
Cambridge, MA 02139, USA. */
|
||||
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 <ansidecl.h>
|
||||
#include <unistd.h>
|
||||
#include <hurd.h>
|
||||
#include <hurd/fd.h>
|
||||
@@ -24,7 +23,7 @@ Cambridge, MA 02139, USA. */
|
||||
|
||||
/* Change the current root directory to FD. */
|
||||
int
|
||||
DEFUN(fchroot, (fd), int fd)
|
||||
fchroot (int fd)
|
||||
{
|
||||
error_t err;
|
||||
file_t dir;
|
||||
@@ -36,7 +35,13 @@ DEFUN(fchroot, (fd), int fd)
|
||||
}));
|
||||
|
||||
if (! err)
|
||||
_hurd_port_set (&_hurd_ports[INIT_PORT_CRDIR], dir);
|
||||
{
|
||||
file_t root;
|
||||
err = __file_reparent (dir, MACH_PORT_NULL, &root);
|
||||
__mach_port_deallocate (__mach_task_self (), dir);
|
||||
if (! err)
|
||||
_hurd_port_set (&_hurd_ports[INIT_PORT_CRDIR], root);
|
||||
}
|
||||
|
||||
return err ? __hurd_fail (err) : 0;
|
||||
}
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user