mirror of
git://sourceware.org/git/glibc.git
synced 2026-09-09 05:59:27 +08:00
Compare commits
17
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
779ae82ecd | ||
|
|
a12ea214db | ||
|
|
47f13fd4ba | ||
|
|
b4012b7542 | ||
|
|
406f977a5a | ||
|
|
db9d4d768f | ||
|
|
29bb8719cf | ||
|
|
307bcd7783 | ||
|
|
dd33e89fb2 | ||
|
|
7799b7b335 | ||
|
|
9d8067d8f2 | ||
|
|
6355131153 | ||
|
|
c131718ccc | ||
|
|
26dee9c49c | ||
|
|
fe7bdd630f | ||
|
|
22d57dd369 | ||
|
|
5929563ff2 |
@@ -14,6 +14,10 @@ gpl2lgpl.sed
|
||||
distinfo
|
||||
distinfo
|
||||
|
||||
analysis
|
||||
docs
|
||||
|
||||
crypt
|
||||
linuxthreads
|
||||
localedata
|
||||
secure_rpc
|
||||
|
||||
@@ -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?''
|
||||
@@ -636,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:
|
||||
@@ -644,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
|
||||
|
||||
@@ -118,8 +118,8 @@ foo:=$(shell echo '+out=$(+out)' >&2; echo foofoo >&2)
|
||||
$(+sysdeps)
|
||||
foo:=$(shell echo 'made +tsrcs=$(+tsrcs)'>&2)
|
||||
foo:=$(shell echo generated='$(generated)' >&2)
|
||||
generated := $(sort $(generated) $(generated:.S=.c) $(generated:.s=.c))
|
||||
foo:=$(shell echo now generated='$(generated)' >&2)
|
||||
#generated := $(sort $(generated) $(generated:.S=.c) $(generated:.s=.c))
|
||||
#foo:=$(shell echo now generated='$(generated)' >&2)
|
||||
+tsrcs := $(sort $(filter-out $(generated),$(+tsrcs)))
|
||||
foo:=$(shell echo '+tsrcs=$(+tsrcs)'>&2)
|
||||
foo:=$(shell echo foobie, dammit! >&2)
|
||||
@@ -195,9 +195,9 @@ dist.tar: README $(tardir) $(+tsrcs)
|
||||
|
||||
$(tardir).tar: dist.tar subdir_dist
|
||||
@echo Files listed here have names exceeding 14 chars.
|
||||
tar xfv $< -C /tmp | sed -n '/[^/]\{15,\}/p'
|
||||
tar covf $@ -C /tmp $(tardir)
|
||||
-rm -fr /tmp/$(tardir) dist.tar &
|
||||
tar xfv $< -C $${TMPDIR-/tmp} | sed -n '/[^/]\{15,\}/p'
|
||||
tar covf $@ -C $${TMPDIR-/tmp} $(tardir)
|
||||
-rm -fr $${TMPDIR-/tmp}/$(tardir) dist.tar &
|
||||
|
||||
%.Z: %
|
||||
compress -c $< > $@
|
||||
|
||||
+18
-9
@@ -318,13 +318,28 @@ ifndef asm-CPPFLAGS
|
||||
asm-CPPFLAGS =
|
||||
endif
|
||||
|
||||
# Installed name of the startup code.
|
||||
ifneq ($(elf),yes)
|
||||
# When not using ELF, there is just one startfile, called crt0.o.
|
||||
start-installed-name = crt0.o
|
||||
else
|
||||
# In the ELF universe, crt0.o is called crt1.o, and there are
|
||||
# some additional bizarre files.
|
||||
start-installed-name = crt1.o
|
||||
have-initfini = yes
|
||||
endif
|
||||
|
||||
|
||||
# Command for linking programs with the C library.
|
||||
ifndef +link
|
||||
+link = $(CC) -nostdlib -nostartfiles -o $@ \
|
||||
$(sysdep-LDFLAGS) $(config-LDFLAGS) $(LDFLAGS) \
|
||||
$(addprefix $(csu-objpfx),start.o) $(+preinit) $(+prector) \
|
||||
$(filter-out $(addprefix $(csu-objpfx),start.o) $(+preinit) \
|
||||
$(link-extra-libs) $(common-objpfx)libc% $(+postinit),$^) \
|
||||
$(addprefix $(csu-objpfx),$(start-installed-name)) \
|
||||
$(+preinit) $(+prector) \
|
||||
$(filter-out $(addprefix $(csu-objpfx),start.o \
|
||||
$(start-installed-name))\
|
||||
$(+preinit) $(link-extra-libs) \
|
||||
$(common-objpfx)libc% $(+postinit),$^) \
|
||||
$(link-extra-libs) $(link-libc) $(+postctor) $(+postinit)
|
||||
endif
|
||||
ifndef config-LDFLAGS
|
||||
@@ -536,12 +551,6 @@ endif
|
||||
ifndef BUILD_CC
|
||||
BUILD_CC = $(CC)
|
||||
endif
|
||||
|
||||
ifneq ($(BUILD_CC),$(CC))
|
||||
cross-compiling := yes
|
||||
else
|
||||
cross-compiling := no
|
||||
endif
|
||||
|
||||
# Figure out the version numbers from version.h.
|
||||
|
||||
|
||||
@@ -280,10 +280,12 @@ parent_echo-distinfo:
|
||||
$(addprefix +nodist+,$(generated))
|
||||
|
||||
|
||||
.PHONY: parent-tests
|
||||
tests: parent-tests
|
||||
|
||||
# Run a test on the header files we use.
|
||||
tests: $(objpfx)isomac
|
||||
$(objpfx)./isomac '$(CC)' '$(+sysdep-includes)' \
|
||||
>$(common-objpfx)isomac.out
|
||||
parent-tests: $(objpfx)isomac
|
||||
$(dir $<)$(notdir $<) '$(CC)' '$(+sysdep-includes)' > $<.out
|
||||
|
||||
$(objpfx)isomac: isomac.c
|
||||
$(native-compile)
|
||||
@@ -313,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)
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
Open jobs for finishing GNU libc:
|
||||
---------------------------------
|
||||
Status: March 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>
|
||||
@@ -57,36 +57,12 @@ contact <bug-glibc@prep.ai.mit.edu>
|
||||
[ 7] Several math functions have to be written:
|
||||
|
||||
- exp2
|
||||
- log2
|
||||
|
||||
each with float, double, and long double arguments. Writing these
|
||||
functions should be possible when following the implementation of
|
||||
the existing exp/log functions for other bases.
|
||||
each with float, double, and long double arguments.
|
||||
|
||||
Beside this most of the complex math functions which are new in
|
||||
ISO C 9X. gcc already has support for numbers of complex type so the
|
||||
implementation should be possible today. I mention here the names
|
||||
and the way to write them (argument is z = x + iy):
|
||||
|
||||
- cexp(z) = e^x (cos y + i sin y)
|
||||
- sin(z) = 1/(2i) (e^(iz) - e^-(iz)) = sin(x) cosh(y) + i cos(x) sinh(y)
|
||||
- cos(z) = 1/2 (e^(iz) + e^-(iz)) = cos(x) cosh(y) - i sin(x) sinh(y)
|
||||
- tan(z) = 1/i (e^(iz) - e^-(iz))/(e^(iz) + e^-(iz))
|
||||
- cot(z) = i (e^(iz) + e^-(iz))/(e^(iz) - e^-(iz))
|
||||
- asin(z) = -i ln(iz + sqrt(1-z^2))
|
||||
- acos(z) = -i ln(z + sqrt(z^2-1))
|
||||
- atan(z) = 1/(2i) ln((1+iz)/(1-iz))
|
||||
- acot(z) = -1/(2i) ln((iz+1)/(iz-1))
|
||||
- sinh(z) = 1/2 (e^z - e^-z)
|
||||
- cosh(z) = 1/2 (e^z + e^-z)
|
||||
- tanh(z) = (e^z - e^-z)/(e^z + e^-z)
|
||||
- coth(z) = (e^z + e^-z)/(e^z - e^-z)
|
||||
|
||||
All functions should we written with all the parallelism in mind.
|
||||
And assembler versions are highly expreciated since, e.g., the ix87
|
||||
FPU provides an `fsincos' instructions which is certainly useful for
|
||||
the `sin' function. The implementations for the normal math functions
|
||||
shows other optimization techniques.
|
||||
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
|
||||
@@ -134,7 +110,9 @@ contact <bug-glibc@prep.ai.mit.edu>
|
||||
+ 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.
|
||||
|
||||
@@ -143,3 +121,14 @@ contact <bug-glibc@prep.ai.mit.edu>
|
||||
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!
|
||||
|
||||
@@ -157,7 +157,7 @@ __argp_fmtstream_update (argp_fmtstream_t fs)
|
||||
the end of the buffer. */
|
||||
nl = fs->p;
|
||||
}
|
||||
else if (fs->point_col + (nl - buf) < fs->rmargin)
|
||||
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. */
|
||||
@@ -309,7 +309,7 @@ __argp_fmtstream_update (argp_fmtstream_t fs)
|
||||
int
|
||||
__argp_fmtstream_ensure (struct argp_fmtstream *fs, size_t amount)
|
||||
{
|
||||
if (fs->end - fs->p < amount)
|
||||
if ((size_t) (fs->end - fs->p) < amount)
|
||||
{
|
||||
ssize_t wrote;
|
||||
|
||||
@@ -330,7 +330,7 @@ __argp_fmtstream_ensure (struct argp_fmtstream *fs, size_t amount)
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (fs->end - fs->buf < amount)
|
||||
if ((size_t) (fs->end - fs->buf) < amount)
|
||||
/* Gotta grow the buffer. */
|
||||
{
|
||||
size_t new_size = fs->end - fs->buf + amount;
|
||||
@@ -354,7 +354,7 @@ __argp_fmtstream_ensure (struct argp_fmtstream *fs, size_t amount)
|
||||
ssize_t
|
||||
__argp_fmtstream_printf (struct argp_fmtstream *fs, const char *fmt, ...)
|
||||
{
|
||||
size_t out;
|
||||
int out;
|
||||
size_t size_guess = PRINTF_SIZE_GUESS; /* How much space to reserve. */
|
||||
|
||||
do
|
||||
|
||||
@@ -238,7 +238,7 @@ ARGP_FS_EI size_t
|
||||
__argp_fmtstream_set_lmargin (argp_fmtstream_t __fs, size_t __lmargin)
|
||||
{
|
||||
size_t __old;
|
||||
if (__fs->p - __fs->buf > __fs->point_offs)
|
||||
if ((size_t) (__fs->p - __fs->buf) > __fs->point_offs)
|
||||
__argp_fmtstream_update (__fs);
|
||||
__old = __fs->lmargin;
|
||||
__fs->lmargin = __lmargin;
|
||||
@@ -250,7 +250,7 @@ ARGP_FS_EI size_t
|
||||
__argp_fmtstream_set_rmargin (argp_fmtstream_t __fs, size_t __rmargin)
|
||||
{
|
||||
size_t __old;
|
||||
if (__fs->p - __fs->buf > __fs->point_offs)
|
||||
if ((size_t) (__fs->p - __fs->buf) > __fs->point_offs)
|
||||
__argp_fmtstream_update (__fs);
|
||||
__old = __fs->rmargin;
|
||||
__fs->rmargin = __rmargin;
|
||||
@@ -262,7 +262,7 @@ ARGP_FS_EI size_t
|
||||
__argp_fmtstream_set_wmargin (argp_fmtstream_t __fs, size_t __wmargin)
|
||||
{
|
||||
size_t __old;
|
||||
if (__fs->p - __fs->buf > __fs->point_offs)
|
||||
if ((size_t) (__fs->p - __fs->buf) > __fs->point_offs)
|
||||
__argp_fmtstream_update (__fs);
|
||||
__old = __fs->wmargin;
|
||||
__fs->wmargin = __wmargin;
|
||||
@@ -273,7 +273,7 @@ __argp_fmtstream_set_wmargin (argp_fmtstream_t __fs, size_t __wmargin)
|
||||
ARGP_FS_EI size_t
|
||||
__argp_fmtstream_point (argp_fmtstream_t __fs)
|
||||
{
|
||||
if (__fs->p - __fs->buf > __fs->point_offs)
|
||||
if ((size_t) (__fs->p - __fs->buf) > __fs->point_offs)
|
||||
__argp_fmtstream_update (__fs);
|
||||
return __fs->point_col >= 0 ? __fs->point_col : 0;
|
||||
}
|
||||
|
||||
+3
-3
@@ -1086,14 +1086,14 @@ hol_entry_help (struct hol_entry *entry, const struct argp_state *state,
|
||||
const char *fstr = filter_doc (tstr, real->key, entry->argp, state);
|
||||
if (fstr && *fstr)
|
||||
{
|
||||
unsigned col = __argp_fmtstream_point (stream);
|
||||
unsigned int col = __argp_fmtstream_point (stream);
|
||||
|
||||
__argp_fmtstream_set_lmargin (stream, uparams.opt_doc_col);
|
||||
__argp_fmtstream_set_wmargin (stream, uparams.opt_doc_col);
|
||||
|
||||
if (col > uparams.opt_doc_col + 3)
|
||||
if (col > (unsigned int) (uparams.opt_doc_col + 3))
|
||||
__argp_fmtstream_putc (stream, '\n');
|
||||
else if (col >= uparams.opt_doc_col)
|
||||
else if (col >= (unsigned int) uparams.opt_doc_col)
|
||||
__argp_fmtstream_puts (stream, " ");
|
||||
else
|
||||
indent_to (stream, uparams.opt_doc_col);
|
||||
|
||||
Vendored
+31
-7
@@ -68,8 +68,26 @@ 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 ;;
|
||||
arc64:OpenBSD:*:*)
|
||||
echo mips64el-unknown-openbsd${UNAME_RELEASE}
|
||||
exit 0 ;;
|
||||
arc:OpenBSD:*:*)
|
||||
echo mipsel-unknown-openbsd${UNAME_RELEASE}
|
||||
exit 0 ;;
|
||||
hkmips:OpenBSD:*:*)
|
||||
echo mips-unknown-openbsd${UNAME_RELEASE}
|
||||
exit 0 ;;
|
||||
pmax:OpenBSD:*:*)
|
||||
echo mipsel-unknown-openbsd${UNAME_RELEASE}
|
||||
exit 0 ;;
|
||||
sgi:OpenBSD:*:*)
|
||||
echo mips-unknown-openbsd${UNAME_RELEASE}
|
||||
exit 0 ;;
|
||||
wgrisc:OpenBSD:*:*)
|
||||
echo mipsel-unknown-openbsd${UNAME_RELEASE}
|
||||
exit 0 ;;
|
||||
arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*)
|
||||
echo arm-acorn-riscix${UNAME_RELEASE}
|
||||
exit 0;;
|
||||
@@ -118,19 +136,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 +402,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}
|
||||
|
||||
@@ -42,6 +42,7 @@ build-omitfp = @omitfp@
|
||||
build-bounded = @bounded@
|
||||
stdio = @stdio@
|
||||
add-ons = @subdirs@
|
||||
cross-compiling = @cross_compiling@
|
||||
|
||||
# Build tools.
|
||||
CC = @CC@
|
||||
|
||||
@@ -776,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.
|
||||
@@ -793,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 ;;
|
||||
@@ -810,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:814: 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'`"
|
||||
|
||||
@@ -1011,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:1015: 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
|
||||
@@ -1065,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:1069: 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
|
||||
@@ -1090,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:1094: 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
|
||||
@@ -1123,7 +1125,7 @@ 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:1127: checking for $ac_word" >&5
|
||||
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
|
||||
@@ -1152,7 +1154,7 @@ 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:1156: checking for $ac_word" >&5
|
||||
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
|
||||
@@ -1200,7 +1202,7 @@ fi
|
||||
fi
|
||||
|
||||
echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works""... $ac_c" 1>&6
|
||||
echo "configure:1204: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works" >&5
|
||||
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.
|
||||
@@ -1210,11 +1212,11 @@ ac_link='${CC-cc} -o conftest $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS
|
||||
cross_compiling=$ac_cv_prog_cc_cross
|
||||
|
||||
cat > conftest.$ac_ext <<EOF
|
||||
#line 1214 "configure"
|
||||
#line 1216 "configure"
|
||||
#include "confdefs.h"
|
||||
main(){return(0);}
|
||||
EOF
|
||||
if { (eval echo configure:1218: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
|
||||
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
|
||||
@@ -1234,12 +1236,12 @@ 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:1238: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler" >&5
|
||||
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:1243: checking whether we are using GNU C" >&5
|
||||
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
|
||||
@@ -1248,7 +1250,7 @@ else
|
||||
yes;
|
||||
#endif
|
||||
EOF
|
||||
if { ac_try='${CC-cc} -E conftest.c'; { (eval echo configure:1252: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; } | egrep yes >/dev/null 2>&1; then
|
||||
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
|
||||
@@ -1263,7 +1265,7 @@ if test $ac_cv_prog_gcc = yes; then
|
||||
ac_save_CFLAGS="$CFLAGS"
|
||||
CFLAGS=
|
||||
echo $ac_n "checking whether ${CC-cc} accepts -g""... $ac_c" 1>&6
|
||||
echo "configure:1267: checking whether ${CC-cc} accepts -g" >&5
|
||||
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
|
||||
@@ -1290,11 +1292,31 @@ else
|
||||
test "${CFLAGS+set}" = set || CFLAGS="-g"
|
||||
fi
|
||||
|
||||
echo $ac_n "checking build system type""... $ac_c" 1>&6
|
||||
echo "configure:1297: checking build system type" >&5
|
||||
|
||||
build_alias=$build
|
||||
case "$build_alias" in
|
||||
NONE)
|
||||
case $nonopt in
|
||||
NONE) build_alias=$host_alias ;;
|
||||
*) build_alias=$nonopt ;;
|
||||
esac ;;
|
||||
esac
|
||||
|
||||
build=`$ac_config_sub $build_alias`
|
||||
build_cpu=`echo $build | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'`
|
||||
build_vendor=`echo $build | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'`
|
||||
build_os=`echo $build | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'`
|
||||
echo "$ac_t""$build" 1>&6
|
||||
|
||||
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
|
||||
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:1298: 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
|
||||
@@ -1305,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
|
||||
@@ -1319,9 +1341,13 @@ 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:1325: checking how to run the C preprocessor" >&5
|
||||
echo "configure:1351: checking how to run the C preprocessor" >&5
|
||||
# On Suns, sometimes $CPP names a directory.
|
||||
if test -n "$CPP" && test -d "$CPP"; then
|
||||
CPP=
|
||||
@@ -1336,13 +1362,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 1340 "configure"
|
||||
#line 1366 "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:1346: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
|
||||
{ (eval echo configure:1372: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
|
||||
ac_err=`grep -v '^ *+' conftest.out`
|
||||
if test -z "$ac_err"; then
|
||||
:
|
||||
@@ -1353,13 +1379,13 @@ else
|
||||
rm -rf conftest*
|
||||
CPP="${CC-cc} -E -traditional-cpp"
|
||||
cat > conftest.$ac_ext <<EOF
|
||||
#line 1357 "configure"
|
||||
#line 1383 "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:1363: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
|
||||
{ (eval echo configure:1389: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
|
||||
ac_err=`grep -v '^ *+' conftest.out`
|
||||
if test -z "$ac_err"; then
|
||||
:
|
||||
@@ -1381,24 +1407,6 @@ else
|
||||
fi
|
||||
echo "$ac_t""$CPP" 1>&6
|
||||
|
||||
echo $ac_n "checking build system type""... $ac_c" 1>&6
|
||||
echo "configure:1386: checking build system type" >&5
|
||||
|
||||
build_alias=$build
|
||||
case "$build_alias" in
|
||||
NONE)
|
||||
case $nonopt in
|
||||
NONE) build_alias=$host_alias ;;
|
||||
*) build_alias=$nonopt ;;
|
||||
esac ;;
|
||||
esac
|
||||
|
||||
build=`$ac_config_sub $build_alias`
|
||||
build_cpu=`echo $build | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'`
|
||||
build_vendor=`echo $build | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'`
|
||||
build_os=`echo $build | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'`
|
||||
echo "$ac_t""$build" 1>&6
|
||||
|
||||
if test $host != $build; then
|
||||
ac_tool_prefix=${host_alias}-
|
||||
else
|
||||
@@ -1408,7 +1416,7 @@ 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:1412: checking for $ac_word" >&5
|
||||
echo "configure:1420: 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
|
||||
@@ -1439,7 +1447,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:1443: checking for $ac_word" >&5
|
||||
echo "configure:1451: 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
|
||||
@@ -1470,7 +1478,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:1474: checking for $ac_word" >&5
|
||||
echo "configure:1482: 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
|
||||
@@ -1505,7 +1513,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:1509: checking for $ac_word" >&5
|
||||
echo "configure:1517: 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
|
||||
@@ -1546,7 +1554,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:1550: checking for $ac_word" >&5
|
||||
echo "configure:1558: 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
|
||||
@@ -1588,7 +1596,7 @@ fi
|
||||
|
||||
|
||||
echo $ac_n "checking for signed size_t type""... $ac_c" 1>&6
|
||||
echo "configure:1592: checking for signed size_t type" >&5
|
||||
echo "configure:1600: 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
|
||||
@@ -1612,12 +1620,12 @@ EOF
|
||||
fi
|
||||
|
||||
echo $ac_n "checking for libc-friendly stddef.h""... $ac_c" 1>&6
|
||||
echo "configure:1616: checking for libc-friendly stddef.h" >&5
|
||||
echo "configure:1624: 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 1621 "configure"
|
||||
#line 1629 "configure"
|
||||
#include "confdefs.h"
|
||||
#define __need_size_t
|
||||
#define __need_wchar_t
|
||||
@@ -1632,7 +1640,7 @@ size_t size; wchar_t wchar;
|
||||
if (&size == NULL || &wchar == NULL) abort ();
|
||||
; return 0; }
|
||||
EOF
|
||||
if { (eval echo configure:1636: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
|
||||
if { (eval echo configure:1644: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
|
||||
rm -rf conftest*
|
||||
libc_cv_friendly_stddef=yes
|
||||
else
|
||||
@@ -1651,7 +1659,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:1655: checking whether we need to use -P to assemble .S files" >&5
|
||||
echo "configure:1663: 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
|
||||
@@ -1674,7 +1682,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:1678: checking for assembler global-symbol directive" >&5
|
||||
echo "configure:1686: 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
|
||||
@@ -1704,7 +1712,7 @@ EOF
|
||||
fi
|
||||
|
||||
echo $ac_n "checking for .set assembler directive""... $ac_c" 1>&6
|
||||
echo "configure:1708: checking for .set assembler directive" >&5
|
||||
echo "configure:1716: 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
|
||||
@@ -1738,7 +1746,7 @@ EOF
|
||||
fi
|
||||
|
||||
echo $ac_n "checking for .symver assembler directive""... $ac_c" 1>&6
|
||||
echo "configure:1742: checking for .symver assembler directive" >&5
|
||||
echo "configure:1750: 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
|
||||
@@ -1757,7 +1765,7 @@ 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:1761: checking for ld --version-script" >&5
|
||||
echo "configure:1769: 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
|
||||
@@ -1774,7 +1782,7 @@ VERS {
|
||||
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:1778: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; };
|
||||
-Wl,--version-script,conftest.map'; { (eval echo configure:1786: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; };
|
||||
then
|
||||
libc_cv_ld_version_script_option=yes
|
||||
else
|
||||
@@ -1804,7 +1812,7 @@ fi
|
||||
|
||||
if test $elf = yes; then
|
||||
echo $ac_n "checking for .previous assembler directive""... $ac_c" 1>&6
|
||||
echo "configure:1808: checking for .previous assembler directive" >&5
|
||||
echo "configure:1816: 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
|
||||
@@ -1812,7 +1820,7 @@ else
|
||||
.section foo_section
|
||||
.previous
|
||||
EOF
|
||||
if { ac_try='${CC-cc} -c $CFLAGS conftest.s 1>&5'; { (eval echo configure:1816: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; }; then
|
||||
if { ac_try='${CC-cc} -c $CFLAGS conftest.s 1>&5'; { (eval echo configure:1824: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; }; then
|
||||
libc_cv_asm_previous_directive=yes
|
||||
else
|
||||
libc_cv_asm_previous_directive=no
|
||||
@@ -1828,7 +1836,7 @@ EOF
|
||||
|
||||
else
|
||||
echo $ac_n "checking for .popsection assembler directive""... $ac_c" 1>&6
|
||||
echo "configure:1832: checking for .popsection assembler directive" >&5
|
||||
echo "configure:1840: 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
|
||||
@@ -1836,7 +1844,7 @@ else
|
||||
.pushsection foo_section
|
||||
.popsection
|
||||
EOF
|
||||
if { ac_try='${CC-cc} -c $CFLAGS conftest.s 1>&5'; { (eval echo configure:1840: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; }; then
|
||||
if { ac_try='${CC-cc} -c $CFLAGS conftest.s 1>&5'; { (eval echo configure:1848: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; }; then
|
||||
libc_cv_asm_popsection_directive=yes
|
||||
else
|
||||
libc_cv_asm_popsection_directive=no
|
||||
@@ -1856,12 +1864,12 @@ fi
|
||||
|
||||
if test $elf != yes; then
|
||||
echo $ac_n "checking for .init and .fini sections""... $ac_c" 1>&6
|
||||
echo "configure:1860: checking for .init and .fini sections" >&5
|
||||
echo "configure:1868: 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 1865 "configure"
|
||||
#line 1873 "configure"
|
||||
#include "confdefs.h"
|
||||
|
||||
int main() {
|
||||
@@ -1870,7 +1878,7 @@ asm (".section .init");
|
||||
asm (".text");
|
||||
; return 0; }
|
||||
EOF
|
||||
if { (eval echo configure:1874: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
|
||||
if { (eval echo configure:1882: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
|
||||
rm -rf conftest*
|
||||
libc_cv_have_initfini=yes
|
||||
else
|
||||
@@ -1895,19 +1903,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:1899: checking for _ prefix on C symbol names" >&5
|
||||
echo "configure:1907: 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 1904 "configure"
|
||||
#line 1912 "configure"
|
||||
#include "confdefs.h"
|
||||
asm ("_glibc_foobar:");
|
||||
int main() {
|
||||
glibc_foobar ();
|
||||
; return 0; }
|
||||
EOF
|
||||
if { (eval echo configure:1911: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
|
||||
if { (eval echo configure:1919: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
|
||||
rm -rf conftest*
|
||||
libc_cv_asm_underscores=yes
|
||||
else
|
||||
@@ -1934,7 +1942,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:1938: checking for assembler .weak directive" >&5
|
||||
echo "configure:1946: 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
|
||||
@@ -1957,7 +1965,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:1961: checking for assembler .weakext directive" >&5
|
||||
echo "configure:1969: 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
|
||||
@@ -1994,7 +2002,7 @@ EOF
|
||||
fi
|
||||
|
||||
echo $ac_n "checking for ld --no-whole-archive""... $ac_c" 1>&6
|
||||
echo "configure:1998: checking for ld --no-whole-archive" >&5
|
||||
echo "configure:2006: 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
|
||||
@@ -2005,7 +2013,7 @@ __throw () {}
|
||||
EOF
|
||||
if { ac_try='${CC-cc} $CFLAGS
|
||||
-nostdlib -nostartfiles -Wl,--no-whole-archive
|
||||
-o conftest conftest.c'; { (eval echo configure:2009: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; }; then
|
||||
-o conftest conftest.c'; { (eval echo configure:2017: \"$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
|
||||
@@ -2016,7 +2024,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:2020: checking for gcc -fno-exceptions" >&5
|
||||
echo "configure:2028: 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
|
||||
@@ -2027,7 +2035,7 @@ __throw () {}
|
||||
EOF
|
||||
if { ac_try='${CC-cc} $CFLAGS
|
||||
-nostdlib -nostartfiles -fno-exceptions
|
||||
-o conftest conftest.c'; { (eval echo configure:2031: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; }; then
|
||||
-o conftest conftest.c'; { (eval echo configure:2039: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; }; then
|
||||
libc_cv_gcc_no_exceptions=yes
|
||||
else
|
||||
libc_cv_gcc_no_exceptions=no
|
||||
@@ -2079,7 +2087,7 @@ if test "$uname" = generic; then
|
||||
fi
|
||||
|
||||
echo $ac_n "checking OS release for uname""... $ac_c" 1>&6
|
||||
echo "configure:2083: checking OS release for uname" >&5
|
||||
echo "configure:2091: 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
|
||||
@@ -2101,7 +2109,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:2105: checking OS version for uname" >&5
|
||||
echo "configure:2113: 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
|
||||
@@ -2123,7 +2131,7 @@ else
|
||||
fi
|
||||
|
||||
echo $ac_n "checking stdio selection""... $ac_c" 1>&6
|
||||
echo "configure:2127: checking stdio selection" >&5
|
||||
echo "configure:2135: checking stdio selection" >&5
|
||||
|
||||
case $stdio in
|
||||
libio) cat >> confdefs.h <<\EOF
|
||||
@@ -2329,13 +2337,14 @@ s%@INSTALL_DATA@%$INSTALL_DATA%g
|
||||
s%@LN_S@%$LN_S%g
|
||||
s%@MSGFMT@%$MSGFMT%g
|
||||
s%@CC@%$CC%g
|
||||
s%@BUILD_CC@%$BUILD_CC%g
|
||||
s%@CPP@%$CPP%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%@BUILD_CC@%$BUILD_CC%g
|
||||
s%@cross_compiling@%$cross_compiling%g
|
||||
s%@CPP@%$CPP%g
|
||||
s%@AR@%$AR%g
|
||||
s%@RANLIB@%$RANLIB%g
|
||||
s%@BASH@%$BASH%g
|
||||
|
||||
+6
-2
@@ -119,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.
|
||||
@@ -138,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 ;;
|
||||
@@ -360,9 +362,11 @@ AC_PROG_LN_S
|
||||
AC_CHECK_PROGS(MSGFMT, msgfmt gmsgfmt, :)
|
||||
|
||||
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_SUBST(cross_compiling)
|
||||
AC_PROG_CPP
|
||||
AC_CHECK_TOOL(AR, ar)
|
||||
AC_CHECK_TOOL(RANLIB, ranlib, :)
|
||||
|
||||
+39
-37
@@ -1,6 +1,6 @@
|
||||
# Makefile for csu code for GNU C library.
|
||||
|
||||
# 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
|
||||
@@ -36,27 +36,14 @@ omit-deps = $(patsubst %.o,%,$(start-installed-name) g$(start-installed-name) \
|
||||
$(csu-dummies))
|
||||
install-lib = $(start-installed-name) g$(start-installed-name) \
|
||||
$(csu-dummies)
|
||||
distribute = initfini.c gmon-start.c start.c
|
||||
distribute = initfini.c gmon-start.c start.c defs.awk abi-note.S abi-tag.h
|
||||
|
||||
all: # Make this the default target; it will be defined in Rules.
|
||||
|
||||
include ../Makeconfig
|
||||
|
||||
ifneq ($(elf),yes)
|
||||
|
||||
# When not using ELF, there is just one startfile, called crt0.o.
|
||||
start-installed-name = crt0.o
|
||||
|
||||
else
|
||||
|
||||
# In the ELF universe, crt0.o is called crt1.o, and there are
|
||||
# some additional bizarre files.
|
||||
start-installed-name = crt1.o
|
||||
have-initfini = yes
|
||||
|
||||
endif
|
||||
|
||||
ifeq (yes,$(have-initfini))
|
||||
ifeq ($(have-initfini),yes)
|
||||
|
||||
CPPFLAGS += -DHAVE_INITFINI
|
||||
|
||||
@@ -67,45 +54,60 @@ crtstuff = crti crtn
|
||||
|
||||
install-lib += $(crtstuff:=.o)
|
||||
extra-objs += $(crtstuff:=.o)
|
||||
generated += $(crtstuff:=.s)
|
||||
generated += $(crtstuff:=.S) initfini.s align.h end.h
|
||||
omit-deps += $(crtstuff)
|
||||
|
||||
# Compile initfini.c to assembly code, which contains embedded shell
|
||||
# commands that produce crti.s-new and crtn.s-new when run. We need to
|
||||
# disable emission of .size directives and debugging information, since
|
||||
# they will get confused by the splitting of the output we do.
|
||||
$(objpfx)cr%i.s $(objpfx)cr%n.s: initfini.c; $(initfini)
|
||||
# Special rules for the building of crti.o and crtn.o
|
||||
$(objpfx)crt%.o: $(objpfx)crt%.S $(objpfx)defs.h
|
||||
$(CC) -c -fPIC -g0 -I$(..) -I$(common-objpfx) -DASSEMBLER $< -o $@
|
||||
|
||||
define initfini
|
||||
-rm -f $(objpfx)crtcommon.tmp
|
||||
(echo 'cat > crtcommon.tmp <<\EOF_common'; \
|
||||
$(CC) $< $(CPPFLAGS) $(CFLAGS) \
|
||||
-fPIC -finhibit-size-directive $(no-exceptions) -g0 -S -o -; \
|
||||
echo 'EOF_common') | (cd $(@D); $(SHELL))
|
||||
cat $(objpfx)crtcommon.tmp >> $(objpfx)crti.s-new
|
||||
cat $(objpfx)crtcommon.tmp >> $(objpfx)crtn.s-new
|
||||
rm -f $(objpfx)crtcommon.tmp
|
||||
mv -f $(objpfx)crti.s-new $(subst crtn,crti,$@)
|
||||
mv -f $(objpfx)crtn.s-new $(subst crti,crtn,$@)
|
||||
endef
|
||||
$(objpfx)initfini.s: initfini.c
|
||||
$(CC) $(CPPFLAGS) $(CFLAGS) -g0 -S -fPIC -finhibit-size-directive \
|
||||
$(no-exceptions) $< -o $@
|
||||
|
||||
$(objpfx)crti.S: $(objpfx)initfini.s
|
||||
sed -n -e '1,/@HEADER_ENDS/p' \
|
||||
-e '/@_.*_PROLOG_BEGINS/,/@_.*_PROLOG_ENDS/p' \
|
||||
-e '/@TRAILER_BEGINS/,$$p' $< > $@
|
||||
|
||||
$(objpfx)crtn.S: $(objpfx)initfini.s
|
||||
sed -n -e '1,/@HEADER_ENDS/p' \
|
||||
-e '/@_.*_EPILOG_BEGINS/,/@_.*_EPILOG_ENDS/p' \
|
||||
-e '/@TRAILER_BEGINS/,$$p' $< > $@
|
||||
|
||||
$(objpfx)defs.h: $(objpfx)initfini.s
|
||||
sed -n -e '/@TESTS_BEGIN/,/@TESTS_END/p' $< | \
|
||||
awk -f defs.awk > $@
|
||||
|
||||
endif
|
||||
|
||||
include ../Rules
|
||||
|
||||
define link-relocatable
|
||||
$(CC) -nostdlib -nostartfiles -r -o $@ $^
|
||||
endef
|
||||
|
||||
ifndef start-installed-name-rule
|
||||
ifeq (yes,$(elf))
|
||||
# We link the ELF startfile along with a SHT_NOTE section indicating
|
||||
# the the kernel ABI the binaries linked with this library will require.
|
||||
$(objpfx)$(start-installed-name): $(objpfx)start.o $(objpfx)abi-note.o
|
||||
$(link-relocatable)
|
||||
else
|
||||
# The startfile is installed under different names, so we just call our
|
||||
# source file `start.c' and copy to the installed name after compiling.
|
||||
$(objpfx)$(start-installed-name): $(objpfx)start.o
|
||||
-rm -f $@
|
||||
rm -f $@
|
||||
ln $< $@
|
||||
endif
|
||||
endif
|
||||
|
||||
# The profiling startfile is made by linking together the normal
|
||||
# startfile with gmon-start.o, which defines a constructor function
|
||||
# to turn on profiling code at startup.
|
||||
$(objpfx)g$(start-installed-name): $(objpfx)start.o $(objpfx)gmon-start.o
|
||||
$(CC) -nostdlib -nostartfiles -r -o $@ $^
|
||||
$(objpfx)g$(start-installed-name): $(objpfx)$(start-installed-name) \
|
||||
$(objpfx)gmon-start.o
|
||||
$(link-relocatable)
|
||||
|
||||
# These extra files are sometimes expected by system standard linking
|
||||
# procedures, but we have nothing for them to do. So compile empty files.
|
||||
|
||||
@@ -0,0 +1,69 @@
|
||||
/* Special .init and .fini section support.
|
||||
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.
|
||||
|
||||
In addition to the permissions in the GNU Library General Public
|
||||
License, the Free Software Foundation gives you unlimited
|
||||
permission to link the compiled version of this file with other
|
||||
programs, and to distribute those programs without any restriction
|
||||
coming from the use of this file. (The Library General Public
|
||||
License restrictions do apply in other respects; for example, they
|
||||
cover modification of the file, and distribution when not linked
|
||||
into another program.)
|
||||
|
||||
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, 59 Temple Place - Suite 330,
|
||||
Boston, MA 02111-1307, USA. */
|
||||
|
||||
#include <sysdep.h>
|
||||
|
||||
/* The basic layout of note sections is specified by the ELF format. */
|
||||
|
||||
#define ELF_NOTE_BEGIN(sectname, sectflags, type, name) \
|
||||
.section sectname, sectflags; \
|
||||
.align ALIGNARG(2); /* Notes are 4-byte aligned. */ \
|
||||
.long 1f - 0f; /* 32-bit word: length of name field */ \
|
||||
.long 3f - 2f; /* 32-bit word: length of desc field */ \
|
||||
.long (type); /* 32-bit word: vendor-defined type field */ \
|
||||
0: .asciz name; /* null-terminated string, any length: name */\
|
||||
1: .align ALIGNARG(2); /* Name data padded to 4-byte alignment. */ \
|
||||
2: /* Here follows the "note descriptor" data, whose format \
|
||||
is not specified by ELF. The vendor name and type field \
|
||||
indicate what sort of data is found here. */
|
||||
|
||||
#define ELF_NOTE_END \
|
||||
3: .align ALIGNARG(2) /* Pad to 4-byte align the next note. */
|
||||
|
||||
|
||||
/* The linker (GNU ld 2.8 and later) recognize an allocated section whose
|
||||
name begins with `.note' and creates a PT_NOTE program header entry
|
||||
pointing at it.
|
||||
|
||||
Such a program header is the canonical way (at least in the free OS
|
||||
community) to identify the OS environment ABI that the executable was
|
||||
created for. The ELF note information identifies a particular OS or
|
||||
coordinated development effort within which the ELF header's e_machine
|
||||
value plus (for dynamically linked programs) the PT_INTERP dynamic
|
||||
linker name and DT_NEEDED shared library names fully identify the
|
||||
runtime environment required by an executable.
|
||||
|
||||
The GNU project and cooperating development efforts (including the Linux
|
||||
community) use a vendor name string of "GNU", and a note type field with
|
||||
value 1 for a note descriptor that indicates ABI requirements. */
|
||||
|
||||
#include <abi-tag.h> /* OS-specific ABI tag value */
|
||||
|
||||
ELF_NOTE_BEGIN(".note.ABI-tag", "a", 1, "GNU")
|
||||
.long ABI_TAG
|
||||
ELF_NOTE_END
|
||||
@@ -0,0 +1,22 @@
|
||||
/.end/ { need_end = 1 }
|
||||
/.align/ { if($2 > max) max = $2; }
|
||||
|
||||
END {
|
||||
if(need_end)
|
||||
{
|
||||
print "#define END_INIT .end _init";
|
||||
print "#define END_FINI .end _fini";
|
||||
}
|
||||
else
|
||||
{
|
||||
print "#define END_INIT";
|
||||
print "#define END_FINI";
|
||||
}
|
||||
if(max)
|
||||
print "#define ALIGN .align", max;
|
||||
else
|
||||
print "#define ALIGN";
|
||||
|
||||
print "#include <libc-symbols.h>";
|
||||
print "weak_extern (__gmon_start__)";
|
||||
}
|
||||
+47
-79
@@ -1,5 +1,5 @@
|
||||
/* Special .init and .fini section support.
|
||||
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
|
||||
@@ -26,68 +26,40 @@
|
||||
write to the Free Software Foundation, 59 Temple Place - Suite 330,
|
||||
Boston, MA 02111-1307, USA. */
|
||||
|
||||
/* This file is compiled into assembly code which is then surrounded by the
|
||||
lines `cat > crtcommon.tmp <<\EOF_common' and `EOF_common' and thus
|
||||
becomes a shell script which creates three files of assembly code.
|
||||
/* This file is compiled into assembly code which is then munged by a sed
|
||||
script into two files: crti.s and crtn.s.
|
||||
|
||||
* The first file is crti.s-new; this puts a function prologue at the
|
||||
beginning of the .init and .fini sections and defines global symbols for
|
||||
* crti.s puts a function prologue at the beginning of the
|
||||
.init and .fini sections and defines global symbols for
|
||||
those addresses, so they can be called as functions.
|
||||
|
||||
* The second file is crtn.s-new; this puts the corresponding function
|
||||
epilogues in the .init and .fini sections.
|
||||
|
||||
* The third file is crtcommon.tmp, which is whatever miscellaneous cruft
|
||||
the compiler generated at the end; it should be appended to both crti.s-new
|
||||
and crtn.s-new. */
|
||||
* crtn.s puts the corresponding function epilogues
|
||||
in the .init and .fini sections. */
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
/* We use embedded asm for .section unconditionally, as this makes it
|
||||
easier to insert the necessary directives into crtn.S. */
|
||||
#define SECTION(x) asm (".section \"" x "\"");
|
||||
|
||||
#ifdef HAVE_ELF
|
||||
/* These declarations make the functions go in the right sections when
|
||||
we define them below. GCC syntax does not allow the attribute
|
||||
specifications to be in the function definitions themselves. */
|
||||
void _init (void) __attribute__ ((section (".init")));
|
||||
void _fini (void) __attribute__ ((section (".fini")));
|
||||
/* Embed an #include to pull in the alignment and .end directives. */
|
||||
asm ("\n#include \"defs.h\"");
|
||||
|
||||
#define SECTION(x) /* Put nothing extra before the defn. */
|
||||
/* The initial common code ends here. */
|
||||
asm ("\n/*@HEADER_ENDS*/");
|
||||
|
||||
#else
|
||||
/* Some non-ELF systems support .init and .fini sections,
|
||||
but the __attribute__ syntax only works for ELF. */
|
||||
#define SECTION(x) asm (".section " x);
|
||||
#endif
|
||||
|
||||
/* End the here document containing the initial common code.
|
||||
Then move the output file crtcommon.tmp to crti.s-new and crtn.s-new. */
|
||||
asm ("\nEOF_common\n\
|
||||
rm -f crti.s-new crtn.s-new\n\
|
||||
mv crtcommon.tmp crti.s-new\n\
|
||||
cp crti.s-new crtn.s-new");
|
||||
|
||||
/* Extract a `.end' if one is produced by the compiler. */
|
||||
asm ("fgrep .end >/dev/null 2>&1 <<\\EOF.end && need_end=yes");
|
||||
/* To determine whether we need .end and .align: */
|
||||
asm ("\n/*@TESTS_BEGIN*/");
|
||||
void
|
||||
useless_function (void)
|
||||
{
|
||||
return;
|
||||
}
|
||||
asm ("\nEOF.end\n");
|
||||
|
||||
/* Find out how much alignment is produced by the compiler. */
|
||||
asm ("align=`awk '$1==\".align\" { if ($2>max) max=$2; } END { print max; }' \
|
||||
<<\\EOF.align");
|
||||
void
|
||||
useless_function2 (void (*foo) (void))
|
||||
dummy (void (*foo) (void))
|
||||
{
|
||||
if (foo)
|
||||
(*foo) ();
|
||||
}
|
||||
asm ("\nEOF.align\n`\n");
|
||||
asm ("\n/*@TESTS_END*/");
|
||||
|
||||
/* Append the .init prologue to crti.s-new. */
|
||||
asm ("cat >> crti.s-new <<\\EOF.crti.init");
|
||||
/* The beginning of _init: */
|
||||
asm ("\n/*@_init_PROLOG_BEGINS*/");
|
||||
|
||||
SECTION (".init")
|
||||
void
|
||||
@@ -99,38 +71,33 @@ _init (void)
|
||||
gcrt1.o to reference a symbol which would be defined by some library
|
||||
module which has a constructor; but then user code's constructors
|
||||
would come first, and not be profiled. */
|
||||
extern void __gmon_start__ (void); weak_extern (__gmon_start__)
|
||||
extern void __gmon_start__ (void) __attribute__ ((weak)); /*weak_extern (__gmon_start__);*/
|
||||
|
||||
if (__gmon_start__)
|
||||
__gmon_start__ ();
|
||||
|
||||
/* End the here document containing the .init prologue code.
|
||||
Then fetch the .section directive just written and append that
|
||||
to crtn.s-new, followed by the function epilogue. */
|
||||
asm ("\n\
|
||||
EOF.crti.init\n\
|
||||
test -n \"$align\" && echo .align $align >> crti.s-new\n\
|
||||
test -n \"$need_end\" && echo .end _init >> crti.s-new\n\
|
||||
fgrep .init crti.s-new >>crtn.s-new\n\
|
||||
fgrep -v .end >> crtn.s-new <<\\EOF.crtn.init");
|
||||
asm ("ALIGN");
|
||||
asm("END_INIT");
|
||||
/* Now the epilog. */
|
||||
asm ("\n/*@_init_PROLOG_ENDS*/");
|
||||
asm ("\n/*@_init_EPILOG_BEGINS*/");
|
||||
SECTION(".init");
|
||||
}
|
||||
asm ("END_INIT");
|
||||
|
||||
/* End the here document containing the .init epilogue code.
|
||||
Then append the .fini prologue to crti.s-new. */
|
||||
asm ("\nEOF.crtn.init\
|
||||
\n\
|
||||
cat >> crti.s-new <<\\EOF.crti.fini");
|
||||
/* End of the _init epilog, beginning of the _fini prolog. */
|
||||
asm ("\n/*@_init_EPILOG_ENDS*/");
|
||||
asm ("\n/*@_fini_PROLOG_BEGINS*/");
|
||||
|
||||
SECTION (".fini")
|
||||
void
|
||||
_fini (void)
|
||||
{
|
||||
/* End the here document containing the .fini prologue code.
|
||||
Then fetch the .section directive just written and append that
|
||||
to crtn.s-new, followed by the function epilogue. */
|
||||
asm ("\nEOF.crti.fini\n\
|
||||
test -n \"$align\" && echo .align $align >> crti.s-new\n\
|
||||
test -n \"$need_end\" && echo .end _fini >> crti.s-new\n\
|
||||
cat > /dev/null <<\\EOF.fini.skip");
|
||||
|
||||
/* End of the _fini prolog. */
|
||||
asm ("ALIGN");
|
||||
asm ("END_FINI");
|
||||
asm ("\n/*@_fini_PROLOG_ENDS*/");
|
||||
|
||||
{
|
||||
/* Let GCC know that _fini is not a leaf function by having a dummy
|
||||
@@ -140,14 +107,15 @@ cat > /dev/null <<\\EOF.fini.skip");
|
||||
i_am_not_a_leaf ();
|
||||
}
|
||||
|
||||
asm ("\nEOF.fini.skip\
|
||||
\n\
|
||||
fgrep .fini crti.s-new >>crtn.s-new\n\
|
||||
fgrep -v .end >> crtn.s-new <<\\EOF.crtn.fini");
|
||||
/* Beginning of the _fini epilog. */
|
||||
asm ("\n/*@_fini_EPILOG_BEGINS*/");
|
||||
SECTION (".fini");
|
||||
}
|
||||
asm ("END_FINI");
|
||||
|
||||
/* End the here document containing the .fini epilogue code.
|
||||
Finally, put the remainder of the generated assembly into crtcommon.tmp. */
|
||||
asm ("\nEOF.crtn.fini\
|
||||
\n\
|
||||
cat > crtcommon.tmp <<\\EOF_common");
|
||||
/* End of the _fini epilog. Any further generated assembly (e.g. .ident)
|
||||
is shared between both crt files. */
|
||||
asm ("\n/*@_fini_EPILOG_ENDS*/");
|
||||
asm ("\n/*@TRAILER_BEGINS*/");
|
||||
|
||||
/* End of file. */
|
||||
|
||||
@@ -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))
|
||||
|
||||
@@ -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).
|
||||
|
||||
+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)
|
||||
|
||||
+3
-5
@@ -199,7 +199,7 @@ _dl_check_map_versions (struct link_map *map, int verbose)
|
||||
aux->vna_flags & VER_FLG_WEAK);
|
||||
|
||||
/* Compare the version index. */
|
||||
if ((aux->vna_other & 0x7fff) > ndx_high)
|
||||
if ((unsigned int) (aux->vna_other & 0x7fff) > ndx_high)
|
||||
ndx_high = aux->vna_other & 0x7fff;
|
||||
|
||||
if (aux->vna_next == 0)
|
||||
@@ -230,7 +230,7 @@ _dl_check_map_versions (struct link_map *map, int verbose)
|
||||
ent = (ElfW(Verdef) *) (map->l_addr + def->d_un.d_ptr);
|
||||
while (1)
|
||||
{
|
||||
if ((ent->vd_ndx & 0x7fff) > ndx_high)
|
||||
if ((unsigned int) (ent->vd_ndx & 0x7fff) > ndx_high)
|
||||
ndx_high = ent->vd_ndx & 0x7fff;
|
||||
|
||||
if (ent->vd_next == 0)
|
||||
@@ -247,9 +247,7 @@ _dl_check_map_versions (struct link_map *map, int verbose)
|
||||
which can be indexed by the version index in the VERSYM
|
||||
section. */
|
||||
map->l_versions = (struct r_found_version *)
|
||||
malloc ((ndx_high + 1) * sizeof (*map->l_versions));
|
||||
memset (map->l_versions, '\0',
|
||||
(ndx_high + 1) * sizeof (*map->l_versions));
|
||||
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]),
|
||||
|
||||
+44
-4
@@ -16,20 +16,60 @@
|
||||
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;
|
||||
|
||||
+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)
|
||||
|
||||
+86
-53
@@ -1,62 +1,95 @@
|
||||
/*
|
||||
* Copyright (c) 1983, 1993
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by the University of
|
||||
* California, Berkeley and its contributors.
|
||||
* 4. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* @(#)inet.h 8.1 (Berkeley) 6/2/93
|
||||
*/
|
||||
/* Copyright (C) 1997 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
|
||||
#ifndef _INET_H_
|
||||
#define _INET_H_
|
||||
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.
|
||||
|
||||
/* External definitions for functions in inet(3) */
|
||||
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 _ARPA_INET_H
|
||||
|
||||
#define _ARPA_INET_H 1
|
||||
#include <features.h>
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
#include <sys/types.h>
|
||||
#include <netinet/in.h> /* To define `struct in_addr'. */
|
||||
|
||||
__BEGIN_DECLS
|
||||
u_long inet_addr __P((const char *));
|
||||
int inet_aton __P((const char *, struct in_addr *));
|
||||
u_int32_t inet_lnaof __P((struct in_addr));
|
||||
struct in_addr inet_makeaddr __P((u_int32_t , u_int32_t));
|
||||
char * inet_neta __P((u_long, char *, size_t));
|
||||
u_int32_t inet_netof __P((struct in_addr));
|
||||
u_int32_t inet_network __P((const char *));
|
||||
char *inet_net_ntop __P((int, const void *, int, char *, size_t));
|
||||
int inet_net_pton __P((int, const char *, void *, size_t));
|
||||
char *inet_ntoa __P((struct in_addr));
|
||||
int inet_pton __P((int, const char *, void *));
|
||||
const char *inet_ntop __P((int, const void *, char *, size_t));
|
||||
u_int inet_nsap_addr __P((const char *, u_char *, int));
|
||||
char *inet_nsap_ntoa __P((int, const u_char *, char *));
|
||||
|
||||
/* Convert Internet host address from numbers-and-dots notation in CP
|
||||
into binary data in network byte order. */
|
||||
extern unsigned long int inet_addr __P ((__const char *__cp));
|
||||
|
||||
/* Convert Internet host address from numbers-and-dots notation in CP
|
||||
into binary data and store the result in the structure INP. */
|
||||
extern int inet_aton __P ((__const char *__cp, struct in_addr *__inp));
|
||||
|
||||
/* Return the local host address part of the Internet address in IN. */
|
||||
extern u_int32_t inet_lnaof __P ((struct in_addr __in));
|
||||
|
||||
/* Make Internet host address in network byte order by combining the
|
||||
network number NET with the local address HOST. */
|
||||
extern struct in_addr inet_makeaddr __P ((u_int32_t __net, u_int32_t __host));
|
||||
|
||||
/* Format a network number NET into presentation format and place result
|
||||
in buffer starting at BUF with length of LEN bytes. */
|
||||
extern char *inet_neta __P ((u_long __net, char *__buf, size_t __len));
|
||||
|
||||
/* Return network number part of the Internet address IN. */
|
||||
extern u_int32_t inet_netof __P ((struct in_addr __in));
|
||||
|
||||
/* Extract the network number in network byte order from the address
|
||||
in numbers-and-dots natation starting at CP. */
|
||||
extern u_int32_t inet_network __P ((__const char *__cp));
|
||||
|
||||
/* Convert network number for interface type AF in buffer starting at
|
||||
CP to presentation format. The result will specifiy BITS bits of
|
||||
the number. */
|
||||
extern char *inet_net_ntop __P((int __af, __const void *__cp, int __bits,
|
||||
char *__buf, size_t __len));
|
||||
|
||||
/* Convert network number for interface type AF from presentation in
|
||||
buffer starting at CP to network format and store result int
|
||||
buffer starting at BUF of size LEN. */
|
||||
extern int inet_net_pton __P ((int __af, __const char *__cp,
|
||||
void *__buf, size_t __len));
|
||||
|
||||
/* Convert Internet number in IN to ASCII representation. The return value
|
||||
is a pointer to an internal array containing the string. */
|
||||
extern char *inet_ntoa __P ((struct in_addr __in));
|
||||
|
||||
/* Convert from presentation format of an Internet number in buffer
|
||||
starting at CP to the binary network format and store result for
|
||||
interface type AF in buffer starting at BUF. */
|
||||
extern int inet_pton __P ((int __af, __const char *__cp, void *__buf));
|
||||
|
||||
/* Convert a Internet address in binary network format for interface
|
||||
type AF in buffer starting at CP to presentation form and place
|
||||
result in buffer of length LEN astarting at BUF. */
|
||||
extern __const char *inet_ntop __P ((int __af, __const void *__cp,
|
||||
char *__buf, size_t __len));
|
||||
|
||||
/* Convert ASCII representation in hexadecimal form of the Internet
|
||||
address to binary form and place result in buffer of length LEN
|
||||
starting at BUF. */
|
||||
extern unsigned int inet_nsap_addr __P ((__const char *__cp,
|
||||
unsigned char *__buf, int __len));
|
||||
|
||||
/* Convert internet address in binary form in LEN bytes starting at CP
|
||||
a presentation form and place result in BUF. */
|
||||
extern char *inet_nsap_ntoa __P ((int __len, __const unsigned char *__cp,
|
||||
char *__buf));
|
||||
|
||||
__END_DECLS
|
||||
|
||||
#endif /* !_INET_H_ */
|
||||
#endif /* arpa/inet.h */
|
||||
|
||||
+89
-51
@@ -1,59 +1,97 @@
|
||||
/*
|
||||
* Copyright (c) 1983, 1993
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by the University of
|
||||
* California, Berkeley and its contributors.
|
||||
* 4. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
/* Convert Inet number to ASCII representation.
|
||||
Copyright (C) 1997 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997.
|
||||
|
||||
#if defined(LIBC_SCCS) && !defined(lint)
|
||||
static char sccsid[] = "@(#)inet_ntoa.c 8.1 (Berkeley) 6/4/93";
|
||||
#endif /* LIBC_SCCS and not lint */
|
||||
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. */
|
||||
|
||||
/*
|
||||
* Convert network-format internet address
|
||||
* to base 256 d.d.d.d representation.
|
||||
*/
|
||||
#include <sys/types.h>
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <libc-lock.h>
|
||||
|
||||
/* The interface of this function is completely stupid, it requires a
|
||||
static buffer. We relax this a bit in that we allow at least one
|
||||
buffer for each thread. */
|
||||
__libc_lock_define_initialized (static, lock);
|
||||
|
||||
/* This is the key for the thread specific memory. */
|
||||
static __libc_key_t key;
|
||||
|
||||
/* Destructor for the thread-specific data. */
|
||||
static void free_key_mem (void *mem);
|
||||
|
||||
|
||||
char *
|
||||
inet_ntoa(in)
|
||||
struct in_addr in;
|
||||
inet_ntoa (struct in_addr in)
|
||||
{
|
||||
static char b[18];
|
||||
register char *p;
|
||||
static char static_buf[18];
|
||||
static int initialized = 0;
|
||||
char *buffer = NULL;
|
||||
unsigned char *bytes;
|
||||
|
||||
p = (char *)∈
|
||||
#define UC(b) (((int)b)&0xff)
|
||||
(void)snprintf(b, sizeof(b),
|
||||
"%d.%d.%d.%d", UC(p[0]), UC(p[1]), UC(p[2]), UC(p[3]));
|
||||
return (b);
|
||||
/* If we have not yet initialized the buffer do it now. */
|
||||
if (!initialized)
|
||||
{
|
||||
/* Make sure there is only one process doing the initialization. */
|
||||
__libc_lock_lock (lock);
|
||||
|
||||
if (!initialized)
|
||||
{
|
||||
if (__libc_key_create (&key, free_key_mem))
|
||||
/* Creating the key failed. This either means we run
|
||||
have only a single-threaded application or something
|
||||
really went wrong. In any case use a static buffer
|
||||
which is better than nothing. */
|
||||
buffer = static_buf;
|
||||
}
|
||||
|
||||
__libc_lock_unlock (lock);
|
||||
}
|
||||
|
||||
if (buffer == NULL)
|
||||
{
|
||||
/* We don't use the static buffer and so we have a key. Use it
|
||||
to get the thread-specific buffer. */
|
||||
buffer = __libc_getspecific (key);
|
||||
if (buffer == NULL)
|
||||
{
|
||||
/* No buffer allocated so far. */
|
||||
buffer = malloc (18);
|
||||
if (buffer == NULL)
|
||||
/* No more memory available. We use the static buffer. */
|
||||
buffer = static_buf;
|
||||
else
|
||||
__libc_setspecific (key, buffer);
|
||||
}
|
||||
}
|
||||
|
||||
bytes = (unsigned char *) ∈
|
||||
snprintf (buffer, 18, "%d.%d.%d.%d", bytes[0], bytes[1], bytes[2], bytes[3]);
|
||||
|
||||
return buffer;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
free_key_mem (void *mem)
|
||||
{
|
||||
free (mem);
|
||||
|
||||
/* And we must set the data to NULL so that the destructor is not
|
||||
called again. */
|
||||
__libc_setspecific (key, NULL);
|
||||
}
|
||||
|
||||
@@ -67,6 +67,10 @@
|
||||
will see messages about iso646.h, wctype.h and wchar.h not being
|
||||
found. */
|
||||
|
||||
#ifndef _GNU_SOURCE
|
||||
# define _GNU_SOURCE 1
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
@@ -168,18 +172,28 @@ static char *macros[] =
|
||||
#define NUMBER_OF_SUFFIXES (sizeof suffix / sizeof *suffix)
|
||||
#define NUMBER_OF_MACROS (sizeof macros / sizeof *macros)
|
||||
|
||||
|
||||
/* Format string to build command to invoke compiler. */
|
||||
static const char fmt[] = "\
|
||||
echo \"#include <%s>\" |\
|
||||
%s -E -dM -ansi -pedantic %s -D_LIBC -I. -I `%s --print-prog-name=include` -\
|
||||
> %s";
|
||||
|
||||
|
||||
/* The compiler we use (given on the command line). */
|
||||
char *CC;
|
||||
/* The -I parameters for CC to find all headers. */
|
||||
char *INC;
|
||||
|
||||
static int check_header (const char *);
|
||||
static const char **get_null_defines (void);
|
||||
static int check_header (const char *, const char **);
|
||||
|
||||
int
|
||||
main (int argc, char *argv[])
|
||||
{
|
||||
int h;
|
||||
int result = 0;
|
||||
const char **ignore_list;
|
||||
|
||||
CC = argc > 1 ? argv[1] : "gcc";
|
||||
INC = argc > 2 ? argv[2] : "";
|
||||
@@ -190,44 +204,109 @@ main (int argc, char *argv[])
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
/* First get list of symbols which are defined by the compiler. */
|
||||
ignore_list = get_null_defines ();
|
||||
|
||||
fputs ("Tested files:\n", stdout);
|
||||
|
||||
for (h = 0; h < NUMBER_OF_HEADERS; ++h)
|
||||
{
|
||||
char file_name[HEADER_MAX];
|
||||
sprintf (file_name, "%s.h", header[h]);
|
||||
result |= check_header (file_name);
|
||||
result |= check_header (file_name, ignore_list);
|
||||
}
|
||||
|
||||
|
||||
#if 0
|
||||
/* The test suite should return errors but for now this is not
|
||||
practical. Give a warning and ask the user to correct the bugs. */
|
||||
return result;
|
||||
#else
|
||||
if (result)
|
||||
fputs ("\
|
||||
##########################################################################\n\
|
||||
# The test suite found some problems with your system (see the generated #\n\
|
||||
# isomac.out file). These are all violations of the ISO C rules and #\n\
|
||||
# should be corrected. If the problem is in the libc, report it using #\n\
|
||||
# the glibcbug script to <bugs@gnu.ai.mit.edu>. If it is a problem with #\n\
|
||||
# your compiler, contact the compiler manufacturer. #\n\
|
||||
##########################################################################\n",
|
||||
stderr);
|
||||
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
static const char **
|
||||
get_null_defines (void)
|
||||
{
|
||||
char line[BUFSIZ], *command;
|
||||
char **result = NULL;
|
||||
size_t result_len = 0;
|
||||
size_t result_max = 0;
|
||||
FILE *input;
|
||||
int first = 1;
|
||||
|
||||
command = malloc (sizeof fmt + sizeof "/dev/null" + 2 * strlen (CC)
|
||||
+ strlen (INC) + strlen (TMPFILE));
|
||||
|
||||
if (command == NULL)
|
||||
{
|
||||
puts ("No more memory.");
|
||||
exit (1);
|
||||
}
|
||||
|
||||
sprintf (command, fmt, "/dev/null", CC, INC, CC, TMPFILE);
|
||||
|
||||
if (system (command))
|
||||
{
|
||||
puts ("system() returned nonzero");
|
||||
return NULL;
|
||||
}
|
||||
free (command);
|
||||
input = fopen (TMPFILE, "r");
|
||||
|
||||
if (input == NULL)
|
||||
{
|
||||
printf ("Could not read %s: ", TMPFILE);
|
||||
perror (NULL);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
while (fgets (line, sizeof line, input) != NULL)
|
||||
{
|
||||
int i, okay = 0;
|
||||
size_t endmac;
|
||||
char *start, *end;
|
||||
if (strlen (line) < 9 || line[7] != ' ')
|
||||
{ /* "#define A" */
|
||||
printf ("Malformed input, expected '#define MACRO'\ngot '%s'\n",
|
||||
line);
|
||||
continue;
|
||||
}
|
||||
if (line[8] == '_')
|
||||
/* It's a safe identifier. */
|
||||
continue;
|
||||
if (result_len == result_max)
|
||||
{
|
||||
result_max += 10;
|
||||
result = realloc (result, result_max * sizeof (char **));
|
||||
if (result == NULL)
|
||||
{
|
||||
puts ("No more memory.");
|
||||
exit (1);
|
||||
}
|
||||
}
|
||||
start = &line[8];
|
||||
for (end = start + 1; !isspace (*end) && *end != '\0'; ++end)
|
||||
;
|
||||
result[result_len++] = strndup (start, end - start);
|
||||
|
||||
if (first)
|
||||
{
|
||||
fputs ("The following identifiers will be ignored since the compiler defines them\nby default:\n", stdout);
|
||||
first = 0;
|
||||
}
|
||||
puts (result[result_len - 1]);
|
||||
}
|
||||
fclose (input);
|
||||
remove (TMPFILE);
|
||||
|
||||
return (const char **) result;
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
check_header (const char *file_name)
|
||||
check_header (const char *file_name, const char **except)
|
||||
{
|
||||
char line[BUFSIZ], *command;
|
||||
FILE *input;
|
||||
int result = 0;
|
||||
static const char fmt[] = "\
|
||||
echo \"#include <%s>\" |\
|
||||
%s -E -dM -ansi -pedantic %s -D_LIBC -I. -I `%s --print-prog-name=include` -\
|
||||
> %s";
|
||||
|
||||
command = malloc (sizeof fmt + strlen (file_name) + 2 * strlen (CC)
|
||||
+ strlen (INC) + strlen (TMPFILE));
|
||||
@@ -260,6 +339,7 @@ echo \"#include <%s>\" |\
|
||||
{
|
||||
int i, okay = 0;
|
||||
size_t endmac;
|
||||
const char **cpp;
|
||||
if (strlen (line) < 9 || line[7] != ' ')
|
||||
{ /* "#define A" */
|
||||
printf ("Malformed input, expected '#define MACRO'\ngot '%s'\n",
|
||||
@@ -278,7 +358,7 @@ echo \"#include <%s>\" |\
|
||||
continue;
|
||||
for (i = 0; i < NUMBER_OF_MACROS; ++i)
|
||||
{
|
||||
if (!strncmp (line+8, macros[i], strlen (macros[i])))
|
||||
if (!strncmp (line + 8, macros[i], strlen (macros[i])))
|
||||
{
|
||||
++okay;
|
||||
break;
|
||||
@@ -305,6 +385,18 @@ echo \"#include <%s>\" |\
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (okay)
|
||||
continue;
|
||||
if (except != NULL)
|
||||
for (cpp = except; *cpp != NULL; ++cpp)
|
||||
{
|
||||
size_t len = strlen (*cpp);
|
||||
if (!strncmp (line + 8, *cpp, len) && isspace (line[8 + len]))
|
||||
{
|
||||
++okay;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!okay)
|
||||
{
|
||||
fputs (line, stdout);
|
||||
|
||||
@@ -317,6 +317,7 @@ DEFUN(_IO_file_overflow, (f, ch),
|
||||
{
|
||||
if (f->_flags & _IO_NO_WRITES) /* SET ERROR */
|
||||
{
|
||||
f->_flags |= _IO_ERR_SEEN;
|
||||
__set_errno (EBADF);
|
||||
return EOF;
|
||||
}
|
||||
|
||||
+1
-1
@@ -615,7 +615,7 @@ DEFUN_VOID(_IO_flush_all_linebuffered)
|
||||
{
|
||||
_IO_FILE *fp;
|
||||
for (fp = _IO_list_all; fp != NULL; fp = fp->_chain)
|
||||
if (fp->_flags & _IO_LINE_BUF)
|
||||
if ((fp->_flags & _IO_NO_WRITES) == 0 && fp->_flags & _IO_LINE_BUF)
|
||||
_IO_OVERFLOW (fp, EOF);
|
||||
}
|
||||
|
||||
|
||||
+1
-1
@@ -104,7 +104,7 @@ extern struct locale_data *_nl_current_##category;
|
||||
|
||||
extern const char *const _nl_category_names[LC_ALL + 1];
|
||||
extern const size_t _nl_category_name_sizes[LC_ALL + 1];
|
||||
extern struct locale_data * *const _nl_current[LC_ALL];
|
||||
extern struct locale_data * *const _nl_current[LC_ALL + 1];
|
||||
|
||||
/* Name of the standard locale. */
|
||||
extern const char _nl_C_name[];
|
||||
|
||||
@@ -49,6 +49,9 @@ static struct locale_data * *const _nl_current[] =
|
||||
[category] = &_nl_current_##category,
|
||||
#include "categories.def"
|
||||
#undef DEFINE_CATEGORY
|
||||
/* We need this additional element to simplify the code. It must
|
||||
simply be != NULL. */
|
||||
[LC_ALL] = (struct locale_data **) ~0ul
|
||||
};
|
||||
|
||||
/* Array indexed by category of pointers to _nl_C_CATEGORY slots.
|
||||
|
||||
+38
-31
@@ -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@cygnus.com>, 1996.
|
||||
|
||||
@@ -25,18 +25,51 @@
|
||||
#include <sys/stat.h>
|
||||
|
||||
void
|
||||
logwtmp (const char *line, const char *name, const char *host)
|
||||
updwtmp (const char *wtmp_file, const struct utmp *ut)
|
||||
{
|
||||
struct utmp ut;
|
||||
struct stat st;
|
||||
size_t written;
|
||||
int fd;
|
||||
|
||||
/* Open WTMP file. */
|
||||
fd = __open (_PATH_WTMP, O_WRONLY | O_APPEND);
|
||||
fd = __open (wtmp_file, O_WRONLY | O_APPEND);
|
||||
if (fd < 0)
|
||||
return;
|
||||
|
||||
/* Try to lock the file. */
|
||||
if (__flock (fd, LOCK_EX | LOCK_NB) < 0 && errno != ENOSYS)
|
||||
{
|
||||
/* Oh, oh. The file is already locked. Wait a bit and try again. */
|
||||
sleep (1);
|
||||
|
||||
/* This time we ignore the error. */
|
||||
__flock (fd, LOCK_EX | LOCK_NB);
|
||||
}
|
||||
|
||||
/* Remember original size of log file: */
|
||||
if (__fstat (fd, &st) < 0)
|
||||
goto done;
|
||||
|
||||
/* Write the entry. If we can't write all the bytes, reset the file
|
||||
size back to the original size. That way, no partial entries
|
||||
will remain. */
|
||||
written = __write (fd, ut, sizeof (struct utmp));
|
||||
if (written > 0 && written != sizeof (struct utmp))
|
||||
ftruncate (fd, st.st_size);
|
||||
|
||||
done:
|
||||
/* And unlock the file. */
|
||||
__flock (fd, LOCK_UN);
|
||||
|
||||
/* Close WTMP file. */
|
||||
__close (fd);
|
||||
}
|
||||
|
||||
void
|
||||
logwtmp (const char *line, const char *name, const char *host)
|
||||
{
|
||||
struct utmp ut;
|
||||
|
||||
/* Set information in new entry. */
|
||||
memset (&ut, 0, sizeof (ut));
|
||||
#if _HAVE_UT_PID - 0
|
||||
@@ -57,31 +90,5 @@ logwtmp (const char *line, const char *name, const char *host)
|
||||
time (&ut.ut_time);
|
||||
#endif
|
||||
|
||||
/* Try to lock the file. */
|
||||
if (__flock (fd, LOCK_EX | LOCK_NB) < 0 && errno != ENOSYS)
|
||||
{
|
||||
/* Oh, oh. The file is already locked. Wait a bit and try again. */
|
||||
sleep (1);
|
||||
|
||||
/* This time we ignore the error. */
|
||||
__flock (fd, LOCK_EX | LOCK_NB);
|
||||
}
|
||||
|
||||
/* Remember original size of log file: */
|
||||
if (__fstat (fd, &st) < 0)
|
||||
goto done;
|
||||
|
||||
/* Write the entry. If we can't write all the bytes, reset the file
|
||||
size back to the original size. That way, no partial entries
|
||||
will remain. */
|
||||
written = __write (fd, &ut, sizeof (ut));
|
||||
if (written > 0 && written != sizeof (ut))
|
||||
ftruncate (fd, st.st_size);
|
||||
|
||||
done:
|
||||
/* And unlock the file. */
|
||||
__flock (fd, LOCK_UN);
|
||||
|
||||
/* Close WTMP file. */
|
||||
__close (fd);
|
||||
updwtmp(_PATH_WTMP, &ut);
|
||||
}
|
||||
|
||||
@@ -49,6 +49,10 @@ extern void login __P ((__const struct utmp *__entry));
|
||||
/* Write the utmp entry to say the user on UT_LINE has logged out. */
|
||||
extern int logout __P ((__const char *__ut_line));
|
||||
|
||||
/* Append the given entry to a wtmp file. */
|
||||
extern void updwtmp __P ((__const char *__wtmp_file,
|
||||
__const struct utmp *__entry));
|
||||
|
||||
/* Append to wtmp an entry for the current time and the given info. */
|
||||
extern void logwtmp __P ((__const char *__ut_line, __const char *__ut_name,
|
||||
__const char *__ut_host));
|
||||
|
||||
+3
-1
@@ -231,7 +231,9 @@ proc_utmp_eq (const struct utmp *entry, const struct utmp *match)
|
||||
&&
|
||||
#endif
|
||||
#if _HAVE_UT_ID - 0
|
||||
strncmp (entry->ut_id, match->ut_id, sizeof match->ut_id) == 0
|
||||
(entry->ut_id[0] && match->ut_id[0]
|
||||
? strncmp (entry->ut_id, match->ut_id, sizeof match->ut_id) == 0
|
||||
: strncmp (entry->ut_line, match->ut_line, sizeof match->ut_line) == 0)
|
||||
#else
|
||||
strncmp (entry->ut_line, match->ut_line, sizeof match->ut_line) == 0
|
||||
#endif
|
||||
|
||||
+93
-32
@@ -1801,11 +1801,16 @@ new_heap(size) size_t size;
|
||||
unsigned long ul;
|
||||
heap_info *h;
|
||||
|
||||
if(size < HEAP_MIN_SIZE)
|
||||
if(size+top_pad < HEAP_MIN_SIZE)
|
||||
size = HEAP_MIN_SIZE;
|
||||
size = (size + page_mask) & ~page_mask;
|
||||
if(size > HEAP_MAX_SIZE)
|
||||
else if(size+top_pad <= HEAP_MAX_SIZE)
|
||||
size += top_pad;
|
||||
else if(size > HEAP_MAX_SIZE)
|
||||
return 0;
|
||||
else
|
||||
size = HEAP_MAX_SIZE;
|
||||
size = (size + page_mask) & ~page_mask;
|
||||
|
||||
p1 = (char *)MMAP(HEAP_MAX_SIZE<<1, PROT_NONE);
|
||||
if(p1 == (char *)-1)
|
||||
return 0;
|
||||
@@ -2228,9 +2233,11 @@ static void malloc_extend_top(ar_ptr, nb) arena *ar_ptr; INTERNAL_SIZE_T nb;
|
||||
(brk < old_end && old_top != initial_top(&main_arena)))
|
||||
return;
|
||||
|
||||
#if defined(_LIBC) || defined(MALLOC_HOOKS)
|
||||
/* Call the `morecore' hook if necessary. */
|
||||
if (__after_morecore_hook)
|
||||
(*__after_morecore_hook) ();
|
||||
#endif
|
||||
|
||||
sbrked_mem += sbrk_size;
|
||||
|
||||
@@ -2260,9 +2267,11 @@ static void malloc_extend_top(ar_ptr, nb) arena *ar_ptr; INTERNAL_SIZE_T nb;
|
||||
new_brk = (char*)(MORECORE (correction));
|
||||
if (new_brk == (char*)(MORECORE_FAILURE)) return;
|
||||
|
||||
#if defined(_LIBC) || defined(MALLOC_HOOKS)
|
||||
/* Call the `morecore' hook if necessary. */
|
||||
if (__after_morecore_hook)
|
||||
(*__after_morecore_hook) ();
|
||||
(*__after_morecore_hook) ();
|
||||
#endif
|
||||
|
||||
sbrked_mem += correction;
|
||||
|
||||
@@ -2303,7 +2312,7 @@ static void malloc_extend_top(ar_ptr, nb) arena *ar_ptr; INTERNAL_SIZE_T nb;
|
||||
}
|
||||
|
||||
/* A new heap must be created. */
|
||||
heap = new_heap(nb + top_pad + (MINSIZE + sizeof(*heap)));
|
||||
heap = new_heap(nb + (MINSIZE + sizeof(*heap)));
|
||||
if(!heap)
|
||||
return;
|
||||
heap->ar_ptr = ar_ptr;
|
||||
@@ -2425,12 +2434,21 @@ Void_t* mALLOc(bytes) size_t bytes;
|
||||
#endif
|
||||
|
||||
nb = request2size(bytes);
|
||||
arena_get(ar_ptr, nb + top_pad);
|
||||
arena_get(ar_ptr, nb);
|
||||
if(!ar_ptr)
|
||||
return 0;
|
||||
victim = chunk_alloc(ar_ptr, nb);
|
||||
(void)mutex_unlock(&ar_ptr->mutex);
|
||||
return victim ? chunk2mem(victim) : 0;
|
||||
if(!victim) {
|
||||
/* Maybe the failure is due to running out of mmapped areas. */
|
||||
if(ar_ptr != &main_arena) {
|
||||
(void)mutex_lock(&main_arena.mutex);
|
||||
victim = chunk_alloc(&main_arena, nb);
|
||||
(void)mutex_unlock(&main_arena.mutex);
|
||||
}
|
||||
if(!victim) return 0;
|
||||
}
|
||||
return chunk2mem(victim);
|
||||
}
|
||||
|
||||
static mchunkptr
|
||||
@@ -2792,8 +2810,6 @@ chunk_free(ar_ptr, p) arena *ar_ptr; mchunkptr p;
|
||||
return;
|
||||
}
|
||||
|
||||
set_head(next, nextsz); /* clear inuse bit */
|
||||
|
||||
islr = 0;
|
||||
|
||||
if (!(hd & PREV_INUSE)) /* consolidate backward */
|
||||
@@ -2820,12 +2836,29 @@ chunk_free(ar_ptr, p) arena *ar_ptr; mchunkptr p;
|
||||
}
|
||||
else
|
||||
unlink(next, bck, fwd);
|
||||
|
||||
next = chunk_at_offset(p, sz);
|
||||
}
|
||||
else
|
||||
set_head(next, nextsz); /* clear inuse bit */
|
||||
|
||||
set_head(p, sz | PREV_INUSE);
|
||||
set_foot(p, sz);
|
||||
next->prev_size = sz;
|
||||
if (!islr)
|
||||
frontlink(ar_ptr, p, sz, idx, bck, fwd);
|
||||
|
||||
#ifndef NO_THREADS
|
||||
/* Check whether the heap containing top can go away now. */
|
||||
if(next->size < MINSIZE &&
|
||||
(unsigned long)sz > trim_threshold &&
|
||||
ar_ptr != &main_arena) { /* fencepost */
|
||||
heap_info* heap = heap_for_ptr(top(ar_ptr));
|
||||
|
||||
if(top(ar_ptr) == chunk_at_offset(heap, sizeof(*heap)) &&
|
||||
heap->prev == heap_for_ptr(p))
|
||||
heap_trim(heap, top_pad);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
@@ -3063,8 +3096,16 @@ arena* ar_ptr; mchunkptr oldp; INTERNAL_SIZE_T oldsize, nb;
|
||||
|
||||
newp = chunk_alloc (ar_ptr, nb);
|
||||
|
||||
if (newp == 0) /* propagate failure */
|
||||
return 0;
|
||||
if (newp == 0) {
|
||||
/* Maybe the failure is due to running out of mmapped areas. */
|
||||
if (ar_ptr != &main_arena) {
|
||||
(void)mutex_lock(&main_arena.mutex);
|
||||
newp = chunk_alloc(&main_arena, nb);
|
||||
(void)mutex_unlock(&main_arena.mutex);
|
||||
}
|
||||
if (newp == 0) /* propagate failure */
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Avoid copy if newp is next chunk after oldp. */
|
||||
/* (This can only happen when new chunk is sbrk'ed.) */
|
||||
@@ -3159,7 +3200,16 @@ Void_t* mEMALIGn(alignment, bytes) size_t alignment; size_t bytes;
|
||||
return 0;
|
||||
p = chunk_align(ar_ptr, nb, alignment);
|
||||
(void)mutex_unlock(&ar_ptr->mutex);
|
||||
return p ? chunk2mem(p) : NULL;
|
||||
if(!p) {
|
||||
/* Maybe the failure is due to running out of mmapped areas. */
|
||||
if(ar_ptr != &main_arena) {
|
||||
(void)mutex_lock(&main_arena.mutex);
|
||||
p = chunk_align(&main_arena, nb, alignment);
|
||||
(void)mutex_unlock(&main_arena.mutex);
|
||||
}
|
||||
if(!p) return 0;
|
||||
}
|
||||
return chunk2mem(p);
|
||||
}
|
||||
|
||||
static mchunkptr
|
||||
@@ -3306,11 +3356,11 @@ Void_t* cALLOc(n, elem_size) size_t n; size_t elem_size;
|
||||
if(mem == 0)
|
||||
return 0;
|
||||
#ifdef HAVE_MEMCPY
|
||||
memset(mem, 0, sz);
|
||||
return memset(mem, 0, sz);
|
||||
#else
|
||||
while(sz > 0) ((char*)mem)[--sz] = 0; /* rather inefficient */
|
||||
#endif
|
||||
return mem;
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -3329,31 +3379,34 @@ Void_t* cALLOc(n, elem_size) size_t n; size_t elem_size;
|
||||
/* Only clearing follows, so we can unlock early. */
|
||||
(void)mutex_unlock(&ar_ptr->mutex);
|
||||
|
||||
if (p == 0)
|
||||
return 0;
|
||||
else
|
||||
{
|
||||
mem = chunk2mem(p);
|
||||
if (p == 0) {
|
||||
/* Maybe the failure is due to running out of mmapped areas. */
|
||||
if(ar_ptr != &main_arena) {
|
||||
(void)mutex_lock(&main_arena.mutex);
|
||||
p = chunk_alloc(&main_arena, sz);
|
||||
(void)mutex_unlock(&main_arena.mutex);
|
||||
}
|
||||
if (p == 0) return 0;
|
||||
}
|
||||
mem = chunk2mem(p);
|
||||
|
||||
/* Two optional cases in which clearing not necessary */
|
||||
/* Two optional cases in which clearing not necessary */
|
||||
|
||||
#if HAVE_MMAP
|
||||
if (chunk_is_mmapped(p)) return mem;
|
||||
if (chunk_is_mmapped(p)) return mem;
|
||||
#endif
|
||||
|
||||
csz = chunksize(p);
|
||||
csz = chunksize(p);
|
||||
|
||||
#if MORECORE_CLEARS
|
||||
if (p == oldtop && csz > oldtopsize)
|
||||
{
|
||||
/* clear only the bytes from non-freshly-sbrked memory */
|
||||
csz = oldtopsize;
|
||||
}
|
||||
if (p == oldtop && csz > oldtopsize) {
|
||||
/* clear only the bytes from non-freshly-sbrked memory */
|
||||
csz = oldtopsize;
|
||||
}
|
||||
#endif
|
||||
|
||||
MALLOC_ZERO(mem, csz - SIZE_SZ);
|
||||
return mem;
|
||||
}
|
||||
MALLOC_ZERO(mem, csz - SIZE_SZ);
|
||||
return mem;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -3444,9 +3497,11 @@ main_trim(pad) size_t pad;
|
||||
|
||||
new_brk = (char*)(MORECORE (-extra));
|
||||
|
||||
#if defined(_LIBC) || defined(MALLOC_HOOKS)
|
||||
/* Call the `morecore' hook if necessary. */
|
||||
if (__after_morecore_hook)
|
||||
(*__after_morecore_hook) ();
|
||||
#endif
|
||||
|
||||
if (new_brk == (char*)(MORECORE_FAILURE)) { /* sbrk failed? */
|
||||
/* Try to figure out what we have */
|
||||
@@ -3692,8 +3747,9 @@ void mALLOC_STATs()
|
||||
#endif
|
||||
#if !defined(NO_THREADS) && MALLOC_DEBUG > 1
|
||||
if(ar_ptr != &main_arena) {
|
||||
heap_info *heap;
|
||||
(void)mutex_lock(&ar_ptr->mutex);
|
||||
heap_info *heap = heap_for_ptr(top(ar_ptr));
|
||||
heap = heap_for_ptr(top(ar_ptr));
|
||||
while(heap) { dump_heap(heap); heap = heap->prev; }
|
||||
(void)mutex_unlock(&ar_ptr->mutex);
|
||||
}
|
||||
@@ -3701,7 +3757,11 @@ void mALLOC_STATs()
|
||||
ar_ptr = ar_ptr->next;
|
||||
if(ar_ptr == &main_arena) break;
|
||||
}
|
||||
#if HAVE_MMAP
|
||||
fprintf(stderr, "Total (incl. mmap):\n");
|
||||
#else
|
||||
fprintf(stderr, "Total:\n");
|
||||
#endif
|
||||
fprintf(stderr, "system bytes = %10u\n", system_b);
|
||||
fprintf(stderr, "in use bytes = %10u\n", in_use_b);
|
||||
#ifdef NO_THREADS
|
||||
@@ -3709,6 +3769,7 @@ void mALLOC_STATs()
|
||||
#endif
|
||||
#if HAVE_MMAP
|
||||
fprintf(stderr, "max mmap regions = %10u\n", (unsigned int)max_n_mmaps);
|
||||
fprintf(stderr, "max mmap bytes = %10lu\n", max_mmapped_mem);
|
||||
#endif
|
||||
#if THREAD_STATS
|
||||
fprintf(stderr, "heaps created = %10d\n", stat_n_heaps);
|
||||
|
||||
+4
-3
@@ -307,13 +307,14 @@ extern int obstack_exit_failure;
|
||||
|
||||
#define obstack_specify_allocation_with_arg(h, size, alignment, chunkfun, freefun, arg) \
|
||||
_obstack_begin_1 ((h), (size), (alignment), \
|
||||
(void *(*) (long)) (chunkfun), (void (*) (void *)) (freefun), (arg))
|
||||
(void *(*) (void *, long)) (chunkfun), \
|
||||
(void (*) (void *, void *)) (freefun), (arg))
|
||||
|
||||
#define obstack_chunkfun(h, newchunkfun) \
|
||||
((h) -> chunkfun = (struct _obstack_chunk *(*)(long)) (newchunkfun))
|
||||
((h) -> chunkfun = (struct _obstack_chunk *(*)(void *, long)) (newchunkfun))
|
||||
|
||||
#define obstack_freefun(h, newfreefun) \
|
||||
((h) -> freefun = (void (*)(void *)) (newfreefun))
|
||||
((h) -> freefun = (void (*)(void *, struct _obstack_chunk *)) (newfreefun))
|
||||
|
||||
#else
|
||||
|
||||
|
||||
@@ -1,540 +0,0 @@
|
||||
@comment This material was copied from /gd/gnu/doc/lgpl.texinfo.
|
||||
|
||||
@node Copying, Concept Index, Maintenance, Top
|
||||
@appendix GNU GENERAL PUBLIC LICENSE
|
||||
@center Version 2, June 1991
|
||||
|
||||
@display
|
||||
Copyright @copyright{} 1991 Free Software Foundation, Inc.
|
||||
675 Mass Ave, Cambridge, MA 02139, USA
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
of this license document, but changing it is not allowed.
|
||||
|
||||
[This is the first released version of the library GPL. It is
|
||||
numbered 2 because it goes with version 2 of the ordinary GPL.]
|
||||
@end display
|
||||
|
||||
@unnumberedsec Preamble
|
||||
|
||||
The licenses for most software are designed to take away your
|
||||
freedom to share and change it. By contrast, the GNU General Public
|
||||
Licenses are intended to guarantee your freedom to share and change
|
||||
free software---to make sure the software is free for all its users.
|
||||
|
||||
This license, the Library General Public License, applies to some
|
||||
specially designated Free Software Foundation software, and to any
|
||||
other libraries whose authors decide to use it. You can use it for
|
||||
your libraries, too.
|
||||
|
||||
When we speak of free software, we are referring to freedom, not
|
||||
price. Our General Public Licenses are designed to make sure that you
|
||||
have the freedom to distribute copies of free software (and charge for
|
||||
this service if you wish), that you receive source code or can get it
|
||||
if you want it, that you can change the software or use pieces of it
|
||||
in new free programs; and that you know you can do these things.
|
||||
|
||||
To protect your rights, we need to make restrictions that forbid
|
||||
anyone to deny you these rights or to ask you to surrender the rights.
|
||||
These restrictions translate to certain responsibilities for you if
|
||||
you distribute copies of the library, or if you modify it.
|
||||
|
||||
For example, if you distribute copies of the library, whether gratis
|
||||
or for a fee, you must give the recipients all the rights that we gave
|
||||
you. You must make sure that they, too, receive or can get the source
|
||||
code. If you link a program with the library, you must provide
|
||||
complete object files to the recipients so that they can relink them
|
||||
with the library, after making changes to the library and recompiling
|
||||
it. And you must show them these terms so they know their rights.
|
||||
|
||||
Our method of protecting your rights has two steps: (1) copyright
|
||||
the library, and (2) offer you this license which gives you legal
|
||||
permission to copy, distribute and/or modify the library.
|
||||
|
||||
Also, for each distributor's protection, we want to make certain
|
||||
that everyone understands that there is no warranty for this free
|
||||
library. If the library is modified by someone else and passed on, we
|
||||
want its recipients to know that what they have is not the original
|
||||
version, so that any problems introduced by others will not reflect on
|
||||
the original authors' reputations.
|
||||
|
||||
Finally, any free program is threatened constantly by software
|
||||
patents. We wish to avoid the danger that companies distributing free
|
||||
software will individually obtain patent licenses, thus in effect
|
||||
transforming the program into proprietary software. To prevent this,
|
||||
we have made it clear that any patent must be licensed for everyone's
|
||||
free use or not licensed at all.
|
||||
|
||||
Most GNU software, including some libraries, is covered by the ordinary
|
||||
GNU General Public License, which was designed for utility programs. This
|
||||
license, the GNU Library General Public License, applies to certain
|
||||
designated libraries. This license is quite different from the ordinary
|
||||
one; be sure to read it in full, and don't assume that anything in it is
|
||||
the same as in the ordinary license.
|
||||
|
||||
The reason we have a separate public license for some libraries is that
|
||||
they blur the distinction we usually make between modifying or adding to a
|
||||
program and simply using it. Linking a program with a library, without
|
||||
changing the library, is in some sense simply using the library, and is
|
||||
analogous to running a utility program or application program. However, in
|
||||
a textual and legal sense, the linked executable is a combined work, a
|
||||
derivative of the original library, and the ordinary General Public License
|
||||
treats it as such.
|
||||
|
||||
Because of this blurred distinction, using the ordinary General
|
||||
Public License for libraries did not effectively promote software
|
||||
sharing, because most developers did not use the libraries. We
|
||||
concluded that weaker conditions might promote sharing better.
|
||||
|
||||
However, unrestricted linking of non-free programs would deprive the
|
||||
users of those programs of all benefit from the free status of the
|
||||
libraries themselves. This Library General Public License is intended to
|
||||
permit developers of non-free programs to use free libraries, while
|
||||
preserving your freedom as a user of such programs to change the free
|
||||
libraries that are incorporated in them. (We have not seen how to achieve
|
||||
this as regards changes in header files, but we have achieved it as regards
|
||||
changes in the actual functions of the Library.) The hope is that this
|
||||
will lead to faster development of free libraries.
|
||||
|
||||
The precise terms and conditions for copying, distribution and
|
||||
modification follow. Pay close attention to the difference between a
|
||||
``work based on the library'' and a ``work that uses the library''. The
|
||||
former contains code derived from the library, while the latter only
|
||||
works together with the library.
|
||||
|
||||
Note that it is possible for a library to be covered by the ordinary
|
||||
General Public License rather than by this special one.
|
||||
|
||||
@iftex
|
||||
@unnumberedsec TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
||||
@end iftex
|
||||
@ifinfo
|
||||
@center TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
||||
@end ifinfo
|
||||
|
||||
@enumerate
|
||||
@item
|
||||
This License Agreement applies to any software library which
|
||||
contains a notice placed by the copyright holder or other authorized
|
||||
party saying it may be distributed under the terms of this Library
|
||||
General Public License (also called ``this License''). Each licensee is
|
||||
addressed as ``you''.
|
||||
|
||||
A ``library'' means a collection of software functions and/or data
|
||||
prepared so as to be conveniently linked with application programs
|
||||
(which use some of those functions and data) to form executables.
|
||||
|
||||
The ``Library'', below, refers to any such software library or work
|
||||
which has been distributed under these terms. A ``work based on the
|
||||
Library'' means either the Library or any derivative work under
|
||||
copyright law: that is to say, a work containing the Library or a
|
||||
portion of it, either verbatim or with modifications and/or translated
|
||||
straightforwardly into another language. (Hereinafter, translation is
|
||||
included without limitation in the term ``modification''.)
|
||||
|
||||
``Source code'' for a work means the preferred form of the work for
|
||||
making modifications to it. For a library, complete source code means
|
||||
all the source code for all modules it contains, plus any associated
|
||||
interface definition files, plus the scripts used to control compilation
|
||||
and installation of the library.
|
||||
|
||||
Activities other than copying, distribution and modification are not
|
||||
covered by this License; they are outside its scope. The act of
|
||||
running a program using the Library is not restricted, and output from
|
||||
such a program is covered only if its contents constitute a work based
|
||||
on the Library (independent of the use of the Library in a tool for
|
||||
writing it). Whether that is true depends on what the Library does
|
||||
and what the program that uses the Library does.
|
||||
|
||||
@item
|
||||
You may copy and distribute verbatim copies of the Library's
|
||||
complete source code as you receive it, in any medium, provided that
|
||||
you conspicuously and appropriately publish on each copy an
|
||||
appropriate copyright notice and disclaimer of warranty; keep intact
|
||||
all the notices that refer to this License and to the absence of any
|
||||
warranty; and distribute a copy of this License along with the
|
||||
Library.
|
||||
|
||||
You may charge a fee for the physical act of transferring a copy,
|
||||
and you may at your option offer warranty protection in exchange for a
|
||||
fee.
|
||||
|
||||
@item
|
||||
You may modify your copy or copies of the Library or any portion
|
||||
of it, thus forming a work based on the Library, and copy and
|
||||
distribute such modifications or work under the terms of Section 1
|
||||
above, provided that you also meet all of these conditions:
|
||||
|
||||
@enumerate a
|
||||
@item
|
||||
The modified work must itself be a software library.
|
||||
|
||||
@item
|
||||
You must cause the files modified to carry prominent notices
|
||||
stating that you changed the files and the date of any change.
|
||||
|
||||
@item
|
||||
You must cause the whole of the work to be licensed at no
|
||||
charge to all third parties under the terms of this License.
|
||||
|
||||
@item
|
||||
If a facility in the modified Library refers to a function or a
|
||||
table of data to be supplied by an application program that uses
|
||||
the facility, other than as an argument passed when the facility
|
||||
is invoked, then you must make a good faith effort to ensure that,
|
||||
in the event an application does not supply such function or
|
||||
table, the facility still operates, and performs whatever part of
|
||||
its purpose remains meaningful.
|
||||
|
||||
(For example, a function in a library to compute square roots has
|
||||
a purpose that is entirely well-defined independent of the
|
||||
application. Therefore, Subsection 2d requires that any
|
||||
application-supplied function or table used by this function must
|
||||
be optional: if the application does not supply it, the square
|
||||
root function must still compute square roots.)
|
||||
@end enumerate
|
||||
|
||||
These requirements apply to the modified work as a whole. If
|
||||
identifiable sections of that work are not derived from the Library,
|
||||
and can be reasonably considered independent and separate works in
|
||||
themselves, then this License, and its terms, do not apply to those
|
||||
sections when you distribute them as separate works. But when you
|
||||
distribute the same sections as part of a whole which is a work based
|
||||
on the Library, the distribution of the whole must be on the terms of
|
||||
this License, whose permissions for other licensees extend to the
|
||||
entire whole, and thus to each and every part regardless of who wrote
|
||||
it.
|
||||
|
||||
Thus, it is not the intent of this section to claim rights or contest
|
||||
your rights to work written entirely by you; rather, the intent is to
|
||||
exercise the right to control the distribution of derivative or
|
||||
collective works based on the Library.
|
||||
|
||||
In addition, mere aggregation of another work not based on the Library
|
||||
with the Library (or with a work based on the Library) on a volume of
|
||||
a storage or distribution medium does not bring the other work under
|
||||
the scope of this License.
|
||||
|
||||
@item
|
||||
You may opt to apply the terms of the ordinary GNU General Public
|
||||
License instead of this License to a given copy of the Library. To do
|
||||
this, you must alter all the notices that refer to this License, so
|
||||
that they refer to the ordinary GNU General Public License, version 2,
|
||||
instead of to this License. (If a newer version than version 2 of the
|
||||
ordinary GNU General Public License has appeared, then you can specify
|
||||
that version instead if you wish.) Do not make any other change in
|
||||
these notices.
|
||||
|
||||
Once this change is made in a given copy, it is irreversible for
|
||||
that copy, so the ordinary GNU General Public License applies to all
|
||||
subsequent copies and derivative works made from that copy.
|
||||
|
||||
This option is useful when you wish to copy part of the code of
|
||||
the Library into a program that is not a library.
|
||||
|
||||
@item
|
||||
You may copy and distribute the Library (or a portion or
|
||||
derivative of it, under Section 2) in object code or executable form
|
||||
under the terms of Sections 1 and 2 above provided that you accompany
|
||||
it with the complete corresponding machine-readable source code, which
|
||||
must be distributed under the terms of Sections 1 and 2 above on a
|
||||
medium customarily used for software interchange.
|
||||
|
||||
If distribution of object code is made by offering access to copy
|
||||
from a designated place, then offering equivalent access to copy the
|
||||
source code from the same place satisfies the requirement to
|
||||
distribute the source code, even though third parties are not
|
||||
compelled to copy the source along with the object code.
|
||||
|
||||
@item
|
||||
A program that contains no derivative of any portion of the
|
||||
Library, but is designed to work with the Library by being compiled or
|
||||
linked with it, is called a ``work that uses the Library''. Such a
|
||||
work, in isolation, is not a derivative work of the Library, and
|
||||
therefore falls outside the scope of this License.
|
||||
|
||||
However, linking a ``work that uses the Library'' with the Library
|
||||
creates an executable that is a derivative of the Library (because it
|
||||
contains portions of the Library), rather than a ``work that uses the
|
||||
library''. The executable is therefore covered by this License.
|
||||
Section 6 states terms for distribution of such executables.
|
||||
|
||||
When a ``work that uses the Library'' uses material from a header file
|
||||
that is part of the Library, the object code for the work may be a
|
||||
derivative work of the Library even though the source code is not.
|
||||
Whether this is true is especially significant if the work can be
|
||||
linked without the Library, or if the work is itself a library. The
|
||||
threshold for this to be true is not precisely defined by law.
|
||||
|
||||
If such an object file uses only numerical parameters, data
|
||||
structure layouts and accessors, and small macros and small inline
|
||||
functions (ten lines or less in length), then the use of the object
|
||||
file is unrestricted, regardless of whether it is legally a derivative
|
||||
work. (Executables containing this object code plus portions of the
|
||||
Library will still fall under Section 6.)
|
||||
|
||||
Otherwise, if the work is a derivative of the Library, you may
|
||||
distribute the object code for the work under the terms of Section 6.
|
||||
Any executables containing that work also fall under Section 6,
|
||||
whether or not they are linked directly with the Library itself.
|
||||
|
||||
@item
|
||||
As an exception to the Sections above, you may also compile or
|
||||
link a ``work that uses the Library'' with the Library to produce a
|
||||
work containing portions of the Library, and distribute that work
|
||||
under terms of your choice, provided that the terms permit
|
||||
modification of the work for the customer's own use and reverse
|
||||
engineering for debugging such modifications.
|
||||
|
||||
You must give prominent notice with each copy of the work that the
|
||||
Library is used in it and that the Library and its use are covered by
|
||||
this License. You must supply a copy of this License. If the work
|
||||
during execution displays copyright notices, you must include the
|
||||
copyright notice for the Library among them, as well as a reference
|
||||
directing the user to the copy of this License. Also, you must do one
|
||||
of these things:
|
||||
|
||||
@enumerate a
|
||||
@item
|
||||
Accompany the work with the complete corresponding
|
||||
machine-readable source code for the Library including whatever
|
||||
changes were used in the work (which must be distributed under
|
||||
Sections 1 and 2 above); and, if the work is an executable linked
|
||||
with the Library, with the complete machine-readable ``work that
|
||||
uses the Library'', as object code and/or source code, so that the
|
||||
user can modify the Library and then relink to produce a modified
|
||||
executable containing the modified Library. (It is understood
|
||||
that the user who changes the contents of definitions files in the
|
||||
Library will not necessarily be able to recompile the application
|
||||
to use the modified definitions.)
|
||||
|
||||
@item
|
||||
Accompany the work with a written offer, valid for at
|
||||
least three years, to give the same user the materials
|
||||
specified in Subsection 6a, above, for a charge no more
|
||||
than the cost of performing this distribution.
|
||||
|
||||
@item
|
||||
If distribution of the work is made by offering access to copy
|
||||
from a designated place, offer equivalent access to copy the above
|
||||
specified materials from the same place.
|
||||
|
||||
@item
|
||||
Verify that the user has already received a copy of these
|
||||
materials or that you have already sent this user a copy.
|
||||
@end enumerate
|
||||
|
||||
For an executable, the required form of the ``work that uses the
|
||||
Library'' must include any data and utility programs needed for
|
||||
reproducing the executable from it. However, as a special exception,
|
||||
the source code distributed need not include anything that is normally
|
||||
distributed (in either source or binary form) with the major
|
||||
components (compiler, kernel, and so on) of the operating system on
|
||||
which the executable runs, unless that component itself accompanies
|
||||
the executable.
|
||||
|
||||
It may happen that this requirement contradicts the license
|
||||
restrictions of other proprietary libraries that do not normally
|
||||
accompany the operating system. Such a contradiction means you cannot
|
||||
use both them and the Library together in an executable that you
|
||||
distribute.
|
||||
|
||||
@item
|
||||
You may place library facilities that are a work based on the
|
||||
Library side-by-side in a single library together with other library
|
||||
facilities not covered by this License, and distribute such a combined
|
||||
library, provided that the separate distribution of the work based on
|
||||
the Library and of the other library facilities is otherwise
|
||||
permitted, and provided that you do these two things:
|
||||
|
||||
@enumerate a
|
||||
@item
|
||||
Accompany the combined library with a copy of the same work
|
||||
based on the Library, uncombined with any other library
|
||||
facilities. This must be distributed under the terms of the
|
||||
Sections above.
|
||||
|
||||
@item
|
||||
Give prominent notice with the combined library of the fact
|
||||
that part of it is a work based on the Library, and explaining
|
||||
where to find the accompanying uncombined form of the same work.
|
||||
@end enumerate
|
||||
|
||||
@item
|
||||
You may not copy, modify, sublicense, link with, or distribute
|
||||
the Library except as expressly provided under this License. Any
|
||||
attempt otherwise to copy, modify, sublicense, link with, or
|
||||
distribute the Library is void, and will automatically terminate your
|
||||
rights under this License. However, parties who have received copies,
|
||||
or rights, from you under this License will not have their licenses
|
||||
terminated so long as such parties remain in full compliance.
|
||||
|
||||
@item
|
||||
You are not required to accept this License, since you have not
|
||||
signed it. However, nothing else grants you permission to modify or
|
||||
distribute the Library or its derivative works. These actions are
|
||||
prohibited by law if you do not accept this License. Therefore, by
|
||||
modifying or distributing the Library (or any work based on the
|
||||
Library), you indicate your acceptance of this License to do so, and
|
||||
all its terms and conditions for copying, distributing or modifying
|
||||
the Library or works based on it.
|
||||
|
||||
@item
|
||||
Each time you redistribute the Library (or any work based on the
|
||||
Library), the recipient automatically receives a license from the
|
||||
original licensor to copy, distribute, link with or modify the Library
|
||||
subject to these terms and conditions. You may not impose any further
|
||||
restrictions on the recipients' exercise of the rights granted herein.
|
||||
You are not responsible for enforcing compliance by third parties to
|
||||
this License.
|
||||
|
||||
@item
|
||||
If, as a consequence of a court judgment or allegation of patent
|
||||
infringement or for any other reason (not limited to patent issues),
|
||||
conditions are imposed on you (whether by court order, agreement or
|
||||
otherwise) that contradict the conditions of this License, they do not
|
||||
excuse you from the conditions of this License. If you cannot
|
||||
distribute so as to satisfy simultaneously your obligations under this
|
||||
License and any other pertinent obligations, then as a consequence you
|
||||
may not distribute the Library at all. For example, if a patent
|
||||
license would not permit royalty-free redistribution of the Library by
|
||||
all those who receive copies directly or indirectly through you, then
|
||||
the only way you could satisfy both it and this License would be to
|
||||
refrain entirely from distribution of the Library.
|
||||
|
||||
If any portion of this section is held invalid or unenforceable under any
|
||||
particular circumstance, the balance of the section is intended to apply,
|
||||
and the section as a whole is intended to apply in other circumstances.
|
||||
|
||||
It is not the purpose of this section to induce you to infringe any
|
||||
patents or other property right claims or to contest validity of any
|
||||
such claims; this section has the sole purpose of protecting the
|
||||
integrity of the free software distribution system which is
|
||||
implemented by public license practices. Many people have made
|
||||
generous contributions to the wide range of software distributed
|
||||
through that system in reliance on consistent application of that
|
||||
system; it is up to the author/donor to decide if he or she is willing
|
||||
to distribute software through any other system and a licensee cannot
|
||||
impose that choice.
|
||||
|
||||
This section is intended to make thoroughly clear what is believed to
|
||||
be a consequence of the rest of this License.
|
||||
|
||||
@item
|
||||
If the distribution and/or use of the Library is restricted in
|
||||
certain countries either by patents or by copyrighted interfaces, the
|
||||
original copyright holder who places the Library under this License may add
|
||||
an explicit geographical distribution limitation excluding those countries,
|
||||
so that distribution is permitted only in or among countries not thus
|
||||
excluded. In such case, this License incorporates the limitation as if
|
||||
written in the body of this License.
|
||||
|
||||
@item
|
||||
The Free Software Foundation may publish revised and/or new
|
||||
versions of the Library General Public License from time to time.
|
||||
Such new versions will be similar in spirit to the present version,
|
||||
but may differ in detail to address new problems or concerns.
|
||||
|
||||
Each version is given a distinguishing version number. If the Library
|
||||
specifies a version number of this License which applies to it and
|
||||
``any later version'', you have the option of following the terms and
|
||||
conditions either of that version or of any later version published by
|
||||
the Free Software Foundation. If the Library does not specify a
|
||||
license version number, you may choose any version ever published by
|
||||
the Free Software Foundation.
|
||||
|
||||
@item
|
||||
If you wish to incorporate parts of the Library into other free
|
||||
programs whose distribution conditions are incompatible with these,
|
||||
write to the author to ask for permission. For software which is
|
||||
copyrighted by the Free Software Foundation, write to the Free
|
||||
Software Foundation; we sometimes make exceptions for this. Our
|
||||
decision will be guided by the two goals of preserving the free status
|
||||
of all derivatives of our free software and of promoting the sharing
|
||||
and reuse of software generally.
|
||||
|
||||
@iftex
|
||||
@heading NO WARRANTY
|
||||
@end iftex
|
||||
@ifinfo
|
||||
@center NO WARRANTY
|
||||
@end ifinfo
|
||||
|
||||
@item
|
||||
BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
|
||||
WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
|
||||
EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
|
||||
OTHER PARTIES PROVIDE THE LIBRARY ``AS IS'' WITHOUT WARRANTY OF ANY
|
||||
KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
|
||||
LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
|
||||
THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
|
||||
|
||||
@item
|
||||
IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
|
||||
WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
|
||||
AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU
|
||||
FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
|
||||
CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
|
||||
LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
|
||||
RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
|
||||
FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
|
||||
SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
|
||||
DAMAGES.
|
||||
@end enumerate
|
||||
|
||||
@iftex
|
||||
@heading END OF TERMS AND CONDITIONS
|
||||
@end iftex
|
||||
@ifinfo
|
||||
@center END OF TERMS AND CONDITIONS
|
||||
@end ifinfo
|
||||
|
||||
@page
|
||||
@unnumberedsec How to Apply These Terms to Your New Libraries
|
||||
|
||||
If you develop a new library, and you want it to be of the greatest
|
||||
possible use to the public, we recommend making it free software that
|
||||
everyone can redistribute and change. You can do so by permitting
|
||||
redistribution under these terms (or, alternatively, under the terms of the
|
||||
ordinary General Public License).
|
||||
|
||||
To apply these terms, attach the following notices to the library. It is
|
||||
safest to attach them to the start of each source file to most effectively
|
||||
convey the exclusion of warranty; and each file should have at least the
|
||||
``copyright'' line and a pointer to where the full notice is found.
|
||||
|
||||
@smallexample
|
||||
@var{one line to give the library's name and a brief idea of what it does.}
|
||||
Copyright (C) @var{year} @var{name of author}
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Library General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2 of the License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Library General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Library General Public
|
||||
License along with this library; if not, write to the Free
|
||||
Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
@end smallexample
|
||||
|
||||
Also add information on how to contact you by electronic and paper mail.
|
||||
|
||||
You should also get your employer (if you work as a programmer) or your
|
||||
school, if any, to sign a ``copyright disclaimer'' for the library, if
|
||||
necessary. Here is a sample; alter the names:
|
||||
|
||||
@example
|
||||
Yoyodyne, Inc., hereby disclaims all copyright interest in the
|
||||
library `Frob' (a library for tweaking knobs) written by James Random Hacker.
|
||||
|
||||
@var{signature of Ty Coon}, 1 April 1990
|
||||
Ty Coon, President of Vice
|
||||
@end example
|
||||
|
||||
That's all there is to it!
|
||||
@@ -1,414 +0,0 @@
|
||||
@node Floating-Point Limits
|
||||
@chapter Floating-Point Limits
|
||||
@pindex <float.h>
|
||||
@cindex floating-point number representation
|
||||
@cindex representation of floating-point numbers
|
||||
|
||||
Because floating-point numbers are represented internally as approximate
|
||||
quantities, algorithms for manipulating floating-point data often need
|
||||
to be parameterized in terms of the accuracy of the representation.
|
||||
Some of the functions in the C library itself need this information; for
|
||||
example, the algorithms for printing and reading floating-point numbers
|
||||
(@pxref{I/O on Streams}) and for calculating trigonometric and
|
||||
irrational functions (@pxref{Mathematics}) use information about the
|
||||
underlying floating-point representation to avoid round-off error and
|
||||
loss of accuracy. User programs that implement numerical analysis
|
||||
techniques also often need to be parameterized in this way in order to
|
||||
minimize or compute error bounds.
|
||||
|
||||
The specific representation of floating-point numbers varies from
|
||||
machine to machine. The GNU C Library defines a set of parameters which
|
||||
characterize each of the supported floating-point representations on a
|
||||
particular system.
|
||||
|
||||
@menu
|
||||
* Floating-Point Representation:: Definitions of terminology.
|
||||
* Floating-Point Parameters:: Descriptions of the library facilities.
|
||||
* IEEE Floating-Point:: An example of a common representation.
|
||||
@end menu
|
||||
|
||||
@node Floating-Point Representation
|
||||
@section Floating-Point Representation
|
||||
|
||||
This section introduces the terminology used to characterize the
|
||||
representation of floating-point numbers.
|
||||
|
||||
You are probably already familiar with most of these concepts in terms
|
||||
of scientific or exponential notation for floating-point numbers. For
|
||||
example, the number @code{123456.0} could be expressed in exponential
|
||||
notation as @code{1.23456e+05}, a shorthand notation indicating that the
|
||||
mantissa @code{1.23456} is multiplied by the base @code{10} raised to
|
||||
power @code{5}.
|
||||
|
||||
More formally, the internal representation of a floating-point number
|
||||
can be characterized in terms of the following parameters:
|
||||
|
||||
@itemize @bullet
|
||||
@item
|
||||
The @dfn{sign} is either @code{-1} or @code{1}.
|
||||
@cindex sign (of floating-point number)
|
||||
|
||||
@item
|
||||
The @dfn{base} or @dfn{radix} for exponentiation; an integer greater
|
||||
than @code{1}. This is a constant for the particular representation.
|
||||
@cindex base (of floating-point number)
|
||||
@cindex radix (of floating-point number)
|
||||
|
||||
@item
|
||||
The @dfn{exponent} to which the base is raised. The upper and lower
|
||||
bounds of the exponent value are constants for the particular
|
||||
representation.
|
||||
@cindex exponent (of floating-point number)
|
||||
|
||||
Sometimes, in the actual bits representing the floating-point number,
|
||||
the exponent is @dfn{biased} by adding a constant to it, to make it
|
||||
always be represented as an unsigned quantity. This is only important
|
||||
if you have some reason to pick apart the bit fields making up the
|
||||
floating-point number by hand, which is something for which the GNU
|
||||
library provides no support. So this is ignored in the discussion that
|
||||
follows.
|
||||
@cindex bias, in exponent (of floating-point number)
|
||||
|
||||
@item
|
||||
The value of the @dfn{mantissa} or @dfn{significand}, which is an
|
||||
unsigned quantity.
|
||||
@cindex mantissa (of floating-point number)
|
||||
@cindex significand (of floating-point number)
|
||||
|
||||
@item
|
||||
The @dfn{precision} of the mantissa. If the base of the representation
|
||||
is @var{b}, then the precision is the number of base-@var{b} digits in
|
||||
the mantissa. This is a constant for the particular representation.
|
||||
|
||||
Many floating-point representations have an implicit @dfn{hidden bit} in
|
||||
the mantissa. Any such hidden bits are counted in the precision.
|
||||
Again, the GNU library provides no facilities for dealing with such low-level
|
||||
aspects of the representation.
|
||||
@cindex precision (of floating-point number)
|
||||
@cindex hidden bit, in mantissa (of floating-point number)
|
||||
@end itemize
|
||||
|
||||
The mantissa of a floating-point number actually represents an implicit
|
||||
fraction whose denominator is the base raised to the power of the
|
||||
precision. Since the largest representable mantissa is one less than
|
||||
this denominator, the value of the fraction is always strictly less than
|
||||
@code{1}. The mathematical value of a floating-point number is then the
|
||||
product of this fraction; the sign; and the base raised to the exponent.
|
||||
|
||||
If the floating-point number is @dfn{normalized}, the mantissa is also
|
||||
greater than or equal to the base raised to the power of one less
|
||||
than the precision (unless the number represents a floating-point zero,
|
||||
in which case the mantissa is zero). The fractional quantity is
|
||||
therefore greater than or equal to @code{1/@var{b}}, where @var{b} is
|
||||
the base.
|
||||
@cindex normalized floating-point number
|
||||
|
||||
@node Floating-Point Parameters
|
||||
@section Floating-Point Parameters
|
||||
|
||||
@strong{Incomplete:} This section needs some more concrete examples
|
||||
of what these parameters mean and how to use them in a program.
|
||||
|
||||
These macro definitions can be accessed by including the header file
|
||||
@file{<float.h>} in your program.
|
||||
|
||||
Macro names starting with @samp{FLT_} refer to the @code{float} type,
|
||||
while names beginning with @samp{DBL_} refer to the @code{double} type
|
||||
and names beginning with @samp{LDBL_} refer to the @code{long double}
|
||||
type. (In implementations that do not support @code{long double} as
|
||||
a distinct data type, the values for those constants are the same
|
||||
as the corresponding constants for the @code{double} type.)@refill
|
||||
|
||||
Note that only @code{FLT_RADIX} is guaranteed to be a constant
|
||||
expression, so the other macros listed here cannot be reliably used in
|
||||
places that require constant expressions, such as @samp{#if}
|
||||
preprocessing directives and array size specifications.
|
||||
|
||||
Although the @w{ISO C} standard specifies minimum and maximum values for
|
||||
most of these parameters, the GNU C implementation uses whatever
|
||||
floating-point representations are supported by the underlying hardware.
|
||||
So whether GNU C actually satisfies the @w{ISO C} requirements depends on
|
||||
what machine it is running on.
|
||||
|
||||
@comment float.h
|
||||
@comment ISO
|
||||
@defvr Macro FLT_ROUNDS
|
||||
This value characterizes the rounding mode for floating-point addition.
|
||||
The following values indicate standard rounding modes:
|
||||
|
||||
@table @code
|
||||
@item -1
|
||||
The mode is indeterminable.
|
||||
@item 0
|
||||
Rounding is towards zero.
|
||||
@item 1
|
||||
Rounding is to the nearest number.
|
||||
@item 2
|
||||
Rounding is towards positive infinity.
|
||||
@item 3
|
||||
Rounding is towards negative infinity.
|
||||
@end table
|
||||
|
||||
@noindent
|
||||
Any other value represents a machine-dependent nonstandard rounding
|
||||
mode.
|
||||
@end defvr
|
||||
|
||||
@comment float.h
|
||||
@comment ISO
|
||||
@defvr Macro FLT_RADIX
|
||||
This is the value of the base, or radix, of exponent representation.
|
||||
This is guaranteed to be a constant expression, unlike the other macros
|
||||
described in this section.
|
||||
@end defvr
|
||||
|
||||
@comment float.h
|
||||
@comment ISO
|
||||
@defvr Macro FLT_MANT_DIG
|
||||
This is the number of base-@code{FLT_RADIX} digits in the floating-point
|
||||
mantissa for the @code{float} data type.
|
||||
@end defvr
|
||||
|
||||
@comment float.h
|
||||
@comment ISO
|
||||
@defvr Macro DBL_MANT_DIG
|
||||
This is the number of base-@code{FLT_RADIX} digits in the floating-point
|
||||
mantissa for the @code{double} data type.
|
||||
@end defvr
|
||||
|
||||
@comment float.h
|
||||
@comment ISO
|
||||
@defvr Macro LDBL_MANT_DIG
|
||||
This is the number of base-@code{FLT_RADIX} digits in the floating-point
|
||||
mantissa for the @code{long double} data type.
|
||||
@end defvr
|
||||
|
||||
@comment float.h
|
||||
@comment ISO
|
||||
@defvr Macro FLT_DIG
|
||||
This is the number of decimal digits of precision for the @code{float}
|
||||
data type. Technically, if @var{p} and @var{b} are the precision and
|
||||
base (respectively) for the representation, then the decimal precision
|
||||
@var{q} is the maximum number of decimal digits such that any floating
|
||||
point number with @var{q} base 10 digits can be rounded to a floating
|
||||
point number with @var{p} base @var{b} digits and back again, without
|
||||
change to the @var{q} decimal digits.
|
||||
|
||||
The value of this macro is guaranteed to be at least @code{6}.
|
||||
@end defvr
|
||||
|
||||
@comment float.h
|
||||
@comment ISO
|
||||
@defvr Macro DBL_DIG
|
||||
This is similar to @code{FLT_DIG}, but is for the @code{double} data
|
||||
type. The value of this macro is guaranteed to be at least @code{10}.
|
||||
@end defvr
|
||||
|
||||
@comment float.h
|
||||
@comment ISO
|
||||
@defvr Macro LDBL_DIG
|
||||
This is similar to @code{FLT_DIG}, but is for the @code{long double}
|
||||
data type. The value of this macro is guaranteed to be at least
|
||||
@code{10}.
|
||||
@end defvr
|
||||
|
||||
@comment float.h
|
||||
@comment ISO
|
||||
@defvr Macro FLT_MIN_EXP
|
||||
This is the minimum negative integer such that the mathematical value
|
||||
@code{FLT_RADIX} raised to this power minus 1 can be represented as a
|
||||
normalized floating-point number of type @code{float}. In terms of the
|
||||
actual implementation, this is just the smallest value that can be
|
||||
represented in the exponent field of the number.
|
||||
@end defvr
|
||||
|
||||
@comment float.h
|
||||
@comment ISO
|
||||
@defvr Macro DBL_MIN_EXP
|
||||
This is similar to @code{FLT_MIN_EXP}, but is for the @code{double} data
|
||||
type.
|
||||
@end defvr
|
||||
|
||||
@comment float.h
|
||||
@comment ISO
|
||||
@defvr Macro LDBL_MIN_EXP
|
||||
This is similar to @code{FLT_MIN_EXP}, but is for the @code{long double}
|
||||
data type.
|
||||
@end defvr
|
||||
|
||||
@comment float.h
|
||||
@comment ISO
|
||||
@defvr Macro FLT_MIN_10_EXP
|
||||
This is the minimum negative integer such that the mathematical value
|
||||
@code{10} raised to this power minus 1 can be represented as a
|
||||
normalized floating-point number of type @code{float}. This is
|
||||
guaranteed to be no greater than @code{-37}.
|
||||
@end defvr
|
||||
|
||||
@comment float.h
|
||||
@comment ISO
|
||||
@defvr Macro DBL_MIN_10_EXP
|
||||
This is similar to @code{FLT_MIN_10_EXP}, but is for the @code{double}
|
||||
data type.
|
||||
@end defvr
|
||||
|
||||
@comment float.h
|
||||
@comment ISO
|
||||
@defvr Macro LDBL_MIN_10_EXP
|
||||
This is similar to @code{FLT_MIN_10_EXP}, but is for the @code{long
|
||||
double} data type.
|
||||
@end defvr
|
||||
|
||||
|
||||
|
||||
@comment float.h
|
||||
@comment ISO
|
||||
@defvr Macro FLT_MAX_EXP
|
||||
This is the maximum negative integer such that the mathematical value
|
||||
@code{FLT_RADIX} raised to this power minus 1 can be represented as a
|
||||
floating-point number of type @code{float}. In terms of the actual
|
||||
implementation, this is just the largest value that can be represented
|
||||
in the exponent field of the number.
|
||||
@end defvr
|
||||
|
||||
@comment float.h
|
||||
@comment ISO
|
||||
@defvr Macro DBL_MAX_EXP
|
||||
This is similar to @code{FLT_MAX_EXP}, but is for the @code{double} data
|
||||
type.
|
||||
@end defvr
|
||||
|
||||
@comment float.h
|
||||
@comment ISO
|
||||
@defvr Macro LDBL_MAX_EXP
|
||||
This is similar to @code{FLT_MAX_EXP}, but is for the @code{long double}
|
||||
data type.
|
||||
@end defvr
|
||||
|
||||
@comment float.h
|
||||
@comment ISO
|
||||
@defvr Macro FLT_MAX_10_EXP
|
||||
This is the maximum negative integer such that the mathematical value
|
||||
@code{10} raised to this power minus 1 can be represented as a
|
||||
normalized floating-point number of type @code{float}. This is
|
||||
guaranteed to be at least @code{37}.
|
||||
@end defvr
|
||||
|
||||
@comment float.h
|
||||
@comment ISO
|
||||
@defvr Macro DBL_MAX_10_EXP
|
||||
This is similar to @code{FLT_MAX_10_EXP}, but is for the @code{double}
|
||||
data type.
|
||||
@end defvr
|
||||
|
||||
@comment float.h
|
||||
@comment ISO
|
||||
@defvr Macro LDBL_MAX_10_EXP
|
||||
This is similar to @code{FLT_MAX_10_EXP}, but is for the @code{long
|
||||
double} data type.
|
||||
@end defvr
|
||||
|
||||
|
||||
@comment float.h
|
||||
@comment ISO
|
||||
@defvr Macro FLT_MAX
|
||||
The value of this macro is the maximum representable floating-point
|
||||
number of type @code{float}, and is guaranteed to be at least
|
||||
@code{1E+37}.
|
||||
@end defvr
|
||||
|
||||
@comment float.h
|
||||
@comment ISO
|
||||
@defvr Macro DBL_MAX
|
||||
The value of this macro is the maximum representable floating-point
|
||||
number of type @code{double}, and is guaranteed to be at least
|
||||
@code{1E+37}.
|
||||
@end defvr
|
||||
|
||||
@comment float.h
|
||||
@comment ISO
|
||||
@defvr Macro LDBL_MAX
|
||||
The value of this macro is the maximum representable floating-point
|
||||
number of type @code{long double}, and is guaranteed to be at least
|
||||
@code{1E+37}.
|
||||
@end defvr
|
||||
|
||||
|
||||
@comment float.h
|
||||
@comment ISO
|
||||
@defvr Macro FLT_MIN
|
||||
The value of this macro is the minimum normalized positive
|
||||
floating-point number that is representable by type @code{float}, and is
|
||||
guaranteed to be no more than @code{1E-37}.
|
||||
@end defvr
|
||||
|
||||
@comment float.h
|
||||
@comment ISO
|
||||
@defvr Macro DBL_MIN
|
||||
The value of this macro is the minimum normalized positive
|
||||
floating-point number that is representable by type @code{double}, and
|
||||
is guaranteed to be no more than @code{1E-37}.
|
||||
@end defvr
|
||||
|
||||
@comment float.h
|
||||
@comment ISO
|
||||
@defvr Macro LDBL_MIN
|
||||
The value of this macro is the minimum normalized positive
|
||||
floating-point number that is representable by type @code{long double},
|
||||
and is guaranteed to be no more than @code{1E-37}.
|
||||
@end defvr
|
||||
|
||||
|
||||
@comment float.h
|
||||
@comment ISO
|
||||
@defvr Macro FLT_EPSILON
|
||||
This is the minimum positive floating-point number of type @code{float}
|
||||
such that @code{1.0 + FLT_EPSILON != 1.0} is true. It's guaranteed to
|
||||
be no greater than @code{1E-5}.
|
||||
@end defvr
|
||||
|
||||
@comment float.h
|
||||
@comment ISO
|
||||
@defvr Macro DBL_EPSILON
|
||||
This is similar to @code{FLT_EPSILON}, but is for the @code{double}
|
||||
type. The maximum value is @code{1E-9}.
|
||||
@end defvr
|
||||
|
||||
@comment float.h
|
||||
@comment ISO
|
||||
@defvr Macro LDBL_EPSILON
|
||||
This is similar to @code{FLT_EPSILON}, but is for the @code{long double}
|
||||
type. The maximum value is @code{1E-9}.
|
||||
@end defvr
|
||||
|
||||
|
||||
|
||||
@node IEEE Floating Point
|
||||
@section IEEE Floating Point
|
||||
|
||||
Here is an example showing how these parameters work for a common
|
||||
floating point representation, specified by the @cite{IEEE Standard for
|
||||
Binary Floating-Point Arithmetic (ANSI/IEEE Std 754-1985 or ANSI/IEEE
|
||||
Std 854-1987)}.
|
||||
|
||||
The IEEE single-precision float representation uses a base of 2. There
|
||||
is a sign bit, a mantissa with 23 bits plus one hidden bit (so the total
|
||||
precision is 24 base-2 digits), and an 8-bit exponent that can represent
|
||||
values in the range -125 to 128, inclusive.
|
||||
|
||||
So, for an implementation that uses this representation for the
|
||||
@code{float} data type, appropriate values for the corresponding
|
||||
parameters are:
|
||||
|
||||
@example
|
||||
FLT_RADIX 2
|
||||
FLT_MANT_DIG 24
|
||||
FLT_DIG 6
|
||||
FLT_MIN_EXP -125
|
||||
FLT_MIN_10_EXP -37
|
||||
FLT_MAX_EXP 128
|
||||
FLT_MAX_10_EXP +38
|
||||
FLT_MIN 1.17549435E-38F
|
||||
FLT_MAX 3.40282347E+38F
|
||||
FLT_EPSILON 1.19209290E-07F
|
||||
@end example
|
||||
@@ -1,593 +0,0 @@
|
||||
@node Representation Limits, System Configuration Limits, System Information, Top
|
||||
@chapter Representation Limits
|
||||
|
||||
This chapter contains information about constants and parameters that
|
||||
characterize the representation of the various integer and
|
||||
floating-point types supported by the GNU C library.
|
||||
|
||||
@menu
|
||||
* Integer Representation Limits:: Determining maximum and minimum
|
||||
representation values of
|
||||
various integer subtypes.
|
||||
* Floating-Point Limits :: Parameters which characterize
|
||||
supported floating-point
|
||||
representations on a particular
|
||||
system.
|
||||
@end menu
|
||||
|
||||
@node Integer Representation Limits, Floating-Point Limits , , Representation Limits
|
||||
@section Integer Representation Limits
|
||||
@cindex integer representation limits
|
||||
@cindex representation limits, integer
|
||||
@cindex limits, integer representation
|
||||
|
||||
Sometimes it is necessary for programs to know about the internal
|
||||
representation of various integer subtypes. For example, if you want
|
||||
your program to be careful not to overflow an @code{int} counter
|
||||
variable, you need to know what the largest representable value that
|
||||
fits in an @code{int} is. These kinds of parameters can vary from
|
||||
compiler to compiler and machine to machine. Another typical use of
|
||||
this kind of parameter is in conditionalizing data structure definitions
|
||||
with @samp{#ifdef} to select the most appropriate integer subtype that
|
||||
can represent the required range of values.
|
||||
|
||||
Macros representing the minimum and maximum limits of the integer types
|
||||
are defined in the header file @file{limits.h}. The values of these
|
||||
macros are all integer constant expressions.
|
||||
@pindex limits.h
|
||||
|
||||
@comment limits.h
|
||||
@comment ISO
|
||||
@deftypevr Macro int CHAR_BIT
|
||||
This is the number of bits in a @code{char}, usually eight.
|
||||
@end deftypevr
|
||||
|
||||
@comment limits.h
|
||||
@comment ISO
|
||||
@deftypevr Macro int SCHAR_MIN
|
||||
This is the minimum value that can be represented by a @code{signed char}.
|
||||
@end deftypevr
|
||||
|
||||
@comment limits.h
|
||||
@comment ISO
|
||||
@deftypevr Macro int SCHAR_MAX
|
||||
This is the maximum value that can be represented by a @code{signed char}.
|
||||
@end deftypevr
|
||||
|
||||
@comment limits.h
|
||||
@comment ISO
|
||||
@deftypevr Macro int UCHAR_MAX
|
||||
This is the maximum value that can be represented by a @code{unsigned char}.
|
||||
(The minimum value of an @code{unsigned char} is zero.)
|
||||
@end deftypevr
|
||||
|
||||
@comment limits.h
|
||||
@comment ISO
|
||||
@deftypevr Macro int CHAR_MIN
|
||||
This is the minimum value that can be represented by a @code{char}.
|
||||
It's equal to @code{SCHAR_MIN} if @code{char} is signed, or zero
|
||||
otherwise.
|
||||
@end deftypevr
|
||||
|
||||
@comment limits.h
|
||||
@comment ISO
|
||||
@deftypevr Macro int CHAR_MAX
|
||||
This is the maximum value that can be represented by a @code{char}.
|
||||
It's equal to @code{SCHAR_MAX} if @code{char} is signed, or
|
||||
@code{UCHAR_MAX} otherwise.
|
||||
@end deftypevr
|
||||
|
||||
@comment limits.h
|
||||
@comment ISO
|
||||
@deftypevr Macro int SHRT_MIN
|
||||
This is the minimum value that can be represented by a @code{signed
|
||||
short int}. On most machines that the GNU C library runs on,
|
||||
@code{short} integers are 16-bit quantities.
|
||||
@end deftypevr
|
||||
|
||||
@comment limits.h
|
||||
@comment ISO
|
||||
@deftypevr Macro int SHRT_MAX
|
||||
This is the maximum value that can be represented by a @code{signed
|
||||
short int}.
|
||||
@end deftypevr
|
||||
|
||||
@comment limits.h
|
||||
@comment ISO
|
||||
@deftypevr Macro int USHRT_MAX
|
||||
This is the maximum value that can be represented by an @code{unsigned
|
||||
short int}. (The minimum value of an @code{unsigned short int} is zero.)
|
||||
@end deftypevr
|
||||
|
||||
@comment limits.h
|
||||
@comment ISO
|
||||
@deftypevr Macro int INT_MIN
|
||||
This is the minimum value that can be represented by a @code{signed
|
||||
int}. On most machines that the GNU C system runs on, an @code{int} is
|
||||
a 32-bit quantity.
|
||||
@end deftypevr
|
||||
|
||||
@comment limits.h
|
||||
@comment ISO
|
||||
@deftypevr Macro int INT_MAX
|
||||
This is the maximum value that can be represented by a @code{signed
|
||||
int}.
|
||||
@end deftypevr
|
||||
|
||||
@comment limits.h
|
||||
@comment ISO
|
||||
@deftypevr Macro {unsigned int} UINT_MAX
|
||||
This is the maximum value that can be represented by an @code{unsigned
|
||||
int}. (The minimum value of an @code{unsigned int} is zero.)
|
||||
@end deftypevr
|
||||
|
||||
@comment limits.h
|
||||
@comment ISO
|
||||
@deftypevr Macro {long int} LONG_MIN
|
||||
This is the minimum value that can be represented by a @code{signed long
|
||||
int}. On most machines that the GNU C system runs on, @code{long}
|
||||
integers are 32-bit quantities, the same size as @code{int}.
|
||||
@end deftypevr
|
||||
|
||||
@comment limits.h
|
||||
@comment ISO
|
||||
@deftypevr Macro {long int} LONG_MAX
|
||||
This is the maximum value that can be represented by a @code{signed long
|
||||
int}.
|
||||
@end deftypevr
|
||||
|
||||
@comment limits.h
|
||||
@comment ISO
|
||||
@deftypevr Macro {unsigned long int} ULONG_MAX
|
||||
This is the maximum value that can be represented by an @code{unsigned
|
||||
long int}. (The minimum value of an @code{unsigned long int} is zero.)
|
||||
@end deftypevr
|
||||
|
||||
@strong{Incomplete:} There should be corresponding limits for the GNU
|
||||
C Compiler's @code{long long} type, too. (But they are not now present
|
||||
in the header file.)
|
||||
|
||||
The header file @file{limits.h} also defines some additional constants
|
||||
that parameterize various operating system and file system limits. These
|
||||
constants are described in @ref{System Parameters} and @ref{File System
|
||||
Parameters}.
|
||||
@pindex limits.h
|
||||
|
||||
|
||||
@node Floating-Point Limits , , Integer Representation Limits, Representation Limits
|
||||
@section Floating-Point Limits
|
||||
@cindex floating-point number representation
|
||||
@cindex representation, floating-point number
|
||||
@cindex limits, floating-point representation
|
||||
|
||||
Because floating-point numbers are represented internally as approximate
|
||||
quantities, algorithms for manipulating floating-point data often need
|
||||
to be parameterized in terms of the accuracy of the representation.
|
||||
Some of the functions in the C library itself need this information; for
|
||||
example, the algorithms for printing and reading floating-point numbers
|
||||
(@pxref{I/O on Streams}) and for calculating trigonometric and
|
||||
irrational functions (@pxref{Mathematics}) use information about the
|
||||
underlying floating-point representation to avoid round-off error and
|
||||
loss of accuracy. User programs that implement numerical analysis
|
||||
techniques also often need to be parameterized in this way in order to
|
||||
minimize or compute error bounds.
|
||||
|
||||
The specific representation of floating-point numbers varies from
|
||||
machine to machine. The GNU C library defines a set of parameters which
|
||||
characterize each of the supported floating-point representations on a
|
||||
particular system.
|
||||
|
||||
@menu
|
||||
* Floating-Point Representation:: Definitions of terminology.
|
||||
* Floating-Point Parameters:: Descriptions of the library
|
||||
facilities.
|
||||
* IEEE Floating Point:: An example of a common
|
||||
representation.
|
||||
@end menu
|
||||
|
||||
@node Floating-Point Representation, Floating-Point Parameters, , Floating-Point Limits
|
||||
@subsection Floating-Point Representation
|
||||
|
||||
This section introduces the terminology used to characterize the
|
||||
representation of floating-point numbers.
|
||||
|
||||
You are probably already familiar with most of these concepts in terms
|
||||
of scientific or exponential notation for floating-point numbers. For
|
||||
example, the number @code{123456.0} could be expressed in exponential
|
||||
notation as @code{1.23456e+05}, a shorthand notation indicating that the
|
||||
mantissa @code{1.23456} is multiplied by the base @code{10} raised to
|
||||
power @code{5}.
|
||||
|
||||
More formally, the internal representation of a floating-point number
|
||||
can be characterized in terms of the following parameters:
|
||||
|
||||
@itemize @bullet
|
||||
@item
|
||||
The @dfn{sign} is either @code{-1} or @code{1}.
|
||||
@cindex sign (of floating-point number)
|
||||
|
||||
@item
|
||||
The @dfn{base} or @dfn{radix} for exponentiation; an integer greater
|
||||
than @code{1}. This is a constant for the particular representation.
|
||||
@cindex base (of floating-point number)
|
||||
@cindex radix (of floating-point number)
|
||||
|
||||
@item
|
||||
The @dfn{exponent} to which the base is raised. The upper and lower
|
||||
bounds of the exponent value are constants for the particular
|
||||
representation.
|
||||
@cindex exponent (of floating-point number)
|
||||
|
||||
Sometimes, in the actual bits representing the floating-point number,
|
||||
the exponent is @dfn{biased} by adding a constant to it, to make it
|
||||
always be represented as an unsigned quantity. This is only important
|
||||
if you have some reason to pick apart the bit fields making up the
|
||||
floating-point number by hand, which is something for which the GNU
|
||||
library provides no support. So this is ignored in the discussion that
|
||||
follows.
|
||||
@cindex bias (of floating-point number exponent)
|
||||
|
||||
@item
|
||||
The value of the @dfn{mantissa} or @dfn{significand}, which is an
|
||||
unsigned integer.
|
||||
@cindex mantissa (of floating-point number)
|
||||
@cindex significand (of floating-point number)
|
||||
|
||||
@item
|
||||
The @dfn{precision} of the mantissa. If the base of the representation
|
||||
is @var{b}, then the precision is the number of base-@var{b} digits in
|
||||
the mantissa. This is a constant for the particular representation.
|
||||
|
||||
Many floating-point representations have an implicit @dfn{hidden bit} in
|
||||
the mantissa. Any such hidden bits are counted in the precision.
|
||||
Again, the GNU library provides no facilities for dealing with such low-level
|
||||
aspects of the representation.
|
||||
@cindex precision (of floating-point number)
|
||||
@cindex hidden bit (of floating-point number mantissa)
|
||||
@end itemize
|
||||
|
||||
The mantissa of a floating-point number actually represents an implicit
|
||||
fraction whose denominator is the base raised to the power of the
|
||||
precision. Since the largest representable mantissa is one less than
|
||||
this denominator, the value of the fraction is always strictly less than
|
||||
@code{1}. The mathematical value of a floating-point number is then the
|
||||
product of this fraction; the sign; and the base raised to the exponent.
|
||||
|
||||
If the floating-point number is @dfn{normalized}, the mantissa is also
|
||||
greater than or equal to the base raised to the power of one less
|
||||
than the precision (unless the number represents a floating-point zero,
|
||||
in which case the mantissa is zero). The fractional quantity is
|
||||
therefore greater than or equal to @code{1/@var{b}}, where @var{b} is
|
||||
the base.
|
||||
@cindex normalized floating-point number
|
||||
|
||||
@node Floating-Point Parameters, IEEE Floating Point, Floating-Point Representation, Floating-Point Limits
|
||||
@subsection Floating-Point Parameters
|
||||
|
||||
@strong{Incomplete:} This section needs some more concrete examples
|
||||
of what these parameters mean and how to use them in a program.
|
||||
|
||||
These macro definitions can be accessed by including the header file
|
||||
@file{float.h} in your program.
|
||||
@pindex float.h
|
||||
|
||||
Macro names starting with @samp{FLT_} refer to the @code{float} type,
|
||||
while names beginning with @samp{DBL_} refer to the @code{double} type
|
||||
and names beginning with @samp{LDBL_} refer to the @code{long double}
|
||||
type. (In implementations that do not support @code{long double} as
|
||||
a distinct data type, the values for those constants are the same
|
||||
as the corresponding constants for the @code{double} type.)@refill
|
||||
@cindex @code{float} representation limits
|
||||
@cindex @code{double} representation limits
|
||||
@cindex @code{long double} representation limits
|
||||
|
||||
Of these macros, only @code{FLT_RADIX} is guaranteed to be a constant
|
||||
expression. The other macros listed here cannot be reliably used in
|
||||
places that require constant expressions, such as @samp{#if}
|
||||
preprocessing directives or array size specifications.
|
||||
|
||||
Although the @w{ISO C} standard specifies minimum and maximum values for
|
||||
most of these parameters, the GNU C implementation uses whatever
|
||||
floating-point representations are supported by the underlying hardware.
|
||||
So whether GNU C actually satisfies the @w{ISO C} requirements depends on
|
||||
what machine it is running on.
|
||||
|
||||
@comment float.h
|
||||
@comment ISO
|
||||
@deftypevr Macro int FLT_ROUNDS
|
||||
This value characterizes the rounding mode for floating-point addition.
|
||||
The following values indicate standard rounding modes:
|
||||
|
||||
@table @code
|
||||
@item -1
|
||||
The mode is indeterminable.
|
||||
@item 0
|
||||
Rounding is towards zero.
|
||||
@item 1
|
||||
Rounding is to the nearest number.
|
||||
@item 2
|
||||
Rounding is towards positive infinity.
|
||||
@item 3
|
||||
Rounding is towards negative infinity.
|
||||
@end table
|
||||
|
||||
@noindent
|
||||
Any other value represents a machine-dependent nonstandard rounding
|
||||
mode.
|
||||
@end deftypevr
|
||||
|
||||
@comment float.h
|
||||
@comment ISO
|
||||
@deftypevr Macro int FLT_RADIX
|
||||
This is the value of the base, or radix, of exponent representation.
|
||||
This is guaranteed to be a constant expression, unlike the other macros
|
||||
described in this section.
|
||||
@end deftypevr
|
||||
|
||||
@comment float.h
|
||||
@comment ISO
|
||||
@deftypevr Macro int FLT_MANT_DIG
|
||||
This is the number of base-@code{FLT_RADIX} digits in the floating-point
|
||||
mantissa for the @code{float} data type.
|
||||
@end deftypevr
|
||||
|
||||
@comment float.h
|
||||
@comment ISO
|
||||
@deftypevr Macro int DBL_MANT_DIG
|
||||
This is the number of base-@code{FLT_RADIX} digits in the floating-point
|
||||
mantissa for the @code{double} data type.
|
||||
@end deftypevr
|
||||
|
||||
@comment float.h
|
||||
@comment ISO
|
||||
@deftypevr Macro int LDBL_MANT_DIG
|
||||
This is the number of base-@code{FLT_RADIX} digits in the floating-point
|
||||
mantissa for the @code{long double} data type.
|
||||
@end deftypevr
|
||||
|
||||
@comment float.h
|
||||
@comment ISO
|
||||
@deftypevr Macro int FLT_DIG
|
||||
This is the number of decimal digits of precision for the @code{float}
|
||||
data type. Technically, if @var{p} and @var{b} are the precision and
|
||||
base (respectively) for the representation, then the decimal precision
|
||||
@var{q} is the maximum number of decimal digits such that any floating
|
||||
point number with @var{q} base 10 digits can be rounded to a floating
|
||||
point number with @var{p} base @var{b} digits and back again, without
|
||||
change to the @var{q} decimal digits.
|
||||
|
||||
The value of this macro is guaranteed to be at least @code{6}.
|
||||
@end deftypevr
|
||||
|
||||
@comment float.h
|
||||
@comment ISO
|
||||
@deftypevr Macro int DBL_DIG
|
||||
This is similar to @code{FLT_DIG}, but is for the @code{double} data
|
||||
type. The value of this macro is guaranteed to be at least @code{10}.
|
||||
@end deftypevr
|
||||
|
||||
@comment float.h
|
||||
@comment ISO
|
||||
@deftypevr Macro int LDBL_DIG
|
||||
This is similar to @code{FLT_DIG}, but is for the @code{long double}
|
||||
data type. The value of this macro is guaranteed to be at least
|
||||
@code{10}.
|
||||
@end deftypevr
|
||||
|
||||
@comment float.h
|
||||
@comment ISO
|
||||
@deftypevr Macro int FLT_MIN_EXP
|
||||
This is the minimum negative integer such that the mathematical value
|
||||
@code{FLT_RADIX} raised to this power minus 1 can be represented as a
|
||||
normalized floating-point number of type @code{float}. In terms of the
|
||||
actual implementation, this is just the smallest value that can be
|
||||
represented in the exponent field of the number.
|
||||
@end deftypevr
|
||||
|
||||
@comment float.h
|
||||
@comment ISO
|
||||
@deftypevr Macro int DBL_MIN_EXP
|
||||
This is similar to @code{FLT_MIN_EXP}, but is for the @code{double} data
|
||||
type.
|
||||
@end deftypevr
|
||||
|
||||
@comment float.h
|
||||
@comment ISO
|
||||
@deftypevr Macro int LDBL_MIN_EXP
|
||||
This is similar to @code{FLT_MIN_EXP}, but is for the @code{long double}
|
||||
data type.
|
||||
@end deftypevr
|
||||
|
||||
@comment float.h
|
||||
@comment ISO
|
||||
@deftypevr Macro int FLT_MIN_10_EXP
|
||||
This is the minimum negative integer such that the mathematical value
|
||||
@code{10} raised to this power minus 1 can be represented as a
|
||||
normalized floating-point number of type @code{float}. This is
|
||||
guaranteed to be no greater than @code{-37}.
|
||||
@end deftypevr
|
||||
|
||||
@comment float.h
|
||||
@comment ISO
|
||||
@deftypevr Macro int DBL_MIN_10_EXP
|
||||
This is similar to @code{FLT_MIN_10_EXP}, but is for the @code{double}
|
||||
data type.
|
||||
@end deftypevr
|
||||
|
||||
@comment float.h
|
||||
@comment ISO
|
||||
@deftypevr Macro int LDBL_MIN_10_EXP
|
||||
This is similar to @code{FLT_MIN_10_EXP}, but is for the @code{long
|
||||
double} data type.
|
||||
@end deftypevr
|
||||
|
||||
|
||||
|
||||
@comment float.h
|
||||
@comment ISO
|
||||
@deftypevr Macro int FLT_MAX_EXP
|
||||
This is the maximum negative integer such that the mathematical value
|
||||
@code{FLT_RADIX} raised to this power minus 1 can be represented as a
|
||||
floating-point number of type @code{float}. In terms of the actual
|
||||
implementation, this is just the largest value that can be represented
|
||||
in the exponent field of the number.
|
||||
@end deftypevr
|
||||
|
||||
@comment float.h
|
||||
@comment ISO
|
||||
@deftypevr Macro int DBL_MAX_EXP
|
||||
This is similar to @code{FLT_MAX_EXP}, but is for the @code{double} data
|
||||
type.
|
||||
@end deftypevr
|
||||
|
||||
@comment float.h
|
||||
@comment ISO
|
||||
@deftypevr Macro int LDBL_MAX_EXP
|
||||
This is similar to @code{FLT_MAX_EXP}, but is for the @code{long double}
|
||||
data type.
|
||||
@end deftypevr
|
||||
|
||||
@comment float.h
|
||||
@comment ISO
|
||||
@deftypevr Macro int FLT_MAX_10_EXP
|
||||
This is the maximum negative integer such that the mathematical value
|
||||
@code{10} raised to this power minus 1 can be represented as a
|
||||
normalized floating-point number of type @code{float}. This is
|
||||
guaranteed to be at least @code{37}.
|
||||
@end deftypevr
|
||||
|
||||
@comment float.h
|
||||
@comment ISO
|
||||
@deftypevr Macro int DBL_MAX_10_EXP
|
||||
This is similar to @code{FLT_MAX_10_EXP}, but is for the @code{double}
|
||||
data type.
|
||||
@end deftypevr
|
||||
|
||||
@comment float.h
|
||||
@comment ISO
|
||||
@deftypevr Macro int LDBL_MAX_10_EXP
|
||||
This is similar to @code{FLT_MAX_10_EXP}, but is for the @code{long
|
||||
double} data type.
|
||||
@end deftypevr
|
||||
|
||||
|
||||
@comment float.h
|
||||
@comment ISO
|
||||
@deftypevr Macro double FLT_MAX
|
||||
The value of this macro is the maximum representable floating-point
|
||||
number of type @code{float}, and is guaranteed to be at least
|
||||
@code{1E+37}.
|
||||
@end deftypevr
|
||||
|
||||
@comment float.h
|
||||
@comment ISO
|
||||
@deftypevr Macro double DBL_MAX
|
||||
The value of this macro is the maximum representable floating-point
|
||||
number of type @code{double}, and is guaranteed to be at least
|
||||
@code{1E+37}.
|
||||
@end deftypevr
|
||||
|
||||
@comment float.h
|
||||
@comment ISO
|
||||
@deftypevr Macro {long double} LDBL_MAX
|
||||
The value of this macro is the maximum representable floating-point
|
||||
number of type @code{long double}, and is guaranteed to be at least
|
||||
@code{1E+37}.
|
||||
@end deftypevr
|
||||
|
||||
|
||||
@comment float.h
|
||||
@comment ISO
|
||||
@deftypevr Macro double FLT_MIN
|
||||
The value of this macro is the minimum normalized positive
|
||||
floating-point number that is representable by type @code{float}, and is
|
||||
guaranteed to be no more than @code{1E-37}.
|
||||
@end deftypevr
|
||||
|
||||
@comment float.h
|
||||
@comment ISO
|
||||
@deftypevr Macro double DBL_MIN
|
||||
The value of this macro is the minimum normalized positive
|
||||
floating-point number that is representable by type @code{double}, and
|
||||
is guaranteed to be no more than @code{1E-37}.
|
||||
@end deftypevr
|
||||
|
||||
@comment float.h
|
||||
@comment ISO
|
||||
@deftypevr Macro {long double} LDBL_MIN
|
||||
The value of this macro is the minimum normalized positive
|
||||
floating-point number that is representable by type @code{long double},
|
||||
and is guaranteed to be no more than @code{1E-37}.
|
||||
@end deftypevr
|
||||
|
||||
|
||||
@comment float.h
|
||||
@comment ISO
|
||||
@deftypevr Macro double FLT_EPSILON
|
||||
This is the minimum positive floating-point number of type @code{float}
|
||||
such that @code{1.0 + FLT_EPSILON != 1.0} is true. It's guaranteed to
|
||||
be no greater than @code{1E-5}.
|
||||
@end deftypevr
|
||||
|
||||
@comment float.h
|
||||
@comment ISO
|
||||
@deftypevr Macro double DBL_EPSILON
|
||||
This is similar to @code{FLT_EPSILON}, but is for the @code{double}
|
||||
type. The maximum value is @code{1E-9}.
|
||||
@end deftypevr
|
||||
|
||||
@comment float.h
|
||||
@comment ISO
|
||||
@deftypevr Macro {long double} LDBL_EPSILON
|
||||
This is similar to @code{FLT_EPSILON}, but is for the @code{long double}
|
||||
type. The maximum value is @code{1E-9}.
|
||||
@end deftypevr
|
||||
|
||||
|
||||
@node IEEE Floating Point, , Floating-Point Parameters, Floating-Point Limits
|
||||
@subsection IEEE Floating Point
|
||||
@cindex IEEE floating-point representation
|
||||
@cindex floating-point, IEEE
|
||||
@cindex IEEE Std 754
|
||||
|
||||
|
||||
Here is an example showing how these parameters work for a common
|
||||
floating point representation, specified by the @cite{IEEE Standard for
|
||||
Binary Floating-Point Arithmetic (ANSI/IEEE Std 754-1985 or ANSI/IEEE
|
||||
Std 854-1987)}. Nearly all computers today use this format.
|
||||
|
||||
The IEEE single-precision float representation uses a base of 2. There
|
||||
is a sign bit, a mantissa with 23 bits plus one hidden bit (so the total
|
||||
precision is 24 base-2 digits), and an 8-bit exponent that can represent
|
||||
values in the range -125 to 128, inclusive.
|
||||
|
||||
So, for an implementation that uses this representation for the
|
||||
@code{float} data type, appropriate values for the corresponding
|
||||
parameters are:
|
||||
|
||||
@example
|
||||
FLT_RADIX 2
|
||||
FLT_MANT_DIG 24
|
||||
FLT_DIG 6
|
||||
FLT_MIN_EXP -125
|
||||
FLT_MIN_10_EXP -37
|
||||
FLT_MAX_EXP 128
|
||||
FLT_MAX_10_EXP +38
|
||||
FLT_MIN 1.17549435E-38F
|
||||
FLT_MAX 3.40282347E+38F
|
||||
FLT_EPSILON 1.19209290E-07F
|
||||
@end example
|
||||
|
||||
Here are the values for the @code{double} data type:
|
||||
|
||||
@example
|
||||
DBL_MANT_DIG 53
|
||||
DBL_DIG 15
|
||||
DBL_MIN_EXP -1021
|
||||
DBL_MIN_10_EXP -307
|
||||
DBL_MAX_EXP 1024
|
||||
DBL_MAX_10_EXP 308
|
||||
DBL_MAX 1.7976931348623157E+308
|
||||
DBL_MIN 2.2250738585072014E-308
|
||||
DBL_EPSILON 2.2204460492503131E-016
|
||||
@end example
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,290 +0,0 @@
|
||||
@node Variable Argument Facilities, Memory Allocation, Common Definitions, Top
|
||||
@chapter Variable Argument Facilities
|
||||
@cindex variadic argument functions
|
||||
@cindex variadic functions
|
||||
@cindex variable number of arguments
|
||||
@cindex optional arguments
|
||||
|
||||
@w{ISO C} defines a syntax as part of the kernel language for specifying
|
||||
functions that take a variable number or type of arguments. (Such
|
||||
functions are also referred to as @dfn{variadic functions}.) However,
|
||||
the kernel language provides no mechanism for actually accessing
|
||||
non-required arguments; instead, you use the variable arguments macros
|
||||
defined in @file{stdarg.h}.
|
||||
@pindex stdarg.h
|
||||
|
||||
@menu
|
||||
* Why Variable Arguments are Used:: Using variable arguments can
|
||||
save you time and effort.
|
||||
* How Variable Arguments are Used:: An overview of the facilities for
|
||||
receiving variable arguments.
|
||||
* Variable Arguments Interface:: Detailed specification of the
|
||||
library facilities.
|
||||
* Example of Variable Arguments:: A complete example.
|
||||
@end menu
|
||||
|
||||
@node Why Variable Arguments are Used, How Variable Arguments are Used, , Variable Argument Facilities
|
||||
@section Why Variable Arguments are Used
|
||||
|
||||
Most C functions take a fixed number of arguments. When you define a
|
||||
function, you also supply a specific data type for each argument.
|
||||
Every call to the function should supply the same number and type of
|
||||
arguments as specified in the function definition.
|
||||
|
||||
On the other hand, sometimes a function performs an operation that can
|
||||
meaningfully accept an unlimited number of arguments.
|
||||
|
||||
For example, consider a function that joins its arguments into a linked
|
||||
list. It makes sense to connect any number of arguments together into a
|
||||
list of arbitrary length. Without facilities for variable arguments,
|
||||
you would have to define a separate function for each possible number of
|
||||
arguments you might want to link together. This is an example of a
|
||||
situation where some kind of mapping or iteration is performed over an
|
||||
arbitrary number of arguments of the same type.
|
||||
|
||||
Another kind of application where variable arguments can be useful is
|
||||
for functions where values for some arguments can simply be omitted in
|
||||
some calls, either because they are not used at all or because the
|
||||
function can determine appropriate defaults for them if they're missing.
|
||||
|
||||
The library function @code{printf} (@pxref{Formatted Output}) is an
|
||||
example of still another class of function where variable arguments are
|
||||
useful. This function prints its arguments (which can vary in type as
|
||||
well as number) under the control of a format template string.
|
||||
|
||||
@node How Variable Arguments are Used, Variable Arguments Interface, Why Variable Arguments are Used, Variable Argument Facilities
|
||||
@section How Variable Arguments are Used
|
||||
|
||||
This section describes how you can define and call functions that take
|
||||
variable arguments, and how to access the values of the non-required
|
||||
arguments.
|
||||
|
||||
@menu
|
||||
* Syntax for Variable Arguments:: How to make a prototype for a
|
||||
function with variable arguments.
|
||||
* Receiving the Argument Values:: Steps you must follow to access the
|
||||
optional argument values.
|
||||
* How Many Arguments:: How to decide whether there are more
|
||||
arguments.
|
||||
* Calling Variadic Functions:: Things you need to know about calling
|
||||
variable arguments functions.
|
||||
@end menu
|
||||
|
||||
@node Syntax for Variable Arguments, Receiving the Argument Values, , How Variable Arguments are Used
|
||||
@subsection Syntax for Variable Arguments
|
||||
|
||||
A function that accepts a variable number of arguments must have at
|
||||
least one required argument with a specified type. In the function
|
||||
definition or prototype declaration, you indicate the fact that a
|
||||
function can accept additional arguments of unspecified type by putting
|
||||
@samp{@dots{}} at the end of the arguments. For example,
|
||||
|
||||
@example
|
||||
int
|
||||
func (const char *a, int b, @dots{})
|
||||
@{
|
||||
@dots{}
|
||||
@}
|
||||
@end example
|
||||
|
||||
@noindent
|
||||
outlines a definition of a function @code{func} which returns an
|
||||
@code{int} and takes at least two arguments, the first two being a
|
||||
@code{const char *} and an @code{int}.@refill
|
||||
|
||||
An obscure restriction placed by the @w{ISO C} standard is that the last
|
||||
required argument must not be declared @code{register} in the function
|
||||
definition. Furthermore, this argument must not be of a function or
|
||||
array type, and may not be, for example, a @code{char} or @code{short
|
||||
int} (whether signed or not) or a @code{float}.
|
||||
|
||||
@strong{Compatibility Note:} Many older C dialects provide a similar,
|
||||
but incompatible, mechanism for defining functions with variable numbers
|
||||
of arguments. In particular, the @samp{@dots{}} syntax is a new feature
|
||||
of @w{ISO C}.
|
||||
|
||||
|
||||
@node Receiving the Argument Values, How Many Arguments, Syntax for Variable Arguments, How Variable Arguments are Used
|
||||
@subsection Receiving the Argument Values
|
||||
|
||||
Inside the definition of a variadic function, to access the optional
|
||||
arguments with the following three step process:
|
||||
|
||||
@enumerate
|
||||
@item
|
||||
You initialize an argument pointer variable of type @code{va_list} using
|
||||
@code{va_start}.
|
||||
|
||||
@item
|
||||
You access the optional arguments by successive calls to @code{va_arg}.
|
||||
|
||||
@item
|
||||
You call @code{va_end} to indicate that you are finished accessing the
|
||||
arguments.
|
||||
@end enumerate
|
||||
|
||||
Steps 1 and 3 must be performed in the function that is defined to
|
||||
accept variable arguments. However, you can pass the @code{va_list}
|
||||
variable as an argument to another function and perform all or part of
|
||||
step 2 there. After doing this, the value of the @code{va_list}
|
||||
variable in the calling function becomes undefined for further calls to
|
||||
@code{va_arg}; you should just pass it to @code{va_end}.
|
||||
|
||||
You can perform the entire sequence of the three steps multiple times
|
||||
within a single function invocation. And, if the function doesn't want
|
||||
to look at its optional arguments at all, it doesn't have to do any of
|
||||
these steps. It is also perfectly all right for a function to access
|
||||
fewer arguments than were supplied in the call, but you will get garbage
|
||||
values if you try to access too many arguments.
|
||||
|
||||
|
||||
@node How Many Arguments, Calling Variadic Functions, Receiving the Argument Values, How Variable Arguments are Used
|
||||
@subsection How Many Arguments Were Supplied
|
||||
|
||||
There is no general way for a function to determine the number and type
|
||||
of the actual values that were passed as optional arguments. Typically,
|
||||
the value of one of the required arguments is used to tell the function
|
||||
this information. It is up to you to define an appropriate calling
|
||||
convention for each function, and write all calls accordingly.
|
||||
|
||||
One calling convention is to make one of the required arguments be an
|
||||
explicit argument count. This convention is usable if all of the
|
||||
optional arguments are of the same type.
|
||||
|
||||
A required argument can be used as a pattern to specify both the number
|
||||
and types of the optional arguments. The format template string
|
||||
argument to @code{printf} is one example of this.
|
||||
|
||||
A similar technique that is sometimes used is to have one of the
|
||||
required arguments be a bit mask, with a bit for each possible optional
|
||||
argument that might be supplied. The bits are tested in a predefined
|
||||
sequence; if the bit is set, the value of the next argument is
|
||||
retrieved, and otherwise a default value is used.
|
||||
|
||||
Another technique that is sometimes used is to pass an ``end marker''
|
||||
value as the last optional argument. For example, for a function that
|
||||
manipulates an arbitrary number of pointer arguments, a null pointer
|
||||
might indicate the end of the argument list, provided that a null
|
||||
pointer isn't otherwise meaningful to the function.
|
||||
|
||||
|
||||
@node Calling Variadic Functions, , How Many Arguments, How Variable Arguments are Used
|
||||
@subsection Calling Variadic Functions
|
||||
|
||||
Functions that are @emph{defined} to be variadic must also be
|
||||
@emph{declared} to be variadic using a function prototype in the scope
|
||||
of all calls to it. This is because C compilers might use a different
|
||||
internal function call protocol for variadic functions than for
|
||||
functions that take a fixed number and type of arguments. If the
|
||||
compiler can't determine in advance that the function being called is
|
||||
variadic, it may end up trying to call it incorrectly and your program
|
||||
won't work.
|
||||
@cindex function prototypes
|
||||
@cindex prototypes for variadic functions
|
||||
@cindex variadic functions need prototypes
|
||||
|
||||
Since the prototype doesn't specify types for optional arguments, in a
|
||||
call to a variadic function the @dfn{default argument promotions} are
|
||||
performed on the optional argument values. This means the objects of
|
||||
type @code{char} or @code{short int} (whether signed or not) are
|
||||
promoted to either @code{int} or @code{unsigned int}, as appropriate;
|
||||
and that objects of type @code{float} are promoted to type
|
||||
@code{double}. So, if the caller passes a @code{char} as an optional
|
||||
argument, it is promoted to a @code{int}, and the function should get it
|
||||
with @code{va_arg (@var{ap}, int)}.
|
||||
|
||||
Promotions of the required arguments are determined by the function
|
||||
prototype in the usual way (as if by assignment to the types of the
|
||||
corresponding formal parameters).
|
||||
@cindex default argument promotions
|
||||
@cindex argument promotion
|
||||
|
||||
@node Variable Arguments Interface, Example of Variable Arguments, How Variable Arguments are Used, Variable Argument Facilities
|
||||
@section Variable Arguments Interface
|
||||
|
||||
Here are descriptions of the macros used to retrieve variable arguments.
|
||||
These macros are defined in the header file @file{stdarg.h}.
|
||||
@pindex stdarg.h
|
||||
|
||||
@comment stdarg.h
|
||||
@comment ISO
|
||||
@deftp {Data Type} va_list
|
||||
The type @code{va_list} is used for argument pointer variables.
|
||||
@end deftp
|
||||
|
||||
@comment stdarg.h
|
||||
@comment ISO
|
||||
@deftypefn {Macro} void va_start (va_list @var{ap}, @var{last_required})
|
||||
This macro initialized the argument pointer variable @var{ap} to point
|
||||
to the first of the optional arguments of the current function;
|
||||
@var{last_required} must be the last required argument to the function.
|
||||
@end deftypefn
|
||||
|
||||
@comment stdarg.h
|
||||
@comment ISO
|
||||
@deftypefn {Macro} @var{type} va_arg (va_list @var{ap}, @var{type})
|
||||
The @code{va_arg} macro returns the value of the next optional argument,
|
||||
and changes the internal state of @var{ap} to move past this argument.
|
||||
Thus, successive uses of @code{va_arg} return successive optional
|
||||
arguments.
|
||||
The type of the value returned by @code{va_arg} is the @var{type}
|
||||
specified in the call.
|
||||
|
||||
The @var{type} must match the type of the actual argument, and must not
|
||||
be @code{char} or @code{short int} or @code{float}. (Remember that the
|
||||
default argument promotions apply to optional arguments.)
|
||||
@end deftypefn
|
||||
|
||||
@comment stdarg.h
|
||||
@comment ISO
|
||||
@deftypefn {Macro} void va_end (va_list @var{ap})
|
||||
This ends the use of @var{ap}. After a @code{va_end} call, further
|
||||
@code{va_arg} calls with the same @var{ap} may not work. You should invoke
|
||||
@code{va_end} before returning from the function in which @code{va_start}
|
||||
was invoked with the same @var{ap} argument.
|
||||
|
||||
In the GNU C library, @code{va_end} does nothing, and you need not ever
|
||||
use it except for reasons of portability.
|
||||
@refill
|
||||
@end deftypefn
|
||||
|
||||
|
||||
@node Example of Variable Arguments, , Variable Arguments Interface, Variable Argument Facilities
|
||||
@section Example of Variable Arguments
|
||||
|
||||
Here is a complete sample function that accepts variable numbers of
|
||||
arguments. The first argument to the function is the count of remaining
|
||||
arguments, which are added up and the result returned. (This is
|
||||
obviously a rather pointless function, but it serves to illustrate the
|
||||
way the variable arguments facility is commonly used.)
|
||||
|
||||
@comment Yes, this example has been tested.
|
||||
|
||||
@example
|
||||
#include <stdarg.h>
|
||||
|
||||
int
|
||||
add_em_up (int count, @dots{})
|
||||
@{
|
||||
va_list ap;
|
||||
int i, sum;
|
||||
|
||||
va_start (ap, count); /* @r{Initialize the argument list.} */
|
||||
|
||||
sum = 0;
|
||||
for (i = 0; i < count; i++)
|
||||
sum = sum + va_arg (ap, int); /* @r{Get the next argument value.} */
|
||||
|
||||
va_end (ap); /* @r{Clean up.} */
|
||||
return sum;
|
||||
@}
|
||||
|
||||
void main (void)
|
||||
@{
|
||||
/* @r{This call prints 16.} */
|
||||
printf ("%d\n", add_em_up (3, 5, 5, 6));
|
||||
|
||||
/* @r{This call prints 55.} */
|
||||
printf ("%d\n", add_em_up (10, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10));
|
||||
@}
|
||||
@end example
|
||||
@@ -1,81 +0,0 @@
|
||||
@node Common Definitions, Memory Allocation, Error Reporting, Top
|
||||
@chapter Common Definitions
|
||||
|
||||
There are some miscellaneous data types and macros that are not part of
|
||||
the C language kernel but are nonetheless almost universally used, such
|
||||
as the macro @code{NULL}. In order to use these type and macro
|
||||
definitions, your program should include the header file
|
||||
@file{stddef.h}.
|
||||
@pindex stddef.h
|
||||
|
||||
@comment stddef.h
|
||||
@comment ISO
|
||||
@deftp {Data Type} ptrdiff_t
|
||||
This is the signed integer type of the result of subtracting two
|
||||
pointers. For example, with the declaration @code{char *p1, *p2;}, the
|
||||
expression @code{p2 - p1} is of type @code{ptrdiff_t}. This will
|
||||
probably be one of the standard signed integer types (@code{short int},
|
||||
@code{int} or @code{long int}), but might be a nonstandard type that
|
||||
exists only for this purpose.
|
||||
@end deftp
|
||||
|
||||
@comment stddef.h
|
||||
@comment ISO
|
||||
@deftp {Data Type} size_t
|
||||
This is an unsigned integer type used to represent the sizes of objects.
|
||||
The result of the @code{sizeof} operator is of this type, and functions
|
||||
such as @code{malloc} (@pxref{Unconstrained Allocation}) and
|
||||
@code{memcpy} (@pxref{Copying and Concatenation}) that manipulate
|
||||
objects of arbitrary sizes accept arguments of this type to specify
|
||||
object sizes.
|
||||
@end deftp
|
||||
|
||||
In the GNU system @code{size_t} is equivalent to one of the types
|
||||
@code{unsigned int} and @code{unsigned long int}. These types have
|
||||
identical properties on the GNU system, and for most purposes, you
|
||||
can use them interchangeably. However, they are distinct types,
|
||||
and in certain contexts, you may not treat them as identical. For
|
||||
example, when you specify the type of a function argument in a
|
||||
function prototype, it makes a difference which one you use. If
|
||||
the system header files declare @code{malloc} with an argument
|
||||
of type @code{size_t} and you declare @code{malloc} with an argument
|
||||
of type @code{unsigned int}, you will get a compilation error if
|
||||
@code{size_t} happens to be @code{unsigned long int} on your system.
|
||||
To avoid any possibility of error, when a function argument is
|
||||
supposed to have type @code{size_t}, always write the type as
|
||||
@code{size_t}, and make no assumptions about what that type might
|
||||
actually be.
|
||||
|
||||
@strong{Compatibility Note:} Types such as @code{size_t} are new
|
||||
features of @w{ISO C}. Older, pre-ANSI C implementations have
|
||||
traditionally used @code{unsigned int} for representing object sizes
|
||||
and @code{int} for pointer subtraction results.
|
||||
|
||||
@comment stddef.h
|
||||
@comment ISO
|
||||
@deftypevr Macro {void *} NULL
|
||||
@cindex null pointer
|
||||
This is a null pointer constant. It can be assigned to any pointer
|
||||
variable since it has type @code{void *}, and is guaranteed not to
|
||||
point to any real object. This macro is the best way to get a null
|
||||
pointer value. You can also use @code{0} or @code{(void *)0} as a null
|
||||
pointer constant, but using @code{NULL} makes the purpose of the
|
||||
constant more evident.
|
||||
|
||||
When passing a null pointer as an argument to a function for which there
|
||||
is no prototype declaration in scope, you should explicitly cast
|
||||
@code{NULL} or @code{0} into a pointer of the appropriate type. Again,
|
||||
this is because the default argument promotions may not do the right
|
||||
thing.
|
||||
@end deftypevr
|
||||
|
||||
@comment stddef.h
|
||||
@comment ISO
|
||||
@deftypefn {Macro} size_t offsetof (@var{type}, @var{member})
|
||||
This expands to a integer constant expression that is the offset of the
|
||||
structure member named @var{member} in a @code{struct} of type
|
||||
@var{type}. For example, @code{offsetof (struct s, elem)} is the
|
||||
offset, in bytes, of the member @code{elem} in a @code{struct s}. This
|
||||
macro won't work if @var{member} is a bit field; you get an error from
|
||||
the C compiler in that case.
|
||||
@end deftypefn
|
||||
+3
-7
@@ -66,13 +66,9 @@ stamp-summary: summary.awk $(chapters) $(chapters-incl)
|
||||
# Generate a file which can be added to the `dir' content to provide direct
|
||||
# access to the documentation of the function, variables, and other
|
||||
# definitions.
|
||||
dir-add.texi: manual/xtract-typefun.awk $(chapters-incl)
|
||||
if test -n "$(chapters-incl)"; then \
|
||||
(for i in $(chapters-incl); do \
|
||||
$(GAWK) -f $< < $i; \
|
||||
done) | sort > $@.new; \
|
||||
./move-if-change $@.new $@; \
|
||||
fi
|
||||
dir-add.texi: xtract-typefun.awk $(chapters)
|
||||
$(GAWK) -f $^ | sort > $@.new;
|
||||
mv -f $@.new $@
|
||||
|
||||
# Generate Texinfo files from the C source for the example programs.
|
||||
%.c.texi: examples/%.c
|
||||
|
||||
+423
-48
@@ -3,12 +3,17 @@
|
||||
|
||||
This chapter contains information about functions for doing basic
|
||||
arithmetic operations, such as splitting a float into its integer and
|
||||
fractional parts. These functions are declared in the header file
|
||||
@file{math.h}.
|
||||
fractional parts or retrieving the imaginary part of a complex value.
|
||||
These functions are declared in the header files @file{math.h} and
|
||||
@file{complex.h}.
|
||||
|
||||
@menu
|
||||
* Infinity:: What is Infinity and how to test for it.
|
||||
* Not a Number:: Making NaNs and testing for NaNs.
|
||||
* Imaginary Unit:: Constructing complex Numbers.
|
||||
* Predicates on Floats:: Testing for infinity and for NaNs.
|
||||
* Floating-Point Classes:: Classifiy floating-point numbers.
|
||||
* Operations on Complex:: Projections, Conjugates, and Decomposing.
|
||||
* Absolute Value:: Absolute value functions.
|
||||
* Normalization Functions:: Hacks for radix-2 representations.
|
||||
* Rounding and Remainders:: Determining the integer and
|
||||
@@ -19,6 +24,44 @@ fractional parts. These functions are declared in the header file
|
||||
from strings.
|
||||
@end menu
|
||||
|
||||
@node Infinity
|
||||
@section Infinity Values
|
||||
@cindex Infinity
|
||||
@cindex IEEE floating point
|
||||
|
||||
Mathematical operations easily can produce as the result values which
|
||||
are not representable by the floating-point format. The functions in
|
||||
the mathematics library also have this problem. The situation is
|
||||
generally solved by raising an overflow exception and by returning a
|
||||
huge value.
|
||||
|
||||
The @w{IEEE 754} floating-point defines a special value to be used in
|
||||
these situations. There is a special value for infinity.
|
||||
|
||||
@comment math.h
|
||||
@comment ISO
|
||||
@deftypevr Macro float_t INFINITY
|
||||
A expression representing the inifite value. @code{INFINITY} values are
|
||||
produce by mathematical operations like @code{1.0 / 0.0}. It is
|
||||
possible to continue the computations with this value since the basic
|
||||
operations as well as the mathematical library functions are prepared to
|
||||
handle values like this.
|
||||
|
||||
Beside @code{INFINITY} also the value @code{-INIFITY} is representable
|
||||
and it is handled differently if needed. It is possible to test a
|
||||
variables for infinite value using a simple comparison but the
|
||||
recommended way is to use the the @code{isinf} function.
|
||||
|
||||
This macro was introduced in the @w{ISO C 9X} standard.
|
||||
@end deftypevr
|
||||
|
||||
@vindex HUGE_VAL
|
||||
The macros @code{HUGE_VAL}, @code{HUGE_VALF} and @code{HUGE_VALL} are
|
||||
defined in a similar way but they are not required to represent the
|
||||
infinite value, only a very large value (@pxref{Domain and Range Errors}).
|
||||
If actually infinity is wanted, @code{INFINITY} should be used.
|
||||
|
||||
|
||||
@node Not a Number
|
||||
@section ``Not a Number'' Values
|
||||
@cindex NaN
|
||||
@@ -54,6 +97,46 @@ such as by defining @code{_GNU_SOURCE}, and then you must include
|
||||
@file{math.h}.)
|
||||
@end deftypevr
|
||||
|
||||
@node Imaginary Unit
|
||||
@section Constructing complex Numbers
|
||||
|
||||
@pindex complex.h
|
||||
To construct complex numbers it is necessary have a way to express the
|
||||
imaginary part of the numbers. In mathematics one uses the symbol ``i''
|
||||
to mark a number as imaginary. For convenienve the @file{complex.h}
|
||||
header defines two macros which allow to use a similar easy notation.
|
||||
|
||||
@deftypevr Macro float_t _Imaginary_I
|
||||
This macro is a (compiler specific) representation of the value ``1i''.
|
||||
I.e., it is the value for which
|
||||
|
||||
@smallexample
|
||||
_Imaginary_I * _Imaginary_I = -1
|
||||
@end smallexample
|
||||
|
||||
@noindent
|
||||
One can use it to easily construct complex number like in
|
||||
|
||||
@smallexample
|
||||
3.0 - _Imaginary_I * 4.0
|
||||
@end smallexample
|
||||
|
||||
@noindent
|
||||
which results in the complex number with a real part of 3.0 and a
|
||||
imaginary part -4.0.
|
||||
@end deftypevr
|
||||
|
||||
@noindent
|
||||
A more intuitive approach is to use the following macro.
|
||||
|
||||
@deftypevr Macro float_t I
|
||||
This macro has exactly the same value as @code{_Imaginary_I}. The
|
||||
problem is that the name @code{I} very easily can clash with macros or
|
||||
variables in programs and so it might be a good idea to avoid this name
|
||||
and stay at the safe side by using @code{_Imaginary_I}.
|
||||
@end deftypevr
|
||||
|
||||
|
||||
@node Predicates on Floats
|
||||
@section Predicates on Floats
|
||||
|
||||
@@ -66,6 +149,8 @@ functions, and thus are available if you define @code{_BSD_SOURCE} or
|
||||
@comment math.h
|
||||
@comment BSD
|
||||
@deftypefun int isinf (double @var{x})
|
||||
@deftypefunx int isinff (float @var{x})
|
||||
@deftypefunx int isinfl (long double @var{x})
|
||||
This function returns @code{-1} if @var{x} represents negative infinity,
|
||||
@code{1} if @var{x} represents positive infinity, and @code{0} otherwise.
|
||||
@end deftypefun
|
||||
@@ -73,6 +158,8 @@ This function returns @code{-1} if @var{x} represents negative infinity,
|
||||
@comment math.h
|
||||
@comment BSD
|
||||
@deftypefun int isnan (double @var{x})
|
||||
@deftypefunx int isnanf (float @var{x})
|
||||
@deftypefunx int isnanl (long double @var{x})
|
||||
This function returns a nonzero value if @var{x} is a ``not a number''
|
||||
value, and zero otherwise. (You can just as well use @code{@var{x} !=
|
||||
@var{x}} to get the same result).
|
||||
@@ -81,6 +168,8 @@ value, and zero otherwise. (You can just as well use @code{@var{x} !=
|
||||
@comment math.h
|
||||
@comment BSD
|
||||
@deftypefun int finite (double @var{x})
|
||||
@deftypefunx int finitef (float @var{x})
|
||||
@deftypefunx int finitel (long double @var{x})
|
||||
This function returns a nonzero value if @var{x} is finite or a ``not a
|
||||
number'' value, and zero otherwise.
|
||||
@end deftypefun
|
||||
@@ -103,6 +192,179 @@ does not fit the @w{ISO C} specification.
|
||||
@strong{Portability Note:} The functions listed in this section are BSD
|
||||
extensions.
|
||||
|
||||
@node Floating-Point Classes
|
||||
@section Floating-Point Number Classification Functions
|
||||
|
||||
Instead of using the BSD specific functions from the last section it is
|
||||
better to use those in this section will are introduced in the @w{ISO C
|
||||
9X} standard and are therefore widely available.
|
||||
|
||||
@comment math.h
|
||||
@comment ISO
|
||||
@deftypefun int fpclassify (@emph{float-type} @var{x})
|
||||
This is a generic macro which works on all floating-point types and
|
||||
which returns a value of type @code{int}. The possible values are:
|
||||
|
||||
@vtable @code
|
||||
@item FP_NAN
|
||||
The floating-point number @var{x} is ``Not a Number'' (@pxref{Not a Number})
|
||||
@item FP_INFINITE
|
||||
The value of @var{x} is either plus or minus infinity (@pxref{Infinity})
|
||||
@item FP_ZERO
|
||||
The value of @var{x} is zero. In floating-point formats like @w{IEEE
|
||||
754} where the zero value can be signed this value is also returned if
|
||||
@var{x} is minus zero.
|
||||
@item FP_SUBNORMAL
|
||||
Some floating-point formats (such as @w{IEEE 754}) allow floating-point
|
||||
numbers to be represented in a denormalized format. This happens if the
|
||||
absolute value of the number is too small to be represented in the
|
||||
normal format. @code{FP_SUBNORMAL} is returned for such values of @var{x}.
|
||||
@item FP_NORMAL
|
||||
This value is returned for all other cases which means the number is a
|
||||
plain floating-point number without special meaning.
|
||||
@end vtable
|
||||
|
||||
This macro is useful if more than property of a number must be
|
||||
tested. If one only has to test for, e.g., a NaN value, there are
|
||||
function which are faster.
|
||||
@end deftypefun
|
||||
|
||||
The remainder of this section introduces some more specific functions.
|
||||
They might be implemented faster than the call to @code{fpclassify} and
|
||||
if the actual need in the program is covered be these functions they
|
||||
should be used (and not @code{fpclassify}).
|
||||
|
||||
@comment math.h
|
||||
@comment ISO
|
||||
@deftypefun int isfinite (@emph{float-type} @var{x})
|
||||
The value returned by this macro is nonzero if the value of @var{x} is
|
||||
not plus or minus infinity and not NaN. I.e., it could be implemented as
|
||||
|
||||
@smallexample
|
||||
(fpclassify (x) != FP_NAN && fpclassify (x) != FP_INFINITE)
|
||||
@end smallexample
|
||||
|
||||
@code{isfinite} is also implemented as a macro which can handle all
|
||||
floating-point types. Programs should use this function instead of
|
||||
@var{finite} (@pxref{Predicates on Floats}).
|
||||
@end deftypefun
|
||||
|
||||
@comment math.h
|
||||
@comment ISO
|
||||
@deftypefun int isnormal (@emph{float-type} @var{x})
|
||||
If @code{isnormal} returns a nonzero value the value or @var{x} is
|
||||
neither a NaN, infinity, zero, nor a denormalized number. I.e., it
|
||||
could be implemented as
|
||||
|
||||
@smallexample
|
||||
(fpclassify (x) == FP_NORMAL)
|
||||
@end smallexample
|
||||
@end deftypefun
|
||||
|
||||
@comment math.h
|
||||
@comment ISO
|
||||
@deftypefun int isnan (@emph{float-type} @var{x})
|
||||
The situation with this macro is a bit complicated. Here @code{isnan}
|
||||
is a macro which can handle all kinds of floating-point types. It
|
||||
returns a nonzero value is @var{x} does not represent a NaN value and
|
||||
could be written like this
|
||||
|
||||
@smallexample
|
||||
(fpclassify (x) == FP_NAN)
|
||||
@end smallexample
|
||||
|
||||
The complication is that there is a function of the same name and the
|
||||
same semantic defined for compatibility with BSD (@pxref{Predicates on
|
||||
Floats}). Fortunately this should not yield to problems in most cases
|
||||
since the macro and the function have the same semantic. Should in a
|
||||
situation the function be absolutely necessary one can use
|
||||
|
||||
@smallexample
|
||||
(isnan) (x)
|
||||
@end smallexample
|
||||
|
||||
@noindent
|
||||
to avoid the macro expansion. Using the macro has two big adavantages:
|
||||
it is more portable and one does not have to choose the right function
|
||||
among @code{isnan}, @code{isnanf}, and @code{isnanl}.
|
||||
@end deftypefun
|
||||
|
||||
|
||||
@node Operations on Complex
|
||||
@section Projections, Conjugates, and Decomposing of Complex Numbers
|
||||
@cindex project complex numbers
|
||||
@cindex conjugate complex numbers
|
||||
@cindex decompose complex numbers
|
||||
|
||||
This section lists functions performing some of the simple mathematical
|
||||
operations on complex numbers. Using any of the function requries that
|
||||
the C compiler understands the @code{complex} keyword, introduced to the
|
||||
C language in the @w{ISO C 9X} standard.
|
||||
|
||||
@pindex complex.h
|
||||
The prototypes for all functions in this section can be found in
|
||||
@file{complex.h}. All functions are available in three variants, one
|
||||
for each of the three floating-point types.
|
||||
|
||||
The easiest operation on complex numbers is the decomposition in the
|
||||
real part and the imaginary part. This is done by the next two
|
||||
functions.
|
||||
|
||||
@comment complex.h
|
||||
@comment ISO
|
||||
@deftypefun double creal (complex double @var{z})
|
||||
@deftypefunx float crealf (complex float @var{z})
|
||||
@deftypefunx {long double} creall (complex long double @var{z})
|
||||
These functions return the real part of the complex number @var{z}.
|
||||
@end deftypefun
|
||||
|
||||
@comment complex.h
|
||||
@comment ISO
|
||||
@deftypefun double cimag (complex double @var{z})
|
||||
@deftypefunx float cimagf (complex float @var{z})
|
||||
@deftypefunx {long double} cimagl (complex long double @var{z})
|
||||
These functions return the imaginary part of the complex number @var{z}.
|
||||
@end deftypefun
|
||||
|
||||
|
||||
The conjugate complex value of a given complex number has the same value
|
||||
for the real part but the complex part is negated.
|
||||
|
||||
@comment complex.h
|
||||
@comment ISO
|
||||
@deftypefun {complex double} conj (complex double @var{z})
|
||||
@deftypefunx {complex float} conjf (complex float @var{z})
|
||||
@deftypefunx {complex long double} conjl (complex long double @var{z})
|
||||
These functions return the conjugate complex value of the complex number
|
||||
@var{z}.
|
||||
@end deftypefun
|
||||
|
||||
@comment complex.h
|
||||
@comment ISO
|
||||
@deftypefun double carg (complex double @var{z})
|
||||
@deftypefunx float cargf (complex float @var{z})
|
||||
@deftypefunx {long double} cargl (complex long double @var{z})
|
||||
These functions return argument of the complex number @var{z}.
|
||||
|
||||
Mathematically, the argument is the phase angle of @var{z} with a branch
|
||||
cut along the negative real axis.
|
||||
@end deftypefun
|
||||
|
||||
@comment complex.h
|
||||
@comment ISO
|
||||
@deftypefun {complex double} cproj (complex double @var{z})
|
||||
@deftypefunx {complex float} cprojf (complex float @var{z})
|
||||
@deftypefunx {complex long double} cprojl (complex long double @var{z})
|
||||
Return the projection of the complex value @var{z} on the Riemann
|
||||
sphere. Values with a infinite complex part (even if the real part
|
||||
is NaN) are projected to positive infinte on the real axis. If the real part is infinite, the result is equivalent to
|
||||
|
||||
@smallexample
|
||||
INFINITY + I * copysign (0.0, cimag (z))
|
||||
@end smallexample
|
||||
@end deftypefun
|
||||
|
||||
|
||||
@node Absolute Value
|
||||
@section Absolute Value
|
||||
@cindex absolute value functions
|
||||
@@ -117,7 +379,8 @@ whose imaginary part is @var{y}, the absolute value is @w{@code{sqrt
|
||||
@pindex math.h
|
||||
@pindex stdlib.h
|
||||
Prototypes for @code{abs} and @code{labs} are in @file{stdlib.h};
|
||||
@code{fabs} and @code{cabs} are declared in @file{math.h}.
|
||||
@code{fabs}, @code{fabsf} and @code{fabsl} are declared in @file{math.h};
|
||||
@code{cabs}, @code{cabsf} and @code{cabsl} are declared in @file{complex.h}.
|
||||
|
||||
@comment stdlib.h
|
||||
@comment ISO
|
||||
@@ -139,20 +402,24 @@ are of type @code{long int} rather than @code{int}.
|
||||
@comment math.h
|
||||
@comment ISO
|
||||
@deftypefun double fabs (double @var{number})
|
||||
@deftypefunx float fabsf (float @var{number})
|
||||
@deftypefunx {long double} fabsl (long double @var{number})
|
||||
This function returns the absolute value of the floating-point number
|
||||
@var{number}.
|
||||
@end deftypefun
|
||||
|
||||
@comment math.h
|
||||
@comment BSD
|
||||
@deftypefun double cabs (struct @{ double real, imag; @} @var{z})
|
||||
The @code{cabs} function returns the absolute value of the complex
|
||||
number @var{z}, whose real part is @code{@var{z}.real} and whose
|
||||
imaginary part is @code{@var{z}.imag}. (See also the function
|
||||
@code{hypot} in @ref{Exponents and Logarithms}.) The value is:
|
||||
@comment complex.h
|
||||
@comment ISO
|
||||
@deftypefun double cabs (complex double @var{z})
|
||||
@deftypefunx float cabsf (complex float @var{z})
|
||||
@deftypefunx {long double} cabsl (complex long double @var{z})
|
||||
These functions return the absolute value of the complex number @var{z}.
|
||||
The compiler must support complex numbers to use these functions. (See
|
||||
also the function @code{hypot} in @ref{Exponents and Logarithms}.) The
|
||||
value is:
|
||||
|
||||
@smallexample
|
||||
sqrt (@var{z}.real*@var{z}.real + @var{z}.imag*@var{z}.imag)
|
||||
sqrt (creal (@var{z}) * creal (@var{z}) + cimag (@var{z}) * cimag (@var{z}))
|
||||
@end smallexample
|
||||
@end deftypefun
|
||||
|
||||
@@ -174,7 +441,9 @@ All these functions are declared in @file{math.h}.
|
||||
@comment math.h
|
||||
@comment ISO
|
||||
@deftypefun double frexp (double @var{value}, int *@var{exponent})
|
||||
The @code{frexp} function is used to split the number @var{value}
|
||||
@deftypefunx float frexpf (float @var{value}, int *@var{exponent})
|
||||
@deftypefunx {long double} frexpl (long double @var{value}, int *@var{exponent})
|
||||
These functions are used to split the number @var{value}
|
||||
into a normalized fraction and an exponent.
|
||||
|
||||
If the argument @var{value} is not zero, the return value is @var{value}
|
||||
@@ -193,7 +462,9 @@ zero is stored in @code{*@var{exponent}}.
|
||||
@comment math.h
|
||||
@comment ISO
|
||||
@deftypefun double ldexp (double @var{value}, int @var{exponent})
|
||||
This function returns the result of multiplying the floating-point
|
||||
@deftypefunx float ldexpf (float @var{value}, int @var{exponent})
|
||||
@deftypefunx {long double} ldexpl (long double @var{value}, int @var{exponent})
|
||||
These functions return the result of multiplying the floating-point
|
||||
number @var{value} by 2 raised to the power @var{exponent}. (It can
|
||||
be used to reassemble floating-point numbers that were taken apart
|
||||
by @code{frexp}.)
|
||||
@@ -207,13 +478,17 @@ equivalent to those of @code{ldexp} and @code{frexp}:
|
||||
@comment math.h
|
||||
@comment BSD
|
||||
@deftypefun double scalb (double @var{value}, int @var{exponent})
|
||||
@deftypefunx float scalbf (float @var{value}, int @var{exponent})
|
||||
@deftypefunx {long double} scalbl (long double @var{value}, int @var{exponent})
|
||||
The @code{scalb} function is the BSD name for @code{ldexp}.
|
||||
@end deftypefun
|
||||
|
||||
@comment math.h
|
||||
@comment BSD
|
||||
@deftypefun double logb (double @var{x})
|
||||
This BSD function returns the integer part of the base-2 logarithm of
|
||||
@deftypefunx float logbf (float @var{x})
|
||||
@deftypefunx {long double} logbl (long double @var{x})
|
||||
These BSD functions return the integer part of the base-2 logarithm of
|
||||
@var{x}, an integer value represented in type @code{double}. This is
|
||||
the highest integer power of @code{2} contained in @var{x}. The sign of
|
||||
@var{x} is ignored. For example, @code{logb (3.5)} is @code{1.0} and
|
||||
@@ -231,11 +506,26 @@ The value returned by @code{logb} is one less than the value that
|
||||
@end deftypefun
|
||||
|
||||
@comment math.h
|
||||
@comment BSD
|
||||
@comment ISO
|
||||
@deftypefun double copysign (double @var{value}, double @var{sign})
|
||||
The @code{copysign} function returns a value whose absolute value is the
|
||||
@deftypefunx float copysignf (float @var{value}, float @var{sign})
|
||||
@deftypefunx {long double} copysignl (long double @var{value}, long double @var{sign})
|
||||
These functions return a value whose absolute value is the
|
||||
same as that of @var{value}, and whose sign matches that of @var{sign}.
|
||||
This is a BSD function.
|
||||
This function appears in BSD and was standardized in @w{ISO C 9X}.
|
||||
@end deftypefun
|
||||
|
||||
@comment math.h
|
||||
@comment ISO
|
||||
@deftypefun int signbit (@emph{float-type} @var{x})
|
||||
@code{signbit} is a generic macro which can work on all floating-point
|
||||
types. It returns a nonzero value if the value of @var{x} has its sign
|
||||
bit set.
|
||||
|
||||
This is not the same as @code{x < 0.0} since in some floating-point
|
||||
formats (e.g., @w{IEEE 754}) the zero value is optionally signed. The
|
||||
comparison @code{-0.0 < 0.0} will not be true while @code{signbit
|
||||
(-0.0)} will return a nonzeri value.
|
||||
@end deftypefun
|
||||
|
||||
@node Rounding and Remainders
|
||||
@@ -260,7 +550,9 @@ result as a @code{double} instead to get around this problem.
|
||||
@comment math.h
|
||||
@comment ISO
|
||||
@deftypefun double ceil (double @var{x})
|
||||
The @code{ceil} function rounds @var{x} upwards to the nearest integer,
|
||||
@deftypefunx float ceilf (float @var{x})
|
||||
@deftypefunx {long double} ceill (long double @var{x})
|
||||
These functions round @var{x} upwards to the nearest integer,
|
||||
returning that value as a @code{double}. Thus, @code{ceil (1.5)}
|
||||
is @code{2.0}.
|
||||
@end deftypefun
|
||||
@@ -268,15 +560,19 @@ is @code{2.0}.
|
||||
@comment math.h
|
||||
@comment ISO
|
||||
@deftypefun double floor (double @var{x})
|
||||
The @code{ceil} function rounds @var{x} downwards to the nearest
|
||||
@deftypefunx float floorf (float @var{x})
|
||||
@deftypefunx {long double} floorl (long double @var{x})
|
||||
These functions round @var{x} downwards to the nearest
|
||||
integer, returning that value as a @code{double}. Thus, @code{floor
|
||||
(1.5)} is @code{1.0} and @code{floor (-1.5)} is @code{-2.0}.
|
||||
@end deftypefun
|
||||
|
||||
@comment math.h
|
||||
@comment BSD
|
||||
@comment ISO
|
||||
@deftypefun double rint (double @var{x})
|
||||
This function rounds @var{x} to an integer value according to the
|
||||
@deftypefunx float rintf (float @var{x})
|
||||
@deftypefunx {long double} rintl (long double @var{x})
|
||||
These functions round @var{x} to an integer value according to the
|
||||
current rounding mode. @xref{Floating Point Parameters}, for
|
||||
information about the various rounding modes. The default
|
||||
rounding mode is to round to the nearest integer; some machines
|
||||
@@ -284,10 +580,22 @@ support other modes, but round-to-nearest is always used unless
|
||||
you explicit select another.
|
||||
@end deftypefun
|
||||
|
||||
@comment math.h
|
||||
@comment ISO
|
||||
@deftypefun double nearbyint (double @var{x})
|
||||
@deftypefunx float nearbyintf (float @var{x})
|
||||
@deftypefunx {long double} nearbyintl (long double @var{x})
|
||||
These functions return the same value as the @code{rint} functions but
|
||||
even some rounding actually takes place @code{nearbyint} does @emph{not}
|
||||
raise the inexact exception.
|
||||
@end deftypefun
|
||||
|
||||
@comment math.h
|
||||
@comment ISO
|
||||
@deftypefun double modf (double @var{value}, double *@var{integer-part})
|
||||
This function breaks the argument @var{value} into an integer part and a
|
||||
@deftypefunx float modff (flaot @var{value}, float *@var{integer-part})
|
||||
@deftypefunx {long double} modfl (long double @var{value}, long double *@var{integer-part})
|
||||
These functions break the argument @var{value} into an integer part and a
|
||||
fractional part (between @code{-1} and @code{1}, exclusive). Their sum
|
||||
equals @var{value}. Each of the parts has the same sign as @var{value},
|
||||
so the rounding of the integer part is towards zero.
|
||||
@@ -300,7 +608,9 @@ returns @code{0.5} and stores @code{2.0} into @code{intpart}.
|
||||
@comment math.h
|
||||
@comment ISO
|
||||
@deftypefun double fmod (double @var{numerator}, double @var{denominator})
|
||||
This function computes the remainder from the division of
|
||||
@deftypefunx float fmodf (float @var{numerator}, float @var{denominator})
|
||||
@deftypefunx {long double} fmodl (long double @var{numerator}, long double @var{denominator})
|
||||
These functions compute the remainder from the division of
|
||||
@var{numerator} by @var{denominator}. Specifically, the return value is
|
||||
@code{@var{numerator} - @w{@var{n} * @var{denominator}}}, where @var{n}
|
||||
is the quotient of @var{numerator} divided by @var{denominator}, rounded
|
||||
@@ -317,7 +627,9 @@ If @var{denominator} is zero, @code{fmod} fails and sets @code{errno} to
|
||||
@comment math.h
|
||||
@comment BSD
|
||||
@deftypefun double drem (double @var{numerator}, double @var{denominator})
|
||||
The function @code{drem} is like @code{fmod} except that it rounds the
|
||||
@deftypefunx float dremf (float @var{numerator}, float @var{denominator})
|
||||
@deftypefunx {long double} dreml (long double @var{numerator}, long double @var{denominator})
|
||||
These functions are like @code{fmod} etc except that it rounds the
|
||||
internal quotient @var{n} to the nearest integer instead of towards zero
|
||||
to an integer. For example, @code{drem (6.5, 2.3)} returns @code{-0.4},
|
||||
which is @code{6.5} minus @code{6.9}.
|
||||
@@ -411,7 +723,36 @@ type @code{long int} rather than @code{int}.)
|
||||
@deftypefun ldiv_t ldiv (long int @var{numerator}, long int @var{denominator})
|
||||
The @code{ldiv} function is similar to @code{div}, except that the
|
||||
arguments are of type @code{long int} and the result is returned as a
|
||||
structure of type @code{ldiv}.
|
||||
structure of type @code{ldiv_t}.
|
||||
@end deftypefun
|
||||
|
||||
@comment stdlib.h
|
||||
@comment GNU
|
||||
@deftp {Data Type} lldiv_t
|
||||
This is a structure type used to hold the result returned by the @code{lldiv}
|
||||
function. It has the following members:
|
||||
|
||||
@table @code
|
||||
@item long long int quot
|
||||
The quotient from the division.
|
||||
|
||||
@item long long int rem
|
||||
The remainder from the division.
|
||||
@end table
|
||||
|
||||
(This is identical to @code{div_t} except that the components are of
|
||||
type @code{long long int} rather than @code{int}.)
|
||||
@end deftp
|
||||
|
||||
@comment stdlib.h
|
||||
@comment GNU
|
||||
@deftypefun lldiv_t lldiv (long long int @var{numerator}, long long int @var{denominator})
|
||||
The @code{lldiv} function is like the @code{div} function, but the
|
||||
arguments are of type @code{long long int} and the result is returned as
|
||||
a structure of type @code{lldiv_t}.
|
||||
|
||||
The @code{lldiv} function is a GNU extension but it will eventually be
|
||||
part of the next ISO C standard.
|
||||
@end deftypefun
|
||||
|
||||
|
||||
@@ -519,42 +860,48 @@ to @code{EINVAL} and returns @code{0ul}.
|
||||
@end deftypefun
|
||||
|
||||
@comment stdlib.h
|
||||
@comment BSD
|
||||
@deftypefun {long long int} strtoq (const char *@var{string}, char **@var{tailptr}, int @var{base})
|
||||
The @code{strtoq} (``string-to-quad-word'') function is like
|
||||
@code{strtol} except that is deals with extra long numbers and it
|
||||
returns its value with type @code{long long int}.
|
||||
@comment GNU
|
||||
@deftypefun {long long int} strtoll (const char *@var{string}, char **@var{tailptr}, int @var{base})
|
||||
The @code{strtoll} function is like @code{strtol} except that is deals
|
||||
with extra long numbers and it returns its value with type @code{long
|
||||
long int}.
|
||||
|
||||
If the string has valid syntax for an integer but the value is not
|
||||
representable because of overflow, @code{strtoq} returns either
|
||||
representable because of overflow, @code{strtoll} returns either
|
||||
@code{LONG_LONG_MAX} or @code{LONG_LONG_MIN} (@pxref{Range of Type}), as
|
||||
appropriate for the sign of the value. It also sets @code{errno} to
|
||||
@code{ERANGE} to indicate there was overflow.
|
||||
@end deftypefun
|
||||
|
||||
@comment stdlib.h
|
||||
@comment GNU
|
||||
@deftypefun {long long int} strtoll (const char *@var{string}, char **@var{tailptr}, int @var{base})
|
||||
@code{strtoll} is only an commonly used other name for the @code{strtoq}
|
||||
function. Everything said for @code{strtoq} applies to @code{strtoll}
|
||||
as well.
|
||||
The @code{strtoll} function is a GNU extension but it will eventually be
|
||||
part of the next ISO C standard.
|
||||
@end deftypefun
|
||||
|
||||
@comment stdlib.h
|
||||
@comment BSD
|
||||
@deftypefun {unsigned long long int} strtouq (const char *@var{string}, char **@var{tailptr}, int @var{base})
|
||||
The @code{strtouq} (``string-to-unsigned-quad-word'') function is like
|
||||
@code{strtoul} except that is deals with extra long numbers and it
|
||||
returns its value with type @code{unsigned long long int}. The value
|
||||
returned in case of overflow is @code{ULONG_LONG_MAX} (@pxref{Range of Type}).
|
||||
@deftypefun {long long int} strtoq (const char *@var{string}, char **@var{tailptr}, int @var{base})
|
||||
@code{strtoq} (``string-to-quad-word'') is only an commonly used other
|
||||
name for the @code{strtoll} function. Everything said for
|
||||
@code{strtoll} applies to @code{strtoq} as well.
|
||||
@end deftypefun
|
||||
|
||||
@comment stdlib.h
|
||||
@comment GNU
|
||||
@deftypefun {unsigned long long int} strtoull (const char *@var{string}, char **@var{tailptr}, int @var{base})
|
||||
@code{strtoull} is only an commonly used other name for the @code{strtouq}
|
||||
function. Everything said for @code{strtouq} applies to @code{strtoull}
|
||||
as well.
|
||||
The @code{strtoull} function is like @code{strtoul} except that is deals
|
||||
with extra long numbers and it returns its value with type
|
||||
@code{unsigned long long int}. The value returned in case of overflow
|
||||
is @code{ULONG_LONG_MAX} (@pxref{Range of Type}).
|
||||
|
||||
The @code{strtoull} function is a GNU extension but it will eventually be
|
||||
part of the next ISO C standard.
|
||||
@end deftypefun
|
||||
|
||||
@comment stdlib.h
|
||||
@comment BSD
|
||||
@deftypefun {unsigned long long int} strtouq (const char *@var{string}, char **@var{tailptr}, int @var{base})
|
||||
@code{strtouq} (``string-to-unsigned-quad-word'') is only an commonly
|
||||
used other name for the @code{strtoull} function. Everything said for
|
||||
@code{strtoull} applies to @code{strtouq} as well.
|
||||
@end deftypefun
|
||||
|
||||
@comment stdlib.h
|
||||
@@ -574,6 +921,16 @@ value rather than @code{long int}. The @code{atoi} function is also
|
||||
considered obsolete; use @code{strtol} instead.
|
||||
@end deftypefun
|
||||
|
||||
@comment stdlib.h
|
||||
@comment GNU
|
||||
@deftypefun {long long int} atoll (const char *@var{string})
|
||||
This function is similar to @code{atol}, except it returns a @code{long
|
||||
long int} value rather than @code{long int}.
|
||||
|
||||
The @code{atoll} function is a GNU extension but it will eventually be
|
||||
part of the next ISO C standard.
|
||||
@end deftypefun
|
||||
|
||||
The POSIX locales contain some information about how to format numbers
|
||||
(@pxref{General Numeric}). This mainly deals with representing numbers
|
||||
for better readability for humans. The functions present so far in this
|
||||
@@ -688,6 +1045,24 @@ the sign of the value. Similarly, if the value is not representable
|
||||
because of underflow, @code{strtod} returns zero. It also sets @code{errno}
|
||||
to @code{ERANGE} if there was overflow or underflow.
|
||||
|
||||
There are two more special inputs which are recognized by @code{strtod}.
|
||||
The string @code{"inf"} or @code{"infinity"} (without consideration of
|
||||
case and optionally preceded by a @code{"+"} or @code{"-"} sign) is
|
||||
changed to the floating-point value for infinity if the floating-point
|
||||
format supports this; and to the largest representable value otherwise.
|
||||
|
||||
If the input string is @code{"nan"} or
|
||||
@code{"nan(@var{n-char-sequence})"} the return value of @code{strtod} is
|
||||
the representation of the NaN (not a number) value (if the
|
||||
flaoting-point formats supports this. The form with the
|
||||
@var{n-char-sequence} enables in an implementation specific way to
|
||||
specify the form of the NaN value. When using the @w{IEEE 754}
|
||||
floating-point format, the NaN value can have a lot of forms since only
|
||||
at least one bit in the mantissa must be set. In the GNU C library
|
||||
implementation of @code{strtod} the @var{n-char-sequence} is interpreted
|
||||
as a number (as recognized by @code{strtol}, @pxref{Parsing of Integers})
|
||||
The mantissa of the return value corresponds to this given number.
|
||||
|
||||
Since the value zero which is returned in the error case is also a valid
|
||||
result the user should set the global variable @code{errno} to zero
|
||||
before calling this function. So one can test for failures after the
|
||||
@@ -707,7 +1082,7 @@ precision can require additional computation.
|
||||
|
||||
If the string has valid syntax for a floating-point number but the value
|
||||
is not representable because of overflow, @code{strtof} returns either
|
||||
positive or negative @code{HUGE_VALf} (@pxref{Mathematics}), depending on
|
||||
positive or negative @code{HUGE_VALF} (@pxref{Mathematics}), depending on
|
||||
the sign of the value.
|
||||
|
||||
This function is a GNU extension.
|
||||
@@ -725,7 +1100,7 @@ of precision are required.
|
||||
|
||||
If the string has valid syntax for a floating-point number but the value
|
||||
is not representable because of overflow, @code{strtold} returns either
|
||||
positive or negative @code{HUGE_VALl} (@pxref{Mathematics}), depending on
|
||||
positive or negative @code{HUGE_VALL} (@pxref{Mathematics}), depending on
|
||||
the sign of the value.
|
||||
|
||||
This function is a GNU extension.
|
||||
|
||||
@@ -1186,6 +1186,18 @@ They are not yet documented.}
|
||||
@comment errno ???/121
|
||||
@end deftypevr
|
||||
|
||||
@comment errno.h
|
||||
@comment Linux???: No medium found
|
||||
@deftypevr Macro int ENOMEDIUM
|
||||
@comment errno ???/???
|
||||
@end deftypevr
|
||||
|
||||
@comment errno.h
|
||||
@comment Linux???: Wrong medium type
|
||||
@deftypevr Macro int EMEDIUMTYPE
|
||||
@comment errno ???/???
|
||||
@end deftypevr
|
||||
|
||||
@node Error Messages, , Error Codes, Error Reporting
|
||||
@section Error Messages
|
||||
|
||||
@@ -1214,6 +1226,25 @@ overwritten. (But it's guaranteed that no library function ever calls
|
||||
The function @code{strerror} is declared in @file{string.h}.
|
||||
@end deftypefun
|
||||
|
||||
@comment string.h
|
||||
@comment GNU
|
||||
@deftypefun {char *} strerror_r (int @var{errnum}, char *@var{buf}, size_t @var{n})
|
||||
The @code{strerror_r} function works like @code{strerror} but instead of
|
||||
returning the error message in a statically allocated buffer shared by
|
||||
all threads in the process, it writes the message string in the user
|
||||
supplied buffer starting at @var{buf} with the length of @var{n} bytes.
|
||||
|
||||
At most @var{n} characters are written (including the NUL byte) so it is
|
||||
up to the user to select the buffer large enough.
|
||||
|
||||
This function should always be used in multi-threaded programs since
|
||||
there is no way to guarantee the string returned by @code{strerror}
|
||||
really belongs to the last call of the current thread.
|
||||
|
||||
This function @code{strerror_r} is a GNU extension and it is declared in
|
||||
@file{string.h}.
|
||||
@end deftypefun
|
||||
|
||||
@comment stdio.h
|
||||
@comment ISO
|
||||
@deftypefun void perror (const char *@var{message})
|
||||
|
||||
@@ -462,6 +462,44 @@ use it except for reasons of portability.
|
||||
@refill
|
||||
@end deftypefn
|
||||
|
||||
Sometimes it is necessary to parse the list of parameters more than once
|
||||
or one wants to remember a certain position in the parameter list. To
|
||||
do this one will have to make a copy of the current value of the
|
||||
argument. But @code{va_list} is an opaque type and it is not guaranteed
|
||||
that one can simply assign the value of a variable to another one of
|
||||
type @code{va_list}
|
||||
|
||||
@comment stdarg.h
|
||||
@comment GNU
|
||||
@deftypefn {Macro} void __va_copy (va_list @var{dest}, va_list @var{src})
|
||||
The @code{__va_copy} macro allows copying of objects of type
|
||||
@code{va_list} even if this is no integral type. The argument pointer
|
||||
in @var{dest} is initialized to point to the same argument as the
|
||||
pointer in @var{src}.
|
||||
|
||||
This macro is a GNU extension but it will hopefully also be available in
|
||||
the next update of the ISO C standard.
|
||||
@end deftypefn
|
||||
|
||||
If you want to use @code{__va_copy} you should always be prepared that
|
||||
this macro is not available. On architectures where a simple assignment
|
||||
is invalid it hopefully is and so one should always write something like
|
||||
this:
|
||||
|
||||
@smallexample
|
||||
@{
|
||||
va_list ap, save;
|
||||
@dots{}
|
||||
#ifdef __va_copy
|
||||
__va_copy (save, ap);
|
||||
#else
|
||||
save = ap;
|
||||
#endif
|
||||
@dots{}
|
||||
@}
|
||||
@end smallexample
|
||||
|
||||
|
||||
@node Variadic Example
|
||||
@subsection Example of a Variadic Function
|
||||
|
||||
|
||||
+5
-3
@@ -3,12 +3,15 @@
|
||||
@setfilename libc.info
|
||||
@settitle The GNU C Library
|
||||
@setchapternewpage odd
|
||||
@comment %**end of header (This is for running Texinfo on a region.)
|
||||
|
||||
@c This tells texinfo.tex to use the real section titles in xrefs in
|
||||
@c place of the node name, when no section title is explicitly given.
|
||||
@set xref-automatic-section-title
|
||||
@smallbook
|
||||
@c @smallbook
|
||||
@iftex
|
||||
@afourpaper
|
||||
@end iftex
|
||||
@comment %**end of header (This is for running Texinfo on a region.)
|
||||
|
||||
@c sold 0.06/1.09, print run out 21may96
|
||||
@set EDITION 0.07 DRAFT
|
||||
@@ -210,7 +213,6 @@ Memory Allocation
|
||||
calling function returns.
|
||||
* Relocating Allocator:: Waste less memory, if you can tolerate
|
||||
automatic relocation of the blocks you get.
|
||||
* Memory Warnings:: Getting warnings when memory is nearly full.
|
||||
|
||||
Unconstrained Allocation
|
||||
|
||||
|
||||
+747
-41
@@ -7,14 +7,22 @@ these functions have prototypes declared in the header file
|
||||
@file{math.h}.
|
||||
@pindex math.h
|
||||
|
||||
All of the functions that operate on floating-point numbers accept
|
||||
arguments and return results of type @code{double}. In the future,
|
||||
there may be additional functions that operate on @code{float} and
|
||||
@code{long double} values. For example, @code{cosf} and @code{cosl}
|
||||
would be versions of the @code{cos} function that operate on
|
||||
@code{float} and @code{long double} arguments, respectively. In the
|
||||
meantime, you should avoid using these names yourself. @xref{Reserved
|
||||
Names}.
|
||||
For all functions which take a single floating-point argument and for
|
||||
several other functions as well there are three different functions
|
||||
available for the type @code{double}, @code{float}, and @code{long
|
||||
double}. The @code{double} versions of the functions are mostly defined
|
||||
even in the @w{ISO C 89} standard. The @code{float} and @code{long
|
||||
double} variants are introduced in the numeric extensions for the C
|
||||
language which are part of the @w{ISO C 9X} standard.
|
||||
|
||||
Which of the three versions of the function should be used depends on
|
||||
the situation. For most functions and implementation it is true that
|
||||
speed and precision do not go together. I.e., the @code{float} versions
|
||||
are normally faster than the @code{double} and @code{long double}
|
||||
versions. On the other hand the @code{long double} version has the
|
||||
highest precision. One should always think about the actual needs and
|
||||
in case of double using @code{double} is a good compromise.
|
||||
|
||||
|
||||
@menu
|
||||
* Domain and Range Errors:: Detecting overflow conditions and the like.
|
||||
@@ -119,11 +127,15 @@ The arguments to all of these functions are in units of radians; recall
|
||||
that pi radians equals 180 degrees.
|
||||
|
||||
@cindex pi (trigonometric constant)
|
||||
The math library doesn't define a symbolic constant for pi, but you can
|
||||
define your own if you need one:
|
||||
The math library does define a symbolic constant for pi in @file{math.h}
|
||||
when BSD compliance is required (@pxref{Feature Test Macros}). Beside
|
||||
pi several other constants are defined.
|
||||
|
||||
@noindent
|
||||
In case it is not possible to use this macro one easily can define it:
|
||||
|
||||
@smallexample
|
||||
#define PI 3.14159265358979323846264338327
|
||||
#define M_PI 3.14159265358979323846264338327
|
||||
@end smallexample
|
||||
|
||||
@noindent
|
||||
@@ -134,21 +146,27 @@ You can also compute the value of pi with the expression @code{acos
|
||||
@comment math.h
|
||||
@comment ISO
|
||||
@deftypefun double sin (double @var{x})
|
||||
This function returns the sine of @var{x}, where @var{x} is given in
|
||||
@deftypefunx float sinf (float @var{x})
|
||||
@deftypefunx {long double} sinl (long double @var{x})
|
||||
These functions return the sine of @var{x}, where @var{x} is given in
|
||||
radians. The return value is in the range @code{-1} to @code{1}.
|
||||
@end deftypefun
|
||||
|
||||
@comment math.h
|
||||
@comment ISO
|
||||
@deftypefun double cos (double @var{x})
|
||||
This function returns the cosine of @var{x}, where @var{x} is given in
|
||||
@deftypefunx float cosf (float @var{x})
|
||||
@deftypefunx {long double} cosl (long double @var{x})
|
||||
These functions return the cosine of @var{x}, where @var{x} is given in
|
||||
radians. The return value is in the range @code{-1} to @code{1}.
|
||||
@end deftypefun
|
||||
|
||||
@comment math.h
|
||||
@comment ISO
|
||||
@deftypefun double tan (double @var{x})
|
||||
This function returns the tangent of @var{x}, where @var{x} is given in
|
||||
@deftypefunx float tanf (float @var{x})
|
||||
@deftypefunx {long double} tanl (long double @var{x})
|
||||
These functions return the tangent of @var{x}, where @var{x} is given in
|
||||
radians.
|
||||
|
||||
The following @code{errno} error conditions are defined for this function:
|
||||
@@ -162,6 +180,83 @@ either positive or negative @code{HUGE_VAL}.
|
||||
@end table
|
||||
@end deftypefun
|
||||
|
||||
In many applications where @code{sin} and @code{cos} are used, the value
|
||||
for the same argument of both of these functions is used at the same
|
||||
time. Since the algorithm to compute these values is very similar for
|
||||
both functions there is an additional function which computes both values
|
||||
at the same time.
|
||||
|
||||
@comment math.h
|
||||
@comment GNU
|
||||
@deftypefun void sincos (double @var{x}, double *@var{sinx}, double *@var{cosx})
|
||||
@deftypefunx void sincosf (float @var{x}, float *@var{sinx}, float *@var{cosx})
|
||||
@deftypefunx void sincosl (long double @var{x}, long double *@var{sinx}, long double *@var{cosx})
|
||||
These functions return the sine of @var{x} in @code{*@var{sinx}} and the
|
||||
cosine of @var{x} in @code{*@var{cos}}, where @var{x} is given in
|
||||
radians. Both values, @code{*@var{sinx}} and @code{*@var{cosx}}, are in
|
||||
the range of @code{-1} to @code{1}.
|
||||
@end deftypefun
|
||||
|
||||
@cindex complex trigonometric functions
|
||||
|
||||
The trigonometric functions are in mathematics not only defined on real
|
||||
numbers. They can be extended to complex numbers and the @w{ISO C 9X}
|
||||
standard introduces these variants in the standard math library.
|
||||
|
||||
@comment complex.h
|
||||
@comment ISO
|
||||
@deftypefun {complex double} csin (complex double @var{z})
|
||||
@deftypefunx {complex float} csinf (complex float @var{z})
|
||||
@deftypefunx {complex long double} csinl (complex long double @var{z})
|
||||
These functions return the complex sine of the complex value in @var{z}.
|
||||
The mathematical definition of the complex sine is
|
||||
|
||||
@ifinfo
|
||||
@math{sin (z) = 1/(2*i) * (exp (z*i) - exp (-z*i))}.
|
||||
@end ifinfo
|
||||
@iftex
|
||||
@tex
|
||||
$$\sin(z) = {1\over 2i} (e^{zi} - e^{-zi})$$
|
||||
@end tex
|
||||
@end iftex
|
||||
@end deftypefun
|
||||
|
||||
@comment complex.h
|
||||
@comment ISO
|
||||
@deftypefun {complex double} ccos (complex double @var{z})
|
||||
@deftypefunx {complex float} ccosf (complex float @var{z})
|
||||
@deftypefunx {complex long double} ccosl (complex long double @var{z})
|
||||
These functions return the complex cosine of the complex value in @var{z}.
|
||||
The mathematical definition of the complex cosine is
|
||||
|
||||
@ifinfo
|
||||
@math{cos (z) = 1/2 * (exp (z*i) + exp (-z*i))}
|
||||
@end ifinfo
|
||||
@iftex
|
||||
@tex
|
||||
$$\cos(z) = {1\over 2} (e^{zi} + e^{-zi})$$
|
||||
@end tex
|
||||
@end iftex
|
||||
@end deftypefun
|
||||
|
||||
@comment complex.h
|
||||
@comment ISO
|
||||
@deftypefun {complex double} ctan (complex double @var{z})
|
||||
@deftypefunx {complex float} ctanf (complex float @var{z})
|
||||
@deftypefunx {complex long double} ctanl (complex long double @var{z})
|
||||
These functions return the complex tangent of the complex value in @var{z}.
|
||||
The mathematical definition of the complex tangent is
|
||||
|
||||
@ifinfo
|
||||
@math{tan (z) = 1/i * (exp (z*i) - exp (-z*i)) / (exp (z*i) + exp (-z*i))}
|
||||
@end ifinfo
|
||||
@iftex
|
||||
@tex
|
||||
$$\tan(z) = {1\over i} {e^{zi} - e^{-zi}\over e^{zi} + e^{-zi}}$$
|
||||
@end tex
|
||||
@end iftex
|
||||
@end deftypefun
|
||||
|
||||
|
||||
@node Inverse Trig Functions
|
||||
@section Inverse Trigonometric Functions
|
||||
@@ -174,7 +269,9 @@ respectively.
|
||||
@comment math.h
|
||||
@comment ISO
|
||||
@deftypefun double asin (double @var{x})
|
||||
This function computes the arc sine of @var{x}---that is, the value whose
|
||||
@deftypefunx float asinf (float @var{x})
|
||||
@deftypefunx {long double} asinl (long double @var{x})
|
||||
These functions compute the arc sine of @var{x}---that is, the value whose
|
||||
sine is @var{x}. The value is in units of radians. Mathematically,
|
||||
there are infinitely many such values; the one actually returned is the
|
||||
one between @code{-pi/2} and @code{pi/2} (inclusive).
|
||||
@@ -187,7 +284,9 @@ over the domain @code{-1} to @code{1}.
|
||||
@comment math.h
|
||||
@comment ISO
|
||||
@deftypefun double acos (double @var{x})
|
||||
This function computes the arc cosine of @var{x}---that is, the value
|
||||
@deftypefunx float acosf (float @var{x})
|
||||
@deftypefunx {long double} acosl (long double @var{x})
|
||||
These functions compute the arc cosine of @var{x}---that is, the value
|
||||
whose cosine is @var{x}. The value is in units of radians.
|
||||
Mathematically, there are infinitely many such values; the one actually
|
||||
returned is the one between @code{0} and @code{pi} (inclusive).
|
||||
@@ -201,7 +300,9 @@ over the domain @code{-1} to @code{1}.
|
||||
@comment math.h
|
||||
@comment ISO
|
||||
@deftypefun double atan (double @var{x})
|
||||
This function computes the arc tangent of @var{x}---that is, the value
|
||||
@deftypefunx float atanf (float @var{x})
|
||||
@deftypefunx {long double} atanl (long double @var{x})
|
||||
These functions compute the arc tangent of @var{x}---that is, the value
|
||||
whose tangent is @var{x}. The value is in units of radians.
|
||||
Mathematically, there are infinitely many such values; the one actually
|
||||
returned is the one between @code{-pi/2} and @code{pi/2}
|
||||
@@ -211,6 +312,8 @@ returned is the one between @code{-pi/2} and @code{pi/2}
|
||||
@comment math.h
|
||||
@comment ISO
|
||||
@deftypefun double atan2 (double @var{y}, double @var{x})
|
||||
@deftypefunx float atan2f (float @var{y}, float @var{x})
|
||||
@deftypefunx {long double} atan2l (long double @var{y}, long double @var{x})
|
||||
This is the two argument arc tangent function. It is similar to computing
|
||||
the arc tangent of @var{y}/@var{x}, except that the signs of both arguments
|
||||
are used to determine the quadrant of the result, and @var{x} is
|
||||
@@ -229,6 +332,45 @@ The function @code{atan2} sets @code{errno} to @code{EDOM} if both
|
||||
case.
|
||||
@end deftypefun
|
||||
|
||||
@cindex inverse complex trigonometric functions
|
||||
|
||||
The inverse trigonometric functions also exist is separate versions
|
||||
which are usable with complex numbers.
|
||||
|
||||
@comment complex.h
|
||||
@comment ISO
|
||||
@deftypefun {complex double} casin (complex double @var{z})
|
||||
@deftypefunx {complex float} casinf (complex float @var{z})
|
||||
@deftypefunx {complex long double} casinl (complex long double @var{z})
|
||||
These functions compute the complex arc sine of @var{z}---that is, the
|
||||
value whose sine is @var{z}. The value is in units of radians.
|
||||
|
||||
Unlike the real version of the arc sine function @code{casin} has no
|
||||
limitation on the argument @var{z}.
|
||||
@end deftypefun
|
||||
|
||||
@comment complex.h
|
||||
@comment ISO
|
||||
@deftypefun {complex double} cacos (complex double @var{z})
|
||||
@deftypefunx {complex float} cacosf (complex float @var{z})
|
||||
@deftypefunx {complex long double} cacosl (complex long double @var{z})
|
||||
These functions compute the complex arc cosine of @var{z}---that is, the
|
||||
value whose cosine is @var{z}. The value is in units of radians.
|
||||
|
||||
Unlike the real version of the arc cosine function @code{cacos} has no
|
||||
limitation on the argument @var{z}.
|
||||
@end deftypefun
|
||||
|
||||
|
||||
@comment complex.h
|
||||
@comment ISO
|
||||
@deftypefun {complex double} catan (complex double @var{z})
|
||||
@deftypefunx {complex float} catanf (complex float @var{z})
|
||||
@deftypefunx {complex long double} catanl (complex long double @var{z})
|
||||
These functions compute the complex arc tangent of @var{z}---that is,
|
||||
the value whose tangent is @var{z}. The value is in units of radians.
|
||||
@end deftypefun
|
||||
|
||||
|
||||
@node Exponents and Logarithms
|
||||
@section Exponentiation and Logarithms
|
||||
@@ -239,17 +381,46 @@ case.
|
||||
@comment math.h
|
||||
@comment ISO
|
||||
@deftypefun double exp (double @var{x})
|
||||
The @code{exp} function returns the value of e (the base of natural
|
||||
@deftypefunx float expf (float @var{x})
|
||||
@deftypefunx {long double} expl (long double @var{x})
|
||||
These functions return the value of @code{e} (the base of natural
|
||||
logarithms) raised to power @var{x}.
|
||||
|
||||
The function fails, and sets @code{errno} to @code{ERANGE}, if the
|
||||
magnitude of the result is too large to be representable.
|
||||
@end deftypefun
|
||||
|
||||
@comment math.h
|
||||
@comment ISO
|
||||
@deftypefun double exp10 (double @var{x})
|
||||
@deftypefunx float exp10f (float @var{x})
|
||||
@deftypefunx {long double} exp10l (long double @var{x})
|
||||
These functions return the value of @code{10} raised to the power @var{x}.
|
||||
Mathematically, @code{exp10 (x)} is the same as @code{exp (x * log (10))}.
|
||||
|
||||
The function fails, and sets @code{errno} to @code{ERANGE}, if the
|
||||
magnitude of the result is too large to be representable.
|
||||
@end deftypefun
|
||||
|
||||
@comment math.h
|
||||
@comment ISO
|
||||
@deftypefun double exp2 (double @var{x})
|
||||
@deftypefunx float exp2f (float @var{x})
|
||||
@deftypefunx {long double} exp2l (long double @var{x})
|
||||
These functions return the value of @code{2} raised to the power @var{x}.
|
||||
Mathematically, @code{exp2 (x)} is the same as @code{exp (x * log (2))}.
|
||||
|
||||
The function fails, and sets @code{errno} to @code{ERANGE}, if the
|
||||
magnitude of the result is too large to be representable.
|
||||
@end deftypefun
|
||||
|
||||
|
||||
@comment math.h
|
||||
@comment ISO
|
||||
@deftypefun double log (double @var{x})
|
||||
This function returns the natural logarithm of @var{x}. @code{exp (log
|
||||
@deftypefunx float logf (floatdouble @var{x})
|
||||
@deftypefunx {long double} logl (long double @var{x})
|
||||
These functions return the natural logarithm of @var{x}. @code{exp (log
|
||||
(@var{x}))} equals @var{x}, exactly in mathematics and approximately in
|
||||
C.
|
||||
|
||||
@@ -268,15 +439,29 @@ The argument is zero. The log of zero is not defined.
|
||||
@comment math.h
|
||||
@comment ISO
|
||||
@deftypefun double log10 (double @var{x})
|
||||
This function returns the base-10 logarithm of @var{x}. Except for the
|
||||
@deftypefunx float log10f (float @var{x})
|
||||
@deftypefunx {long double} log10l (long double @var{x})
|
||||
These functions return the base-10 logarithm of @var{x}. Except for the
|
||||
different base, it is similar to the @code{log} function. In fact,
|
||||
@code{log10 (@var{x})} equals @code{log (@var{x}) / log (10)}.
|
||||
@end deftypefun
|
||||
|
||||
@comment math.h
|
||||
@comment ISO
|
||||
@deftypefun double log2 (double @var{x})
|
||||
@deftypefunx float log2f (float @var{x})
|
||||
@deftypefunx {long double} log2l (long double @var{x})
|
||||
These functions return the base-2 logarithm of @var{x}. Except for the
|
||||
different base, it is similar to the @code{log} function. In fact,
|
||||
@code{log2 (@var{x})} equals @code{log (@var{x}) / log (2)}.
|
||||
@end deftypefun
|
||||
|
||||
@comment math.h
|
||||
@comment ISO
|
||||
@deftypefun double pow (double @var{base}, double @var{power})
|
||||
This is a general exponentiation function, returning @var{base} raised
|
||||
@deftypefunx float powf (float @var{base}, float @var{power})
|
||||
@deftypefunx {long double} powl (long double @var{base}, long double @var{power})
|
||||
These are general exponentiation functions, returning @var{base} raised
|
||||
to @var{power}.
|
||||
|
||||
@need 250
|
||||
@@ -296,48 +481,141 @@ An underflow or overflow condition was detected in the result.
|
||||
@comment math.h
|
||||
@comment ISO
|
||||
@deftypefun double sqrt (double @var{x})
|
||||
This function returns the nonnegative square root of @var{x}.
|
||||
@deftypefunx float sqrtf (float @var{x})
|
||||
@deftypefunx {long double} sqrtl (long double @var{x})
|
||||
These functions return the nonnegative square root of @var{x}.
|
||||
|
||||
The @code{sqrt} function fails, and sets @code{errno} to @code{EDOM}, if
|
||||
@var{x} is negative. Mathematically, the square root would be a complex
|
||||
number.
|
||||
@c (@pxref{csqrt})
|
||||
@end deftypefun
|
||||
|
||||
@cindex cube root function
|
||||
@comment math.h
|
||||
@comment BSD
|
||||
@deftypefun double cbrt (double @var{x})
|
||||
This function returns the cube root of @var{x}. This function cannot
|
||||
@deftypefunx float cbrtf (float @var{x})
|
||||
@deftypefunx {long double} cbrtl (long double @var{x})
|
||||
These functions return the cube root of @var{x}. They cannot
|
||||
fail; every representable real value has a representable real cube root.
|
||||
@end deftypefun
|
||||
|
||||
@comment math.h
|
||||
@comment BSD
|
||||
@comment ISO
|
||||
@deftypefun double hypot (double @var{x}, double @var{y})
|
||||
The @code{hypot} function returns @code{sqrt (@var{x}*@var{x} +
|
||||
@deftypefunx float hypotf (float @var{x}, float @var{y})
|
||||
@deftypefunx {long double} hypotl (long double @var{x}, long double @var{y})
|
||||
These functions return @code{sqrt (@var{x}*@var{x} +
|
||||
@var{y}*@var{y})}. (This is the length of the hypotenuse of a right
|
||||
triangle with sides of length @var{x} and @var{y}, or the distance
|
||||
of the point (@var{x}, @var{y}) from the origin.) See also the function
|
||||
@code{cabs} in @ref{Absolute Value}.
|
||||
of the point (@var{x}, @var{y}) from the origin.) Using this function
|
||||
instead of the direct formula is highly appreciated since the error is
|
||||
much smaller. See also the function @code{cabs} in @ref{Absolute Value}.
|
||||
@end deftypefun
|
||||
|
||||
@comment math.h
|
||||
@comment BSD
|
||||
@comment ISO
|
||||
@deftypefun double expm1 (double @var{x})
|
||||
This function returns a value equivalent to @code{exp (@var{x}) - 1}.
|
||||
@deftypefunx float expm1f (float @var{x})
|
||||
@deftypefunx {long double} expm1l (long double @var{x})
|
||||
These functions return a value equivalent to @code{exp (@var{x}) - 1}.
|
||||
It is computed in a way that is accurate even if the value of @var{x} is
|
||||
near zero---a case where @code{exp (@var{x}) - 1} would be inaccurate due
|
||||
to subtraction of two numbers that are nearly equal.
|
||||
@end deftypefun
|
||||
|
||||
@comment math.h
|
||||
@comment BSD
|
||||
@comment ISO
|
||||
@deftypefun double log1p (double @var{x})
|
||||
@deftypefunx float log1pf (float @var{x})
|
||||
@deftypefunx {long double} log1pl (long double @var{x})
|
||||
This function returns a value equivalent to @w{@code{log (1 + @var{x})}}.
|
||||
It is computed in a way that is accurate even if the value of @var{x} is
|
||||
near zero.
|
||||
@end deftypefun
|
||||
|
||||
@cindex complex exponentiation functions
|
||||
@cindex complex logarithm functions
|
||||
|
||||
@w{ISO C 9X} defines variants of some of the exponentiation and
|
||||
logarithm functions. As for the other functions handlung complex
|
||||
numbers these functions are perhaps better optimized and provide better
|
||||
error checking than a direct use of the formulas of the mathematical
|
||||
definition.
|
||||
|
||||
@comment complex.h
|
||||
@comment ISO
|
||||
@deftypefun {complex double} cexp (complex double @var{z})
|
||||
@deftypefunx {complex float} cexpf (complex float @var{z})
|
||||
@deftypefunx {complex long double} cexpl (complex long double @var{z})
|
||||
These functions return the value of @code{e} (the base of natural
|
||||
logarithms) raised to power of the complex value @var{z}.
|
||||
|
||||
@noindent
|
||||
Mathematically this corresponds to the value
|
||||
|
||||
@ifinfo
|
||||
@math{exp (z) = exp (creal (z)) * (cos (cimag (z)) + I * sin (cimag (z)))}
|
||||
@end ifinfo
|
||||
@iftex
|
||||
@tex
|
||||
$$\exp(z) = e^z = e^{{\rm Re} z} (\cos ({\rm Im} z) + i \sin ({\rm Im} z))$$
|
||||
@end tex
|
||||
@end iftex
|
||||
@end deftypefun
|
||||
|
||||
@comment complex.h
|
||||
@comment ISO
|
||||
@deftypefun {complex double} clog (complex double @var{z})
|
||||
@deftypefunx {complex float} clogf (complex float @var{z})
|
||||
@deftypefunx {complex long double} clogl (complex long double @var{z})
|
||||
These functions return the natural logarithm of the complex value
|
||||
@var{z}. Unlike the real value version @code{log} and its variants,
|
||||
@code{clog} has no limit for the range of its argument @var{z}.
|
||||
|
||||
@noindent
|
||||
Mathematically this corresponds to the value
|
||||
|
||||
@ifinfo
|
||||
@math{log (z) = log (cabs (z)) + I * carg (z)}
|
||||
@end ifinfo
|
||||
@iftex
|
||||
@tex
|
||||
$$\log(z) = \log(|z|) + i \arg(z)$$
|
||||
@end tex
|
||||
@end iftex
|
||||
@end deftypefun
|
||||
|
||||
@comment complex.h
|
||||
@comment ISO
|
||||
@deftypefun {complex double} csqrt (complex double @var{z})
|
||||
@deftypefunx {complex float} csqrtf (complex float @var{z})
|
||||
@deftypefunx {complex long double} csqrtl (complex long double @var{z})
|
||||
These functions return the complex root of the argument @var{z}. Unlike
|
||||
the @code{sqrt} function these functions do not have any restriction on
|
||||
the value of the argument.
|
||||
@end deftypefun
|
||||
|
||||
@comment complex.h
|
||||
@comment ISO
|
||||
@deftypefun {complex double} cpow (complex double @var{base}, complex double @var{power})
|
||||
@deftypefunx {complex float} cpowf (complex float @var{base}, complex float @var{power})
|
||||
@deftypefunx {complex long double} cpowl (complex long double @var{base}, complex long double @var{power})
|
||||
These functions return the complex value @var{BASE} raised to the power of
|
||||
@var{power}. This is computed as
|
||||
|
||||
@ifinfo
|
||||
@math{cpow (x, y) = cexp (y * clog (x))}
|
||||
@end ifinfo
|
||||
@iftex
|
||||
@tex
|
||||
$${\rm cpow}(x, y) = e^{y \log(x)}$$
|
||||
@end tex
|
||||
@end iftex
|
||||
@end deftypefun
|
||||
|
||||
|
||||
@node Hyperbolic Functions
|
||||
@section Hyperbolic Functions
|
||||
@cindex hyperbolic functions
|
||||
@@ -348,8 +626,10 @@ see @ref{Exponents and Logarithms}.
|
||||
@comment math.h
|
||||
@comment ISO
|
||||
@deftypefun double sinh (double @var{x})
|
||||
The @code{sinh} function returns the hyperbolic sine of @var{x}, defined
|
||||
mathematically as @w{@code{exp (@var{x}) - exp (-@var{x}) / 2}}. The
|
||||
@deftypefunx float sinhf (float @var{x})
|
||||
@deftypefunx {long double} sinhl (long double @var{x})
|
||||
These functions return the hyperbolic sine of @var{x}, defined
|
||||
mathematically as @w{@code{(exp (@var{x}) - exp (-@var{x})) / 2}}. The
|
||||
function fails, and sets @code{errno} to @code{ERANGE}, if the value of
|
||||
@var{x} is too large; that is, if overflow occurs.
|
||||
@end deftypefun
|
||||
@@ -357,8 +637,10 @@ function fails, and sets @code{errno} to @code{ERANGE}, if the value of
|
||||
@comment math.h
|
||||
@comment ISO
|
||||
@deftypefun double cosh (double @var{x})
|
||||
The @code{cosh} function returns the hyperbolic cosine of @var{x},
|
||||
defined mathematically as @w{@code{exp (@var{x}) + exp (-@var{x}) / 2}}.
|
||||
@deftypefunx float coshf (float @var{x})
|
||||
@deftypefunx {long double} coshl (long double @var{x})
|
||||
These function return the hyperbolic cosine of @var{x},
|
||||
defined mathematically as @w{@code{(exp (@var{x}) + exp (-@var{x})) / 2}}.
|
||||
The function fails, and sets @code{errno} to @code{ERANGE}, if the value
|
||||
of @var{x} is too large; that is, if overflow occurs.
|
||||
@end deftypefun
|
||||
@@ -366,36 +648,116 @@ of @var{x} is too large; that is, if overflow occurs.
|
||||
@comment math.h
|
||||
@comment ISO
|
||||
@deftypefun double tanh (double @var{x})
|
||||
This function returns the hyperbolic tangent of @var{x}, whose
|
||||
@deftypefunx float tanhf (float @var{x})
|
||||
@deftypefunx {long double} tanhl (long double @var{x})
|
||||
These functions return the hyperbolic tangent of @var{x}, whose
|
||||
mathematical definition is @w{@code{sinh (@var{x}) / cosh (@var{x})}}.
|
||||
@end deftypefun
|
||||
|
||||
@cindex hyperbolic functions
|
||||
|
||||
There are counterparts for these hyperbolic functions which work with
|
||||
complex valued arguments. They should always be used instead of the
|
||||
obvious mathematical formula since the implementations in the math
|
||||
library are optimized for accuracy and speed.
|
||||
|
||||
@comment complex.h
|
||||
@comment ISO
|
||||
@deftypefun {complex double} csinh (complex double @var{z})
|
||||
@deftypefunx {complex float} csinhf (complex float @var{z})
|
||||
@deftypefunx {complex long double} csinhl (complex long double @var{z})
|
||||
These functions return the complex hyperbolic sine of @var{z}, defined
|
||||
mathematically as @w{@code{(exp (@var{z}) - exp (-@var{z})) / 2}}. The
|
||||
function fails, and sets @code{errno} to @code{ERANGE}, if the value of
|
||||
result is too large.
|
||||
@end deftypefun
|
||||
|
||||
@comment complex.h
|
||||
@comment ISO
|
||||
@deftypefun {complex double} ccosh (complex double @var{z})
|
||||
@deftypefunx {complex float} ccoshf (complex float @var{z})
|
||||
@deftypefunx {complex long double} ccoshl (complex long double @var{z})
|
||||
These functions return the complex hyperbolic cosine of @var{z}, defined
|
||||
mathematically as @w{@code{(exp (@var{z}) + exp (-@var{z})) / 2}}. The
|
||||
function fails, and sets @code{errno} to @code{ERANGE}, if the value of
|
||||
result is too large.
|
||||
@end deftypefun
|
||||
|
||||
@comment complex.h
|
||||
@comment ISO
|
||||
@deftypefun {complex double} ctanh (complex double @var{z})
|
||||
@deftypefunx {complex float} ctanhf (complex float @var{z})
|
||||
@deftypefunx {complex long double} ctanhl (complex long double @var{z})
|
||||
These functions return the complex hyperbolic tangent of @var{z}, whose
|
||||
mathematical definition is @w{@code{csinh (@var{z}) / ccosh (@var{z})}}.
|
||||
@end deftypefun
|
||||
|
||||
|
||||
@cindex inverse hyperbolic functions
|
||||
|
||||
@comment math.h
|
||||
@comment BSD
|
||||
@comment ISO
|
||||
@deftypefun double asinh (double @var{x})
|
||||
This function returns the inverse hyperbolic sine of @var{x}---the
|
||||
@deftypefunx float asinhf (float @var{x})
|
||||
@deftypefunx {long double} asinhl (long double @var{x})
|
||||
These functions return the inverse hyperbolic sine of @var{x}---the
|
||||
value whose hyperbolic sine is @var{x}.
|
||||
@end deftypefun
|
||||
|
||||
@comment math.h
|
||||
@comment BSD
|
||||
@comment ISO
|
||||
@deftypefun double acosh (double @var{x})
|
||||
This function returns the inverse hyperbolic cosine of @var{x}---the
|
||||
@deftypefunx float acoshf (float @var{x})
|
||||
@deftypefunx {long double} acoshl (long double @var{x})
|
||||
These functions return the inverse hyperbolic cosine of @var{x}---the
|
||||
value whose hyperbolic cosine is @var{x}. If @var{x} is less than
|
||||
@code{1}, @code{acosh} returns @code{HUGE_VAL}.
|
||||
@end deftypefun
|
||||
|
||||
@comment math.h
|
||||
@comment BSD
|
||||
@comment ISO
|
||||
@deftypefun double atanh (double @var{x})
|
||||
This function returns the inverse hyperbolic tangent of @var{x}---the
|
||||
@deftypefunx float atanhf (float @var{x})
|
||||
@deftypefunx {long double} atanhl (long double @var{x})
|
||||
These functions return the inverse hyperbolic tangent of @var{x}---the
|
||||
value whose hyperbolic tangent is @var{x}. If the absolute value of
|
||||
@var{x} is greater than or equal to @code{1}, @code{atanh} returns
|
||||
@code{HUGE_VAL}.
|
||||
@end deftypefun
|
||||
|
||||
@cindex inverse complex hyperbolic functions
|
||||
|
||||
@comment complex.h
|
||||
@comment ISO
|
||||
@deftypefun {complex double} casinh (complex double @var{z})
|
||||
@deftypefunx {complex float} casinhf (complex float @var{z})
|
||||
@deftypefunx {complex long double} casinhl (complex long double @var{z})
|
||||
These functions return the inverse complex hyperbolic sine of
|
||||
@var{z}---the value whose complex hyperbolic sine is @var{z}.
|
||||
@end deftypefun
|
||||
|
||||
@comment complex.h
|
||||
@comment ISO
|
||||
@deftypefun {complex double} cacosh (complex double @var{z})
|
||||
@deftypefunx {complex float} cacoshf (complex float @var{z})
|
||||
@deftypefunx {complex long double} cacoshl (complex long double @var{z})
|
||||
These functions return the inverse complex hyperbolic cosine of
|
||||
@var{z}---the value whose complex hyperbolic cosine is @var{z}. Unlike
|
||||
the real valued function @code{acosh} there is not limit for the range
|
||||
of the argument.
|
||||
@end deftypefun
|
||||
|
||||
@comment complex.h
|
||||
@comment ISO
|
||||
@deftypefun {complex double} catanh (complex double @var{z})
|
||||
@deftypefunx {complex float} catanhf (complex float @var{z})
|
||||
@deftypefunx {complex long double} catanhl (complex long double @var{z})
|
||||
These functions return the inverse complex hyperbolic tangent of
|
||||
@var{z}---the value whose complex hyperbolic tangent is @var{z}. Unlike
|
||||
the real valued function @code{atanh} there is not limit for the range
|
||||
of the argument.
|
||||
@end deftypefun
|
||||
|
||||
@node Pseudo-Random Numbers
|
||||
@section Pseudo-Random Numbers
|
||||
@cindex random numbers
|
||||
@@ -431,6 +793,7 @@ ones, @code{rand} and @code{srand}.
|
||||
@menu
|
||||
* ISO Random:: @code{rand} and friends.
|
||||
* BSD Random:: @code{random} and friends.
|
||||
* SVID Random:: @code{drand48} and friends.
|
||||
@end menu
|
||||
|
||||
@node ISO Random
|
||||
@@ -526,3 +889,346 @@ The return value is the previous value of the state information array.
|
||||
You can use thise value later as an argument to @code{setstate} to
|
||||
restore that state.
|
||||
@end deftypefun
|
||||
|
||||
|
||||
@node SVID Random
|
||||
@subsection SVID Random Number Function
|
||||
|
||||
The C library on SVID systems contains yet another kind of random number
|
||||
generator functions. They use a state of 48 bits of data. The user can
|
||||
choose among a collection of functions which all return the random bits
|
||||
in different forms.
|
||||
|
||||
Generally there are two kinds of functions: those which use a state of
|
||||
the random number generator which is shared among several functions and
|
||||
by all threads of the process. The second group of functions require
|
||||
the user to handle the state.
|
||||
|
||||
All functions have in common that they use the same congruential
|
||||
formula with the same constants. The formula is
|
||||
|
||||
@smallexample
|
||||
Y = (a * X + c) mod m
|
||||
@end smallexample
|
||||
|
||||
@noindent
|
||||
where @var{X} is the state of the generator at the beginning and
|
||||
@var{Y} the state at the end. @code{a} and @code{c} are constants
|
||||
determining the way the generator work. By default they are
|
||||
|
||||
@smallexample
|
||||
a = 0x5DEECE66D = 25214903917
|
||||
c = 0xb = 11
|
||||
@end smallexample
|
||||
|
||||
@noindent
|
||||
but they can also be changed by the user. @code{m} is of course 2^48
|
||||
since the state consists of a 48 bit array.
|
||||
|
||||
|
||||
@comment stdlib.h
|
||||
@comment SVID
|
||||
@deftypefun double drand48 ()
|
||||
This function returns a @code{double} value in the range of @code{0.0}
|
||||
to @code{1.0} (exclusive). The random bits are determined by the global
|
||||
state of the random number generator in the C library.
|
||||
|
||||
Since the @code{double} type according to @w{IEEE 754} has a 52 bit
|
||||
mantissa this means 4 bits are not initialized by the random number
|
||||
generator. These are (of course) chosen to be the least significant
|
||||
bits and they are initialized to @code{0}.
|
||||
@end deftypefun
|
||||
|
||||
@comment stdlib.h
|
||||
@comment SVID
|
||||
@deftypefun double erand48 (unsigned short int @var{xsubi}[3])
|
||||
This function returns a @code{double} value in the range of @code{0.0}
|
||||
to @code{1.0} (exclusive), similar to @code{drand48}. The argument is
|
||||
an array describing the state of the random number generator.
|
||||
|
||||
This function can be called subsequently since it updates the array to
|
||||
guarantee random numbers. The array should have been initialized before
|
||||
using to get reproducible results.
|
||||
@end deftypefun
|
||||
|
||||
@comment stdlib.h
|
||||
@comment SVID
|
||||
@deftypefun {long int} lrand48 ()
|
||||
The @code{lrand48} functions return an integer value in the range of
|
||||
@code{0} to @code{2^31} (exclusive). Even if the size of the @code{long
|
||||
int} type can take more than 32 bits no higher numbers are returned.
|
||||
The random bits are determined by the global state of the random number
|
||||
generator in the C library.
|
||||
@end deftypefun
|
||||
|
||||
@comment stdlib.h
|
||||
@comment SVID
|
||||
@deftypefun {long int} nrand48 (unsigned short int @var{xsubi}[3])
|
||||
This function is similar to the @code{lrand48} function in that it
|
||||
returns a number in the range of @code{0} to @code{2^31} (exclusive) but
|
||||
the state of the random number generator used to produce the random bits
|
||||
is determined by the array provided as the parameter to the function.
|
||||
|
||||
The numbers in the array are afterwards updated so that subsequent calls
|
||||
to this function yield to different results (as it is expected by a
|
||||
random number generator). The array should have been initialized before
|
||||
the first call to get reproducible results.
|
||||
@end deftypefun
|
||||
|
||||
@comment stdlib.h
|
||||
@comment SVID
|
||||
@deftypefun {long int} mrand48 ()
|
||||
The @code{mrand48} function is similar to @code{lrand48}. The only
|
||||
difference is that the numbers returned are in the range @code{-2^31} to
|
||||
@code{2^31} (exclusive).
|
||||
@end deftypefun
|
||||
|
||||
@comment stdlib.h
|
||||
@comment SVID
|
||||
@deftypefun {long int} jrand48 (unsigned short int @var{xsubi}[3])
|
||||
The @code{jrand48} function is similar to @code{nrand48}. The only
|
||||
difference is that the numbers returned are in the range @code{-2^31} to
|
||||
@code{2^31} (exclusive). For the @code{xsubi} parameter the same
|
||||
requirements are necessary.
|
||||
@end deftypefun
|
||||
|
||||
The internal state of the random number generator can be initialized in
|
||||
several ways. The functions differ in the completeness of the
|
||||
information provided.
|
||||
|
||||
@comment stdlib.h
|
||||
@comment SVID
|
||||
@deftypefun void srand48 (long int @var{seedval}))
|
||||
The @code{srand48} function sets the most significant 32 bits of the
|
||||
state internal state of the random number generator to the least
|
||||
significant 32 bits of the @var{seedval} parameter. The lower 16 bts
|
||||
are initilialized to the value @code{0x330E}. Even if the @code{long
|
||||
int} type contains more the 32 bits only the lower 32 bits are used.
|
||||
|
||||
Due to this limitation the initialization of the state using this
|
||||
function of not very useful. But it makes it easy to use a constrcut
|
||||
like @code{srand48 (time (0))}.
|
||||
|
||||
A side-effect of this function is that the values @code{a} and @code{c}
|
||||
from the internal state, which are used in the congruential formula,
|
||||
are reset to the default values given above. This is of importance once
|
||||
the user called the @code{lcong48} function (see below).
|
||||
@end deftypefun
|
||||
|
||||
@comment stdlib.h
|
||||
@comment SVID
|
||||
@deftypefun {unsigned short int *} seed48 (unsigned short int @var{seed16v}[3])
|
||||
The @code{seed48} function initializes all 48 bits of the state of the
|
||||
internal random number generator from the content of the parameter
|
||||
@var{seed16v}. Here the lower 16 bits of the first element of
|
||||
@var{see16v} initialize the least significant 16 bits of the internal
|
||||
state, the lower 16 bits of @code{@var{seed16v}[1]} initialize the mid-order
|
||||
16 bits of the state and the 16 lower bits of @code{@var{seed16v}[2]}
|
||||
initialize the most significant 16 bits of the state.
|
||||
|
||||
Unlike @code{srand48} this function lets the user initialize all 48 bits
|
||||
of the state.
|
||||
|
||||
The value returned by @code{seed48} is a pointer to an array containing
|
||||
the values of the internal state before the change. This might be
|
||||
useful to restart the random number generator at a certain state.
|
||||
Otherwise, the value can simply be ignored.
|
||||
|
||||
As for @code{srand48}, the values @code{a} and @code{c} from the
|
||||
congruential formula are reset to the default values.
|
||||
@end deftypefun
|
||||
|
||||
There is one more function to initialize the random number generator
|
||||
which allows to specify even more information by allowing to change the
|
||||
parameters in the congruential formula.
|
||||
|
||||
@comment stdlib.h
|
||||
@comment SVID
|
||||
@deftypefun void lcong48 (unsigned short int @var{param}[7])
|
||||
The @code{lcong48} function allows the user to change the complete state
|
||||
of the random number generator. Unlike @code{srand48} and
|
||||
@code{seed48}, this function also changes the constants in the
|
||||
congruential formula.
|
||||
|
||||
From the seven elements in the array @var{param} the least significant
|
||||
16 bits of the entries @code{@var{param}[0]} to @code{@var{param}[2]}
|
||||
determine the the initial state, the least 16 bits of
|
||||
@code{@var{param}[3]} to @code{@var{param}[5]} determine the 48 bit
|
||||
constant @code{a} and @code{@var{param}[6]} determines the 16 bit value
|
||||
@code{c}.
|
||||
@end deftypefun
|
||||
|
||||
All the above functions have in common that they use the global
|
||||
parameters for the congruential formula. In multi-threaded programs it
|
||||
might sometimes be useful to have different parameters in different
|
||||
threads. For this reason all the above functions have a counterpart
|
||||
which works on a description of the random number generator in the
|
||||
user-supplied buffer instead of the global state.
|
||||
|
||||
Please note that it is no problem if several threads use the global
|
||||
state if all threads use the functions which take a pointer to an array
|
||||
containing the state. The random numbers are computed following the
|
||||
same loop but if the state in the array is different all threads will
|
||||
get an individuual random number generator.
|
||||
|
||||
The user supplied buffer must be of type @code{struct drand48_data}.
|
||||
This type should be regarded as opaque and no member should be used
|
||||
directly.
|
||||
|
||||
@comment stdlib.h
|
||||
@comment GNU
|
||||
@deftypefun int drand48_r (struct drand48_data *@var{buffer}, double *@var{result})
|
||||
This function is equivalent to the @code{drand48} function with the
|
||||
difference it does not modify the global random number generator
|
||||
parameters but instead the parameters is the buffer supplied by the
|
||||
buffer through the pointer @var{buffer}. The random number is return in
|
||||
the variable pointed to by @var{result}.
|
||||
|
||||
The return value of the function indicate whether the call succeeded.
|
||||
If the value is less than @code{0} an error occurred and @var{errno} is
|
||||
set to indicate the problem.
|
||||
|
||||
This function is a GNU extension and should not be used in portable
|
||||
programs.
|
||||
@end deftypefun
|
||||
|
||||
@comment stdlib.h
|
||||
@comment GNU
|
||||
@deftypefun int erand48_r (unsigned short int @var{xsubi}[3], struct drand48_data *@var{buffer}, double *@var{result})
|
||||
The @code{erand48_r} function works like the @code{erand48} and it takes
|
||||
an argument @var{buffer} which describes the random number generator.
|
||||
The state of the random number genertor is taken from the @code{xsubi}
|
||||
array, the parameters for the congruential formula from the global
|
||||
random number generator data. The random number is return in the
|
||||
variable pointed to by @var{result}.
|
||||
|
||||
The return value is non-negative is the call succeeded.
|
||||
|
||||
This function is a GNU extension and should not be used in portable
|
||||
programs.
|
||||
@end deftypefun
|
||||
|
||||
@comment stdlib.h
|
||||
@comment GNU
|
||||
@deftypefun int lrand48_r (struct drand48_data *@var{buffer}, double *@var{result})
|
||||
This function is similar to @code{lrand48} and it takes a pointer to a
|
||||
buffer describing the state of the random number generator as a
|
||||
parameter just like @code{drand48}.
|
||||
|
||||
If the return value of the function is non-negative the variable pointed
|
||||
to by @var{result} contains the result. Otherwise an error occurred.
|
||||
|
||||
This function is a GNU extension and should not be used in portable
|
||||
programs.
|
||||
@end deftypefun
|
||||
|
||||
@comment stdlib.h
|
||||
@comment GNU
|
||||
@deftypefun int nrand48_r (unsigned short int @var{xsubi}[3], struct drand48_data *@var{buffer}, long int *@var{result})
|
||||
The @code{nrand48_r} function works like @code{nrand48} in that it
|
||||
produces a random number in range @code{0} to @code{2^31}. But instead
|
||||
of using the global parameters for the congruential formula it uses the
|
||||
information from the buffer pointed to by @var{buffer}. The state is
|
||||
described by the values in @var{xsubi}.
|
||||
|
||||
If the return value is non-negative the variable pointed to by
|
||||
@var{result} contains the result.
|
||||
|
||||
This function is a GNU extension and should not be used in portable
|
||||
programs.
|
||||
@end deftypefun
|
||||
|
||||
@comment stdlib.h
|
||||
@comment GNU
|
||||
@deftypefun int mrand48_r (struct drand48_data *@var{buffer}, double *@var{result})
|
||||
This function is similar to @code{mrand48} but as the other reentrant
|
||||
function it uses the random number generator described by the value in
|
||||
the buffer pointed to by @var{buffer}.
|
||||
|
||||
If the return value is non-negative the variable pointed to by
|
||||
@var{result} contains the result.
|
||||
|
||||
This function is a GNU extension and should not be used in portable
|
||||
programs.
|
||||
@end deftypefun
|
||||
|
||||
@comment stdlib.h
|
||||
@comment GNU
|
||||
@deftypefun int jrand48_r (unsigned short int @var{xsubi}[3], struct drand48_data *@var{buffer}, long int *@var{result})
|
||||
The @code{jrand48_r} function is similar to @code{jrand48}. But as the
|
||||
other reentrant functions of this function family it uses the
|
||||
congruential formula parameters from the buffer pointed to by
|
||||
@var{buffer}.
|
||||
|
||||
If the return value is non-negative the variable pointed to by
|
||||
@var{result} contains the result.
|
||||
|
||||
This function is a GNU extension and should not be used in portable
|
||||
programs.
|
||||
@end deftypefun
|
||||
|
||||
Before any of the above functions should be used the buffer of type
|
||||
@code{struct drand48_data} should initialized. The easiest way is to
|
||||
fill the whole buffer with null bytes, e.g., using
|
||||
|
||||
@smallexample
|
||||
memset (buffer, '\0', sizeof (struct drand48_data));
|
||||
@end smallexample
|
||||
|
||||
@noindent
|
||||
Using any of the reetrant functions of this family now will
|
||||
automatically initialize the random number generator to the default
|
||||
values for the state and the parameters of the congruential formula.
|
||||
|
||||
The other possibility is too use any of the functions which explicitely
|
||||
initialize the buffer. Though it might be obvious how to initialize the
|
||||
buffer from the data given as parameter from the function it is highly
|
||||
recommended to use these functions since the result might not always be
|
||||
what you expect.
|
||||
|
||||
@comment stdlib.h
|
||||
@comment GNU
|
||||
@deftypefun int srand48_r (long int @var{seedval}, struct drand48_data *@var{buffer})
|
||||
The description of the random number generator represented by the
|
||||
information in @var{buffer} is initialized similar to what the function
|
||||
@code{srand48} does. The state is initialized from the paramter
|
||||
@var{seedval} and the paameters for the congruential formula are
|
||||
initialized to the default values.
|
||||
|
||||
If the return value is non-negative the function call succeeded.
|
||||
|
||||
This function is a GNU extension and should not be used in portable
|
||||
programs.
|
||||
@end deftypefun
|
||||
|
||||
@comment stdlib.h
|
||||
@comment GNU
|
||||
@deftypefun int seed48_r (unsigned short int @var{seed16v}[3], struct drand48_data *@var{buffer})
|
||||
This function is similar to @code{srand48_r} but like @code{seed48} it
|
||||
initializes all 48 bits of the state from the parameter @var{seed16v}.
|
||||
|
||||
If the return value is non-negative the function call succeeded. It
|
||||
does not return a pointer to the previous state of the random number
|
||||
generator like the @code{seed48} function does. if the user wants to
|
||||
preserve the state for a later rerun s/he can copy the whole buffer
|
||||
pointed to by @var{buffer}.
|
||||
|
||||
This function is a GNU extension and should not be used in portable
|
||||
programs.
|
||||
@end deftypefun
|
||||
|
||||
@comment stdlib.h
|
||||
@comment GNU
|
||||
@deftypefun int lcong48_r (unsigned short int @var{param}[7], struct drand48_data *@var{buffer})
|
||||
This function initializes all aspects of the random number generator
|
||||
described in @var{buffer} by the data in @var{param}. Here it is
|
||||
especially true the function does more than just copying the contents of
|
||||
@var{param} of @var{buffer}. Some more actions are required and
|
||||
therefore it is important to use this function and not initialized the
|
||||
random number generator directly.
|
||||
|
||||
If the return value is non-negative the function call succeeded.
|
||||
|
||||
This function is a GNU extension and should not be used in portable
|
||||
programs.
|
||||
@end deftypefun
|
||||
|
||||
+133
-42
@@ -38,7 +38,6 @@ will be freed automatically. @xref{Variable Size Automatic}.
|
||||
calling function returns.
|
||||
* Relocating Allocator:: Waste less memory, if you can tolerate
|
||||
automatic relocation of the blocks you get.
|
||||
* Memory Warnings:: Getting warnings when memory is nearly full.
|
||||
@end menu
|
||||
|
||||
@node Memory Concepts
|
||||
@@ -140,6 +139,8 @@ any time (or never).
|
||||
these functions.
|
||||
* Aligned Memory Blocks:: Allocating specially aligned memory:
|
||||
@code{memalign} and @code{valloc}.
|
||||
* Malloc Tunable Parameters:: Use @code{mallopt} to adjust allocation
|
||||
parameters.
|
||||
* Heap Consistency Checking:: Automatic checking for errors.
|
||||
* Hooks for Malloc:: You can use these hooks for debugging
|
||||
programs that use @code{malloc}.
|
||||
@@ -238,10 +239,10 @@ savestring (const char *ptr, size_t len)
|
||||
|
||||
The block that @code{malloc} gives you is guaranteed to be aligned so
|
||||
that it can hold any type of data. In the GNU system, the address is
|
||||
always a multiple of eight; if the size of block is 16 or more, then the
|
||||
address is always a multiple of 16. Only rarely is any higher boundary
|
||||
(such as a page boundary) necessary; for those cases, use
|
||||
@code{memalign} or @code{valloc} (@pxref{Aligned Memory Blocks}).
|
||||
always a multiple of eight on most systems, and a multiple of 16 on
|
||||
64-bit systems. Only rarely is any higher boundary (such as a page
|
||||
boundary) necessary; for those cases, use @code{memalign} or
|
||||
@code{valloc} (@pxref{Aligned Memory Blocks}).
|
||||
|
||||
Note that the memory located after the end of the block is likely to be
|
||||
in use for something else; perhaps a block already allocated by another
|
||||
@@ -368,9 +369,11 @@ xrealloc (void *ptr, size_t size)
|
||||
@end smallexample
|
||||
|
||||
You can also use @code{realloc} to make a block smaller. The reason you
|
||||
would do this is to avoid tying up a lot of memory space when only a little
|
||||
is needed. Making a block smaller sometimes necessitates copying it, so it
|
||||
can fail if no other space is available.
|
||||
is needed.
|
||||
@comment The following is no longer true with the new malloc.
|
||||
@comment But it seems wise to keep the warning for other implementations.
|
||||
In several allocation implementations, making a block smaller sometimes
|
||||
necessitates copying it, so it can fail if no other space is available.
|
||||
|
||||
If the new size you specify is the same as the old size, @code{realloc}
|
||||
is guaranteed to change nothing and return the same address that you gave.
|
||||
@@ -404,10 +407,18 @@ calloc (size_t count, size_t eltsize)
|
||||
@}
|
||||
@end smallexample
|
||||
|
||||
But in general, it is not guaranteed that @code{calloc} calls
|
||||
@code{malloc} internally. Therefore, if an application provides its own
|
||||
@code{malloc}/@code{realloc}/@code{free} outside the C library, it
|
||||
should always define @code{calloc}, too.
|
||||
|
||||
@node Efficiency and Malloc
|
||||
@subsection Efficiency Considerations for @code{malloc}
|
||||
@cindex efficiency and @code{malloc}
|
||||
|
||||
@ignore
|
||||
|
||||
@c No longer true, see below instead.
|
||||
To make the best use of @code{malloc}, it helps to know that the GNU
|
||||
version of @code{malloc} always dispenses small amounts of memory in
|
||||
blocks whose sizes are powers of two. It keeps separate pools for each
|
||||
@@ -433,6 +444,24 @@ time using it. Also, large blocks are normally fewer in number.
|
||||
Therefore, for large blocks, it makes sense to use a method which takes
|
||||
more time to minimize the wasted space.
|
||||
|
||||
@end ignore
|
||||
|
||||
As apposed to other versions, the @code{malloc} in GNU libc does not
|
||||
round up block sizes to powers of two, neither for large nor for small
|
||||
sizes. Neighboring chunks can be coalesced on a @code{free} no matter
|
||||
what their size is. This makes the implementation suitable for all
|
||||
kinds of allocation patterns without generally incurring high memory
|
||||
waste through fragmentation.
|
||||
|
||||
Very large blocks (much larger than a page) are allocated with
|
||||
@code{mmap} (anonymous or via @code{/dev/zero}) by this implementation.
|
||||
This has the great advantage that these chunks are returned to the
|
||||
system immediately when they are freed. Therefore, it cannot happen
|
||||
that a large chunk becomes ``locked'' in between smaller ones and even
|
||||
after calling @code{free} wastes memory. The size threshold for
|
||||
@code{mmap} to be used can be adjusted with @code{mallopt}. The use of
|
||||
@code{mmap} can also be disabled completely.
|
||||
|
||||
@node Aligned Memory Blocks
|
||||
@subsection Allocating Aligned Memory Blocks
|
||||
|
||||
@@ -440,10 +469,10 @@ more time to minimize the wasted space.
|
||||
@cindex alignment (with @code{malloc})
|
||||
@pindex stdlib.h
|
||||
The address of a block returned by @code{malloc} or @code{realloc} in
|
||||
the GNU system is always a multiple of eight. If you need a block whose
|
||||
address is a multiple of a higher power of two than that, use
|
||||
@code{memalign} or @code{valloc}. These functions are declared in
|
||||
@file{stdlib.h}.
|
||||
the GNU system is always a multiple of eight (or sixteen on 64-bit
|
||||
systems). If you need a block whose address is a multiple of a higher
|
||||
power of two than that, use @code{memalign} or @code{valloc}. These
|
||||
functions are declared in @file{stdlib.h}.
|
||||
|
||||
With the GNU library, you can use @code{free} to free the blocks that
|
||||
@code{memalign} and @code{valloc} return. That does not work in BSD,
|
||||
@@ -454,9 +483,9 @@ however---BSD does not provide any way to free such blocks.
|
||||
@deftypefun {void *} memalign (size_t @var{boundary}, size_t @var{size})
|
||||
The @code{memalign} function allocates a block of @var{size} bytes whose
|
||||
address is a multiple of @var{boundary}. The @var{boundary} must be a
|
||||
power of two! The function @code{memalign} works by calling
|
||||
@code{malloc} to allocate a somewhat larger block, and then returning an
|
||||
address within the block that is on the specified boundary.
|
||||
power of two! The function @code{memalign} works by allocating a
|
||||
somewhat larger block, and then returning an address within the block
|
||||
that is on the specified boundary.
|
||||
@end deftypefun
|
||||
|
||||
@comment malloc.h stdlib.h
|
||||
@@ -475,6 +504,42 @@ valloc (size_t size)
|
||||
@c !!! xref getpagesize
|
||||
@end deftypefun
|
||||
|
||||
@node Malloc Tunable Parameters
|
||||
@subsection Malloc Tunable Parameters
|
||||
|
||||
You can adjust some parameters for dynamic memory allocation with the
|
||||
@code{mallopt} function. This function is the general SVID/XPG
|
||||
interface, defined in @file{malloc.h}.
|
||||
@pindex malloc.h
|
||||
|
||||
@deftypefun int mallopt (int @var{param}, int @var{value})
|
||||
When calling @code{mallopt}, the @var{param} argument specifies the
|
||||
parameter to be set, and @var{value} the new value to be set. Possible
|
||||
choices for @var{param}, as defined in @file{malloc.h}, are:
|
||||
|
||||
@table @code
|
||||
@item M_TRIM_THRESHOLD
|
||||
This is the minimum size (in bytes) of the top-most, releaseable chunk
|
||||
that will cause @code{sbrk} to be called with a negative argument in
|
||||
order to return memory to the system.
|
||||
@item M_TOP_PAD
|
||||
This parameter determines the amount of extra memory to obtain from the
|
||||
system when a call to @code{sbrk} is required. It also specifies the
|
||||
number of bytes to retain when shrinking the heap by calling @code{sbrk}
|
||||
with a negative argument. This provides the necessary hysteresis in
|
||||
heap size such that excessive amounts of system calls can be avoided.
|
||||
@item M_MMAP_THRESHOLD
|
||||
All chunks larger than this value are allocated outside the normal
|
||||
heap, using the @code{mmap} system call. This way it is guaranteed
|
||||
that the memory for these chunks can be returned to the system on
|
||||
@code{free}.
|
||||
@item M_MMAP_MAX
|
||||
The maximum number of chunks to allocate with @code{mmap}. Setting this
|
||||
to zero disables all use of @code{mmap}.
|
||||
@end table
|
||||
|
||||
@end deftypefun
|
||||
|
||||
@node Heap Consistency Checking
|
||||
@subsection Heap Consistency Checking
|
||||
|
||||
@@ -636,44 +701,62 @@ installing such hooks.
|
||||
|
||||
@cindex allocation statistics
|
||||
You can get information about dynamic storage allocation by calling the
|
||||
@code{mstats} function. This function and its associated data type are
|
||||
declared in @file{malloc.h}; they are a GNU extension.
|
||||
@code{mallinfo} function. This function and its associated data type
|
||||
are declared in @file{malloc.h}; they are an extension of the standard
|
||||
SVID/XPG version.
|
||||
@pindex malloc.h
|
||||
|
||||
@comment malloc.h
|
||||
@comment GNU
|
||||
@deftp {Data Type} {struct mstats}
|
||||
@deftp {Data Type} {struct mallinfo}
|
||||
This structure type is used to return information about the dynamic
|
||||
storage allocator. It contains the following members:
|
||||
|
||||
@table @code
|
||||
@item size_t bytes_total
|
||||
This is the total size of memory managed by @code{malloc}, in bytes.
|
||||
@item int arena
|
||||
This is the total size of memory allocated with @code{sbrk} by
|
||||
@code{malloc}, in bytes.
|
||||
|
||||
@item size_t chunks_used
|
||||
This is the number of chunks in use. (The storage allocator internally
|
||||
gets chunks of memory from the operating system, and then carves them up
|
||||
to satisfy individual @code{malloc} requests; see @ref{Efficiency and
|
||||
Malloc}.)
|
||||
@item int ordblks
|
||||
This is the number of chunks not in use. (The storage allocator
|
||||
internally gets chunks of memory from the operating system, and then
|
||||
carves them up to satisfy individual @code{malloc} requests; see
|
||||
@ref{Efficiency and Malloc}.)
|
||||
|
||||
@item size_t bytes_used
|
||||
This is the number of bytes in use.
|
||||
@item int smblks
|
||||
This field is unused.
|
||||
|
||||
@item size_t chunks_free
|
||||
This is the number of chunks which are free -- that is, that have been
|
||||
allocated by the operating system to your program, but which are not
|
||||
now being used.
|
||||
@item int hblks
|
||||
This is the total number of chunks allocated with @code{mmap}.
|
||||
|
||||
@item int hblkhd
|
||||
This is the total size of memory allocated with @code{mmap}, in bytes.
|
||||
|
||||
@item int usmblks
|
||||
This field is unused.
|
||||
|
||||
@item int fsmblks
|
||||
This field is unused.
|
||||
|
||||
@item int uordblks
|
||||
This is the total size of memory occupied by chunks handed out by
|
||||
@code{malloc}.
|
||||
|
||||
@item int fordblks
|
||||
This is the total size of memory occupied by free (not in use) chunks.
|
||||
|
||||
@item int keepcost
|
||||
This is the size of the top-most, releaseable chunk that normally
|
||||
borders the end of the heap (i.e. the ``brk'' of the process).
|
||||
|
||||
@item size_t bytes_free
|
||||
This is the number of bytes which are free.
|
||||
@end table
|
||||
@end deftp
|
||||
|
||||
@comment malloc.h
|
||||
@comment GNU
|
||||
@deftypefun {struct mstats} mstats (void)
|
||||
@comment SVID
|
||||
@deftypefun {struct mallinfo} mallinfo (void)
|
||||
This function returns information about the current dynamic memory usage
|
||||
in a structure of type @code{struct mstats}.
|
||||
in a structure of type @code{struct mallinfo}.
|
||||
@end deftypefun
|
||||
|
||||
@node Summary of Malloc
|
||||
@@ -706,6 +789,9 @@ Allocate a block of @var{size} bytes, starting on a page boundary.
|
||||
Allocate a block of @var{size} bytes, starting on an address that is a
|
||||
multiple of @var{boundary}. @xref{Aligned Memory Blocks}.
|
||||
|
||||
@item int mallopt (int @var{param}, int @var{value})
|
||||
Adjust a tunable parameter. @xref{Malloc Tunable Parameters}
|
||||
|
||||
@item int mcheck (void (*@var{abortfn}) (void))
|
||||
Tell @code{malloc} to perform occasional consistency checks on
|
||||
dynamically allocated memory, and to call @var{abortfn} when an
|
||||
@@ -720,7 +806,7 @@ A pointer to a function that @code{realloc} uses whenever it is called.
|
||||
@item void (*__free_hook) (void *@var{ptr})
|
||||
A pointer to a function that @code{free} uses whenever it is called.
|
||||
|
||||
@item struct mstats mstats (void)
|
||||
@item struct mallinfo mallinfo (void)
|
||||
Return information about the current dynamic memory usage.
|
||||
@xref{Statistics of Malloc}.
|
||||
@end table
|
||||
@@ -1744,10 +1830,13 @@ If enough memory is not available, this function returns a null pointer
|
||||
and does not modify @code{*@var{handleptr}}.
|
||||
@end deftypefun
|
||||
|
||||
@node Memory Warnings
|
||||
@section Memory Usage Warnings
|
||||
@cindex memory usage warnings
|
||||
@cindex warnings of memory almost full
|
||||
@ignore
|
||||
@comment No longer available...
|
||||
|
||||
@comment @node Memory Warnings
|
||||
@comment @section Memory Usage Warnings
|
||||
@comment @cindex memory usage warnings
|
||||
@comment @cindex warnings of memory almost full
|
||||
|
||||
@pindex malloc.c
|
||||
You can ask for warnings as the program approaches running out of memory
|
||||
@@ -1757,7 +1846,7 @@ system. This is a GNU extension declared in @file{malloc.h}.
|
||||
|
||||
@comment malloc.h
|
||||
@comment GNU
|
||||
@deftypefun void memory_warnings (void *@var{start}, void (*@var{warn-func}) (const char *))
|
||||
@comment @deftypefun void memory_warnings (void *@var{start}, void (*@var{warn-func}) (const char *))
|
||||
Call this function to request warnings for nearing exhaustion of virtual
|
||||
memory.
|
||||
|
||||
@@ -1775,3 +1864,5 @@ Normally it ought to display the string for the user to read.
|
||||
The warnings come when memory becomes 75% full, when it becomes 85%
|
||||
full, and when it becomes 95% full. Above 95% you get another warning
|
||||
each time memory usage increases.
|
||||
|
||||
@end ignore
|
||||
|
||||
+14
-10
@@ -68,6 +68,9 @@ The databases available in the NSS are
|
||||
@cindex services
|
||||
@cindex shadow
|
||||
@vtable @code
|
||||
@item aliases
|
||||
Mail aliases
|
||||
@comment @pxref{Mail Aliases}.
|
||||
@item ethers
|
||||
Ethernet numbers,
|
||||
@comment @pxref{Ethernet Numbers}.
|
||||
@@ -94,8 +97,8 @@ Shadow user passwords,
|
||||
@end vtable
|
||||
|
||||
@noindent
|
||||
There will be some more added later (@code{aliases}, @code{automount},
|
||||
@code{bootparams}, @code{netmasks}, and @code{publickey}).
|
||||
There will be some more added later (@code{automount}, @code{bootparams},
|
||||
@code{netmasks}, and @code{publickey}).
|
||||
|
||||
@node NSS Configuration File, NSS Module Internals, NSS Basics, Name Service Switch
|
||||
@section The NSS Configuration File
|
||||
@@ -123,7 +126,7 @@ different items:
|
||||
@item
|
||||
the service specification like @code{files}, @code{db}, or @code{nis}.
|
||||
@item
|
||||
the reaction on lookup result line @code{[NOTFOUND=return]}.
|
||||
the reaction on lookup result like @code{[NOTFOUND=return]}.
|
||||
@end itemize
|
||||
|
||||
@menu
|
||||
@@ -346,8 +349,9 @@ functions. I.e., if the user would call the @code{gethostbyname_r}
|
||||
function this also would end in the above function. For all user
|
||||
interface functions the C library maps this call to a call to the
|
||||
reentrant function. For reentrant functions this is trivial since the
|
||||
interface is (nearly) the same. For the non-reentrant version pointers
|
||||
to static buffers are used to replace the user supplied buffers.
|
||||
interface is (nearly) the same. For the non-reentrant version The
|
||||
library keeps internal buffers which are used to replace the user
|
||||
supplied buffer.
|
||||
|
||||
I.e., the reentrant functions @emph{can} have counterparts. No service
|
||||
module is forced to have functions for all databases and all kinds to
|
||||
@@ -399,9 +403,9 @@ enum nss_status _nss_files_gethostbyname_r (const char *name,
|
||||
@end smallexample
|
||||
|
||||
I.e., the interface function is in fact the reentrant function with the
|
||||
change of the return value. While the user-level function returns a
|
||||
pointer to the result the reentrant function return an @code{enum
|
||||
nss_status} value:
|
||||
change of the return value and the omission of the @var{result}
|
||||
parameter. While the user-level function returns a pointer to the
|
||||
result the reentrant function return an @code{enum nss_status} value:
|
||||
|
||||
@vindex NSS_STATUS_TRYAGAIN
|
||||
@vindex NSS_STATUS_UNAVAIL
|
||||
@@ -458,13 +462,13 @@ function;
|
||||
the next three arguments are:
|
||||
|
||||
@table @code
|
||||
@item STRUCT_TYPE result_buf
|
||||
@item STRUCT_TYPE *result_buf
|
||||
pointer to buffer where the result is stored. @code{STRUCT_TYPE} is
|
||||
normally a struct which corresponds to the database.
|
||||
@item char *buffer
|
||||
pointer to a buffer where the function can store additional adata for
|
||||
the result etc.
|
||||
@item int buflen
|
||||
@item size_t buflen
|
||||
length of the buffer pointed to by @var{buffer}.
|
||||
@end table
|
||||
|
||||
|
||||
+1
-2
@@ -833,10 +833,9 @@ will not affect your program unless it explicitly uses them for something.
|
||||
@comment signal.h
|
||||
@comment POSIX.1
|
||||
@deftypevr Macro int SIGUSR1
|
||||
@end deftypevr
|
||||
@comment signal.h
|
||||
@comment POSIX.1
|
||||
@deftypevr Macro int SIGUSR2
|
||||
@deftypevrx Macro int SIGUSR2
|
||||
@cindex user signals
|
||||
The @code{SIGUSR1} and @code{SIGUSR2} signals are set aside for you to
|
||||
use any way you want. They're useful for simple interprocess
|
||||
|
||||
@@ -826,6 +826,10 @@ string in the standard numbers-and-dots notation. The return value is
|
||||
a pointer into a statically-allocated buffer. Subsequent calls will
|
||||
overwrite the same buffer, so you should copy the string if you need
|
||||
to save it.
|
||||
|
||||
In multi-threaded programs each thread has an own statically-allocated
|
||||
buffer. But still subsequent calls of @code{inet_ntoa} in the same
|
||||
thread will overwrite the result of the last call.
|
||||
@end deftypefun
|
||||
|
||||
@comment arpa/inet.h
|
||||
|
||||
+108
-22
@@ -1479,11 +1479,11 @@ the @var{size} argument specifies the maximum number of characters to
|
||||
produce. The trailing null character is counted towards this limit, so
|
||||
you should allocate at least @var{size} characters for the string @var{s}.
|
||||
|
||||
The return value is the number of characters which are generated for the
|
||||
given input. If this value is greater than @var{size}, not all
|
||||
characters from the result have been stored in @var{s}. You should
|
||||
try again with a bigger output string. Here is an example of doing
|
||||
this:
|
||||
The return value is the number of characters which would be generated
|
||||
for the given input. If this value is greater or equal to @var{size},
|
||||
not all characters from the result have been stored in @var{s}. You
|
||||
should try again with a bigger output string. Here is an example of
|
||||
doing this:
|
||||
|
||||
@smallexample
|
||||
@group
|
||||
@@ -1503,7 +1503,7 @@ make_message (char *name, char *value)
|
||||
name, value);
|
||||
@end group
|
||||
@group
|
||||
if (nchars) >= size)
|
||||
if (nchars >= size)
|
||||
@{
|
||||
/* @r{Reallocate buffer now that we know how much space is needed.} */
|
||||
buffer = (char *) xrealloc (buffer, nchars + 1);
|
||||
@@ -1765,47 +1765,40 @@ extract just the basic type code.
|
||||
Here are symbolic constants that represent the basic types; they stand
|
||||
for integer values.
|
||||
|
||||
@table @code
|
||||
@vtable @code
|
||||
@comment printf.h
|
||||
@comment GNU
|
||||
@item PA_INT
|
||||
@vindex PA_INT
|
||||
This specifies that the base type is @code{int}.
|
||||
|
||||
@comment printf.h
|
||||
@comment GNU
|
||||
@item PA_CHAR
|
||||
@vindex PA_CHAR
|
||||
This specifies that the base type is @code{int}, cast to @code{char}.
|
||||
|
||||
@comment printf.h
|
||||
@comment GNU
|
||||
@item PA_STRING
|
||||
@vindex PA_STRING
|
||||
This specifies that the base type is @code{char *}, a null-terminated string.
|
||||
|
||||
@comment printf.h
|
||||
@comment GNU
|
||||
@item PA_POINTER
|
||||
@vindex PA_POINTER
|
||||
This specifies that the base type is @code{void *}, an arbitrary pointer.
|
||||
|
||||
@comment printf.h
|
||||
@comment GNU
|
||||
@item PA_FLOAT
|
||||
@vindex PA_FLOAT
|
||||
This specifies that the base type is @code{float}.
|
||||
|
||||
@comment printf.h
|
||||
@comment GNU
|
||||
@item PA_DOUBLE
|
||||
@vindex PA_DOUBLE
|
||||
This specifies that the base type is @code{double}.
|
||||
|
||||
@comment printf.h
|
||||
@comment GNU
|
||||
@item PA_LAST
|
||||
@vindex PA_LAST
|
||||
You can define additional base types for your own programs as offsets
|
||||
from @code{PA_LAST}. For example, if you have data types @samp{foo}
|
||||
and @samp{bar} with their own specialized @code{printf} conversions,
|
||||
@@ -1815,16 +1808,15 @@ you could define encodings for these types as:
|
||||
#define PA_FOO PA_LAST
|
||||
#define PA_BAR (PA_LAST + 1)
|
||||
@end smallexample
|
||||
@end table
|
||||
@end vtable
|
||||
|
||||
Here are the flag bits that modify a basic type. They are combined with
|
||||
the code for the basic type using inclusive-or.
|
||||
|
||||
@table @code
|
||||
@vtable @code
|
||||
@comment printf.h
|
||||
@comment GNU
|
||||
@item PA_FLAG_PTR
|
||||
@vindex PA_FLAG_PTR
|
||||
If this bit is set, it indicates that the encoded type is a pointer to
|
||||
the base type, rather than an immediate value.
|
||||
For example, @samp{PA_INT|PA_FLAG_PTR} represents the type @samp{int *}.
|
||||
@@ -1832,31 +1824,27 @@ For example, @samp{PA_INT|PA_FLAG_PTR} represents the type @samp{int *}.
|
||||
@comment printf.h
|
||||
@comment GNU
|
||||
@item PA_FLAG_SHORT
|
||||
@vindex PA_FLAG_SHORT
|
||||
If this bit is set, it indicates that the base type is modified with
|
||||
@code{short}. (This corresponds to the @samp{h} type modifier.)
|
||||
|
||||
@comment printf.h
|
||||
@comment GNU
|
||||
@item PA_FLAG_LONG
|
||||
@vindex PA_FLAG_LONG
|
||||
If this bit is set, it indicates that the base type is modified with
|
||||
@code{long}. (This corresponds to the @samp{l} type modifier.)
|
||||
|
||||
@comment printf.h
|
||||
@comment GNU
|
||||
@item PA_FLAG_LONG_LONG
|
||||
@vindex PA_FLAG_LONG_LONG
|
||||
If this bit is set, it indicates that the base type is modified with
|
||||
@code{long long}. (This corresponds to the @samp{L} type modifier.)
|
||||
|
||||
@comment printf.h
|
||||
@comment GNU
|
||||
@item PA_FLAG_LONG_DOUBLE
|
||||
@vindex PA_FLAG_LONG_DOUBLE
|
||||
This is a synonym for @code{PA_FLAG_LONG_LONG}, used by convention with
|
||||
a base type of @code{PA_DOUBLE} to indicate a type of @code{long double}.
|
||||
@end table
|
||||
@end vtable
|
||||
|
||||
@ifinfo
|
||||
For an example of using these facilities, see @ref{Example of Parsing}.
|
||||
@@ -1968,6 +1956,7 @@ The facilities of this section are declared in the header file
|
||||
to @code{register_printf_function}.
|
||||
* Printf Extension Example:: How to define a @code{printf}
|
||||
handler function.
|
||||
* Predefined Printf Handlers:: Predefined @code{printf} handlers.
|
||||
@end menu
|
||||
|
||||
@strong{Portability Note:} The ability to extend the syntax of
|
||||
@@ -2212,6 +2201,103 @@ The output produced by this program looks like:
|
||||
|<Widget 0xffeffb7c: mywidget> |
|
||||
@end smallexample
|
||||
|
||||
@node Predefined Printf Handlers
|
||||
@subsection Predefined @code{printf} Handlers
|
||||
|
||||
The GNU libc also contains a concrete and useful application of the
|
||||
@code{printf} handler extension. There are two functions available
|
||||
which implement a special way to print floating-point numbers.
|
||||
|
||||
@comment printf.h
|
||||
@comment GNU
|
||||
@deftypefun int printf_size (FILE *@var{fp}, const struct printf_info *@var{info}, const void *const *@var{args})
|
||||
Print a given floating point number as for the format @code{%f} except
|
||||
that there is a postfix character indicating the divisor for the
|
||||
number to make this less than 1000. There are two possible divisors:
|
||||
powers of 1024 or powers to 1000. Which one is used depends on the
|
||||
format character specified while registered this handler. If the
|
||||
character is of lower case, 1024 is used. For upper case characters,
|
||||
1000 is used.
|
||||
|
||||
The postfix tag corresponds to bytes, kilobytes, megabytes, gigabytes,
|
||||
etc. The full table is:
|
||||
|
||||
@ifinfo
|
||||
@multitable @hsep @vsep {' '} {2^10 (1024)} {zetta} {Upper} {10^24 (1000)}
|
||||
@item low @tab Multiplier @tab From @tab Upper @tab Multiplier
|
||||
@item ' ' @tab 1 @tab @tab ' ' @tab 1
|
||||
@item k @tab 2^10 (1024) @tab kilo @tab K @tab 10^3 (1000)
|
||||
@item m @tab 2^20 @tab mega @tab M @tab 10^6
|
||||
@item g @tab 2^30 @tab giga @tab G @tab 10^9
|
||||
@item t @tab 2^40 @tab tera @tab T @tab 10^12
|
||||
@item p @tab 2^50 @tab peta @tab P @tab 10^15
|
||||
@item e @tab 2^60 @tab exa @tab E @tab 10^18
|
||||
@item z @tab 2^70 @tab zetta @tab Z @tab 10^21
|
||||
@item y @tab 2^80 @tab yotta @tab Y @tab 10^24
|
||||
@end multitable
|
||||
@end ifinfo
|
||||
@iftex
|
||||
@tex
|
||||
\hbox to\hsize{\hfil\vbox{\offinterlineskip
|
||||
\hrule
|
||||
\halign{\strut#& \vrule#\tabskip=1em plus2em& {\tt#}\hfil& \vrule#& #\hfil& \vrule#& #\hfil& \vrule#& {\tt#}\hfil& \vrule#& #\hfil& \vrule#\tabskip=0pt\cr
|
||||
\noalign{\hrule}
|
||||
\omit&height2pt&\omit&&\omit&&\omit&&\omit&&\omit&\cr
|
||||
&& \omit low && Multiplier && From && \omit Upper && Multiplier &\cr
|
||||
\omit&height2pt&\omit&&\omit&&\omit&&\omit&&\omit&\cr
|
||||
\noalign{\hrule}
|
||||
&& {\tt\char32} && 1 && && {\tt\char32} && 1 &\cr
|
||||
&& k && $2^{10} = 1024$ && kilo && K && $10^3 = 1000$ &\cr
|
||||
&& m && $2^{20}$ && mega && M && $10^6$ &\cr
|
||||
&& g && $2^{30}$ && giga && G && $10^9$ &\cr
|
||||
&& t && $2^{40}$ && tera && T && $10^{12}$ &\cr
|
||||
&& p && $2^{50}$ && peta && P && $10^{15}$ &\cr
|
||||
&& e && $2^{60}$ && exa && E && $10^{18}$ &\cr
|
||||
&& z && $2^{70}$ && zetta && Z && $10^{21}$ &\cr
|
||||
&& y && $2^{80}$ && yotta && Y && $10^{24}$ &\cr
|
||||
\noalign{\hrule}}}\hfil}
|
||||
@end tex
|
||||
@end iftex
|
||||
|
||||
The default precision is 3, i.e., 1024 is printed with a lower-case
|
||||
format character as if it were @code{%.3fk} and will yield @code{1.000k}.
|
||||
@end deftypefun
|
||||
|
||||
Due to the requirements of @code{register_printf_function} we must also
|
||||
provide the function which return information about the arguments.
|
||||
|
||||
@comment printf.h
|
||||
@comment GNU
|
||||
@deftypefun int printf_size_info (const struct printf_info *@var{info}, size_t @var{n}, int *@var{argtypes})
|
||||
This function will return in @var{argtypes} the information about the
|
||||
used parameters in the way the @code{vfprintf} implementation expects
|
||||
it. The format always takes one argument.
|
||||
@end deftypefun
|
||||
|
||||
To use these functions both functions must be registered with a call like
|
||||
|
||||
@smallexample
|
||||
register_printf_function ('B', printf_size, printf_size_info);
|
||||
@end smallexample
|
||||
|
||||
Here we register the functions to print numbers as powers of 1000 since
|
||||
the format character @code{'B'} is an upper-case characeter. If we
|
||||
would additionally use @code{'b'} in a line like
|
||||
|
||||
@smallexample
|
||||
register_printf_function ('b', printf_size, printf_size_info);
|
||||
@end smallexample
|
||||
|
||||
@noindent
|
||||
we could also print using power of 1024. Please note that all what is
|
||||
different in these both lines in the format specifier. The
|
||||
@code{printf_size} function knows about the difference of low and upper
|
||||
case format specifiers.
|
||||
|
||||
The use of @code{'B'} and @code{'b'} is no coincidence. Rather it is
|
||||
the preferred way to use this functionality since it is available on
|
||||
some other systems also available using the format specifiers.
|
||||
|
||||
@node Formatted Input
|
||||
@section Formatted Input
|
||||
|
||||
|
||||
+73
-10
@@ -32,9 +32,10 @@ too.
|
||||
* Search Functions:: Searching for a specific element or substring.
|
||||
* Finding Tokens in a String:: Splitting a string into tokens by looking
|
||||
for delimiters.
|
||||
* Encode Binary Data:: Encoding and Decoding of Binary Data.
|
||||
@end menu
|
||||
|
||||
@node Representation of Strings, String/Array Conventions, , String and Array Utilities
|
||||
@node Representation of Strings
|
||||
@section Representation of Strings
|
||||
@cindex string, representation of
|
||||
|
||||
@@ -99,7 +100,7 @@ checks for overflowing the array. Many of the library functions
|
||||
an extra byte to hold the null character that marks the end of the
|
||||
string.
|
||||
|
||||
@node String/Array Conventions, String Length, Representation of Strings, String and Array Utilities
|
||||
@node String/Array Conventions
|
||||
@section String and Array Conventions
|
||||
|
||||
This chapter describes both functions that work on arbitrary arrays or
|
||||
@@ -132,7 +133,7 @@ other hand, when you are manipulating null-terminated strings it is
|
||||
usually more convenient to use the @samp{str} functions, unless you
|
||||
already know the length of the string in advance.
|
||||
|
||||
@node String Length, Copying and Concatenation, String/Array Conventions, String and Array Utilities
|
||||
@node String Length
|
||||
@section String Length
|
||||
|
||||
You can get the length of a string using the @code{strlen} function.
|
||||
@@ -166,7 +167,7 @@ strlen (string)
|
||||
@end smallexample
|
||||
@end deftypefun
|
||||
|
||||
@node Copying and Concatenation, String/Array Comparison, String Length, String and Array Utilities
|
||||
@node Copying and Concatenation
|
||||
@section Copying and Concatenation
|
||||
|
||||
You can use the functions described in this section to copy the contents
|
||||
@@ -470,7 +471,7 @@ BSD. Note that it is not as general as @code{memset}, because the only
|
||||
value it can store is zero.
|
||||
@end deftypefun
|
||||
|
||||
@node String/Array Comparison, Collation Functions, Copying and Concatenation, String and Array Utilities
|
||||
@node String/Array Comparison
|
||||
@section String/Array Comparison
|
||||
@cindex comparing strings and arrays
|
||||
@cindex string comparison functions
|
||||
@@ -613,7 +614,7 @@ strncmp ("hello, world", "hello, stupid world!!!", 5)
|
||||
This is an obsolete alias for @code{memcmp}, derived from BSD.
|
||||
@end deftypefun
|
||||
|
||||
@node Collation Functions, Search Functions, String/Array Comparison, String and Array Utilities
|
||||
@node Collation Functions
|
||||
@section Collation Functions
|
||||
|
||||
@cindex collating strings
|
||||
@@ -792,9 +793,9 @@ sort_strings_fast (char **array, int nstrings)
|
||||
@end smallexample
|
||||
|
||||
@strong{Compatibility Note:} The string collation functions are a new
|
||||
feature of @w{ISO C}. Older C dialects have no equivalent feature.
|
||||
feature of @w{ISO C 89}. Older C dialects have no equivalent feature.
|
||||
|
||||
@node Search Functions, Finding Tokens in a String, Collation Functions, String and Array Utilities
|
||||
@node Search Functions
|
||||
@section Search Functions
|
||||
|
||||
This section describes library functions which perform various kinds
|
||||
@@ -881,7 +882,7 @@ strstr ("hello, world", "wo")
|
||||
|
||||
@comment string.h
|
||||
@comment GNU
|
||||
@deftypefun {void *} memmem (const void *@var{needle}, size_t @var{needle-len},@*const void *@var{haystack}, size_t @var{haystack-len})
|
||||
@deftypefun {void *} memmem (const void *@var{haystack}, size_t @var{haystack-len},@*const void *@var{needle}, size_t @var{needle-len})
|
||||
This is like @code{strstr}, but @var{needle} and @var{haystack} are byte
|
||||
arrays rather than null-terminated strings. @var{needle-len} is the
|
||||
length of @var{needle} and @var{haystack-len} is the length of
|
||||
@@ -940,7 +941,7 @@ strpbrk ("hello, world", " \t\n,.;!?")
|
||||
@c @end group
|
||||
@end deftypefun
|
||||
|
||||
@node Finding Tokens in a String, , Search Functions, String and Array Utilities
|
||||
@node Finding Tokens in a String
|
||||
@section Finding Tokens in a String
|
||||
|
||||
@cindex tokenizing strings
|
||||
@@ -1087,3 +1088,65 @@ token = strsep (&running, delimiters); /* token => "and" */
|
||||
token = strsep (&running, delimiters); /* token => "punctuation" */
|
||||
token = strsep (&running, delimiters); /* token => NULL */
|
||||
@end smallexample
|
||||
|
||||
@node Encode Binary Data
|
||||
@section Encode Binary Data
|
||||
|
||||
To store or transfer binary data in environments which only support text
|
||||
one has to encode the binary data by mapping the input bytes to
|
||||
characters in the range allowed for storing or transfering. SVID
|
||||
systems (and nowadays XPG compliant systems) have such a function in the
|
||||
C library.
|
||||
|
||||
@comment stdlib.h
|
||||
@comment XPG
|
||||
@deftypefun {char *} l64a (long int @var{n})
|
||||
This function encodes an input value with 32 bits using characters from
|
||||
the basic character set. Groups of 6 bits are encoded using the
|
||||
following table:
|
||||
|
||||
@multitable {xxxxx} {xxx} {xxx} {xxx} {xxx} {xxx} {xxx} {xxx} {xxx}
|
||||
@item @tab 0 @tab 1 @tab 2 @tab 3 @tab 4 @tab 5 @tab 6 @tab 7
|
||||
@item 0 @tab @code{.} @tab @code{/} @tab @code{0} @tab @code{1}
|
||||
@tab @code{2} @tab @code{3} @tab @code{4} @tab @code{5}
|
||||
@item 8 @tab @code{6} @tab @code{7} @tab @code{8} @tab @code{9}
|
||||
@tab @code{A} @tab @code{B} @tab @code{C} @tab @code{D}
|
||||
@item 16 @tab @code{E} @tab @code{F} @tab @code{G} @tab @code{H}
|
||||
@tab @code{I} @tab @code{J} @tab @code{K} @tab @code{L}
|
||||
@item 24 @tab @code{M} @tab @code{N} @tab @code{O} @tab @code{P}
|
||||
@tab @code{Q} @tab @code{R} @tab @code{S} @tab @code{T}
|
||||
@item 32 @tab @code{U} @tab @code{V} @tab @code{W} @tab @code{X}
|
||||
@tab @code{Y} @tab @code{Z} @tab @code{a} @tab @code{b}
|
||||
@item 40 @tab @code{c} @tab @code{d} @tab @code{e} @tab @code{f}
|
||||
@tab @code{g} @tab @code{h} @tab @code{i} @tab @code{j}
|
||||
@item 48 @tab @code{k} @tab @code{l} @tab @code{m} @tab @code{n}
|
||||
@tab @code{o} @tab @code{p} @tab @code{q} @tab @code{r}
|
||||
@item 56 @tab @code{s} @tab @code{t} @tab @code{u} @tab @code{v}
|
||||
@tab @code{w} @tab @code{x} @tab @code{y} @tab @code{z}
|
||||
@end multitable
|
||||
|
||||
The function returns a pointer to a static buffer which contains the
|
||||
string representing of the encoding of @var{n}. To encoded a series of
|
||||
bytes the use should append the new string to the destination buffer.
|
||||
@emph{Warning:} Since a static buffer is used this function should not
|
||||
be used in multi-threaded programs. There is no thread-safe alternatice
|
||||
to this function in the C library.
|
||||
@end deftypefun
|
||||
|
||||
To decode data produced with @code{l64a} the following function should be
|
||||
used.
|
||||
|
||||
@deftypefun {long int} a64l (const char *@var{string})
|
||||
The parameter @var{string} should contain a string which was produced by
|
||||
a call to @code{l64a}. The function processes the next 6 characters and
|
||||
decodes the characters it finds according to the table above.
|
||||
Characters not in the conversion table are simply ignored. This is
|
||||
useful for breaking the information in lines in which case the end of
|
||||
line characters are simply ignored.
|
||||
|
||||
The decoded number is returned at the end as a @code{long int} value.
|
||||
Consecutive calls to this function are possible but the caller must make
|
||||
sure the buffer pointer is update after each call to @code{a64l} since
|
||||
this function does not modify the buffer pointer. Every call consumes 6
|
||||
characters.
|
||||
@end deftypefun
|
||||
|
||||
@@ -25,29 +25,53 @@
|
||||
|
||||
BEGIN { header = 0;
|
||||
nameword["@defun"]=1
|
||||
nameword["@defunx"]=1
|
||||
nameword["@defmac"]=1
|
||||
nameword["@defmacx"]=1
|
||||
nameword["@defspec"]=1
|
||||
nameword["@defspecx"]=1
|
||||
nameword["@defvar"]=1
|
||||
nameword["@defvarx"]=1
|
||||
nameword["@defopt"]=1
|
||||
nameword["@defoptx"]=1
|
||||
nameword["@deffn"]=2
|
||||
nameword["@deffnx"]=2
|
||||
nameword["@defvr"]=2
|
||||
nameword["@defvrx"]=2
|
||||
nameword["@deftp"]=2
|
||||
nameword["@deftpx"]=2
|
||||
nameword["@deftypefun"]=2
|
||||
nameword["@deftypefunx"]=2
|
||||
nameword["@deftypevar"]=2
|
||||
nameword["@deftypevarx"]=2
|
||||
nameword["@deftypefn"]=3
|
||||
nameword["@deftypefnx"]=3
|
||||
nameword["@deftypevr"]=3
|
||||
nameword["@deftypevrx"]=3
|
||||
firstword["@defun"]=1
|
||||
firstword["@defunx"]=1
|
||||
firstword["@defmac"]=1
|
||||
firstword["@defmacx"]=1
|
||||
firstword["@defspec"]=1
|
||||
firstword["@defspecx"]=1
|
||||
firstword["@defvar"]=1
|
||||
firstword["@defvarx"]=1
|
||||
firstword["@defopt"]=1
|
||||
firstword["@defoptx"]=1
|
||||
firstword["@deffn"]=2
|
||||
firstword["@deffnx"]=2
|
||||
firstword["@defvr"]=2
|
||||
firstword["@defvrx"]=2
|
||||
firstword["@deftp"]=2
|
||||
firstword["@deftpx"]=2
|
||||
firstword["@deftypefun"]=1
|
||||
firstword["@deftypefunx"]=1
|
||||
firstword["@deftypevar"]=1
|
||||
firstword["@deftypevarx"]=1
|
||||
firstword["@deftypefn"]=2
|
||||
firstword["@deftypefnx"]=2
|
||||
firstword["@deftypevr"]=2
|
||||
firstword["@deftypevrx"]=2
|
||||
nameword["@item"]=1
|
||||
firstword["@item"]=1
|
||||
nameword["@itemx"]=1
|
||||
|
||||
+71
-63
@@ -1,5 +1,5 @@
|
||||
%% TeX macros to handle Texinfo files.
|
||||
%% $Id: texinfo.tex,v 2.196 1997/01/04 19:24:13 karl Exp $
|
||||
%% $Id: texinfo.tex,v 2.197 1997/04/30 15:34:30 drepper Exp $
|
||||
|
||||
% Copyright (C) 1985, 86, 88, 90, 91, 92, 93,
|
||||
% 94, 95, 96, 97 Free Software Foundation, Inc.
|
||||
@@ -36,7 +36,7 @@
|
||||
|
||||
% This automatically updates the version number based on RCS.
|
||||
\def\deftexinfoversion$#1: #2 ${\def\texinfoversion{#2}}
|
||||
\deftexinfoversion$Revision: 2.196 $
|
||||
\deftexinfoversion$Revision: 2.197 $
|
||||
\message{Loading texinfo package [Version \texinfoversion]:}
|
||||
|
||||
% If in a .fmt file, print the version number
|
||||
@@ -118,33 +118,41 @@
|
||||
\showboxbreadth\maxdimen\showboxdepth\maxdimen
|
||||
}%
|
||||
|
||||
%---------------------Begin change-----------------------
|
||||
% For @cropmarks command.
|
||||
% Do @cropmarks to get crop marks.
|
||||
%
|
||||
\newif\ifcropmarks
|
||||
\let\cropmarks = \cropmarkstrue
|
||||
%
|
||||
%%%% For @cropmarks command.
|
||||
% Dimensions to add cropmarks at corners Added by P. A. MacKay, 12 Nov. 1986
|
||||
% Dimensions to add cropmarks at corners.
|
||||
% Added by P. A. MacKay, 12 Nov. 1986
|
||||
%
|
||||
\newdimen\cornerlong \newdimen\cornerthick
|
||||
\newdimen \topandbottommargin
|
||||
\newdimen \outerhsize \newdimen \outervsize
|
||||
\newdimen\topandbottommargin
|
||||
\newdimen\outerhsize \newdimen\outervsize
|
||||
\cornerlong=1pc\cornerthick=.3pt % These set size of cropmarks
|
||||
\outerhsize=7in
|
||||
%\outervsize=9.5in
|
||||
% Alternative @smallbook page size is 9.25in
|
||||
\outervsize=9.25in
|
||||
\topandbottommargin=.75in
|
||||
%
|
||||
%---------------------End change-----------------------
|
||||
|
||||
% Main output routine.
|
||||
\chardef\PAGE = 255
|
||||
\output = {\onepageout{\pagecontents\PAGE}}
|
||||
|
||||
\newbox\headlinebox \newbox\footlinebox
|
||||
\newbox\headlinebox
|
||||
\newbox\footlinebox
|
||||
|
||||
% \onepageout takes a vbox as an argument. Note that \pagecontents
|
||||
% does insertions, but you have to call it yourself.
|
||||
\def\onepageout#1{%
|
||||
\hoffset=\normaloffset
|
||||
\ifcropmarks
|
||||
\hoffset = 0pt
|
||||
\else
|
||||
\hoffset = \normaloffset
|
||||
\fi
|
||||
%
|
||||
\ifodd\pageno \advance\hoffset by \bindingoffset
|
||||
\else \advance\hoffset by -\bindingoffset\fi
|
||||
%
|
||||
@@ -163,53 +171,41 @@
|
||||
\normalturnoffactive % \ in index entries must not stay \, e.g., if
|
||||
% the page break happens to be in the middle of an example.
|
||||
\shipout\vbox{%
|
||||
\ifcropmarks
|
||||
\vbox to \outervsize\bgroup
|
||||
\hsize = \outerhsize
|
||||
\vbox{\line{\ewtop\hfill\ewtop}}%
|
||||
\nointerlineskip
|
||||
\line{%
|
||||
\vbox{\moveleft\cornerthick\nstop}%
|
||||
\hfill
|
||||
\vbox{\moveright\cornerthick\nstop}%
|
||||
}%
|
||||
\vskip\topandbottommargin
|
||||
\fi
|
||||
%
|
||||
\unvbox\headlinebox
|
||||
\pagebody{#1}%
|
||||
\unvbox\footlinebox
|
||||
%
|
||||
\ifcropmarks
|
||||
\vskip\topandbottommargin plus1fill minus1fill
|
||||
\boxmaxdepth = \cornerthick
|
||||
\line{%
|
||||
\vbox{\moveleft\cornerthick\nsbot}%
|
||||
\hfill
|
||||
\vbox{\moveright\cornerthick\nsbot}%
|
||||
}%
|
||||
\nointerlineskip
|
||||
\vbox{\line{\ewbot\hfill\ewbot}}%
|
||||
\egroup % \vbox from first cropmarks clause
|
||||
\fi
|
||||
}%
|
||||
}%
|
||||
\advancepageno
|
||||
\ifnum\outputpenalty>-20000 \else\dosupereject\fi
|
||||
}
|
||||
|
||||
%%%% For @cropmarks command %%%%
|
||||
|
||||
% Here is a modification of the main output routine for Near East Publications
|
||||
% This provides right-angle cropmarks at all four corners.
|
||||
% The contents of the page are centerlined into the cropmarks,
|
||||
% and any desired binding offset is added as an \hskip on either
|
||||
% site of the centerlined box. (P. A. MacKay, 12 November, 1986)
|
||||
%
|
||||
\def\croppageout#1{\hoffset=0pt % make sure this doesn't mess things up
|
||||
{\escapechar=`\\\relax % makes sure backslash is used in output files.
|
||||
\shipout
|
||||
\vbox to \outervsize{\hsize=\outerhsize
|
||||
\vbox{\line{\ewtop\hfill\ewtop}}
|
||||
\nointerlineskip
|
||||
\line{\vbox{\moveleft\cornerthick\nstop}
|
||||
\hfill
|
||||
\vbox{\moveright\cornerthick\nstop}}
|
||||
\vskip \topandbottommargin
|
||||
\centerline{\ifodd\pageno\hskip\bindingoffset\fi
|
||||
\vbox{
|
||||
{\let\hsize=\pagewidth \makeheadline}
|
||||
\pagebody{#1}
|
||||
{\let\hsize=\pagewidth \makefootline}}
|
||||
\ifodd\pageno\else\hskip\bindingoffset\fi}
|
||||
\vskip \topandbottommargin plus1fill minus1fill
|
||||
\boxmaxdepth\cornerthick
|
||||
\line{\vbox{\moveleft\cornerthick\nsbot}
|
||||
\hfill
|
||||
\vbox{\moveright\cornerthick\nsbot}}
|
||||
\nointerlineskip
|
||||
\vbox{\line{\ewbot\hfill\ewbot}}
|
||||
}}
|
||||
\advancepageno
|
||||
\ifnum\outputpenalty>-20000 \else\dosupereject\fi}
|
||||
%
|
||||
% Do @cropmarks to get crop marks
|
||||
\def\cropmarks{\let\onepageout=\croppageout }
|
||||
|
||||
\newinsert\margin \dimen\margin=\maxdimen
|
||||
|
||||
\def\pagebody#1{\vbox to\pageheight{\boxmaxdepth=\maxdepth #1}}
|
||||
@@ -2240,6 +2236,7 @@ width0pt\relax} \fi
|
||||
\def\r##1{\realbackslash r {##1}}%
|
||||
\def\i##1{\realbackslash i {##1}}%
|
||||
\def\b##1{\realbackslash b {##1}}%
|
||||
\def\sc##1{\realbackslash sc {##1}}%
|
||||
\def\cite##1{\realbackslash cite {##1}}%
|
||||
\def\key##1{\realbackslash key {##1}}%
|
||||
\def\file##1{\realbackslash file {##1}}%
|
||||
@@ -2774,7 +2771,8 @@ width0pt\relax} \fi
|
||||
% because we don't want its macros evaluated now.
|
||||
\xdef\thischapter{\putwordChapter{} \the\chapno: \noexpand\thischaptername}%
|
||||
{\chapternofonts%
|
||||
\edef\temp{{\realbackslash chapentry {#1}{\the\chapno}{\noexpand\folio}}}%
|
||||
\toks0 = {#1}%
|
||||
\edef\temp{{\realbackslash chapentry{\the\toks0}{\the\chapno}{\noexpand\folio}}}%
|
||||
\escapechar=`\\%
|
||||
\write \contentsfile \temp %
|
||||
\donoderef %
|
||||
@@ -2793,8 +2791,9 @@ width0pt\relax} \fi
|
||||
\gdef\thischaptername{#1}%
|
||||
\xdef\thischapter{\putwordAppendix{} \appendixletter: \noexpand\thischaptername}%
|
||||
{\chapternofonts%
|
||||
\edef\temp{{\realbackslash chapentry
|
||||
{#1}{\putwordAppendix{} \appendixletter}{\noexpand\folio}}}%
|
||||
\toks0 = {#1}%
|
||||
\edef\temp{{\realbackslash chapentry{\the\toks0}%
|
||||
{\putwordAppendix{} \appendixletter}{\noexpand\folio}}}%
|
||||
\escapechar=`\\%
|
||||
\write \contentsfile \temp %
|
||||
\appendixnoderef %
|
||||
@@ -2828,7 +2827,8 @@ width0pt\relax} \fi
|
||||
\unnumbchapmacro {#1}%
|
||||
\gdef\thischapter{#1}\gdef\thissection{#1}%
|
||||
{\chapternofonts%
|
||||
\edef\temp{{\realbackslash unnumbchapentry {#1}{\noexpand\folio}}}%
|
||||
\toks0 = {#1}%
|
||||
\edef\temp{{\realbackslash unnumbchapentry{\the\toks0}{\noexpand\folio}}}%
|
||||
\escapechar=`\\%
|
||||
\write \contentsfile \temp %
|
||||
\unnumbnoderef %
|
||||
@@ -2843,8 +2843,9 @@ width0pt\relax} \fi
|
||||
\subsecno=0 \subsubsecno=0 \global\advance \secno by 1 %
|
||||
\gdef\thissection{#1}\secheading {#1}{\the\chapno}{\the\secno}%
|
||||
{\chapternofonts%
|
||||
\toks0 = {#1}%
|
||||
\edef\temp{{\realbackslash secentry %
|
||||
{#1}{\the\chapno}{\the\secno}{\noexpand\folio}}}%
|
||||
{\the\toks0}{\the\chapno}{\the\secno}{\noexpand\folio}}}%
|
||||
\escapechar=`\\%
|
||||
\write \contentsfile \temp %
|
||||
\donoderef %
|
||||
@@ -2858,8 +2859,9 @@ width0pt\relax} \fi
|
||||
\subsecno=0 \subsubsecno=0 \global\advance \secno by 1 %
|
||||
\gdef\thissection{#1}\secheading {#1}{\appendixletter}{\the\secno}%
|
||||
{\chapternofonts%
|
||||
\toks0 = {#1}%
|
||||
\edef\temp{{\realbackslash secentry %
|
||||
{#1}{\appendixletter}{\the\secno}{\noexpand\folio}}}%
|
||||
{\the\toks0}{\appendixletter}{\the\secno}{\noexpand\folio}}}%
|
||||
\escapechar=`\\%
|
||||
\write \contentsfile \temp %
|
||||
\appendixnoderef %
|
||||
@@ -2871,7 +2873,8 @@ width0pt\relax} \fi
|
||||
\def\unnumberedseczzz #1{\seccheck{unnumberedsec}%
|
||||
\plainsecheading {#1}\gdef\thissection{#1}%
|
||||
{\chapternofonts%
|
||||
\edef\temp{{\realbackslash unnumbsecentry{#1}{\noexpand\folio}}}%
|
||||
\toks0 = {#1}%
|
||||
\edef\temp{{\realbackslash unnumbsecentry{\the\toks0}{\noexpand\folio}}}%
|
||||
\escapechar=`\\%
|
||||
\write \contentsfile \temp %
|
||||
\unnumbnoderef %
|
||||
@@ -2884,8 +2887,9 @@ width0pt\relax} \fi
|
||||
\gdef\thissection{#1}\subsubsecno=0 \global\advance \subsecno by 1 %
|
||||
\subsecheading {#1}{\the\chapno}{\the\secno}{\the\subsecno}%
|
||||
{\chapternofonts%
|
||||
\toks0 = {#1}%
|
||||
\edef\temp{{\realbackslash subsecentry %
|
||||
{#1}{\the\chapno}{\the\secno}{\the\subsecno}{\noexpand\folio}}}%
|
||||
{\the\toks0}{\the\chapno}{\the\secno}{\the\subsecno}{\noexpand\folio}}}%
|
||||
\escapechar=`\\%
|
||||
\write \contentsfile \temp %
|
||||
\donoderef %
|
||||
@@ -2898,8 +2902,9 @@ width0pt\relax} \fi
|
||||
\gdef\thissection{#1}\subsubsecno=0 \global\advance \subsecno by 1 %
|
||||
\subsecheading {#1}{\appendixletter}{\the\secno}{\the\subsecno}%
|
||||
{\chapternofonts%
|
||||
\toks0 = {#1}%
|
||||
\edef\temp{{\realbackslash subsecentry %
|
||||
{#1}{\appendixletter}{\the\secno}{\the\subsecno}{\noexpand\folio}}}%
|
||||
{\the\toks0}{\appendixletter}{\the\secno}{\the\subsecno}{\noexpand\folio}}}%
|
||||
\escapechar=`\\%
|
||||
\write \contentsfile \temp %
|
||||
\appendixnoderef %
|
||||
@@ -2911,7 +2916,8 @@ width0pt\relax} \fi
|
||||
\def\unnumberedsubseczzz #1{\seccheck{unnumberedsubsec}%
|
||||
\plainsubsecheading {#1}\gdef\thissection{#1}%
|
||||
{\chapternofonts%
|
||||
\edef\temp{{\realbackslash unnumbsubsecentry{#1}{\noexpand\folio}}}%
|
||||
\toks0 = {#1}%
|
||||
\edef\temp{{\realbackslash unnumbsubsecentry{\the\toks0}{\noexpand\folio}}}%
|
||||
\escapechar=`\\%
|
||||
\write \contentsfile \temp %
|
||||
\unnumbnoderef %
|
||||
@@ -2925,8 +2931,8 @@ width0pt\relax} \fi
|
||||
\subsubsecheading {#1}
|
||||
{\the\chapno}{\the\secno}{\the\subsecno}{\the\subsubsecno}%
|
||||
{\chapternofonts%
|
||||
\edef\temp{{\realbackslash subsubsecentry %
|
||||
{#1}
|
||||
\toks0 = {#1}%
|
||||
\edef\temp{{\realbackslash subsubsecentry{\the\toks0}
|
||||
{\the\chapno}{\the\secno}{\the\subsecno}{\the\subsubsecno}
|
||||
{\noexpand\folio}}}%
|
||||
\escapechar=`\\%
|
||||
@@ -2942,7 +2948,8 @@ width0pt\relax} \fi
|
||||
\subsubsecheading {#1}
|
||||
{\appendixletter}{\the\secno}{\the\subsecno}{\the\subsubsecno}%
|
||||
{\chapternofonts%
|
||||
\edef\temp{{\realbackslash subsubsecentry{#1}%
|
||||
\toks0 = {#1}%
|
||||
\edef\temp{{\realbackslash subsubsecentry{\the\toks0}%
|
||||
{\appendixletter}
|
||||
{\the\secno}{\the\subsecno}{\the\subsubsecno}{\noexpand\folio}}}%
|
||||
\escapechar=`\\%
|
||||
@@ -2956,7 +2963,8 @@ width0pt\relax} \fi
|
||||
\def\unnumberedsubsubseczzz #1{\seccheck{unnumberedsubsubsec}%
|
||||
\plainsubsubsecheading {#1}\gdef\thissection{#1}%
|
||||
{\chapternofonts%
|
||||
\edef\temp{{\realbackslash unnumbsubsubsecentry{#1}{\noexpand\folio}}}%
|
||||
\toks0 = {#1}%
|
||||
\edef\temp{{\realbackslash unnumbsubsubsecentry{\the\toks0}{\noexpand\folio}}}%
|
||||
\escapechar=`\\%
|
||||
\write \contentsfile \temp %
|
||||
\unnumbnoderef %
|
||||
|
||||
@@ -9,18 +9,18 @@ BEGIN {
|
||||
|
||||
/^@deftypefun/ {
|
||||
printf ("* %s: (libc)%s.\n",
|
||||
gensub (/@deftypefun +([^{ ]+|\{[^}]+\}) +([[:alpha:]_][[:alnum:]_]+).*/, "\\2", 1),
|
||||
gensub (/@deftypefunx? +([^{ ]+|\{[^}]+\}) +([[:alpha:]_][[:alnum:]_]*).*/, "\\2", 1),
|
||||
last_node);
|
||||
}
|
||||
|
||||
/^@deftypevr/ {
|
||||
printf ("* %s: (libc)%s.\n",
|
||||
gensub (/@deftypevr +([^{ ]+|\{[^}]+\}) +([^{ ]+|\{[^}]+\}) +([[:alpha:]_][[:alnum:]_]+).*/, "\\3", 1),
|
||||
gensub (/@deftypevrx? +([^{ ]+|\{[^}]+\}) +([^{ ]+|\{[^}]+\}) +([[:alpha:]_][[:alnum:]_]*).*/, "\\3", 1),
|
||||
last_node);
|
||||
}
|
||||
|
||||
/^@deftypefn/ {
|
||||
printf ("* %s: (libc)%s.\n",
|
||||
gensub (/@deftypefn +([^{ ]+|\{[^}]+\}) +[^{ ]*(\{[^}]+\})? +([[:alpha:]_][[:alnum:]_]+).*/, "\\3", 1),
|
||||
gensub (/@deftypefnx? +([^{ ]+|\{[^}]+\}) +[^{ ]*(\{[^}]+\})? +([[:alpha:]_][[:alnum:]_]*).*/, "\\3", 1),
|
||||
last_node);
|
||||
}
|
||||
|
||||
+14
-4
@@ -22,7 +22,8 @@ subdir := math
|
||||
|
||||
# Installed header files.
|
||||
headers := math.h mathcalls.h __math.h huge_val.h nan.h \
|
||||
fpu_control.h complex.h cmathcalls.h
|
||||
fpu_control.h complex.h cmathcalls.h fenv.h \
|
||||
fenvbits.h mathbits.h
|
||||
|
||||
# Internal header files.
|
||||
distribute := math_private.h machine/asm.h machine/endian.h
|
||||
@@ -35,7 +36,11 @@ aux := fpu_control setfpucw
|
||||
extra-libs := libm
|
||||
extra-libs-others = $(extra-libs)
|
||||
|
||||
libm-support = k_standard s_lib_version s_matherr s_signgam
|
||||
libm-support = k_standard s_lib_version s_matherr s_signgam \
|
||||
s_rinttol s_rinttoll s_roundtol s_roundtoll \
|
||||
fclrexcpt fgetexcptflg fraiseexcpt fsetexcptflg \
|
||||
ftestexcept fegetround fesetround fegetenv feholdexcpt \
|
||||
fesetenv feupdateenv
|
||||
libm-calls = e_acos e_acosh e_asin e_atan2 e_atanh e_cosh e_exp e_fmod \
|
||||
e_hypot e_j0 e_j1 e_jn e_lgamma_r e_log e_log10 e_pow \
|
||||
e_rem_pio2 e_remainder e_scalb e_sinh e_sqrt k_cos \
|
||||
@@ -48,8 +53,10 @@ libm-calls = e_acos e_acosh e_asin e_atan2 e_atanh e_cosh e_exp e_fmod \
|
||||
w_gamma_r w_hypot w_j0 w_j1 w_jn w_lgamma w_lgamma_r \
|
||||
w_log w_log10 w_pow w_remainder w_scalb w_sinh w_sqrt \
|
||||
s_signbit s_fpclassify s_fmax s_fmin s_fdim s_nan s_trunc \
|
||||
s_remquo s_log2 s_exp2 \
|
||||
conj cimag creal cabs carg s_cexp s_csinh s_ccosh
|
||||
s_remquo s_log2 s_exp2 s_round s_nearbyint s_sincos \
|
||||
conj cimag creal cabs carg s_cexp s_csinh s_ccosh s_clog \
|
||||
s_catan s_casin s_ccos s_csin s_ctan s_ctanh s_cacos \
|
||||
s_casinh s_cacosh s_catanh s_csqrt s_cpow s_cproj
|
||||
libm-routines = $(libm-support) $(libm-calls) \
|
||||
$(patsubst %_rf,%f_r,$(libm-calls:=f)) \
|
||||
$(long-m-$(long-double-fcts))
|
||||
@@ -73,6 +80,9 @@ tests = test-float test-double $(test-longdouble-$(long-double-fcts))
|
||||
# XXX This test is disabled for now since the functions are too buggy.
|
||||
#test-longdouble-yes = test-longdouble
|
||||
|
||||
CFLAGS-test-float.c = -fno-inline
|
||||
CFLAGS-test-double.c = -fno-inline
|
||||
CFLAGS-test-longdouble.c = -fno-inline
|
||||
LDLIBS-test-float = libm
|
||||
LDLIBS-test-double = libm
|
||||
LDLIBS-test-longdouble = libm
|
||||
|
||||
+1
-1
@@ -100,7 +100,7 @@ __MATHCALL (cpow, (_Mdouble_complex_ __x, _Mdouble_complex_ __y));
|
||||
__MATHCALL (csqrt, (_Mdouble_complex_ __z));
|
||||
|
||||
|
||||
/* Absolute value, projections, conjugates, and projection. */
|
||||
/* Absolute value, conjugates, and projection. */
|
||||
|
||||
/* Absolute value of Z. */
|
||||
__MATHDECL (_Mdouble_,cabs, (_Mdouble_complex_ __z));
|
||||
|
||||
+1
-1
@@ -38,7 +38,7 @@ __BEGIN_DECLS
|
||||
/* Narrowest imaginary unit. This depends on the floating-point
|
||||
evaluation method.
|
||||
XXX This probably has to go into a gcc related file. */
|
||||
#define _Imaginary_I (DBL_EPSISON * 1.0i)
|
||||
#define _Imaginary_I (1.0iF)
|
||||
|
||||
/* Another more descriptive name is `I'. */
|
||||
#undef I
|
||||
|
||||
+114
@@ -0,0 +1,114 @@
|
||||
/* 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. */
|
||||
|
||||
/*
|
||||
* ISO C 9X 7.6: Floating-point environment <fenv.h>
|
||||
*/
|
||||
|
||||
#ifndef _FENV_H
|
||||
|
||||
#define _FENV_H 1
|
||||
#include <features.h>
|
||||
|
||||
/* Get the architecture dependend definitions. The following definitions
|
||||
are expected to be done:
|
||||
|
||||
fenv_t type for object representing an entire floating-point
|
||||
environment
|
||||
|
||||
FE_DFL_ENV macro of type pointer to fenv_t to be used as the argument
|
||||
to functions taking an argument of type fenv_t; in this
|
||||
case the default environment will be used
|
||||
|
||||
fexcept_t type for object representing the floating-point exception
|
||||
flags including status associated with the flags
|
||||
|
||||
The following macros are defined iff the implementation supports this
|
||||
kind of exception.
|
||||
FE_INEXACT inexact result
|
||||
FE_DIVBYZERO devision by zero
|
||||
FE_UNDERFLOW result not representable due to underflow
|
||||
FE_OVERFLOW result not representable due to overflow
|
||||
FE_INVALID invalid operation
|
||||
|
||||
FE_ALL_EXCEPT bitwise OR of all supported exceptions
|
||||
|
||||
The next macros are defined iff the appropriate rounding mode is
|
||||
supported by the implementation.
|
||||
FE_TONEAREST round to nearest
|
||||
FE_UPWARD round toward +Inf
|
||||
FE_DOWNWARD round toward -Inf
|
||||
FE_TOWARDZERO round toward 0
|
||||
*/
|
||||
#include <fenvbits.h>
|
||||
|
||||
__BEGIN_DECLS
|
||||
|
||||
/* Floating-point exception handling. */
|
||||
|
||||
/* Clear the supported exceptions represented by EXCEPTS. */
|
||||
extern void feclearexcept __P ((int __excepts));
|
||||
|
||||
/* Store implementation-defined representation of the exception flags
|
||||
indicated by EXCEPTS in the object pointed to by FLAGP. */
|
||||
extern void fegetexceptflag __P ((fexcept_t *__flagp, int __excepts));
|
||||
|
||||
/* Raise the supported exceptions represented by EXCEPTS. */
|
||||
extern void feraiseexcept __P ((int __excepts));
|
||||
|
||||
/* Set complete status for exceptions inidicated by EXCEPTS according to
|
||||
the representation in the object pointed to by FLAGP. */
|
||||
extern void fesetexceptflag __P ((__const fexcept_t *__flagp, int __excepts));
|
||||
|
||||
/* Determine which of subset of the exceptions specified by EXCEPTS are
|
||||
currently set. */
|
||||
extern int fetestexcept __P ((int __excepts));
|
||||
|
||||
|
||||
/* Rounding control. */
|
||||
|
||||
/* Get current rounding direction. */
|
||||
extern int fegetround __P ((void));
|
||||
|
||||
/* Establish the rounding direction represented by ROUND. */
|
||||
extern int fesetround __P ((int __rounding_direction));
|
||||
|
||||
|
||||
/* Floating-point environment. */
|
||||
|
||||
/* Store the current floating-point environment in the object pointed
|
||||
to by ENVP. */
|
||||
extern void fegetenv __P ((fenv_t *__envp));
|
||||
|
||||
/* Save the current environment in the object pointed to by ENVP, clear
|
||||
exception flags and install a non-stop mode (if available) for all
|
||||
exceptions. */
|
||||
extern int feholdexcept __P ((fenv_t *__envp));
|
||||
|
||||
/* Establish the floating-point environment represented by the object
|
||||
pointed to by ENVP. */
|
||||
extern void fesetenv __P ((__const fenv_t *__envp));
|
||||
|
||||
/* Save current exceptions in temporary storage, install environment
|
||||
represented by object pointed to by ENVP and raise exceptions
|
||||
according to saved exceptions. */
|
||||
extern void feupdateenv __P ((__const fenv_t *__envp));
|
||||
|
||||
__END_DECLS
|
||||
|
||||
#endif /* fenv.h */
|
||||
+1469
-307
File diff suppressed because it is too large
Load Diff
+29
-6
@@ -115,6 +115,25 @@ extern int signgam;
|
||||
/* ISO C 9X defines some generic macros which work on any data type. */
|
||||
#if __USE_ISOC9X
|
||||
|
||||
/* Get the architecture specific values describing the floating-point
|
||||
evaluation. The following symbols will get defined:
|
||||
|
||||
float_t floating-point type at least as wide as `float' used
|
||||
to evaluate `float' expressions
|
||||
double_t floating-point type at least as wide as `double' used
|
||||
to evaluate `double' expressions
|
||||
|
||||
FLT_EVAL_METHOD
|
||||
Defined to
|
||||
0 if `float_t' is `float' and `double_t' is `double'
|
||||
1 if `float_t' and `double_t' are `double'
|
||||
2 if `float_t' and `double_t' are `long double'
|
||||
else `float_t' and `double_t' are unspecified
|
||||
|
||||
INFINITY representation of the infinity value of type `float_t'
|
||||
*/
|
||||
#include <mathbits.h>
|
||||
|
||||
/* All floating-point numbers can be put in one of these categories. */
|
||||
enum
|
||||
{
|
||||
@@ -133,7 +152,7 @@ enum
|
||||
/* Return number of classification appropriate for X. */
|
||||
#define fpclassify(x) \
|
||||
(sizeof (x) == sizeof (float) ? \
|
||||
__fpclassifyf (x) \
|
||||
__fpclassifyf (x) \
|
||||
: sizeof (x) == sizeof (double) ? \
|
||||
__fpclassify (x) : __fpclassifyl (x))
|
||||
|
||||
@@ -145,7 +164,11 @@ enum
|
||||
__signbit (x) : __signbitl (x))
|
||||
|
||||
/* Return nonzero value if X is not +-Inf or NaN. */
|
||||
#define isfinite(x) (fpclassify (x) >= FP_ZERO)
|
||||
#define isfinite(x) \
|
||||
(sizeof (x) == sizeof (float) ? \
|
||||
__finitef (x) \
|
||||
: sizeof (x) == sizeof (double) ? \
|
||||
__finite (x) : __finitel (x))
|
||||
|
||||
/* Return nonzero value if X is neither zero, subnormal, Inf, nor NaN. */
|
||||
#define isnormal(x) (fpclassify (x) == FP_NORMAL)
|
||||
@@ -163,13 +186,13 @@ enum
|
||||
|
||||
/* Round X to nearest integral value according to current rounding
|
||||
direction. */
|
||||
extern long int rinttol __P ((double __x));
|
||||
extern long long int rinttoll __P ((double __x));
|
||||
extern long int rinttol __P ((long double __x));
|
||||
extern long long int rinttoll __P ((long double __x));
|
||||
|
||||
/* Round X to nearest integral value, rounding halfway cases away from
|
||||
zero. */
|
||||
extern long int roundtol __P ((double __x));
|
||||
extern long long int roundtoll __P ((double __x));
|
||||
extern long int roundtol __P ((long double __x));
|
||||
extern long long int roundtoll __P ((long double __x));
|
||||
|
||||
|
||||
/* Comparison macros. */
|
||||
|
||||
@@ -63,6 +63,11 @@ __MATHCALL (sin,, (_Mdouble_ __x));
|
||||
/* Tangent of X. */
|
||||
__MATHCALL (tan,, (_Mdouble_ __x));
|
||||
|
||||
#ifdef __USE_GNU
|
||||
/* Cosine and sine of X. */
|
||||
__MATHDECL (void, sincos,,
|
||||
(_Mdouble_ __x, _Mdouble_ *__sinx, _Mdouble_ *__cosx));
|
||||
#endif
|
||||
|
||||
/* Hyperbolic functions. */
|
||||
|
||||
|
||||
+8
-2
@@ -26,8 +26,14 @@ __BEGIN_DECLS
|
||||
/* Return directory part of PATH or "." if none is available. */
|
||||
extern char *dirname __P ((char *__path));
|
||||
|
||||
/* Return filename part of PATH. */
|
||||
extern char *basename __P ((__const char *__path));
|
||||
/* Return final component of PATH.
|
||||
|
||||
This is the weird XPG version of this function. It sometimes will
|
||||
modify its argument. Therefore we normally use the GNU version (in
|
||||
<string.h>) and only if this header is included make the XPG
|
||||
version available under the real name. */
|
||||
extern char *__xpg_basename __P ((char *__path));
|
||||
#define basename(path) __xpg_basename (path)
|
||||
|
||||
__END_DECLS
|
||||
|
||||
|
||||
+17
-14
@@ -17,10 +17,13 @@
|
||||
write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
Boston, MA 02111-1307, USA. */
|
||||
|
||||
#define _GNU_SOURCE 1
|
||||
#ifndef _GNU_SOURCE
|
||||
# define _GNU_SOURCE 1
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <search.h>
|
||||
|
||||
#define SEED 0
|
||||
@@ -112,7 +115,7 @@ walk_action (const void *nodep, const VISIT which, const int depth)
|
||||
if (depths[key] != depth)
|
||||
{
|
||||
fputs ("Depth for one element is not constant during tree walk.\n",
|
||||
stderr);
|
||||
stdout);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -129,7 +132,7 @@ walk_tree (void *root, int expected_count)
|
||||
for (i = 0; i < expected_count; ++i)
|
||||
if (z[i] != 1)
|
||||
{
|
||||
fputs ("Node was not visited.\n", stderr);
|
||||
fputs ("Node was not visited.\n", stdout);
|
||||
error = 1;
|
||||
}
|
||||
|
||||
@@ -139,7 +142,7 @@ walk_tree (void *root, int expected_count)
|
||||
if (max_depth > expected_count)
|
||||
#endif
|
||||
{
|
||||
fputs ("Depth too large during tree walk.\n", stderr);
|
||||
fputs ("Depth too large during tree walk.\n", stdout);
|
||||
error = 1;
|
||||
}
|
||||
}
|
||||
@@ -196,7 +199,7 @@ mangle_tree (enum order how, enum action what, void **root, int lag)
|
||||
{
|
||||
if (tfind (x + j, (const void **) root, cmp_fn) != NULL)
|
||||
{
|
||||
fputs ("Found element which is not in tree yet.\n", stderr);
|
||||
fputs ("Found element which is not in tree yet.\n", stdout);
|
||||
error = 1;
|
||||
}
|
||||
elem = tsearch (x + j, root, cmp_fn);
|
||||
@@ -204,7 +207,7 @@ mangle_tree (enum order how, enum action what, void **root, int lag)
|
||||
|| tfind (x + j, (const void **) root, cmp_fn) == NULL)
|
||||
{
|
||||
fputs ("Couldn't find element after it was added.\n",
|
||||
stderr);
|
||||
stdout);
|
||||
error = 1;
|
||||
}
|
||||
}
|
||||
@@ -219,7 +222,7 @@ mangle_tree (enum order how, enum action what, void **root, int lag)
|
||||
elem = tfind (x + j, (const void **) root, cmp_fn);
|
||||
if (elem == NULL || tdelete (x + j, root, cmp_fn) == NULL)
|
||||
{
|
||||
fputs ("Error deleting element.\n", stderr);
|
||||
fputs ("Error deleting element.\n", stdout);
|
||||
error = 1;
|
||||
}
|
||||
break;
|
||||
@@ -227,7 +230,7 @@ mangle_tree (enum order how, enum action what, void **root, int lag)
|
||||
case find:
|
||||
if (tfind (x + j, (const void **) root, cmp_fn) == NULL)
|
||||
{
|
||||
fputs ("Couldn't find element after it was added.\n", stderr);
|
||||
fputs ("Couldn't find element after it was added.\n", stdout);
|
||||
error = 1;
|
||||
}
|
||||
break;
|
||||
@@ -252,10 +255,10 @@ main (int argc, char **argv)
|
||||
|
||||
/* Do this loop several times to get different permutations for the
|
||||
random case. */
|
||||
fputs ("Series I\n", stderr);
|
||||
fputs ("Series I\n", stdout);
|
||||
for (i = 0; i < PASSES; ++i)
|
||||
{
|
||||
fprintf (stderr, "Pass %d... ", i + 1);
|
||||
fprintf (stdout, "Pass %d... ", i + 1);
|
||||
fflush (stdout);
|
||||
error = 0;
|
||||
|
||||
@@ -301,14 +304,14 @@ main (int argc, char **argv)
|
||||
mangle_tree (randomorder, build_and_del, &root, j);
|
||||
}
|
||||
|
||||
fputs (error ? " failed!\n" : " ok.\n", stderr);
|
||||
fputs (error ? " failed!\n" : " ok.\n", stdout);
|
||||
total_error |= error;
|
||||
}
|
||||
|
||||
fputs ("Series II\n", stderr);
|
||||
fputs ("Series II\n", stdout);
|
||||
for (i = 1; i < SIZE; i *= 2)
|
||||
{
|
||||
fprintf (stderr, "For size %d... ", i);
|
||||
fprintf (stdout, "For size %d... ", i);
|
||||
fflush (stdout);
|
||||
error = 0;
|
||||
|
||||
@@ -321,7 +324,7 @@ main (int argc, char **argv)
|
||||
mangle_tree (ascending, build_and_del, &root, i);
|
||||
mangle_tree (descending, build_and_del, &root, i);
|
||||
|
||||
fputs (error ? " failed!\n" : " ok.\n", stderr);
|
||||
fputs (error ? " failed!\n" : " ok.\n", stdout);
|
||||
total_error |= error;
|
||||
}
|
||||
|
||||
|
||||
+4
-49
@@ -27,10 +27,10 @@ distribute := nss-nis.h nss-nisplus.h
|
||||
# These are the databases available for the nis (and perhaps later nisplus)
|
||||
# service. This must be a superset of the services in nss.
|
||||
databases = proto service hosts network grp pwd rpc ethers \
|
||||
spwd netgrp alias
|
||||
spwd netgrp alias publickey
|
||||
|
||||
# Specify rules for the nss_* modules.
|
||||
services := nis compat nisplus
|
||||
services := nis nisplus compat
|
||||
|
||||
extra-libs = libnsl $(services:%=libnss_%)
|
||||
# These libraries will be built in the `others' pass rather than
|
||||
@@ -55,57 +55,12 @@ libnss_nis-inhibit-o = $(filter-out .so,$(object-suffixes))
|
||||
libnss_nisplus-routines := $(addprefix nisplus-,$(databases))
|
||||
libnss_nisplus-inhibit-o = $(filter-out .so,$(object-suffixes))
|
||||
|
||||
# Sun's header files are not too clean.
|
||||
CFLAGS-compat-pwd.c = -Wno-strict-prototypes
|
||||
CFLAGS-compat-spwd.c = -Wno-strict-prototypes
|
||||
CFLAGS-compat-grp.c = -Wno-strict-prototypes
|
||||
CFLAGS-nis-alias.c = -Wno-strict-prototypes
|
||||
CFLAGS-nis-ethers.c = -Wno-strict-prototypes
|
||||
CFLAGS-nis-grp.c = -Wno-strict-prototypes
|
||||
CFLAGS-nis-hosts.c = -Wno-strict-prototypes
|
||||
CFLAGS-nis-netgrp.c = -Wno-strict-prototypes
|
||||
CFLAGS-nis-network.c = -Wno-strict-prototypes
|
||||
CFLAGS-nis-proto.c = -Wno-strict-prototypes
|
||||
CFLAGS-nis-publickey.c = -Wno-strict-prototypes
|
||||
CFLAGS-nis-pwd.c = -Wno-strict-prototypes
|
||||
CFLAGS-nis-rpc.c = -Wno-strict-prototypes
|
||||
CFLAGS-nis-service.c = -Wno-strict-prototypes
|
||||
CFLAGS-nis-spwd.c = -Wno-strict-prototypes
|
||||
CFLAGS-ypclnt.c = -Wno-strict-prototypes -Wno-write-strings -Irpcsvc
|
||||
CFLAGS-yp_xdr.c = -Wno-strict-prototypes -Irpcsvc
|
||||
CFLAGS-ypupdate_xdr.c = -Wno-strict-prototypes -Irpcsvc
|
||||
# For the NIS+ Code
|
||||
CFLAGS-nis_call.c = -DNO_DES_RPC -Wno-strict-prototypes
|
||||
CFLAGS-nis_subr.c = -Wno-strict-prototypes
|
||||
CFLAGS-nis_local_names.c = -Wno-strict-prototypes
|
||||
CFLAGS-nis_free.c = -Wno-strict-prototypes
|
||||
CFLAGS-nis_file.c = -Wno-strict-prototypes
|
||||
CFLAGS-nis_print.c = -Wno-strict-prototypes
|
||||
CFLAGS-nis_error.c = -Wno-strict-prototypes
|
||||
CFLAGS-nis_names.c = -Wno-strict-prototypes
|
||||
CFLAGS-nis_clone.c = -Wno-strict-prototypes
|
||||
CFLAGS-nis_table.c = -Wno-strict-prototypes
|
||||
CFLAGS-nis_server.c = -Wno-strict-prototypes
|
||||
CFLAGS-nis_xdr.c = -Wno-strict-prototypes
|
||||
CFLAGS-nis_intern.c = -Wno-strict-prototypes
|
||||
CFLAGS-nisplus-alias.c = -Wno-strict-prototypes
|
||||
CFLAGS-nisplus-ethers.c = -Wno-strict-prototypes
|
||||
CFLAGS-nisplus-grp.c = -Wno-strict-prototypes
|
||||
CFLAGS-nisplus-hosts.c = -Wno-strict-prototypes
|
||||
CFLAGS-nisplus-netgrp.c = -Wno-strict-prototypes
|
||||
CFLAGS-nisplus-network.c = -Wno-strict-prototypes
|
||||
CFLAGS-nisplus-proto.c = -Wno-strict-prototypes
|
||||
CFLAGS-nisplus-publickey.c = -Wno-strict-prototypes
|
||||
CFLAGS-nisplus-pwd.c = -Wno-strict-prototypes
|
||||
CFLAGS-nisplus-rpc.c = -Wno-strict-prototypes
|
||||
CFLAGS-nisplus-service.c = -Wno-strict-prototypes
|
||||
CFLAGS-nisplus-spwd.c = -Wno-strict-prototypes
|
||||
|
||||
include ../Rules
|
||||
|
||||
|
||||
$(objpfx)libnss_compat.so: $(objpfx)libnsl.so$(libnsl.so-version) \
|
||||
$(common-objpfx)nss/libnss_files.so
|
||||
$(common-objpfx)nss/libnss_files.so \
|
||||
$(common-objpfx)nis/libnss_nisplus.so
|
||||
$(objpfx)libnss_nis.so: $(objpfx)libnsl.so$(libnsl.so-version) \
|
||||
$(common-objpfx)nss/libnss_files.so
|
||||
$(objpfx)libnss_nisplus.so: $(objpfx)libnsl.so$(libnsl.so-version)
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
|
||||
* nss_nisplus: When using parser form nss_files, rewrite parser
|
||||
|
||||
* compat could use data from nisplus, too. Implement this
|
||||
|
||||
* nss_nisplus: Search the data in the complete NIS+ namespace
|
||||
specified by NIS_PATH
|
||||
|
||||
* nis_server: implement nis_getservlist, nis_stats, nis_servstate
|
||||
|
||||
* nis_groups: implement it
|
||||
@@ -22,10 +23,10 @@
|
||||
* Possible flags:
|
||||
- FOLLOW_LINKS (nis_list, nis_lookup)
|
||||
- FOLLOW_PATH (nis_list, not supported)
|
||||
- HARD_LOOKUP (__do_niscall, not supported)
|
||||
- HARD_LOOKUP (__do_niscall)
|
||||
- ALL_RESULTS (nis_list, not supported, needs server callback)
|
||||
- NO_CACHE (__do_niscall, cache not supported yet)
|
||||
- MASTER_ONLY (__do_niscall, not supported)
|
||||
- MASTER_ONLY (__do_niscall)
|
||||
- EXPAND_NAME (nis_lookup, nis_list)
|
||||
- RETURN_RESULT (nis_table.c)
|
||||
- ADD_OVERWRITE (nis_table.c)
|
||||
@@ -37,4 +38,3 @@
|
||||
- USE_DGRAM (__do_niscall)
|
||||
- NO_AUTHINFO (__do_niscall)
|
||||
|
||||
|
||||
|
||||
+41
-40
@@ -60,13 +60,11 @@ __nis_dobind (const nis_server *server, u_long flags)
|
||||
int clnt_sock;
|
||||
size_t i;
|
||||
CLIENT *client = NULL;
|
||||
/* XXX What is this variable for? */
|
||||
void *out = NULL;
|
||||
|
||||
memset (&clnt_saddr, '\0', sizeof clnt_saddr);
|
||||
clnt_saddr.sin_family = AF_INET;
|
||||
for (i = 0; i < server->ep.ep_len; i++)
|
||||
{
|
||||
memset (&clnt_saddr, '\0', sizeof clnt_saddr);
|
||||
clnt_saddr.sin_family = AF_INET;
|
||||
if (strcmp (server->ep.ep_val[i].family,"loopback") == 0)
|
||||
{
|
||||
if (server->ep.ep_val[i].uaddr[i] == '-')
|
||||
@@ -79,14 +77,14 @@ __nis_dobind (const nis_server *server, u_long flags)
|
||||
else
|
||||
continue;
|
||||
}
|
||||
else
|
||||
if (strcmp (server->ep.ep_val[i].proto,"tcp") == 0)
|
||||
{
|
||||
if ((flags & USE_DGRAM) == USE_DGRAM)
|
||||
continue;
|
||||
else
|
||||
clnt_saddr.sin_addr.s_addr = htonl (INADDR_LOOPBACK);
|
||||
}
|
||||
else
|
||||
if (strcmp (server->ep.ep_val[i].proto,"tcp") == 0)
|
||||
{
|
||||
if ((flags & USE_DGRAM) == USE_DGRAM)
|
||||
continue;
|
||||
else
|
||||
clnt_saddr.sin_addr.s_addr = htonl (INADDR_LOOPBACK);
|
||||
}
|
||||
}
|
||||
else
|
||||
if (strcmp (server->ep.ep_val[i].family,"inet") == 0)
|
||||
@@ -126,36 +124,35 @@ __nis_dobind (const nis_server *server, u_long flags)
|
||||
|
||||
if (client == NULL)
|
||||
continue;
|
||||
#if 1
|
||||
if (clnt_call (client, 0, (xdrproc_t) xdr_void, NULL,
|
||||
(xdrproc_t) xdr_void, out, TIMEOUT) != RPC_SUCCESS)
|
||||
(xdrproc_t) xdr_void, NULL, TIMEOUT) != RPC_SUCCESS)
|
||||
{
|
||||
clnt_destroy (client);
|
||||
continue;
|
||||
}
|
||||
#endif
|
||||
if ((flags & NO_AUTHINFO) != NO_AUTHINFO)
|
||||
{
|
||||
#if !defined(NO_DES_RPC)
|
||||
if (server->key_type == NIS_PK_DH)
|
||||
{
|
||||
char netname[MAXNETNAMELEN+1];
|
||||
char *p;
|
||||
|
||||
strcpy (netname, "unix.");
|
||||
strncat (netname, server->name,MAXNETNAMELEN-5);
|
||||
netname[MAXNETNAMELEN-5] = '\0';
|
||||
p = strchr (netname, '.');
|
||||
*p = '@';
|
||||
client->cl_auth =
|
||||
authdes_pk_create (netname, &server->pkey, 300, NULL, NULL);
|
||||
if (!client->cl_auth)
|
||||
client->cl_auth = authunix_create_default ();
|
||||
}
|
||||
else
|
||||
if ((flags & NO_AUTHINFO) != NO_AUTHINFO)
|
||||
{
|
||||
#if defined(HAVE_SECURE_RPC)
|
||||
if (server->key_type == NIS_PK_DH)
|
||||
{
|
||||
char netname[MAXNETNAMELEN+1];
|
||||
char *p;
|
||||
|
||||
p = stpcpy (netname, "unix.");
|
||||
strncpy (p, server->name,MAXNETNAMELEN-5);
|
||||
netname[MAXNETNAMELEN] = '\0';
|
||||
p = strchr (netname, '.');
|
||||
*p = '@';
|
||||
client->cl_auth =
|
||||
authdes_pk_create (netname, &server->pkey, 300, NULL, NULL);
|
||||
if (!client->cl_auth)
|
||||
client->cl_auth = authunix_create_default ();
|
||||
}
|
||||
else
|
||||
#endif
|
||||
client->cl_auth = authunix_create_default ();
|
||||
}
|
||||
client->cl_auth = authunix_create_default ();
|
||||
}
|
||||
return client;
|
||||
}
|
||||
|
||||
@@ -170,7 +167,8 @@ __do_niscall (const nis_server *serv, int serv_len, u_long prog,
|
||||
CLIENT *clnt;
|
||||
directory_obj *dir = NULL;
|
||||
const nis_server *server;
|
||||
int try, result, server_len;
|
||||
int try, result;
|
||||
unsigned int server_len;
|
||||
|
||||
if (serv == NULL || serv_len == 0)
|
||||
{
|
||||
@@ -189,6 +187,9 @@ __do_niscall (const nis_server *serv, int serv_len, u_long prog,
|
||||
server_len = serv_len;
|
||||
}
|
||||
|
||||
if (((flags & MASTER_ONLY) == MASTER_ONLY) && server_len > 1)
|
||||
server_len = 1; /* The first entry is the master */
|
||||
|
||||
try = 0;
|
||||
result = NIS_NAMEUNREACHABLE;
|
||||
|
||||
@@ -196,7 +197,9 @@ __do_niscall (const nis_server *serv, int serv_len, u_long prog,
|
||||
{
|
||||
unsigned int i;
|
||||
|
||||
++try;
|
||||
if ((flags & HARD_LOOKUP) == 0)
|
||||
++try;
|
||||
|
||||
for (i = 0; i < server_len; i++)
|
||||
{
|
||||
if ((clnt = __nis_dobind (&server[i], flags)) == NULL)
|
||||
@@ -206,9 +209,7 @@ __do_niscall (const nis_server *serv, int serv_len, u_long prog,
|
||||
|
||||
if (result != RPC_SUCCESS)
|
||||
{
|
||||
/* XXX Grrr. The cast is needed for now since Sun code does
|
||||
note know about `const'. */
|
||||
clnt_perror (clnt, (char *) "do_niscall: clnt_call");
|
||||
clnt_perror (clnt, "do_niscall: clnt_call");
|
||||
clnt_destroy (clnt);
|
||||
result = NIS_RPCERROR;
|
||||
}
|
||||
|
||||
+4
-4
@@ -25,7 +25,7 @@
|
||||
/* Nearly the same as nis_getnames, but nis_getnames stopped
|
||||
when 2 points left */
|
||||
nis_name *
|
||||
__nis_expandname (const nis_name name)
|
||||
__nis_expandname (const char *name)
|
||||
{
|
||||
nis_name *getnames = NULL;
|
||||
char local_domain[NIS_MAXNAMELEN + 1];
|
||||
@@ -145,13 +145,13 @@ __nis_expandname (const nis_name name)
|
||||
}
|
||||
|
||||
fd_result *
|
||||
__nis_finddirectoy (nis_name dir_name)
|
||||
__nis_finddirectoy (const_nis_name name)
|
||||
{
|
||||
fd_args args;
|
||||
nis_error status;
|
||||
fd_result *res;
|
||||
|
||||
args.dir_name = dir_name;
|
||||
args.dir_name = (char *) name;
|
||||
args.requester = nis_local_principal ();
|
||||
|
||||
res = calloc (1, sizeof (fd_result));
|
||||
@@ -160,7 +160,7 @@ __nis_finddirectoy (nis_name dir_name)
|
||||
|
||||
if ((status = __do_niscall (NULL, 0, NIS_FINDDIRECTORY,
|
||||
(xdrproc_t) xdr_fd_args,
|
||||
(caddr_t) & args,
|
||||
(caddr_t) &args,
|
||||
(xdrproc_t) xdr_fd_result,
|
||||
(caddr_t) res, 0)) != RPC_SUCCESS)
|
||||
res->status = status;
|
||||
|
||||
+3
-4
@@ -27,12 +27,11 @@ __BEGIN_DECLS
|
||||
extern nis_error __do_niscall (__const nis_server *server, int server_len,
|
||||
u_long prog, xdrproc_t xargs, caddr_t req,
|
||||
xdrproc_t xres, caddr_t resp, u_long flags);
|
||||
#if !defined(NO_DES_RPC)
|
||||
extern AUTH *authdes_pk_create (char *, netobj *, u_int,
|
||||
#if defined (HAVE_SECURE_RPC)
|
||||
extern AUTH *authdes_pk_create (const char *, const netobj *, u_int,
|
||||
struct sockaddr *, des_block *);
|
||||
#endif
|
||||
|
||||
extern nis_name *__nis_expandname (__const nis_name);
|
||||
extern nis_name *__nis_expandname (const char *);
|
||||
|
||||
__END_DECLS
|
||||
|
||||
|
||||
+35
-11
@@ -25,7 +25,7 @@
|
||||
#include "nis_intern.h"
|
||||
|
||||
nis_result *
|
||||
nis_lookup (const nis_name name, const u_long flags)
|
||||
nis_lookup (const_nis_name name, const u_long flags)
|
||||
{
|
||||
nis_result *res;
|
||||
struct ns_request req;
|
||||
@@ -106,7 +106,7 @@ nis_lookup (const nis_name name, const u_long flags)
|
||||
}
|
||||
else
|
||||
{
|
||||
req.ns_name = name;
|
||||
req.ns_name = (char *)name;
|
||||
|
||||
while (is_link)
|
||||
{
|
||||
@@ -116,7 +116,7 @@ nis_lookup (const nis_name name, const u_long flags)
|
||||
|
||||
if ((status = __do_niscall (NULL, 0, NIS_LOOKUP,
|
||||
(xdrproc_t) xdr_ns_request,
|
||||
(caddr_t) & req,
|
||||
(caddr_t) &req,
|
||||
(xdrproc_t) xdr_nis_result,
|
||||
(caddr_t) res, flags)) != RPC_SUCCESS)
|
||||
{
|
||||
@@ -158,31 +158,55 @@ nis_lookup (const nis_name name, const u_long flags)
|
||||
}
|
||||
|
||||
nis_result *
|
||||
nis_add (const nis_name name, const nis_object *obj)
|
||||
nis_add (const_nis_name name, const nis_object *obj)
|
||||
{
|
||||
nis_result *res;
|
||||
nis_error status;
|
||||
struct ns_request req;
|
||||
char *p1, *p2, *p3, *p4;
|
||||
char buf1 [strlen (name) + 20];
|
||||
char buf4 [strlen (name) + 20];
|
||||
|
||||
res = calloc (1, sizeof (nis_result));
|
||||
|
||||
req.ns_name = name;
|
||||
req.ns_name = (char *)name;
|
||||
|
||||
req.ns_object.ns_object_len = 1;
|
||||
req.ns_object.ns_object_val = nis_clone_object (obj, NULL);
|
||||
|
||||
p1 = req.ns_object.ns_object_val[0].zo_name;
|
||||
req.ns_object.ns_object_val[0].zo_name =
|
||||
nis_name_of_r (name, buf1, sizeof (buf1));
|
||||
|
||||
p2 = req.ns_object.ns_object_val[0].zo_owner;
|
||||
if (p2 == NULL || strlen (p2) == 0)
|
||||
req.ns_object.ns_object_val[0].zo_owner = nis_local_principal ();
|
||||
|
||||
p3 = req.ns_object.ns_object_val[0].zo_group;
|
||||
if (p3 == NULL || strlen (p3) == 0)
|
||||
req.ns_object.ns_object_val[0].zo_group = nis_local_group ();
|
||||
|
||||
p4 = req.ns_object.ns_object_val[0].zo_domain;
|
||||
req.ns_object.ns_object_val[0].zo_domain =
|
||||
nis_domain_of_r (name, buf4, sizeof (buf4));
|
||||
|
||||
if ((status = __do_niscall (NULL, 0, NIS_ADD, (xdrproc_t) xdr_ns_request,
|
||||
(caddr_t) & req, (xdrproc_t) xdr_nis_result,
|
||||
(caddr_t) &req, (xdrproc_t) xdr_nis_result,
|
||||
(caddr_t) res, 0)) != RPC_SUCCESS)
|
||||
res->status = status;
|
||||
|
||||
req.ns_object.ns_object_val[0].zo_name = p1;
|
||||
req.ns_object.ns_object_val[0].zo_owner = p2;
|
||||
req.ns_object.ns_object_val[0].zo_group = p3;
|
||||
req.ns_object.ns_object_val[0].zo_domain = p4;
|
||||
|
||||
nis_destroy_object (req.ns_object.ns_object_val);
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
nis_result *
|
||||
nis_remove (const nis_name name, const nis_object *obj)
|
||||
nis_remove (const_nis_name name, const nis_object *obj)
|
||||
{
|
||||
nis_result *res;
|
||||
nis_error status;
|
||||
@@ -190,7 +214,7 @@ nis_remove (const nis_name name, const nis_object *obj)
|
||||
|
||||
res = calloc (1, sizeof (nis_result));
|
||||
|
||||
req.ns_name = name;
|
||||
req.ns_name = (char *)name;
|
||||
|
||||
if (obj != NULL)
|
||||
{
|
||||
@@ -214,7 +238,7 @@ nis_remove (const nis_name name, const nis_object *obj)
|
||||
}
|
||||
|
||||
nis_result *
|
||||
nis_modify (const nis_name name, const nis_object *obj)
|
||||
nis_modify (const_nis_name name, const nis_object *obj)
|
||||
{
|
||||
nis_result *res;
|
||||
nis_error status;
|
||||
@@ -222,12 +246,12 @@ nis_modify (const nis_name name, const nis_object *obj)
|
||||
|
||||
res = calloc (1, sizeof (nis_result));
|
||||
|
||||
req.ns_name = name;
|
||||
req.ns_name = (char *)name;
|
||||
|
||||
req.ns_object.ns_object_len = 1;
|
||||
req.ns_object.ns_object_val = nis_clone_object (obj, NULL);
|
||||
|
||||
if ((status = __do_niscall (NULL, 0, NIS_REMOVE, (xdrproc_t) xdr_ns_request,
|
||||
if ((status = __do_niscall (NULL, 0, NIS_MODIFY, (xdrproc_t) xdr_ns_request,
|
||||
(caddr_t) & req, (xdrproc_t) xdr_nis_result,
|
||||
(caddr_t) res, 0)) != RPC_SUCCESS)
|
||||
res->status = status;
|
||||
|
||||
+11
-11
@@ -22,7 +22,7 @@
|
||||
#include "nis_intern.h"
|
||||
|
||||
nis_error
|
||||
nis_mkdir (const nis_name dir, const nis_server *server)
|
||||
nis_mkdir (const_nis_name dir, const nis_server *server)
|
||||
{
|
||||
nis_error res;
|
||||
|
||||
@@ -30,8 +30,8 @@ nis_mkdir (const nis_name dir, const nis_server *server)
|
||||
{
|
||||
int result;
|
||||
if ((result = __do_niscall (NULL, 0, NIS_MKDIR, (xdrproc_t) xdr_nis_name,
|
||||
(caddr_t) dir, (xdrproc_t) xdr_nis_error,
|
||||
(caddr_t) & res, 0)) != RPC_SUCCESS)
|
||||
(caddr_t) &dir, (xdrproc_t) xdr_nis_error,
|
||||
(caddr_t) &res, 0)) != RPC_SUCCESS)
|
||||
{
|
||||
fprintf (stderr, _("__do_niscall: Error #%d\n"), result);
|
||||
return NIS_RPCERROR;
|
||||
@@ -42,8 +42,8 @@ nis_mkdir (const nis_name dir, const nis_server *server)
|
||||
int result;
|
||||
if ((result = __do_niscall (server, 1, NIS_MKDIR,
|
||||
(xdrproc_t) xdr_nis_name,
|
||||
(caddr_t) dir, (xdrproc_t) xdr_nis_error,
|
||||
(caddr_t) & res, 0)) != RPC_SUCCESS)
|
||||
(caddr_t) &dir, (xdrproc_t) xdr_nis_error,
|
||||
(caddr_t) &res, 0)) != RPC_SUCCESS)
|
||||
{
|
||||
fprintf (stderr, _("__do_niscall: Error #%d\n"), result);
|
||||
return NIS_RPCERROR;
|
||||
@@ -54,7 +54,7 @@ nis_mkdir (const nis_name dir, const nis_server *server)
|
||||
}
|
||||
|
||||
nis_error
|
||||
nis_rmdir (const nis_name dir, const nis_server *server)
|
||||
nis_rmdir (const_nis_name dir, const nis_server *server)
|
||||
{
|
||||
nis_error res;
|
||||
|
||||
@@ -62,8 +62,8 @@ nis_rmdir (const nis_name dir, const nis_server *server)
|
||||
{
|
||||
int result;
|
||||
if ((result = __do_niscall (NULL, 0, NIS_RMDIR, (xdrproc_t) xdr_nis_name,
|
||||
(caddr_t) dir, (xdrproc_t) xdr_nis_error,
|
||||
(caddr_t) & res, 0)) != RPC_SUCCESS)
|
||||
(caddr_t) &dir, (xdrproc_t) xdr_nis_error,
|
||||
(caddr_t) &res, 0)) != RPC_SUCCESS)
|
||||
{
|
||||
fprintf (stderr, _("__do_niscall: Error #%d\n"), result);
|
||||
return NIS_RPCERROR;
|
||||
@@ -74,8 +74,8 @@ nis_rmdir (const nis_name dir, const nis_server *server)
|
||||
int result;
|
||||
if ((result = __do_niscall (server, 1, NIS_RMDIR,
|
||||
(xdrproc_t) xdr_nis_name,
|
||||
(caddr_t) dir, (xdrproc_t) xdr_nis_error,
|
||||
(caddr_t) & res, 0)) != RPC_SUCCESS)
|
||||
(caddr_t) &dir, (xdrproc_t) xdr_nis_error,
|
||||
(caddr_t) &res, 0)) != RPC_SUCCESS)
|
||||
{
|
||||
fprintf (stderr, _("__do_niscall: Error #%d\n"), result);
|
||||
return NIS_RPCERROR;
|
||||
@@ -116,7 +116,7 @@ nis_freetags (nis_tag *tags, const int numtags)
|
||||
}
|
||||
|
||||
nis_server **
|
||||
nis_getservlist (const nis_name dir)
|
||||
nis_getservlist (const_nis_name dir)
|
||||
{
|
||||
nis_server **serv;
|
||||
|
||||
|
||||
+9
-9
@@ -23,7 +23,7 @@
|
||||
#include <rpcsvc/nislib.h>
|
||||
|
||||
nis_name
|
||||
nis_leaf_of (const nis_name name)
|
||||
nis_leaf_of (const_nis_name name)
|
||||
{
|
||||
static char result[NIS_MAXNAMELEN + 1];
|
||||
|
||||
@@ -31,7 +31,7 @@ nis_leaf_of (const nis_name name)
|
||||
}
|
||||
|
||||
nis_name
|
||||
nis_leaf_of_r (const nis_name name, char *buffer, size_t buflen)
|
||||
nis_leaf_of_r (const_nis_name name, char *buffer, size_t buflen)
|
||||
{
|
||||
size_t i = 0;
|
||||
|
||||
@@ -53,7 +53,7 @@ nis_leaf_of_r (const nis_name name, char *buffer, size_t buflen)
|
||||
}
|
||||
|
||||
nis_name
|
||||
nis_name_of (const nis_name name)
|
||||
nis_name_of (const_nis_name name)
|
||||
{
|
||||
static char result[NIS_MAXNAMELEN + 1];
|
||||
|
||||
@@ -61,7 +61,7 @@ nis_name_of (const nis_name name)
|
||||
}
|
||||
|
||||
nis_name
|
||||
nis_name_of_r (const nis_name name, char *buffer, size_t buflen)
|
||||
nis_name_of_r (const_nis_name name, char *buffer, size_t buflen)
|
||||
{
|
||||
char *local_domain;
|
||||
int diff;
|
||||
@@ -90,7 +90,7 @@ nis_name_of_r (const nis_name name, char *buffer, size_t buflen)
|
||||
}
|
||||
|
||||
nis_name
|
||||
nis_domain_of (const nis_name name)
|
||||
nis_domain_of (const_nis_name name)
|
||||
{
|
||||
static char result[NIS_MAXNAMELEN + 1];
|
||||
|
||||
@@ -98,7 +98,7 @@ nis_domain_of (const nis_name name)
|
||||
}
|
||||
|
||||
nis_name
|
||||
nis_domain_of_r (const nis_name name, char *buffer, size_t buflen)
|
||||
nis_domain_of_r (const_nis_name name, char *buffer, size_t buflen)
|
||||
{
|
||||
char *cptr;
|
||||
size_t cptr_len;
|
||||
@@ -122,7 +122,7 @@ nis_domain_of_r (const nis_name name, char *buffer, size_t buflen)
|
||||
}
|
||||
|
||||
static int
|
||||
count_dots (const nis_name str)
|
||||
count_dots (const_nis_name str)
|
||||
{
|
||||
int count = 0;
|
||||
size_t i;
|
||||
@@ -135,7 +135,7 @@ count_dots (const nis_name str)
|
||||
}
|
||||
|
||||
nis_name *
|
||||
nis_getnames (const nis_name name)
|
||||
nis_getnames (const_nis_name name)
|
||||
{
|
||||
nis_name *getnames = NULL;
|
||||
char local_domain[NIS_MAXNAMELEN + 1];
|
||||
@@ -267,7 +267,7 @@ nis_freenames (nis_name *names)
|
||||
}
|
||||
|
||||
name_pos
|
||||
nis_dir_cmp (const nis_name n1, const nis_name n2)
|
||||
nis_dir_cmp (const_nis_name n1, const_nis_name n2)
|
||||
{
|
||||
int len1, len2;
|
||||
|
||||
|
||||
+12
-12
@@ -23,7 +23,7 @@
|
||||
#include "nis_intern.h"
|
||||
|
||||
static void
|
||||
splitname (const nis_name name, nis_name *ibr_name, int *srch_len,
|
||||
splitname (const_nis_name name, nis_name *ibr_name, int *srch_len,
|
||||
nis_attr **srch_val)
|
||||
{
|
||||
char *cptr, *key, *val, *next;
|
||||
@@ -138,7 +138,7 @@ splitname (const nis_name name, nis_name *ibr_name, int *srch_len,
|
||||
}
|
||||
|
||||
static struct ib_request *
|
||||
__create_ib_request (const nis_name name, struct ib_request *ibreq,
|
||||
__create_ib_request (const_nis_name name, struct ib_request *ibreq,
|
||||
u_long flags)
|
||||
{
|
||||
splitname (name, &ibreq->ibr_name, &ibreq->ibr_srch.ibr_srch_len,
|
||||
@@ -173,8 +173,8 @@ __create_ib_request (const nis_name name, struct ib_request *ibreq,
|
||||
}
|
||||
|
||||
nis_result *
|
||||
nis_list (const nis_name name, const u_long flags,
|
||||
int (*callback) (const nis_name name,
|
||||
nis_list (const_nis_name name, u_long flags,
|
||||
int (*callback) (const_nis_name name,
|
||||
const nis_object *object,
|
||||
const void *userdata),
|
||||
const void *userdata)
|
||||
@@ -257,8 +257,8 @@ nis_list (const nis_name name, const u_long flags,
|
||||
}
|
||||
|
||||
nis_result *
|
||||
nis_add_entry (const nis_name name, const nis_object *obj,
|
||||
const u_long flags)
|
||||
nis_add_entry (const_nis_name name, const nis_object *obj,
|
||||
u_long flags)
|
||||
{
|
||||
nis_result *res;
|
||||
struct ib_request ibreq;
|
||||
@@ -289,8 +289,8 @@ nis_add_entry (const nis_name name, const nis_object *obj,
|
||||
}
|
||||
|
||||
nis_result *
|
||||
nis_modify_entry (const nis_name name, const nis_object *obj,
|
||||
const u_long flags)
|
||||
nis_modify_entry (const_nis_name name, const nis_object *obj,
|
||||
u_long flags)
|
||||
{
|
||||
nis_result *res;
|
||||
struct ib_request ibreq;
|
||||
@@ -320,8 +320,8 @@ nis_modify_entry (const nis_name name, const nis_object *obj,
|
||||
}
|
||||
|
||||
nis_result *
|
||||
nis_remove_entry (const nis_name name, const nis_object *obj,
|
||||
const u_long flags)
|
||||
nis_remove_entry (const_nis_name name, const nis_object *obj,
|
||||
u_long flags)
|
||||
{
|
||||
nis_result *res;
|
||||
struct ib_request ibreq;
|
||||
@@ -354,7 +354,7 @@ nis_remove_entry (const nis_name name, const nis_object *obj,
|
||||
}
|
||||
|
||||
nis_result *
|
||||
nis_first_entry (const nis_name name)
|
||||
nis_first_entry (const_nis_name name)
|
||||
{
|
||||
nis_result *res;
|
||||
struct ib_request ibreq;
|
||||
@@ -379,7 +379,7 @@ nis_first_entry (const nis_name name)
|
||||
}
|
||||
|
||||
nis_result *
|
||||
nis_next_entry (const nis_name name, const netobj *cookie)
|
||||
nis_next_entry (const_nis_name name, const netobj *cookie)
|
||||
{
|
||||
nis_result *res;
|
||||
struct ib_request ibreq;
|
||||
|
||||
+223
-34
@@ -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 Thorsten Kukuk <kukuk@vt.uni-paderborn.de>, 1996.
|
||||
|
||||
@@ -25,6 +25,14 @@
|
||||
#include <string.h>
|
||||
#include <rpcsvc/yp.h>
|
||||
#include <rpcsvc/ypclnt.h>
|
||||
#include <rpcsvc/nis.h>
|
||||
#include <rpcsvc/nislib.h>
|
||||
#include <nsswitch.h>
|
||||
|
||||
#include "nss-nisplus.h"
|
||||
|
||||
static service_user *ni = NULL;
|
||||
static bool_t use_nisplus = FALSE; /* default: group_compat: nis */
|
||||
|
||||
/* Get the declaration of the parser function. */
|
||||
#define ENTNAME grent
|
||||
@@ -32,7 +40,7 @@
|
||||
#define EXTERN_PARSER
|
||||
#include "../../nss/nss_files/files-parse.c"
|
||||
|
||||
/* Structure for remembering -@netgroup and -user members ... */
|
||||
/* Structure for remembering -group members ... */
|
||||
#define BLACKLIST_INITIAL_SIZE 512
|
||||
#define BLACKLIST_INCREMENT 256
|
||||
struct blacklist_t
|
||||
@@ -48,12 +56,15 @@ struct ent_t
|
||||
bool_t nis_first;
|
||||
char *oldkey;
|
||||
int oldkeylen;
|
||||
nis_result *result;
|
||||
nis_name *names;
|
||||
u_long names_nr;
|
||||
FILE *stream;
|
||||
struct blacklist_t blacklist;
|
||||
};
|
||||
};
|
||||
typedef struct ent_t ent_t;
|
||||
|
||||
static ent_t ext_ent = {0, 0, NULL, 0, NULL, {NULL, 0, 0}};
|
||||
static ent_t ext_ent = {0, 0, NULL, 0, NULL, NULL, 0, NULL, {NULL, 0, 0}};
|
||||
|
||||
/* Protect global state against multiple changers. */
|
||||
__libc_lock_define_initialized (static, lock)
|
||||
@@ -61,6 +72,8 @@ __libc_lock_define_initialized (static, lock)
|
||||
/* Prototypes for local functions. */
|
||||
static void blacklist_store_name (const char *, ent_t *);
|
||||
static int in_blacklist (const char *, int, ent_t *);
|
||||
extern int _nss_nisplus_parse_grent (nis_result *, struct group *,
|
||||
char *, size_t);
|
||||
|
||||
static enum nss_status
|
||||
internal_setgrent (ent_t *ent)
|
||||
@@ -76,6 +89,18 @@ internal_setgrent (ent_t *ent)
|
||||
ent->oldkeylen = 0;
|
||||
}
|
||||
|
||||
if (ent->result != NULL)
|
||||
{
|
||||
nis_freeresult (ent->result);
|
||||
ent->result = NULL;
|
||||
}
|
||||
|
||||
if (ent->names != NULL)
|
||||
{
|
||||
nis_freenames (ent->names);
|
||||
ent->names = NULL;
|
||||
}
|
||||
ent->names_nr = 0;
|
||||
ent->blacklist.current = 0;
|
||||
if (ent->blacklist.data != NULL)
|
||||
ent->blacklist.data[0] = '\0';
|
||||
@@ -101,6 +126,12 @@ _nss_compat_setgrent (void)
|
||||
|
||||
__libc_lock_lock (lock);
|
||||
|
||||
if (ni == NULL)
|
||||
{
|
||||
__nss_database_lookup ("group_compat", NULL, "nis", &ni);
|
||||
use_nisplus = (strcmp (ni->name, "nisplus") == 0);
|
||||
}
|
||||
|
||||
result = internal_setgrent (&ext_ent);
|
||||
|
||||
__libc_lock_unlock (lock);
|
||||
@@ -127,6 +158,18 @@ internal_endgrent (ent_t *ent)
|
||||
ent->oldkeylen = 0;
|
||||
}
|
||||
|
||||
if (ent->result != NULL)
|
||||
{
|
||||
nis_freeresult (ent->result);
|
||||
ent->result = NULL;
|
||||
}
|
||||
|
||||
if (ent->names != NULL)
|
||||
{
|
||||
nis_freenames (ent->names);
|
||||
ent->names = NULL;
|
||||
}
|
||||
ent->names_nr = 0;
|
||||
ent->blacklist.current = 0;
|
||||
if (ent->blacklist.data != NULL)
|
||||
ent->blacklist.data[0] = '\0';
|
||||
@@ -155,7 +198,7 @@ getgrent_next_nis (struct group *result, ent_t *ent, char *buffer,
|
||||
struct parser_data *data = (void *) buffer;
|
||||
char *domain;
|
||||
char *outkey, *outval;
|
||||
int outkeylen, outvallen;
|
||||
int outkeylen, outvallen, parse_res;
|
||||
char *p;
|
||||
|
||||
if (yp_get_default_domain (&domain) != YPERR_SUCCESS)
|
||||
@@ -202,13 +245,133 @@ getgrent_next_nis (struct group *result, ent_t *ent, char *buffer,
|
||||
|
||||
while (isspace (*p))
|
||||
++p;
|
||||
}
|
||||
while (!_nss_files_parse_grent (p, result, data, buflen));
|
||||
|
||||
if (!in_blacklist (result->gr_name, strlen (result->gr_name), ent))
|
||||
parse_res = _nss_files_parse_grent (p, result, data, buflen);
|
||||
|
||||
if (parse_res &&
|
||||
in_blacklist (result->gr_name, strlen (result->gr_name), ent))
|
||||
parse_res = 0; /* if result->gr_name in blacklist,search next entry */
|
||||
}
|
||||
while (!parse_res);
|
||||
|
||||
return NSS_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
static enum nss_status
|
||||
getgrent_next_nisplus (struct group *result, ent_t *ent, char *buffer,
|
||||
size_t buflen)
|
||||
{
|
||||
int parse_res;
|
||||
|
||||
if (ent->names == NULL)
|
||||
{
|
||||
ent->names = nis_getnames ("group.org_dir");
|
||||
if (ent->names == NULL || ent->names[0] == NULL)
|
||||
{
|
||||
ent->nis = 0;
|
||||
return NSS_STATUS_UNAVAIL;
|
||||
}
|
||||
}
|
||||
|
||||
do
|
||||
{
|
||||
if (ent->nis_first)
|
||||
{
|
||||
next_name:
|
||||
ent->result = nis_first_entry(ent->names[ent->names_nr]);
|
||||
if (niserr2nss (ent->result->status) != NSS_STATUS_SUCCESS)
|
||||
{
|
||||
ent->nis = 0;
|
||||
return niserr2nss (ent->result->status);
|
||||
}
|
||||
ent->nis_first = FALSE;
|
||||
}
|
||||
else
|
||||
{
|
||||
nis_result *res;
|
||||
|
||||
res = nis_next_entry(ent->names[ent->names_nr],
|
||||
&ent->result->cookie);
|
||||
nis_freeresult (ent->result);
|
||||
ent->result = res;
|
||||
if (niserr2nss (ent->result->status) != NSS_STATUS_SUCCESS)
|
||||
{
|
||||
if ((ent->result->status == NIS_NOTFOUND) &&
|
||||
ent->names[ent->names_nr + 1] != NULL)
|
||||
{
|
||||
nis_freeresult (ent->result);
|
||||
ent->names_nr += 1;
|
||||
goto next_name;
|
||||
}
|
||||
else
|
||||
{
|
||||
ent->nis = 0;
|
||||
return niserr2nss (ent->result->status);
|
||||
}
|
||||
}
|
||||
}
|
||||
parse_res = _nss_nisplus_parse_grent (ent->result, result, buffer,
|
||||
buflen);
|
||||
if (parse_res &&
|
||||
in_blacklist (result->gr_name, strlen (result->gr_name), ent))
|
||||
parse_res = 0; /* if result->gr_name in blacklist,search next entry */
|
||||
}
|
||||
while (!parse_res);
|
||||
|
||||
return NSS_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
/* This function handle the +group entrys in /etc/group */
|
||||
static enum nss_status
|
||||
getgrent_next_file_plusgroup (struct group *result, char *buffer,
|
||||
size_t buflen)
|
||||
{
|
||||
struct parser_data *data = (void *) buffer;
|
||||
int parse_res;
|
||||
|
||||
if (use_nisplus) /* Do the NIS+ query here */
|
||||
{
|
||||
nis_result *res;
|
||||
char buf[strlen (result->gr_name) + 24];
|
||||
|
||||
sprintf(buf, "[name=%s],group.org_dir",
|
||||
&result->gr_name[1]);
|
||||
res = nis_list(buf, EXPAND_NAME, NULL, NULL);
|
||||
if (niserr2nss (res->status) != NSS_STATUS_SUCCESS)
|
||||
{
|
||||
enum nss_status status = niserr2nss (res->status);
|
||||
|
||||
nis_freeresult (res);
|
||||
return status;
|
||||
}
|
||||
parse_res = _nss_nisplus_parse_grent (res, result, buffer, buflen);
|
||||
nis_freeresult (res);
|
||||
}
|
||||
else /* Use NIS */
|
||||
{
|
||||
char *domain, *outval, *p;
|
||||
int outvallen;
|
||||
|
||||
if (yp_get_default_domain (&domain) != YPERR_SUCCESS)
|
||||
return NSS_STATUS_TRYAGAIN;
|
||||
|
||||
if (yp_match (domain, "group.byname", &result->gr_name[1],
|
||||
strlen (result->gr_name) - 1, &outval, &outvallen)
|
||||
!= YPERR_SUCCESS)
|
||||
return NSS_STATUS_TRYAGAIN;
|
||||
p = strncpy (buffer, outval,
|
||||
buflen < (size_t) outvallen ? buflen : (size_t) outvallen);
|
||||
free (outval);
|
||||
while (isspace (*p))
|
||||
p++;
|
||||
parse_res = _nss_files_parse_grent (p, result, data, buflen);
|
||||
}
|
||||
|
||||
if (parse_res)
|
||||
/* We found the entry. */
|
||||
return NSS_STATUS_SUCCESS;
|
||||
else
|
||||
return NSS_STATUS_NOTFOUND;
|
||||
return NSS_STATUS_RETURN;
|
||||
}
|
||||
|
||||
|
||||
@@ -256,27 +419,16 @@ getgrent_next_file (struct group *result, ent_t *ent,
|
||||
if (result->gr_name[0] == '+' && result->gr_name[1] != '\0'
|
||||
&& result->gr_name[1] != '@')
|
||||
{
|
||||
char *domain;
|
||||
char *outval;
|
||||
int outvallen;
|
||||
enum nss_status status;
|
||||
|
||||
if (yp_get_default_domain (&domain) != YPERR_SUCCESS)
|
||||
/* XXX Should we regard this as an fatal error? I don't
|
||||
think so. Just continue working. --drepper@gnu */
|
||||
continue;
|
||||
|
||||
if (yp_match (domain, "group.byname", &result->gr_name[1],
|
||||
strlen (result->gr_name) - 1, &outval, &outvallen)
|
||||
!= YPERR_SUCCESS)
|
||||
continue;
|
||||
|
||||
p = strncpy (buffer, outval, buflen);
|
||||
while (isspace (*p))
|
||||
p++;
|
||||
free (outval);
|
||||
if (_nss_files_parse_grent (p, result, data, buflen))
|
||||
/* We found the entry. */
|
||||
break;
|
||||
status = getgrent_next_file_plusgroup (result, buffer, buflen);
|
||||
if (status == NSS_STATUS_SUCCESS) /* We found the entry. */
|
||||
break;
|
||||
else
|
||||
if (status == NSS_STATUS_RETURN) /* We couldn't parse the entry */
|
||||
continue;
|
||||
else
|
||||
return status;
|
||||
}
|
||||
|
||||
/* +:... */
|
||||
@@ -285,7 +437,10 @@ getgrent_next_file (struct group *result, ent_t *ent,
|
||||
ent->nis = TRUE;
|
||||
ent->nis_first = TRUE;
|
||||
|
||||
return getgrent_next_nis (result, ent, buffer, buflen);
|
||||
if (use_nisplus)
|
||||
return getgrent_next_nisplus (result, ent, buffer, buflen);
|
||||
else
|
||||
return getgrent_next_nis (result, ent, buffer, buflen);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -298,7 +453,12 @@ internal_getgrent_r (struct group *gr, ent_t *ent, char *buffer,
|
||||
size_t buflen)
|
||||
{
|
||||
if (ent->nis)
|
||||
return getgrent_next_nis (gr, ent, buffer, buflen);
|
||||
{
|
||||
if (use_nisplus)
|
||||
return getgrent_next_nisplus (gr, ent, buffer, buflen);
|
||||
else
|
||||
return getgrent_next_nis (gr, ent, buffer, buflen);
|
||||
}
|
||||
else
|
||||
return getgrent_next_file (gr, ent, buffer, buflen);
|
||||
}
|
||||
@@ -310,6 +470,12 @@ _nss_compat_getgrent_r (struct group *grp, char *buffer, size_t buflen)
|
||||
|
||||
__libc_lock_lock (lock);
|
||||
|
||||
if (ni == NULL)
|
||||
{
|
||||
__nss_database_lookup ("group_compat", NULL, "nis", &ni);
|
||||
use_nisplus = (strcmp (ni->name, "nisplus") == 0);
|
||||
}
|
||||
|
||||
/* Be prepared that the setgrent function was not called before. */
|
||||
if (ext_ent.stream == NULL)
|
||||
status = internal_setgrent (&ext_ent);
|
||||
@@ -327,12 +493,21 @@ enum nss_status
|
||||
_nss_compat_getgrnam_r (const char *name, struct group *grp,
|
||||
char *buffer, size_t buflen)
|
||||
{
|
||||
ent_t ent = {0, 0, NULL, 0, NULL, {NULL, 0, 0}};
|
||||
ent_t ent = {0, 0, NULL, 0, NULL, NULL, 0, NULL, {NULL, 0, 0}};
|
||||
enum nss_status status;
|
||||
|
||||
if (name[0] == '-' || name[0] == '+')
|
||||
return NSS_STATUS_NOTFOUND;
|
||||
|
||||
__libc_lock_lock (lock);
|
||||
|
||||
if (ni == NULL)
|
||||
{
|
||||
__nss_database_lookup ("group_compat", NULL, "nis", &ni);
|
||||
use_nisplus = (strcmp (ni->name, "nisplus") == 0);
|
||||
}
|
||||
|
||||
__libc_lock_unlock (lock);
|
||||
|
||||
status = internal_setgrent (&ent);
|
||||
if (status != NSS_STATUS_SUCCESS)
|
||||
@@ -352,9 +527,19 @@ enum nss_status
|
||||
_nss_compat_getgrgid_r (gid_t gid, struct group *grp,
|
||||
char *buffer, size_t buflen)
|
||||
{
|
||||
ent_t ent = {0, 0, NULL, 0, NULL, {NULL, 0, 0}};
|
||||
ent_t ent = {0, 0, NULL, 0, NULL, NULL, 0, NULL, {NULL, 0, 0}};
|
||||
enum nss_status status;
|
||||
|
||||
__libc_lock_lock (lock);
|
||||
|
||||
if (ni == NULL)
|
||||
{
|
||||
__nss_database_lookup ("group_compat", NULL, "nis", &ni);
|
||||
use_nisplus = (strcmp (ni->name, "nisplus") == 0);
|
||||
}
|
||||
|
||||
__libc_lock_unlock (lock);
|
||||
|
||||
status = internal_setgrent (&ent);
|
||||
if (status != NSS_STATUS_SUCCESS)
|
||||
return status;
|
||||
@@ -420,10 +605,14 @@ static bool_t
|
||||
in_blacklist (const char *name, int namelen, ent_t *ent)
|
||||
{
|
||||
char buf[namelen + 3];
|
||||
char *cp;
|
||||
|
||||
if (ent->blacklist.data == NULL)
|
||||
return FALSE;
|
||||
|
||||
stpcpy (stpcpy (stpcpy (buf, "|"), name), "|");
|
||||
buf[0] = '|';
|
||||
cp = stpcpy (&buf[1], name);
|
||||
*cp++= '|';
|
||||
*cp = '\0';
|
||||
return strstr (ent->blacklist.data, buf) != NULL;
|
||||
}
|
||||
|
||||
+354
-64
@@ -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 Thorsten Kukuk <kukuk@vt.uni-paderborn.de>, 1996.
|
||||
|
||||
@@ -26,8 +26,15 @@
|
||||
#include <libc-lock.h>
|
||||
#include <rpcsvc/yp.h>
|
||||
#include <rpcsvc/ypclnt.h>
|
||||
#include <rpcsvc/nis.h>
|
||||
#include <rpcsvc/nislib.h>
|
||||
#include <nsswitch.h>
|
||||
|
||||
#include "netgroup.h"
|
||||
#include "nss-nisplus.h"
|
||||
|
||||
static service_user *ni = NULL;
|
||||
static bool_t use_nisplus = FALSE; /* default: passwd_compat: nis */
|
||||
|
||||
/* Get the declaration of the parser function. */
|
||||
#define ENTNAME pwent
|
||||
@@ -52,6 +59,9 @@ struct ent_t
|
||||
bool_t first;
|
||||
char *oldkey;
|
||||
int oldkeylen;
|
||||
nis_result *result;
|
||||
nis_name *names;
|
||||
u_long names_nr;
|
||||
FILE *stream;
|
||||
struct blacklist_t blacklist;
|
||||
struct passwd pwd;
|
||||
@@ -59,7 +69,7 @@ struct ent_t
|
||||
};
|
||||
typedef struct ent_t ent_t;
|
||||
|
||||
static ent_t ext_ent = {0, 0, 0, NULL, 0, NULL, {NULL, 0, 0},
|
||||
static ent_t ext_ent = {0, 0, 0, NULL, 0, NULL, NULL, 0, NULL, {NULL, 0, 0},
|
||||
{NULL, NULL, 0, 0, NULL, NULL, NULL}};
|
||||
|
||||
/* Protect global state against multiple changers. */
|
||||
@@ -68,7 +78,8 @@ __libc_lock_define_initialized (static, lock)
|
||||
/* Prototypes for local functions. */
|
||||
static void blacklist_store_name (const char *, ent_t *);
|
||||
static int in_blacklist (const char *, int, ent_t *);
|
||||
|
||||
extern int _nss_nisplus_parse_pwent (nis_result *, struct passwd *,
|
||||
char *, size_t);
|
||||
static void
|
||||
give_pwd_free (struct passwd *pwd)
|
||||
{
|
||||
@@ -192,6 +203,18 @@ internal_setpwent (ent_t *ent)
|
||||
ent->oldkeylen = 0;
|
||||
}
|
||||
|
||||
if (ent->result != NULL)
|
||||
{
|
||||
nis_freeresult (ent->result);
|
||||
ent->result = NULL;
|
||||
}
|
||||
|
||||
if (ent->names != NULL)
|
||||
{
|
||||
nis_freenames (ent->names);
|
||||
ent->names = NULL;
|
||||
}
|
||||
ent->names_nr = 0;
|
||||
ent->blacklist.current = 0;
|
||||
if (ent->blacklist.data != NULL)
|
||||
ent->blacklist.data[0] = '\0';
|
||||
@@ -219,6 +242,12 @@ _nss_compat_setpwent (void)
|
||||
|
||||
__libc_lock_lock (lock);
|
||||
|
||||
if (ni == NULL)
|
||||
{
|
||||
__nss_database_lookup ("passwd_compat", NULL, "nis", &ni);
|
||||
use_nisplus = (strcmp (ni->name, "nisplus") == 0);
|
||||
}
|
||||
|
||||
result = internal_setpwent (&ext_ent);
|
||||
|
||||
__libc_lock_unlock (lock);
|
||||
@@ -245,6 +274,19 @@ internal_endpwent (ent_t *ent)
|
||||
ent->oldkeylen = 0;
|
||||
}
|
||||
|
||||
if (ent->result != NULL)
|
||||
{
|
||||
nis_freeresult (ent->result);
|
||||
ent->result = NULL;
|
||||
}
|
||||
|
||||
if (ent->names != NULL)
|
||||
{
|
||||
nis_freenames (ent->names);
|
||||
ent->names = NULL;
|
||||
}
|
||||
ent->names_nr = 0;
|
||||
|
||||
ent->blacklist.current = 0;
|
||||
if (ent->blacklist.data != NULL)
|
||||
ent->blacklist.data[0] = '\0';
|
||||
@@ -272,8 +314,8 @@ _nss_compat_endpwent (void)
|
||||
}
|
||||
|
||||
static enum nss_status
|
||||
getpwent_next_netgr (struct passwd *result, ent_t *ent, char *group,
|
||||
char *buffer, size_t buflen)
|
||||
getpwent_next_nis_netgr (struct passwd *result, ent_t *ent, char *group,
|
||||
char *buffer, size_t buflen)
|
||||
{
|
||||
struct parser_data *data = (void *) buffer;
|
||||
char *ypdomain, *host, *user, *domain, *outval, *p, *p2;
|
||||
@@ -290,7 +332,7 @@ getpwent_next_netgr (struct passwd *result, ent_t *ent, char *group,
|
||||
|
||||
if (ent->first == TRUE)
|
||||
{
|
||||
bzero (&ent->netgrdata, sizeof (struct __netgrent));
|
||||
memset (&ent->netgrdata, 0, sizeof (struct __netgrent));
|
||||
__internal_setnetgrent (group, &ent->netgrdata);
|
||||
ent->first = FALSE;
|
||||
}
|
||||
@@ -340,13 +382,176 @@ getpwent_next_netgr (struct passwd *result, ent_t *ent, char *group,
|
||||
return NSS_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
static enum nss_status
|
||||
getpwent_next_nisplus_netgr (struct passwd *result, ent_t *ent, char *group,
|
||||
char *buffer, size_t buflen)
|
||||
{
|
||||
char *ypdomain, *host, *user, *domain, *p2;
|
||||
int status, parse_res;
|
||||
size_t p2len;
|
||||
nis_result *nisres;
|
||||
|
||||
/* Maybe we should use domainname here ? We need the current
|
||||
domainname for the domain field in netgroups */
|
||||
if (yp_get_default_domain (&ypdomain) != YPERR_SUCCESS)
|
||||
{
|
||||
ent->netgroup = 0;
|
||||
ent->first = 0;
|
||||
give_pwd_free (&ent->pwd);
|
||||
return NSS_STATUS_UNAVAIL;
|
||||
}
|
||||
|
||||
if (ent->first == TRUE)
|
||||
{
|
||||
bzero (&ent->netgrdata, sizeof (struct __netgrent));
|
||||
__internal_setnetgrent (group, &ent->netgrdata);
|
||||
ent->first = FALSE;
|
||||
}
|
||||
|
||||
while (1)
|
||||
{
|
||||
status = __internal_getnetgrent_r (&host, &user, &domain,
|
||||
&ent->netgrdata, buffer, buflen);
|
||||
if (status != 1)
|
||||
{
|
||||
__internal_endnetgrent (&ent->netgrdata);
|
||||
ent->netgroup = 0;
|
||||
give_pwd_free (&ent->pwd);
|
||||
return NSS_STATUS_RETURN;
|
||||
}
|
||||
|
||||
if (user == NULL || user[0] == '-')
|
||||
continue;
|
||||
|
||||
if (domain != NULL && strcmp (ypdomain, domain) != 0)
|
||||
continue;
|
||||
|
||||
p2len = pwd_need_buflen (&ent->pwd);
|
||||
if (p2len > buflen)
|
||||
{
|
||||
__set_errno (ERANGE);
|
||||
return NSS_STATUS_TRYAGAIN;
|
||||
}
|
||||
p2 = buffer + (buflen - p2len);
|
||||
buflen -= p2len;
|
||||
{
|
||||
char buf[strlen (user) + 30];
|
||||
sprintf(buf, "[name=%s],passwd.org_dir", user);
|
||||
nisres = nis_list(buf, EXPAND_NAME, NULL, NULL);
|
||||
}
|
||||
if (niserr2nss (nisres->status) != NSS_STATUS_SUCCESS)
|
||||
{
|
||||
nis_freeresult (nisres);
|
||||
continue;
|
||||
}
|
||||
parse_res = _nss_nisplus_parse_pwent (nisres, result, buffer, buflen);
|
||||
nis_freeresult (nisres);
|
||||
|
||||
if (parse_res)
|
||||
{
|
||||
copy_pwd_changes (result, &ent->pwd, p2, p2len);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return NSS_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
static enum nss_status
|
||||
getpwent_next_netgr (struct passwd *result, ent_t *ent, char *group,
|
||||
char *buffer, size_t buflen)
|
||||
{
|
||||
if (use_nisplus)
|
||||
return getpwent_next_nisplus_netgr (result, ent, group, buffer, buflen);
|
||||
else
|
||||
return getpwent_next_nis_netgr (result, ent, group, buffer, buflen);
|
||||
}
|
||||
|
||||
static enum nss_status
|
||||
getpwent_next_nisplus (struct passwd *result, ent_t *ent, char *buffer,
|
||||
size_t buflen)
|
||||
{
|
||||
int parse_res;
|
||||
size_t p2len;
|
||||
char *p2;
|
||||
|
||||
if (ent->names == NULL)
|
||||
{
|
||||
ent->names = nis_getnames ("passwd.org_dir");
|
||||
if (ent->names == NULL || ent->names[0] == NULL)
|
||||
{
|
||||
ent->nis = 0;
|
||||
return NSS_STATUS_UNAVAIL;
|
||||
}
|
||||
}
|
||||
|
||||
p2len = pwd_need_buflen (&ent->pwd);
|
||||
if (p2len > buflen)
|
||||
{
|
||||
__set_errno (ERANGE);
|
||||
return NSS_STATUS_TRYAGAIN;
|
||||
}
|
||||
p2 = buffer + (buflen - p2len);
|
||||
buflen -= p2len;
|
||||
do
|
||||
{
|
||||
if (ent->first)
|
||||
{
|
||||
next_name:
|
||||
ent->result = nis_first_entry(ent->names[ent->names_nr]);
|
||||
if (niserr2nss (ent->result->status) != NSS_STATUS_SUCCESS)
|
||||
{
|
||||
ent->nis = 0;
|
||||
give_pwd_free (&ent->pwd);
|
||||
return niserr2nss (ent->result->status);
|
||||
}
|
||||
ent->first = FALSE;
|
||||
}
|
||||
else
|
||||
{
|
||||
nis_result *res;
|
||||
|
||||
res = nis_next_entry(ent->names[ent->names_nr],
|
||||
&ent->result->cookie);
|
||||
nis_freeresult (ent->result);
|
||||
ent->result = res;
|
||||
if (niserr2nss (ent->result->status) != NSS_STATUS_SUCCESS)
|
||||
{
|
||||
if ((ent->result->status == NIS_NOTFOUND) &&
|
||||
ent->names[ent->names_nr + 1] != NULL)
|
||||
{
|
||||
nis_freeresult (ent->result);
|
||||
ent->names_nr += 1;
|
||||
goto next_name;
|
||||
}
|
||||
else
|
||||
{
|
||||
ent->nis = 0;
|
||||
give_pwd_free (&ent->pwd);
|
||||
return niserr2nss (ent->result->status);
|
||||
}
|
||||
}
|
||||
}
|
||||
parse_res = _nss_nisplus_parse_pwent (ent->result, result, buffer,
|
||||
buflen);
|
||||
if (parse_res &&
|
||||
in_blacklist (result->pw_name, strlen (result->pw_name), ent))
|
||||
parse_res = 0; /* if result->pw_name in blacklist,search next entry */
|
||||
}
|
||||
while (!parse_res);
|
||||
|
||||
copy_pwd_changes (result, &ent->pwd, p2, p2len);
|
||||
|
||||
return NSS_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
static enum nss_status
|
||||
getpwent_next_nis (struct passwd *result, ent_t *ent, char *buffer,
|
||||
size_t buflen)
|
||||
{
|
||||
struct parser_data *data = (void *) buffer;
|
||||
char *domain, *outkey, *outval, *p, *p2;
|
||||
int outkeylen, outvallen;
|
||||
int outkeylen, outvallen, parse_res;
|
||||
size_t p2len;
|
||||
|
||||
if (yp_get_default_domain (&domain) != YPERR_SUCCESS)
|
||||
@@ -404,17 +609,96 @@ getpwent_next_nis (struct passwd *result, ent_t *ent, char *buffer,
|
||||
|
||||
while (isspace (*p))
|
||||
++p;
|
||||
parse_res = _nss_files_parse_pwent (p, result, data, buflen);
|
||||
if (parse_res &&
|
||||
in_blacklist (result->pw_name, strlen (result->pw_name), ent))
|
||||
parse_res = 0;
|
||||
}
|
||||
while (!_nss_files_parse_pwent (p, result, data, buflen));
|
||||
while (!parse_res);
|
||||
|
||||
copy_pwd_changes (result, &ent->pwd, p2, p2len);
|
||||
|
||||
if (!in_blacklist (result->pw_name, strlen (result->pw_name), ent))
|
||||
return NSS_STATUS_SUCCESS;
|
||||
else
|
||||
return NSS_STATUS_NOTFOUND;
|
||||
return NSS_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
/* This function handle the +user entrys in /etc/passwd */
|
||||
static enum nss_status
|
||||
getpwent_next_file_plususer (struct passwd *result, char *buffer,
|
||||
size_t buflen)
|
||||
{
|
||||
struct parser_data *data = (void *) buffer;
|
||||
struct passwd pwd;
|
||||
int parse_res;
|
||||
char *p;
|
||||
size_t plen;
|
||||
|
||||
memset (&pwd, '\0', sizeof (struct passwd));
|
||||
|
||||
copy_pwd_changes (&pwd, result, NULL, 0);
|
||||
|
||||
plen = pwd_need_buflen (&pwd);
|
||||
if (plen > buflen)
|
||||
{
|
||||
__set_errno (ERANGE);
|
||||
return NSS_STATUS_TRYAGAIN;
|
||||
}
|
||||
p = buffer + (buflen - plen);
|
||||
buflen -= plen;
|
||||
|
||||
if (use_nisplus) /* Do the NIS+ query here */
|
||||
{
|
||||
nis_result *res;
|
||||
char buf[strlen (result->pw_name) + 24];
|
||||
|
||||
sprintf(buf, "[name=%s],passwd.org_dir",
|
||||
&result->pw_name[1]);
|
||||
res = nis_list(buf, EXPAND_NAME, NULL, NULL);
|
||||
if (niserr2nss (res->status) != NSS_STATUS_SUCCESS)
|
||||
{
|
||||
enum nss_status status = niserr2nss (res->status);
|
||||
|
||||
nis_freeresult (res);
|
||||
return status;
|
||||
}
|
||||
parse_res = _nss_nisplus_parse_pwent (res, result, buffer, buflen);
|
||||
nis_freeresult (res);
|
||||
}
|
||||
else /* Use NIS */
|
||||
{
|
||||
char *domain;
|
||||
char *outval;
|
||||
int outvallen;
|
||||
|
||||
if (yp_get_default_domain (&domain) != YPERR_SUCCESS)
|
||||
return NSS_STATUS_TRYAGAIN;
|
||||
|
||||
if (yp_match (domain, "passwd.byname", &result->pw_name[1],
|
||||
strlen (result->pw_name) - 1, &outval, &outvallen)
|
||||
!= YPERR_SUCCESS)
|
||||
return NSS_STATUS_TRYAGAIN;
|
||||
p = strncpy (buffer, outval,
|
||||
buflen < (size_t) outvallen ? buflen : (size_t) outvallen);
|
||||
free (outval);
|
||||
while (isspace (*p))
|
||||
p++;
|
||||
parse_res = _nss_files_parse_pwent (p, result, data, buflen);
|
||||
}
|
||||
|
||||
if (parse_res)
|
||||
{
|
||||
copy_pwd_changes (result, &pwd, p, plen);
|
||||
give_pwd_free (&pwd);
|
||||
/* We found the entry. */
|
||||
return NSS_STATUS_SUCCESS;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Give buffer the old len back */
|
||||
buflen += plen;
|
||||
give_pwd_free (&pwd);
|
||||
}
|
||||
return NSS_STATUS_RETURN;
|
||||
}
|
||||
|
||||
static enum nss_status
|
||||
getpwent_next_file (struct passwd *result, ent_t *ent,
|
||||
@@ -423,8 +707,7 @@ getpwent_next_file (struct passwd *result, ent_t *ent,
|
||||
struct parser_data *data = (void *) buffer;
|
||||
while (1)
|
||||
{
|
||||
char *p, *p2;
|
||||
size_t p2len;
|
||||
char *p;
|
||||
|
||||
do
|
||||
{
|
||||
@@ -452,15 +735,19 @@ getpwent_next_file (struct passwd *result, ent_t *ent,
|
||||
if (result->pw_name[0] == '-' && result->pw_name[1] == '@'
|
||||
&& result->pw_name[2] != '\0')
|
||||
{
|
||||
char buf2[1024];
|
||||
char *user, *host, *domain;
|
||||
struct __netgrent netgrdata;
|
||||
|
||||
setnetgrent (&result->pw_name[2]);
|
||||
while (getnetgrent (&host, &user, &domain))
|
||||
bzero (&netgrdata, sizeof (struct __netgrent));
|
||||
__internal_setnetgrent (&result->pw_name[2], &netgrdata);
|
||||
while (__internal_getnetgrent_r (&host, &user, &domain,
|
||||
&netgrdata, buf2, sizeof (buf2)))
|
||||
{
|
||||
if (user != NULL && user[0] != '-')
|
||||
blacklist_store_name (user, ent);
|
||||
}
|
||||
endnetgrent ();
|
||||
__internal_endnetgrent (&netgrdata);
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -494,50 +781,16 @@ getpwent_next_file (struct passwd *result, ent_t *ent,
|
||||
if (result->pw_name[0] == '+' && result->pw_name[1] != '\0'
|
||||
&& result->pw_name[1] != '@')
|
||||
{
|
||||
char *domain;
|
||||
char *outval;
|
||||
int outvallen;
|
||||
struct passwd pwd;
|
||||
enum nss_status status;
|
||||
|
||||
memset (&pwd, '\0', sizeof (struct passwd));
|
||||
|
||||
if (yp_get_default_domain (&domain) != YPERR_SUCCESS)
|
||||
/* XXX Should we regard this as an fatal error? I don't
|
||||
think so. Just continue working. --drepper@gnu */
|
||||
continue;
|
||||
|
||||
if (yp_match (domain, "passwd.byname", &result->pw_name[1],
|
||||
strlen (result->pw_name) - 1, &outval, &outvallen)
|
||||
!= YPERR_SUCCESS)
|
||||
continue;
|
||||
|
||||
copy_pwd_changes (&pwd, result, NULL, 0);
|
||||
|
||||
p2len = pwd_need_buflen (&pwd);
|
||||
if (p2len > buflen)
|
||||
{
|
||||
__set_errno (ERANGE);
|
||||
return NSS_STATUS_TRYAGAIN;
|
||||
}
|
||||
p2 = buffer + (buflen - p2len);
|
||||
buflen -= p2len;
|
||||
p = strncpy (buffer, outval, buflen);
|
||||
while (isspace (*p))
|
||||
p++;
|
||||
free (outval);
|
||||
if (_nss_files_parse_pwent (p, result, data, buflen))
|
||||
{
|
||||
copy_pwd_changes (result, &pwd, p2, p2len);
|
||||
give_pwd_free (&pwd);
|
||||
/* We found the entry. */
|
||||
break;
|
||||
}
|
||||
status = getpwent_next_file_plususer (result, buffer, buflen);
|
||||
if (status == NSS_STATUS_SUCCESS) /* We found the entry. */
|
||||
break;
|
||||
else
|
||||
{
|
||||
/* Give buffer the old len back */
|
||||
buflen += p2len;
|
||||
give_pwd_free (&pwd);
|
||||
}
|
||||
if (status == NSS_STATUS_RETURN) /* We couldn't parse the entry */
|
||||
continue;
|
||||
else
|
||||
return status;
|
||||
}
|
||||
|
||||
/* +:... */
|
||||
@@ -547,7 +800,10 @@ getpwent_next_file (struct passwd *result, ent_t *ent,
|
||||
ent->first = TRUE;
|
||||
copy_pwd_changes (&ent->pwd, result, NULL, 0);
|
||||
|
||||
return getpwent_next_nis (result, ent, buffer, buflen);
|
||||
if (use_nisplus)
|
||||
return getpwent_next_nisplus (result, ent, buffer, buflen);
|
||||
else
|
||||
return getpwent_next_nis (result, ent, buffer, buflen);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -572,7 +828,12 @@ internal_getpwent_r (struct passwd *pw, ent_t *ent, char *buffer,
|
||||
return status;
|
||||
}
|
||||
else if (ent->nis)
|
||||
return getpwent_next_nis (pw, ent, buffer, buflen);
|
||||
{
|
||||
if (use_nisplus)
|
||||
return getpwent_next_nisplus (pw, ent, buffer, buflen);
|
||||
else
|
||||
return getpwent_next_nis (pw, ent, buffer, buflen);
|
||||
}
|
||||
else
|
||||
return getpwent_next_file (pw, ent, buffer, buflen);
|
||||
}
|
||||
@@ -585,6 +846,12 @@ _nss_compat_getpwent_r (struct passwd *pwd, char *buffer,
|
||||
|
||||
__libc_lock_lock (lock);
|
||||
|
||||
if (ni == NULL)
|
||||
{
|
||||
__nss_database_lookup ("passwd_compat", NULL, "nis", &ni);
|
||||
use_nisplus = (strcmp (ni->name, "nisplus") == 0);
|
||||
}
|
||||
|
||||
/* Be prepared that the setpwent function was not called before. */
|
||||
if (ext_ent.stream == NULL)
|
||||
status = internal_setpwent (&ext_ent);
|
||||
@@ -602,13 +869,22 @@ enum nss_status
|
||||
_nss_compat_getpwnam_r (const char *name, struct passwd *pwd,
|
||||
char *buffer, size_t buflen)
|
||||
{
|
||||
ent_t ent = {0, 0, 0, NULL, 0, NULL, {NULL, 0, 0},
|
||||
ent_t ent = {0, 0, 0, NULL, 0, NULL, NULL, 0, NULL, {NULL, 0, 0},
|
||||
{NULL, NULL, 0, 0, NULL, NULL, NULL}};
|
||||
enum nss_status status;
|
||||
|
||||
if (name[0] == '-' || name[0] == '+')
|
||||
return NSS_STATUS_NOTFOUND;
|
||||
|
||||
__libc_lock_lock (lock);
|
||||
|
||||
if (ni == NULL)
|
||||
{
|
||||
__nss_database_lookup ("passwd_compat", NULL, "nis", &ni);
|
||||
use_nisplus = (strcmp (ni->name, "nisplus") == 0);
|
||||
}
|
||||
|
||||
__libc_lock_unlock (lock);
|
||||
|
||||
status = internal_setpwent (&ent);
|
||||
if (status != NSS_STATUS_SUCCESS)
|
||||
@@ -628,10 +904,20 @@ enum nss_status
|
||||
_nss_compat_getpwuid_r (uid_t uid, struct passwd *pwd,
|
||||
char *buffer, size_t buflen)
|
||||
{
|
||||
ent_t ent = {0, 0, 0, NULL, 0, NULL, {NULL, 0, 0},
|
||||
ent_t ent = {0, 0, 0, NULL, 0, NULL, NULL, 0, NULL, {NULL, 0, 0},
|
||||
{NULL, NULL, 0, 0, NULL, NULL, NULL}};
|
||||
enum nss_status status;
|
||||
|
||||
__libc_lock_lock (lock);
|
||||
|
||||
if (ni == NULL)
|
||||
{
|
||||
__nss_database_lookup ("passwd_compat", NULL, "nis", &ni);
|
||||
use_nisplus = (strcmp (ni->name, "nisplus") == 0);
|
||||
}
|
||||
|
||||
__libc_lock_unlock (lock);
|
||||
|
||||
status = internal_setpwent (&ent);
|
||||
if (status != NSS_STATUS_SUCCESS)
|
||||
return status;
|
||||
@@ -697,10 +983,14 @@ static bool_t
|
||||
in_blacklist (const char *name, int namelen, ent_t *ent)
|
||||
{
|
||||
char buf[namelen + 3];
|
||||
char *cp;
|
||||
|
||||
if (ent->blacklist.data == NULL)
|
||||
return FALSE;
|
||||
|
||||
stpcpy (stpcpy (stpcpy (buf, "|"), name), "|");
|
||||
buf[0] = '|';
|
||||
cp = stpcpy (&buf[1], name);
|
||||
*cp++= '|';
|
||||
*cp = '\0';
|
||||
return strstr (ent->blacklist.data, buf) != NULL;
|
||||
}
|
||||
|
||||
+360
-70
@@ -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 Thorsten Kukuk <kukuk@vt.uni-paderborn.de>, 1996.
|
||||
|
||||
@@ -26,6 +26,15 @@
|
||||
#include <libc-lock.h>
|
||||
#include <rpcsvc/yp.h>
|
||||
#include <rpcsvc/ypclnt.h>
|
||||
#include <rpcsvc/nis.h>
|
||||
#include <rpcsvc/nislib.h>
|
||||
#include <nsswitch.h>
|
||||
|
||||
#include "netgroup.h"
|
||||
#include "nss-nisplus.h"
|
||||
|
||||
static service_user *ni = NULL;
|
||||
static bool_t use_nisplus = FALSE; /* default: passwd_compat: nis */
|
||||
|
||||
/* Get the declaration of the parser function. */
|
||||
#define ENTNAME spent
|
||||
@@ -50,13 +59,17 @@ struct ent_t
|
||||
bool_t first;
|
||||
char *oldkey;
|
||||
int oldkeylen;
|
||||
nis_result *result;
|
||||
nis_name *names;
|
||||
u_long names_nr;
|
||||
FILE *stream;
|
||||
struct blacklist_t blacklist;
|
||||
struct spwd pwd;
|
||||
struct __netgrent netgrdata;
|
||||
};
|
||||
typedef struct ent_t ent_t;
|
||||
|
||||
static ent_t ext_ent = {0, 0, 0, NULL, 0, NULL, {NULL, 0, 0},
|
||||
static ent_t ext_ent = {0, 0, 0, NULL, 0, NULL, NULL, 0, NULL, {NULL, 0, 0},
|
||||
{NULL, NULL, 0, 0, 0, 0, 0, 0, 0}};
|
||||
|
||||
/* Protect global state against multiple changers. */
|
||||
@@ -65,7 +78,8 @@ __libc_lock_define_initialized (static, lock)
|
||||
/* Prototypes for local functions. */
|
||||
static void blacklist_store_name (const char *, ent_t *);
|
||||
static int in_blacklist (const char *, int, ent_t *);
|
||||
|
||||
extern int _nss_nisplus_parse_spent (nis_result *, struct spwd *,
|
||||
char *, size_t);
|
||||
static void
|
||||
give_spwd_free (struct spwd *pwd)
|
||||
{
|
||||
@@ -130,6 +144,10 @@ internal_setspent (ent_t *ent)
|
||||
|
||||
ent->nis = ent->first = ent->netgroup = 0;
|
||||
|
||||
/* If something was left over free it. */
|
||||
if (ent->netgroup)
|
||||
__internal_endnetgrent (&ent->netgrdata);
|
||||
|
||||
if (ent->oldkey != NULL)
|
||||
{
|
||||
free (ent->oldkey);
|
||||
@@ -137,6 +155,18 @@ internal_setspent (ent_t *ent)
|
||||
ent->oldkeylen = 0;
|
||||
}
|
||||
|
||||
if (ent->result != NULL)
|
||||
{
|
||||
nis_freeresult (ent->result);
|
||||
ent->result = NULL;
|
||||
}
|
||||
if (ent->names != NULL)
|
||||
{
|
||||
nis_freenames (ent->names);
|
||||
ent->names = NULL;
|
||||
}
|
||||
ent->names_nr = 0;
|
||||
|
||||
ent->blacklist.current = 0;
|
||||
if (ent->blacklist.data != NULL)
|
||||
ent->blacklist.data[0] = '\0';
|
||||
@@ -164,6 +194,12 @@ _nss_compat_setspent (void)
|
||||
|
||||
__libc_lock_lock (lock);
|
||||
|
||||
if (ni == NULL)
|
||||
{
|
||||
__nss_database_lookup ("shadow_compat", "passwd_compat", "nis", &ni);
|
||||
use_nisplus = (strcmp (ni->name, "nisplus") == 0);
|
||||
}
|
||||
|
||||
result = internal_setspent (&ext_ent);
|
||||
|
||||
__libc_lock_unlock (lock);
|
||||
@@ -181,6 +217,9 @@ internal_endspent (ent_t *ent)
|
||||
ent->stream = NULL;
|
||||
}
|
||||
|
||||
if (ent->netgroup)
|
||||
__internal_endnetgrent (&ent->netgrdata);
|
||||
|
||||
ent->nis = ent->first = ent->netgroup = 0;
|
||||
|
||||
if (ent->oldkey != NULL)
|
||||
@@ -190,6 +229,18 @@ internal_endspent (ent_t *ent)
|
||||
ent->oldkeylen = 0;
|
||||
}
|
||||
|
||||
if (ent->result != NULL)
|
||||
{
|
||||
nis_freeresult (ent->result);
|
||||
ent->result = NULL;
|
||||
}
|
||||
if (ent->names != NULL)
|
||||
{
|
||||
nis_freenames (ent->names);
|
||||
ent->names = NULL;
|
||||
}
|
||||
ent->names_nr = 0;
|
||||
|
||||
ent->blacklist.current = 0;
|
||||
if (ent->blacklist.data != NULL)
|
||||
ent->blacklist.data[0] = '\0';
|
||||
@@ -215,8 +266,8 @@ _nss_compat_endspent (void)
|
||||
|
||||
|
||||
static enum nss_status
|
||||
getspent_next_netgr (struct spwd *result, ent_t *ent, char *group,
|
||||
char *buffer, size_t buflen)
|
||||
getspent_next_nis_netgr (struct spwd *result, ent_t *ent, char *group,
|
||||
char *buffer, size_t buflen)
|
||||
{
|
||||
struct parser_data *data = (void *) buffer;
|
||||
char *ypdomain, *host, *user, *domain, *outval, *p, *p2;
|
||||
@@ -233,15 +284,18 @@ getspent_next_netgr (struct spwd *result, ent_t *ent, char *group,
|
||||
|
||||
if (ent->first == TRUE)
|
||||
{
|
||||
setnetgrent (group);
|
||||
bzero (&ent->netgrdata, sizeof (struct __netgrent));
|
||||
__internal_setnetgrent (group, &ent->netgrdata);
|
||||
ent->first = FALSE;
|
||||
}
|
||||
|
||||
while (1)
|
||||
{
|
||||
if ((status = getnetgrent (&host, &user, &domain)) != 1)
|
||||
status = __internal_getnetgrent_r (&host, &user, &domain,
|
||||
&ent->netgrdata, buffer, buflen);
|
||||
if (status != 1)
|
||||
{
|
||||
endnetgrent ();
|
||||
__internal_endnetgrent (&ent->netgrdata);
|
||||
ent->netgroup = 0;
|
||||
give_spwd_free (&ent->pwd);
|
||||
return NSS_STATUS_RETURN;
|
||||
@@ -280,13 +334,177 @@ getspent_next_netgr (struct spwd *result, ent_t *ent, char *group,
|
||||
return NSS_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
static enum nss_status
|
||||
getspent_next_nisplus_netgr (struct spwd *result, ent_t *ent, char *group,
|
||||
char *buffer, size_t buflen)
|
||||
{
|
||||
char *ypdomain, *host, *user, *domain, *p2;
|
||||
int status, parse_res;
|
||||
size_t p2len;
|
||||
nis_result *nisres;
|
||||
|
||||
/* Maybe we should use domainname here ? We need the current
|
||||
domainname for the domain field in netgroups */
|
||||
if (yp_get_default_domain (&ypdomain) != YPERR_SUCCESS)
|
||||
{
|
||||
ent->netgroup = 0;
|
||||
ent->first = 0;
|
||||
give_spwd_free (&ent->pwd);
|
||||
return NSS_STATUS_UNAVAIL;
|
||||
}
|
||||
|
||||
if (ent->first == TRUE)
|
||||
{
|
||||
bzero (&ent->netgrdata, sizeof (struct __netgrent));
|
||||
__internal_setnetgrent (group, &ent->netgrdata);
|
||||
ent->first = FALSE;
|
||||
}
|
||||
|
||||
while (1)
|
||||
{
|
||||
status = __internal_getnetgrent_r (&host, &user, &domain,
|
||||
&ent->netgrdata, buffer, buflen);
|
||||
if (status != 1)
|
||||
{
|
||||
__internal_endnetgrent (&ent->netgrdata);
|
||||
ent->netgroup = 0;
|
||||
give_spwd_free (&ent->pwd);
|
||||
return NSS_STATUS_RETURN;
|
||||
}
|
||||
|
||||
if (user == NULL || user[0] == '-')
|
||||
continue;
|
||||
|
||||
if (domain != NULL && strcmp (ypdomain, domain) != 0)
|
||||
continue;
|
||||
|
||||
p2len = spwd_need_buflen (&ent->pwd);
|
||||
if (p2len > buflen)
|
||||
{
|
||||
__set_errno (ERANGE);
|
||||
return NSS_STATUS_TRYAGAIN;
|
||||
}
|
||||
p2 = buffer + (buflen - p2len);
|
||||
buflen -= p2len;
|
||||
{
|
||||
char buf[strlen (user) + 30];
|
||||
sprintf(buf, "[name=%s],passwd.org_dir", user);
|
||||
nisres = nis_list(buf, EXPAND_NAME, NULL, NULL);
|
||||
}
|
||||
if (niserr2nss (nisres->status) != NSS_STATUS_SUCCESS)
|
||||
{
|
||||
nis_freeresult (nisres);
|
||||
continue;
|
||||
}
|
||||
parse_res = _nss_nisplus_parse_spent (nisres, result, buffer, buflen);
|
||||
nis_freeresult (nisres);
|
||||
|
||||
if (parse_res)
|
||||
{
|
||||
copy_spwd_changes (result, &ent->pwd, p2, p2len);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return NSS_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
static enum nss_status
|
||||
getspent_next_netgr (struct spwd *result, ent_t *ent, char *group,
|
||||
char *buffer, size_t buflen)
|
||||
{
|
||||
if (use_nisplus)
|
||||
return getspent_next_nisplus_netgr (result, ent, group, buffer, buflen);
|
||||
else
|
||||
return getspent_next_nis_netgr (result, ent, group, buffer, buflen);
|
||||
}
|
||||
|
||||
static enum nss_status
|
||||
getspent_next_nisplus (struct spwd *result, ent_t *ent, char *buffer,
|
||||
size_t buflen)
|
||||
{
|
||||
int parse_res;
|
||||
size_t p2len;
|
||||
char *p2;
|
||||
|
||||
if (ent->names == NULL)
|
||||
{
|
||||
ent->names = nis_getnames ("passwd.org_dir");
|
||||
if (ent->names == NULL || ent->names[0] == NULL)
|
||||
{
|
||||
ent->nis = 0;
|
||||
return NSS_STATUS_UNAVAIL;
|
||||
}
|
||||
}
|
||||
|
||||
p2len = spwd_need_buflen (&ent->pwd);
|
||||
if (p2len > buflen)
|
||||
{
|
||||
__set_errno (ERANGE);
|
||||
return NSS_STATUS_TRYAGAIN;
|
||||
}
|
||||
p2 = buffer + (buflen - p2len);
|
||||
buflen -= p2len;
|
||||
do
|
||||
{
|
||||
if (ent->first)
|
||||
{
|
||||
next_name:
|
||||
ent->result = nis_first_entry(ent->names[ent->names_nr]);
|
||||
if (niserr2nss (ent->result->status) != NSS_STATUS_SUCCESS)
|
||||
{
|
||||
ent->nis = 0;
|
||||
give_spwd_free (&ent->pwd);
|
||||
return niserr2nss (ent->result->status);
|
||||
}
|
||||
ent->first = FALSE;
|
||||
}
|
||||
else
|
||||
{
|
||||
nis_result *res;
|
||||
|
||||
res = nis_next_entry(ent->names[ent->names_nr],
|
||||
&ent->result->cookie);
|
||||
nis_freeresult (ent->result);
|
||||
ent->result = res;
|
||||
if (niserr2nss (ent->result->status) != NSS_STATUS_SUCCESS)
|
||||
{
|
||||
if ((ent->result->status == NIS_NOTFOUND) &&
|
||||
ent->names[ent->names_nr + 1] != NULL)
|
||||
{
|
||||
nis_freeresult (ent->result);
|
||||
ent->names_nr += 1;
|
||||
goto next_name;
|
||||
}
|
||||
else
|
||||
{
|
||||
ent->nis = 0;
|
||||
give_spwd_free (&ent->pwd);
|
||||
return niserr2nss (ent->result->status);
|
||||
}
|
||||
}
|
||||
}
|
||||
parse_res = _nss_nisplus_parse_spent (ent->result, result, buffer,
|
||||
buflen);
|
||||
if (parse_res &&
|
||||
in_blacklist (result->sp_namp, strlen (result->sp_namp), ent))
|
||||
parse_res = 0; /* if result->pw_name in blacklist,search next entry */
|
||||
}
|
||||
while (!parse_res);
|
||||
|
||||
copy_spwd_changes (result, &ent->pwd, p2, p2len);
|
||||
|
||||
return NSS_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
static enum nss_status
|
||||
getspent_next_nis (struct spwd *result, ent_t *ent,
|
||||
char *buffer, size_t buflen)
|
||||
{
|
||||
struct parser_data *data = (void *) buffer;
|
||||
char *domain, *outkey, *outval, *p, *p2;
|
||||
int outkeylen, outvallen;
|
||||
int outkeylen, outvallen, parse_res;
|
||||
size_t p2len;
|
||||
|
||||
if (yp_get_default_domain (&domain) != YPERR_SUCCESS)
|
||||
@@ -344,17 +562,96 @@ getspent_next_nis (struct spwd *result, ent_t *ent,
|
||||
|
||||
while (isspace (*p))
|
||||
++p;
|
||||
parse_res = _nss_files_parse_spent (p, result, data, buflen);
|
||||
if (parse_res &&
|
||||
in_blacklist (result->sp_namp, strlen (result->sp_namp), ent))
|
||||
parse_res = 0;
|
||||
}
|
||||
while (!_nss_files_parse_spent (p, result, data, buflen));
|
||||
while (!parse_res);
|
||||
|
||||
copy_spwd_changes (result, &ent->pwd, p2, p2len);
|
||||
|
||||
if (!in_blacklist (result->sp_namp, strlen (result->sp_namp), ent))
|
||||
return NSS_STATUS_SUCCESS;
|
||||
else
|
||||
return NSS_STATUS_NOTFOUND;
|
||||
return NSS_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
/* This function handle the +user entrys in /etc/shadow */
|
||||
static enum nss_status
|
||||
getspent_next_file_plususer (struct spwd *result, char *buffer,
|
||||
size_t buflen)
|
||||
{
|
||||
struct parser_data *data = (void *) buffer;
|
||||
struct spwd pwd;
|
||||
int parse_res;
|
||||
char *p;
|
||||
size_t plen;
|
||||
|
||||
memset (&pwd, '\0', sizeof (struct spwd));
|
||||
|
||||
copy_spwd_changes (&pwd, result, NULL, 0);
|
||||
|
||||
plen = spwd_need_buflen (&pwd);
|
||||
if (plen > buflen)
|
||||
{
|
||||
__set_errno (ERANGE);
|
||||
return NSS_STATUS_TRYAGAIN;
|
||||
}
|
||||
p = buffer + (buflen - plen);
|
||||
buflen -= plen;
|
||||
|
||||
if (use_nisplus) /* Do the NIS+ query here */
|
||||
{
|
||||
nis_result *res;
|
||||
char buf[strlen (result->sp_namp) + 24];
|
||||
|
||||
sprintf(buf, "[name=%s],passwd.org_dir",
|
||||
&result->sp_namp[1]);
|
||||
res = nis_list(buf, EXPAND_NAME, NULL, NULL);
|
||||
if (niserr2nss (res->status) != NSS_STATUS_SUCCESS)
|
||||
{
|
||||
enum nss_status status = niserr2nss (res->status);
|
||||
|
||||
nis_freeresult (res);
|
||||
return status;
|
||||
}
|
||||
parse_res = _nss_nisplus_parse_spent (res, result, buffer, buflen);
|
||||
nis_freeresult (res);
|
||||
}
|
||||
else /* Use NIS */
|
||||
{
|
||||
char *domain;
|
||||
char *outval;
|
||||
int outvallen;
|
||||
|
||||
if (yp_get_default_domain (&domain) != YPERR_SUCCESS)
|
||||
return NSS_STATUS_TRYAGAIN;
|
||||
|
||||
if (yp_match (domain, "passwd.byname", &result->sp_namp[1],
|
||||
strlen (result->sp_namp) - 1, &outval, &outvallen)
|
||||
!= YPERR_SUCCESS)
|
||||
return NSS_STATUS_TRYAGAIN;
|
||||
p = strncpy (buffer, outval,
|
||||
buflen < (size_t) outvallen ? buflen : (size_t) outvallen);
|
||||
free (outval);
|
||||
while (isspace (*p))
|
||||
p++;
|
||||
parse_res = _nss_files_parse_spent (p, result, data, buflen);
|
||||
}
|
||||
|
||||
if (parse_res)
|
||||
{
|
||||
copy_spwd_changes (result, &pwd, p, plen);
|
||||
give_spwd_free (&pwd);
|
||||
/* We found the entry. */
|
||||
return NSS_STATUS_SUCCESS;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Give buffer the old len back */
|
||||
buflen += plen;
|
||||
give_spwd_free (&pwd);
|
||||
}
|
||||
return NSS_STATUS_RETURN;
|
||||
}
|
||||
|
||||
static enum nss_status
|
||||
getspent_next_file (struct spwd *result, ent_t *ent,
|
||||
@@ -363,8 +660,7 @@ getspent_next_file (struct spwd *result, ent_t *ent,
|
||||
struct parser_data *data = (void *) buffer;
|
||||
while (1)
|
||||
{
|
||||
char *p, *p2;
|
||||
size_t p2len;
|
||||
char *p;
|
||||
|
||||
do
|
||||
{
|
||||
@@ -379,10 +675,10 @@ getspent_next_file (struct spwd *result, ent_t *ent,
|
||||
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. */
|
||||
!_nss_files_parse_spent (p, result, data, buflen));
|
||||
|| !_nss_files_parse_spent (p, result, data, buflen));
|
||||
|
||||
if (result->sp_namp[0] != '+' && result->sp_namp[0] != '-')
|
||||
/* This is a real entry. */
|
||||
@@ -392,15 +688,19 @@ getspent_next_file (struct spwd *result, ent_t *ent,
|
||||
if (result->sp_namp[0] == '-' && result->sp_namp[1] == '@'
|
||||
&& result->sp_namp[2] != '\0')
|
||||
{
|
||||
char *user, *host, *domain;
|
||||
char buf2[1024];
|
||||
char *user, *host, *domain;
|
||||
struct __netgrent netgrdata;
|
||||
|
||||
setnetgrent (&result->sp_namp[2]);
|
||||
while (getnetgrent (&host, &user, &domain))
|
||||
bzero (&netgrdata, sizeof (struct __netgrent));
|
||||
__internal_setnetgrent (&result->sp_namp[2], &netgrdata);
|
||||
while (__internal_getnetgrent_r (&host, &user, &domain,
|
||||
&netgrdata, buf2, sizeof (buf2)))
|
||||
{
|
||||
if (user != NULL && user[0] != '-')
|
||||
blacklist_store_name (user, ent);
|
||||
}
|
||||
endnetgrent ();
|
||||
__internal_endnetgrent (&netgrdata);
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -434,50 +734,16 @@ getspent_next_file (struct spwd *result, ent_t *ent,
|
||||
if (result->sp_namp[0] == '+' && result->sp_namp[1] != '\0'
|
||||
&& result->sp_namp[1] != '@')
|
||||
{
|
||||
char *domain;
|
||||
char *outval;
|
||||
int outvallen;
|
||||
struct spwd pwd;
|
||||
enum nss_status status;
|
||||
|
||||
memset (&pwd, '\0', sizeof (struct spwd));
|
||||
|
||||
if (yp_get_default_domain (&domain) != YPERR_SUCCESS)
|
||||
/* XXX Should we regard this as an fatal error? I don't
|
||||
think so. Just continue working. --drepper@gnu */
|
||||
continue;
|
||||
|
||||
if (yp_match (domain, "shadow.byname", &result->sp_namp[1],
|
||||
strlen (result->sp_namp) - 1, &outval, &outvallen)
|
||||
!= YPERR_SUCCESS)
|
||||
continue;
|
||||
|
||||
copy_spwd_changes (&pwd, result, NULL, 0);
|
||||
|
||||
p2len = spwd_need_buflen (&pwd);
|
||||
if (p2len > buflen)
|
||||
{
|
||||
__set_errno (ERANGE);
|
||||
return NSS_STATUS_TRYAGAIN;
|
||||
}
|
||||
p2 = buffer + (buflen - p2len);
|
||||
buflen -= p2len;
|
||||
p = strncpy (buffer, outval, buflen);
|
||||
while (isspace (*p))
|
||||
p++;
|
||||
free (outval);
|
||||
if (_nss_files_parse_spent (p, result, data, buflen))
|
||||
{
|
||||
copy_spwd_changes (result, &pwd, p2, p2len);
|
||||
give_spwd_free (&pwd);
|
||||
/* We found the entry. */
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Give buffer the old len back */
|
||||
buflen += p2len;
|
||||
give_spwd_free (&pwd);
|
||||
}
|
||||
status = getspent_next_file_plususer (result, buffer, buflen);
|
||||
if (status == NSS_STATUS_SUCCESS) /* We found the entry. */
|
||||
break;
|
||||
else
|
||||
if (status == NSS_STATUS_RETURN) /* We couldn't parse the entry */
|
||||
continue;
|
||||
else
|
||||
return status;
|
||||
}
|
||||
|
||||
/* +:... */
|
||||
@@ -487,7 +753,10 @@ getspent_next_file (struct spwd *result, ent_t *ent,
|
||||
ent->first = TRUE;
|
||||
copy_spwd_changes (&ent->pwd, result, NULL, 0);
|
||||
|
||||
return getspent_next_nis (result, ent, buffer, buflen);
|
||||
if (use_nisplus)
|
||||
return getspent_next_nisplus (result, ent, buffer, buflen);
|
||||
else
|
||||
return getspent_next_nis (result, ent, buffer, buflen);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -512,7 +781,12 @@ internal_getspent_r (struct spwd *pw, ent_t *ent,
|
||||
return status;
|
||||
}
|
||||
else if (ent->nis)
|
||||
return getspent_next_nis (pw, ent, buffer, buflen);
|
||||
{
|
||||
if (use_nisplus)
|
||||
return getspent_next_nisplus (pw, ent, buffer, buflen);
|
||||
else
|
||||
return getspent_next_nis (pw, ent, buffer, buflen);
|
||||
}
|
||||
else
|
||||
return getspent_next_file (pw, ent, buffer, buflen);
|
||||
}
|
||||
@@ -524,6 +798,12 @@ _nss_compat_getspent_r (struct spwd *pwd, char *buffer, size_t buflen)
|
||||
|
||||
__libc_lock_lock (lock);
|
||||
|
||||
if (ni == NULL)
|
||||
{
|
||||
__nss_database_lookup ("shadow_compat", "passwd_compat", "nis", &ni);
|
||||
use_nisplus = (strcmp (ni->name, "nisplus") == 0);
|
||||
}
|
||||
|
||||
/* Be prepared that the setspent function was not called before. */
|
||||
if (ext_ent.stream == NULL)
|
||||
status = internal_setspent (&ext_ent);
|
||||
@@ -541,13 +821,19 @@ enum nss_status
|
||||
_nss_compat_getspnam_r (const char *name, struct spwd *pwd,
|
||||
char *buffer, size_t buflen)
|
||||
{
|
||||
ent_t ent = {0, 0, 0, NULL, 0, NULL, {NULL, 0, 0},
|
||||
ent_t ent = {0, 0, 0, NULL, 0, NULL, NULL, 0, NULL, {NULL, 0, 0},
|
||||
{NULL, NULL, 0, 0, 0, 0, 0, 0, 0}};
|
||||
enum nss_status status;
|
||||
|
||||
if (name[0] == '-' || name[0] == '+')
|
||||
return NSS_STATUS_NOTFOUND;
|
||||
|
||||
if (ni == NULL)
|
||||
{
|
||||
__nss_database_lookup ("shadow_compat", "passwd_compat", "nis", &ni);
|
||||
use_nisplus = (strcmp (ni->name, "nisplus") == 0);
|
||||
}
|
||||
|
||||
status = internal_setspent (&ent);
|
||||
if (status != NSS_STATUS_SUCCESS)
|
||||
return status;
|
||||
@@ -607,15 +893,19 @@ blacklist_store_name (const char *name, ent_t *ent)
|
||||
return;
|
||||
}
|
||||
|
||||
/* returns TRUE if ent->blacklist contains name, else FALSE */
|
||||
/* Returns TRUE if ent->blacklist contains name, else FALSE. */
|
||||
static bool_t
|
||||
in_blacklist (const char *name, int namelen, ent_t *ent)
|
||||
{
|
||||
char buf[namelen + 3];
|
||||
char *cp;
|
||||
|
||||
if (ent->blacklist.data == NULL)
|
||||
return FALSE;
|
||||
|
||||
stpcpy (stpcpy (stpcpy (buf, "|"), name), "|");
|
||||
buf[0] = '|';
|
||||
cp = stpcpy (&buf[1], name);
|
||||
*cp++= '|';
|
||||
*cp = '\0';
|
||||
return strstr (ent->blacklist.data, buf) != NULL;
|
||||
}
|
||||
|
||||
@@ -122,7 +122,7 @@ internal_nis_getgrent_r (struct group *grp, char *buffer, size_t buflen)
|
||||
free (result);
|
||||
|
||||
parse_res = _nss_files_parse_grent (p, grp, data, buflen);
|
||||
if (!parse_res && errno == ERANGE)
|
||||
if (parse_res < 1 && errno == ERANGE)
|
||||
return NSS_STATUS_TRYAGAIN;
|
||||
|
||||
free (oldkey);
|
||||
@@ -130,7 +130,7 @@ internal_nis_getgrent_r (struct group *grp, char *buffer, size_t buflen)
|
||||
oldkeylen = keylen;
|
||||
new_start = 0;
|
||||
}
|
||||
while (!parse_res);
|
||||
while (parse_res < 1);
|
||||
|
||||
return NSS_STATUS_SUCCESS;
|
||||
}
|
||||
@@ -192,7 +192,7 @@ _nss_nis_getgrnam_r (const char *name, struct group *grp,
|
||||
|
||||
parse_res = _nss_files_parse_grent (p, grp, data, buflen);
|
||||
|
||||
if (!parse_res)
|
||||
if (parse_res < 1)
|
||||
{
|
||||
if (errno == ERANGE)
|
||||
return NSS_STATUS_TRYAGAIN;
|
||||
@@ -243,7 +243,7 @@ _nss_nis_getgrgid_r (gid_t gid, struct group *grp,
|
||||
|
||||
parse_res = _nss_files_parse_grent (p, grp, data, buflen);
|
||||
|
||||
if (!parse_res)
|
||||
if (parse_res < 1)
|
||||
{
|
||||
if (errno == ERANGE)
|
||||
return NSS_STATUS_TRYAGAIN;
|
||||
|
||||
@@ -23,22 +23,24 @@
|
||||
#include <string.h>
|
||||
#include <syslog.h>
|
||||
#include <libc-lock.h>
|
||||
#include <rpc/key_prot.h>
|
||||
#include <rpc/rpc.h>
|
||||
#include <rpcsvc/yp.h>
|
||||
#include <rpcsvc/ypclnt.h>
|
||||
#if defined (HAVE_SECURE_RPC)
|
||||
#include <rpc/key_prot.h>
|
||||
extern int xdecrypt (char *, char *);
|
||||
#endif
|
||||
|
||||
#include "nss-nis.h"
|
||||
|
||||
extern int xdecrypt (char *, char *);
|
||||
|
||||
/* If we found the entry, we give a SUCCESS and an empty key back. */
|
||||
/* If we haven't found the entry, we give a SUCCESS and an empty key back. */
|
||||
enum nss_status
|
||||
_nss_nis_getpublickey (const char *netname, char *pkey)
|
||||
{
|
||||
enum nss_status retval;
|
||||
char *domain, *result;
|
||||
int len;
|
||||
|
||||
|
||||
pkey[0] = 0;
|
||||
|
||||
if (netname == NULL)
|
||||
@@ -75,6 +77,7 @@ _nss_nis_getpublickey (const char *netname, char *pkey)
|
||||
enum nss_status
|
||||
_nss_nis_getsecretkey (const char *netname, char *skey, char *passwd)
|
||||
{
|
||||
#if defined (HAVE_SECURE_RPC)
|
||||
enum nss_status retval;
|
||||
char buf[1024];
|
||||
char *domain, *result;
|
||||
@@ -120,6 +123,9 @@ _nss_nis_getsecretkey (const char *netname, char *skey, char *passwd)
|
||||
buf[HEXKEYBYTES] = 0;
|
||||
strcpy (skey, buf);
|
||||
}
|
||||
#else
|
||||
skey[0] = 0;
|
||||
#endif
|
||||
return NSS_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
@@ -44,7 +44,7 @@ _nss_nisplus_parse_aliasent (nis_result *result, struct aliasent *alias,
|
||||
char *buffer, size_t buflen)
|
||||
{
|
||||
if (result == NULL)
|
||||
return -1;
|
||||
return 0;
|
||||
|
||||
if ((result->status != NIS_SUCCESS && result->status != NIS_S_SUCCESS) ||
|
||||
result->objects.objects_len != 1 ||
|
||||
@@ -52,7 +52,7 @@ _nss_nisplus_parse_aliasent (nis_result *result, struct aliasent *alias,
|
||||
strcmp(result->objects.objects_val[0].zo_data.objdata_u.en_data.en_type,
|
||||
"mail_aliases") != 0 ||
|
||||
result->objects.objects_val[0].zo_data.objdata_u.en_data.en_cols.en_cols_len < 2)
|
||||
return -1;
|
||||
return 0;
|
||||
else
|
||||
{
|
||||
char *first_unused = buffer + NISENTRYLEN(0, 1, result) + 1;
|
||||
@@ -67,7 +67,7 @@ _nss_nisplus_parse_aliasent (nis_result *result, struct aliasent *alias,
|
||||
/* The line is too long for our buffer. */
|
||||
no_more_room:
|
||||
__set_errno (ERANGE);
|
||||
return -1;
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
@@ -86,7 +86,7 @@ _nss_nisplus_parse_etherent (nis_result *result, struct etherent *ether,
|
||||
struct parser_data *data = (void *) buffer;
|
||||
|
||||
if (result == NULL)
|
||||
return -1;
|
||||
return 0;
|
||||
|
||||
if ((result->status != NIS_SUCCESS && result->status != NIS_S_SUCCESS) ||
|
||||
result->objects.objects_len != 1 ||
|
||||
@@ -94,7 +94,7 @@ _nss_nisplus_parse_etherent (nis_result *result, struct etherent *ether,
|
||||
strcmp(result->objects.objects_val[0].zo_data.objdata_u.en_data.en_type,
|
||||
"ethers_tbl") != 0 ||
|
||||
result->objects.objects_val[0].zo_data.objdata_u.en_data.en_cols.en_cols_len < 2)
|
||||
return -1;
|
||||
return 0;
|
||||
|
||||
memset (p, '\0', room_left);
|
||||
|
||||
@@ -102,7 +102,7 @@ _nss_nisplus_parse_etherent (nis_result *result, struct etherent *ether,
|
||||
if (NISENTRYLEN (0, 0, result) +1 > room_left)
|
||||
{
|
||||
__set_errno (ERANGE);
|
||||
return -1;
|
||||
return 0;
|
||||
}
|
||||
strncpy (p, NISENTRYVAL (0, 0, result), NISENTRYLEN (0, 0, result));
|
||||
room_left -= (NISENTRYLEN (0, 0, result) +1);
|
||||
@@ -110,7 +110,7 @@ _nss_nisplus_parse_etherent (nis_result *result, struct etherent *ether,
|
||||
if (NISENTRYLEN (0, 1, result) +1 > room_left)
|
||||
{
|
||||
__set_errno (ERANGE);
|
||||
return -1;
|
||||
return 0;
|
||||
}
|
||||
strcat (p, "\t");
|
||||
strncat (p, NISENTRYVAL (0, 1, result), NISENTRYLEN (0, 1, result));
|
||||
|
||||
@@ -39,63 +39,34 @@ static nis_name *names = NULL;
|
||||
#define NISENTRYLEN(idx,col,res) \
|
||||
((res)->objects.objects_val[(idx)].zo_data.objdata_u.en_data.en_cols.en_cols_val[(col)].ec_value.ec_value_len)
|
||||
|
||||
#define STRUCTURE group
|
||||
#define ENTNAME grent
|
||||
struct grent_data {};
|
||||
|
||||
#define TRAILING_LIST_MEMBER gr_mem
|
||||
#define TRAILING_LIST_SEPARATOR_P(c) ((c) == ',')
|
||||
#include "../../nss/nss_files/files-parse.c"
|
||||
LINE_PARSER
|
||||
(,
|
||||
STRING_FIELD (result->gr_name, ISCOLON, 0);
|
||||
if (line[0] == '\0'
|
||||
&& (result->gr_name[0] == '+' || result->gr_name[0] == '-'))
|
||||
{
|
||||
result->gr_passwd = NULL;
|
||||
result->gr_gid = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
STRING_FIELD (result->gr_passwd, ISCOLON, 0);
|
||||
if (result->gr_name[0] == '+' || result->gr_name[0] == '-')
|
||||
INT_FIELD_MAYBE_NULL (result->gr_gid, ISCOLON, 0, 10, , 0)
|
||||
else
|
||||
INT_FIELD (result->gr_gid, ISCOLON, 0, 10,)
|
||||
}
|
||||
)
|
||||
|
||||
static int
|
||||
int
|
||||
_nss_nisplus_parse_grent (nis_result * result, struct group *gr,
|
||||
char *buffer, size_t buflen)
|
||||
{
|
||||
#if 0
|
||||
/* XXX here is a bug, sometimes we get some special characters at the
|
||||
end of a line */
|
||||
char *first_unused = buffer;
|
||||
size_t room_left = buflen;
|
||||
char *line;
|
||||
int count;
|
||||
|
||||
|
||||
if (result == NULL)
|
||||
return -1;
|
||||
|
||||
return 0;
|
||||
|
||||
if ((result->status != NIS_SUCCESS && result->status != NIS_S_SUCCESS) ||
|
||||
result->objects.objects_len != 1 ||
|
||||
result->objects.objects_val[0].zo_data.zo_type != ENTRY_OBJ ||
|
||||
strcmp (result->objects.objects_val[0].zo_data.objdata_u.en_data.en_type,
|
||||
"group_tbl") != 0 ||
|
||||
strcmp (result->objects.objects_val[0].zo_data.objdata_u.en_data.en_type,
|
||||
"group_tbl") != 0 ||
|
||||
result->objects.objects_val[0].zo_data.objdata_u.en_data.en_cols.en_cols_len < 4)
|
||||
return -1;
|
||||
return 0;
|
||||
|
||||
if (NISENTRYLEN (0, 0, result) >= room_left)
|
||||
{
|
||||
/* The line is too long for our buffer. */
|
||||
no_more_room:
|
||||
__set_errno (ERANGE);
|
||||
return -1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
strncpy (first_unused, NISENTRYVAL (0, 0, result),
|
||||
NISENTRYLEN (0, 0, result));
|
||||
first_unused[NISENTRYLEN (0, 0, result)] = '\0';
|
||||
@@ -158,8 +129,11 @@ _nss_nisplus_parse_grent (nis_result * result, struct group *gr,
|
||||
|
||||
if (line != gr->gr_mem[count])
|
||||
{
|
||||
*line = '\0';
|
||||
++line;
|
||||
if (*line != '\0')
|
||||
{
|
||||
*line = '\0';
|
||||
++line;
|
||||
}
|
||||
++count;
|
||||
}
|
||||
else
|
||||
@@ -171,59 +145,6 @@ _nss_nisplus_parse_grent (nis_result * result, struct group *gr,
|
||||
gr->gr_mem[count] = NULL;
|
||||
|
||||
return 1;
|
||||
#else
|
||||
char *p = buffer;
|
||||
size_t room_left = buflen;
|
||||
struct parser_data *data = (void *) buffer;
|
||||
|
||||
if (result == NULL)
|
||||
return -1;
|
||||
|
||||
if ((result->status != NIS_SUCCESS && result->status != NIS_S_SUCCESS) ||
|
||||
result->objects.objects_len != 1 ||
|
||||
result->objects.objects_val[0].zo_data.zo_type != ENTRY_OBJ ||
|
||||
strcmp (result->objects.objects_val[0].zo_data.objdata_u.en_data.en_type,
|
||||
"group_tbl") != 0 ||
|
||||
result->objects.objects_val[0].zo_data.objdata_u.en_data.en_cols.en_cols_len < 4)
|
||||
return -1;
|
||||
|
||||
memset (p, '\0', room_left);
|
||||
|
||||
if (NISENTRYLEN (0, 0, result) + 1 > room_left)
|
||||
{
|
||||
__set_errno (ERANGE);
|
||||
return -1;
|
||||
}
|
||||
strncpy (p, NISENTRYVAL (0, 0, result), NISENTRYLEN (0, 0, result));
|
||||
room_left -= (NISENTRYLEN (0, 0, result) + 1);
|
||||
strcat (p, ":");
|
||||
|
||||
if (NISENTRYLEN (0, 1, result) + 1 > room_left)
|
||||
{
|
||||
__set_errno (ERANGE);
|
||||
return -1;
|
||||
}
|
||||
strncat (p, NISENTRYVAL (0, 1, result), NISENTRYLEN (0, 1, result));
|
||||
room_left -= (NISENTRYLEN (0, 1, result) + 1);
|
||||
strcat (p, ":");
|
||||
if (NISENTRYLEN (0, 2, result) + 1 > room_left)
|
||||
{
|
||||
__set_errno (ERANGE);
|
||||
return -1;
|
||||
}
|
||||
strncat (p, NISENTRYVAL (0, 2, result), NISENTRYLEN (0, 2, result));
|
||||
room_left -= (NISENTRYLEN (0, 2, result) + 1);
|
||||
strcat (p, ":");
|
||||
if (NISENTRYLEN (0, 3, result) + 1 > room_left)
|
||||
{
|
||||
__set_errno (ERANGE);
|
||||
return -1;
|
||||
}
|
||||
strncat (p, NISENTRYVAL (0, 3, result), NISENTRYLEN (0, 3, result));
|
||||
room_left -= (NISENTRYLEN (0, 3, result) + 1);
|
||||
|
||||
return _nss_files_parse_grent (p, gr, data, buflen);
|
||||
#endif
|
||||
}
|
||||
|
||||
enum nss_status
|
||||
|
||||
@@ -117,18 +117,19 @@ _nss_nisplus_parse_hostent (nis_result *result, struct hostent *host,
|
||||
{
|
||||
char *p = buffer;
|
||||
size_t room_left = buflen;
|
||||
int parse_res, i;
|
||||
int parse_res;
|
||||
unsigned int i;
|
||||
struct parser_data *data = (void *) buffer;
|
||||
|
||||
if (result == NULL)
|
||||
return -1;
|
||||
return 0;
|
||||
|
||||
if ((result->status != NIS_SUCCESS && result->status != NIS_S_SUCCESS) ||
|
||||
result->objects.objects_val[0].zo_data.zo_type != ENTRY_OBJ ||
|
||||
strcmp(result->objects.objects_val[0].zo_data.objdata_u.en_data.en_type,
|
||||
"hosts_tbl") != 0 ||
|
||||
result->objects.objects_val[0].zo_data.objdata_u.en_data.en_cols.en_cols_len < 4)
|
||||
return -1;
|
||||
return 0;
|
||||
|
||||
memset (p, '\0', room_left);
|
||||
|
||||
@@ -136,7 +137,7 @@ _nss_nisplus_parse_hostent (nis_result *result, struct hostent *host,
|
||||
if (NISENTRYLEN (0, 2, result) + 1 > room_left)
|
||||
{
|
||||
__set_errno (ERANGE);
|
||||
return -1;
|
||||
return 0;
|
||||
}
|
||||
strncpy (p, NISENTRYVAL (0, 2, result),
|
||||
NISENTRYLEN (0, 2, result));
|
||||
@@ -145,7 +146,7 @@ _nss_nisplus_parse_hostent (nis_result *result, struct hostent *host,
|
||||
if (NISENTRYLEN (0, 0, result) + 1 > room_left)
|
||||
{
|
||||
__set_errno (ERANGE);
|
||||
return -1;
|
||||
return 0;
|
||||
}
|
||||
strcat (p, "\t");
|
||||
strncat (p, NISENTRYVAL (0, 0, result), NISENTRYLEN (0, 0, result));
|
||||
@@ -157,7 +158,7 @@ _nss_nisplus_parse_hostent (nis_result *result, struct hostent *host,
|
||||
if (NISENTRYLEN (i, 1, result) + 1 > room_left)
|
||||
{
|
||||
__set_errno (ERANGE);
|
||||
return -1;
|
||||
return 0;
|
||||
}
|
||||
strcat (p, " ");
|
||||
strcat (p, NISENTRYVAL (i, 1, result));
|
||||
|
||||
@@ -31,13 +31,9 @@
|
||||
|
||||
__libc_lock_define_initialized (static, lock)
|
||||
|
||||
static char *data = NULL;
|
||||
static size_t data_size = 0;
|
||||
static char *cursor = NULL;;
|
||||
|
||||
extern enum nss_status
|
||||
_nss_netgroup_parseline (char **cursor, struct __netgrent *result,
|
||||
char *buffer, size_t buflen);
|
||||
static nis_result *data = NULL;
|
||||
static unsigned long data_size = 0;
|
||||
static unsigned long position = 0;
|
||||
|
||||
#define NISENTRYVAL(idx,col,res) \
|
||||
((res)->objects.objects_val[(idx)].zo_data.objdata_u.en_data.en_cols.en_cols_val[(col)].ec_value.ec_value_val)
|
||||
@@ -45,15 +41,103 @@ _nss_netgroup_parseline (char **cursor, struct __netgrent *result,
|
||||
#define NISENTRYLEN(idx,col,res) \
|
||||
((res)->objects.objects_val[(idx)].zo_data.objdata_u.en_data.en_cols.en_cols_val[(col)].ec_value.ec_value_len)
|
||||
|
||||
static enum nss_status
|
||||
_nss_nisplus_parse_netgroup (struct __netgrent *result, char *buffer,
|
||||
size_t buflen)
|
||||
{
|
||||
enum nss_status status;
|
||||
|
||||
/* Some sanity checks. */
|
||||
if (data == NULL || data_size == 0)
|
||||
/* User bug. setnetgrent() wasn't called before. */
|
||||
abort ();
|
||||
|
||||
if (position == data_size)
|
||||
return result->first ? NSS_STATUS_NOTFOUND : NSS_STATUS_RETURN;
|
||||
|
||||
if (NISENTRYLEN (position, 1, data) > 0)
|
||||
{
|
||||
/* We have a list of other netgroups. */
|
||||
|
||||
result->type = group_val;
|
||||
if (NISENTRYLEN (position, 1, data) >= buflen)
|
||||
{
|
||||
__set_errno (ERANGE);
|
||||
return NSS_STATUS_TRYAGAIN;
|
||||
}
|
||||
strncpy (buffer, NISENTRYVAL (position, 1, data),
|
||||
NISENTRYLEN (position, 1, data));
|
||||
buffer[NISENTRYLEN (position, 1, data)] = '\0';
|
||||
result->val.group = buffer;
|
||||
++position;
|
||||
result->first = 0;
|
||||
|
||||
return NSS_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
/* Before we can copy the entry to the private buffer we have to make
|
||||
sure it is big enough. */
|
||||
if (NISENTRYLEN (position, 2, data) + NISENTRYLEN (position, 3, data) +
|
||||
NISENTRYLEN (position, 4, data) + 6 > buflen)
|
||||
{
|
||||
__set_errno (ERANGE);
|
||||
status = NSS_STATUS_UNAVAIL;
|
||||
}
|
||||
else
|
||||
{
|
||||
char *cp = buffer;
|
||||
|
||||
result->type = triple_val;
|
||||
|
||||
if (NISENTRYLEN (position, 2, data) == 0)
|
||||
result->val.triple.host = NULL;
|
||||
else
|
||||
{
|
||||
result->val.triple.host = cp;
|
||||
cp = stpncpy (cp, NISENTRYVAL (position, 2, data),
|
||||
NISENTRYLEN (position, 2, data));
|
||||
*cp = '\0';
|
||||
++cp;
|
||||
}
|
||||
|
||||
if (NISENTRYLEN (position, 3, data) == 0)
|
||||
result->val.triple.user = NULL;
|
||||
else
|
||||
{
|
||||
result->val.triple.user = cp;
|
||||
cp = stpncpy (cp, NISENTRYVAL (position, 3, data),
|
||||
NISENTRYLEN (position, 3, data));
|
||||
*cp = '\0';
|
||||
++cp;
|
||||
}
|
||||
|
||||
if (NISENTRYLEN (position, 4, data) == 0)
|
||||
result->val.triple.domain = NULL;
|
||||
else
|
||||
{
|
||||
result->val.triple.domain = cp;
|
||||
cp = stpncpy (cp, NISENTRYVAL (position, 4, data),
|
||||
NISENTRYLEN (position, 4, data));
|
||||
*cp = '\0';
|
||||
}
|
||||
|
||||
status = NSS_STATUS_SUCCESS;
|
||||
|
||||
/* Remember where we stopped reading. */
|
||||
++position;
|
||||
|
||||
result->first = 0;
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
enum nss_status
|
||||
_nss_nisplus_setnetgrent (char *group)
|
||||
|
||||
{
|
||||
enum nss_status status;
|
||||
nis_result *result;
|
||||
char buf[strlen (group) + 30];
|
||||
int i;
|
||||
size_t len;
|
||||
|
||||
if (group == NULL || group[0] == '\0')
|
||||
return NSS_STATUS_UNAVAIL;
|
||||
@@ -64,43 +148,27 @@ _nss_nisplus_setnetgrent (char *group)
|
||||
|
||||
if (data != NULL)
|
||||
{
|
||||
free (data);
|
||||
nis_freeresult (data);
|
||||
data = NULL;
|
||||
data_size = 0;
|
||||
cursor = NULL;
|
||||
position = 0;
|
||||
}
|
||||
|
||||
sprintf(buf, "[name=%s],netgroup.org_dir", group);
|
||||
|
||||
result = nis_list(buf, EXPAND_NAME, NULL, NULL);
|
||||
data = nis_list(buf, EXPAND_NAME, NULL, NULL);
|
||||
|
||||
if (niserr2nss (result->status) != NSS_STATUS_SUCCESS)
|
||||
status = niserr2nss (result->status);
|
||||
|
||||
len = 0;
|
||||
for (i = 0; i < result->objects.objects_len; i++)
|
||||
len += 1 + NISENTRYLEN (i, 1, result) + 1 + NISENTRYLEN(i,2,result)
|
||||
+ 1 + NISENTRYLEN(i,3,result) + 1 + NISENTRYLEN(i,4,result) + 2;
|
||||
|
||||
data = malloc (len+1);
|
||||
memset (data, '\0', len+1);
|
||||
|
||||
for (i = 0; i < result->objects.objects_len; i++)
|
||||
if (niserr2nss (data->status) != NSS_STATUS_SUCCESS)
|
||||
{
|
||||
strncat (data, NISENTRYVAL (i, 1, result), NISENTRYLEN (i, 1, result));
|
||||
strcat (data," (");
|
||||
strncat (data, NISENTRYVAL(i,2,result), NISENTRYLEN (i, 2, result));
|
||||
strcat (data, ",");
|
||||
strncat (data, NISENTRYVAL(i,3,result), NISENTRYLEN (i, 3, result));
|
||||
strcat (data, ",");
|
||||
strncat (data, NISENTRYVAL(i,4,result), NISENTRYLEN (i, 4, result));
|
||||
strcat (data, ") ");
|
||||
status = niserr2nss (data->status);
|
||||
nis_freeresult (data);
|
||||
data = NULL;
|
||||
}
|
||||
|
||||
nis_freeresult (result);
|
||||
|
||||
else
|
||||
data_size = data->objects.objects_len;
|
||||
|
||||
__libc_lock_unlock (lock);
|
||||
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
@@ -111,10 +179,10 @@ _nss_nisplus_endnetgrent (void)
|
||||
|
||||
if (data != NULL)
|
||||
{
|
||||
free (data);
|
||||
nis_freeresult (data);
|
||||
data = NULL;
|
||||
data_size = 0;
|
||||
cursor = NULL;
|
||||
position = 0;
|
||||
}
|
||||
|
||||
__libc_lock_unlock (lock);
|
||||
@@ -128,12 +196,9 @@ _nss_nisplus_getnetgrent_r (struct __netgrent *result,
|
||||
{
|
||||
enum nss_status status;
|
||||
|
||||
if (cursor == NULL)
|
||||
return NSS_STATUS_NOTFOUND;
|
||||
|
||||
__libc_lock_lock (lock);
|
||||
|
||||
status = _nss_netgroup_parseline (&cursor, result, buffer, buflen);
|
||||
status = _nss_nisplus_parse_netgroup (result, buffer, buflen);
|
||||
|
||||
__libc_lock_unlock (lock);
|
||||
|
||||
|
||||
@@ -65,24 +65,24 @@ _nss_nisplus_parse_netent (nis_result *result, struct netent *network,
|
||||
{
|
||||
char *p = buffer;
|
||||
size_t room_left = buflen;
|
||||
int i;
|
||||
unsigned int i;
|
||||
struct parser_data *data = (void *) buffer;
|
||||
|
||||
if (result == NULL)
|
||||
return -1;
|
||||
return 0;
|
||||
|
||||
if ((result->status != NIS_SUCCESS && result->status != NIS_S_SUCCESS) ||
|
||||
result->objects.objects_val[0].zo_data.zo_type != ENTRY_OBJ ||
|
||||
strcmp(result->objects.objects_val[0].zo_data.objdata_u.en_data.en_type,
|
||||
"networks_tbl") != 0 ||
|
||||
result->objects.objects_val[0].zo_data.objdata_u.en_data.en_cols.en_cols_len < 3)
|
||||
return -1;
|
||||
return 0;
|
||||
|
||||
/* Generate the network entry format and use the normal parser */
|
||||
if (NISENTRYLEN (0, 0, result) +1 > room_left)
|
||||
{
|
||||
__set_errno (ERANGE);
|
||||
return -1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
memset (p, '\0', room_left);
|
||||
@@ -93,7 +93,7 @@ _nss_nisplus_parse_netent (nis_result *result, struct netent *network,
|
||||
if (NISENTRYLEN (0, 2, result) +1 > room_left)
|
||||
{
|
||||
__set_errno (ERANGE);
|
||||
return -1;
|
||||
return 0;
|
||||
}
|
||||
strcat (p, "\t");
|
||||
strncat (p, NISENTRYVAL (0, 2, result), NISENTRYLEN (0, 2, result));
|
||||
@@ -101,12 +101,11 @@ _nss_nisplus_parse_netent (nis_result *result, struct netent *network,
|
||||
/* + 1: We overwrite the last \0 */
|
||||
|
||||
for (i = 1; i < result->objects.objects_len; i++)
|
||||
/* XXX should we start with i = 0 or with i = 1 ? */
|
||||
{
|
||||
if (NISENTRYLEN (i, 1, result) +1 > room_left)
|
||||
{
|
||||
__set_errno (ERANGE);
|
||||
return -1;
|
||||
return 0;
|
||||
}
|
||||
strcat (p, " ");
|
||||
strncat (p, NISENTRYVAL (i, 1, result), NISENTRYLEN (i, 1, result));
|
||||
|
||||
@@ -56,18 +56,18 @@ _nss_nisplus_parse_protoent (nis_result * result, struct protoent *proto,
|
||||
{
|
||||
char *p = buffer;
|
||||
size_t room_left = buflen;
|
||||
int i;
|
||||
unsigned int i;
|
||||
struct parser_data *data = (void *) buffer;
|
||||
|
||||
if (result == NULL)
|
||||
return -1;
|
||||
return 0;
|
||||
|
||||
if ((result->status != NIS_SUCCESS && result->status != NIS_S_SUCCESS) ||
|
||||
result->objects.objects_val[0].zo_data.zo_type != ENTRY_OBJ ||
|
||||
strcmp (result->objects.objects_val[0].zo_data.objdata_u.en_data.en_type,
|
||||
"protocols_tbl") != 0 ||
|
||||
result->objects.objects_val[0].zo_data.objdata_u.en_data.en_cols.en_cols_len < 3)
|
||||
return -1;
|
||||
return 0;
|
||||
|
||||
memset (p, '\0', room_left);
|
||||
|
||||
@@ -75,7 +75,7 @@ _nss_nisplus_parse_protoent (nis_result * result, struct protoent *proto,
|
||||
if (NISENTRYLEN (0, 0, result) + 1 > room_left)
|
||||
{
|
||||
__set_errno (ERANGE);
|
||||
return -1;
|
||||
return 0;
|
||||
}
|
||||
strncpy (p, NISENTRYVAL (0, 0, result), NISENTRYLEN (0, 0, result));
|
||||
room_left -= (NISENTRYLEN (0, 0, result) + 1);
|
||||
@@ -83,7 +83,7 @@ _nss_nisplus_parse_protoent (nis_result * result, struct protoent *proto,
|
||||
if (NISENTRYLEN (0, 2, result) + 1 > room_left)
|
||||
{
|
||||
__set_errno (ERANGE);
|
||||
return -1;
|
||||
return 0;
|
||||
}
|
||||
strcat (p, "\t");
|
||||
strncat (p, NISENTRYVAL (0, 2, result), NISENTRYLEN (0, 2, result));
|
||||
@@ -95,7 +95,7 @@ _nss_nisplus_parse_protoent (nis_result * result, struct protoent *proto,
|
||||
if (NISENTRYLEN (i, 1, result) + 1 > room_left)
|
||||
{
|
||||
__set_errno (ERANGE);
|
||||
return -1;
|
||||
return 0;
|
||||
}
|
||||
strcat (p, " ");
|
||||
strncat (p, NISENTRYVAL (i, 1, result), NISENTRYLEN (i, 1, result));
|
||||
|
||||
@@ -23,15 +23,17 @@
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <syslog.h>
|
||||
#include <rpc/key_prot.h>
|
||||
#include <rpc/rpc.h>
|
||||
#include <rpcsvc/nis.h>
|
||||
#include <rpcsvc/nislib.h>
|
||||
#ifdef HAVE_SECURE_RPC
|
||||
#include <rpc/key_prot.h>
|
||||
extern int xdecrypt (char *, char *);
|
||||
#endif
|
||||
|
||||
#include <nss-nisplus.h>
|
||||
|
||||
extern int xdecrypt (char *, char *);
|
||||
|
||||
/* If we found the entry, we give a SUCCESS and an empty key back. */
|
||||
/* If we haven't found the entry, we give a SUCCESS and an empty key back. */
|
||||
enum nss_status
|
||||
_nss_nisplus_getpublickey (const char *netname, char *pkey)
|
||||
{
|
||||
@@ -70,6 +72,8 @@ _nss_nisplus_getpublickey (const char *netname, char *pkey)
|
||||
{
|
||||
if (retval == NSS_STATUS_TRYAGAIN)
|
||||
__set_errno (EAGAIN);
|
||||
if (res->status == NIS_NOTFOUND)
|
||||
retval = NSS_STATUS_SUCCESS;
|
||||
nis_freeresult (res);
|
||||
return retval;
|
||||
}
|
||||
@@ -100,6 +104,7 @@ _nss_nisplus_getpublickey (const char *netname, char *pkey)
|
||||
enum nss_status
|
||||
_nss_nisplus_getsecretkey (const char *netname, char *skey, char *passwd)
|
||||
{
|
||||
#ifdef HAVE_SECURE_RPC
|
||||
nis_result *res;
|
||||
enum nss_status retval;
|
||||
char buf[NIS_MAXNAMELEN+2];
|
||||
@@ -167,6 +172,9 @@ _nss_nisplus_getsecretkey (const char *netname, char *skey, char *passwd)
|
||||
|
||||
buf[HEXKEYBYTES] = 0;
|
||||
strcpy (skey, buf);
|
||||
#else
|
||||
skey[0] = 0;
|
||||
#endif
|
||||
|
||||
return NSS_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
@@ -38,7 +38,7 @@ static nis_name *names = NULL;
|
||||
#define NISENTRYLEN(idx,col,res) \
|
||||
((res)->objects.objects_val[(idx)].zo_data.objdata_u.en_data.en_cols.en_cols_val[(col)].ec_value.ec_value_len)
|
||||
|
||||
static int
|
||||
int
|
||||
_nss_nisplus_parse_pwent (nis_result *result, struct passwd *pw,
|
||||
char *buffer, size_t buflen)
|
||||
{
|
||||
@@ -46,7 +46,7 @@ _nss_nisplus_parse_pwent (nis_result *result, struct passwd *pw,
|
||||
size_t room_left = buflen;
|
||||
|
||||
if (result == NULL)
|
||||
return -1;
|
||||
return 0;
|
||||
|
||||
if ((result->status != NIS_SUCCESS && result->status != NIS_S_SUCCESS) ||
|
||||
result->objects.objects_len != 1 ||
|
||||
@@ -54,14 +54,14 @@ _nss_nisplus_parse_pwent (nis_result *result, struct passwd *pw,
|
||||
strcmp(result->objects.objects_val[0].zo_data.objdata_u.en_data.en_type,
|
||||
"passwd_tbl") != 0 ||
|
||||
result->objects.objects_val[0].zo_data.objdata_u.en_data.en_cols.en_cols_len < 7)
|
||||
return -1;
|
||||
return 0;
|
||||
|
||||
if (NISENTRYLEN(0, 0, result) >= room_left)
|
||||
{
|
||||
/* The line is too long for our buffer. */
|
||||
no_more_room:
|
||||
__set_errno (ERANGE);
|
||||
return -1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
strncpy (first_unused, NISENTRYVAL(0, 0, result),
|
||||
|
||||
@@ -56,18 +56,18 @@ _nss_nisplus_parse_rpcent (nis_result *result, struct rpcent *rpc,
|
||||
{
|
||||
char *p = buffer;
|
||||
size_t room_left = buflen;
|
||||
int i;
|
||||
unsigned int i;
|
||||
struct parser_data *data = (void *) buffer;
|
||||
|
||||
if (result == NULL)
|
||||
return -1;
|
||||
return 0;
|
||||
|
||||
if ((result->status != NIS_SUCCESS && result->status != NIS_S_SUCCESS) ||
|
||||
result->objects.objects_val[0].zo_data.zo_type != ENTRY_OBJ ||
|
||||
strcmp(result->objects.objects_val[0].zo_data.objdata_u.en_data.en_type,
|
||||
"rpc_tbl") != 0 ||
|
||||
result->objects.objects_val[0].zo_data.objdata_u.en_data.en_cols.en_cols_len < 3)
|
||||
return -1;
|
||||
return 0;
|
||||
|
||||
memset (p, '\0', room_left);
|
||||
|
||||
@@ -75,7 +75,7 @@ _nss_nisplus_parse_rpcent (nis_result *result, struct rpcent *rpc,
|
||||
if (NISENTRYLEN (0, 0, result) +1 > room_left)
|
||||
{
|
||||
__set_errno (ERANGE);
|
||||
return -1;
|
||||
return 0;
|
||||
}
|
||||
strncpy (p, NISENTRYVAL (0, 0, result), NISENTRYLEN (0, 0, result));
|
||||
room_left -= (NISENTRYLEN (0, 0, result) +1);
|
||||
@@ -83,7 +83,7 @@ _nss_nisplus_parse_rpcent (nis_result *result, struct rpcent *rpc,
|
||||
if (NISENTRYLEN (0, 2, result) +1 > room_left)
|
||||
{
|
||||
__set_errno (ERANGE);
|
||||
return -1;
|
||||
return 0;
|
||||
}
|
||||
strcat (p, "\t");
|
||||
strncat (p, NISENTRYVAL (0, 2, result), NISENTRYLEN (0, 2, result));
|
||||
@@ -96,7 +96,7 @@ _nss_nisplus_parse_rpcent (nis_result *result, struct rpcent *rpc,
|
||||
if (NISENTRYLEN (i, 1, result) +1 > room_left)
|
||||
{
|
||||
__set_errno (ERANGE);
|
||||
return -1;
|
||||
return 0;
|
||||
}
|
||||
strcat (p, " ");
|
||||
strncat (p, NISENTRYVAL (i, 1, result), NISENTRYLEN (i, 1, result));
|
||||
|
||||
@@ -59,18 +59,18 @@ _nss_nisplus_parse_servent (nis_result *result, struct servent *serv,
|
||||
{
|
||||
char *p = buffer;
|
||||
size_t room_left = buflen;
|
||||
int i;
|
||||
unsigned int i;
|
||||
struct parser_data *data = (void *) buffer;
|
||||
|
||||
if (result == NULL)
|
||||
return -1;
|
||||
return 0;
|
||||
|
||||
if ((result->status != NIS_SUCCESS && result->status != NIS_S_SUCCESS) ||
|
||||
result->objects.objects_val[0].zo_data.zo_type != ENTRY_OBJ ||
|
||||
strcmp (result->objects.objects_val[0].zo_data.objdata_u.en_data.en_type,
|
||||
"services_tbl") != 0 ||
|
||||
result->objects.objects_val[0].zo_data.objdata_u.en_data.en_cols.en_cols_len < 4)
|
||||
return -1;
|
||||
return 0;
|
||||
|
||||
memset (p, '\0', room_left);
|
||||
|
||||
@@ -78,7 +78,7 @@ _nss_nisplus_parse_servent (nis_result *result, struct servent *serv,
|
||||
if (NISENTRYLEN (0, 0, result) + 1 > room_left)
|
||||
{
|
||||
__set_errno (ERANGE);
|
||||
return -1;
|
||||
return 0;
|
||||
}
|
||||
strncpy (p, NISENTRYVAL (0, 0, result), NISENTRYLEN (0, 0, result));
|
||||
room_left -= (NISENTRYLEN (0, 0, result) + 1);
|
||||
@@ -86,7 +86,7 @@ _nss_nisplus_parse_servent (nis_result *result, struct servent *serv,
|
||||
if (NISENTRYLEN (0, 3, result) + 1 > room_left)
|
||||
{
|
||||
__set_errno (ERANGE);
|
||||
return -1;
|
||||
return 0;
|
||||
}
|
||||
strcat (p, "\t");
|
||||
strncat (p, NISENTRYVAL (0, 3, result), NISENTRYLEN (0, 3, result));
|
||||
@@ -94,7 +94,7 @@ _nss_nisplus_parse_servent (nis_result *result, struct servent *serv,
|
||||
if (NISENTRYLEN (0, 2, result) + 1 > room_left)
|
||||
{
|
||||
__set_errno (ERANGE);
|
||||
return -1;
|
||||
return 0;
|
||||
}
|
||||
strcat (p, "/");
|
||||
strncat (p, NISENTRYVAL (0, 2, result), NISENTRYLEN (0, 2, result));
|
||||
@@ -105,7 +105,7 @@ _nss_nisplus_parse_servent (nis_result *result, struct servent *serv,
|
||||
if (NISENTRYLEN (i, 1, result) + 1 > room_left)
|
||||
{
|
||||
__set_errno (ERANGE);
|
||||
return -1;
|
||||
return 0;
|
||||
}
|
||||
strcat (p, " ");
|
||||
strcat (p, NISENTRYVAL (i, 1, result));
|
||||
|
||||
@@ -38,7 +38,7 @@ static nis_name *names = NULL;
|
||||
#define NISENTRYLEN(idx,col,res) \
|
||||
((res)->objects.objects_val[(idx)].zo_data.objdata_u.en_data.en_cols.en_cols_val[(col)].ec_value.ec_value_len)
|
||||
|
||||
static int
|
||||
int
|
||||
_nss_nisplus_parse_spent (nis_result *result, struct spwd *sp,
|
||||
char *buffer, size_t buflen)
|
||||
{
|
||||
@@ -47,7 +47,7 @@ _nss_nisplus_parse_spent (nis_result *result, struct spwd *sp,
|
||||
char *line, *cp;
|
||||
|
||||
if (result == NULL)
|
||||
return -1;
|
||||
return 0;
|
||||
|
||||
if ((result->status != NIS_SUCCESS && result->status != NIS_S_SUCCESS) ||
|
||||
result->objects.objects_len != 1 ||
|
||||
@@ -55,14 +55,14 @@ _nss_nisplus_parse_spent (nis_result *result, struct spwd *sp,
|
||||
strcmp (result->objects.objects_val[0].zo_data.objdata_u.en_data.en_type,
|
||||
"passwd_tbl") != 0 ||
|
||||
result->objects.objects_val[0].zo_data.objdata_u.en_data.en_cols.en_cols_len < 8)
|
||||
return -1;
|
||||
return 0;
|
||||
|
||||
if (NISENTRYLEN(0, 0, result) >= room_left)
|
||||
{
|
||||
/* The line is too long for our buffer. */
|
||||
no_more_room:
|
||||
__set_errno (ERANGE);
|
||||
return -1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
strncpy (first_unused, NISENTRYVAL (0, 0, result),
|
||||
|
||||
+190
-92
@@ -24,57 +24,144 @@
|
||||
|
||||
__BEGIN_DECLS
|
||||
|
||||
/*
|
||||
** nis_names
|
||||
*/
|
||||
extern nis_result *nis_lookup __P ((__const nis_name, const u_long));
|
||||
extern nis_result *nis_add __P ((__const nis_name, const nis_object *));
|
||||
extern nis_result *nis_remove __P ((__const nis_name, const nis_object *));
|
||||
extern nis_result *nis_modify __P ((__const nis_name, const nis_object *));
|
||||
/*
|
||||
** nis_table
|
||||
*/
|
||||
extern nis_result *nis_list __P ((__const nis_name, const u_long,
|
||||
int (*)(__const nis_name,
|
||||
__const nis_object *,
|
||||
__const void *), __const void *));
|
||||
extern nis_result *nis_add_entry __P ((__const nis_name, __const nis_object *,
|
||||
__const u_long));
|
||||
extern nis_result *nis_modify_entry __P ((__const nis_name,
|
||||
__const nis_object *,
|
||||
__const u_long));
|
||||
extern nis_result *nis_remove_entry __P ((__const nis_name,
|
||||
__const nis_object *,
|
||||
__const u_long));
|
||||
extern nis_result *nis_first_entry __P ((__const nis_name));
|
||||
extern nis_result *nis_next_entry __P ((__const nis_name, __const netobj *));
|
||||
typedef const char *const_nis_name;
|
||||
|
||||
/* nis_names: These functions are used to locate and manipulate all NIS+
|
||||
* objects except the NIS+ entry objects.
|
||||
*
|
||||
* nis_lookup (name, flags) resolves a NIS+ name and returns a copy of
|
||||
* that object from a NIS+ server.
|
||||
* const nis_name name: name of the object to be resolved
|
||||
* u_long flags: logically ORing zero or more flags (FOLLOW_LINKS,
|
||||
* HARD_LOOKUP, [NO_CACHE], MASTER_ONLY, EXPAND_NAME)
|
||||
*
|
||||
* nis_add (name, obj) adds objects to the NIS+ namespace.
|
||||
* const nis_name name: fully qualified NIS+ name.
|
||||
* const nis_object *obj: object members zo_name and zo_domain will be
|
||||
* constructed from name.
|
||||
*
|
||||
* nis_remove (name, obj) removes objects from the NIS+ namespace.
|
||||
* const nis_name name: fully qualified NIS+ name.
|
||||
* const nis_object *obj: if not NULL, it is assumed to point to a copy
|
||||
* of the object being removed. In this case, if
|
||||
* the object on the server does not have the same
|
||||
* object identifier as the object being passed,
|
||||
* the operation will fail with the NIS_NOTSAMEOBJ
|
||||
* error.
|
||||
*
|
||||
* nis_modify (name, obj) can change specific attributes of an object
|
||||
* that already exists in the namespace.
|
||||
*/
|
||||
extern nis_result *nis_lookup __P ((const_nis_name name, u_long flags));
|
||||
extern nis_result *nis_add __P ((const_nis_name name, const nis_object *obj));
|
||||
extern nis_result *nis_remove __P ((const_nis_name name,
|
||||
const nis_object *obj));
|
||||
extern nis_result *nis_modify __P ((const_nis_name name,
|
||||
const nis_object *obj));
|
||||
|
||||
/* nis_tables: These functions are used to search and modify NIS+ tables.
|
||||
*
|
||||
* nis_list (table_name, flags, callback(table_name, obj, userdata), userdata)
|
||||
* search a table in the NIS+ namespace.
|
||||
* const nis_name table_name: indexed name ([xx=yy],table.dir)
|
||||
* u_long flags: logically ORing one or more flags (FOLLOW_LINKS,
|
||||
* [FOLLOW_PATH], HARD_LOOKUP, [ALL_RESULTS], [NO_CACHE],
|
||||
* MASTER_ONLY, EXPAND_NAME, RETURN_RESULT)
|
||||
* callback(): callback is an optional pointer to a function that will
|
||||
* process the ENTRY type objects that are returned from the
|
||||
* search. If this pointer is NULL, then all entries that match
|
||||
* the search criteria are returned in the nis_result structure,
|
||||
* otherwise this function will be called once for each
|
||||
* entry returned.
|
||||
* void *userdata: passed to callback function along with the returned
|
||||
* entry object.
|
||||
*
|
||||
* nis_add_entry (table_name, obj, flags) will add the NIS+ object to the
|
||||
* NIS+ table_name.
|
||||
* const nis_name table_name
|
||||
* const nis_object *obj
|
||||
* u_long flags: 0, ADD_OVERWRITE, RETURN_RESULT
|
||||
*
|
||||
* nis_modify_entry (name, obj, flags) modifies an object identified by name.
|
||||
* const nis_name name: object identifier
|
||||
* const nis_object *obj: should point to an entry with the EN_MODIFIED
|
||||
* flag set in each column that contains new
|
||||
* information.
|
||||
* u_long flags: 0, MOD_SAMEOBJ, RETURN_RESULT
|
||||
*
|
||||
* nis_remove_entry (table_name, obj, flags) removes a set of entries
|
||||
* identified by table_name from the table.
|
||||
* const nis_name table_name: indexed NIS+ name
|
||||
* const nis_object *obj: if obj is non-null, it is presumed to point to
|
||||
* a cached copy of the entry. When the removal is
|
||||
* attempted, and the object that would be removed
|
||||
* is not the same as the cached object pointed to
|
||||
* by object then the operation will fail with an
|
||||
* NIS_NOTSAMEOBJ error
|
||||
* u_long flags: 0, REM_MULTIPLE
|
||||
*
|
||||
* nis_first_entry (table_name) fetches entries from a table one at a time.
|
||||
* const nis_name table_name
|
||||
*
|
||||
* nis_next_entry (table_name, cookie) retrieves the "next" entry from a
|
||||
* table specified by table_name.
|
||||
* const nis_name table_name:
|
||||
* const netobj *cookie: The value of cookie from the nis_result structure
|
||||
* form the previous call.
|
||||
*/
|
||||
extern nis_result *nis_list __P ((const_nis_name name, u_long flags,
|
||||
int (*callback)(const_nis_name table_name,
|
||||
const nis_object *obj,
|
||||
const void *userdata),
|
||||
const void *userdata));
|
||||
extern nis_result *nis_add_entry __P ((const_nis_name table_name,
|
||||
const nis_object *obj, u_long flags));
|
||||
extern nis_result *nis_modify_entry __P ((const_nis_name name,
|
||||
const nis_object *obj,
|
||||
u_long flags));
|
||||
extern nis_result *nis_remove_entry __P ((const_nis_name table_name,
|
||||
const nis_object *obj,
|
||||
u_long flags));
|
||||
extern nis_result *nis_first_entry __P ((const_nis_name table_name));
|
||||
extern nis_result *nis_next_entry __P ((const_nis_name table_name,
|
||||
const netobj *cookie));
|
||||
/*
|
||||
** nis_server
|
||||
*/
|
||||
extern nis_error nis_mkdir __P ((__const nis_name, __const nis_server *));
|
||||
extern nis_error nis_rmdir __P ((__const nis_name, __const nis_server *));
|
||||
extern nis_error nis_servstate __P ((__const nis_server *, __const nis_tag *,
|
||||
__const int, nis_tag **));
|
||||
extern nis_error nis_stats __P ((__const nis_server *, __const nis_tag *,
|
||||
__const int, nis_tag **));
|
||||
extern void nis_freetags __P ((nis_tag *, __const int));
|
||||
extern nis_server **nis_getservlist __P ((__const nis_name));
|
||||
extern void nis_freeservlist __P ((nis_server **));
|
||||
extern nis_error nis_mkdir __P ((const_nis_name dirname,
|
||||
const nis_server *machine));
|
||||
extern nis_error nis_rmdir __P ((const_nis_name dirname,
|
||||
const nis_server *machine));
|
||||
extern nis_error nis_servstate __P ((const nis_server *machine,
|
||||
const nis_tag *tags, int numtags,
|
||||
nis_tag **result));
|
||||
extern nis_error nis_stats __P ((const nis_server *machine,
|
||||
const nis_tag *tags, int numtags,
|
||||
nis_tag **result));
|
||||
extern void nis_freetags __P ((nis_tag *tags, int numtags));
|
||||
extern nis_server **nis_getservlist __P ((const_nis_name dirname));
|
||||
extern void nis_freeservlist __P ((nis_server **machines));
|
||||
|
||||
/*
|
||||
** nis_subr
|
||||
*/
|
||||
extern nis_name nis_leaf_of __P ((__const nis_name));
|
||||
extern nis_name nis_leaf_of_r __P ((__const nis_name, char *, size_t));
|
||||
extern nis_name nis_name_of __P ((__const nis_name));
|
||||
extern nis_name nis_name_of_r __P ((__const nis_name, char *, size_t));
|
||||
extern nis_name nis_domain_of __P ((__const nis_name));
|
||||
extern nis_name nis_domain_of_r __P ((__const nis_name, char *, size_t));
|
||||
extern nis_name *nis_getnames __P ((__const nis_name));
|
||||
extern void nis_freenames __P ((nis_name *));
|
||||
extern name_pos nis_dir_cmp __P ((nis_name, nis_name));
|
||||
extern nis_object *nis_clone_object __P ((__const nis_object *, nis_object *));
|
||||
extern void nis_destroy_object __P ((nis_object *));
|
||||
extern void nis_print_object __P ((__const nis_object *));
|
||||
extern nis_name nis_leaf_of __P ((const_nis_name name));
|
||||
extern nis_name nis_leaf_of_r __P ((const_nis_name name, char *buffer,
|
||||
size_t buflen));
|
||||
extern nis_name nis_name_of __P ((const_nis_name name));
|
||||
extern nis_name nis_name_of_r __P ((const_nis_name name, char *buffer,
|
||||
size_t buflen));
|
||||
extern nis_name nis_domain_of __P ((const_nis_name name));
|
||||
extern nis_name nis_domain_of_r __P ((const_nis_name name, char *buffer,
|
||||
size_t buflen));
|
||||
extern nis_name *nis_getnames __P ((const_nis_name name));
|
||||
extern void nis_freenames __P ((nis_name *namelist));
|
||||
extern name_pos nis_dir_cmp __P ((const_nis_name n1, const_nis_name n2));
|
||||
extern nis_object *nis_clone_object __P ((const nis_object *src,
|
||||
nis_object *dest));
|
||||
extern void nis_destroy_object __P ((nis_object *obj));
|
||||
extern void nis_print_object __P ((const nis_object *obj));
|
||||
|
||||
/*
|
||||
** nis_local_names
|
||||
*/
|
||||
@@ -82,81 +169,92 @@ extern nis_name nis_local_group __P ((void));
|
||||
extern nis_name nis_local_directory __P ((void));
|
||||
extern nis_name nis_local_principal __P ((void));
|
||||
extern nis_name nis_local_host __P ((void));
|
||||
|
||||
/*
|
||||
** nis_error
|
||||
*/
|
||||
extern const char *nis_sperrno __P ((__const nis_error));
|
||||
extern void nis_perror __P ((__const nis_error, __const char *));
|
||||
extern void nis_lerror __P ((__const nis_error, __const char *));
|
||||
extern char *nis_sperror __P ((__const nis_error, __const char *));
|
||||
extern char *nis_sperror_r __P ((__const nis_error, __const char *,
|
||||
char *, size_t));
|
||||
extern const char *nis_sperrno __P ((const nis_error status));
|
||||
extern void nis_perror __P ((const nis_error status, const char *label));
|
||||
extern void nis_lerror __P ((const nis_error status, const char *label));
|
||||
extern char *nis_sperror __P ((const nis_error status, const char *label));
|
||||
extern char *nis_sperror_r __P ((const nis_error status, const char *label,
|
||||
char *buffer, size_t buflen));
|
||||
/*
|
||||
** nis_groups
|
||||
*/
|
||||
extern bool_t nis_ismember __P ((__const nis_name, __const nis_name));
|
||||
extern nis_error nis_addmember __P ((__const nis_name, __const nis_name));
|
||||
extern nis_error nis_removemember __P ((__const nis_name, __const nis_name));
|
||||
extern nis_error nis_creategroup __P ((__const nis_name, __const u_long));
|
||||
extern nis_error nis_destroygroup __P ((__const nis_name));
|
||||
extern void nis_print_group_entry __P ((__const nis_name));
|
||||
extern nis_error nis_verifygroup __P ((__const nis_name));
|
||||
extern bool_t nis_ismember __P ((const_nis_name principal,
|
||||
const_nis_name group));
|
||||
extern nis_error nis_addmember __P ((const_nis_name member,
|
||||
const_nis_name group));
|
||||
extern nis_error nis_removemember __P ((const_nis_name member,
|
||||
const_nis_name group));
|
||||
extern nis_error nis_creategroup __P ((const_nis_name group, u_long flags));
|
||||
extern nis_error nis_destroygroup __P ((const_nis_name group));
|
||||
extern void nis_print_group_entry __P ((const_nis_name group));
|
||||
extern nis_error nis_verifygroup __P ((const_nis_name group));
|
||||
|
||||
/*
|
||||
** nis_ping
|
||||
*/
|
||||
extern void nis_ping __P ((__const nis_name, __const u_long,
|
||||
__const nis_object *));
|
||||
extern nis_result *nis_checkpoint __P ((__const nis_name));
|
||||
extern void nis_ping __P ((const_nis_name dirname, u_long utime,
|
||||
const nis_object *dirobj));
|
||||
extern nis_result *nis_checkpoint __P ((const_nis_name dirname));
|
||||
|
||||
/*
|
||||
** nis_print (XXX INTERNAL FUNCTIONS, SHOULD NOT BE USED !!)
|
||||
*/
|
||||
extern void nis_print_result __P ((__const nis_result *));
|
||||
extern void nis_print_rights __P ((__const u_long));
|
||||
extern void nis_print_directory __P ((__const directory_obj *));
|
||||
extern void nis_print_group __P ((__const group_obj *));
|
||||
extern void nis_print_table __P ((__const table_obj *));
|
||||
extern void nis_print_link __P ((__const link_obj *));
|
||||
extern void nis_print_entry __P ((__const entry_obj *));
|
||||
extern void nis_print_result __P ((const nis_result *result));
|
||||
extern void nis_print_rights __P ((u_long rights));
|
||||
extern void nis_print_directory __P ((const directory_obj *dirobj));
|
||||
extern void nis_print_group __P ((const group_obj *grpobj));
|
||||
extern void nis_print_table __P ((const table_obj *tblobj));
|
||||
extern void nis_print_link __P ((const link_obj *lnkobj));
|
||||
extern void nis_print_entry __P ((const entry_obj *enobj));
|
||||
|
||||
/*
|
||||
** nis_file (XXX INTERNAL FUNCTIONS, SHOULD NOT BE USED !!)
|
||||
*/
|
||||
extern directory_obj *readColdStartFile __P ((void));
|
||||
extern bool_t writeColdStartFile __P ((__const directory_obj *));
|
||||
extern nis_object *nis_read_obj __P ((__const char *));
|
||||
extern bool_t nis_write_obj __P ((__const char *, __const nis_object *));
|
||||
extern bool_t writeColdStartFile __P ((const directory_obj *dirobj));
|
||||
extern nis_object *nis_read_obj __P ((const char *obj));
|
||||
extern bool_t nis_write_obj __P ((const char *file, const nis_object *obj));
|
||||
|
||||
/*
|
||||
** nis_clone - (XXX INTERNAL FUNCTIONS, SHOULD NOT BE USED !!)
|
||||
*/
|
||||
extern directory_obj *nis_clone_directory __P ((const directory_obj *src,
|
||||
directory_obj *dest));
|
||||
extern group_obj *nis_clone_group __P ((const group_obj *src,
|
||||
group_obj *dest));
|
||||
extern table_obj *nis_clone_table __P ((const table_obj *src,
|
||||
table_obj *dest));
|
||||
extern entry_obj *nis_clone_entry __P ((const entry_obj *src,
|
||||
entry_obj *dest));
|
||||
extern link_obj *nis_clone_link __P ((const link_obj *src, link_obj *dest));
|
||||
extern objdata *nis_clone_objdata __P ((const objdata *src, objdata *dest));
|
||||
extern nis_result *nis_clone_result __P ((const nis_result *src,
|
||||
nis_result *dest));
|
||||
|
||||
extern directory_obj *nis_clone_directory __P ((__const directory_obj *,
|
||||
directory_obj *));
|
||||
extern group_obj *nis_clone_group __P ((__const group_obj *, group_obj *));
|
||||
extern table_obj *nis_clone_table __P ((__const table_obj *, table_obj *));
|
||||
extern entry_obj *nis_clone_entry __P ((__const entry_obj *, entry_obj *));
|
||||
extern link_obj *nis_clone_link __P ((__const link_obj *, link_obj *));
|
||||
extern objdata *nis_clone_objdata __P ((__const objdata *, objdata *));
|
||||
extern nis_result *nis_clone_result __P ((__const nis_result *, nis_result *));
|
||||
/*
|
||||
** nis_free - nis_freeresult
|
||||
*/
|
||||
extern void nis_freeresult __P ((nis_result *));
|
||||
/* (XXX INTERNAL FUNCTIONS, SHOULD NOT BE USED !!) */
|
||||
extern void nis_free_attr __P ((nis_attr *));
|
||||
extern void nis_free_request __P ((ib_request *));
|
||||
extern void nis_free_endpoints __P ((endpoint *, unsigned int));
|
||||
extern void nis_free_servers __P ((nis_server *, unsigned int));
|
||||
extern void nis_free_directory __P ((directory_obj *));
|
||||
extern void nis_free_group __P ((group_obj *));
|
||||
extern void nis_free_table __P ((table_obj *));
|
||||
extern void nis_free_entry __P ((entry_obj *));
|
||||
extern void nis_free_link __P ((link_obj *));
|
||||
extern void nis_free_object __P ((nis_object *));
|
||||
extern void nis_freeresult __P ((nis_result *result));
|
||||
/* (XXX THE FOLLOWING ARE INTERNAL FUNCTIONS, SHOULD NOT BE USED !!) */
|
||||
extern void nis_free_attr __P ((nis_attr *attr));
|
||||
extern void nis_free_request __P ((ib_request *req));
|
||||
extern void nis_free_endpoints __P ((endpoint *ep, unsigned int count));
|
||||
extern void nis_free_servers __P ((nis_server *machine, unsigned int count));
|
||||
extern void nis_free_directory __P ((directory_obj *dirobj));
|
||||
extern void nis_free_group __P ((group_obj *grpobj));
|
||||
extern void nis_free_table __P ((table_obj *tblobj));
|
||||
extern void nis_free_entry __P ((entry_obj *enobj));
|
||||
extern void nis_free_link __P ((link_obj *lnkobj));
|
||||
extern void nis_free_object __P ((nis_object *obj));
|
||||
|
||||
/* This is the SUN definition, but I don't know for what we need
|
||||
the directory_obj parameter */
|
||||
/* extern fd_result *nis_finddirectory __P ((directory_obj *, nis_name)); */
|
||||
extern fd_result *__nis_finddirectory __P ((nis_name));
|
||||
extern fd_result *__nis_finddirectory __P ((const_nis_name name));
|
||||
extern int __start_clock(int);
|
||||
extern u_long __stop_clock(int);
|
||||
|
||||
|
||||
+4
-3
@@ -21,6 +21,7 @@
|
||||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
#include <libc-lock.h>
|
||||
#include <rpc/rpc.h>
|
||||
#include <rpcsvc/yp.h>
|
||||
#include <rpcsvc/ypclnt.h>
|
||||
#include <rpcsvc/ypupd.h>
|
||||
@@ -781,7 +782,7 @@ int
|
||||
yp_update (char *domain, char *map, unsigned ypop,
|
||||
char *key, int keylen, char *data, int datalen)
|
||||
{
|
||||
#if 0
|
||||
#if defined (HAVE_SECURE_RPC)
|
||||
union
|
||||
{
|
||||
ypupdate_args update_args;
|
||||
@@ -847,8 +848,8 @@ yp_update (char *domain, char *map, unsigned ypop,
|
||||
clnt->cl_auth = authunix_create_default ();
|
||||
|
||||
again:
|
||||
r = clnt_call (clnt, ypop, xdr_argument, &args,
|
||||
(xdrproc_t) xdr_u_int, &res, TIMEOUT);
|
||||
r = clnt_call (clnt, ypop, xdr_argument, (caddr_t) &args,
|
||||
(xdrproc_t) xdr_u_int, (caddr_t) &res, TIMEOUT);
|
||||
|
||||
if (r == RPC_AUTHERROR)
|
||||
{
|
||||
|
||||
@@ -122,6 +122,9 @@ FUNCTION_NAME (ADD_PARAMS)
|
||||
buffer = new_buf;
|
||||
}
|
||||
|
||||
if (buffer == NULL)
|
||||
result = NULL;
|
||||
|
||||
#ifdef HANDLE_DIGITS_DOTS
|
||||
done:
|
||||
#endif
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user