]> git.ipfire.org Git - thirdparty/glibc.git/commitdiff
Update. cvs/libc-ud-971207
authorUlrich Drepper <drepper@redhat.com>
Mon, 8 Dec 1997 03:06:47 +0000 (03:06 +0000)
committerUlrich Drepper <drepper@redhat.com>
Mon, 8 Dec 1997 03:06:47 +0000 (03:06 +0000)
1997-12-08 03:24  Ulrich Drepper  <drepper@cygnus.com>

* Makeconfig: Define $(rt) to rt if linuxthreads is available.
* Makefile (subdirs): Replace rt by $(rt).

* shlib-versions: Use version .2 for NSS modules.

* grp/fgetgrent_r.c (LINE_PARSER): Call parse_line with extra
argument.
* pwd/fgetpwent_r.c: Likewise.
* spwd/fgetspent_r.c: Likewise.
* spwd/sgetspent_r.c: Likewise.
* hesiod/nss_hesiod/hesiod-grp.c (lookup): Add new argument.
Store error number in *ERRNOP.  Little optimization.
* hesiod/nss_hesiod/hesiod-pwd.c: Likewise.
* hesiod/nss_hesiod/hesiod-service.c: Likewise.
* inet/getnetgrent_r.c (__internal_setnetgrent_reuse): Likewise.
(__internal_getnetgrent_r): New argument.
Call __internal_setnetgrent_reuse with new argument.
(__getnetgrent_r): Call __internal_getnetgrent_r with new argument.
* inet/netgroup.h: Add argument to prototypes.
* nis/nisplus-parser.h: Likewise.
* nis/nss_compat/compat-grp.c: Change everything to store error
code through provided pointer and not use errno.
* nis/nss_compat/compat-pwd.c: Likewise.
* nis/nss_compat/compat-spwd.c: Likewise.
* nis/nss_nis/nis-alias.c: Likewise.
* nis/nss_nis/nis-ethers.c: Likewise.
* nis/nss_nis/nis-grp.c: Likewise.
* nis/nss_nis/nis-hosts.c: Likewise.
* nis/nss_nis/nis-netgrp.c: Likewise.
* nis/nss_nis/nis-network.c: Likewise.
* nis/nss_nis/nis-proto.c: Likewise.
* nis/nss_nis/nis-publickey.c: Likewise.
* nis/nss_nis/nis-pwd.c: Likewise.
* nis/nss_nis/nis-rpc.c: Likewise.
* nis/nss_nis/nis-service.c: Likewise.
* nis/nss_nis/nis-spwd.c: Likewise.
* nis/nss_nisplus/nisplus-alias.c: Likewise.
* nis/nss_nisplus/nisplus-ethers.c: Likewise.
* nis/nss_nisplus/nisplus-grp.c: Likewise.
* nis/nss_nisplus/nisplus-hosts.c: Likewise.
* nis/nss_nisplus/nisplus-netgrp.c: Likewise.
* nis/nss_nisplus/nisplus-network.c: Likewise.
* nis/nss_nisplus/nisplus-parser.c: Likewise.
* nis/nss_nisplus/nisplus-proto.c: Likewise.
* nis/nss_nisplus/nisplus-publickey.c: Likewise.
* nis/nss_nisplus/nisplus-pwd.c: Likewise.
* nis/nss_nisplus/nisplus-rpc.c: Likewise.
* nis/nss_nisplus/nisplus-service.c: Likewise.
* nis/nss_nisplus/nisplus-spwd.c: Likewise.
* nss/nss_db/db-XXX.c: Likewise.
* nss/nss_db/db-alias.c: Likewise.
* nss/nss_db/db-netgrp.c: Likewise.
* nss/nss_files/files-XXX.c: Likewise
* nss/nss_files/files-alias.c: Likewise
* nss/nss_files/files-netgrp.c: Likewise
* nss/nss_files/files-parse.c: Likewise
* nss/getXXbyYY_r.c: Call with __errno_location() as value for new
parameter of get functions.
* nss/getXXent_r.c: Likewise.

* localedata/tst-fmon.c: Print debug info if test fails.

* rt/Makefile (routines): Add aio_notify.
* rt/aio.h: Remove non-public definitions.  Add aioinit stuff.
* rt/aio_cancel.c: Rewrite to support lio_listio and aio_suspend.
* rt/aio_fsync.c: Likewise.
* rt/aio_misc.c: Likewise.
* rt/aio_misc.h: Likewise.
* rt/aio_read.c: Likewise.
* rt/aio_read64.c: Likewise.
* rt/aio_suspend.c: Likewise.
* rt/aio_write.c: Likewise.
* rt/aio_write64.c: Likewise.
* rt/lio_listio.c: Likewise.
* rt/lio_listio64.c: Likewise.
* rt/aio_notify.c: New file.

* sysdeps/generic/bits/sigset.h: Pretty print.

* sysdeps/posix/pwrite.c: Define weak alias only if function is
really defined as __pwrite.

* sysdeps/unix/sysv/linux/pread.c: Rewrite to use syscall directly
instead of pread64.
* sysdeps/unix/sysv/linux/pwrite.c: Likewise.

* sysdeps/unix/sysv/linux/Makefile [$(subdir)=signal]
(sysdep_routines): Add rt_sigpending and rt_sigreturn.
* sysdeps/unix/sysv/linux/sigaction.c: Use correct value for sigset_t
size in syscall.
* sysdeps/unix/sysv/linux/sigpending.c: Likewise.
* sysdeps/unix/sysv/linux/sigprocmask.c: Likewise.
* sysdeps/unix/sysv/linux/sigreturn.c: Likewise.
* sysdeps/unix/sysv/linux/sigsuspend.c: Likewise.
* sysdeps/unix/sysv/linux/sigtimedwait.c: Likewise.
* sysdeps/unix/sysv/linux/sigwaitinfo.c: Likewise.
* sysdeps/unix/sysv/linux/i386/sigaction.c: Likewise.  Take care
for ACT being NULL.
* sysdeps/unix/sysv/linux/syscalls.list: Don't mention user for
RT signals.
* sysdeps/unix/sysv/linux/i386/s_pread64.s: Return ENOSYS if
__NR_pread is not defined.
* sysdeps/unix/sysv/linux/i386/s_pwrite64.s: Return ENOSYS if
__NR_pwrite is not defined.

1997-12-07 11:15  Thorsten Kukuk  <kukuk@vt.uni-paderborn.de>

* nis/nss_compat/compat-grp.c: If buffer is to small, set the file
handle for /etc/group back in some more cases.
* nis/nss_compat/compat-pwd.c: If buffer is to small, set the file
handle for /etc/passwd back in some more cases.
* nis/nss_compat/compat-spwd.c: If buffer is to small, set the file
handle for /etc/shadow back in some more cases.

1997-12-06 17:00  H.J. Lu  <hjl@gnu.org>

* sysdeps/posix/sigblock.c (__sigblock): Don't check int mask
beyound its size.
* sysdeps/posix/sigsetmask.c (__sigsetmask): Ditto.
* sysdeps/posix/sigvec.c (convert_mask, __sigvec): Ditto.

1997-12-06 04:38  Ulrich Drepper  <drepper@cygnus.com>

* sysdeps/wordsize-32/inttypes.h: Rewrite {str,wcs}to{i,u}max
handling.  Don't use macros, we need functions.  Use inline functions
for optimization.
* sysdeps/wordsize-64/inttypes.h: Likewise.
* sysdeps/wordsize-32/Makefile: Add strtoimax, stroumax, wcstoimax,
and wcstoumax.
* sysdeps/wordsize-64/Makefile: Likewise.
* sysdeps/wordsize-32/Dist: Likewise.
* sysdeps/wordsize-64/Dist: Likewise.
* sysdeps/wordsize-32/strtoimax.c: New file.
* sysdeps/wordsize-32/strtoumax.c: New file.
* sysdeps/wordsize-32/wcstoimax.c: New file.
* sysdeps/wordsize-32/wcstoumax.c: New file.
* sysdeps/wordsize-64/strtoimax.c: New file.
* sysdeps/wordsize-64/strtoumax.c: New file.
* sysdeps/wordsize-64/wcstoimax.c: New file.
* sysdeps/wordsize-64/wcstoumax.c: New file.

1997-12-04 10:40  Philip Blundell  <pb@nexus.co.uk>

* sysdeps/generic/wait3.c (__wait3): Use ANSI-style definition so
that transparent union works.
* sysdeps/generic/wait4.c (__wait4): Likewise.
* sysdeps/generic/wait.c (__wait): Likewise.

* sysdeps/generic/getpeername.c (getpeername): Use socklen_t not
size_t.

* sysdeps/generic/syscall.c (syscall): Return value and arg are
long, to match prototype.

* malloc/malloc.c (HAVE_MREMAP): Set to 0 for ARM, as we don't
have mremap() yet.

* sysdeps/generic/usleep.c (usleep): Returns void, to match prototype.

* sysdeps/unix/sysv/linux/arm/syscalls.list: New file.

* sysdeps/generic/bits/time.h: Use __time_t not time_t.

* sysdeps/generic/bits/resource.h: Include <bits/types.h> for
__rlim_t.

* sysdeps/standalone/arm/bits/errno.h (ENOTTY): Added.

* sysdeps/generic/bits/dirent.h (struct dirent64): Added.

* io/sys/stat.h (S_ISLNK): Always false if we don't have
__S_IFLNK.

* sysdeps/standalone/close.c (_STDIO_H): Define before including
<bits/stdio_lim.h>.
* sysdeps/standalone/filedesc.h (_STDIO_H): Likewise.

1997-12-06 01:09  Ulrich Drepper  <drepper@cygnus.com>

* posix/sys/wait.h: Don't use transparent unions in C++.

1997-12-05  Andreas Jaeger  <aj@arthur.rhein-neckar.de>

* time/time.h: Add strfxtime.

* libc.map: Add tcgetsid, strcasestr, wmemrtombs, wmemrtowcs,
sysv_signal, strfxtime, pread64, pwrite64.

1997-11-30 21:57  Richard Henderson  <rth@cygnus.com>

Alpha changes for EGCS:
* config.h.in (ASM_ALPHA_NG_SYMBOL_PREFIX): New entry.
* configure.in (libc_cv_gcc_alpha_ng_prefix): New check.
* sysdeps/alpha/dl-machine.h (_dl_runtime_resolve): Care for prefix.
(_start): Likewise.
* sysdeps/unix/sysv/linux/alpha/init-first.h: Likewise.

125 files changed:
ChangeLog
FAQ.in
Makeconfig
Makefile
bits/dirent.h
bits/resource.h
bits/sigset.h
bits/time.h
config.h.in
configure
configure.in
grp/fgetgrent_r.c
hesiod/nss_hesiod/hesiod-grp.c
hesiod/nss_hesiod/hesiod-pwd.c
hesiod/nss_hesiod/hesiod-service.c
inet/getnetgrent_r.c
inet/netgroup.h
io/sys/stat.h
libc.map
malloc/malloc.c
nis/nisplus-parser.h
nis/nss_compat/compat-grp.c
nis/nss_compat/compat-pwd.c
nis/nss_compat/compat-spwd.c
nis/nss_nis/nis-alias.c
nis/nss_nis/nis-ethers.c
nis/nss_nis/nis-grp.c
nis/nss_nis/nis-hosts.c
nis/nss_nis/nis-netgrp.c
nis/nss_nis/nis-network.c
nis/nss_nis/nis-proto.c
nis/nss_nis/nis-publickey.c
nis/nss_nis/nis-pwd.c
nis/nss_nis/nis-rpc.c
nis/nss_nis/nis-service.c
nis/nss_nis/nis-spwd.c
nis/nss_nisplus/nisplus-alias.c
nis/nss_nisplus/nisplus-ethers.c
nis/nss_nisplus/nisplus-grp.c
nis/nss_nisplus/nisplus-hosts.c
nis/nss_nisplus/nisplus-netgrp.c
nis/nss_nisplus/nisplus-network.c
nis/nss_nisplus/nisplus-parser.c
nis/nss_nisplus/nisplus-proto.c
nis/nss_nisplus/nisplus-publickey.c
nis/nss_nisplus/nisplus-pwd.c
nis/nss_nisplus/nisplus-rpc.c
nis/nss_nisplus/nisplus-service.c
nis/nss_nisplus/nisplus-spwd.c
nss/getXXbyYY_r.c
nss/getXXent_r.c
nss/nss_db/db-XXX.c
nss/nss_db/db-alias.c
nss/nss_db/db-netgrp.c
nss/nss_files/files-XXX.c
nss/nss_files/files-alias.c
nss/nss_files/files-netgrp.c
nss/nss_files/files-parse.c
posix/sys/wait.h
pwd/fgetpwent_r.c
rt/Makefile
rt/aio.h
rt/aio_cancel.c
rt/aio_fsync.c
rt/aio_misc.c
rt/aio_misc.h
rt/aio_notify.c [new file with mode: 0644]
rt/aio_read.c
rt/aio_read64.c
rt/aio_suspend.c
rt/aio_write.c
rt/aio_write64.c
rt/lio_listio.c
rt/lio_listio64.c
shadow/fgetspent_r.c
shadow/sgetspent_r.c
shlib-versions
sysdeps/alpha/dl-machine.h
sysdeps/generic/bits/dirent.h
sysdeps/generic/bits/resource.h
sysdeps/generic/bits/sigset.h
sysdeps/generic/bits/time.h
sysdeps/generic/getpeername.c
sysdeps/generic/syscall.c
sysdeps/generic/usleep.c
sysdeps/generic/wait.c
sysdeps/generic/wait3.c
sysdeps/generic/wait4.c
sysdeps/posix/pwrite.c
sysdeps/posix/sigblock.c
sysdeps/posix/sigsetmask.c
sysdeps/posix/sigvec.c
sysdeps/standalone/arm/bits/errno.h
sysdeps/standalone/close.c
sysdeps/standalone/filedesc.h
sysdeps/unix/sysv/linux/Makefile
sysdeps/unix/sysv/linux/arm/syscalls.list [new file with mode: 0644]
sysdeps/unix/sysv/linux/i386/s_pread64.S
sysdeps/unix/sysv/linux/i386/s_pwrite64.S
sysdeps/unix/sysv/linux/i386/sigaction.c
sysdeps/unix/sysv/linux/pread.c
sysdeps/unix/sysv/linux/pwrite.c
sysdeps/unix/sysv/linux/sigaction.c
sysdeps/unix/sysv/linux/sigpending.c
sysdeps/unix/sysv/linux/sigprocmask.c
sysdeps/unix/sysv/linux/sigreturn.c
sysdeps/unix/sysv/linux/sigsuspend.c
sysdeps/unix/sysv/linux/sigtimedwait.c
sysdeps/unix/sysv/linux/sigwaitinfo.c
sysdeps/unix/sysv/linux/syscalls.list
sysdeps/wordsize-32/Dist
sysdeps/wordsize-32/Makefile
sysdeps/wordsize-32/inttypes.h
sysdeps/wordsize-32/strtoimax.c [new file with mode: 0644]
sysdeps/wordsize-32/strtoumax.c [new file with mode: 0644]
sysdeps/wordsize-32/wcstoimax.c [new file with mode: 0644]
sysdeps/wordsize-32/wcstoumax.c [new file with mode: 0644]
sysdeps/wordsize-64/Dist
sysdeps/wordsize-64/Makefile
sysdeps/wordsize-64/inttypes.h
sysdeps/wordsize-64/strtoimax.c [new file with mode: 0644]
sysdeps/wordsize-64/strtoumax.c [new file with mode: 0644]
sysdeps/wordsize-64/wcstoimax.c [new file with mode: 0644]
sysdeps/wordsize-64/wcstoumax.c [new file with mode: 0644]
time/time.h

index f9a3fce48e506c00d1740ae0a6406369cc5b28de..fc0222df14f18ead332d5cc35ad0e289d48f2c38 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,202 @@
+1997-12-08 03:24  Ulrich Drepper  <drepper@cygnus.com>
+
+       * Makeconfig: Define $(rt) to rt if linuxthreads is available.
+       * Makefile (subdirs): Replace rt by $(rt).
+
+       * shlib-versions: Use version .2 for NSS modules.
+
+       * grp/fgetgrent_r.c (LINE_PARSER): Call parse_line with extra
+       argument.
+       * pwd/fgetpwent_r.c: Likewise.
+       * spwd/fgetspent_r.c: Likewise.
+       * spwd/sgetspent_r.c: Likewise.
+       * hesiod/nss_hesiod/hesiod-grp.c (lookup): Add new argument.
+       Store error number in *ERRNOP.  Little optimization.
+       * hesiod/nss_hesiod/hesiod-pwd.c: Likewise.
+       * hesiod/nss_hesiod/hesiod-service.c: Likewise.
+       * inet/getnetgrent_r.c (__internal_setnetgrent_reuse): Likewise.
+       (__internal_getnetgrent_r): New argument.
+       Call __internal_setnetgrent_reuse with new argument.
+       (__getnetgrent_r): Call __internal_getnetgrent_r with new argument.
+       * inet/netgroup.h: Add argument to prototypes.
+       * nis/nisplus-parser.h: Likewise.
+       * nis/nss_compat/compat-grp.c: Change everything to store error
+       code through provided pointer and not use errno.
+       * nis/nss_compat/compat-pwd.c: Likewise.
+       * nis/nss_compat/compat-spwd.c: Likewise.
+       * nis/nss_nis/nis-alias.c: Likewise.
+       * nis/nss_nis/nis-ethers.c: Likewise.
+       * nis/nss_nis/nis-grp.c: Likewise.
+       * nis/nss_nis/nis-hosts.c: Likewise.
+       * nis/nss_nis/nis-netgrp.c: Likewise.
+       * nis/nss_nis/nis-network.c: Likewise.
+       * nis/nss_nis/nis-proto.c: Likewise.
+       * nis/nss_nis/nis-publickey.c: Likewise.
+       * nis/nss_nis/nis-pwd.c: Likewise.
+       * nis/nss_nis/nis-rpc.c: Likewise.
+       * nis/nss_nis/nis-service.c: Likewise.
+       * nis/nss_nis/nis-spwd.c: Likewise.
+       * nis/nss_nisplus/nisplus-alias.c: Likewise.
+       * nis/nss_nisplus/nisplus-ethers.c: Likewise.
+       * nis/nss_nisplus/nisplus-grp.c: Likewise.
+       * nis/nss_nisplus/nisplus-hosts.c: Likewise.
+       * nis/nss_nisplus/nisplus-netgrp.c: Likewise.
+       * nis/nss_nisplus/nisplus-network.c: Likewise.
+       * nis/nss_nisplus/nisplus-parser.c: Likewise.
+       * nis/nss_nisplus/nisplus-proto.c: Likewise.
+       * nis/nss_nisplus/nisplus-publickey.c: Likewise.
+       * nis/nss_nisplus/nisplus-pwd.c: Likewise.
+       * nis/nss_nisplus/nisplus-rpc.c: Likewise.
+       * nis/nss_nisplus/nisplus-service.c: Likewise.
+       * nis/nss_nisplus/nisplus-spwd.c: Likewise.
+       * nss/nss_db/db-XXX.c: Likewise.
+       * nss/nss_db/db-alias.c: Likewise.
+       * nss/nss_db/db-netgrp.c: Likewise.
+       * nss/nss_files/files-XXX.c: Likewise
+       * nss/nss_files/files-alias.c: Likewise
+       * nss/nss_files/files-netgrp.c: Likewise
+       * nss/nss_files/files-parse.c: Likewise
+       * nss/getXXbyYY_r.c: Call with __errno_location() as value for new
+       parameter of get functions.
+       * nss/getXXent_r.c: Likewise.
+
+       * localedata/tst-fmon.c: Print debug info if test fails.
+
+       * rt/Makefile (routines): Add aio_notify.
+       * rt/aio.h: Remove non-public definitions.  Add aioinit stuff.
+       * rt/aio_cancel.c: Rewrite to support lio_listio and aio_suspend.
+       * rt/aio_fsync.c: Likewise.
+       * rt/aio_misc.c: Likewise.
+       * rt/aio_misc.h: Likewise.
+       * rt/aio_read.c: Likewise.
+       * rt/aio_read64.c: Likewise.
+       * rt/aio_suspend.c: Likewise.
+       * rt/aio_write.c: Likewise.
+       * rt/aio_write64.c: Likewise.
+       * rt/lio_listio.c: Likewise.
+       * rt/lio_listio64.c: Likewise.
+       * rt/aio_notify.c: New file.
+
+       * sysdeps/generic/bits/sigset.h: Pretty print.
+
+       * sysdeps/posix/pwrite.c: Define weak alias only if function is
+       really defined as __pwrite.
+
+       * sysdeps/unix/sysv/linux/pread.c: Rewrite to use syscall directly
+       instead of pread64.
+       * sysdeps/unix/sysv/linux/pwrite.c: Likewise.
+
+       * sysdeps/unix/sysv/linux/Makefile [$(subdir)=signal]
+       (sysdep_routines): Add rt_sigpending and rt_sigreturn.
+       * sysdeps/unix/sysv/linux/sigaction.c: Use correct value for sigset_t
+       size in syscall.
+       * sysdeps/unix/sysv/linux/sigpending.c: Likewise.
+       * sysdeps/unix/sysv/linux/sigprocmask.c: Likewise.
+       * sysdeps/unix/sysv/linux/sigreturn.c: Likewise.
+       * sysdeps/unix/sysv/linux/sigsuspend.c: Likewise.
+       * sysdeps/unix/sysv/linux/sigtimedwait.c: Likewise.
+       * sysdeps/unix/sysv/linux/sigwaitinfo.c: Likewise.
+       * sysdeps/unix/sysv/linux/i386/sigaction.c: Likewise.  Take care
+       for ACT being NULL.
+       * sysdeps/unix/sysv/linux/syscalls.list: Don't mention user for
+       RT signals.
+       * sysdeps/unix/sysv/linux/i386/s_pread64.s: Return ENOSYS if
+       __NR_pread is not defined.
+       * sysdeps/unix/sysv/linux/i386/s_pwrite64.s: Return ENOSYS if
+       __NR_pwrite is not defined.
+
+1997-12-07 11:15  Thorsten Kukuk  <kukuk@vt.uni-paderborn.de>
+
+       * nis/nss_compat/compat-grp.c: If buffer is to small, set the file
+       handle for /etc/group back in some more cases.
+       * nis/nss_compat/compat-pwd.c: If buffer is to small, set the file
+       handle for /etc/passwd back in some more cases.
+       * nis/nss_compat/compat-spwd.c: If buffer is to small, set the file
+       handle for /etc/shadow back in some more cases.
+
+1997-12-06 17:00  H.J. Lu  <hjl@gnu.org>
+
+       * sysdeps/posix/sigblock.c (__sigblock): Don't check int mask
+       beyound its size.
+       * sysdeps/posix/sigsetmask.c (__sigsetmask): Ditto.
+       * sysdeps/posix/sigvec.c (convert_mask, __sigvec): Ditto.
+
+1997-12-06 04:38  Ulrich Drepper  <drepper@cygnus.com>
+
+       * sysdeps/wordsize-32/inttypes.h: Rewrite {str,wcs}to{i,u}max
+       handling.  Don't use macros, we need functions.  Use inline functions
+       for optimization.
+       * sysdeps/wordsize-64/inttypes.h: Likewise.
+       * sysdeps/wordsize-32/Makefile: Add strtoimax, stroumax, wcstoimax,
+       and wcstoumax.
+       * sysdeps/wordsize-64/Makefile: Likewise.
+       * sysdeps/wordsize-32/Dist: Likewise.
+       * sysdeps/wordsize-64/Dist: Likewise.
+       * sysdeps/wordsize-32/strtoimax.c: New file.
+       * sysdeps/wordsize-32/strtoumax.c: New file.
+       * sysdeps/wordsize-32/wcstoimax.c: New file.
+       * sysdeps/wordsize-32/wcstoumax.c: New file.
+       * sysdeps/wordsize-64/strtoimax.c: New file.
+       * sysdeps/wordsize-64/strtoumax.c: New file.
+       * sysdeps/wordsize-64/wcstoimax.c: New file.
+       * sysdeps/wordsize-64/wcstoumax.c: New file.
+
+1997-12-04 10:40  Philip Blundell  <pb@nexus.co.uk>
+
+       * sysdeps/generic/wait3.c (__wait3): Use ANSI-style definition so
+       that transparent union works.
+       * sysdeps/generic/wait4.c (__wait4): Likewise.
+       * sysdeps/generic/wait.c (__wait): Likewise.
+
+       * sysdeps/generic/getpeername.c (getpeername): Use socklen_t not
+       size_t.
+
+       * sysdeps/generic/syscall.c (syscall): Return value and arg are
+       long, to match prototype.
+
+       * malloc/malloc.c (HAVE_MREMAP): Set to 0 for ARM, as we don't
+       have mremap() yet.
+
+       * sysdeps/generic/usleep.c (usleep): Returns void, to match prototype.
+
+       * sysdeps/unix/sysv/linux/arm/syscalls.list: New file.
+
+       * sysdeps/generic/bits/time.h: Use __time_t not time_t.
+
+       * sysdeps/generic/bits/resource.h: Include <bits/types.h> for
+       __rlim_t.
+
+       * sysdeps/standalone/arm/bits/errno.h (ENOTTY): Added.
+
+       * sysdeps/generic/bits/dirent.h (struct dirent64): Added.
+
+       * io/sys/stat.h (S_ISLNK): Always false if we don't have
+       __S_IFLNK.
+
+       * sysdeps/standalone/close.c (_STDIO_H): Define before including
+       <bits/stdio_lim.h>.
+       * sysdeps/standalone/filedesc.h (_STDIO_H): Likewise.
+
+1997-12-06 01:09  Ulrich Drepper  <drepper@cygnus.com>
+
+       * posix/sys/wait.h: Don't use transparent unions in C++.
+
+1997-12-05  Andreas Jaeger  <aj@arthur.rhein-neckar.de>
+
+       * time/time.h: Add strfxtime.
+
+       * libc.map: Add tcgetsid, strcasestr, wmemrtombs, wmemrtowcs,
+       sysv_signal, strfxtime, pread64, pwrite64.
+
+1997-11-30 21:57  Richard Henderson  <rth@cygnus.com>
+
+       Alpha changes for EGCS:
+       * config.h.in (ASM_ALPHA_NG_SYMBOL_PREFIX): New entry.
+       * configure.in (libc_cv_gcc_alpha_ng_prefix): New check.
+       * sysdeps/alpha/dl-machine.h (_dl_runtime_resolve): Care for prefix.
+       (_start): Likewise.
+       * sysdeps/unix/sysv/linux/alpha/init-first.h: Likewise.
+
 1997-12-05 00:01  Ulrich Drepper  <drepper@cygnus.com>
 
        The kernel expects the arguments in a different order.
diff --git a/FAQ.in b/FAQ.in
index 770bef4133dac05f036be76f84f8212b569bc1f6..edc0c29e7a0a9281ea294438c81f01bb1112dc96 100644 (file)
--- a/FAQ.in
+++ b/FAQ.in
@@ -469,7 +469,7 @@ catalog files to the XPG4 form:
 ??     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.
 
-{??} The glibc NIS+ implementation uses a /var/nis/NIS_COLD_START
+{TK} 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 does not contain all the necessary
 information.  You have to copy a NIS_COLD_START file from a Solaris
@@ -780,6 +780,7 @@ Answers were given by:
 {PB} Phil Blundell, <Philip.Blundell@pobox.com>
 {MK} Mark Kettenis, <kettenis@phys.uva.nl>
 {ZW} Zack Weinberg, <zack@rabi.phys.columbia.edu>
+{TK} Thorsten Kukuk, <kukuk@vt.uni-paderborn.de>
 \f
 Local Variables:
  mode:outline
index 44afe0fe30454a7b6ad26b44a0eed492e5058c44..1f0f96e8a3a14318680521ef27866c2be9811445 100644 (file)
@@ -692,6 +692,8 @@ endif
 # for now.
 ifneq (,$(findstring linuxthreads,$(add-ons)))
 shared-thread-library = $(common-objpfx)linuxthreads/libpthread.so
+# Yes, we can compile librt.
+rt = rt
 endif
 
 endif # build-shared
index 2c0785b8d38f676423649169b599d3d8be8afd29..dbacf8b6697d942701ca3ad9824244944a905136 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -55,7 +55,7 @@ subdirs = csu assert ctype db2 locale intl catgets math setjmp signal stdlib \
          stdio-common $(stdio) malloc string wcsmbs time dirent grp pwd \
          posix io termios resource misc socket sysvipc gmon gnulib iconv \
          iconvdata wctype manual shadow md5-crypt po argp $(add-ons) nss \
-         localedata rt $(sysdep-subdirs) $(binfmt-subdir)
+         localedata $(rt) $(sysdep-subdirs) $(binfmt-subdir)
 export subdirs := $(subdirs)   # Benign, useless in GNU make before 3.63.
 
 # The mach and hurd subdirectories have many generated header files which
index 366cdf8ce2295f94bd46e6516e2f93849d304ebb..d0745895621255934e4a37627bd5f1f130859f91 100644 (file)
@@ -26,3 +26,12 @@ struct dirent
     char d_name[1];            /* Variable length.  */
     int d_fileno;
   };
+
+#ifdef __USE_LARGEFILE64
+struct dirent64
+  {
+    char d_name[1];            /* Variable length.  */
+    int d_fileno;
+  };
+#endif
+
index d0ebeb56c8346a9bcb0ee6b516026a776ab1a58b..e72836d3c742f3bd426bca4d693ef7ceb9679394 100644 (file)
@@ -21,6 +21,8 @@
 # error "Never use <bits/resource.h> directly; include <sys/resource.h> instead."
 #endif
 
+#include <bits/types.h>
+
 /* These are the values for 4.4 BSD and GNU.  Earlier BSD systems have a
    subset of these kinds of resource limit.  In systems where `getrlimit'
    and `setrlimit' are not system calls, these are the values used by the C
index 9fad4538d7872114a97fa06db86e76a3a79c581f..c442d53643ec1c22387189ecd1d3d537ed960186 100644 (file)
@@ -34,7 +34,7 @@ typedef unsigned long int __sigset_t;
    trouble can be caused by functions being defined (e.g., any global
    register vars declared later will cause compilation errors).  */
 
-#if !defined (_SIGSET_H_fns) && defined (_SIGNAL_H)
+#if !defined _SIGSET_H_fns && defined _SIGNAL_H
 #define _SIGSET_H_fns 1
 
 #ifndef _EXTERN_INLINE
index cdbd39f91d97fa30f0fe1d4fba6302e05a62420f..f608e2c99622fcdf664b55ee7923f540365d8578 100644 (file)
@@ -39,8 +39,8 @@
    microsecond but also has a range of years.  */
 struct timeval
   {
-    time_t tv_sec;             /* Seconds.  */
-    time_t tv_usec;            /* Microseconds.  */
+    __time_t tv_sec;           /* Seconds.  */
+    __time_t tv_usec;          /* Microseconds.  */
   };
 # endif        /* struct timeval */
 #endif /* need timeval */
index f2fa9167d377d7bbe7b742bc7679aeee0a151732..a38900b64aecb468b3cf7e3bad853c6ab209e383 100644 (file)
@@ -43,6 +43,9 @@
    directive.  */
 #undef HAVE_ASM_POPSECTION_DIRECTIVE
 
+/* Define to the prefix Alpha/ELF GCC emits before ..ng symbols.  */
+#undef  ASM_ALPHA_NG_SYMBOL_PREFIX
+
 /* Define if versioning of the library is wanted.  */
 #undef DO_VERSIONING
 
index b6fd050e165e1c96255d677c9802a4403c086c2b..133194c598077d38ed47cade4d0c1597b82157c9 100755 (executable)
--- a/configure
+++ b/configure
@@ -49,7 +49,8 @@ ac_help="$ac_help
   --disable-versioning    do not include versioning information in the
                           library objects [default=yes if supported]"
 ac_help="$ac_help
-  --enable-add-ons=DIR1,DIR2... configure and build named extra directories"
+  --enable-add-ons[=DIR1,DIR2]... configure and build add-ons in DIR1,DIR2,...
+                                  search for add-ons if no parameter given"
 ac_help="$ac_help
   --enable-static-nss     build static NSS modules [default=no]"
 
@@ -757,7 +758,7 @@ else { echo "configure: error: can not run $ac_config_sub" 1>&2; exit 1; }
 fi
 
 echo $ac_n "checking host system type""... $ac_c" 1>&6
-echo "configure:761: checking host system type" >&5
+echo "configure:762: checking host system type" >&5
 
 host_alias=$host
 case "$host_alias" in
@@ -876,7 +877,7 @@ fi
 # This can take a while to compute.
 sysdep_dir=$srcdir/sysdeps
 echo $ac_n "checking sysdep dirs""... $ac_c" 1>&6
-echo "configure:880: checking sysdep dirs" >&5
+echo "configure:881: 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'`"
 
@@ -1077,7 +1078,7 @@ echo "$ac_t""sysdeps/generic" 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:1081: checking for a BSD compatible install" >&5
+echo "configure:1082: 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
@@ -1131,7 +1132,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:1135: checking whether ln -s works" >&5
+echo "configure:1136: 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
@@ -1156,7 +1157,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:1160: checking for $ac_word" >&5
+echo "configure:1161: 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
@@ -1188,7 +1189,7 @@ test -n "$MSGFMT" || MSGFMT=":"
 # Extract the first word of "makeinfo", so it can be a program name with args.
 set dummy makeinfo; ac_word=$2
 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:1192: checking for $ac_word" >&5
+echo "configure:1193: checking for $ac_word" >&5
 if eval "test \"`echo '$''{'ac_cv_prog_MAKEINFO'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -1228,7 +1229,7 @@ fi
 # 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:1232: checking for $ac_word" >&5
+echo "configure:1233: 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
@@ -1257,7 +1258,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:1261: checking for $ac_word" >&5
+echo "configure:1262: 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
@@ -1305,7 +1306,7 @@ fi
 fi
 
 echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works""... $ac_c" 1>&6
-echo "configure:1309: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works" >&5
+echo "configure:1310: 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.
@@ -1315,11 +1316,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 1319 "configure"
+#line 1320 "configure"
 #include "confdefs.h"
 main(){return(0);}
 EOF
-if { (eval echo configure:1323: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
+if { (eval echo configure:1324: \"$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
@@ -1342,13 +1343,13 @@ else
  cross_linkable=yes
 fi
 echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler""... $ac_c" 1>&6
-echo "configure:1346: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler" >&5
+echo "configure:1347: 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:1352: checking whether we are using GNU C" >&5
+echo "configure:1353: 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
@@ -1357,7 +1358,7 @@ else
   yes;
 #endif
 EOF
-if { ac_try='${CC-cc} -E conftest.c'; { (eval echo configure:1361: \"$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:1362: \"$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
@@ -1374,7 +1375,7 @@ if test $ac_cv_prog_gcc = yes; then
   yes;
 #endif
 EOF
-  if { ac_try='${CC-cc} -E conftest.c'; { (eval echo configure:1378: \"$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:1379: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; } | egrep yes >/dev/null 2>&1; then
     if test -z "$CFLAGS"; then
       CFLAGS="-g -O2"
     fi
@@ -1386,7 +1387,7 @@ else
 fi
 
 echo $ac_n "checking build system type""... $ac_c" 1>&6
-echo "configure:1390: checking build system type" >&5
+echo "configure:1391: checking build system type" >&5
 
 build_alias=$build
 case "$build_alias" in
@@ -1409,7 +1410,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:1413: checking for $ac_word" >&5
+echo "configure:1414: 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
@@ -1440,7 +1441,7 @@ done
 fi
 
 echo $ac_n "checking how to run the C preprocessor""... $ac_c" 1>&6
-echo "configure:1444: checking how to run the C preprocessor" >&5
+echo "configure:1445: checking how to run the C preprocessor" >&5
 # On Suns, sometimes $CPP names a directory.
 if test -n "$CPP" && test -d "$CPP"; then
   CPP=
@@ -1455,13 +1456,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 1459 "configure"
+#line 1460 "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:1465: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:1466: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
 ac_err=`grep -v '^ *+' conftest.out`
 if test -z "$ac_err"; then
   :
@@ -1472,13 +1473,13 @@ else
   rm -rf conftest*
   CPP="${CC-cc} -E -traditional-cpp"
   cat > conftest.$ac_ext <<EOF
-#line 1476 "configure"
+#line 1477 "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:1482: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:1483: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
 ac_err=`grep -v '^ *+' conftest.out`
 if test -z "$ac_err"; then
   :
@@ -1511,7 +1512,7 @@ LD=`$CC -print-file-name=ld`
 
 # Determine whether we are using GNU binutils.
 echo $ac_n "checking whether $AS is GNU as""... $ac_c" 1>&6
-echo "configure:1515: checking whether $AS is GNU as" >&5
+echo "configure:1516: checking whether $AS is GNU as" >&5
 if eval "test \"`echo '$''{'libc_cv_prog_as_gnu'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -1529,7 +1530,7 @@ rm -f a.out
 gnu_as=$libc_cv_prog_as_gnu
 
 echo $ac_n "checking whether $LD is GNU ld""... $ac_c" 1>&6
-echo "configure:1533: checking whether $LD is GNU ld" >&5
+echo "configure:1534: checking whether $LD is GNU ld" >&5
 if eval "test \"`echo '$''{'libc_cv_prog_ld_gnu'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -1553,7 +1554,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:1557: checking for $ac_word" >&5
+echo "configure:1558: 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
@@ -1584,7 +1585,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:1588: checking for $ac_word" >&5
+echo "configure:1589: 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
@@ -1615,7 +1616,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:1619: checking for $ac_word" >&5
+echo "configure:1620: 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
@@ -1650,7 +1651,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:1654: checking for $ac_word" >&5
+echo "configure:1655: 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
@@ -1692,7 +1693,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:1696: checking for $ac_word" >&5
+echo "configure:1697: 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
@@ -1738,7 +1739,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:1742: checking for $ac_word" >&5
+echo "configure:1743: checking for $ac_word" >&5
 if eval "test \"`echo '$''{'ac_cv_path_PERL'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -1773,7 +1774,7 @@ test -n "$PERL" || PERL="no"
 
 
 echo $ac_n "checking for signed size_t type""... $ac_c" 1>&6
-echo "configure:1777: checking for signed size_t type" >&5
+echo "configure:1778: 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
@@ -1797,12 +1798,12 @@ EOF
 fi
 
 echo $ac_n "checking for libc-friendly stddef.h""... $ac_c" 1>&6
-echo "configure:1801: checking for libc-friendly stddef.h" >&5
+echo "configure:1802: 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 1806 "configure"
+#line 1807 "configure"
 #include "confdefs.h"
 #define __need_size_t
 #define __need_wchar_t
@@ -1817,7 +1818,7 @@ size_t size; wchar_t wchar;
 if (&size == NULL || &wchar == NULL) abort ();
 ; return 0; }
 EOF
-if { (eval echo configure:1821: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:1822: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
   rm -rf conftest*
   libc_cv_friendly_stddef=yes
 else
@@ -1836,7 +1837,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:1840: checking whether we need to use -P to assemble .S files" >&5
+echo "configure:1841: 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
@@ -1867,7 +1868,7 @@ if test $ac_cv_prog_gcc = yes; then
   # We must check this even if -pipe is not given here, because the user
   # might do `make CFLAGS=-pipe'.
   echo $ac_n "checking for gcc 2.7.x -pipe bug""... $ac_c" 1>&6
-echo "configure:1871: checking for gcc 2.7.x -pipe bug" >&5
+echo "configure:1872: checking for gcc 2.7.x -pipe bug" >&5
 if eval "test \"`echo '$''{'libc_cv_gcc_pipe_bug'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -1896,7 +1897,7 @@ else
 fi
 
 echo $ac_n "checking for assembler global-symbol directive""... $ac_c" 1>&6
-echo "configure:1900: checking for assembler global-symbol directive" >&5
+echo "configure:1901: 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
@@ -1926,7 +1927,7 @@ EOF
 fi
 
 echo $ac_n "checking for .set assembler directive""... $ac_c" 1>&6
-echo "configure:1930: checking for .set assembler directive" >&5
+echo "configure:1931: 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
@@ -1960,7 +1961,7 @@ EOF
 fi
 
 echo $ac_n "checking for .symver assembler directive""... $ac_c" 1>&6
-echo "configure:1964: checking for .symver assembler directive" >&5
+echo "configure:1965: 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
@@ -1979,7 +1980,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:1983: checking for ld --version-script" >&5
+echo "configure:1984: 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
@@ -2002,7 +2003,7 @@ EOF
     if { ac_try='${CC-cc} $CFLAGS -shared -o conftest.so conftest.o
                                        -nostartfiles -nostdlib
                                        -Wl,--version-script,conftest.map
-                      1>&5'; { (eval echo configure:2006: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; };
+                      1>&5'; { (eval echo configure:2007: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; };
     then
       libc_cv_ld_version_script_option=yes
     else
@@ -2040,7 +2041,7 @@ if test $VERSIONING = no; then
 fi
 if test $elf = yes; then
   echo $ac_n "checking for .previous assembler directive""... $ac_c" 1>&6
-echo "configure:2044: checking for .previous assembler directive" >&5
+echo "configure:2045: 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
@@ -2048,7 +2049,7 @@ else
 .section foo_section
 .previous
 EOF
-  if { ac_try='${CC-cc} -c $CFLAGS conftest.s 1>&5'; { (eval echo configure:2052: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; }; then
+  if { ac_try='${CC-cc} -c $CFLAGS conftest.s 1>&5'; { (eval echo configure:2053: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; }; then
     libc_cv_asm_previous_directive=yes
   else
     libc_cv_asm_previous_directive=no
@@ -2064,7 +2065,7 @@ EOF
 
   else
     echo $ac_n "checking for .popsection assembler directive""... $ac_c" 1>&6
-echo "configure:2068: checking for .popsection assembler directive" >&5
+echo "configure:2069: 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
@@ -2072,7 +2073,7 @@ else
 .pushsection foo_section
 .popsection
 EOF
-    if { ac_try='${CC-cc} -c $CFLAGS conftest.s 1>&5'; { (eval echo configure:2076: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; }; then
+    if { ac_try='${CC-cc} -c $CFLAGS conftest.s 1>&5'; { (eval echo configure:2077: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; }; then
       libc_cv_asm_popsection_directive=yes
     else
       libc_cv_asm_popsection_directive=no
@@ -2092,12 +2093,12 @@ fi
 
 if test $elf != yes; then
   echo $ac_n "checking for .init and .fini sections""... $ac_c" 1>&6
-echo "configure:2096: checking for .init and .fini sections" >&5
+echo "configure:2097: 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 2101 "configure"
+#line 2102 "configure"
 #include "confdefs.h"
 
 int main() {
@@ -2106,7 +2107,7 @@ asm (".section .init");
                                    asm (".text");
 ; return 0; }
 EOF
-if { (eval echo configure:2110: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:2111: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
   rm -rf conftest*
   libc_cv_have_initfini=yes
 else
@@ -2134,19 +2135,19 @@ if test $elf = yes; then
 else
   if test $ac_cv_prog_cc_works = yes; then
     echo $ac_n "checking for _ prefix on C symbol names""... $ac_c" 1>&6
-echo "configure:2138: checking for _ prefix on C symbol names" >&5
+echo "configure:2139: 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 2143 "configure"
+#line 2144 "configure"
 #include "confdefs.h"
 asm ("_glibc_foobar:");
 int main() {
 glibc_foobar ();
 ; return 0; }
 EOF
-if { (eval echo configure:2150: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
+if { (eval echo configure:2151: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
   rm -rf conftest*
   libc_cv_asm_underscores=yes
 else
@@ -2161,17 +2162,17 @@ fi
 echo "$ac_t""$libc_cv_asm_underscores" 1>&6
   else
     echo $ac_n "checking for _ prefix on C symbol names""... $ac_c" 1>&6
-echo "configure:2165: checking for _ prefix on C symbol names" >&5
+echo "configure:2166: 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 2170 "configure"
+#line 2171 "configure"
 #include "confdefs.h"
 void underscore_test(void) {
 return; }
 EOF
-if { (eval echo configure:2175: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:2176: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
   if grep _underscore_test conftest* >/dev/null; then
     rm -f conftest*
     libc_cv_asm_underscores=yes
@@ -2204,7 +2205,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:2208: checking for assembler .weak directive" >&5
+echo "configure:2209: 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
@@ -2227,7 +2228,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:2231: checking for assembler .weakext directive" >&5
+echo "configure:2232: 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
@@ -2264,7 +2265,7 @@ EOF
 fi
 
 echo $ac_n "checking for ld --no-whole-archive""... $ac_c" 1>&6
-echo "configure:2268: checking for ld --no-whole-archive" >&5
+echo "configure:2269: 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
@@ -2275,7 +2276,7 @@ __throw () {}
 EOF
 if { ac_try='${CC-cc} $CFLAGS
                            -nostdlib -nostartfiles -Wl,--no-whole-archive
-                           -o conftest conftest.c 1>&5'; { (eval echo configure:2279: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; }; then
+                           -o conftest conftest.c 1>&5'; { (eval echo configure:2280: \"$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
@@ -2286,7 +2287,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:2290: checking for gcc -fno-exceptions" >&5
+echo "configure:2291: 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
@@ -2297,7 +2298,7 @@ __throw () {}
 EOF
 if { ac_try='${CC-cc} $CFLAGS
                            -nostdlib -nostartfiles -fno-exceptions
-                           -o conftest conftest.c 1>&5'; { (eval echo configure:2301: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; }; then
+                           -o conftest conftest.c 1>&5'; { (eval echo configure:2302: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; }; then
   libc_cv_gcc_no_exceptions=yes
 else
   libc_cv_gcc_no_exceptions=no
@@ -2307,13 +2308,45 @@ fi
 
 echo "$ac_t""$libc_cv_gcc_no_exceptions" 1>&6
 
+if test "$base_machine" = alpha ; then
+echo $ac_n "checking for function ..ng prefix""... $ac_c" 1>&6
+echo "configure:2314: checking for function ..ng prefix" >&5
+if eval "test \"`echo '$''{'libc_cv_gcc_alpha_ng_prefix'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  cat > conftest.c <<\EOF
+foo () { }
+EOF
+if { ac_try='${CC-cc} -S conftest.c -o - | fgrep '$foo..ng' > /dev/null'; { (eval echo configure:2321: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; };
+then
+  libc_cv_gcc_alpha_ng_prefix=yes
+else
+  libc_cv_gcc_alpha_ng_prefix=no
+fi
+rm -f conftest* 
+fi
+
+echo "$ac_t""$libc_cv_gcc_alpha_ng_prefix" 1>&6
+if test $libc_cv_gcc_alpha_ng_prefix = yes ; then
+  cat >> confdefs.h <<\EOF
+#define ASM_ALPHA_NG_SYMBOL_PREFIX "$"
+EOF
+
+else
+  cat >> confdefs.h <<\EOF
+#define ASM_ALPHA_NG_SYMBOL_PREFIX ""
+EOF
+
+fi
+fi
+
 echo $ac_n "checking for DWARF2 unwind info support""... $ac_c" 1>&6
-echo "configure:2312: checking for DWARF2 unwind info support" >&5
+echo "configure:2345: checking for DWARF2 unwind info support" >&5
 if eval "test \"`echo '$''{'libc_cv_gcc_dwarf2_unwind_info'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.c <<EOF
-#line 2317 "configure"
+#line 2350 "configure"
 static char __EH_FRAME_BEGIN__;
 _start ()
 {
@@ -2334,7 +2367,7 @@ __bzero () {}
 EOF
 if { ac_try='${CC-cc} $CFLAGS
                            -nostdlib -nostartfiles
-                           -o conftest conftest.c -lgcc >&5'; { (eval echo configure:2338: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; }; then
+                           -o conftest conftest.c -lgcc >&5'; { (eval echo configure:2371: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; }; then
   libc_cv_gcc_dwarf2_unwind_info=yes
 else
   libc_cv_gcc_dwarf2_unwind_info=no
@@ -2392,7 +2425,7 @@ if test "$uname" = "sysdeps/generic"; then
   fi
 
   echo $ac_n "checking OS release for uname""... $ac_c" 1>&6
-echo "configure:2396: checking OS release for uname" >&5
+echo "configure:2429: 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
@@ -2414,7 +2447,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:2418: checking OS version for uname" >&5
+echo "configure:2451: 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
@@ -2436,7 +2469,7 @@ else
 fi
 
 echo $ac_n "checking stdio selection""... $ac_c" 1>&6
-echo "configure:2440: checking stdio selection" >&5
+echo "configure:2473: checking stdio selection" >&5
 
 case $stdio in
 libio) cat >> confdefs.h <<\EOF
@@ -2448,7 +2481,7 @@ esac
 echo "$ac_t""$stdio" 1>&6
 
 echo $ac_n "checking ldap selection""... $ac_c" 1>&6
-echo "configure:2452: checking ldap selection" >&5
+echo "configure:2485: checking ldap selection" >&5
 
 case $add_ons in
 *ldap*)
@@ -2498,7 +2531,7 @@ if test $shared = default; then
 fi
 
 echo $ac_n "checking whether -fPIC is default""... $ac_c" 1>&6
-echo "configure:2502: checking whether -fPIC is default" >&5
+echo "configure:2535: checking whether -fPIC is default" >&5
 if eval "test \"`echo '$''{'pic_default'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
index 80fe259b32ef843b364b3fe4b4105afe90db5fb9..939fda8a4ec3df8ea7473b78fbb3bdbbedb3bd36 100644 (file)
@@ -81,7 +81,8 @@ AC_ARG_ENABLE(versioning, dnl
 
 dnl Generic infrastructure for drop-in additions to libc.
 AC_ARG_ENABLE(add-ons, dnl
-[  --enable-add-ons=DIR1,DIR2... configure and build named extra directories],
+[  --enable-add-ons[=DIR1,DIR2]... configure and build add-ons in DIR1,DIR2,...
+                                  search for add-ons if no parameter given],
   [case "$enableval" in
     yes) add_ons=`echo $srcdir/*/configure | \
                  sed -e "s!$srcdir/!!g" -e 's!/configure!!g'`;;
@@ -830,6 +831,26 @@ fi
 rm -f conftest*])
 AC_SUBST(libc_cv_gcc_no_exceptions)dnl
 
+if test "$base_machine" = alpha ; then
+AC_CACHE_CHECK(for function ..ng prefix, libc_cv_gcc_alpha_ng_prefix, [dnl
+cat > conftest.c <<\EOF
+foo () { }
+EOF
+dnl
+if AC_TRY_COMMAND([${CC-cc} -S conftest.c -o - | fgrep '$foo..ng' > /dev/null]);
+then
+  libc_cv_gcc_alpha_ng_prefix=yes
+else
+  libc_cv_gcc_alpha_ng_prefix=no
+fi
+rm -f conftest* ])
+if test $libc_cv_gcc_alpha_ng_prefix = yes ; then
+  AC_DEFINE(ASM_ALPHA_NG_SYMBOL_PREFIX, "$")
+else
+  AC_DEFINE(ASM_ALPHA_NG_SYMBOL_PREFIX, "")
+fi
+fi
+
 AC_CACHE_CHECK(for DWARF2 unwind info support, libc_cv_gcc_dwarf2_unwind_info,
 [cat > conftest.c <<EOF
 #line __oline__ "configure"
index 44298c5ba60c46c92d2b70d2dcd280a066de5a99..b142f908e6dafd69e8195c081909386a672de850 100644 (file)
@@ -17,6 +17,7 @@
    Boston, MA 02111-1307, USA.  */
 
 #include <ctype.h>
+#include <errno.h>
 #include <grp.h>
 #include <stdio.h>
 
@@ -29,7 +30,7 @@ struct grent_data {};
 
 #define TRAILING_LIST_MEMBER           gr_mem
 #define TRAILING_LIST_SEPARATOR_P(c)   ((c) == ',')
-#include "../nss/nss_files/files-parse.c"
+#include <nss/nss_files/files-parse.c>
 LINE_PARSER
 (,
  STRING_FIELD (result->gr_name, ISCOLON, 0);
@@ -74,7 +75,8 @@ __fgetgrent_r (FILE *stream, struct group *resbuf, char *buffer, size_t buflen,
             /* Parse the line.  If it is invalid, loop to
                get the next line of the file to parse.  */
             || ! (parse_result = parse_line (p, resbuf,
-                                             (void *) buffer, buflen)));
+                                             (void *) buffer, buflen,
+                                             __errno_location ())));
 
   if (parse_result == -1)
     {
index 7b0832dbe38104ea475f7571620c4061011409d5..e08b9dca8cd172205ba057046d3cfe7d30d28874 100644 (file)
@@ -81,13 +81,14 @@ _nss_hesiod_endgrent (void)
 
 static enum nss_status
 lookup (const char *name, const char *type, struct group *grp,
-       char *buffer, size_t buflen)
+       char *buffer, size_t buflen, int *errnop)
 {
   enum nss_status status;
   struct parser_data *data = (void *) buffer;
   size_t linebuflen;
   char **list;
   int parse_res;
+  size_t len;
 
   status = internal_setgrent ();
   if (status != NSS_STATUS_SUCCESS)
@@ -98,17 +99,18 @@ lookup (const char *name, const char *type, struct group *grp,
     return errno == ENOENT ? NSS_STATUS_NOTFOUND : NSS_STATUS_UNAVAIL;
 
   linebuflen = buffer + buflen - data->linebuffer;
-  if (linebuflen < strlen (*list) + 1)
+  len = strlen (*list) + 1;
+  if (linebuflen < len)
     {
       hesiod_free_list (context, list);
-      __set_errno (ERANGE);
+      *errnop = ERANGE;
       return NSS_STATUS_TRYAGAIN;
     }
 
-  strcpy (buffer, *list);
+  memcpy (data->linebuffer, *list, len);
   hesiod_free_list (context, list);
 
-  parse_res = _nss_files_parse_grent (buffer, grp, data, buflen);
+  parse_res = _nss_files_parse_grent (buffer, grp, data, buflen, errnop);
   if (parse_res < 1)
     return parse_res == -1 ? NSS_STATUS_TRYAGAIN : NSS_STATUS_NOTFOUND;
 
@@ -117,13 +119,13 @@ lookup (const char *name, const char *type, struct group *grp,
 
 enum nss_status
 _nss_hesiod_getgrnam_r (const char *name, struct group *grp,
-                       char *buffer, size_t buflen)
+                       char *buffer, size_t buflen, int *errnop)
 {
   enum nss_status status;
 
   __libc_lock_lock (lock);
 
-  status = lookup (name, "group", grp, buffer, buflen);
+  status = lookup (name, "group", grp, buffer, buflen, errnop);
 
   __libc_lock_unlock (lock);
 
@@ -132,7 +134,7 @@ _nss_hesiod_getgrnam_r (const char *name, struct group *grp,
 
 enum nss_status
 _nss_hesiod_getgrgid_r (gid_t gid, struct group *grp,
-                       char *buffer, size_t buflen)
+                       char *buffer, size_t buflen, int *errnop)
 {
   enum nss_status status = NSS_STATUS_UNAVAIL;
   char gidstr[21];     /* We will probably never have a gid_t with more
@@ -142,7 +144,7 @@ _nss_hesiod_getgrgid_r (gid_t gid, struct group *grp,
 
   __libc_lock_lock (lock);
 
-  status = lookup (gidstr, "gid", grp, buffer, buflen);
+  status = lookup (gidstr, "gid", grp, buffer, buflen, errnop);
 
   __libc_lock_unlock (lock);
 
index bb2a4c87852dab2aa359c04205efe739e7983609..ce97443164d6b5285489de8c8eca5d8a97c06baf 100644 (file)
@@ -81,13 +81,14 @@ _nss_hesiod_endpwent (void)
 
 static enum nss_status
 lookup (const char *name, const char *type, struct passwd *pwd,
-       char *buffer, size_t buflen)
+       char *buffer, size_t buflen, int *errnop)
 {
   enum nss_status status;
   struct parser_data *data = (void *) buffer;
   size_t linebuflen;
   char **list;
   int parse_res;
+  size_t len;
 
   status = internal_setpwent ();
   if (status != NSS_STATUS_SUCCESS)
@@ -98,17 +99,18 @@ lookup (const char *name, const char *type, struct passwd *pwd,
     return errno == ENOENT ? NSS_STATUS_NOTFOUND : NSS_STATUS_UNAVAIL;
 
   linebuflen = buffer + buflen - data->linebuffer;
-  if (linebuflen < strlen (*list) + 1)
+  len = strlen (*list) + 1;
+  if (linebuflen < len)
     {
       hesiod_free_list (context, list);
-      __set_errno (ERANGE);
+      *errnop = ERANGE;
       return NSS_STATUS_TRYAGAIN;
     }
 
-  strcpy (data->linebuffer, *list);
+  memcpy (data->linebuffer, *list, len);
   hesiod_free_list (context, list);
 
-  parse_res = _nss_files_parse_pwent (buffer, pwd, data, buflen);
+  parse_res = _nss_files_parse_pwent (buffer, pwd, data, buflen, errnop);
   if (parse_res < 1)
     return parse_res == -1 ? NSS_STATUS_TRYAGAIN : NSS_STATUS_NOTFOUND;
 
@@ -117,13 +119,13 @@ lookup (const char *name, const char *type, struct passwd *pwd,
 
 enum nss_status
 _nss_hesiod_getpwnam_r (const char *name, struct passwd *pwd,
-                       char *buffer, size_t buflen)
+                       char *buffer, size_t buflen, int *errnop)
 {
   enum nss_status status;
 
   __libc_lock_lock (lock);
 
-  status = lookup (name, "passwd", pwd, buffer, buflen);
+  status = lookup (name, "passwd", pwd, buffer, buflen, errnop);
 
   __libc_lock_unlock (lock);
 
@@ -132,7 +134,7 @@ _nss_hesiod_getpwnam_r (const char *name, struct passwd *pwd,
 
 enum nss_status
 _nss_hesiod_getpwuid_r (uid_t uid, struct passwd *pwd,
-                       char *buffer, size_t buflen)
+                       char *buffer, size_t buflen, int *errnop)
 {
   enum nss_status status = NSS_STATUS_UNAVAIL;
   char uidstr[21];     /* We will probably never have a gid_t with more
@@ -142,7 +144,7 @@ _nss_hesiod_getpwuid_r (uid_t uid, struct passwd *pwd,
 
   __libc_lock_lock (lock);
 
-  status = lookup (uidstr, "uid", pwd, buffer, buflen);
+  status = lookup (uidstr, "uid", pwd, buffer, buflen, errnop);
 
   __libc_lock_unlock (lock);
 
index f74877f7488314a0642d51990533da3fe6208786..e0ca96531098b7c3cb166eb59f7e66b81f04d085 100644 (file)
@@ -97,7 +97,7 @@ _nss_hesiod_endservent (void)
 
 static enum nss_status
 lookup (const char *name, const char *protocol, struct servent *serv,
-       char *buffer, size_t buflen)
+       char *buffer, size_t buflen, int *errnop)
 {
   enum nss_status status;
   struct parser_data *data = (void *) buffer;
@@ -120,16 +120,18 @@ lookup (const char *name, const char *protocol, struct servent *serv,
   found = 0;
   do
     {
-      if (linebuflen < strlen (*item) + 1)
+      size_t len = strlen (*item) + 1;
+
+      if (linebuflen < len)
        {
          hesiod_free_list (context, list);
-         __set_errno (ERANGE);
+         *errnop = ERANGE;
          return NSS_STATUS_TRYAGAIN;
        }
 
-      strcpy (data->linebuffer, *item);
+      memcpy (data->linebuffer, *item, len);
 
-      parse_res = parse_line (buffer, serv, data, buflen);
+      parse_res = parse_line (buffer, serv, data, buflen, errnop);
       if (parse_res == -1)
        {
          hesiod_free_list (context, list);
@@ -151,13 +153,13 @@ lookup (const char *name, const char *protocol, struct servent *serv,
 enum nss_status
 _nss_hesiod_getservbyname_r (const char *name, const char *protocol,
                             struct servent *serv,
-                            char *buffer, size_t buflen)
+                            char *buffer, size_t buflen, int *errnop)
 {
   enum nss_status status;
 
   __libc_lock_lock (lock);
 
-  status = lookup (name, protocol, serv, buffer, buflen);
+  status = lookup (name, protocol, serv, buffer, buflen, errnop);
 
   __libc_lock_unlock (lock);
 
index a388d86ba8d92804738c655227b030bd5a5f341c..d7a2b58b78516b59dc18eca54be8fd3b79e5cc70 100644 (file)
@@ -92,7 +92,8 @@ free_memory (struct __netgrent *data)
 \f
 static int
 internal_function
-__internal_setnetgrent_reuse (const char *group, struct __netgrent *datap)
+__internal_setnetgrent_reuse (const char *group, struct __netgrent *datap,
+                             int *errnop)
 {
   enum nss_status (*fct) (const char *, struct __netgrent *);
   enum nss_status status = NSS_STATUS_UNAVAIL;
@@ -115,7 +116,8 @@ __internal_setnetgrent_reuse (const char *group, struct __netgrent *datap)
     {
       if (new_elem != NULL)
        free (new_elem);
-      status = NSS_STATUS_UNAVAIL;
+      *errnop = errno;
+      status = NSS_STATUS_TRYAGAIN;
     }
   else
     {
@@ -132,7 +134,7 @@ __internal_setnetgrent (const char *group, struct __netgrent *datap)
   /* Free list of all netgroup names from last run.  */
   free_memory (datap);
 
-  return __internal_setnetgrent_reuse (group, datap);
+  return __internal_setnetgrent_reuse (group, datap, __errno_location ());
 }
 
 int
@@ -190,7 +192,7 @@ endnetgrent (void)
 int
 __internal_getnetgrent_r (char **hostp, char **userp, char **domainp,
                          struct __netgrent *datap,
-                         char *buffer, size_t buflen)
+                         char *buffer, size_t buflen, int *errnop)
 {
   enum nss_status (*fct) (struct __netgrent *, char *, size_t);
   int no_more;
@@ -219,7 +221,7 @@ __internal_getnetgrent_r (char **hostp, char **userp, char **domainp,
              datap->known_groups = tmp;
 
              found = __internal_setnetgrent_reuse (datap->known_groups->name,
-                                                   datap);
+                                                   datap, errnop);
            }
 
          if (found)
@@ -280,7 +282,7 @@ __getnetgrent_r (char **hostp, char **userp, char **domainp,
   __libc_lock_lock (lock);
 
   status = __internal_getnetgrent_r (hostp, userp, domainp, &dataset,
-                                    buffer, buflen);
+                                    buffer, buflen, __errno_location ());
 
   __libc_lock_unlock (lock);
 
index a37244c52e8c76d7fb5d390fca2e4e79ed0bdd9c..804a201ddae2adb5b265e32c68011fb61369c607 100644 (file)
@@ -65,6 +65,6 @@ extern int __internal_setnetgrent (const char *group,
 extern void __internal_endnetgrent (struct __netgrent *datap);
 extern int __internal_getnetgrent_r (char **hostp, char **userp,
                                     char **domainp, struct __netgrent *datap,
-                                    char *buffer, size_t buflen);
+                                    char *buffer, size_t buflen, int *errnop);
 
 #endif /* netgroup.h */
index 01bc00165ee97086c7bb6f776bc294df354bf526..d57b8d6ee81403a2ca672e37fab6a8e1ca7d385a 100644 (file)
@@ -63,6 +63,8 @@ __BEGIN_DECLS
 #ifdef __USE_BSD
 # ifdef __S_IFLNK
 #  define S_ISLNK(mode)         __S_ISTYPE((mode), __S_IFLNK)
+# else
+#  define S_ISLNK(mode)  0
 # endif
 # ifdef __S_IFSOCK
 #  define S_ISSOCK(mode) __S_ISTYPE((mode), __S_IFSOCK)
index a4b880b52b43e91f88960875deb32ebc93c174e1..d133f227579c2688e4eef358fcbaccacb2e622e4 100644 (file)
--- a/libc.map
+++ b/libc.map
@@ -192,7 +192,7 @@ GLIBC_2.0 {
 
     # g*
     gai_strerror; gcvt; get_avphys_pages; get_current_dir_name;
-    get_kernel_syms; get_myaddress; get_nprocs; get_nprocs_conf;
+    get_myaddress; get_nprocs; get_nprocs_conf;
     get_phys_pages; getaddrinfo; getaliasbyname; getaliasbyname_r;
     getaliasent; getaliasent_r; getc; getc_unlocked; getchar;
     getchar_unlocked; getcontext;
@@ -285,8 +285,8 @@ GLIBC_2.0 {
     parse_printf_format; passwd2des; pathconf; pause; pciconfig_read;
     pciconfig_write; pclose; perror;
     personality; pipe; pmap_getmaps; pmap_getport; pmap_rmtcall; pmap_set;
-    pmap_unset; poll; popen; prctl; pread; printf; printf_size;
-    printf_size_info; profil; profil_counter; pwrite; pselect; psignal;
+    pmap_unset; poll; popen; prctl; pread; pread64; printf; printf_size;
+    printf_size_info; profil; profil_counter; pwrite; pwrite64; pselect; psignal;
 
     pthread_attr_destroy;
     pthread_attr_getdetachstate; pthread_attr_getinheritsched;
@@ -351,9 +351,10 @@ GLIBC_2.0 {
 
     sleep; snprintf; socket; socketpair; sprintf; srand; srand48;
     srand48_r; srandom; srandom_r; sscanf; ssignal; sstk; statfs; statfs64;
-    step; stime; stpcpy; stpncpy; strcasecmp; strcat; strchr; strcmp; strcoll;
+    step; stime; stpcpy; stpncpy; strcasecmp; strcasestr; strcat;
+    strchr; strcmp; strcoll;
     strcpy; strcspn; strdup; strerror; strerror_r; strfmon; strfry;
-    strftime; strlen; strncasecmp; strncat; strncmp; strncpy; strndup;
+    strftime; strfxtime; strlen; strncasecmp; strncat; strncmp; strncpy; strndup;
     strnlen; strpbrk; strptime; strrchr; strsep; strsignal; strspn;
     strstr; strtod; strtof; strtok; strtok_r; strtol; strtold; strtoll;
     strtoq; strtoul; strtoull; strtouq; strverscmp; strxfrm; stty;
@@ -366,10 +367,10 @@ GLIBC_2.0 {
 
     swab; swapoff; swapon; symlink; sync;
     syscall; sysconf; sysctl; sysinfo; syslog; sysmips;
-    system;
+    system; sysv_signal;
 
     # t*
-    tcdrain; tcflow; tcflush; tcgetattr; tcgetpgrp; tcsendbreak;
+    tcdrain; tcflow; tcflush; tcgetattr; tcgetpgrp; tcgetsid; tcsendbreak;
     tcsetattr; tcsetpgrp; tdelete; tdestroy; telldir; tempnam; textdomain;
     tfind; time; timegm; timelocal; times; tmpfile; tmpfile64; tmpnam;
     tmpnam_r;
@@ -398,7 +399,7 @@ GLIBC_2.0 {
     wcstoul; wcstoull; wcstouq; wcswcs; wcswidth; wcsxfrm; wctob; wctomb;
     wctrans; wctype; wcwidth;
 
-    wmemchr; wmemcmp; wmemcpy; wmemmove; wmemset;
+    wmemchr; wmemcmp; wmemcpy; wmemmove; wmemrtombs; wmemrtowcs; wmemset;
 
     wordexp; wordfree;
 
index 7f80b9ad60a20ff271600504810fdb63d21004b8..058c156be4a9ecc481d51a0200005777f473ad8e 100644 (file)
@@ -510,7 +510,7 @@ do {                                                                          \
 */
 
 #ifndef HAVE_MREMAP
-#define HAVE_MREMAP defined(__linux__)
+#define HAVE_MREMAP defined(__linux__) && !defined(__arm__)
 #endif
 
 #if HAVE_MMAP
index b24ca46507821efcecafeb73803e41bb84b27705..2d54edba28faa648ce0dacdd8342ab3afda88331 100644 (file)
    write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
    Boston, MA 02111-1307, USA.  */
 
-#ifndef __NISPLUS_PARSER_H_
-#define __NISPLUS_PARSER_H_ 1
+#ifndef __NISPLUS_PARSER_H
+#define __NISPLUS_PARSER_H     1
 
 #include <pwd.h>
 #include <grp.h>
 #include <shadow.h>
 
 extern int _nss_nisplus_parse_pwent (nis_result *, struct passwd *,
-                                    char *, size_t);
+                                    char *, size_t, int *);
 extern int _nss_nisplus_parse_grent (nis_result *, u_long, struct group *,
-                                    char *, size_t);
+                                    char *, size_t, int *);
 extern int _nss_nisplus_parse_spent (nis_result *, struct spwd *,
-                                    char *, size_t);
+                                    char *, size_t, int *);
 
 #endif
index 6d4ca25e5d67b3010a96a882719cf463f969b84e..a586d1fbbf2e38057d2baf99eb15bd3d7c89f473 100644 (file)
@@ -225,7 +225,7 @@ _nss_compat_endgrent (void)
 
 static enum nss_status
 getgrent_next_nis (struct group *result, ent_t *ent, char *buffer,
-                  size_t buflen)
+                  size_t buflen, int *errnop)
 {
   struct parser_data *data = (void *) buffer;
   char *domain;
@@ -286,13 +286,14 @@ getgrent_next_nis (struct group *result, ent_t *ent, char *buffer,
       while (isspace (*p))
        ++p;
 
-      if ((parse_res = _nss_files_parse_grent (p, result, data, buflen)) == -1)
+      parse_res = _nss_files_parse_grent (p, result, data, buflen, errnop);
+      if (parse_res == -1)
        {
          free (ent->oldkey);
          ent->oldkey = save_oldkey;
          ent->oldkeylen = save_oldlen;
          ent->nis_first = save_nis_first;
-         __set_errno (ERANGE);
+         *errnop = ERANGE;
          return NSS_STATUS_TRYAGAIN;
        }
       else
@@ -312,7 +313,7 @@ getgrent_next_nis (struct group *result, ent_t *ent, char *buffer,
 
 static enum nss_status
 getgrent_next_nisplus (struct group *result, ent_t *ent, char *buffer,
-                       size_t buflen)
+                       size_t buflen, int *errnop)
 {
   int parse_res;
 
@@ -347,13 +348,14 @@ getgrent_next_nisplus (struct group *result, ent_t *ent, char *buffer,
              return niserr2nss (ent->result->status);
             }
         }
-      if ((parse_res = _nss_nisplus_parse_grent (ent->result, 0, result,
-                                                buffer, buflen)) == -1)
+      parse_res = _nss_nisplus_parse_grent (ent->result, 0, result,
+                                           buffer, buflen, errnop);
+      if (parse_res == -1)
        {
          nis_freeresult (ent->result);
          ent->result = save_oldres;
          ent->nis_first = save_nis_first;
-         __set_errno (ERANGE);
+         *errnop = ERANGE;
          return NSS_STATUS_TRYAGAIN;
        }
       else
@@ -374,7 +376,7 @@ getgrent_next_nisplus (struct group *result, ent_t *ent, char *buffer,
 /* This function handle the +group entrys in /etc/group */
 static enum nss_status
 getgrnam_plusgroup (const char *name, struct group *result, char *buffer,
-                   size_t buflen)
+                   size_t buflen, int *errnop)
 {
   struct parser_data *data = (void *) buffer;
   int parse_res;
@@ -393,11 +395,12 @@ getgrnam_plusgroup (const char *name, struct group *result, char *buffer,
           nis_freeresult (res);
           return status;
         }
-      if ((parse_res = _nss_nisplus_parse_grent (res, 0, result, buffer,
-                                                buflen)) == -1)
+      parse_res = _nss_nisplus_parse_grent (res, 0, result, buffer, buflen,
+                                           errnop);
+      if (parse_res == -1)
        {
-         __set_errno (ERANGE);
          nis_freeresult (res);
+         *errnop = ERANGE;
          return NSS_STATUS_TRYAGAIN;
        }
       nis_freeresult (res);
@@ -408,21 +411,25 @@ getgrnam_plusgroup (const char *name, struct group *result, char *buffer,
       int outvallen;
 
       if (yp_get_default_domain (&domain) != YPERR_SUCCESS)
-        return NSS_STATUS_TRYAGAIN;
+       {
+         *errnop = errno;
+         return NSS_STATUS_TRYAGAIN;
+       }
 
       if (yp_match (domain, "group.byname", name, strlen (name),
                    &outval, &outvallen) != YPERR_SUCCESS)
-        return NSS_STATUS_TRYAGAIN;
+       {
+         *errnop = errno;
+         return NSS_STATUS_TRYAGAIN;
+       }
       p = strncpy (buffer, outval,
                    buflen < (size_t) outvallen ? buflen : (size_t) outvallen);
       free (outval);
       while (isspace (*p))
         p++;
-      if ((parse_res = _nss_files_parse_grent (p, result, data, buflen)) == -1)
-       {
-         __set_errno (ERANGE);
-         return NSS_STATUS_TRYAGAIN;
-       }
+      parse_res = _nss_files_parse_grent (p, result, data, buflen, errnop);
+      if (parse_res == -1)
+       return NSS_STATUS_TRYAGAIN;
     }
 
   if (parse_res)
@@ -434,7 +441,7 @@ getgrnam_plusgroup (const char *name, struct group *result, char *buffer,
 
 static enum nss_status
 getgrent_next_file (struct group *result, ent_t *ent,
-                   char *buffer, size_t buflen)
+                   char *buffer, size_t buflen, int *errnop)
 {
   struct parser_data *data = (void *) buffer;
   while (1)
@@ -453,7 +460,8 @@ getgrent_next_file (struct group *result, ent_t *ent,
                return NSS_STATUS_NOTFOUND;
              else
                {
-                 __set_errno (ERANGE);
+                 fsetpos (ent->stream, &pos);
+                 *errnop = ERANGE;
                  return NSS_STATUS_TRYAGAIN;
                }
            }
@@ -468,13 +476,14 @@ getgrent_next_file (struct group *result, ent_t *ent,
       while (*p == '\0' || *p == '#' || /* Ignore empty and comment lines. */
       /* Parse the line.  If it is invalid, loop to
          get the next line of the file to parse.  */
-            !(parse_res = _nss_files_parse_grent (p, result, data, buflen)));
+            !(parse_res = _nss_files_parse_grent (p, result, data, buflen,
+                                                  errnop)));
 
       if (parse_res == -1)
        {
          /* The parser ran out of space.  */
          fsetpos (ent->stream, &pos);
-         __set_errno (ERANGE);
+         *errnop = ERANGE;
          return NSS_STATUS_TRYAGAIN;
        }
 
@@ -500,14 +509,22 @@ getgrent_next_file (struct group *result, ent_t *ent,
             /etc/group */
          blacklist_store_name (&result->gr_name[1], ent);
          status = getgrnam_plusgroup (&result->gr_name[1], result, buffer,
-                                      buflen);
+                                      buflen, errnop);
           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;
+             {
+               if (status == NSS_STATUS_TRYAGAIN)
+                 {
+                   /* The parser ran out of space.  */
+                   fsetpos (ent->stream, &pos);
+                   *errnop = ERANGE;
+                 }
+               return status;
+             }
        }
 
       /* +:... */
@@ -517,9 +534,9 @@ getgrent_next_file (struct group *result, ent_t *ent,
          ent->nis_first = TRUE;
 
          if (use_nisplus)
-           return getgrent_next_nisplus (result, ent, buffer, buflen);
+           return getgrent_next_nisplus (result, ent, buffer, buflen, errnop);
          else
-           return getgrent_next_nis (result, ent, buffer, buflen);
+           return getgrent_next_nis (result, ent, buffer, buflen, errnop);
        }
     }
 
@@ -529,21 +546,22 @@ getgrent_next_file (struct group *result, ent_t *ent,
 
 static enum nss_status
 internal_getgrent_r (struct group *gr, ent_t *ent, char *buffer,
-                    size_t buflen)
+                    size_t buflen, int *errnop)
 {
   if (ent->nis)
     {
       if (use_nisplus)
-       return getgrent_next_nisplus (gr, ent, buffer, buflen);
+       return getgrent_next_nisplus (gr, ent, buffer, buflen, errnop);
       else
-       return getgrent_next_nis (gr, ent, buffer, buflen);
+       return getgrent_next_nis (gr, ent, buffer, buflen, errnop);
     }
   else
-    return getgrent_next_file (gr, ent, buffer, buflen);
+    return getgrent_next_file (gr, ent, buffer, buflen, errnop);
 }
 
 enum nss_status
-_nss_compat_getgrent_r (struct group *grp, char *buffer, size_t buflen)
+_nss_compat_getgrent_r (struct group *grp, char *buffer, size_t buflen,
+                       int *errnop)
 {
   enum nss_status status = NSS_STATUS_SUCCESS;
 
@@ -554,7 +572,7 @@ _nss_compat_getgrent_r (struct group *grp, char *buffer, size_t buflen)
     status = internal_setgrent (&ext_ent);
 
   if (status == NSS_STATUS_SUCCESS)
-    status = internal_getgrent_r (grp, &ext_ent, buffer, buflen);
+    status = internal_getgrent_r (grp, &ext_ent, buffer, buflen, errnop);
 
   __libc_lock_unlock (lock);
 
@@ -564,7 +582,7 @@ _nss_compat_getgrent_r (struct group *grp, char *buffer, size_t buflen)
 /* Searches in /etc/group and the NIS/NIS+ map for a special group */
 static enum nss_status
 internal_getgrnam_r (const char *name, struct group *result, ent_t *ent,
-                    char *buffer, size_t buflen)
+                    char *buffer, size_t buflen, int *errnop)
 {
   struct parser_data *data = (void *) buffer;
   while (1)
@@ -583,7 +601,8 @@ internal_getgrnam_r (const char *name, struct group *result, ent_t *ent,
                return NSS_STATUS_NOTFOUND;
              else
                {
-                 __set_errno (ERANGE);
+                 fsetpos (ent->stream, &pos);
+                 *errnop = ERANGE;
                  return NSS_STATUS_TRYAGAIN;
                }
            }
@@ -598,13 +617,14 @@ internal_getgrnam_r (const char *name, struct group *result, ent_t *ent,
       while (*p == '\0' || *p == '#' || /* Ignore empty and comment lines. */
       /* Parse the line.  If it is invalid, loop to
          get the next line of the file to parse.  */
-            !(parse_res = _nss_files_parse_grent (p, result, data, buflen)));
+            !(parse_res = _nss_files_parse_grent (p, result, data, buflen,
+                                                  errnop)));
 
       if (parse_res == -1)
        {
          /* The parser ran out of space.  */
          fsetpos (ent->stream, &pos);
-         __set_errno (ERANGE);
+         *errnop = ERANGE;
          return NSS_STATUS_TRYAGAIN;
        }
 
@@ -618,8 +638,7 @@ internal_getgrnam_r (const char *name, struct group *result, ent_t *ent,
        }
 
       /* -group */
-      if (result->gr_name[0] == '-' && result->gr_name[1] != '\0'
-         && result->gr_name[1] != '@')
+      if (result->gr_name[0] == '-' && result->gr_name[1] != '\0')
        {
          if (strcmp (&result->gr_name[1], name) == 0)
            return NSS_STATUS_NOTFOUND;
@@ -628,14 +647,14 @@ internal_getgrnam_r (const char *name, struct group *result, ent_t *ent,
        }
 
       /* +group */
-      if (result->gr_name[0] == '+' && result->gr_name[1] != '\0'
-         && result->gr_name[1] != '@')
+      if (result->gr_name[0] == '+' && result->gr_name[1] != '\0')
        {
          if (strcmp (name, &result->gr_name[1]) == 0)
            {
              enum nss_status status;
 
-             status = getgrnam_plusgroup (name, result, buffer, buflen);
+             status = getgrnam_plusgroup (name, result, buffer, buflen,
+                                          errnop);
              if (status == NSS_STATUS_RETURN)
                /* We couldn't parse the entry */
                continue;
@@ -648,7 +667,7 @@ internal_getgrnam_r (const char *name, struct group *result, ent_t *ent,
        {
          enum nss_status status;
 
-         status = getgrnam_plusgroup (name, result, buffer, buflen);
+         status = getgrnam_plusgroup (name, result, buffer, buflen, errnop);
          if (status == NSS_STATUS_RETURN)
            /* We couldn't parse the entry */
            continue;
@@ -662,7 +681,7 @@ internal_getgrnam_r (const char *name, struct group *result, ent_t *ent,
 
 enum nss_status
 _nss_compat_getgrnam_r (const char *name, struct group *grp,
-                       char *buffer, size_t buflen)
+                       char *buffer, size_t buflen, int *errnop)
 {
   ent_t ent = {0, 0, NULL, 0, NULL, NULL, {NULL, 0, 0}};
   enum nss_status status;
@@ -679,7 +698,7 @@ _nss_compat_getgrnam_r (const char *name, struct group *grp,
   if (status != NSS_STATUS_SUCCESS)
     return status;
 
-  status = internal_getgrnam_r (name, grp, &ent, buffer, buflen);
+  status = internal_getgrnam_r (name, grp, &ent, buffer, buflen, errnop);
 
   internal_endgrent (&ent);
 
@@ -689,7 +708,7 @@ _nss_compat_getgrnam_r (const char *name, struct group *grp,
 /* This function handle the + entry in /etc/group */
 static enum nss_status
 getgrgid_plusgroup (gid_t gid, struct group *result, char *buffer,
-                   size_t buflen)
+                   size_t buflen, int *errnop)
 {
   struct parser_data *data = (void *) buffer;
   int parse_res;
@@ -709,10 +728,10 @@ getgrgid_plusgroup (gid_t gid, struct group *result, char *buffer,
           return status;
         }
       if ((parse_res = _nss_nisplus_parse_grent (res, 0, result, buffer,
-                                                buflen)) == -1)
+                                                buflen, errnop)) == -1)
        {
-         __set_errno (ERANGE);
          nis_freeresult (res);
+         *errnop = ERANGE;
          return NSS_STATUS_TRYAGAIN;
        }
       nis_freeresult (res);
@@ -724,23 +743,27 @@ getgrgid_plusgroup (gid_t gid, struct group *result, char *buffer,
       int outvallen;
 
       if (yp_get_default_domain (&domain) != YPERR_SUCCESS)
-        return NSS_STATUS_TRYAGAIN;
+       {
+         *errnop = errno;
+         return NSS_STATUS_TRYAGAIN;
+       }
 
       snprintf (buf, sizeof (buf), "%d", gid);
 
       if (yp_match (domain, "group.bygid", buf, strlen (buf),
                    &outval, &outvallen) != YPERR_SUCCESS)
-        return NSS_STATUS_TRYAGAIN;
+       {
+         *errnop = errno;
+         return NSS_STATUS_TRYAGAIN;
+       }
       p = strncpy (buffer, outval,
                    buflen < (size_t) outvallen ? buflen : (size_t) outvallen);
       free (outval);
       while (isspace (*p))
         p++;
-      if ((parse_res = _nss_files_parse_grent (p, result, data, buflen)) == -1)
-       {
-         __set_errno (ERANGE);
-         return NSS_STATUS_TRYAGAIN;
-       }
+      parse_res = _nss_files_parse_grent (p, result, data, buflen, errnop);
+      if (parse_res == -1)
+       return NSS_STATUS_TRYAGAIN;
     }
 
   if (parse_res)
@@ -753,7 +776,7 @@ getgrgid_plusgroup (gid_t gid, struct group *result, char *buffer,
 /* Searches in /etc/group and the NIS/NIS+ map for a special group id */
 static enum nss_status
 internal_getgrgid_r (gid_t gid, struct group *result, ent_t *ent,
-                    char *buffer, size_t buflen)
+                    char *buffer, size_t buflen, int *errnop)
 {
   struct parser_data *data = (void *) buffer;
   while (1)
@@ -772,7 +795,8 @@ internal_getgrgid_r (gid_t gid, struct group *result, ent_t *ent,
                return NSS_STATUS_NOTFOUND;
              else
                {
-                 __set_errno (ERANGE);
+                 fsetpos (ent->stream, &pos);
+                 *errnop = ERANGE;
                  return NSS_STATUS_TRYAGAIN;
                }
            }
@@ -787,13 +811,14 @@ internal_getgrgid_r (gid_t gid, struct group *result, ent_t *ent,
       while (*p == '\0' || *p == '#' || /* Ignore empty and comment lines. */
       /* Parse the line.  If it is invalid, loop to
          get the next line of the file to parse.  */
-            !(parse_res = _nss_files_parse_grent (p, result, data, buflen)));
+            !(parse_res = _nss_files_parse_grent (p, result, data, buflen,
+                                                  errnop)));
 
       if (parse_res == -1)
        {
          /* The parser ran out of space.  */
          fsetpos (ent->stream, &pos);
-         __set_errno (ERANGE);
+         *errnop = ERANGE;
          return NSS_STATUS_TRYAGAIN;
        }
 
@@ -807,16 +832,14 @@ internal_getgrgid_r (gid_t gid, struct group *result, ent_t *ent,
        }
 
       /* -group */
-      if (result->gr_name[0] == '-' && result->gr_name[1] != '\0'
-         && result->gr_name[1] != '@')
+      if (result->gr_name[0] == '-' && result->gr_name[1] != '\0')
        {
           blacklist_store_name (&result->gr_name[1], ent);
           continue;
        }
 
       /* +group */
-      if (result->gr_name[0] == '+' && result->gr_name[1] != '\0'
-         && result->gr_name[1] != '@')
+      if (result->gr_name[0] == '+' && result->gr_name[1] != '\0')
        {
          enum nss_status status;
 
@@ -824,7 +847,7 @@ internal_getgrgid_r (gid_t gid, struct group *result, ent_t *ent,
              /etc/group */
           blacklist_store_name (&result->gr_name[1], ent);
          status = getgrnam_plusgroup (&result->gr_name[1], result, buffer,
-                                     buflen);
+                                     buflen, errnop);
          if (status == NSS_STATUS_SUCCESS && result->gr_gid == gid)
            break;
          else
@@ -835,7 +858,7 @@ internal_getgrgid_r (gid_t gid, struct group *result, ent_t *ent,
        {
          enum nss_status status;
 
-         status = getgrgid_plusgroup (gid, result, buffer, buflen);
+         status = getgrgid_plusgroup (gid, result, buffer, buflen, errnop);
          if (status == NSS_STATUS_RETURN) /* We couldn't parse the entry */
            return NSS_STATUS_NOTFOUND;
          else
@@ -848,7 +871,7 @@ internal_getgrgid_r (gid_t gid, struct group *result, ent_t *ent,
 
 enum nss_status
 _nss_compat_getgrgid_r (gid_t gid, struct group *grp,
-                       char *buffer, size_t buflen)
+                       char *buffer, size_t buflen, int *errnop)
 {
   ent_t ent = {0, 0, NULL, 0, NULL, NULL, {NULL, 0, 0}};
   enum nss_status status;
@@ -862,7 +885,7 @@ _nss_compat_getgrgid_r (gid_t gid, struct group *grp,
   if (status != NSS_STATUS_SUCCESS)
     return status;
 
-  status = internal_getgrgid_r (gid, grp, &ent, buffer, buflen);
+  status = internal_getgrgid_r (gid, grp, &ent, buffer, buflen, errnop);
 
   internal_endgrent (&ent);
 
index 38a7e2f205351f11714ab9f64e64b7b86544901c..c8e6f9cc8dbd31df43d523d467d4dcea8a756849 100644 (file)
@@ -338,7 +338,7 @@ _nss_compat_endpwent (void)
 
 static enum nss_status
 getpwent_next_nis_netgr (const char *name, struct passwd *result, ent_t *ent,
-                        char *group, char *buffer, size_t buflen)
+                        char *group, char *buffer, size_t buflen, int *errnop)
 {
   struct parser_data *data = (void *) buffer;
   char *ypdomain, *host, *user, *domain, *outval, *p, *p2;
@@ -367,7 +367,8 @@ getpwent_next_nis_netgr (const char *name, struct passwd *result, ent_t *ent,
 
       saved_cursor = ent->netgrdata.cursor;
       status = __internal_getnetgrent_r (&host, &user, &domain,
-                                        &ent->netgrdata, buffer, buflen);
+                                        &ent->netgrdata, buffer, buflen,
+                                        errnop);
       if (status != 1)
        {
          __internal_endnetgrent (&ent->netgrdata);
@@ -395,7 +396,7 @@ getpwent_next_nis_netgr (const char *name, struct passwd *result, ent_t *ent,
       p2len = pwd_need_buflen (&ent->pwd);
       if (p2len > buflen)
        {
-         __set_errno (ERANGE);
+         *errnop = ERANGE;
          return NSS_STATUS_TRYAGAIN;
        }
       p2 = buffer + (buflen - p2len);
@@ -404,7 +405,8 @@ getpwent_next_nis_netgr (const char *name, struct passwd *result, ent_t *ent,
       while (isspace (*p))
        p++;
       free (outval);
-      if ((parse_res = _nss_files_parse_pwent (p, result, data, buflen)) == -1)
+      parse_res = _nss_files_parse_pwent (p, result, data, buflen, errnop);
+      if (parse_res == -1)
        {
          ent->netgrdata.cursor = saved_cursor;
          return NSS_STATUS_TRYAGAIN;
@@ -426,7 +428,7 @@ getpwent_next_nis_netgr (const char *name, struct passwd *result, ent_t *ent,
 static enum nss_status
 getpwent_next_nisplus_netgr (const char *name, struct passwd *result,
                             ent_t *ent, char *group, char *buffer,
-                            size_t buflen)
+                            size_t buflen, int *errnop)
 {
   char *ypdomain, *host, *user, *domain, *p2;
   int status, parse_res;
@@ -456,7 +458,8 @@ getpwent_next_nisplus_netgr (const char *name, struct passwd *result,
 
       saved_cursor = ent->netgrdata.cursor;
       status = __internal_getnetgrent_r (&host, &user, &domain,
-                                        &ent->netgrdata, buffer, buflen);
+                                        &ent->netgrdata, buffer, buflen,
+                                        errnop);
       if (status != 1)
        {
          __internal_endnetgrent (&ent->netgrdata);
@@ -479,7 +482,7 @@ getpwent_next_nisplus_netgr (const char *name, struct passwd *result,
       p2len = pwd_need_buflen (&ent->pwd);
       if (p2len > buflen)
        {
-         __set_errno (ERANGE);
+         *errnop = ERANGE;
          return NSS_STATUS_TRYAGAIN;
        }
       p2 = buffer + (buflen - p2len);
@@ -494,11 +497,13 @@ getpwent_next_nisplus_netgr (const char *name, struct passwd *result,
          nis_freeresult (nisres);
          continue;
        }
-      if ((parse_res = _nss_nisplus_parse_pwent (nisres, result, buffer,
-                                                buflen)) == -1)
+      parse_res = _nss_nisplus_parse_pwent (nisres, result, buffer,
+                                           buflen, errnop);
+      if (parse_res == -1)
        {
          nis_freeresult (nisres);
          ent->netgrdata.cursor = saved_cursor;
+         *errnop = ERANGE;
          return NSS_STATUS_TRYAGAIN;
        }
       nis_freeresult (nisres);
@@ -518,7 +523,7 @@ getpwent_next_nisplus_netgr (const char *name, struct passwd *result,
 
 static enum nss_status
 getpwent_next_nisplus (struct passwd *result, ent_t *ent, char *buffer,
-                      size_t buflen)
+                      size_t buflen, int *errnop)
 {
   int parse_res;
   size_t p2len;
@@ -527,7 +532,7 @@ getpwent_next_nisplus (struct passwd *result, ent_t *ent, char *buffer,
   p2len = pwd_need_buflen (&ent->pwd);
   if (p2len > buflen)
     {
-      __set_errno (ERANGE);
+      *errnop = ERANGE;
       return NSS_STATUS_TRYAGAIN;
     }
   p2 = buffer + (buflen - p2len);
@@ -542,7 +547,7 @@ getpwent_next_nisplus (struct passwd *result, ent_t *ent, char *buffer,
          saved_first = TRUE;
          saved_res = ent->result;
 
-         ent->result = nis_first_entry(pwdtable);
+         ent->result = nis_first_entry (pwdtable);
           if (niserr2nss (ent->result->status) != NSS_STATUS_SUCCESS)
            {
              ent->nis = 0;
@@ -555,7 +560,7 @@ getpwent_next_nisplus (struct passwd *result, ent_t *ent, char *buffer,
        {
          nis_result *res;
 
-         res = nis_next_entry(pwdtable, &ent->result->cookie);
+         res = nis_next_entry (pwdtable, &ent->result->cookie);
          saved_res = ent->result;
          saved_first = FALSE;
          ent->result = res;
@@ -567,13 +572,14 @@ getpwent_next_nisplus (struct passwd *result, ent_t *ent, char *buffer,
              return niserr2nss (ent->result->status);
            }
        }
-      if ((parse_res = _nss_nisplus_parse_pwent (ent->result, result, buffer,
-                                                buflen)) == -1)
+      parse_res = _nss_nisplus_parse_pwent (ent->result, result, buffer,
+                                           buflen, errnop);
+      if (parse_res == -1)
        {
          nis_freeresult (ent->result);
          ent->result = saved_res;
          ent->first = saved_first;
-         __set_errno (ERANGE);
+         *errnop = ERANGE;
          return NSS_STATUS_TRYAGAIN;
        }
       else
@@ -595,7 +601,7 @@ getpwent_next_nisplus (struct passwd *result, ent_t *ent, char *buffer,
 
 static enum nss_status
 getpwent_next_nis (struct passwd *result, ent_t *ent, char *buffer,
-                  size_t buflen)
+                  size_t buflen, int *errnop)
 {
   struct parser_data *data = (void *) buffer;
   char *domain, *outkey, *outval, *p, *p2;
@@ -612,7 +618,7 @@ getpwent_next_nis (struct passwd *result, ent_t *ent, char *buffer,
   p2len = pwd_need_buflen (&ent->pwd);
   if (p2len > buflen)
     {
-      __set_errno (ERANGE);
+      *errnop = ERANGE;
       return NSS_STATUS_TRYAGAIN;
     }
   p2 = buffer + (buflen - p2len);
@@ -666,13 +672,14 @@ getpwent_next_nis (struct passwd *result, ent_t *ent, char *buffer,
 
       while (isspace (*p))
        ++p;
-      if ((parse_res = _nss_files_parse_pwent (p, result, data, buflen)) == -1)
+      parse_res = _nss_files_parse_pwent (p, result, data, buflen, errnop);
+      if (parse_res == -1)
        {
          free (ent->oldkey);
          ent->oldkey = saved_oldkey;
          ent->oldkeylen = saved_oldlen;
          ent->first = saved_first;
-         __set_errno (ERANGE);
+         *errnop = ERANGE;
          return NSS_STATUS_TRYAGAIN;
        }
       else
@@ -680,8 +687,8 @@ getpwent_next_nis (struct passwd *result, ent_t *ent, char *buffer,
          if (!saved_first)
            free (saved_oldkey);
        }
-      if (parse_res &&
-         in_blacklist (result->pw_name, strlen (result->pw_name), ent))
+      if (parse_res
+         && in_blacklist (result->pw_name, strlen (result->pw_name), ent))
        parse_res = 0;
     }
   while (!parse_res);
@@ -694,7 +701,7 @@ getpwent_next_nis (struct passwd *result, ent_t *ent, char *buffer,
 /* This function handle the +user entrys in /etc/passwd */
 static enum nss_status
 getpwnam_plususer (const char *name, struct passwd *result, char *buffer,
-                  size_t buflen)
+                  size_t buflen, int *errnop)
 {
   struct parser_data *data = (void *) buffer;
   struct passwd pwd;
@@ -709,7 +716,7 @@ getpwnam_plususer (const char *name, struct passwd *result, char *buffer,
   plen = pwd_need_buflen (&pwd);
   if (plen > buflen)
     {
-      __set_errno (ERANGE);
+      *errnop = ERANGE;
       return NSS_STATUS_TRYAGAIN;
     }
   p = buffer + (buflen - plen);
@@ -729,11 +736,12 @@ getpwnam_plususer (const char *name, struct passwd *result, char *buffer,
          nis_freeresult (res);
          return status;
        }
-      if ((parse_res = _nss_nisplus_parse_pwent (res, result, buffer,
-                                                buflen)) == -1)
+      parse_res = _nss_nisplus_parse_pwent (res, result, buffer,
+                                           buflen, errnop);
+      if (parse_res == -1)
        {
          nis_freeresult (res);
-         __set_errno (ERANGE);
+         *errnop = ERANGE;
          return NSS_STATUS_TRYAGAIN;
        }
       nis_freeresult (res);
@@ -744,24 +752,27 @@ getpwnam_plususer (const char *name, struct passwd *result, char *buffer,
       int outvallen;
 
       if (yp_get_default_domain (&domain) != YPERR_SUCCESS)
-       return NSS_STATUS_TRYAGAIN;
+       {
+         *errnop = errno;
+         return NSS_STATUS_TRYAGAIN;
+       }
 
       if (yp_match (domain, "passwd.byname", name, strlen (name),
                    &outval, &outvallen)
          != YPERR_SUCCESS)
-       return NSS_STATUS_TRYAGAIN;
+       {
+         *errnop = errno;
+         return NSS_STATUS_TRYAGAIN;
+       }
       ptr = strncpy (buffer, outval, buflen < (size_t) outvallen ?
                     buflen : (size_t) outvallen);
       buffer[buflen < (size_t) outvallen ? buflen : (size_t) outvallen] = '\0';
       free (outval);
       while (isspace (*ptr))
        ptr++;
-      if ((parse_res = _nss_files_parse_pwent (ptr, result, data, buflen))
-         == -1)
-       {
-         __set_errno (ERANGE);
-         return NSS_STATUS_TRYAGAIN;
-       }
+      parse_res = _nss_files_parse_pwent (ptr, result, data, buflen, errnop);
+      if (parse_res == -1)
+       return NSS_STATUS_TRYAGAIN;
     }
 
   if (parse_res > 0)
@@ -782,7 +793,7 @@ getpwnam_plususer (const char *name, struct passwd *result, char *buffer,
 
 static enum nss_status
 getpwent_next_file (struct passwd *result, ent_t *ent,
-                   char *buffer, size_t buflen)
+                   char *buffer, size_t buflen, int *errnop)
 {
   struct parser_data *data = (void *) buffer;
   while (1)
@@ -796,7 +807,16 @@ getpwent_next_file (struct passwd *result, ent_t *ent,
          fgetpos (ent->stream, &pos);
          p = fgets (buffer, buflen, ent->stream);
          if (p == NULL)
-           return NSS_STATUS_NOTFOUND;
+           {
+             if (feof (ent->stream))
+               return NSS_STATUS_NOTFOUND;
+             else
+               {
+                 fsetpos (ent->stream, &pos);
+                 *errnop = ERANGE;
+                 return NSS_STATUS_TRYAGAIN;
+               }
+           }
 
          /* Terminate the line for any case.  */
          buffer[buflen - 1] = '\0';
@@ -808,13 +828,14 @@ getpwent_next_file (struct passwd *result, ent_t *ent,
       while (*p == '\0' || *p == '#' || /* Ignore empty and comment lines.  */
       /* Parse the line.  If it is invalid, loop to
          get the next line of the file to parse.  */
-            !(parse_res = _nss_files_parse_pwent (p, result, data, buflen)));
+            !(parse_res = _nss_files_parse_pwent (p, result, data, buflen,
+                                                  errnop)));
 
       if (parse_res == -1)
        {
          /* The parser ran out of space.  */
          fsetpos (ent->stream, &pos);
-         __set_errno (ERANGE);
+         *errnop = ERANGE;
          return NSS_STATUS_TRYAGAIN;
        }
 
@@ -826,14 +847,15 @@ getpwent_next_file (struct passwd *result, ent_t *ent,
       if (result->pw_name[0] == '-' && result->pw_name[1] == '@'
          && result->pw_name[2] != '\0')
        {
+         /* XXX Do not use fixed length buffer.  */
          char buf2[1024];
          char *user, *host, *domain;
          struct __netgrent netgrdata;
 
          bzero (&netgrdata, sizeof (struct __netgrent));
          __internal_setnetgrent (&result->pw_name[2], &netgrdata);
-         while (__internal_getnetgrent_r (&host, &user, &domain,
-                                          &netgrdata, buf2, sizeof (buf2)))
+         while (__internal_getnetgrent_r (&host, &user, &domain, &netgrdata,
+                                          buf2, sizeof (buf2), errnop))
            {
              if (user != NULL && user[0] != '-')
                blacklist_store_name (user, ent);
@@ -855,11 +877,11 @@ getpwent_next_file (struct passwd *result, ent_t *ent,
          if (use_nisplus)
            status =  getpwent_next_nisplus_netgr (NULL, result, ent,
                                                   &result->pw_name[2],
-                                                  buffer, buflen);
+                                                  buffer, buflen, errnop);
          else
            status =  getpwent_next_nis_netgr (NULL, result, ent,
                                               &result->pw_name[2],
-                                              buffer, buflen);
+                                              buffer, buflen, errnop);
          if (status == NSS_STATUS_RETURN)
            continue;
          else
@@ -884,14 +906,22 @@ getpwent_next_file (struct passwd *result, ent_t *ent,
             /etc/passwd */
          blacklist_store_name (&result->pw_name[1], ent);
          status = getpwnam_plususer (&result->pw_name[1], result, buffer,
-                                     buflen);
+                                     buflen, errnop);
          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;
+             {
+               if (status == NSS_STATUS_TRYAGAIN)
+                 {
+                   /* The parser ran out of space */
+                   fsetpos (ent->stream, &pos);
+                   *errnop = ERANGE;
+                 }
+               return status;
+             }
        }
 
       /* +:... */
@@ -902,9 +932,9 @@ getpwent_next_file (struct passwd *result, ent_t *ent,
          copy_pwd_changes (&ent->pwd, result, NULL, 0);
 
          if (use_nisplus)
-           return getpwent_next_nisplus (result, ent, buffer, buflen);
+           return getpwent_next_nisplus (result, ent, buffer, buflen, errnop);
          else
-           return getpwent_next_nis (result, ent, buffer, buflen);
+           return getpwent_next_nis (result, ent, buffer, buflen, errnop);
        }
     }
 
@@ -914,7 +944,7 @@ getpwent_next_file (struct passwd *result, ent_t *ent,
 
 static enum nss_status
 internal_getpwent_r (struct passwd *pw, ent_t *ent, char *buffer,
-                    size_t buflen)
+                    size_t buflen, int *errnop)
 {
   if (ent->netgroup)
     {
@@ -924,11 +954,12 @@ internal_getpwent_r (struct passwd *pw, ent_t *ent, char *buffer,
       /* Since this is not the first call, we don't need the group name */
       if (use_nisplus)
        status = getpwent_next_nisplus_netgr (NULL, pw, ent, NULL, buffer,
-                                             buflen);
+                                             buflen, errnop);
       else
-       status = getpwent_next_nis_netgr (NULL, pw, ent, NULL, buffer, buflen);
+       status = getpwent_next_nis_netgr (NULL, pw, ent, NULL, buffer, buflen,
+                                         errnop);
       if (status == NSS_STATUS_RETURN)
-       return getpwent_next_file (pw, ent, buffer, buflen);
+       return getpwent_next_file (pw, ent, buffer, buflen, errnop);
       else
        return status;
     }
@@ -936,16 +967,17 @@ internal_getpwent_r (struct passwd *pw, ent_t *ent, char *buffer,
     if (ent->nis)
       {
        if (use_nisplus)
-         return getpwent_next_nisplus (pw, ent, buffer, buflen);
+         return getpwent_next_nisplus (pw, ent, buffer, buflen, errnop);
        else
-         return getpwent_next_nis (pw, ent, buffer, buflen);
+         return getpwent_next_nis (pw, ent, buffer, buflen, errnop);
       }
     else
-      return getpwent_next_file (pw, ent, buffer, buflen);
+      return getpwent_next_file (pw, ent, buffer, buflen, errnop);
 }
 
 enum nss_status
-_nss_compat_getpwent_r (struct passwd *pwd, char *buffer, size_t buflen)
+_nss_compat_getpwent_r (struct passwd *pwd, char *buffer, size_t buflen,
+                       int *errnop)
 {
   enum nss_status status = NSS_STATUS_SUCCESS;
 
@@ -962,7 +994,7 @@ _nss_compat_getpwent_r (struct passwd *pwd, char *buffer, size_t buflen)
     status = internal_setpwent (&ext_ent);
 
   if (status == NSS_STATUS_SUCCESS)
-    status = internal_getpwent_r (pwd, &ext_ent, buffer, buflen);
+    status = internal_getpwent_r (pwd, &ext_ent, buffer, buflen, errnop);
 
   __libc_lock_unlock (lock);
 
@@ -972,7 +1004,7 @@ _nss_compat_getpwent_r (struct passwd *pwd, char *buffer, size_t buflen)
 /* Searches in /etc/passwd and the NIS/NIS+ map for a special user */
 static enum nss_status
 internal_getpwnam_r (const char *name, struct passwd *result, ent_t *ent,
-                    char *buffer, size_t buflen)
+                    char *buffer, size_t buflen, int *errnop)
 {
   struct parser_data *data = (void *) buffer;
 
@@ -992,7 +1024,8 @@ internal_getpwnam_r (const char *name, struct passwd *result, ent_t *ent,
                return NSS_STATUS_NOTFOUND;
              else
                {
-                 __set_errno (ERANGE);
+                 fsetpos (ent->stream, &pos);
+                 *errnop = ERANGE;
                  return NSS_STATUS_TRYAGAIN;
                }
            }
@@ -1007,13 +1040,14 @@ internal_getpwnam_r (const char *name, struct passwd *result, ent_t *ent,
       while (*p == '\0' || *p == '#' || /* Ignore empty and comment lines.  */
             /* Parse the line.  If it is invalid, loop to
                get the next line of the file to parse.  */
-            !(parse_res = _nss_files_parse_pwent (p, result, data, buflen)));
+            !(parse_res = _nss_files_parse_pwent (p, result, data, buflen,
+                                                  errnop)));
 
       if (parse_res == -1)
        {
          /* The parser ran out of space.  */
          fsetpos (ent->stream, &pos);
-         __set_errno (ERANGE);
+         *errnop = ERANGE;
          return NSS_STATUS_TRYAGAIN;
        }
 
@@ -1030,14 +1064,15 @@ internal_getpwnam_r (const char *name, struct passwd *result, ent_t *ent,
       if (result->pw_name[0] == '-' && result->pw_name[1] == '@'
          && result->pw_name[2] != '\0')
        {
+         /* XXX Do not use fixed length buffers.  */
          char buf2[1024];
          char *user, *host, *domain;
          struct __netgrent netgrdata;
 
          bzero (&netgrdata, sizeof (struct __netgrent));
          __internal_setnetgrent (&result->pw_name[2], &netgrdata);
-         while (__internal_getnetgrent_r (&host, &user, &domain,
-                                          &netgrdata, buf2, sizeof (buf2)))
+         while (__internal_getnetgrent_r (&host, &user, &domain, &netgrdata,
+                                          buf2, sizeof (buf2), errnop))
            {
              if (user != NULL && user[0] != '-')
                if (strcmp (user, name) == 0)
@@ -1063,10 +1098,10 @@ internal_getpwnam_r (const char *name, struct passwd *result, ent_t *ent,
            {
              if (use_nisplus)
                status = getpwent_next_nisplus_netgr (name, result, ent, buf,
-                                                     buffer, buflen);
+                                                     buffer, buflen, errnop);
              else
                status = getpwent_next_nis_netgr (name, result, ent, buf,
-                                                 buffer, buflen);
+                                                 buffer, buflen, errnop);
              if (status == NSS_STATUS_RETURN)
                continue;
 
@@ -1095,7 +1130,8 @@ internal_getpwnam_r (const char *name, struct passwd *result, ent_t *ent,
            {
              enum nss_status status;
 
-             status = getpwnam_plususer (name, result, buffer, buflen);
+             status = getpwnam_plususer (name, result, buffer, buflen,
+                                         errnop);
              if (status == NSS_STATUS_RETURN)
                /* We couldn't parse the entry */
                return NSS_STATUS_NOTFOUND;
@@ -1109,7 +1145,7 @@ internal_getpwnam_r (const char *name, struct passwd *result, ent_t *ent,
        {
          enum nss_status status;
 
-         status = getpwnam_plususer (name, result, buffer, buflen);
+         status = getpwnam_plususer (name, result, buffer, buflen, errnop);
          if (status == NSS_STATUS_SUCCESS) /* We found the entry. */
            break;
          else
@@ -1124,7 +1160,7 @@ internal_getpwnam_r (const char *name, struct passwd *result, ent_t *ent,
 
 enum nss_status
 _nss_compat_getpwnam_r (const char *name, struct passwd *pwd,
-                       char *buffer, size_t buflen)
+                       char *buffer, size_t buflen, int *errnop)
 {
   ent_t ent = {0, 0, 0, NULL, 0, NULL, NULL, {NULL, 0, 0},
               {NULL, NULL, 0, 0, NULL, NULL, NULL}};
@@ -1147,7 +1183,7 @@ _nss_compat_getpwnam_r (const char *name, struct passwd *pwd,
   if (status != NSS_STATUS_SUCCESS)
     return status;
 
-  status = internal_getpwnam_r (name, pwd, &ent, buffer, buflen);
+  status = internal_getpwnam_r (name, pwd, &ent, buffer, buflen, errnop);
 
   internal_endpwent (&ent);
 
@@ -1157,7 +1193,7 @@ _nss_compat_getpwnam_r (const char *name, struct passwd *pwd,
 /* This function handle the + entry in /etc/passwd for getpwuid */
 static enum nss_status
 getpwuid_plususer (uid_t uid, struct passwd *result, char *buffer,
-                  size_t buflen)
+                  size_t buflen, int *errnop)
 {
   struct parser_data *data = (void *) buffer;
   struct passwd pwd;
@@ -1172,7 +1208,7 @@ getpwuid_plususer (uid_t uid, struct passwd *result, char *buffer,
   plen = pwd_need_buflen (&pwd);
   if (plen > buflen)
     {
-      __set_errno (ERANGE);
+      *errnop = ERANGE;
       return NSS_STATUS_TRYAGAIN;
     }
   p = buffer + (buflen - plen);
@@ -1183,7 +1219,7 @@ getpwuid_plususer (uid_t uid, struct passwd *result, char *buffer,
       nis_result *res;
       char buf[1024 + pwdtablelen];
 
-      sprintf(buf, "[uid=%d],%s", uid, pwdtable);
+      snprintf(buf, sizeof (buf), "[uid=%d],%s", uid, pwdtable);
       res = nis_list(buf, FOLLOW_PATH | FOLLOW_LINKS, NULL, NULL);
       if (niserr2nss (res->status) != NSS_STATUS_SUCCESS)
        {
@@ -1193,10 +1229,10 @@ getpwuid_plususer (uid_t uid, struct passwd *result, char *buffer,
          return status;
        }
       if ((parse_res = _nss_nisplus_parse_pwent (res, result, buffer,
-                                                buflen)) == -1)
+                                                buflen, errnop)) == -1)
        {
          nis_freeresult (res);
-         __set_errno (ERANGE);
+         *errnop = ERANGE;
          return NSS_STATUS_TRYAGAIN;
        }
       nis_freeresult (res);
@@ -1208,25 +1244,28 @@ getpwuid_plususer (uid_t uid, struct passwd *result, char *buffer,
       int outvallen;
 
       if (yp_get_default_domain (&domain) != YPERR_SUCCESS)
-       return NSS_STATUS_TRYAGAIN;
+       {
+         *errnop = errno;
+         return NSS_STATUS_TRYAGAIN;
+       }
 
       sprintf (buf, "%d", uid);
       if (yp_match (domain, "passwd.byuid", buf, strlen (buf),
                    &outval, &outvallen)
          != YPERR_SUCCESS)
-       return NSS_STATUS_TRYAGAIN;
+       {
+         *errnop = errno;
+         return NSS_STATUS_TRYAGAIN;
+       }
       ptr = strncpy (buffer, outval, buflen < (size_t) outvallen ?
                     buflen : (size_t) outvallen);
       buffer[buflen < (size_t) outvallen ? buflen : (size_t) outvallen] = '\0';
       free (outval);
       while (isspace (*ptr))
        ptr++;
-      if ((parse_res = _nss_files_parse_pwent (ptr, result, data, buflen))
-         == -1)
-       {
-         __set_errno (ERANGE);
-         return NSS_STATUS_TRYAGAIN;
-       }
+      parse_res = _nss_files_parse_pwent (ptr, result, data, buflen, errnop);
+      if (parse_res == -1)
+       return NSS_STATUS_TRYAGAIN;
     }
 
   if (parse_res > 0)
@@ -1248,7 +1287,7 @@ getpwuid_plususer (uid_t uid, struct passwd *result, char *buffer,
 /* Searches in /etc/passwd and the NIS/NIS+ map for a special user id */
 static enum nss_status
 internal_getpwuid_r (uid_t uid, struct passwd *result, ent_t *ent,
-                    char *buffer, size_t buflen)
+                    char *buffer, size_t buflen, int *errnop)
 {
   struct parser_data *data = (void *) buffer;
 
@@ -1263,7 +1302,16 @@ internal_getpwuid_r (uid_t uid, struct passwd *result, ent_t *ent,
          fgetpos (ent->stream, &pos);
          p = fgets (buffer, buflen, ent->stream);
          if (p == NULL)
-           return NSS_STATUS_NOTFOUND;
+           {
+             if (feof (ent->stream))
+               return NSS_STATUS_NOTFOUND;
+             else
+               {
+                 fsetpos (ent->stream, &pos);
+                 *errnop = ERANGE;
+                 return NSS_STATUS_TRYAGAIN;
+               }
+           }
 
          /* Terminate the line for any case.  */
          buffer[buflen - 1] = '\0';
@@ -1275,13 +1323,14 @@ internal_getpwuid_r (uid_t uid, struct passwd *result, ent_t *ent,
       while (*p == '\0' || *p == '#' || /* Ignore empty and comment lines.  */
             /* Parse the line.  If it is invalid, loop to
                get the next line of the file to parse.  */
-            !(parse_res = _nss_files_parse_pwent (p, result, data, buflen)));
+            !(parse_res = _nss_files_parse_pwent (p, result, data, buflen,
+                                                  errnop)));
 
       if (parse_res == -1)
        {
          /* The parser ran out of space.  */
          fsetpos (ent->stream, &pos);
-         __set_errno (ERANGE);
+         *errnop = ERANGE;
          return NSS_STATUS_TRYAGAIN;
        }
 
@@ -1298,14 +1347,15 @@ internal_getpwuid_r (uid_t uid, struct passwd *result, ent_t *ent,
       if (result->pw_name[0] == '-' && result->pw_name[1] == '@'
          && result->pw_name[2] != '\0')
        {
+         /* XXX Do not use fixed length buffers.  */
          char buf2[1024];
          char *user, *host, *domain;
          struct __netgrent netgrdata;
 
          bzero (&netgrdata, sizeof (struct __netgrent));
          __internal_setnetgrent (&result->pw_name[2], &netgrdata);
-         while (__internal_getnetgrent_r (&host, &user, &domain,
-                                          &netgrdata, buf2, sizeof (buf2)))
+         while (__internal_getnetgrent_r (&host, &user, &domain, &netgrdata,
+                                          buf2, sizeof (buf2), errnop))
            {
               if (user != NULL && user[0] != '-')
                 blacklist_store_name (user, ent);
@@ -1330,10 +1380,10 @@ internal_getpwuid_r (uid_t uid, struct passwd *result, ent_t *ent,
            {
              if (use_nisplus)
                status = getpwent_next_nisplus_netgr (NULL, result, ent, buf,
-                                                     buffer, buflen);
+                                                     buffer, buflen, errnop);
              else
                status = getpwent_next_nis_netgr (NULL, result, ent, buf,
-                                                 buffer, buflen);
+                                                 buffer, buflen, errnop);
              if (status == NSS_STATUS_RETURN)
                continue;
 
@@ -1361,7 +1411,7 @@ internal_getpwuid_r (uid_t uid, struct passwd *result, ent_t *ent,
              /etc/passwd */
           blacklist_store_name (&result->pw_name[1], ent);
          status = getpwnam_plususer (&result->pw_name[1], result, buffer,
-                                     buflen);
+                                     buflen, errnop);
          if (status == NSS_STATUS_SUCCESS && result->pw_uid == uid)
            break;
          else
@@ -1373,7 +1423,7 @@ internal_getpwuid_r (uid_t uid, struct passwd *result, ent_t *ent,
        {
          enum nss_status status;
 
-         status = getpwuid_plususer (uid, result, buffer, buflen);
+         status = getpwuid_plususer (uid, result, buffer, buflen, errnop);
          if (status == NSS_STATUS_SUCCESS) /* We found the entry. */
            break;
          else
@@ -1388,7 +1438,7 @@ internal_getpwuid_r (uid_t uid, struct passwd *result, ent_t *ent,
 
 enum nss_status
 _nss_compat_getpwuid_r (uid_t uid, struct passwd *pwd,
-                       char *buffer, size_t buflen)
+                       char *buffer, size_t buflen, int *errnop)
 {
   ent_t ent = {0, 0, 0, NULL, 0, NULL, NULL, {NULL, 0, 0},
               {NULL, NULL, 0, 0, NULL, NULL, NULL}};
@@ -1408,7 +1458,7 @@ _nss_compat_getpwuid_r (uid_t uid, struct passwd *pwd,
   if (status != NSS_STATUS_SUCCESS)
     return status;
 
-  status = internal_getpwuid_r (uid, pwd, &ent, buffer, buflen);
+  status = internal_getpwuid_r (uid, pwd, &ent, buffer, buflen, errnop);
 
   internal_endpwent (&ent);
 
index 5da19d3feb9166f0654282a27a02732e4434f02a..92224f8ae70f099e35800a63cb3628a7cac554e3 100644 (file)
@@ -291,7 +291,7 @@ _nss_compat_endspent (void)
 
 static enum nss_status
 getspent_next_nis_netgr (const char *name, struct spwd *result, ent_t *ent,
-                        char *group, char *buffer, size_t buflen)
+                        char *group, char *buffer, size_t buflen, int *errnop)
 {
   struct parser_data *data = (void *) buffer;
   char *ypdomain, *host, *user, *domain, *outval, *p, *p2;
@@ -320,7 +320,8 @@ getspent_next_nis_netgr (const char *name, struct spwd *result, ent_t *ent,
 
       saved_cursor = ent->netgrdata.cursor;
       status = __internal_getnetgrent_r (&host, &user, &domain,
-                                        &ent->netgrdata, buffer, buflen);
+                                        &ent->netgrdata, buffer, buflen,
+                                        errnop);
       if (status != 1)
        {
          __internal_endnetgrent (&ent->netgrdata);
@@ -348,7 +349,7 @@ getspent_next_nis_netgr (const char *name, struct spwd *result, ent_t *ent,
       p2len = spwd_need_buflen (&ent->pwd);
       if (p2len > buflen)
        {
-         __set_errno (ERANGE);
+         *errnop = ERANGE;
          return NSS_STATUS_TRYAGAIN;
        }
       p2 = buffer + (buflen - p2len);
@@ -357,7 +358,8 @@ getspent_next_nis_netgr (const char *name, struct spwd *result, ent_t *ent,
       while (isspace (*p))
        p++;
       free (outval);
-      if ((parse_res = _nss_files_parse_spent (p, result, data, buflen)) == -1)
+      parse_res = _nss_files_parse_spent (p, result, data, buflen, errnop);
+      if (parse_res == -1)
        {
          ent->netgrdata.cursor = saved_cursor;
          return NSS_STATUS_TRYAGAIN;
@@ -379,7 +381,7 @@ getspent_next_nis_netgr (const char *name, struct spwd *result, ent_t *ent,
 static enum nss_status
 getspent_next_nisplus_netgr (const char *name, struct spwd *result,
                             ent_t *ent, char *group, char *buffer,
-                            size_t buflen)
+                            size_t buflen, int *errnop)
 {
   char *ypdomain, *host, *user, *domain, *p2;
   int status, parse_res;
@@ -409,7 +411,8 @@ getspent_next_nisplus_netgr (const char *name, struct spwd *result,
 
       saved_cursor = ent->netgrdata.cursor;
       status = __internal_getnetgrent_r (&host, &user, &domain,
-                                         &ent->netgrdata, buffer, buflen);
+                                         &ent->netgrdata, buffer, buflen,
+                                        errnop);
       if (status != 1)
         {
           __internal_endnetgrent (&ent->netgrdata);
@@ -432,25 +435,27 @@ getspent_next_nisplus_netgr (const char *name, struct spwd *result,
       p2len = spwd_need_buflen (&ent->pwd);
       if (p2len > buflen)
         {
-          __set_errno (ERANGE);
+          *errnop = ERANGE;
           return NSS_STATUS_TRYAGAIN;
         }
       p2 = buffer + (buflen - p2len);
       buflen -= p2len;
       {
         char buf[strlen (user) + 30 + pwdtablelen];
-        sprintf(buf, "[name=%s],%s", user, pwdtable);
-        nisres = nis_list(buf, FOLLOW_LINKS | FOLLOW_PATH, NULL, NULL);
+        sprintf (buf, "[name=%s],%s", user, pwdtable);
+        nisres = nis_list (buf, FOLLOW_LINKS | FOLLOW_PATH, NULL, NULL);
       }
       if (niserr2nss (nisres->status) != NSS_STATUS_SUCCESS)
         {
           nis_freeresult (nisres);
           continue;
         }
-      if ((parse_res = _nss_nisplus_parse_spent (nisres, result, buffer,
-                                                buflen)) == -1)
+      parse_res = _nss_nisplus_parse_spent (nisres, result, buffer,
+                                           buflen, errnop);
+      if (parse_res == -1)
        {
          nis_freeresult (nisres);
+         *errnop = ERANGE;
          return NSS_STATUS_TRYAGAIN;
        }
       nis_freeresult (nisres);
@@ -470,7 +475,7 @@ getspent_next_nisplus_netgr (const char *name, struct spwd *result,
 
 static enum nss_status
 getspent_next_nisplus (struct spwd *result, ent_t *ent, char *buffer,
-                       size_t buflen)
+                       size_t buflen, int *errnop)
 {
   int parse_res;
   size_t p2len;
@@ -479,7 +484,7 @@ getspent_next_nisplus (struct spwd *result, ent_t *ent, char *buffer,
   p2len = spwd_need_buflen (&ent->pwd);
   if (p2len > buflen)
     {
-      __set_errno (ERANGE);
+      *errnop = ERANGE;
       return NSS_STATUS_TRYAGAIN;
     }
   p2 = buffer + (buflen - p2len);
@@ -494,7 +499,7 @@ getspent_next_nisplus (struct spwd *result, ent_t *ent, char *buffer,
          saved_first = TRUE;
          saved_res = ent->result;
 
-          ent->result = nis_first_entry(pwdtable);
+          ent->result = nis_first_entry (pwdtable);
           if (niserr2nss (ent->result->status) != NSS_STATUS_SUCCESS)
             {
               ent->nis = 0;
@@ -510,7 +515,7 @@ getspent_next_nisplus (struct spwd *result, ent_t *ent, char *buffer,
          saved_first = FALSE;
          saved_res = ent->result;
 
-          res = nis_next_entry(pwdtable, &ent->result->cookie);
+          res = nis_next_entry (pwdtable, &ent->result->cookie);
           ent->result = res;
           if (niserr2nss (ent->result->status) != NSS_STATUS_SUCCESS)
             {
@@ -520,13 +525,14 @@ getspent_next_nisplus (struct spwd *result, ent_t *ent, char *buffer,
              return niserr2nss (ent->result->status);
             }
         }
-      if ((parse_res = _nss_nisplus_parse_spent (ent->result, result, buffer,
-                                                buflen)) == -1)
+      parse_res = _nss_nisplus_parse_spent (ent->result, result, buffer,
+                                           buflen, errnop);
+      if (parse_res == -1)
        {
          ent->first = saved_first;
          nis_freeresult (ent->result);
          ent->result = saved_res;
-         __set_errno (ERANGE);
+         *errnop = ERANGE;
          return NSS_STATUS_TRYAGAIN;
        }
       else
@@ -548,7 +554,7 @@ getspent_next_nisplus (struct spwd *result, ent_t *ent, char *buffer,
 
 static enum nss_status
 getspent_next_nis (struct spwd *result, ent_t *ent,
-                  char *buffer, size_t buflen)
+                  char *buffer, size_t buflen, int *errnop)
 {
   struct parser_data *data = (void *) buffer;
   char *domain, *outkey, *outval, *p, *p2;
@@ -565,7 +571,7 @@ getspent_next_nis (struct spwd *result, ent_t *ent,
   p2len = spwd_need_buflen (&ent->pwd);
   if (p2len > buflen)
     {
-      __set_errno (ERANGE);
+      *errnop = ERANGE;
       return NSS_STATUS_TRYAGAIN;
     }
   p2 = buffer + (buflen - p2len);
@@ -618,13 +624,14 @@ getspent_next_nis (struct spwd *result, ent_t *ent,
 
       while (isspace (*p))
        ++p;
-      if ((parse_res = _nss_files_parse_spent (p, result, data, buflen)) == -1)
+      parse_res = _nss_files_parse_spent (p, result, data, buflen, errnop);
+      if (parse_res == -1)
        {
          free (ent->oldkey);
          ent->oldkey = saved_oldkey;
          ent->oldkeylen = saved_oldlen;
          ent->first = saved_first;
-         __set_errno (ERANGE);
+         *errnop = ERANGE;
          return NSS_STATUS_TRYAGAIN;
        }
       else
@@ -646,7 +653,7 @@ getspent_next_nis (struct spwd *result, ent_t *ent,
 /* This function handle the +user entrys in /etc/shadow */
 static enum nss_status
 getspnam_plususer (const char *name, struct spwd *result, char *buffer,
-                  size_t buflen)
+                  size_t buflen, int *errnop)
 {
   struct parser_data *data = (void *) buffer;
   struct spwd pwd;
@@ -661,7 +668,7 @@ getspnam_plususer (const char *name, struct spwd *result, char *buffer,
   plen = spwd_need_buflen (&pwd);
   if (plen > buflen)
     {
-      __set_errno (ERANGE);
+      *errnop = ERANGE;
       return NSS_STATUS_TRYAGAIN;
     }
   p = buffer + (buflen - plen);
@@ -681,10 +688,12 @@ getspnam_plususer (const char *name, struct spwd *result, char *buffer,
           nis_freeresult (res);
           return status;
         }
-      if ((parse_res = _nss_nisplus_parse_spent (res, result, buffer,
-                                                buflen)) == -1)
+      parse_res = _nss_nisplus_parse_spent (res, result, buffer,
+                                           buflen, errnop);
+      if (parse_res == -1)
        {
          nis_freeresult (res);
+         *errnop = ERANGE;
          return NSS_STATUS_TRYAGAIN;
        }
       nis_freeresult (res);
@@ -695,24 +704,27 @@ getspnam_plususer (const char *name, struct spwd *result, char *buffer,
       int outvallen;
 
       if (yp_get_default_domain (&domain) != YPERR_SUCCESS)
-        return NSS_STATUS_TRYAGAIN;
+       {
+         *errnop = errno;
+         return NSS_STATUS_TRYAGAIN;
+       }
 
       if (yp_match (domain, "shadow.byname", name, strlen (name),
                    &outval, &outvallen)
           != YPERR_SUCCESS)
-        return NSS_STATUS_TRYAGAIN;
+       {
+         *errnop = errno;
+         return NSS_STATUS_TRYAGAIN;
+       }
       ptr = strncpy (buffer, outval, buflen < (size_t) outvallen ?
                     buflen : (size_t) outvallen);
       buffer[buflen < (size_t) outvallen ? buflen : (size_t) outvallen] = '\0';
       free (outval);
       while (isspace (*ptr))
         ptr++;
-      if ((parse_res = _nss_files_parse_spent (ptr, result, data, buflen))
-         == -1)
-       {
-         __set_errno (ERANGE);
-         return NSS_STATUS_TRYAGAIN;
-       }
+      parse_res = _nss_files_parse_spent (ptr, result, data, buflen, errnop);
+      if (parse_res == -1)
+       return NSS_STATUS_TRYAGAIN;
     }
 
   if (parse_res)
@@ -733,7 +745,7 @@ getspnam_plususer (const char *name, struct spwd *result, char *buffer,
 
 static enum nss_status
 getspent_next_file (struct spwd *result, ent_t *ent,
-                   char *buffer, size_t buflen)
+                   char *buffer, size_t buflen, int *errnop)
 {
   struct parser_data *data = (void *) buffer;
   while (1)
@@ -760,13 +772,13 @@ getspent_next_file (struct spwd *result, ent_t *ent,
       /* Parse the line.  If it is invalid, loop to
          get the next line of the file to parse.  */
             || !(parse_res = _nss_files_parse_spent (p, result, data,
-                                                     buflen)));
+                                                     buflen, errnop)));
 
       if (parse_res == -1)
         {
           /* The parser ran out of space.  */
           fsetpos (ent->stream, &pos);
-          __set_errno (ERANGE);
+          *errnop = ERANGE;
           return NSS_STATUS_TRYAGAIN;
         }
 
@@ -778,6 +790,7 @@ getspent_next_file (struct spwd *result, ent_t *ent,
       if (result->sp_namp[0] == '-' && result->sp_namp[1] == '@'
          && result->sp_namp[2] != '\0')
        {
+         /* XXX Do not use fixed length buffers.  */
           char buf2[1024];
          char *user, *host, *domain;
           struct __netgrent netgrdata;
@@ -785,7 +798,8 @@ getspent_next_file (struct spwd *result, ent_t *ent,
           bzero (&netgrdata, sizeof (struct __netgrent));
           __internal_setnetgrent (&result->sp_namp[2], &netgrdata);
          while (__internal_getnetgrent_r (&host, &user, &domain,
-                                          &netgrdata, buf2, sizeof (buf2)))
+                                          &netgrdata, buf2, sizeof (buf2),
+                                          errnop))
            {
              if (user != NULL && user[0] != '-')
                blacklist_store_name (user, ent);
@@ -807,11 +821,11 @@ getspent_next_file (struct spwd *result, ent_t *ent,
          if (use_nisplus)
            status = getspent_next_nisplus_netgr (NULL, result, ent,
                                                  &result->sp_namp[2],
-                                                 buffer, buflen);
+                                                 buffer, buflen, errnop);
          else
            status = getspent_next_nis_netgr (NULL, result, ent,
                                              &result->sp_namp[2],
-                                             buffer, buflen);
+                                             buffer, buflen, errnop);
          if (status == NSS_STATUS_RETURN)
            continue;
          else
@@ -836,14 +850,21 @@ getspent_next_file (struct spwd *result, ent_t *ent,
             /etc/passwd */
          blacklist_store_name (&result->sp_namp[1], ent);
           status = getspnam_plususer (&result->sp_namp[1], result, buffer,
-                                     buflen);
+                                     buflen, errnop);
           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;
+             {
+               if (status == NSS_STATUS_TRYAGAIN)
+                 {
+                   fsetpos (ent->stream, &pos);
+                   *errnop = ERANGE;
+                 }
+               return status;
+             }
        }
 
       /* +:... */
@@ -854,9 +875,9 @@ getspent_next_file (struct spwd *result, ent_t *ent,
          copy_spwd_changes (&ent->pwd, result, NULL, 0);
 
          if (use_nisplus)
-           return getspent_next_nisplus (result, ent, buffer, buflen);
+           return getspent_next_nisplus (result, ent, buffer, buflen, errnop);
          else
-           return getspent_next_nis (result, ent, buffer, buflen);
+           return getspent_next_nis (result, ent, buffer, buflen, errnop);
        }
     }
 
@@ -866,7 +887,7 @@ getspent_next_file (struct spwd *result, ent_t *ent,
 
 static enum nss_status
 internal_getspent_r (struct spwd *pw, ent_t *ent,
-                    char *buffer, size_t buflen)
+                    char *buffer, size_t buflen, int *errnop)
 {
   if (ent->netgroup)
     {
@@ -876,11 +897,12 @@ internal_getspent_r (struct spwd *pw, ent_t *ent,
       /* Since this is not the first call, we don't need the group name */
       if (use_nisplus)
        status = getspent_next_nisplus_netgr (NULL, pw, ent, NULL, buffer,
-                                             buflen);
+                                             buflen, errnop);
       else
-       status = getspent_next_nis_netgr (NULL, pw, ent, NULL, buffer, buflen);
+       status = getspent_next_nis_netgr (NULL, pw, ent, NULL, buffer, buflen,
+                                         errnop);
       if (status == NSS_STATUS_RETURN)
-       return getspent_next_file (pw, ent, buffer, buflen);
+       return getspent_next_file (pw, ent, buffer, buflen, errnop);
       else
        return status;
     }
@@ -888,16 +910,17 @@ internal_getspent_r (struct spwd *pw, ent_t *ent,
     if (ent->nis)
       {
        if (use_nisplus)
-         return getspent_next_nisplus (pw, ent, buffer, buflen);
+         return getspent_next_nisplus (pw, ent, buffer, buflen, errnop);
        else
-         return getspent_next_nis (pw, ent, buffer, buflen);
+         return getspent_next_nis (pw, ent, buffer, buflen, errnop);
       }
     else
-      return getspent_next_file (pw, ent, buffer, buflen);
+      return getspent_next_file (pw, ent, buffer, buflen, errnop);
 }
 
 enum nss_status
-_nss_compat_getspent_r (struct spwd *pwd, char *buffer, size_t buflen)
+_nss_compat_getspent_r (struct spwd *pwd, char *buffer, size_t buflen,
+                       int *errnop)
 {
   enum nss_status status = NSS_STATUS_SUCCESS;
 
@@ -914,7 +937,7 @@ _nss_compat_getspent_r (struct spwd *pwd, char *buffer, size_t buflen)
     status = internal_setspent (&ext_ent);
 
   if (status == NSS_STATUS_SUCCESS)
-    status = internal_getspent_r (pwd, &ext_ent, buffer, buflen);
+    status = internal_getspent_r (pwd, &ext_ent, buffer, buflen, errnop);
 
   __libc_lock_unlock (lock);
 
@@ -924,7 +947,7 @@ _nss_compat_getspent_r (struct spwd *pwd, char *buffer, size_t buflen)
 /* Searches in /etc/passwd and the NIS/NIS+ map for a special user */
 static enum nss_status
 internal_getspnam_r (const char *name, struct spwd *result, ent_t *ent,
-                    char *buffer, size_t buflen)
+                    char *buffer, size_t buflen, int *errnop)
 {
   struct parser_data *data = (void *) buffer;
 
@@ -951,13 +974,14 @@ internal_getspnam_r (const char *name, struct spwd *result, ent_t *ent,
       while (*p == '\0' || *p == '#' || /* Ignore empty and comment lines.  */
             /* Parse the line.  If it is invalid, loop to
                get the next line of the file to parse.  */
-            !(parse_res = _nss_files_parse_spent (p, result, data, buflen)));
+            !(parse_res = _nss_files_parse_spent (p, result, data, buflen,
+                                                  errnop)));
 
       if (parse_res == -1)
        {
          /* The parser ran out of space.  */
          fsetpos (ent->stream, &pos);
-         __set_errno (ERANGE);
+         *errnop = ERANGE;
          return NSS_STATUS_TRYAGAIN;
        }
 
@@ -974,14 +998,15 @@ internal_getspnam_r (const char *name, struct spwd *result, ent_t *ent,
       if (result->sp_namp[0] == '-' && result->sp_namp[1] == '@'
          && result->sp_namp[2] != '\0')
        {
+         /* XXX Do not use fixed length buffers.  */
          char buf2[1024];
          char *user, *host, *domain;
          struct __netgrent netgrdata;
 
          bzero (&netgrdata, sizeof (struct __netgrent));
          __internal_setnetgrent (&result->sp_namp[2], &netgrdata);
-         while (__internal_getnetgrent_r (&host, &user, &domain,
-                                          &netgrdata, buf2, sizeof (buf2)))
+         while (__internal_getnetgrent_r (&host, &user, &domain, &netgrdata,
+                                          buf2, sizeof (buf2), errnop))
            {
              if (user != NULL && user[0] != '-')
                if (strcmp (user, name) == 0)
@@ -995,10 +1020,9 @@ internal_getspnam_r (const char *name, struct spwd *result, ent_t *ent,
       if (result->sp_namp[0] == '+' && result->sp_namp[1] == '@'
          && result->sp_namp[2] != '\0')
        {
-         char buf[strlen (result->sp_namp)];
+         char *buf = strdupa (&result->sp_namp[2]);
          int status;
 
-         strcpy (buf, &result->sp_namp[2]);
          ent->netgroup = TRUE;
          ent->first = TRUE;
          copy_spwd_changes (&ent->pwd, result, NULL, 0);
@@ -1007,15 +1031,15 @@ internal_getspnam_r (const char *name, struct spwd *result, ent_t *ent,
            {
              if (use_nisplus)
                status = getspent_next_nisplus_netgr (name, result, ent, buf,
-                                                     buffer, buflen);
+                                                     buffer, buflen, errnop);
              else
                status = getspent_next_nis_netgr (name, result, ent, buf,
-                                                 buffer, buflen);
+                                                 buffer, buflen, errnop);
              if (status == NSS_STATUS_RETURN)
                continue;
 
-             if (status == NSS_STATUS_SUCCESS &&
-                 strcmp (result->sp_namp, name) == 0)
+             if (status == NSS_STATUS_SUCCESS
+                 && strcmp (result->sp_namp, name) == 0)
                return NSS_STATUS_SUCCESS;
            } while (status == NSS_STATUS_SUCCESS);
          continue;
@@ -1039,7 +1063,8 @@ internal_getspnam_r (const char *name, struct spwd *result, ent_t *ent,
            {
              enum nss_status status;
 
-             status = getspnam_plususer (name, result, buffer, buflen);
+             status = getspnam_plususer (name, result, buffer, buflen,
+                                         errnop);
              if (status == NSS_STATUS_RETURN)
                /* We couldn't parse the entry */
                return NSS_STATUS_NOTFOUND;
@@ -1053,7 +1078,7 @@ internal_getspnam_r (const char *name, struct spwd *result, ent_t *ent,
        {
          enum nss_status status;
 
-         status = getspnam_plususer (name, result, buffer, buflen);
+         status = getspnam_plususer (name, result, buffer, buflen, errnop);
          if (status == NSS_STATUS_RETURN) /* We couldn't parse the entry */
            return NSS_STATUS_NOTFOUND;
          else
@@ -1065,7 +1090,7 @@ internal_getspnam_r (const char *name, struct spwd *result, ent_t *ent,
 
 enum nss_status
 _nss_compat_getspnam_r (const char *name, struct spwd *pwd,
-                       char *buffer, size_t buflen)
+                       char *buffer, size_t buflen, int *errnop)
 {
   ent_t ent = {0, 0, 0, NULL, 0, NULL, NULL, {NULL, 0, 0},
               {NULL, NULL, 0, 0, 0, 0, 0, 0, 0}};
@@ -1084,7 +1109,7 @@ _nss_compat_getspnam_r (const char *name, struct spwd *pwd,
   if (status != NSS_STATUS_SUCCESS)
     return status;
 
-  status = internal_getspnam_r (name, pwd, &ent, buffer, buflen);
+  status = internal_getspnam_r (name, pwd, &ent, buffer, buflen, errnop);
 
   internal_endspent (&ent);
 
index e187716bb0d2b881c23e58ed81d7be254467aa49..0d0294082dc018596c1c33729fd21107ce2a4a57 100644 (file)
@@ -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.
 
@@ -36,7 +36,7 @@ static int oldkeylen = 0;
 
 static int
 _nss_nis_parse_aliasent (const char *key, char *alias, struct aliasent *result,
-                        char *buffer, size_t buflen)
+                        char *buffer, size_t buflen, int *errnop)
 {
   char *first_unused = buffer + strlen (alias) + 1;
   size_t room_left =
@@ -53,7 +53,7 @@ _nss_nis_parse_aliasent (const char *key, char *alias, struct aliasent *result,
     {
       /* The line is too long for our buffer.  */
     no_more_room:
-      __set_errno (ERANGE);
+      *errnop = ERANGE;
       return -1;
     }
 
@@ -138,7 +138,7 @@ _nss_nis_endaliasent (void)
 
 static enum nss_status
 internal_nis_getaliasent_r (struct aliasent *alias, char *buffer,
-                           size_t buflen)
+                           size_t buflen, int *errnop)
 {
   char *domain;
   char *result;
@@ -168,14 +168,14 @@ internal_nis_getaliasent_r (struct aliasent *alias, char *buffer,
       if (retval != NSS_STATUS_SUCCESS)
        {
          if (retval == NSS_STATUS_TRYAGAIN)
-            __set_errno (EAGAIN);
+            *errnop = errno;
           return retval;
         }
 
       if ((size_t) (len + 1) > buflen)
         {
          free (result);
-          __set_errno (ERANGE);
+          *errnop = ERANGE;
           return NSS_STATUS_TRYAGAIN;
         }
       p = strncpy (buffer, result, len);
@@ -184,11 +184,12 @@ internal_nis_getaliasent_r (struct aliasent *alias, char *buffer,
         ++p;
       free (result);
 
-      if ((parse_res = _nss_nis_parse_aliasent (outkey, p, alias, 
-                                               buffer, buflen)) == -1)
+      parse_res = _nss_nis_parse_aliasent (outkey, p, alias, buffer, buflen,
+                                          errnop);
+      if (parse_res == -1)
        {
          free (outkey);
-         __set_errno (ERANGE);
+         *errnop = ERANGE;
          return NSS_STATUS_TRYAGAIN;
        }
 
@@ -203,13 +204,14 @@ internal_nis_getaliasent_r (struct aliasent *alias, char *buffer,
 }
 
 enum nss_status
-_nss_nis_getaliasent_r (struct aliasent *alias, char *buffer, size_t buflen)
+_nss_nis_getaliasent_r (struct aliasent *alias, char *buffer, size_t buflen,
+                       int *errnop)
 {
   enum nss_status status;
 
   __libc_lock_lock (lock);
 
-  status = internal_nis_getaliasent_r (alias, buffer, buflen);
+  status = internal_nis_getaliasent_r (alias, buffer, buflen, errnop);
 
   __libc_lock_unlock (lock);
 
@@ -218,7 +220,7 @@ _nss_nis_getaliasent_r (struct aliasent *alias, char *buffer, size_t buflen)
 
 enum nss_status
 _nss_nis_getaliasbyname_r (const char *name, struct aliasent *alias,
-                          char *buffer, size_t buflen)
+                          char *buffer, size_t buflen, int *errnop)
 {
   enum nss_status retval;
   int parse_res;
@@ -241,14 +243,14 @@ _nss_nis_getaliasbyname_r (const char *name, struct aliasent *alias,
   if (retval != NSS_STATUS_SUCCESS)
     {
       if (retval == NSS_STATUS_TRYAGAIN)
-       __set_errno (EAGAIN);
+       *errnop = errno;
       return retval;
     }
 
   if ((size_t) (len + 1) > buflen)
     {
       free (result);
-      __set_errno (ERANGE);
+      *errnop = ERANGE;
       return NSS_STATUS_TRYAGAIN;
     }
 
@@ -259,10 +261,10 @@ _nss_nis_getaliasbyname_r (const char *name, struct aliasent *alias,
   free (result);
 
   alias->alias_local = 0;
-  if ((parse_res = _nss_nis_parse_aliasent (name, p, alias, buffer, 
-                                           buflen)) == -1)
+  parse_res = _nss_nis_parse_aliasent (name, p, alias, buffer, buflen, errnop);
+  if (parse_res == -1)
     return NSS_STATUS_TRYAGAIN;
-  
+
   if (parse_res)
     return NSS_STATUS_SUCCESS;
   else
index e54262409cac9bc76494a9de34e8d29ad9776a74..365f9c9c1d4c8dc1932672ac92d3d71ee445be0b 100644 (file)
@@ -143,7 +143,8 @@ _nss_nis_endetherent (void)
 }
 
 static enum nss_status
-internal_nis_getetherent_r (struct ether *eth, char *buffer, size_t buflen)
+internal_nis_getetherent_r (struct ether *eth, char *buffer, size_t buflen,
+                           int *errnop)
 {
   struct parser_data *data = (void *) buffer;
   int parse_res;
@@ -163,23 +164,25 @@ internal_nis_getetherent_r (struct ether *eth, char *buffer, size_t buflen)
       while (isspace (*p))
         ++p;
 
-      if ((parse_res = _nss_files_parse_etherent (p, eth, data, buflen)) == -1)
+      parse_res = _nss_files_parse_etherent (p, eth, data, buflen, errnop);
+      if (parse_res == -1)
        return NSS_STATUS_TRYAGAIN;
       next = next->next;
     }
   while (!parse_res);
-  
+
   return NSS_STATUS_SUCCESS;
 }
 
 enum nss_status
-_nss_nis_getetherent_r (struct ether *result, char *buffer, size_t buflen)
+_nss_nis_getetherent_r (struct ether *result, char *buffer, size_t buflen,
+                       int *errnop)
 {
   int status;
 
   __libc_lock_lock (lock);
 
-  status = internal_nis_getetherent_r (result, buffer, buflen);
+  status = internal_nis_getetherent_r (result, buffer, buflen, errnop);
 
   __libc_lock_unlock (lock);
 
@@ -188,7 +191,7 @@ _nss_nis_getetherent_r (struct ether *result, char *buffer, size_t buflen)
 
 enum nss_status
 _nss_nis_gethostton_r (const char *name, struct ether *eth,
-                      char *buffer, size_t buflen)
+                      char *buffer, size_t buflen, int *errnop)
 {
   struct parser_data *data = (void *) buffer;
   enum nss_status retval;
@@ -210,14 +213,14 @@ _nss_nis_gethostton_r (const char *name, struct ether *eth,
   if (retval != NSS_STATUS_SUCCESS)
     {
       if (retval == NSS_STATUS_TRYAGAIN)
-        __set_errno (EAGAIN);
+        *errnop = errno;
       return retval;
     }
 
   if ((size_t) (len + 1) > buflen)
     {
       free (result);
-      __set_errno (ERANGE);
+      *errnop = ERANGE;
       return NSS_STATUS_TRYAGAIN;
     }
 
@@ -227,7 +230,8 @@ _nss_nis_gethostton_r (const char *name, struct ether *eth,
     ++p;
   free (result);
 
-  if ((parse_res = _nss_files_parse_etherent (p, eth, data, buflen)) == -1)
+  parse_res = _nss_files_parse_etherent (p, eth, data, buflen, errnop);
+  if (parse_res == -1)
     return NSS_STATUS_TRYAGAIN;
 
   if (!parse_res)
@@ -238,7 +242,7 @@ _nss_nis_gethostton_r (const char *name, struct ether *eth,
 
 enum nss_status
 _nss_nis_getntohost_r (struct ether_addr *addr, struct ether *eth,
-                      char *buffer, size_t buflen)
+                      char *buffer, size_t buflen, int *errnop)
 {
   struct parser_data *data = (void *) buffer;
   enum nss_status retval;
@@ -269,14 +273,14 @@ _nss_nis_getntohost_r (struct ether_addr *addr, struct ether *eth,
   if (retval != NSS_STATUS_SUCCESS)
     {
       if (retval == NSS_STATUS_TRYAGAIN)
-        __set_errno (EAGAIN);
+        *errnop = errno;
       return retval;
     }
 
   if ((size_t) (len + 1) > buflen)
     {
       free (result);
-      __set_errno (ERANGE);
+      *errnop = ERANGE;
       return NSS_STATUS_TRYAGAIN;
     }
 
@@ -286,7 +290,8 @@ _nss_nis_getntohost_r (struct ether_addr *addr, struct ether *eth,
     ++p;
   free (result);
 
-  if ((parse_res = _nss_files_parse_etherent (p, eth, data, buflen)) == -1)
+  parse_res = _nss_files_parse_etherent (p, eth, data, buflen, errnop);
+  if (parse_res == -1)
     return NSS_STATUS_TRYAGAIN;
 
   if (!parse_res)
index 7897e2188176f0c2edfce61410c92ee1fe199b7f..98cc4fd8783b99c8a243ade24b28630db4b1f54e 100644 (file)
@@ -78,7 +78,8 @@ _nss_nis_endgrent (void)
 }
 
 static enum nss_status
-internal_nis_getgrent_r (struct group *grp, char *buffer, size_t buflen)
+internal_nis_getgrent_r (struct group *grp, char *buffer, size_t buflen,
+                        int *errnop)
 {
   struct parser_data *data = (void *) buffer;
   char *domain, *result, *outkey;
@@ -104,14 +105,14 @@ internal_nis_getgrent_r (struct group *grp, char *buffer, size_t buflen)
       if (retval != NSS_STATUS_SUCCESS)
         {
           if (retval == NSS_STATUS_TRYAGAIN)
-            __set_errno (EAGAIN);
+            *errnop = errno;
           return retval;
         }
 
       if ((size_t) (len + 1) > buflen)
         {
           free (result);
-          __set_errno (ERANGE);
+          *errnop = ERANGE;
           return NSS_STATUS_TRYAGAIN;
         }
 
@@ -121,9 +122,11 @@ internal_nis_getgrent_r (struct group *grp, char *buffer, size_t buflen)
         ++p;
       free (result);
 
-      if ((parse_res = _nss_files_parse_grent (p, grp, data, buflen)) == -1)
+      parse_res = _nss_files_parse_grent (p, grp, data, buflen, errnop);
+      if (parse_res == -1)
        {
          free (outkey);
+         *errnop = ERANGE;
          return NSS_STATUS_TRYAGAIN;
        }
 
@@ -138,13 +141,14 @@ internal_nis_getgrent_r (struct group *grp, char *buffer, size_t buflen)
 }
 
 enum nss_status
-_nss_nis_getgrent_r (struct group *result, char *buffer, size_t buflen)
+_nss_nis_getgrent_r (struct group *result, char *buffer, size_t buflen,
+                    int *errnop)
 {
   int status;
 
   __libc_lock_lock (lock);
 
-  status = internal_nis_getgrent_r (result, buffer, buflen);
+  status = internal_nis_getgrent_r (result, buffer, buflen, errnop);
 
   __libc_lock_unlock (lock);
 
@@ -153,7 +157,7 @@ _nss_nis_getgrent_r (struct group *result, char *buffer, size_t buflen)
 
 enum nss_status
 _nss_nis_getgrnam_r (const char *name, struct group *grp,
-                    char *buffer, size_t buflen)
+                    char *buffer, size_t buflen, int *errnop)
 {
   struct parser_data *data = (void *) buffer;
   enum nss_status retval;
@@ -175,14 +179,14 @@ _nss_nis_getgrnam_r (const char *name, struct group *grp,
   if (retval != NSS_STATUS_SUCCESS)
     {
       if (retval == NSS_STATUS_TRYAGAIN)
-        __set_errno (EAGAIN);
+        *errnop = errno;
       return retval;
     }
 
   if ((size_t) (len + 1) > buflen)
     {
       free (result);
-      __set_errno (ERANGE);
+      *errnop = ERANGE;
       return NSS_STATUS_TRYAGAIN;
     }
 
@@ -192,7 +196,8 @@ _nss_nis_getgrnam_r (const char *name, struct group *grp,
     ++p;
   free (result);
 
-  if ((parse_res = _nss_files_parse_grent (p, grp, data, buflen)) == -1)
+  parse_res = _nss_files_parse_grent (p, grp, data, buflen, errnop);
+  if (parse_res == -1)
     return NSS_STATUS_TRYAGAIN;
 
   if (parse_res)
@@ -203,7 +208,7 @@ _nss_nis_getgrnam_r (const char *name, struct group *grp,
 
 enum nss_status
 _nss_nis_getgrgid_r (gid_t gid, struct group *grp,
-                    char *buffer, size_t buflen)
+                    char *buffer, size_t buflen, int *errnop)
 {
   struct parser_data *data = (void *) buffer;
   enum nss_status retval;
@@ -222,14 +227,14 @@ _nss_nis_getgrgid_r (gid_t gid, struct group *grp,
   if (retval != NSS_STATUS_SUCCESS)
     {
       if (retval == NSS_STATUS_TRYAGAIN)
-        __set_errno (EAGAIN);
+        *errnop = errno;
       return retval;
     }
 
   if ((size_t) (len + 1) > buflen)
     {
       free (result);
-      __set_errno (ERANGE);
+      *errnop = ERANGE;
       return NSS_STATUS_TRYAGAIN;
     }
 
@@ -239,7 +244,8 @@ _nss_nis_getgrgid_r (gid_t gid, struct group *grp,
     ++p;
   free (result);
 
-  if ((parse_res = _nss_files_parse_grent (p, grp, data, buflen)) == -1)
+  parse_res = _nss_files_parse_grent (p, grp, data, buflen, errnop);
+  if (parse_res == -1)
     return NSS_STATUS_TRYAGAIN;
 
   if (parse_res)
index da7cef5ada8b32d857fad03a7f4366642937fa9e..f08a624c37c8dc3e34fe9f659568fdfc5f7ecb7a 100644 (file)
@@ -133,7 +133,7 @@ _nss_nis_endhostent (void)
 
 static enum nss_status
 internal_nis_gethostent_r (struct hostent *host, char *buffer,
-                          size_t buflen, int *h_errnop)
+                          size_t buflen, int *errnop, int *h_errnop)
 {
   char *domain;
   char *result;
@@ -148,7 +148,7 @@ internal_nis_gethostent_r (struct hostent *host, char *buffer,
 
   if (buflen < sizeof *data + 1)
     {
-      __set_errno (ERANGE);
+      *errnop = ERANGE;
       *h_errnop = NETDB_INTERNAL;
       return NSS_STATUS_TRYAGAIN;
     }
@@ -172,7 +172,7 @@ internal_nis_gethostent_r (struct hostent *host, char *buffer,
          switch (retval)
            {
            case NSS_STATUS_TRYAGAIN:
-             __set_errno (EAGAIN);
+             *errnop = errno;
              *h_errnop = TRY_AGAIN;
              break;
            case NSS_STATUS_NOTFOUND:
@@ -189,7 +189,7 @@ internal_nis_gethostent_r (struct hostent *host, char *buffer,
         {
           free (result);
          *h_errnop = NETDB_INTERNAL;
-          __set_errno (ERANGE);
+          *errnop = ERANGE;
           return NSS_STATUS_TRYAGAIN;
         }
 
@@ -199,10 +199,11 @@ internal_nis_gethostent_r (struct hostent *host, char *buffer,
        ++p;
       free (result);
 
-      if ((parse_res = parse_line (p, host, data, buflen)) == -1)
+      if ((parse_res = parse_line (p, host, data, buflen, errnop)) == -1)
        {
          free (outkey);
-         *h_errnop = NETDB_INTERNAL;;
+         *h_errnop = NETDB_INTERNAL;
+         *errnop = ERANGE;
          return NSS_STATUS_TRYAGAIN;
        }
       free (oldkey);
@@ -218,13 +219,13 @@ internal_nis_gethostent_r (struct hostent *host, char *buffer,
 
 int
 _nss_nis_gethostent_r (struct hostent *host, char *buffer, size_t buflen,
-                      int *h_errnop)
+                      int *errnop, int *h_errnop)
 {
   int status;
 
   __libc_lock_lock (lock);
 
-  status = internal_nis_gethostent_r (host, buffer, buflen, h_errnop);
+  status = internal_nis_gethostent_r (host, buffer, buflen, errnop, h_errnop);
 
   __libc_lock_unlock (lock);
 
@@ -233,7 +234,8 @@ _nss_nis_gethostent_r (struct hostent *host, char *buffer, size_t buflen,
 
 enum nss_status
 _nss_nis_gethostbyname2_r (const char *name, int af, struct hostent *host,
-                         char *buffer, size_t buflen, int *h_errnop)
+                          char *buffer, size_t buflen, int *errnop,
+                          int *h_errnop)
 {
   enum nss_status retval;
   char *domain, *result, *p;
@@ -253,7 +255,7 @@ _nss_nis_gethostbyname2_r (const char *name, int af, struct hostent *host,
   if (buflen < sizeof *data + 1)
     {
       *h_errnop = NETDB_INTERNAL;
-      __set_errno (ERANGE);
+      *errnop = ERANGE;
       return NSS_STATUS_TRYAGAIN;
     }
   retval = yperr2nss (yp_match (domain, "hosts.byname", name,
@@ -264,7 +266,7 @@ _nss_nis_gethostbyname2_r (const char *name, int af, struct hostent *host,
       if (retval == NSS_STATUS_TRYAGAIN)
        {
          *h_errnop = TRY_AGAIN;
-         __set_errno (EAGAIN);
+         *errnop = errno;
        }
       if (retval == NSS_STATUS_NOTFOUND)
        *h_errnop = HOST_NOT_FOUND;
@@ -275,7 +277,7 @@ _nss_nis_gethostbyname2_r (const char *name, int af, struct hostent *host,
     {
       free (result);
       *h_errnop = NETDB_INTERNAL;
-      __set_errno (ERANGE);
+      *errnop = ERANGE;
       return NSS_STATUS_TRYAGAIN;
     }
 
@@ -285,7 +287,7 @@ _nss_nis_gethostbyname2_r (const char *name, int af, struct hostent *host,
     ++p;
   free (result);
 
-  parse_res = parse_line (p, host, data, buflen);
+  parse_res = parse_line (p, host, data, buflen, errnop);
 
   if (parse_res < 1 || host->h_addrtype != af)
     {
@@ -306,27 +308,27 @@ _nss_nis_gethostbyname2_r (const char *name, int af, struct hostent *host,
 }
 
 enum nss_status
-_nss_nis_gethostbyname_r (const char *name, struct hostent *host,
-                         char *buffer, size_t buflen, int *h_errnop)
+_nss_nis_gethostbyname_r (const char *name, struct hostent *host, char *buffer,
+                         size_t buflen, int *errnop, int *h_errnop)
 {
   if (_res.options & RES_USE_INET6)
     {
       enum nss_status status;
 
       status = _nss_nis_gethostbyname2_r (name, AF_INET6, host, buffer, buflen,
-                                         h_errnop);
+                                         errnop, h_errnop);
       if (status == NSS_STATUS_SUCCESS)
        return status;
     }
 
   return _nss_nis_gethostbyname2_r (name, AF_INET, host, buffer, buflen,
-                                   h_errnop);
+                                   errnop, h_errnop);
 }
 
 enum nss_status
 _nss_nis_gethostbyaddr_r (char *addr, int addrlen, int type,
                          struct hostent *host, char *buffer, size_t buflen,
-                         int *h_errnop)
+                         int *errnop, int *h_errnop)
 {
   enum nss_status retval;
   char *domain, *result, *p;
@@ -340,7 +342,7 @@ _nss_nis_gethostbyaddr_r (char *addr, int addrlen, int type,
 
   if (buflen < sizeof *data + 1)
     {
-      __set_errno (ERANGE);
+      *errnop = ERANGE;
       *h_errnop = NETDB_INTERNAL;
       return NSS_STATUS_TRYAGAIN;
     }
@@ -355,7 +357,7 @@ _nss_nis_gethostbyaddr_r (char *addr, int addrlen, int type,
       if (retval == NSS_STATUS_TRYAGAIN)
        {
          *h_errnop = TRY_AGAIN;
-         __set_errno (EAGAIN);
+         *errnop = errno;
        }
       if (retval == NSS_STATUS_NOTFOUND)
        *h_errnop = HOST_NOT_FOUND;
@@ -365,7 +367,7 @@ _nss_nis_gethostbyaddr_r (char *addr, int addrlen, int type,
   if ((size_t) (len + 1) > linebuflen)
     {
       free (result);
-      __set_errno (ERANGE);
+      *errnop = ERANGE;
       *h_errnop = NETDB_INTERNAL;
       return NSS_STATUS_TRYAGAIN;
     }
@@ -376,7 +378,7 @@ _nss_nis_gethostbyaddr_r (char *addr, int addrlen, int type,
     ++p;
   free (result);
 
-  parse_res = parse_line (p, host, data, buflen);
+  parse_res = parse_line (p, host, data, buflen, errnop);
   if (parse_res < 1)
     {
       if (parse_res == -1)
index ce8762a1e5b0738722f7d3f5ad00f07d78d97d4f..d170b56f5056e077463609221223ac28cceebb18 100644 (file)
@@ -40,7 +40,7 @@ static char *cursor = NULL;;
 
 extern enum nss_status
 _nss_netgroup_parseline (char **cursor, struct __netgrent *result,
-                        char *buffer, size_t buflen);
+                        char *buffer, size_t buflen, int *errnop);
 
 enum nss_status
 _nss_nis_setnetgrent (char *group)
@@ -111,7 +111,8 @@ _nss_nis_endnetgrent (void)
 }
 
 enum nss_status
-_nss_nis_getnetgrent_r (struct __netgrent *result, char *buffer, size_t buflen)
+_nss_nis_getnetgrent_r (struct __netgrent *result, char *buffer, size_t buflen,
+                       int *errnop)
 {
   enum nss_status status;
 
@@ -120,7 +121,7 @@ _nss_nis_getnetgrent_r (struct __netgrent *result, char *buffer, size_t buflen)
 
   __libc_lock_lock (lock);
 
-  status = _nss_netgroup_parseline (&cursor, result, buffer, buflen);
+  status = _nss_netgroup_parseline (&cursor, result, buffer, buflen, errnop);
 
   __libc_lock_unlock (lock);
 
index c17ba81a6257bbfc97a1c9ba8c3b7a71414caa69..4fcf729b346ce2648438326a369128473bb44d6a 100644 (file)
@@ -79,7 +79,7 @@ _nss_nis_endnetent (void)
 
 static enum nss_status
 internal_nis_getnetent_r (struct netent *net, char *buffer, size_t buflen,
-                         int *herrnop)
+                         int *errnop, int *herrnop)
 {
   struct parser_data *data = (void *) buffer;
   char *domain, *result, *outkey;
@@ -107,7 +107,7 @@ internal_nis_getnetent_r (struct netent *net, char *buffer, size_t buflen,
           if (retval == NSS_STATUS_TRYAGAIN)
            {
              *herrnop = NETDB_INTERNAL;
-             __set_errno (EAGAIN);
+             *errnop = errno;
            }
           return retval;
         }
@@ -126,10 +126,12 @@ internal_nis_getnetent_r (struct netent *net, char *buffer, size_t buflen,
         ++p;
       free (result);
 
-      if ((parse_res = _nss_files_parse_netent (p, net, data, buflen)) == -1)
+      parse_res = _nss_files_parse_netent (p, net, data, buflen, errnop);
+      if (parse_res == -1)
        {
          free (outkey);
          *herrnop = NETDB_INTERNAL;
+         *errnop = ERANGE;
          return NSS_STATUS_TRYAGAIN;
        }
 
@@ -145,13 +147,13 @@ internal_nis_getnetent_r (struct netent *net, char *buffer, size_t buflen,
 
 enum nss_status
 _nss_nis_getnetent_r (struct netent *net, char *buffer, size_t buflen,
-                     int *herrnop)
+                     int *errnop, int *herrnop)
 {
   enum nss_status status;
 
   __libc_lock_lock (lock);
 
-  status = internal_nis_getnetent_r (net, buffer, buflen, herrnop);
+  status = internal_nis_getnetent_r (net, buffer, buflen, errnop, herrnop);
 
   __libc_lock_unlock (lock);
 
@@ -159,8 +161,8 @@ _nss_nis_getnetent_r (struct netent *net, char *buffer, size_t buflen,
 }
 
 enum nss_status
-_nss_nis_getnetbyname_r (const char *name, struct netent *net,
-                        char *buffer, size_t buflen, int *herrnop)
+_nss_nis_getnetbyname_r (const char *name, struct netent *net, char *buffer,
+                        size_t buflen, int *errnop, int *herrnop)
 {
   enum nss_status retval;
   struct parser_data *data = (void *) buffer;
@@ -184,7 +186,7 @@ _nss_nis_getnetbyname_r (const char *name, struct netent *net,
     {
       if (retval == NSS_STATUS_TRYAGAIN)
        {
-         __set_errno (EAGAIN);
+         *errnop = errno;
          *herrnop = NETDB_INTERNAL;
        }
       return retval;
@@ -193,7 +195,7 @@ _nss_nis_getnetbyname_r (const char *name, struct netent *net,
   if ((size_t) (len + 1) > buflen)
     {
       free (result);
-      __set_errno (ERANGE);
+      *errnop = ERANGE;
       *herrnop = NETDB_INTERNAL;
       return NSS_STATUS_TRYAGAIN;
     }
@@ -204,7 +206,7 @@ _nss_nis_getnetbyname_r (const char *name, struct netent *net,
     ++p;
   free (result);
 
-  parse_res = _nss_files_parse_netent (p, net, data, buflen);
+  parse_res = _nss_files_parse_netent (p, net, data, buflen, errnop);
 
   if (parse_res < 1)
     {
@@ -220,7 +222,8 @@ _nss_nis_getnetbyname_r (const char *name, struct netent *net,
 
 enum nss_status
 _nss_nis_getnetbyaddr_r (unsigned long addr, int type, struct netent *net,
-                        char *buffer, size_t buflen, int *herrnop)
+                        char *buffer, size_t buflen, int *errnop,
+                        int *herrnop)
 {
   struct parser_data *data = (void *) buffer;
   char *domain;
@@ -264,7 +267,7 @@ _nss_nis_getnetbyaddr_r (unsigned long addr, int type, struct netent *net,
            else
              {
                if (retval == NSS_STATUS_TRYAGAIN)
-                 __set_errno (EAGAIN);
+                 *errnop = errno;
                return retval;
              }
          }
@@ -272,7 +275,7 @@ _nss_nis_getnetbyaddr_r (unsigned long addr, int type, struct netent *net,
       if ((size_t) (len + 1) > buflen)
        {
          free (result);
-         __set_errno (ERANGE);
+         *errnop = ERANGE;
          *herrnop = NETDB_INTERNAL;
          return NSS_STATUS_TRYAGAIN;
        }
@@ -283,8 +286,7 @@ _nss_nis_getnetbyaddr_r (unsigned long addr, int type, struct netent *net,
          ++p;
        free (result);
 
-       parse_res = _nss_files_parse_netent (p, net, data, buflen);
-
+       parse_res = _nss_files_parse_netent (p, net, data, buflen, errnop);
 
        if (parse_res < 1)
          {
index eb09bb4ec78aee7fefb1ab7202fcb871cbf7553e..e0c976041d829614ee2e13f1e306148a7ce172be 100644 (file)
@@ -136,7 +136,7 @@ _nss_nis_endprotoent (void)
 
 static enum nss_status
 internal_nis_getprotoent_r (struct protoent *proto,
-                           char *buffer, size_t buflen)
+                           char *buffer, size_t buflen, int *errnop)
 {
   struct parser_data *data = (void *) buffer;
   int parse_res;
@@ -156,24 +156,25 @@ internal_nis_getprotoent_r (struct protoent *proto,
       while (isspace (*p))
         ++p;
 
-      if ((parse_res = _nss_files_parse_protoent (p, proto, data, 
-                                                 buflen)) == -1)
+      parse_res = _nss_files_parse_protoent (p, proto, data, buflen, errnop);
+      if (parse_res == -1)
         return NSS_STATUS_TRYAGAIN;
       next = next->next;
     }
   while (!parse_res);
-  
+
   return NSS_STATUS_SUCCESS;
 }
 
 enum nss_status
-_nss_nis_getprotoent_r (struct protoent *proto, char *buffer, size_t buflen)
+_nss_nis_getprotoent_r (struct protoent *proto, char *buffer, size_t buflen,
+                       int *errnop)
 {
   enum nss_status status;
 
   __libc_lock_lock (lock);
 
-  status = internal_nis_getprotoent_r (proto, buffer, buflen);
+  status = internal_nis_getprotoent_r (proto, buffer, buflen, errnop);
 
   __libc_lock_unlock (lock);
 
@@ -182,7 +183,7 @@ _nss_nis_getprotoent_r (struct protoent *proto, char *buffer, size_t buflen)
 
 enum nss_status
 _nss_nis_getprotobyname_r (const char *name, struct protoent *proto,
-                          char *buffer, size_t buflen)
+                          char *buffer, size_t buflen, int *errnop)
 {
   struct parser_data *data = (void *) buffer;
   enum nss_status retval;
@@ -204,14 +205,14 @@ _nss_nis_getprotobyname_r (const char *name, struct protoent *proto,
   if (retval != NSS_STATUS_SUCCESS)
     {
       if (retval == NSS_STATUS_TRYAGAIN)
-        __set_errno (EAGAIN);
+       *errnop = errno;
       return retval;
     }
 
   if ((size_t) (len + 1) > buflen)
     {
       free (result);
-      __set_errno (ERANGE);
+      *errnop = ERANGE;
       return NSS_STATUS_TRYAGAIN;
     }
 
@@ -221,7 +222,8 @@ _nss_nis_getprotobyname_r (const char *name, struct protoent *proto,
     ++p;
   free (result);
 
-  if ((parse_res = _nss_files_parse_protoent (p, proto, data, buflen)) == -1)
+  parse_res = _nss_files_parse_protoent (p, proto, data, buflen, errnop);
+  if (parse_res == -1)
     return NSS_STATUS_TRYAGAIN;
 
   if (parse_res)
@@ -232,7 +234,7 @@ _nss_nis_getprotobyname_r (const char *name, struct protoent *proto,
 
 enum nss_status
 _nss_nis_getprotobynumber_r (int number, struct protoent *proto,
-                            char *buffer, size_t buflen)
+                            char *buffer, size_t buflen, int *errnop)
 {
   struct parser_data *data = (void *) buffer;
   enum nss_status retval;
@@ -251,14 +253,14 @@ _nss_nis_getprotobynumber_r (int number, struct protoent *proto,
   if (retval != NSS_STATUS_SUCCESS)
     {
       if (retval == NSS_STATUS_TRYAGAIN)
-        __set_errno (EAGAIN);
+       *errnop = errno;
       return retval;
     }
 
   if ((size_t) (len + 1) > buflen)
     {
       free (result);
-      __set_errno (ERANGE);
+      *errnop = ERANGE;
       return NSS_STATUS_TRYAGAIN;
     }
 
@@ -268,7 +270,8 @@ _nss_nis_getprotobynumber_r (int number, struct protoent *proto,
     ++p;
   free (result);
 
-  if ((parse_res = _nss_files_parse_protoent (p, proto, data, buflen)) == -1)
+  parse_res = _nss_files_parse_protoent (p, proto, data, buflen, errnop);
+  if (parse_res == -1)
     return NSS_STATUS_TRYAGAIN;
 
   if (parse_res)
index 4c921f4853844626f2993a5c24586169dfbc8be7..1c485d9d230e979b0e18a25edcf5eeb933e1c396 100644 (file)
@@ -32,7 +32,7 @@ extern int xdecrypt (char *, char *);
 
 /* 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)
+_nss_nis_getpublickey (const char *netname, char *pkey, int *errnop)
 {
   enum nss_status retval;
   char *domain, *result;
@@ -57,7 +57,7 @@ _nss_nis_getpublickey (const char *netname, char *pkey)
   if (retval != NSS_STATUS_SUCCESS)
     {
       if (retval == NSS_STATUS_TRYAGAIN)
-       __set_errno (EAGAIN);
+       *errnop = errno;
       return retval;
     }
 
@@ -72,7 +72,8 @@ _nss_nis_getpublickey (const char *netname, char *pkey)
 }
 
 enum nss_status
-_nss_nis_getsecretkey (const char *netname, char *skey, char *passwd)
+_nss_nis_getsecretkey (const char *netname, char *skey, char *passwd,
+                      int *errnop)
 {
   enum nss_status retval;
   char buf[1024];
@@ -98,7 +99,7 @@ _nss_nis_getsecretkey (const char *netname, char *skey, char *passwd)
   if (retval != NSS_STATUS_SUCCESS)
     {
       if (retval == NSS_STATUS_TRYAGAIN)
-       __set_errno (EAGAIN);
+       *errnop = errno;
       return retval;
     }
 
@@ -178,7 +179,7 @@ parse_netid_str (const char *s, uid_t *uidp, gid_t *gidp, int *gidlenp,
 
 enum nss_status
 _nss_nis_netname2user (char netname[MAXNETNAMELEN + 1], uid_t *uidp,
-                      gid_t *gidp, int *gidlenp, gid_t *gidlist)
+                      gid_t *gidp, int *gidlenp, gid_t *gidlist, int *errnop)
 {
   char *domain;
   int yperr;
index f693db17eaf039915765a5e57ecf597d85617479..8924886e1ea098bd6d210a0e1b4e21c09a8f9b75 100644 (file)
@@ -78,7 +78,8 @@ _nss_nis_endpwent (void)
 }
 
 static enum nss_status
-internal_nis_getpwent_r (struct passwd *pwd, char *buffer, size_t buflen)
+internal_nis_getpwent_r (struct passwd *pwd, char *buffer, size_t buflen,
+                        int *errnop)
 {
   struct parser_data *data = (void *) buffer;
   char *domain, *result, *outkey;
@@ -104,14 +105,14 @@ internal_nis_getpwent_r (struct passwd *pwd, char *buffer, size_t buflen)
       if (retval != NSS_STATUS_SUCCESS)
         {
           if (retval == NSS_STATUS_TRYAGAIN)
-            __set_errno (EAGAIN);
+            *errnop = errno;
           return retval;
         }
 
       if ((size_t) (len + 1) > buflen)
         {
           free (result);
-          __set_errno (ERANGE);
+         *errnop = ERANGE;
           return NSS_STATUS_TRYAGAIN;
         }
 
@@ -121,9 +122,11 @@ internal_nis_getpwent_r (struct passwd *pwd, char *buffer, size_t buflen)
         ++p;
       free (result);
 
-      if ((parse_res = _nss_files_parse_pwent (p, pwd, data, buflen)) == -1)
+      parse_res = _nss_files_parse_pwent (p, pwd, data, buflen, errnop);
+      if (parse_res == -1)
        {
          free (outkey);
+         *errnop = ERANGE;
          return NSS_STATUS_TRYAGAIN;
        }
 
@@ -138,13 +141,14 @@ internal_nis_getpwent_r (struct passwd *pwd, char *buffer, size_t buflen)
 }
 
 enum nss_status
-_nss_nis_getpwent_r (struct passwd *result, char *buffer, size_t buflen)
+_nss_nis_getpwent_r (struct passwd *result, char *buffer, size_t buflen,
+                    int *errnop)
 {
   int status;
 
   __libc_lock_lock (lock);
 
-  status = internal_nis_getpwent_r (result, buffer, buflen);
+  status = internal_nis_getpwent_r (result, buffer, buflen, errnop);
 
   __libc_lock_unlock (lock);
 
@@ -153,7 +157,7 @@ _nss_nis_getpwent_r (struct passwd *result, char *buffer, size_t buflen)
 
 enum nss_status
 _nss_nis_getpwnam_r (const char *name, struct passwd *pwd,
-                    char *buffer, size_t buflen)
+                    char *buffer, size_t buflen, int *errnop)
 {
   struct parser_data *data = (void *) buffer;
   enum nss_status retval;
@@ -175,14 +179,14 @@ _nss_nis_getpwnam_r (const char *name, struct passwd *pwd,
   if (retval != NSS_STATUS_SUCCESS)
     {
       if (retval == NSS_STATUS_TRYAGAIN)
-        __set_errno (EAGAIN);
+       *errnop = errno;
       return retval;
     }
 
   if ((size_t) (len + 1) > buflen)
     {
       free (result);
-      __set_errno (ERANGE);
+      *errnop = ERANGE;
       return NSS_STATUS_TRYAGAIN;
     }
 
@@ -192,8 +196,7 @@ _nss_nis_getpwnam_r (const char *name, struct passwd *pwd,
     ++p;
   free (result);
 
-  parse_res = _nss_files_parse_pwent (p, pwd, data, buflen);
-
+  parse_res = _nss_files_parse_pwent (p, pwd, data, buflen, errnop);
   if (parse_res < 1)
     {
       if (parse_res == -1)
@@ -207,7 +210,7 @@ _nss_nis_getpwnam_r (const char *name, struct passwd *pwd,
 
 enum nss_status
 _nss_nis_getpwuid_r (uid_t uid, struct passwd *pwd,
-                    char *buffer, size_t buflen)
+                    char *buffer, size_t buflen, int *errnop)
 {
   struct parser_data *data = (void *) buffer;
   enum nss_status retval;
@@ -226,14 +229,14 @@ _nss_nis_getpwuid_r (uid_t uid, struct passwd *pwd,
   if (retval != NSS_STATUS_SUCCESS)
     {
       if (retval == NSS_STATUS_TRYAGAIN)
-        __set_errno (EAGAIN);
+       *errnop = errno;
       return retval;
     }
 
   if ((size_t) (len + 1) > buflen)
     {
       free (result);
-      __set_errno (ERANGE);
+      *errnop = ERANGE;
       return NSS_STATUS_TRYAGAIN;
     }
 
@@ -243,8 +246,7 @@ _nss_nis_getpwuid_r (uid_t uid, struct passwd *pwd,
     ++p;
   free (result);
 
-  parse_res = _nss_files_parse_pwent (p, pwd, data, buflen);
-
+  parse_res = _nss_files_parse_pwent (p, pwd, data, buflen, errnop);
   if (parse_res < 1)
     {
       if (parse_res == -1)
index cd1f0db9b55ba53268b7317e80876a61407aa13a..274ef04b7aa1d979eb87112d9808da7ba5b0bb04 100644 (file)
@@ -154,7 +154,7 @@ _nss_nis_endrpcent (void)
 
 static enum nss_status
 internal_nis_getrpcent_r (struct rpcent *rpc, char *buffer, size_t buflen,
-                         intern_t *data)
+                         int *errnop, intern_t *data)
 {
   struct parser_data *pdata = (void *) buffer;
   int parse_res;
@@ -172,7 +172,8 @@ internal_nis_getrpcent_r (struct rpcent *rpc, char *buffer, size_t buflen,
       while (isspace (*p))
         ++p;
 
-      if ((parse_res = _nss_files_parse_rpcent (p, rpc, pdata, buflen)) == -1)
+      parse_res = _nss_files_parse_rpcent (p, rpc, pdata, buflen, errnop);
+      if (parse_res == -1)
        return NSS_STATUS_TRYAGAIN;
       data->next = data->next->next;
     }
@@ -182,13 +183,14 @@ internal_nis_getrpcent_r (struct rpcent *rpc, char *buffer, size_t buflen,
 }
 
 enum nss_status
-_nss_nis_getrpcent_r (struct rpcent *rpc, char *buffer, size_t buflen)
+_nss_nis_getrpcent_r (struct rpcent *rpc, char *buffer, size_t buflen,
+                     int *errnop)
 {
   enum nss_status status;
 
   __libc_lock_lock (lock);
 
-  status = internal_nis_getrpcent_r (rpc, buffer, buflen, &intern);
+  status = internal_nis_getrpcent_r (rpc, buffer, buflen, errnop, &intern);
 
   __libc_lock_unlock (lock);
 
@@ -197,7 +199,7 @@ _nss_nis_getrpcent_r (struct rpcent *rpc, char *buffer, size_t buflen)
 
 enum nss_status
 _nss_nis_getrpcbyname_r (const char *name, struct rpcent *rpc,
-                        char *buffer, size_t buflen)
+                        char *buffer, size_t buflen, int *errnop)
 {
   intern_t data = {NULL, NULL};
   enum nss_status status;
@@ -215,8 +217,8 @@ _nss_nis_getrpcbyname_r (const char *name, struct rpcent *rpc,
 
   found = 0;
   while (!found &&
-         ((status = internal_nis_getrpcent_r (rpc, buffer, buflen, &data))
-          == NSS_STATUS_SUCCESS))
+         ((status = internal_nis_getrpcent_r (rpc, buffer, buflen, errnop,
+                                             &data)) == NSS_STATUS_SUCCESS))
     {
       if (strcmp (rpc->r_name, name) == 0)
        found = 1;
@@ -247,7 +249,7 @@ _nss_nis_getrpcbyname_r (const char *name, struct rpcent *rpc,
 
 enum nss_status
 _nss_nis_getrpcbynumber_r (int number, struct rpcent *rpc,
-                          char *buffer, size_t buflen)
+                          char *buffer, size_t buflen, int *errnop)
 {
   struct parser_data *data = (void *) buffer;
   enum nss_status retval;
@@ -266,14 +268,14 @@ _nss_nis_getrpcbynumber_r (int number, struct rpcent *rpc,
   if (retval != NSS_STATUS_SUCCESS)
     {
       if (retval == NSS_STATUS_TRYAGAIN)
-       __set_errno (EAGAIN);
+       *errnop = errno;
       return retval;
     }
 
   if ((size_t) (len + 1) > buflen)
     {
       free (result);
-      __set_errno (ERANGE);
+      *errnop = ERANGE;
       return NSS_STATUS_TRYAGAIN;
     }
 
@@ -283,7 +285,7 @@ _nss_nis_getrpcbynumber_r (int number, struct rpcent *rpc,
     ++p;
   free (result);
 
-  parse_res = _nss_files_parse_rpcent (p, rpc, data, buflen);
+  parse_res = _nss_files_parse_rpcent (p, rpc, data, buflen, errnop);
 
   if (parse_res < 1)
     {
index 5ec89c86778743be2feac8ecacdeb475f7620b34..c55b3e019113341c01e1c4aa0d0a0014e4405045 100644 (file)
@@ -31,7 +31,7 @@
 
 /* The parser is defined in a different module.  */
 extern int _nss_files_parse_servent (char *line, struct servent *result,
-                                    char *data, size_t datalen);
+                                    char *data, size_t datalen, int *errnop);
 
 
 
@@ -155,7 +155,7 @@ _nss_nis_endservent (void)
 
 static enum nss_status
 internal_nis_getservent_r (struct servent *serv, char *buffer,
-                          size_t buflen, intern_t *data)
+                          size_t buflen, int *errnop, intern_t *data)
 {
   int parse_res;
   char *p;
@@ -172,8 +172,8 @@ internal_nis_getservent_r (struct servent *serv, char *buffer,
            while (isspace (*p))
         ++p;
 
-      if ((parse_res = _nss_files_parse_servent (p, serv, buffer, 
-                                                buflen)) == -1)
+      parse_res = _nss_files_parse_servent (p, serv, buffer, buflen, errnop);
+      if (parse_res == -1)
         return NSS_STATUS_TRYAGAIN;
       data->next = data->next->next;
     }
@@ -183,13 +183,14 @@ internal_nis_getservent_r (struct servent *serv, char *buffer,
 }
 
 enum nss_status
-_nss_nis_getservent_r (struct servent *serv, char *buffer, size_t buflen)
+_nss_nis_getservent_r (struct servent *serv, char *buffer, size_t buflen,
+                      int *errnop)
 {
   enum nss_status status;
 
   __libc_lock_lock (lock);
 
-  status = internal_nis_getservent_r (serv, buffer, buflen, &intern);
+  status = internal_nis_getservent_r (serv, buffer, buflen, errnop, &intern);
 
   __libc_lock_unlock (lock);
 
@@ -198,7 +199,8 @@ _nss_nis_getservent_r (struct servent *serv, char *buffer, size_t buflen)
 
 enum nss_status
 _nss_nis_getservbyname_r (const char *name, char *protocol,
-                         struct servent *serv, char *buffer, size_t buflen)
+                         struct servent *serv, char *buffer, size_t buflen,
+                         int *errnop)
 {
   intern_t data = { NULL, NULL };
   enum nss_status status;
@@ -216,8 +218,8 @@ _nss_nis_getservbyname_r (const char *name, char *protocol,
 
   found = 0;
   while (!found &&
-         ((status = internal_nis_getservent_r (serv, buffer, buflen, &data))
-          == NSS_STATUS_SUCCESS))
+         ((status = internal_nis_getservent_r (serv, buffer, buflen, errnop,
+                                              &data)) == NSS_STATUS_SUCCESS))
     {
       if (protocol == NULL || strcmp (serv->s_proto, protocol) == 0)
        {
@@ -242,7 +244,7 @@ _nss_nis_getservbyname_r (const char *name, char *protocol,
 
 enum nss_status
 _nss_nis_getservbyport_r (int port, char *protocol, struct servent *serv,
-                         char *buffer, size_t buflen)
+                         char *buffer, size_t buflen, int *errnop)
 {
   intern_t data = { NULL, NULL };
   enum nss_status status;
@@ -260,17 +262,11 @@ _nss_nis_getservbyport_r (int port, char *protocol, struct servent *serv,
 
   found = 0;
   while (!found &&
-         ((status = internal_nis_getservent_r (serv, buffer, buflen, &data))
-          == NSS_STATUS_SUCCESS))
-    {
-      if (htons (serv->s_port) == port)
-        {
-          if  (strcmp (serv->s_proto, protocol) == 0)
-            {
-              found = 1;
-            }
-        }
-    }
+         ((status = internal_nis_getservent_r (serv, buffer, buflen, errnop,
+                                              &data)) == NSS_STATUS_SUCCESS))
+    if (htons (serv->s_port) == port
+       &&  strcmp (serv->s_proto, protocol) == 0)
+      found = 1;
 
   internal_nis_endservent (&data);
 
index 0263f4e313f1810ecb78bef10da91a5b1ee5cfd0..5be010d433b9043e16a5e96cccf819488d906823 100644 (file)
@@ -78,7 +78,8 @@ _nss_nis_endspent (void)
 }
 
 static enum nss_status
-internal_nis_getspent_r (struct spwd *sp, char *buffer, size_t buflen)
+internal_nis_getspent_r (struct spwd *sp, char *buffer, size_t buflen,
+                        int *errnop)
 {
   struct parser_data *data = (void *) buffer;
   char *domain, *result, *outkey;
@@ -104,14 +105,14 @@ internal_nis_getspent_r (struct spwd *sp, char *buffer, size_t buflen)
       if (retval != NSS_STATUS_SUCCESS)
         {
           if (retval == NSS_STATUS_TRYAGAIN)
-            __set_errno (EAGAIN);
+           *errnop = errno;
           return retval;
         }
 
       if ((size_t) (len + 1) > buflen)
         {
           free (result);
-          __set_errno (ERANGE);
+         *errnop = ERANGE;
           return NSS_STATUS_TRYAGAIN;
         }
 
@@ -121,12 +122,14 @@ internal_nis_getspent_r (struct spwd *sp, char *buffer, size_t buflen)
         ++p;
       free (result);
 
-      if ((parse_res = _nss_files_parse_spent (p, sp, data, buflen)) == -1)
+      parse_res = _nss_files_parse_spent (p, sp, data, buflen, errnop);
+      if (parse_res == -1)
        {
          free (outkey);
+         *errnop = ERANGE;
          return NSS_STATUS_TRYAGAIN;
        }
-      
+
       free (oldkey);
       oldkey = outkey;
       oldkeylen = keylen;
@@ -138,13 +141,14 @@ internal_nis_getspent_r (struct spwd *sp, char *buffer, size_t buflen)
 }
 
 enum nss_status
-_nss_nis_getspent_r (struct spwd *result, char *buffer, size_t buflen)
+_nss_nis_getspent_r (struct spwd *result, char *buffer, size_t buflen,
+                    int *errnop)
 {
   int status;
 
   __libc_lock_lock (lock);
 
-  status = internal_nis_getspent_r (result, buffer, buflen);
+  status = internal_nis_getspent_r (result, buffer, buflen, errnop);
 
   __libc_lock_unlock (lock);
 
@@ -153,7 +157,7 @@ _nss_nis_getspent_r (struct spwd *result, char *buffer, size_t buflen)
 
 enum nss_status
 _nss_nis_getspnam_r (const char *name, struct spwd *sp,
-                    char *buffer, size_t buflen)
+                    char *buffer, size_t buflen, int *errnop)
 {
   struct parser_data *data = (void *) buffer;
   enum nss_status retval;
@@ -175,14 +179,14 @@ _nss_nis_getspnam_r (const char *name, struct spwd *sp,
   if (retval != NSS_STATUS_SUCCESS)
     {
       if (retval == NSS_STATUS_TRYAGAIN)
-        __set_errno (EAGAIN);
+       *errnop = errno;
       return retval;
     }
 
   if ((size_t) (len + 1) > buflen)
     {
       free (result);
-      __set_errno (ERANGE);
+      *errnop = ERANGE;
       return NSS_STATUS_TRYAGAIN;
     }
 
@@ -192,7 +196,8 @@ _nss_nis_getspnam_r (const char *name, struct spwd *sp,
     ++p;
   free (result);
 
-  if ((parse_res = _nss_files_parse_spent (p, sp, data, buflen)) == -1)
+  parse_res = _nss_files_parse_spent (p, sp, data, buflen, errnop);
+  if (parse_res == -1)
     return NSS_STATUS_TRYAGAIN;
 
   if (parse_res)
index 76c6f258132031557fbe8d46e4f8fb6c2a8e7445..381ad18228c844d7dda1f5065ee1acf13053f76c 100644 (file)
@@ -41,7 +41,7 @@ static u_long tablename_len = 0;
         ((res)->objects.objects_val[(idx)].EN_data.en_cols.en_cols_val[(col)].ec_value.ec_value_len)
 
 static enum nss_status
-_nss_create_tablename (void)
+_nss_create_tablename (int *errnop)
 {
   if (tablename_val == NULL)
     {
@@ -52,7 +52,10 @@ _nss_create_tablename (void)
       p = __stpcpy (p, nis_local_directory ());
       tablename_val = __strdup (buf);
       if (tablename_val == NULL)
-        return NSS_STATUS_TRYAGAIN;
+       {
+         *errnop = errno;
+         return NSS_STATUS_TRYAGAIN;
+       }
       tablename_len = strlen (tablename_val);
     }
   return NSS_STATUS_SUCCESS;
@@ -61,38 +64,38 @@ _nss_create_tablename (void)
 static int
 _nss_nisplus_parse_aliasent (nis_result *result, unsigned long entry,
                             struct aliasent *alias, char *buffer,
-                            size_t buflen)
+                            size_t buflen, int *errnop)
 {
   if (result == NULL)
     return 0;
 
-  if ((result->status != NIS_SUCCESS && result->status != NIS_S_SUCCESS) ||
-      __type_of (&result->objects.objects_val[entry]) != NIS_ENTRY_OBJ ||
-      strcmp(result->objects.objects_val[entry].EN_data.en_type,
-            "mail_aliases") != 0 ||
-      result->objects.objects_val[entry].EN_data.en_cols.en_cols_len < 2)
+  if ((result->status != NIS_SUCCESS && result->status != NIS_S_SUCCESS)
+      || __type_of (&result->objects.objects_val[entry]) != NIS_ENTRY_OBJ
+      || strcmp (result->objects.objects_val[entry].EN_data.en_type,
+                "mail_aliases") != 0
+      || result->objects.objects_val[entry].EN_data.en_cols.en_cols_len < 2)
     return 0;
   else
     {
-      char *first_unused = buffer + NISENTRYLEN(0, 1, result) + 1;
+      char *first_unused = buffer + NISENTRYLEN (0, 1, result) + 1;
       size_t room_left =
        buflen - (buflen % __alignof__ (char *)) -
-       NISENTRYLEN(0, 1, result) - 2;
+       NISENTRYLEN (0, 1, result) - 2;
       char *line;
       char *cp;
 
-      if (NISENTRYLEN(entry, 1, result) >= buflen)
+      if (NISENTRYLEN (entry, 1, result) >= buflen)
        {
          /* The line is too long for our buffer.  */
        no_more_room:
-         __set_errno (ERANGE);
+         *errnop = ERANGE;
          return -1;
        }
       else
        {
-         strncpy (buffer, NISENTRYVAL(entry, 1, result),
-                  NISENTRYLEN(entry, 1, result));
-         buffer[NISENTRYLEN(entry, 1, result)] = '\0';
+         strncpy (buffer, NISENTRYVAL (entry, 1, result),
+                  NISENTRYLEN (entry, 1, result));
+         buffer[NISENTRYLEN (entry, 1, result)] = '\0';
        }
 
       if (NISENTRYLEN(entry, 0, result) >= room_left)
@@ -102,8 +105,8 @@ _nss_nisplus_parse_aliasent (nis_result *result, unsigned long entry,
       alias->alias_members_len = 0;
       *first_unused = '\0';
       ++first_unused;
-      strcpy (first_unused, NISENTRYVAL(entry, 0, result));
-      first_unused[NISENTRYLEN(entry, 0, result)] = '\0';
+      strcpy (first_unused, NISENTRYVAL (entry, 0, result));
+      first_unused[NISENTRYLEN (entry, 0, result)] = '\0';
       alias->alias_name = first_unused;
 
       /* Terminate the line for any case.  */
@@ -153,16 +156,17 @@ static enum nss_status
 internal_setaliasent (void)
 {
   enum nss_status status;
+  int err;
 
   if (result)
     nis_freeresult (result);
   result = NULL;
 
-  if (_nss_create_tablename () != NSS_STATUS_SUCCESS)
+  if (_nss_create_tablename (&err) != NSS_STATUS_SUCCESS)
     return NSS_STATUS_UNAVAIL;
 
   next_entry = 0;
-  result = nis_list(tablename_val, FOLLOW_PATH | FOLLOW_LINKS, NULL, NULL);
+  result = nis_list (tablename_val, FOLLOW_PATH | FOLLOW_LINKS, NULL, NULL);
   status = niserr2nss (result->status);
   if (status != NSS_STATUS_SUCCESS)
     {
@@ -203,7 +207,7 @@ _nss_nisplus_endaliasent (void)
 
 static enum nss_status
 internal_nisplus_getaliasent_r (struct aliasent *alias,
-                               char *buffer, size_t buflen)
+                               char *buffer, size_t buflen, int *errnop)
 {
   int parse_res;
 
@@ -222,8 +226,9 @@ internal_nisplus_getaliasent_r (struct aliasent *alias,
       if (next_entry >= result->objects.objects_len)
        return NSS_STATUS_NOTFOUND;
 
-      if ((parse_res = _nss_nisplus_parse_aliasent (result, next_entry, alias,
-                                                   buffer, buflen)) == -1)
+      parse_res = _nss_nisplus_parse_aliasent (result, next_entry, alias,
+                                              buffer, buflen, errnop);
+      if (parse_res == -1)
        return NSS_STATUS_TRYAGAIN;
 
       ++next_entry;
@@ -234,13 +239,13 @@ internal_nisplus_getaliasent_r (struct aliasent *alias,
 
 enum nss_status
 _nss_nisplus_getaliasent_r (struct aliasent *result, char *buffer,
-                           size_t buflen)
+                           size_t buflen, int *errnop)
 {
   int status;
 
   __libc_lock_lock (lock);
 
-  status = internal_nisplus_getaliasent_r (result, buffer, buflen);
+  status = internal_nisplus_getaliasent_r (result, buffer, buflen, errnop);
 
   __libc_lock_unlock (lock);
 
@@ -249,28 +254,32 @@ _nss_nisplus_getaliasent_r (struct aliasent *result, char *buffer,
 
 enum nss_status
 _nss_nisplus_getaliasbyname_r (const char *name, struct aliasent *alias,
-                           char *buffer, size_t buflen)
+                           char *buffer, size_t buflen, int *errnop)
 {
   int parse_res;
 
   if (tablename_val == NULL)
-    if (_nss_create_tablename() != NSS_STATUS_SUCCESS)
-      return NSS_STATUS_UNAVAIL;
+    {
+      enum nss_status status = _nss_create_tablename (errnop);
+      if (status != NSS_STATUS_SUCCESS)
+       return status;
+    }
 
-  if (name != NULL || strlen(name) <= 8)
+  if (name != NULL || strlen (name) <= 8)
     {
       nis_result *result;
       char buf[strlen (name) + 30 + tablename_len];
 
-      sprintf(buf, "[name=%s],%s", name, tablename_val);
+      sprintf (buf, "[name=%s],%s", name, tablename_val);
 
-      result = nis_list(buf, FOLLOW_PATH | FOLLOW_LINKS, NULL, NULL);
+      result = nis_list (buf, FOLLOW_PATH | FOLLOW_LINKS, NULL, NULL);
 
       if (niserr2nss (result->status) != NSS_STATUS_SUCCESS)
        return niserr2nss (result->status);
 
-      if ((parse_res = _nss_nisplus_parse_aliasent (result, 0, alias,
-                                                   buffer, buflen)) == -1)
+      parse_res = _nss_nisplus_parse_aliasent (result, 0, alias,
+                                              buffer, buflen, errnop);
+      if (parse_res == -1)
        return NSS_STATUS_TRYAGAIN;
 
       if (parse_res)
index 8ca6935cc7e1645ed84f2467a00a200ad8383ee8..76805f1403597f244a58d9e799e168f70d74b8ed 100644 (file)
@@ -53,7 +53,7 @@ struct etherent_data {};
 
 static int
 _nss_nisplus_parse_etherent (nis_result *result, struct etherent *ether,
-                          char *buffer, size_t buflen)
+                          char *buffer, size_t buflen, int *errnop)
 {
   char *p = buffer;
   size_t room_left = buflen;
@@ -61,18 +61,18 @@ _nss_nisplus_parse_etherent (nis_result *result, struct etherent *ether,
   if (result == NULL)
     return 0;
 
-  if ((result->status != NIS_SUCCESS && result->status != NIS_S_SUCCESS) ||
-      result->objects.objects_len != 1 ||
-      __type_of (NIS_RES_OBJECT (result)) != NIS_ENTRY_OBJ ||
-      strcmp(NIS_RES_OBJECT (result)->EN_data.en_type,
-             "ethers_tbl") != 0 ||
-      NIS_RES_OBJECT(result)->EN_data.en_cols.en_cols_len < 2)
+  if ((result->status != NIS_SUCCESS && result->status != NIS_S_SUCCESS)
+      || result->objects.objects_len != 1
+      || __type_of (NIS_RES_OBJECT (result)) != NIS_ENTRY_OBJ
+      || strcmp (NIS_RES_OBJECT (result)->EN_data.en_type,
+                "ethers_tbl") != 0
+      || NIS_RES_OBJECT (result)->EN_data.en_cols.en_cols_len < 2)
     return 0;
 
   /* Generate the ether entry format and use the normal parser */
   if (NISENTRYLEN (0, 0, result) +1 > room_left)
     {
-      __set_errno (ERANGE);
+      *errnop = ERANGE;
       return -1;
     }
   strncpy (p, NISENTRYVAL (0, 0, result), NISENTRYLEN (0, 0, result));
@@ -85,7 +85,7 @@ _nss_nisplus_parse_etherent (nis_result *result, struct etherent *ether,
 }
 
 static enum nss_status
-_nss_create_tablename (void)
+_nss_create_tablename (int *errnop)
 {
   if (tablename_val == NULL)
     {
@@ -96,7 +96,10 @@ _nss_create_tablename (void)
       p = __stpcpy (p, nis_local_directory ());
       tablename_val = __strdup (buf);
       if (tablename_val == NULL)
-        return NSS_STATUS_TRYAGAIN;
+       {
+         *errnop = errno;
+         return NSS_STATUS_TRYAGAIN;
+       }
       tablename_len = strlen (tablename_val);
     }
   return NSS_STATUS_SUCCESS;
@@ -107,6 +110,7 @@ enum nss_status
 _nss_nisplus_setetherent (void)
 {
   enum nss_status status;
+  int err;
 
   status = NSS_STATUS_SUCCESS;
 
@@ -116,7 +120,7 @@ _nss_nisplus_setetherent (void)
     nis_freeresult (result);
   result = NULL;
 
-  if (_nss_create_tablename () != NSS_STATUS_SUCCESS)
+  if (_nss_create_tablename (&err) != NSS_STATUS_SUCCESS)
     status = NSS_STATUS_UNAVAIL;
 
   __libc_lock_unlock (lock);
@@ -140,13 +144,17 @@ _nss_nisplus_endetherent (void)
 
 static enum nss_status
 internal_nisplus_getetherent_r (struct etherent *ether, char *buffer,
-                               size_t buflen)
+                               size_t buflen, int *errnop)
 {
   int parse_res;
 
   if (tablename_val == NULL)
-    if (_nss_create_tablename () != NSS_STATUS_SUCCESS)
-      return NSS_STATUS_UNAVAIL;
+    {
+      enum nss_status status = _nss_create_tablename (errnop);
+
+      if (status != NSS_STATUS_SUCCESS)
+       return status;
+    }
 
   /* Get the next entry until we found a correct one. */
   do
@@ -156,7 +164,7 @@ internal_nisplus_getetherent_r (struct etherent *ether, char *buffer,
       if (result == NULL)
        {
          saved_result = NULL;
-         result = nis_first_entry(tablename_val);
+         result = nis_first_entry (tablename_val);
          if (niserr2nss (result->status) != NSS_STATUS_SUCCESS)
            return niserr2nss (result->status);
        }
@@ -174,10 +182,12 @@ internal_nisplus_getetherent_r (struct etherent *ether, char *buffer,
            }
        }
 
-      if ((parse_res = _nss_nisplus_parse_etherent (result, ether, buffer,
-                                                   buflen)) == -1)
+      parse_res = _nss_nisplus_parse_etherent (result, ether, buffer,
+                                              buflen, errnop);
+      if (parse_res == -1)
        {
          nis_freeresult (result);
+         *errnop = ERANGE;
          result = saved_result;
          return NSS_STATUS_TRYAGAIN;
        }
@@ -194,13 +204,13 @@ internal_nisplus_getetherent_r (struct etherent *ether, char *buffer,
 
 enum nss_status
 _nss_nisplus_getetherent_r (struct etherent *result, char *buffer,
-                           size_t buflen)
+                           size_t buflen, int *errnop)
 {
   int status;
 
   __libc_lock_lock (lock);
 
-  status = internal_nisplus_getetherent_r (result, buffer, buflen);
+  status = internal_nisplus_getetherent_r (result, buffer, buflen, errnop);
 
   __libc_lock_unlock (lock);
 
@@ -209,22 +219,26 @@ _nss_nisplus_getetherent_r (struct etherent *result, char *buffer,
 
 enum nss_status
 _nss_nisplus_gethostton_r (const char *name, struct etherent *eth,
-                          char *buffer, size_t buflen)
+                          char *buffer, size_t buflen, int *errnop)
 {
   int parse_res;
 
   if (tablename_val == NULL)
-    if (_nss_create_tablename () != NSS_STATUS_SUCCESS)
-      return NSS_STATUS_UNAVAIL;
+    {
+      enum nss_status status = _nss_create_tablename (errnop);
+
+      if (status != NSS_STATUS_SUCCESS)
+       return status;
+    }
 
   if (name != NULL)
     {
       nis_result *result;
       char buf[strlen (name) + 40 + tablename_len];
 
-      sprintf(buf, "[name=%s],%s", name, tablename_val);
+      sprintf (buf, "[name=%s],%s", name, tablename_val);
 
-      result = nis_list(buf, FOLLOW_PATH | FOLLOW_LINKS, NULL, NULL);
+      result = nis_list (buf, FOLLOW_PATH | FOLLOW_LINKS, NULL, NULL);
 
       if (niserr2nss (result->status) != NSS_STATUS_SUCCESS)
        {
@@ -233,10 +247,12 @@ _nss_nisplus_gethostton_r (const char *name, struct etherent *eth,
          return status;
        }
 
-      if ((parse_res = _nss_nisplus_parse_etherent (result, eth, buffer,
-                                                   buflen)) == -1)
+      parse_res = _nss_nisplus_parse_etherent (result, eth, buffer,
+                                              buflen, errnop);
+      if (parse_res == -1)
        {
          nis_freeresult (result);
+         *errnop = ERANGE;
          return NSS_STATUS_TRYAGAIN;
        }
 
@@ -249,15 +265,19 @@ _nss_nisplus_gethostton_r (const char *name, struct etherent *eth,
 enum nss_status
 _nss_nisplus_getntohost_r (const struct ether_addr *addr,
                           struct etherent *eth,
-                          char *buffer, size_t buflen)
+                          char *buffer, size_t buflen, int *errnop)
 {
   if (tablename_val == NULL)
-    if (_nss_create_tablename () != NSS_STATUS_SUCCESS)
-      return NSS_STATUS_UNAVAIL;
+    {
+      enum nss_status status = _nss_create_tablename (errnop);
+
+      if (status != NSS_STATUS_SUCCESS)
+       return status;
+    }
 
   if (addr == NULL)
     {
-      __set_errno (EINVAL);
+      *errnop = EINVAL;
       return NSS_STATUS_UNAVAIL;
     }
   else
@@ -267,12 +287,12 @@ _nss_nisplus_getntohost_r (const struct ether_addr *addr,
       char buf[255 + tablename_len];
 
       memset (&buf, '\0', sizeof (buf));
-      sprintf(buf, "[addr=%x:%x:%x:%x:%x:%x],ethers.org_dir",
-             addr->ether_addr_octet[0], addr->ether_addr_octet[1],
-             addr->ether_addr_octet[2], addr->ether_addr_octet[3],
-             addr->ether_addr_octet[4], addr->ether_addr_octet[5]);
+      sprintf (buf, "[addr=%x:%x:%x:%x:%x:%x],ethers.org_dir",
+              addr->ether_addr_octet[0], addr->ether_addr_octet[1],
+              addr->ether_addr_octet[2], addr->ether_addr_octet[3],
+              addr->ether_addr_octet[4], addr->ether_addr_octet[5]);
 
-      result = nis_list(buf, FOLLOW_PATH | FOLLOW_LINKS, NULL, NULL);
+      result = nis_list (buf, FOLLOW_PATH | FOLLOW_LINKS, NULL, NULL);
 
       if (niserr2nss (result->status) != NSS_STATUS_SUCCESS)
        {
@@ -281,10 +301,12 @@ _nss_nisplus_getntohost_r (const struct ether_addr *addr,
          return status;
        }
 
-      if ((parse_res = _nss_nisplus_parse_etherent (result, eth, buffer,
-                                                   buflen)) == -1)
+      parse_res = _nss_nisplus_parse_etherent (result, eth, buffer,
+                                              buflen, errnop);
+      if (parse_res == -1)
        {
          nis_freeresult (result);
+         *errnop = ERANGE;
          return NSS_STATUS_TRYAGAIN;
        }
 
index fb200321d2867f9b37c2885bfeed22b6c78875f0..4ac048ef05def5178e3c670725423c701884398c 100644 (file)
@@ -36,7 +36,7 @@ static nis_name tablename_val = NULL;
 static u_long tablename_len = 0;
 
 static enum nss_status
-_nss_create_tablename (void)
+_nss_create_tablename (int *errnop)
 {
   if (tablename_val == NULL)
     {
@@ -47,7 +47,10 @@ _nss_create_tablename (void)
       p = __stpcpy (p, nis_local_directory ());
       tablename_val = __strdup (buf);
       if (tablename_val == NULL)
-        return NSS_STATUS_TRYAGAIN;
+       {
+         *errnop = errno;
+         return NSS_STATUS_TRYAGAIN;
+       }
       tablename_len = strlen (tablename_val);
     }
   return NSS_STATUS_SUCCESS;
@@ -57,6 +60,7 @@ static enum nss_status
 internal_setgrent (void)
 {
   enum nss_status status;
+  int err;
 
   if (result)
     nis_freeresult (result);
@@ -64,7 +68,7 @@ internal_setgrent (void)
   next_entry = 0;
 
   if (tablename_val == NULL)
-    if (_nss_create_tablename () != NSS_STATUS_SUCCESS)
+    if (_nss_create_tablename (&err) != NSS_STATUS_SUCCESS)
       return NSS_STATUS_UNAVAIL;
 
   result = nis_list (tablename_val, FOLLOW_LINKS | FOLLOW_PATH, NULL, NULL);
@@ -106,7 +110,8 @@ _nss_nisplus_endgrent (void)
 }
 
 static enum nss_status
-internal_nisplus_getgrent_r (struct group *gr, char *buffer, size_t buflen)
+internal_nisplus_getgrent_r (struct group *gr, char *buffer, size_t buflen,
+                            int *errnop)
 {
   int parse_res;
 
@@ -125,8 +130,9 @@ internal_nisplus_getgrent_r (struct group *gr, char *buffer, size_t buflen)
       if (next_entry >= result->objects.objects_len)
        return NSS_STATUS_NOTFOUND;
 
-      if ((parse_res = _nss_nisplus_parse_grent (result, next_entry, gr,
-                                                buffer, buflen)) == -1)
+      parse_res = _nss_nisplus_parse_grent (result, next_entry, gr,
+                                           buffer, buflen, errnop);
+      if (parse_res == -1)
        return NSS_STATUS_TRYAGAIN;
 
       ++next_entry;
@@ -137,13 +143,14 @@ internal_nisplus_getgrent_r (struct group *gr, char *buffer, size_t buflen)
 }
 
 enum nss_status
-_nss_nisplus_getgrent_r (struct group *result, char *buffer, size_t buflen)
+_nss_nisplus_getgrent_r (struct group *result, char *buffer, size_t buflen,
+                        int *errnop)
 {
   int status;
 
   __libc_lock_lock (lock);
 
-  status = internal_nisplus_getgrent_r (result, buffer, buflen);
+  status = internal_nisplus_getgrent_r (result, buffer, buflen, errnop);
 
   __libc_lock_unlock (lock);
 
@@ -152,13 +159,17 @@ _nss_nisplus_getgrent_r (struct group *result, char *buffer, size_t buflen)
 
 enum nss_status
 _nss_nisplus_getgrnam_r (const char *name, struct group *gr,
-                        char *buffer, size_t buflen)
+                        char *buffer, size_t buflen, int *errnop)
 {
   int parse_res;
 
   if (tablename_val == NULL)
-    if (_nss_create_tablename() != NSS_STATUS_SUCCESS)
-      return NSS_STATUS_UNAVAIL;
+    {
+      enum nss_status status = _nss_create_tablename (errnop);
+
+      if (status != NSS_STATUS_SUCCESS)
+       return status;
+    }
 
   if (name == NULL || strlen (name) > 8)
     return NSS_STATUS_NOTFOUND;
@@ -179,11 +190,15 @@ _nss_nisplus_getgrnam_r (const char *name, struct group *gr,
          return status;
        }
 
-      parse_res = _nss_nisplus_parse_grent (result, 0, gr, buffer, buflen);
+      parse_res = _nss_nisplus_parse_grent (result, 0, gr, buffer, buflen,
+                                           errnop);
       nis_freeresult (result);
 
       if (parse_res == -1)
-       return NSS_STATUS_TRYAGAIN;
+       {
+         *errnop = ERANGE;
+         return NSS_STATUS_TRYAGAIN;
+       }
       if (parse_res)
        return NSS_STATUS_SUCCESS;
 
@@ -193,11 +208,15 @@ _nss_nisplus_getgrnam_r (const char *name, struct group *gr,
 
 enum nss_status
 _nss_nisplus_getgrgid_r (const gid_t gid, struct group *gr,
-                        char *buffer, size_t buflen)
+                        char *buffer, size_t buflen, int *errnop)
 {
   if (tablename_val == NULL)
-    if (_nss_create_tablename() != NSS_STATUS_SUCCESS)
-      return NSS_STATUS_UNAVAIL;
+    {
+      enum nss_status status = _nss_create_tablename (errnop);
+
+      if (status != NSS_STATUS_SUCCESS)
+       return status;
+    }
 
   {
     int parse_res;
@@ -216,12 +235,16 @@ _nss_nisplus_getgrgid_r (const gid_t gid, struct group *gr,
        return status;
       }
 
-    parse_res = _nss_nisplus_parse_grent (result, 0, gr, buffer, buflen);
+    parse_res = _nss_nisplus_parse_grent (result, 0, gr, buffer, buflen,
+                                         errnop);
 
     nis_freeresult (result);
 
     if (parse_res == -1)
-      return NSS_STATUS_TRYAGAIN;
+      {
+       *errnop = ERANGE;
+       return NSS_STATUS_TRYAGAIN;
+      }
 
     if (parse_res)
       return NSS_STATUS_SUCCESS;
index d1aa5ef78792771f2f2607a6cc73dd71b4e49823..8514a63e8a1c19edc79649006ab156c3acaa793c 100644 (file)
@@ -42,11 +42,11 @@ static u_long tablename_len = 0;
         ((res)->objects.objects_val[(idx)].EN_data.en_cols.en_cols_val[(col)].ec_value.ec_value_len)
 
 /* Get implementation for some internal functions. */
-#include "../../resolv/mapv4v6addr.h"
+#include <resolv/mapv4v6addr.h>
 
 static int
 _nss_nisplus_parse_hostent (nis_result *result, int af, struct hostent *host,
-                           char *buffer, size_t buflen)
+                           char *buffer, size_t buflen, int *errnop)
 {
   unsigned int i;
   char *first_unused = buffer;
@@ -66,7 +66,7 @@ _nss_nisplus_parse_hostent (nis_result *result, int af, struct hostent *host,
   if (room_left < NISENTRYLEN (0, 2, result) + 1)
     {
     no_more_room:
-      __set_errno (ERANGE);
+      *errnop = ERANGE;
       return -1;
     }
 
@@ -169,7 +169,7 @@ _nss_nisplus_parse_hostent (nis_result *result, int af, struct hostent *host,
 }
 
 static enum nss_status
-_nss_create_tablename (void)
+_nss_create_tablename (int *errnop)
 {
   if (tablename_val == NULL)
     {
@@ -180,7 +180,10 @@ _nss_create_tablename (void)
       p = __stpcpy (p, nis_local_directory ());
       tablename_val = __strdup (buf);
       if (tablename_val == NULL)
-        return NSS_STATUS_TRYAGAIN;
+       {
+         *errnop = errno;
+         return NSS_STATUS_TRYAGAIN;
+       }
       tablename_len = strlen (tablename_val);
     }
   return NSS_STATUS_SUCCESS;
@@ -190,6 +193,7 @@ enum nss_status
 _nss_nisplus_sethostent (void)
 {
   enum nss_status status = NSS_STATUS_SUCCESS;
+  int err;
 
   __libc_lock_lock (lock);
 
@@ -198,8 +202,7 @@ _nss_nisplus_sethostent (void)
   result = NULL;
 
   if (tablename_val == NULL)
-    if (_nss_create_tablename() != NSS_STATUS_SUCCESS)
-      status = NSS_STATUS_UNAVAIL;
+    status = _nss_create_tablename (&err);
 
   __libc_lock_unlock (lock);
 
@@ -222,7 +225,7 @@ _nss_nisplus_endhostent (void)
 
 static enum nss_status
 internal_nisplus_gethostent_r (struct hostent *host, char *buffer,
-                              size_t buflen, int *herrnop)
+                              size_t buflen, int *errnop, int *herrnop)
 {
   int parse_res;
 
@@ -235,17 +238,21 @@ internal_nisplus_gethostent_r (struct hostent *host, char *buffer,
        {
          saved_res = NULL;
          if (tablename_val == NULL)
-           if (_nss_create_tablename() != NSS_STATUS_SUCCESS)
-             return NSS_STATUS_UNAVAIL;
+           {
+             enum nss_status status = _nss_create_tablename (errnop);
 
-         result = nis_first_entry(tablename_val);
+             if (status != NSS_STATUS_SUCCESS)
+               return status;
+           }
+
+         result = nis_first_entry (tablename_val);
          if (niserr2nss (result->status) != NSS_STATUS_SUCCESS)
             {
               enum nss_status retval = niserr2nss (result->status);
               if (retval == NSS_STATUS_TRYAGAIN)
                 {
                   *herrnop = NETDB_INTERNAL;
-                  __set_errno (EAGAIN);
+                  *errnop = errno;
                 }
               return retval;
             }
@@ -267,22 +274,23 @@ internal_nisplus_gethostent_r (struct hostent *host, char *buffer,
               if (retval == NSS_STATUS_TRYAGAIN)
                 {
                   *herrnop = NETDB_INTERNAL;
-                  __set_errno (EAGAIN);
+                 *errnop = errno;
                 }
               return retval;
             }
        }
 
-      parse_res = _nss_nisplus_parse_hostent (result, AF_INET6,
-                                             host, buffer, buflen);
-      if (parse_res < 1 && errno != ERANGE)
+      parse_res = _nss_nisplus_parse_hostent (result, AF_INET6, host, buffer,
+                                             buflen, errnop);
+      if (parse_res < 1 && *errnop != ERANGE)
        parse_res = _nss_nisplus_parse_hostent (result, AF_INET, host,
-                                               buffer, buflen);
-      if (parse_res < 1 && errno == ERANGE)
+                                               buffer, buflen, errnop);
+      if (parse_res < 1 && *errnop == ERANGE)
         {
          nis_freeresult (result);
          result = saved_res;
           *herrnop = NETDB_INTERNAL;
+         *errnop = ERANGE;
           return NSS_STATUS_TRYAGAIN;
         }
       if (saved_res != NULL)
@@ -295,13 +303,14 @@ internal_nisplus_gethostent_r (struct hostent *host, char *buffer,
 
 enum nss_status
 _nss_nisplus_gethostent_r (struct hostent *result, char *buffer,
-                          size_t buflen, int *herrnop)
+                          size_t buflen, int *errnop, int *herrnop)
 {
   int status;
 
   __libc_lock_lock (lock);
 
-  status = internal_nisplus_gethostent_r (result, buffer, buflen, herrnop);
+  status = internal_nisplus_gethostent_r (result, buffer, buflen, errnop,
+                                         herrnop);
 
   __libc_lock_unlock (lock);
 
@@ -310,20 +319,25 @@ _nss_nisplus_gethostent_r (struct hostent *result, char *buffer,
 
 enum nss_status
 _nss_nisplus_gethostbyname2_r (const char *name, int af, struct hostent *host,
-                             char *buffer, size_t buflen, int *herrnop)
+                              char *buffer, size_t buflen, int *errnop,
+                              int *herrnop)
 {
   int parse_res, retval;
 
   if (tablename_val == NULL)
-    if (_nss_create_tablename() != NSS_STATUS_SUCCESS)
-      {
-       *herrnop = NETDB_INTERNAL;
-       return NSS_STATUS_UNAVAIL;
-      }
+    {
+      enum nss_status status = _nss_create_tablename (errnop);
+
+      if (status != NSS_STATUS_SUCCESS)
+       {
+         *herrnop = NETDB_INTERNAL;
+         return NSS_STATUS_UNAVAIL;
+       }
+    }
 
   if (name == NULL)
     {
-      __set_errno (EINVAL);
+      *errnop = EINVAL;
       *herrnop = NETDB_INTERNAL;
       return NSS_STATUS_NOTFOUND;
     }
@@ -334,38 +348,38 @@ _nss_nisplus_gethostbyname2_r (const char *name, int af, struct hostent *host,
 
       /* Search at first in the alias list, and use the correct name
         for the next search */
-      sprintf(buf, "[name=%s],%s", name, tablename_val);
-      result = nis_list(buf, FOLLOW_PATH | FOLLOW_LINKS, NULL, NULL);
+      sprintf (buf, "[name=%s],%s", name, tablename_val);
+      result = nis_list (buf, FOLLOW_PATH | FOLLOW_LINKS, NULL, NULL);
 
       /* If we do not find it, try it as original name. But if the
         database is correct, we should find it in the first case, too */
-      if ((result->status != NIS_SUCCESS && result->status != NIS_S_SUCCESS) ||
-         __type_of (result->objects.objects_val) != NIS_ENTRY_OBJ ||
-         strcmp(result->objects.objects_val->EN_data.en_type,
-                "hosts_tbl") != 0 ||
-         result->objects.objects_val->EN_data.en_cols.en_cols_len < 3)
-       sprintf(buf, "[cname=%s],%s", name, tablename_val);
+      if ((result->status != NIS_SUCCESS && result->status != NIS_S_SUCCESS)
+         || __type_of (result->objects.objects_val) != NIS_ENTRY_OBJ
+         || strcmp (result->objects.objects_val->EN_data.en_type,
+                    "hosts_tbl") != 0
+         || result->objects.objects_val->EN_data.en_cols.en_cols_len < 3)
+       sprintf (buf, "[cname=%s],%s", name, tablename_val);
       else
-       sprintf(buf, "[cname=%s],%s", NISENTRYVAL(0, 0, result),
-               tablename_val);
+       sprintf (buf, "[cname=%s],%s", NISENTRYVAL(0, 0, result),
+                tablename_val);
 
       nis_freeresult (result);
-      result = nis_list(buf, FOLLOW_PATH | FOLLOW_LINKS, NULL, NULL);
+      result = nis_list (buf, FOLLOW_PATH | FOLLOW_LINKS, NULL, NULL);
 
       retval = niserr2nss (result->status);
       if (retval != NSS_STATUS_SUCCESS)
         {
           if (retval == NSS_STATUS_TRYAGAIN)
             {
-              __set_errno (EAGAIN);
+             *errnop = errno;
               *herrnop = NETDB_INTERNAL;
             }
          nis_freeresult (result);
           return retval;
         }
 
-      parse_res =
-       _nss_nisplus_parse_hostent (result, af, host, buffer, buflen);
+      parse_res = _nss_nisplus_parse_hostent (result, af, host, buffer,
+                                             buflen, errnop);
 
       nis_freeresult (result);
 
@@ -374,7 +388,10 @@ _nss_nisplus_gethostbyname2_r (const char *name, int af, struct hostent *host,
 
       *herrnop = NETDB_INTERNAL;
       if (parse_res == -1)
-       return NSS_STATUS_TRYAGAIN;
+       {
+         *errnop = ERANGE;
+         return NSS_STATUS_TRYAGAIN;
+       }
       else
        return NSS_STATUS_NOTFOUND;
     }
@@ -382,30 +399,35 @@ _nss_nisplus_gethostbyname2_r (const char *name, int af, struct hostent *host,
 
 enum nss_status
 _nss_nisplus_gethostbyname_r (const char *name, struct hostent *host,
-                             char *buffer, size_t buflen, int *h_errnop)
+                             char *buffer, size_t buflen, int *errnop,
+                             int *h_errnop)
 {
   if (_res.options & RES_USE_INET6)
     {
       enum nss_status status;
 
       status = _nss_nisplus_gethostbyname2_r (name, AF_INET6, host, buffer,
-                                             buflen, h_errnop);
+                                             buflen, errnop, h_errnop);
       if (status == NSS_STATUS_SUCCESS)
         return status;
     }
 
   return _nss_nisplus_gethostbyname2_r (name, AF_INET, host, buffer,
-                                       buflen, h_errnop);
+                                       buflen, errnop, h_errnop);
 }
 
 enum nss_status
 _nss_nisplus_gethostbyaddr_r (const char *addr, int addrlen, int type,
                              struct hostent *host, char *buffer,
-                             size_t buflen, int *herrnop)
+                             size_t buflen, int *errnop, int *herrnop)
 {
   if (tablename_val == NULL)
-    if (_nss_create_tablename() != NSS_STATUS_SUCCESS)
-      return NSS_STATUS_UNAVAIL;
+    {
+      enum nss_status status = _nss_create_tablename (errnop);
+
+      if (status != NSS_STATUS_SUCCESS)
+       return status;
+    }
 
   if (addr == NULL)
     return NSS_STATUS_NOTFOUND;
@@ -416,15 +438,15 @@ _nss_nisplus_gethostbyaddr_r (const char *addr, int addrlen, int type,
       int retval, parse_res;
 
       sprintf (buf, "[addr=%s],%s",
-              inet_ntoa (*(struct in_addr *)addr), tablename_val);
-      result = nis_list(buf, FOLLOW_PATH | FOLLOW_LINKS, NULL, NULL);
+              inet_ntoa (*(struct in_addr *) addr), tablename_val);
+      result = nis_list (buf, FOLLOW_PATH | FOLLOW_LINKS, NULL, NULL);
 
       retval = niserr2nss (result->status);
       if (retval != NSS_STATUS_SUCCESS)
         {
           if (retval == NSS_STATUS_TRYAGAIN)
             {
-              __set_errno (EAGAIN);
+             *errnop = errno;
               *herrnop = NETDB_INTERNAL;
             }
          nis_freeresult (result);
@@ -432,7 +454,7 @@ _nss_nisplus_gethostbyaddr_r (const char *addr, int addrlen, int type,
         }
 
       parse_res = _nss_nisplus_parse_hostent (result, type, host,
-                                             buffer, buflen);
+                                             buffer, buflen, errnop);
       nis_freeresult (result);
 
       if (parse_res > 0)
@@ -440,7 +462,10 @@ _nss_nisplus_gethostbyaddr_r (const char *addr, int addrlen, int type,
 
       *herrnop = NETDB_INTERNAL;
       if (parse_res == -1)
-       return NSS_STATUS_TRYAGAIN;
+       {
+         *errnop = ERANGE;
+         return NSS_STATUS_TRYAGAIN;
+       }
       else
        return NSS_STATUS_NOTFOUND;
     }
index 2a2f4b5ec9c0955b7b58d118969da440a65f2cae..5d5b7272921e36c32cdbbb49c841275234e8f7a5 100644 (file)
@@ -42,7 +42,7 @@ static unsigned long position = 0;
 
 static enum nss_status
 _nss_nisplus_parse_netgroup (struct __netgrent *result, char *buffer,
-                            size_t buflen)
+                            size_t buflen, int *errnop)
 {
   enum nss_status status;
 
@@ -60,7 +60,7 @@ _nss_nisplus_parse_netgroup (struct __netgrent *result, char *buffer,
       result->type = group_val;
       if (NISENTRYLEN (position, 1, data) >= buflen)
        {
-         __set_errno (ERANGE);
+         *errnop = ERANGE;
          return NSS_STATUS_TRYAGAIN;
        }
       strncpy (buffer, NISENTRYVAL (position, 1, data),
@@ -78,7 +78,7 @@ _nss_nisplus_parse_netgroup (struct __netgrent *result, char *buffer,
   if (NISENTRYLEN (position, 2, data) + NISENTRYLEN (position, 3, data) +
       NISENTRYLEN (position, 4, data) + 6 > buflen)
     {
-      __set_errno (ERANGE);
+      *errnop = ERANGE;
       status = NSS_STATUS_TRYAGAIN;
     }
   else
@@ -94,8 +94,7 @@ _nss_nisplus_parse_netgroup (struct __netgrent *result, char *buffer,
          result->val.triple.host = cp;
          cp = __stpncpy (cp, NISENTRYVAL (position, 2, data),
                          NISENTRYLEN (position, 2, data));
-         *cp = '\0';
-         ++cp;
+         *cp++ = '\0';
        }
 
       if (NISENTRYLEN (position, 3, data) == 0)
@@ -105,8 +104,7 @@ _nss_nisplus_parse_netgroup (struct __netgrent *result, char *buffer,
          result->val.triple.user = cp;
          cp = __stpncpy (cp, NISENTRYVAL (position, 3, data),
                          NISENTRYLEN (position, 3, data));
-         *cp = '\0';
-         ++cp;
+         *cp++ = '\0';
        }
 
       if (NISENTRYLEN (position, 4, data) == 0)
@@ -190,13 +188,13 @@ _nss_nisplus_endnetgrent (void)
 
 enum nss_status
 _nss_nisplus_getnetgrent_r (struct __netgrent *result,
-                           char *buffer, size_t buflen)
+                           char *buffer, size_t buflen, int *errnop)
 {
   enum nss_status status;
 
   __libc_lock_lock (lock);
 
-  status = _nss_nisplus_parse_netgroup (result, buffer, buflen);
+  status = _nss_nisplus_parse_netgroup (result, buffer, buflen, errnop);
 
   __libc_lock_unlock (lock);
 
index e548017068a74d028bd3bc9423826f56da28d2b7..b39a54fe03867d7ad097c239979f10811e1fde2d 100644 (file)
@@ -43,7 +43,7 @@ static u_long tablename_len = 0;
 
 static int
 _nss_nisplus_parse_netent (nis_result *result, struct netent *network,
-                           char *buffer, size_t buflen)
+                           char *buffer, size_t buflen, int *errnop)
 {
   char *first_unused = buffer;
   size_t room_left = buflen;
@@ -53,24 +53,24 @@ _nss_nisplus_parse_netent (nis_result *result, struct netent *network,
   if (result == NULL)
     return 0;
 
-  if ((result->status != NIS_SUCCESS && result->status != NIS_S_SUCCESS) ||
-      __type_of (result->objects.objects_val) != NIS_ENTRY_OBJ ||
-      strcmp(result->objects.objects_val[0].EN_data.en_type,
-             "networks_tbl") != 0 ||
-      result->objects.objects_val[0].EN_data.en_cols.en_cols_len < 3)
+  if ((result->status != NIS_SUCCESS && result->status != NIS_S_SUCCESS)
+      || __type_of (result->objects.objects_val) != NIS_ENTRY_OBJ
+      || strcmp (result->objects.objects_val[0].EN_data.en_type,
+                "networks_tbl") != 0
+      || result->objects.objects_val[0].EN_data.en_cols.en_cols_len < 3)
     return 0;
 
   if (NISENTRYLEN(0, 0, result) >= room_left)
     {
       /* The line is too long for our buffer.  */
     no_more_room:
-      __set_errno (ERANGE);
+      *errnop = ERANGE;
       return -1;
     }
 
   strncpy (first_unused, NISENTRYVAL(0, 0, result),
            NISENTRYLEN (0, 0, result));
-  first_unused[NISENTRYLEN(0, 0, result)] = '\0';
+  first_unused[NISENTRYLEN (0, 0, result)] = '\0';
   network->n_name = first_unused;
   room_left -= (strlen (first_unused) +1);
   first_unused += strlen (first_unused) +1;
@@ -142,7 +142,7 @@ _nss_nisplus_parse_netent (nis_result *result, struct netent *network,
 }
 
 static enum nss_status
-_nss_create_tablename (void)
+_nss_create_tablename (int *errnop)
 {
   if (tablename_val == NULL)
     {
@@ -153,7 +153,10 @@ _nss_create_tablename (void)
       p = __stpcpy (p, nis_local_directory ());
       tablename_val = __strdup (buf);
       if (tablename_val == NULL)
-        return NSS_STATUS_TRYAGAIN;
+       {
+         *errnop = errno;
+         return NSS_STATUS_TRYAGAIN;
+       }
       tablename_len = strlen (tablename_val);
     }
   return NSS_STATUS_SUCCESS;
@@ -163,6 +166,7 @@ enum nss_status
 _nss_nisplus_setnetent (void)
 {
   enum nss_status status = NSS_STATUS_SUCCESS;
+  int err;
 
   __libc_lock_lock (lock);
 
@@ -171,8 +175,7 @@ _nss_nisplus_setnetent (void)
   result = NULL;
 
   if (tablename_val == NULL)
-    if (_nss_create_tablename () != NSS_STATUS_SUCCESS)
-      status = NSS_STATUS_UNAVAIL;
+    status = _nss_create_tablename (&err);
 
   __libc_lock_unlock (lock);
 
@@ -195,7 +198,7 @@ _nss_nisplus_endnetent (void)
 
 static enum nss_status
 internal_nisplus_getnetent_r (struct netent *network, char *buffer,
-                              size_t buflen, int *herrnop)
+                              size_t buflen, int *errnop, int *herrnop)
 {
   int parse_res;
 
@@ -209,10 +212,14 @@ internal_nisplus_getnetent_r (struct netent *network, char *buffer,
          saved_res = NULL;
 
          if (tablename_val == NULL)
-           if (_nss_create_tablename() != NSS_STATUS_SUCCESS)
-             return NSS_STATUS_UNAVAIL;
+           {
+             enum nss_status status = _nss_create_tablename (errnop);
+
+             if (status != NSS_STATUS_SUCCESS)
+               return status;
+           }
 
-         result = nis_first_entry(tablename_val);
+         result = nis_first_entry (tablename_val);
          if (niserr2nss (result->status) != NSS_STATUS_SUCCESS)
            {
              int retval;
@@ -223,7 +230,7 @@ internal_nisplus_getnetent_r (struct netent *network, char *buffer,
              if (retval == NSS_STATUS_TRYAGAIN)
                {
                  *herrnop = NETDB_INTERNAL;
-                 __set_errno (EAGAIN);
+                 *errnop = errno;
                  return retval;
                }
              else
@@ -234,7 +241,7 @@ internal_nisplus_getnetent_r (struct netent *network, char *buffer,
        {
          nis_result *res;
 
-         res = nis_next_entry(tablename_val, &result->cookie);
+         res = nis_next_entry (tablename_val, &result->cookie);
          saved_res = result;
          result = res;
          if (niserr2nss (result->status) != NSS_STATUS_SUCCESS)
@@ -247,14 +254,15 @@ internal_nisplus_getnetent_r (struct netent *network, char *buffer,
              if (retval == NSS_STATUS_TRYAGAIN)
                {
                  *herrnop = NETDB_INTERNAL;
-                 __set_errno (EAGAIN);
+                 *errnop = errno;
                }
              return retval;
            }
        }
 
-      if ((parse_res = _nss_nisplus_parse_netent (result, network, buffer,
-                                                 buflen)) == -1)
+      parse_res = _nss_nisplus_parse_netent (result, network, buffer,
+                                            buflen, errnop);
+      if (parse_res == -1)
         {
           *herrnop = NETDB_INTERNAL;
           return NSS_STATUS_TRYAGAIN;
@@ -267,13 +275,14 @@ internal_nisplus_getnetent_r (struct netent *network, char *buffer,
 
 enum nss_status
 _nss_nisplus_getnetent_r (struct netent *result, char *buffer,
-                          size_t buflen, int *herrnop)
+                          size_t buflen, int *errnop, int *herrnop)
 {
   int status;
 
   __libc_lock_lock (lock);
 
-  status = internal_nisplus_getnetent_r (result, buffer, buflen, herrnop);
+  status = internal_nisplus_getnetent_r (result, buffer, buflen, errnop,
+                                        herrnop);
 
   __libc_lock_unlock (lock);
 
@@ -282,17 +291,22 @@ _nss_nisplus_getnetent_r (struct netent *result, char *buffer,
 
 enum nss_status
 _nss_nisplus_getnetbyname_r (const char *name, struct netent *network,
-                             char *buffer, size_t buflen, int *herrnop)
+                             char *buffer, size_t buflen, int *errnop,
+                            int *herrnop)
 {
   int parse_res, retval;
 
   if (tablename_val == NULL)
-    if (_nss_create_tablename() != NSS_STATUS_SUCCESS)
-      return NSS_STATUS_UNAVAIL;
+    {
+      enum nss_status status = _nss_create_tablename (errnop);
+
+      if (status != NSS_STATUS_SUCCESS)
+       return status;
+    }
 
   if (name == NULL)
     {
-      __set_errno (EINVAL);
+      *errnop = EINVAL;
       *herrnop = NETDB_INTERNAL;
       return NSS_STATUS_UNAVAIL;
     }
@@ -303,38 +317,38 @@ _nss_nisplus_getnetbyname_r (const char *name, struct netent *network,
 
       /* Search at first in the alias list, and use the correct name
         for the next search */
-      sprintf(buf, "[name=%s],%s", name, tablename_val);
-      result = nis_list(buf, FOLLOW_LINKS | FOLLOW_PATH, NULL, NULL);
+      sprintf (buf, "[name=%s],%s", name, tablename_val);
+      result = nis_list (buf, FOLLOW_LINKS | FOLLOW_PATH, NULL, NULL);
 
       /* If we do not find it, try it as original name. But if the
         database is correct, we should find it in the first case, too */
-      if ((result->status != NIS_SUCCESS &&
-          result->status != NIS_S_SUCCESS) ||
-         __type_of (result->objects.objects_val) != NIS_ENTRY_OBJ ||
-         strcmp(result->objects.objects_val[0].EN_data.en_type,
-                "networks_tbl") != 0 ||
-         result->objects.objects_val[0].EN_data.en_cols.en_cols_len < 3)
-       sprintf(buf, "[cname=%s],%s", name, tablename_val);
+      if ((result->status != NIS_SUCCESS && result->status != NIS_S_SUCCESS)
+         || __type_of (result->objects.objects_val) != NIS_ENTRY_OBJ
+         || strcmp (result->objects.objects_val[0].EN_data.en_type,
+                    "networks_tbl") != 0
+         || result->objects.objects_val[0].EN_data.en_cols.en_cols_len < 3)
+       sprintf (buf, "[cname=%s],%s", name, tablename_val);
       else
-       sprintf(buf, "[cname=%s],%s", NISENTRYVAL(0, 0, result),
-               tablename_val);
+       sprintf (buf, "[cname=%s],%s", NISENTRYVAL (0, 0, result),
+                tablename_val);
 
       nis_freeresult (result);
-      result = nis_list(buf, FOLLOW_LINKS | FOLLOW_PATH, NULL, NULL);
+      result = nis_list (buf, FOLLOW_LINKS | FOLLOW_PATH, NULL, NULL);
 
       retval = niserr2nss (result->status);
       if (retval != NSS_STATUS_SUCCESS)
        {
          if (retval == NSS_STATUS_TRYAGAIN)
            {
-             __set_errno (EAGAIN);
+             *errnop = errno;
              *herrnop = NETDB_INTERNAL;
            }
          nis_freeresult (result);
          return retval;
        }
 
-      parse_res = _nss_nisplus_parse_netent (result, network, buffer, buflen);
+      parse_res = _nss_nisplus_parse_netent (result, network, buffer, buflen,
+                                            errnop);
 
       nis_freeresult (result);
 
@@ -343,7 +357,10 @@ _nss_nisplus_getnetbyname_r (const char *name, struct netent *network,
 
       *herrnop = NETDB_INTERNAL;
       if (parse_res == -1)
-       return NSS_STATUS_TRYAGAIN;
+       {
+         *errnop = ERANGE;
+         return NSS_STATUS_TRYAGAIN;
+       }
       else
        return NSS_STATUS_NOTFOUND;
     }
@@ -352,12 +369,16 @@ _nss_nisplus_getnetbyname_r (const char *name, struct netent *network,
 /* XXX type is ignored, SUN's NIS+ table doesn't support it */
 enum nss_status
 _nss_nisplus_getnetbyaddr_r (const unsigned long addr, const int type,
-                            struct netent *network,
-                            char *buffer, size_t buflen, int *herrnop)
+                            struct netent *network, char *buffer,
+                            size_t buflen, int *errnop, int *herrnop)
 {
   if (tablename_val == NULL)
-    if (_nss_create_tablename() != NSS_STATUS_SUCCESS)
-      return NSS_STATUS_UNAVAIL;
+    {
+      enum nss_status status = _nss_create_tablename (errnop);
+
+      if (status != NSS_STATUS_SUCCESS)
+       return status;
+    }
 
   {
     int parse_res, retval;
@@ -368,21 +389,22 @@ _nss_nisplus_getnetbyaddr_r (const unsigned long addr, const int type,
     in = inet_makeaddr (addr, 0);
     sprintf (buf, "[addr=%s],%s", inet_ntoa (in), tablename_val);
 
-    result = nis_list(buf, EXPAND_NAME, NULL, NULL);
+    result = nis_list (buf, EXPAND_NAME, NULL, NULL);
 
     retval = niserr2nss (result->status);
     if (retval != NSS_STATUS_SUCCESS)
       {
        if (retval == NSS_STATUS_TRYAGAIN)
          {
-           __set_errno (EAGAIN);
+           *errnop = errno;
            *herrnop = NETDB_INTERNAL;
          }
        nis_freeresult (result);
        return retval;
       }
 
-    parse_res = _nss_nisplus_parse_netent (result, network, buffer, buflen);
+    parse_res = _nss_nisplus_parse_netent (result, network, buffer, buflen,
+                                          errnop);
 
     nis_freeresult (result);
 
@@ -391,7 +413,10 @@ _nss_nisplus_getnetbyaddr_r (const unsigned long addr, const int type,
 
     *herrnop = NETDB_INTERNAL;
     if (parse_res == -1)
-      return NSS_STATUS_TRYAGAIN;
+      {
+       *errnop = ERANGE;
+       return NSS_STATUS_TRYAGAIN;
+      }
     else
       return NSS_STATUS_NOTFOUND;
   }
index b700fa66b47e6636379785cb8133e725e8e01f3f..fa4073e6d87b5f8550d20bfeb59923654d1e4e19 100644 (file)
@@ -34,7 +34,7 @@
 
 int
 _nss_nisplus_parse_pwent (nis_result *result, struct passwd *pw,
-                         char *buffer, size_t buflen)
+                         char *buffer, size_t buflen, int *errnop)
 {
   char *first_unused = buffer;
   size_t room_left = buflen;
@@ -42,35 +42,35 @@ _nss_nisplus_parse_pwent (nis_result *result, struct passwd *pw,
   if (result == NULL)
     return 0;
 
-  if ((result->status != NIS_SUCCESS && result->status != NIS_S_SUCCESS) ||
-      result->objects.objects_len != 1 ||
-      __type_of (result->objects.objects_val) != NIS_ENTRY_OBJ ||
-      strcmp(result->objects.objects_val->EN_data.en_type,
-            "passwd_tbl") != 0 ||
-      result->objects.objects_val->EN_data.en_cols.en_cols_len < 7)
+  if ((result->status != NIS_SUCCESS && result->status != NIS_S_SUCCESS)
+      || result->objects.objects_len != 1
+      || __type_of (result->objects.objects_val) != NIS_ENTRY_OBJ
+      || strcmp (result->objects.objects_val->EN_data.en_type,
+                "passwd_tbl") != 0
+      || result->objects.objects_val->EN_data.en_cols.en_cols_len < 7)
     return 0;
 
   if (NISENTRYLEN (0, 0, result) >= room_left)
     {
       /* The line is too long for our buffer.  */
     no_more_room:
-      __set_errno (ERANGE);
+      *errnop = ERANGE;
       return -1;
     }
 
-  strncpy (first_unused, NISENTRYVAL(0, 0, result),
+  strncpy (first_unused, NISENTRYVAL (0, 0, result),
           NISENTRYLEN (0, 0, result));
-  first_unused[NISENTRYLEN(0, 0, result)] = '\0';
+  first_unused[NISENTRYLEN (0, 0, result)] = '\0';
   pw->pw_name = first_unused;
   room_left -= (strlen (first_unused) +1);
   first_unused += strlen (first_unused) +1;
 
-  if (NISENTRYLEN(0, 1, result) >= room_left)
+  if (NISENTRYLEN (0, 1, result) >= room_left)
     goto no_more_room;
 
-  strncpy (first_unused, NISENTRYVAL(0, 1, result),
+  strncpy (first_unused, NISENTRYVAL (0, 1, result),
           NISENTRYLEN (0, 1, result));
-  first_unused[NISENTRYLEN(0, 1, result)] = '\0';
+  first_unused[NISENTRYLEN (0, 1, result)] = '\0';
   pw->pw_passwd = first_unused;
   room_left -= (strlen (first_unused) +1);
   first_unused += strlen (first_unused) +1;
@@ -80,17 +80,17 @@ _nss_nisplus_parse_pwent (nis_result *result, struct passwd *pw,
 
   strncpy (first_unused, NISENTRYVAL (0, 2, result),
           NISENTRYLEN (0, 2, result));
-  first_unused[NISENTRYLEN(0, 2, result)] = '\0';
+  first_unused[NISENTRYLEN (0, 2, result)] = '\0';
   pw->pw_uid = atoi (first_unused);
   room_left -= (strlen (first_unused) +1);
   first_unused += strlen (first_unused) +1;
 
-  if (NISENTRYLEN(0, 3, result) >= room_left)
+  if (NISENTRYLEN (0, 3, result) >= room_left)
     goto no_more_room;
 
-  strncpy (first_unused, NISENTRYVAL(0, 3, result),
+  strncpy (first_unused, NISENTRYVAL (0, 3, result),
           NISENTRYLEN (0, 3, result));
-  first_unused[NISENTRYLEN(0, 3, result)] = '\0';
+  first_unused[NISENTRYLEN (0, 3, result)] = '\0';
   pw->pw_gid = atoi (first_unused);
   room_left -= (strlen (first_unused) +1);
   first_unused += strlen (first_unused) +1;
@@ -98,24 +98,24 @@ _nss_nisplus_parse_pwent (nis_result *result, struct passwd *pw,
   if (NISENTRYLEN(0, 4, result) >= room_left)
     goto no_more_room;
 
-  strncpy (first_unused, NISENTRYVAL(0, 4, result),
+  strncpy (first_unused, NISENTRYVAL (0, 4, result),
           NISENTRYLEN (0, 4, result));
-  first_unused[NISENTRYLEN(0, 4, result)] = '\0';
+  first_unused[NISENTRYLEN (0, 4, result)] = '\0';
   pw->pw_gecos = first_unused;
   room_left -= (strlen (first_unused) +1);
   first_unused += strlen (first_unused) +1;
 
-  if (NISENTRYLEN(0, 5, result) >= room_left)
+  if (NISENTRYLEN (0, 5, result) >= room_left)
     goto no_more_room;
 
   strncpy (first_unused, NISENTRYVAL (0, 5, result),
           NISENTRYLEN (0, 5, result));
-  first_unused[NISENTRYLEN(0, 5, result)] = '\0';
+  first_unused[NISENTRYLEN (0, 5, result)] = '\0';
   pw->pw_dir = first_unused;
   room_left -= (strlen (first_unused) +1);
   first_unused += strlen (first_unused) +1;
 
-  if (NISENTRYLEN(0, 6, result) >= room_left)
+  if (NISENTRYLEN (0, 6, result) >= room_left)
     goto no_more_room;
 
   strncpy (first_unused, NISENTRYVAL (0, 6, result),
@@ -129,8 +129,8 @@ _nss_nisplus_parse_pwent (nis_result *result, struct passwd *pw,
 }
 
 int
-_nss_nisplus_parse_grent (nis_result *result, u_long entry,
-                         struct group *gr, char *buffer, size_t buflen)
+_nss_nisplus_parse_grent (nis_result *result, u_long entry, struct group *gr,
+                         char *buffer, size_t buflen, int *errnop)
 {
   char *first_unused = buffer;
   size_t room_left = buflen;
@@ -140,18 +140,18 @@ _nss_nisplus_parse_grent (nis_result *result, u_long entry,
   if (result == NULL)
     return 0;
 
-  if ((result->status != NIS_SUCCESS && result->status != NIS_S_SUCCESS) ||
-      __type_of(result->objects.objects_val) != NIS_ENTRY_OBJ ||
-      strcmp (result->objects.objects_val[entry].EN_data.en_type,
-             "group_tbl") != 0 ||
-      result->objects.objects_val[entry].EN_data.en_cols.en_cols_len < 4)
+  if ((result->status != NIS_SUCCESS && result->status != NIS_S_SUCCESS)
+      || __type_of(result->objects.objects_val) != NIS_ENTRY_OBJ
+      || strcmp (result->objects.objects_val[entry].EN_data.en_type,
+                "group_tbl") != 0
+      || result->objects.objects_val[entry].EN_data.en_cols.en_cols_len < 4)
     return 0;
 
   if (NISENTRYLEN (entry, 0, result) >= room_left)
     {
       /* The line is too long for our buffer.  */
     no_more_room:
-      __set_errno (ERANGE);
+      *errnop = ERANGE;
       return -1;
     }
 
@@ -240,7 +240,7 @@ _nss_nisplus_parse_grent (nis_result *result, u_long entry,
 
 int
 _nss_nisplus_parse_spent (nis_result *result, struct spwd *sp,
-                         char *buffer, size_t buflen)
+                         char *buffer, size_t buflen, int *errnop)
 {
   char *first_unused = buffer;
   size_t room_left = buflen;
@@ -248,35 +248,35 @@ _nss_nisplus_parse_spent (nis_result *result, struct spwd *sp,
   if (result == NULL)
     return 0;
 
-  if ((result->status != NIS_SUCCESS && result->status != NIS_S_SUCCESS) ||
-      result->objects.objects_len != 1 ||
-      __type_of(result->objects.objects_val) != NIS_ENTRY_OBJ ||
-      strcmp (result->objects.objects_val->EN_data.en_type,
-             "passwd_tbl") != 0 ||
-      result->objects.objects_val[0].EN_data.en_cols.en_cols_len < 8)
+  if ((result->status != NIS_SUCCESS && result->status != NIS_S_SUCCESS)
+      || result->objects.objects_len != 1
+      || __type_of(result->objects.objects_val) != NIS_ENTRY_OBJ
+      || strcmp (result->objects.objects_val->EN_data.en_type,
+                "passwd_tbl") != 0
+      || result->objects.objects_val[0].EN_data.en_cols.en_cols_len < 8)
     return 0;
 
-  if (NISENTRYLEN(0, 0, result) >= room_left)
+  if (NISENTRYLEN (0, 0, result) >= room_left)
     {
       /* The line is too long for our buffer.  */
     no_more_room:
-      __set_errno (ERANGE);
+      *errnop = ERANGE;
       return -1;
     }
 
   strncpy (first_unused, NISENTRYVAL (0, 0, result),
           NISENTRYLEN (0, 0, result));
-  first_unused[NISENTRYLEN(0, 0, result)] = '\0';
+  first_unused[NISENTRYLEN (0, 0, result)] = '\0';
   sp->sp_namp = first_unused;
   room_left -= (strlen (first_unused) +1);
   first_unused += strlen (first_unused) +1;
 
-  if (NISENTRYLEN(0, 1, result) >= room_left)
+  if (NISENTRYLEN (0, 1, result) >= room_left)
     goto no_more_room;
 
   strncpy (first_unused, NISENTRYVAL (0, 1, result),
           NISENTRYLEN (0, 1, result));
-  first_unused[NISENTRYLEN(0, 1, result)] = '\0';
+  first_unused[NISENTRYLEN (0, 1, result)] = '\0';
   sp->sp_pwdp = first_unused;
   room_left -= (strlen (first_unused) +1);
   first_unused += strlen (first_unused) +1;
@@ -300,40 +300,40 @@ _nss_nisplus_parse_spent (nis_result *result, struct spwd *sp,
       if (cp == NULL)
        return 0;
       *cp++ = '\0';
-      sp->sp_min = atol(line);
+      sp->sp_min = atol (line);
 
       line = cp;
       cp = strchr (line, ':');
       if (cp == NULL)
        return 0;
       *cp++ = '\0';
-      sp->sp_max = atol(line);
+      sp->sp_max = atol (line);
 
       line = cp;
       cp = strchr (line, ':');
       if (cp == NULL)
        return 0;
       *cp++ = '\0';
-      sp->sp_warn = atol(line);
+      sp->sp_warn = atol (line);
 
       line = cp;
       cp = strchr (line, ':');
       if (cp == NULL)
        return 0;
       *cp++ = '\0';
-      sp->sp_inact = atol(line);
+      sp->sp_inact = atol (line);
 
       line = cp;
       cp = strchr (line, ':');
       if (cp == NULL)
        return 0;
       *cp++ = '\0';
-      sp->sp_expire = atol(line);
+      sp->sp_expire = atol (line);
 
       line = cp;
       if (line == NULL)
        return 0;
-      sp->sp_flag = atol(line);
+      sp->sp_flag = atol (line);
     }
 
   return 1;
index 2cbd9fe2fa6fc35b0ef67a780483ed3016895f79..262276f301fc9ff47635f008c8aaa3475cf0a961 100644 (file)
@@ -41,7 +41,7 @@ static u_long tablename_len = 0;
 
 static int
 _nss_nisplus_parse_protoent (nis_result * result, struct protoent *proto,
-                            char *buffer, size_t buflen)
+                            char *buffer, size_t buflen, int *errnop)
 {
   char *first_unused = buffer;
   size_t room_left = buflen;
@@ -51,9 +51,10 @@ _nss_nisplus_parse_protoent (nis_result * result, struct protoent *proto,
   if (result == NULL)
     return 0;
 
-  if ((result->status != NIS_SUCCESS && result->status != NIS_S_SUCCESS) ||
-      __type_of (NIS_RES_OBJECT (result)) != NIS_ENTRY_OBJ ||
-      strcmp (NIS_RES_OBJECT (result)->EN_data.en_type, "protocols_tbl") != 0
+  if ((result->status != NIS_SUCCESS && result->status != NIS_S_SUCCESS)
+      || __type_of (NIS_RES_OBJECT (result)) != NIS_ENTRY_OBJ
+      || strcmp (NIS_RES_OBJECT (result)->EN_data.en_type,
+                "protocols_tbl") != 0
       || NIS_RES_OBJECT (result)->EN_data.en_cols.en_cols_len < 3)
     return 0;
 
@@ -61,7 +62,7 @@ _nss_nisplus_parse_protoent (nis_result * result, struct protoent *proto,
   if (NISENTRYLEN (0, 0, result) + 1 > room_left)
     {
     no_more_room:
-      __set_errno (ERANGE);
+      *errnop = ERANGE;
       return -1;
     }
   strncpy (first_unused, NISENTRYVAL (0, 0, result),
@@ -101,7 +102,7 @@ _nss_nisplus_parse_protoent (nis_result * result, struct protoent *proto,
   proto->p_aliases = (char **) first_unused;
   if (room_left < sizeof (char *))
     goto no_more_room;
-  room_left -= (sizeof (char *));
+  room_left -= sizeof (char *);
   proto->p_aliases[0] = NULL;
 
   i = 0;
@@ -136,7 +137,7 @@ _nss_nisplus_parse_protoent (nis_result * result, struct protoent *proto,
 }
 
 static enum nss_status
-_nss_create_tablename (void)
+_nss_create_tablename (int *errnop)
 {
   if (tablename_val == NULL)
     {
@@ -147,7 +148,10 @@ _nss_create_tablename (void)
       p = __stpcpy (p, nis_local_directory ());
       tablename_val = __strdup (buf);
       if (tablename_val == NULL)
-        return NSS_STATUS_TRYAGAIN;
+       {
+         *errnop = errno;
+         return NSS_STATUS_TRYAGAIN;
+       }
       tablename_len = strlen (tablename_val);
     }
   return NSS_STATUS_SUCCESS;
@@ -165,7 +169,10 @@ _nss_nisplus_setprotoent (void)
   result = NULL;
 
   if (tablename_val == NULL)
-    status = _nss_create_tablename ();
+    {
+      int err;
+      status = _nss_create_tablename (&err);
+    }
 
   __libc_lock_unlock (lock);
 
@@ -188,7 +195,7 @@ _nss_nisplus_endprotoent (void)
 
 static enum nss_status
 internal_nisplus_getprotoent_r (struct protoent *proto, char *buffer,
-                               size_t buflen)
+                               size_t buflen, int *errnop)
 {
   int parse_res;
 
@@ -201,8 +208,12 @@ internal_nisplus_getprotoent_r (struct protoent *proto, char *buffer,
        {
          saved_res = NULL;
          if (tablename_val == NULL)
-           if (_nss_create_tablename () != NSS_STATUS_SUCCESS)
-             return NSS_STATUS_UNAVAIL;
+           {
+             enum nss_status status = _nss_create_tablename (errnop);
+
+             if (status != NSS_STATUS_SUCCESS)
+               return status;
+           }
 
          result = nis_first_entry (tablename_val);
          if (niserr2nss (result->status) != NSS_STATUS_SUCCESS)
@@ -223,11 +234,13 @@ internal_nisplus_getprotoent_r (struct protoent *proto, char *buffer,
            }
        }
 
-      if ((parse_res = _nss_nisplus_parse_protoent (result, proto, buffer,
-                                                   buflen)) == -1)
+      parse_res = _nss_nisplus_parse_protoent (result, proto, buffer,
+                                              buflen, errnop);
+      if (parse_res == -1)
        {
          nis_freeresult (result);
          result = saved_res;
+         *errnop = ERANGE;
          return NSS_STATUS_TRYAGAIN;
        }
       else
@@ -243,13 +256,13 @@ internal_nisplus_getprotoent_r (struct protoent *proto, char *buffer,
 
 enum nss_status
 _nss_nisplus_getprotoent_r (struct protoent *result, char *buffer,
-                           size_t buflen)
+                           size_t buflen, int *errnop)
 {
   int status;
 
   __libc_lock_lock (lock);
 
-  status = internal_nisplus_getprotoent_r (result, buffer, buflen);
+  status = internal_nisplus_getprotoent_r (result, buffer, buflen, errnop);
 
   __libc_lock_unlock (lock);
 
@@ -258,13 +271,17 @@ _nss_nisplus_getprotoent_r (struct protoent *result, char *buffer,
 
 enum nss_status
 _nss_nisplus_getprotobyname_r (const char *name, struct protoent *proto,
-                              char *buffer, size_t buflen)
+                              char *buffer, size_t buflen, int *errnop)
 {
   int parse_res;
 
   if (tablename_val == NULL)
-    if (_nss_create_tablename () != NSS_STATUS_SUCCESS)
-      return NSS_STATUS_UNAVAIL;
+    {
+      enum nss_status status = _nss_create_tablename (errnop);
+
+      if (status != NSS_STATUS_SUCCESS)
+       return status;
+    }
 
   if (name == NULL)
     return NSS_STATUS_NOTFOUND;
@@ -280,12 +297,11 @@ _nss_nisplus_getprotobyname_r (const char *name, struct protoent *proto,
 
       /* If we do not find it, try it as original name. But if the
          database is correct, we should find it in the first case, too */
-      if ((result->status != NIS_SUCCESS &&
-          result->status != NIS_S_SUCCESS) ||
-         __type_of (result->objects.objects_val) != NIS_ENTRY_OBJ ||
-         strcmp (result->objects.objects_val->EN_data.en_type,
-                 "protocols_tbl") != 0 ||
-         result->objects.objects_val->EN_data.en_cols.en_cols_len < 3)
+      if ((result->status != NIS_SUCCESS && result->status != NIS_S_SUCCESS)
+         || __type_of (result->objects.objects_val) != NIS_ENTRY_OBJ
+         || strcmp (result->objects.objects_val->EN_data.en_type,
+                    "protocols_tbl") != 0
+         || result->objects.objects_val->EN_data.en_cols.en_cols_len < 3)
        sprintf (buf, "[cname=%s],%s", name, tablename_val);
       else
        sprintf (buf, "[cname=%s],%s", NISENTRYVAL (0, 0, result),
@@ -302,12 +318,16 @@ _nss_nisplus_getprotobyname_r (const char *name, struct protoent *proto,
          return status;
        }
 
-      parse_res = _nss_nisplus_parse_protoent (result, proto, buffer, buflen);
+      parse_res = _nss_nisplus_parse_protoent (result, proto, buffer, buflen,
+                                              errnop);
 
       nis_freeresult (result);
 
       if (parse_res == -1)
-       return NSS_STATUS_TRYAGAIN;
+       {
+         *errnop = ERANGE;
+         return NSS_STATUS_TRYAGAIN;
+       }
       if (parse_res)
        return NSS_STATUS_SUCCESS;
 
@@ -317,11 +337,16 @@ _nss_nisplus_getprotobyname_r (const char *name, struct protoent *proto,
 
 enum nss_status
 _nss_nisplus_getprotobynumber_r (const int number, struct protoent *proto,
-                                char *buffer, size_t buflen)
+                                char *buffer, size_t buflen, int *errnop)
 {
   if (tablename_val == NULL)
-    if (_nss_create_tablename () != NSS_STATUS_SUCCESS)
-      return NSS_STATUS_UNAVAIL;
+    {
+      enum nss_status status = _nss_create_tablename (errnop);
+
+      if (status != NSS_STATUS_SUCCESS)
+       return status;
+    }
+
   {
     int parse_res;
     nis_result *result;
@@ -339,12 +364,16 @@ _nss_nisplus_getprotobynumber_r (const int number, struct protoent *proto,
        return status;
       }
 
-    parse_res = _nss_nisplus_parse_protoent (result, proto, buffer, buflen);
+    parse_res = _nss_nisplus_parse_protoent (result, proto, buffer, buflen,
+                                            errnop);
 
     nis_freeresult (result);
 
     if (parse_res == -1)
-      return NSS_STATUS_TRYAGAIN;
+      {
+       *errnop = ERANGE;
+       return NSS_STATUS_TRYAGAIN;
+      }
 
     if (parse_res)
       return NSS_STATUS_SUCCESS;
index aa2a6f0c3ad74b8f133f5fa57d00d7f401529d32..24d217b804bac74aee7c35bed77e4d42b8dd98a2 100644 (file)
@@ -32,7 +32,7 @@ extern int xdecrypt (char *, char *);
 
 /* 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)
+_nss_nisplus_getpublickey (const char *netname, char *pkey, int *errnop)
 {
   nis_result *res;
   enum nss_status retval;
@@ -45,7 +45,7 @@ _nss_nisplus_getpublickey (const char *netname, char *pkey)
 
   if (netname == NULL)
     {
-      __set_errno (EINVAL);
+      *errnop = EINVAL;
       return NSS_STATUS_UNAVAIL;
     }
 
@@ -72,7 +72,7 @@ _nss_nisplus_getpublickey (const char *netname, char *pkey)
   if (retval != NSS_STATUS_SUCCESS)
     {
       if (retval == NSS_STATUS_TRYAGAIN)
-       __set_errno (EAGAIN);
+       *errnop = errno;
       if (res->status == NIS_NOTFOUND)
        retval = NSS_STATUS_SUCCESS;
       nis_freeresult (res);
@@ -103,7 +103,8 @@ _nss_nisplus_getpublickey (const char *netname, char *pkey)
 }
 
 enum nss_status
-_nss_nisplus_getsecretkey (const char *netname, char *skey, char *passwd)
+_nss_nisplus_getsecretkey (const char *netname, char *skey, char *passwd,
+                          int *errnop)
 {
   nis_result *res;
   enum nss_status retval;
@@ -116,7 +117,7 @@ _nss_nisplus_getsecretkey (const char *netname, char *skey, char *passwd)
 
   if (netname == NULL)
     {
-      __set_errno (EINVAL);
+      *errnop = EINVAL;
       return NSS_STATUS_UNAVAIL;
     }
 
@@ -143,7 +144,7 @@ _nss_nisplus_getsecretkey (const char *netname, char *skey, char *passwd)
   if (retval != NSS_STATUS_SUCCESS)
     {
       if (retval == NSS_STATUS_TRYAGAIN)
-       __set_errno (EAGAIN);
+       *errnop = errno;
       nis_freeresult (res);
       return retval;
     }
@@ -183,7 +184,8 @@ _nss_nisplus_getsecretkey (const char *netname, char *skey, char *passwd)
 /* Parse information from the passed string.
    The format of the string passed is gid,grp,grp, ...  */
 static enum nss_status
-parse_grp_str (const char *s, gid_t *gidp, int *gidlenp, gid_t *gidlist)
+parse_grp_str (const char *s, gid_t *gidp, int *gidlenp, gid_t *gidlist,
+              int *errnop)
 {
   int gidlen;
 
@@ -209,7 +211,7 @@ parse_grp_str (const char *s, gid_t *gidp, int *gidlenp, gid_t *gidlist)
 
 enum nss_status
 _nss_nisplus_netname2user (char netname[MAXNETNAMELEN + 1], uid_t *uidp,
-                      gid_t *gidp, int *gidlenp, gid_t *gidlist)
+                      gid_t *gidp, int *gidlenp, gid_t *gidlist, int *errnop)
 {
   char *domain;
   nis_result *res;
@@ -223,7 +225,7 @@ _nss_nisplus_netname2user (char netname[MAXNETNAMELEN + 1], uid_t *uidp,
   if (! domain)
     return NSS_STATUS_UNAVAIL;
 
-  domain++;  /* skip '@' */
+  ++domain;  /* skip '@' */
 
   /* 2.  Get user's nisplus principal name.  */
   if ((strlen (netname) + strlen (domain)+45) >
@@ -260,6 +262,7 @@ _nss_nisplus_netname2user (char netname[MAXNETNAMELEN + 1], uid_t *uidp,
       syslog (LOG_ERR, _("netname2user: (nis+ lookup): %s\n"),
              nis_sperrno (res->status));
       nis_freeresult (res);
+      *errnop = errno;
       return NSS_STATUS_TRYAGAIN;
     default:
       syslog (LOG_ERR, _("netname2user: (nis+ lookup): %s\n"),
@@ -269,16 +272,14 @@ _nss_nisplus_netname2user (char netname[MAXNETNAMELEN + 1], uid_t *uidp,
     }
 
   if (res->objects.objects_len > 1)
-    {
-      /*
-       * A netname belonging to more than one principal?
-       * Something wrong with cred table. should be unique.
-       * Warn user and continue.
-       */
-      syslog (LOG_ALERT,
-             _("netname2user: DES entry for %s in directory %s not unique"),
-             netname, domain);
-    }
+    /*
+     * A netname belonging to more than one principal?
+     * Something wrong with cred table. should be unique.
+     * Warn user and continue.
+     */
+    syslog (LOG_ALERT,
+           _("netname2user: DES entry for %s in directory %s not unique"),
+           netname, domain);
 
   len = ENTRY_LEN (res->objects.objects_val, 0);
   strncpy (principal, ENTRY_VAL (res->objects.objects_val, 0), len);
@@ -326,6 +327,7 @@ _nss_nisplus_netname2user (char netname[MAXNETNAMELEN + 1], uid_t *uidp,
       syslog (LOG_ERR, _("netname2user: (nis+ lookup): %s\n"),
              nis_sperrno (res->status));
       nis_freeresult (res);
+      *errnop = errno;
       return NSS_STATUS_TRYAGAIN;
     case NIS_SUCCESS:
     case NIS_S_SUCCESS:
@@ -338,16 +340,14 @@ _nss_nisplus_netname2user (char netname[MAXNETNAMELEN + 1], uid_t *uidp,
     }
 
   if (res->objects.objects_len > 1)
-    {
-      /*
-       * A principal can have more than one LOCAL entry?
-       * Something wrong with cred table.
-       * Warn user and continue.
-       */
-      syslog (LOG_ALERT,
-             _("netname2user: LOCAL entry for %s in directory %s not unique"),
-             netname, domain);
-    }
+    /*
+     * A principal can have more than one LOCAL entry?
+     * Something wrong with cred table.
+     * Warn user and continue.
+     */
+    syslog (LOG_ALERT,
+           _("netname2user: LOCAL entry for %s in directory %s not unique"),
+           netname, domain);
   /* Fetch the uid */
   *uidp = atoi (ENTRY_VAL (res->objects.objects_val, 2));
 
@@ -358,7 +358,7 @@ _nss_nisplus_netname2user (char netname[MAXNETNAMELEN + 1], uid_t *uidp,
     }
 
   parse_grp_str (ENTRY_VAL (res->objects.objects_val, 3),
-                gidp, gidlenp, gidlist);
+                gidp, gidlenp, gidlist, errnop);
 
   nis_freeresult (res);
   return NSS_STATUS_SUCCESS;
index 3974defa4747723a89b2c68c0ca71861021cb608..18114ad7e5f620e81df40315d3b35c39cb5c3a9a 100644 (file)
@@ -33,10 +33,10 @@ static nis_name tablename_val = NULL;
 static u_long tablename_len = 0;
 
 extern int _nss_nisplus_parse_pwent (nis_result *res, struct passwd *pw,
-                                    char *buffer, size_t buflen);
+                                    char *buffer, size_t buflen, int *errnop);
 
 static enum nss_status
-_nss_create_tablename (void)
+_nss_create_tablename (int *errnop)
 {
   if (tablename_val == NULL)
     {
@@ -47,7 +47,10 @@ _nss_create_tablename (void)
       p = __stpcpy (p, nis_local_directory ());
       tablename_val = __strdup (buf);
       if (tablename_val == NULL)
-        return NSS_STATUS_TRYAGAIN;
+       {
+         *errnop = errno;
+         return NSS_STATUS_TRYAGAIN;
+       }
       tablename_len = strlen (tablename_val);
     }
   return NSS_STATUS_SUCCESS;
@@ -58,6 +61,7 @@ enum nss_status
 _nss_nisplus_setpwent (void)
 {
   enum nss_status status = NSS_STATUS_SUCCESS;
+  int err;
 
   __libc_lock_lock (lock);
 
@@ -66,7 +70,7 @@ _nss_nisplus_setpwent (void)
   result = NULL;
 
   if (tablename_val == NULL)
-    status = _nss_create_tablename ();
+    status = _nss_create_tablename (&err);
 
   __libc_lock_unlock (lock);
 
@@ -88,7 +92,8 @@ _nss_nisplus_endpwent (void)
 }
 
 static enum nss_status
-internal_nisplus_getpwent_r (struct passwd *pw, char *buffer, size_t buflen)
+internal_nisplus_getpwent_r (struct passwd *pw, char *buffer, size_t buflen,
+                            int *errnop)
 {
   int parse_res;
 
@@ -101,10 +106,14 @@ internal_nisplus_getpwent_r (struct passwd *pw, char *buffer, size_t buflen)
        {
          saved_res = NULL;
           if (tablename_val == NULL)
-            if (_nss_create_tablename () != NSS_STATUS_SUCCESS)
-              return NSS_STATUS_UNAVAIL;
+           {
+             enum nss_status status = _nss_create_tablename (errnop);
+
+             if (status != NSS_STATUS_SUCCESS)
+               return status;
+           }
 
-         result = nis_first_entry(tablename_val);
+         result = nis_first_entry (tablename_val);
          if (niserr2nss (result->status) != NSS_STATUS_SUCCESS)
            return niserr2nss (result->status);
        }
@@ -113,7 +122,7 @@ internal_nisplus_getpwent_r (struct passwd *pw, char *buffer, size_t buflen)
          nis_result *res;
 
          saved_res = result;
-         res = nis_next_entry(tablename_val, &result->cookie);
+         res = nis_next_entry (tablename_val, &result->cookie);
          result = res;
          if (niserr2nss (result->status) != NSS_STATUS_SUCCESS)
            {
@@ -122,11 +131,13 @@ internal_nisplus_getpwent_r (struct passwd *pw, char *buffer, size_t buflen)
            }
        }
 
-      if ((parse_res = _nss_nisplus_parse_pwent (result, pw, buffer,
-                                                buflen)) == -1)
+      parse_res = _nss_nisplus_parse_pwent (result, pw, buffer,
+                                           buflen, errnop);
+      if (parse_res == -1)
        {
          nis_freeresult (result);
          result = saved_res;
+         *errnop = ERANGE;
          return NSS_STATUS_TRYAGAIN;
        }
       else
@@ -140,13 +151,14 @@ internal_nisplus_getpwent_r (struct passwd *pw, char *buffer, size_t buflen)
 }
 
 enum nss_status
-_nss_nisplus_getpwent_r (struct passwd *result, char *buffer, size_t buflen)
+_nss_nisplus_getpwent_r (struct passwd *result, char *buffer, size_t buflen,
+                        int *errnop)
 {
   int status;
 
   __libc_lock_lock (lock);
 
-  status = internal_nisplus_getpwent_r (result, buffer, buflen);
+  status = internal_nisplus_getpwent_r (result, buffer, buflen, errnop);
 
   __libc_lock_unlock (lock);
 
@@ -155,13 +167,17 @@ _nss_nisplus_getpwent_r (struct passwd *result, char *buffer, size_t buflen)
 
 enum nss_status
 _nss_nisplus_getpwnam_r (const char *name, struct passwd *pw,
-                    char *buffer, size_t buflen)
+                        char *buffer, size_t buflen, int *errnop)
 {
   int parse_res;
 
   if (tablename_val == NULL)
-    if (_nss_create_tablename () != NSS_STATUS_SUCCESS)
-      return NSS_STATUS_UNAVAIL;
+    {
+      enum nss_status status = _nss_create_tablename (errnop);
+
+      if (status != NSS_STATUS_SUCCESS)
+       return status;
+    }
 
   if (name == NULL || strlen (name) > 8)
     return NSS_STATUS_NOTFOUND;
@@ -170,7 +186,7 @@ _nss_nisplus_getpwnam_r (const char *name, struct passwd *pw,
       nis_result *result;
       char buf[strlen (name) + 24 + tablename_len];
 
-      sprintf(buf, "[name=%s],%s", name, tablename_val);
+      sprintf (buf, "[name=%s],%s", name, tablename_val);
 
       result = nis_list(buf, FOLLOW_PATH | FOLLOW_LINKS, NULL, NULL);
 
@@ -182,12 +198,16 @@ _nss_nisplus_getpwnam_r (const char *name, struct passwd *pw,
          return status;
        }
 
-      parse_res = _nss_nisplus_parse_pwent (result, pw, buffer, buflen);
+      parse_res = _nss_nisplus_parse_pwent (result, pw, buffer, buflen,
+                                           errnop);
 
       nis_freeresult (result);
 
       if (parse_res == -1)
-       return NSS_STATUS_TRYAGAIN;
+       {
+         *errnop = ERANGE;
+         return NSS_STATUS_TRYAGAIN;
+       }
 
       if (parse_res)
        return NSS_STATUS_SUCCESS;
@@ -198,17 +218,22 @@ _nss_nisplus_getpwnam_r (const char *name, struct passwd *pw,
 
 enum nss_status
 _nss_nisplus_getpwuid_r (const uid_t uid, struct passwd *pw,
-                    char *buffer, size_t buflen)
+                        char *buffer, size_t buflen, int *errnop)
 {
   if (tablename_val == NULL)
-    if (_nss_create_tablename () != NSS_STATUS_SUCCESS)
-      return NSS_STATUS_UNAVAIL;
+    {
+      enum nss_status status = _nss_create_tablename (errnop);
+
+      if (status != NSS_STATUS_SUCCESS)
+       return status;
+    }
+
   {
     int parse_res;
     nis_result *result;
     char buf[100 + tablename_len];
 
-    sprintf(buf, "[uid=%d],%s", uid, tablename_val);
+    sprintf (buf, "[uid=%d],%s", uid, tablename_val);
 
     result = nis_list(buf, FOLLOW_PATH | FOLLOW_LINKS, NULL, NULL);
 
@@ -220,12 +245,15 @@ _nss_nisplus_getpwuid_r (const uid_t uid, struct passwd *pw,
        return status;
       }
 
-    parse_res = _nss_nisplus_parse_pwent (result, pw, buffer, buflen);
+    parse_res = _nss_nisplus_parse_pwent (result, pw, buffer, buflen, errnop);
 
     nis_freeresult (result);
 
     if (parse_res == -1)
-      return NSS_STATUS_TRYAGAIN;
+      {
+       *errnop = ERANGE;
+       return NSS_STATUS_TRYAGAIN;
+      }
 
     if (parse_res)
       return NSS_STATUS_SUCCESS;
index 77a7248305ee605fd13a6b609a1e1a4f8c908cda..452fb4cc5e368ec5754373fa4e78318bcc1903a7 100644 (file)
@@ -41,7 +41,7 @@ static u_long tablename_len = 0;
 
 static int
 _nss_nisplus_parse_rpcent (nis_result *result, struct rpcent *rpc,
-                          char *buffer, size_t buflen)
+                          char *buffer, size_t buflen, int *errnop)
 {
   char *first_unused = buffer;
   size_t room_left = buflen;
@@ -52,25 +52,25 @@ _nss_nisplus_parse_rpcent (nis_result *result, struct rpcent *rpc,
   if (result == NULL)
     return 0;
 
-  if ((result->status != NIS_SUCCESS && result->status != NIS_S_SUCCESS) ||
-      __type_of (result->objects.objects_val) != NIS_ENTRY_OBJ ||
-      strcmp(result->objects.objects_val[0].EN_data.en_type,
-             "rpc_tbl") != 0 ||
-      result->objects.objects_val[0].EN_data.en_cols.en_cols_len < 3)
+  if ((result->status != NIS_SUCCESS && result->status != NIS_S_SUCCESS)
+      || __type_of (result->objects.objects_val) != NIS_ENTRY_OBJ
+      || strcmp (result->objects.objects_val[0].EN_data.en_type,
+                "rpc_tbl") != 0
+      || result->objects.objects_val[0].EN_data.en_cols.en_cols_len < 3)
     return 0;
 
   if (NISENTRYLEN (0, 0, result) >= room_left)
     {
     no_more_room:
-      __set_errno (ERANGE);
+      *errnop = ERANGE;
       return -1;
     }
   strncpy (first_unused, NISENTRYVAL (0, 0, result),
            NISENTRYLEN (0, 0, result));
   first_unused[NISENTRYLEN (0, 0, result)] = '\0';
   rpc->r_name = first_unused;
-  room_left -= (strlen (first_unused) +1);
-  first_unused += strlen (first_unused) +1;
+  room_left -= strlen (first_unused) + 1;
+  first_unused += strlen (first_unused) + 1;
   rpc->r_number = atoi (NISENTRYVAL (0, 2, result));
   p = first_unused;
 
@@ -98,7 +98,7 @@ _nss_nisplus_parse_rpcent (nis_result *result, struct rpcent *rpc,
   rpc->r_aliases = (char **) first_unused;
   if (room_left < sizeof (char *))
     goto no_more_room;
-  room_left -= (sizeof (char *));
+  room_left -= sizeof (char *);
   rpc->r_aliases[0] = NULL;
 
   i = 0;
@@ -137,7 +137,7 @@ _nss_nisplus_parse_rpcent (nis_result *result, struct rpcent *rpc,
 }
 
 static enum nss_status
-_nss_create_tablename (void)
+_nss_create_tablename (int *errnop)
 {
   if (tablename_val == NULL)
     {
@@ -148,7 +148,10 @@ _nss_create_tablename (void)
       p = __stpcpy (p, nis_local_directory ());
       tablename_val = __strdup (buf);
       if (tablename_val == NULL)
-        return NSS_STATUS_TRYAGAIN;
+       {
+         *errnop = errno;
+         return NSS_STATUS_TRYAGAIN;
+       }
       tablename_len = strlen (tablename_val);
     }
   return NSS_STATUS_SUCCESS;
@@ -159,6 +162,7 @@ enum nss_status
 _nss_nisplus_setrpcent (void)
 {
   enum nss_status status = NSS_STATUS_SUCCESS;
+  int err;
 
   __libc_lock_lock (lock);
 
@@ -167,7 +171,7 @@ _nss_nisplus_setrpcent (void)
   result = NULL;
 
   if (tablename_val == NULL)
-    status = _nss_create_tablename ();
+    status = _nss_create_tablename (&err);
 
   __libc_lock_unlock (lock);
 
@@ -190,7 +194,7 @@ _nss_nisplus_endrpcent (void)
 
 static enum nss_status
 internal_nisplus_getrpcent_r (struct rpcent *rpc, char *buffer,
-                             size_t buflen)
+                             size_t buflen, int *errnop)
 {
   int parse_res;
 
@@ -203,10 +207,14 @@ internal_nisplus_getrpcent_r (struct rpcent *rpc, char *buffer,
        {
          saved_res = NULL;
           if (tablename_val == NULL)
-            if (_nss_create_tablename () != NSS_STATUS_SUCCESS)
-              return NSS_STATUS_UNAVAIL;
+           {
+             enum nss_status status =  _nss_create_tablename (errnop);
+
+             if (status != NSS_STATUS_SUCCESS)
+               return status;
+           }
 
-         result = nis_first_entry(tablename_val);
+         result = nis_first_entry (tablename_val);
          if (niserr2nss (result->status) != NSS_STATUS_SUCCESS)
            return niserr2nss (result->status);
        }
@@ -224,11 +232,13 @@ internal_nisplus_getrpcent_r (struct rpcent *rpc, char *buffer,
            }
        }
 
-      if ((parse_res = _nss_nisplus_parse_rpcent (result, rpc, buffer,
-                                                 buflen)) == -1)
+      parse_res = _nss_nisplus_parse_rpcent (result, rpc, buffer,
+                                            buflen, errnop);
+      if (parse_res == -1)
        {
          nis_freeresult (result);
          result = saved_res;
+         *errnop = ERANGE;
          return NSS_STATUS_TRYAGAIN;
        }
       else
@@ -243,13 +253,13 @@ internal_nisplus_getrpcent_r (struct rpcent *rpc, char *buffer,
 
 enum nss_status
 _nss_nisplus_getrpcent_r (struct rpcent *result, char *buffer,
-                         size_t buflen)
+                         size_t buflen, int *errnop)
 {
   int status;
 
   __libc_lock_lock (lock);
 
-  status = internal_nisplus_getrpcent_r (result, buffer, buflen);
+  status = internal_nisplus_getrpcent_r (result, buffer, buflen, errnop);
 
   __libc_lock_unlock (lock);
 
@@ -258,13 +268,17 @@ _nss_nisplus_getrpcent_r (struct rpcent *result, char *buffer,
 
 enum nss_status
 _nss_nisplus_getrpcbyname_r (const char *name, struct rpcent *rpc,
-                            char *buffer, size_t buflen)
+                            char *buffer, size_t buflen, int *errnop)
 {
   int parse_res;
 
   if (tablename_val == NULL)
-    if (_nss_create_tablename () != NSS_STATUS_SUCCESS)
-      return NSS_STATUS_UNAVAIL;
+    {
+      enum nss_status status = _nss_create_tablename (errnop);
+
+      if (status != NSS_STATUS_SUCCESS)
+       return status;
+    }
 
   if (name == NULL)
     return NSS_STATUS_NOTFOUND;
@@ -280,19 +294,18 @@ _nss_nisplus_getrpcbyname_r (const char *name, struct rpcent *rpc,
 
       /* If we do not find it, try it as original name. But if the
          database is correct, we should find it in the first case, too */
-      if ((result->status != NIS_SUCCESS &&
-           result->status != NIS_S_SUCCESS) ||
-          __type_of (result->objects.objects_val) != NIS_ENTRY_OBJ ||
-          strcmp (result->objects.objects_val->EN_data.en_type,
-                 "rpc_tbl") != 0 ||
-          result->objects.objects_val->EN_data.en_cols.en_cols_len < 3)
+      if ((result->status != NIS_SUCCESS && result->status != NIS_S_SUCCESS)
+         || __type_of (result->objects.objects_val) != NIS_ENTRY_OBJ
+         || strcmp (result->objects.objects_val->EN_data.en_type,
+                    "rpc_tbl") != 0
+         || result->objects.objects_val->EN_data.en_cols.en_cols_len < 3)
         sprintf (buf, "[cname=%s],%s", name, tablename_val);
       else
-        sprintf (buf, "[cname=%s],%s", NISENTRYVAL(0, 0, result),
+        sprintf (buf, "[cname=%s],%s", NISENTRYVAL (0, 0, result),
                 tablename_val);
 
       nis_freeresult (result);
-      result = nis_list(buf, FOLLOW_PATH | FOLLOW_LINKS , NULL, NULL);
+      result = nis_list (buf, FOLLOW_PATH | FOLLOW_LINKS , NULL, NULL);
 
       if (niserr2nss (result->status) != NSS_STATUS_SUCCESS)
        {
@@ -302,12 +315,16 @@ _nss_nisplus_getrpcbyname_r (const char *name, struct rpcent *rpc,
          return status;
        }
 
-      parse_res = _nss_nisplus_parse_rpcent (result, rpc, buffer, buflen);
+      parse_res = _nss_nisplus_parse_rpcent (result, rpc, buffer, buflen,
+                                            errnop);
 
       nis_freeresult (result);
 
       if (parse_res == -1)
-       return NSS_STATUS_TRYAGAIN;
+       {
+         *errnop = ERANGE;
+         return NSS_STATUS_TRYAGAIN;
+       }
 
       if (parse_res)
        return NSS_STATUS_SUCCESS;
@@ -318,11 +335,15 @@ _nss_nisplus_getrpcbyname_r (const char *name, struct rpcent *rpc,
 
 enum nss_status
 _nss_nisplus_getrpcbynumber_r (const int number, struct rpcent *rpc,
-                               char *buffer, size_t buflen)
+                              char *buffer, size_t buflen, int *errnop)
 {
   if (tablename_val == NULL)
-    if (_nss_create_tablename () != NSS_STATUS_SUCCESS)
-      return NSS_STATUS_UNAVAIL;
+    {
+      enum nss_status status = _nss_create_tablename (errnop);
+
+      if (status != NSS_STATUS_SUCCESS)
+       return status;
+    }
 
   {
     int parse_res;
@@ -341,12 +362,16 @@ _nss_nisplus_getrpcbynumber_r (const int number, struct rpcent *rpc,
        return status;
       }
 
-    parse_res = _nss_nisplus_parse_rpcent (result, rpc, buffer, buflen);
+    parse_res = _nss_nisplus_parse_rpcent (result, rpc, buffer, buflen,
+                                          errnop);
 
     nis_freeresult (result);
 
     if (parse_res == -1)
-      return NSS_STATUS_TRYAGAIN;
+      {
+       *errnop = ERANGE;
+       return NSS_STATUS_TRYAGAIN;
+      }
 
     if (parse_res)
       return NSS_STATUS_SUCCESS;
index 95a8cfa74bf088816ec18ace509e8e1e543a2242..1cb1aec8d7478dbbba61b5590bcd65acd7042b9a 100644 (file)
@@ -41,7 +41,7 @@ static u_long tablename_len = 0;
 
 static int
 _nss_nisplus_parse_servent (nis_result *result, struct servent *serv,
-                           char *buffer, size_t buflen)
+                           char *buffer, size_t buflen, int *errnop)
 {
   char *first_unused = buffer;
   size_t room_left = buflen;
@@ -51,17 +51,17 @@ _nss_nisplus_parse_servent (nis_result *result, struct servent *serv,
   if (result == NULL)
     return 0;
 
-  if ((result->status != NIS_SUCCESS && result->status != NIS_S_SUCCESS) ||
-      __type_of (result->objects.objects_val) != NIS_ENTRY_OBJ ||
-      strcmp (result->objects.objects_val->EN_data.en_type,
-             "services_tbl") != 0 ||
-      result->objects.objects_val->EN_data.en_cols.en_cols_len < 4)
+  if ((result->status != NIS_SUCCESS && result->status != NIS_S_SUCCESS)
+      || __type_of (result->objects.objects_val) != NIS_ENTRY_OBJ
+      || strcmp (result->objects.objects_val->EN_data.en_type,
+                "services_tbl") != 0
+      || result->objects.objects_val->EN_data.en_cols.en_cols_len < 4)
     return 0;
 
   if (NISENTRYLEN (0, 0, result) >= room_left)
     {
     no_more_room:
-      __set_errno (ERANGE);
+      *errnop = ERANGE;
       return -1;
     }
   strncpy (first_unused, NISENTRYVAL (0, 0, result),
@@ -77,8 +77,8 @@ _nss_nisplus_parse_servent (nis_result *result, struct servent *serv,
            NISENTRYLEN (0, 2, result));
   first_unused[NISENTRYLEN (0, 2, result)] = '\0';
   serv->s_proto = first_unused;
-  room_left -= (strlen (first_unused) +1);
-  first_unused += strlen (first_unused) +1;
+  room_left -= strlen (first_unused) + 1;
+  first_unused += strlen (first_unused) + 1;
 
   serv->s_port = atoi (NISENTRYVAL (0, 3, result));
   p = first_unused;
@@ -143,7 +143,7 @@ _nss_nisplus_parse_servent (nis_result *result, struct servent *serv,
 }
 
 static enum nss_status
-_nss_create_tablename (void)
+_nss_create_tablename (int *errnop)
 {
   if (tablename_val == NULL)
     {
@@ -154,7 +154,10 @@ _nss_create_tablename (void)
       p = __stpcpy (p, nis_local_directory ());
       tablename_val = __strdup (buf);
       if (tablename_val == NULL)
-        return NSS_STATUS_TRYAGAIN;
+       {
+         *errnop = errno;
+         return NSS_STATUS_TRYAGAIN;
+       }
       tablename_len = strlen (tablename_val);
     }
   return NSS_STATUS_SUCCESS;
@@ -165,6 +168,7 @@ enum nss_status
 _nss_nisplus_setservent (void)
 {
   enum nss_status status = NSS_STATUS_SUCCESS;
+  int err;
 
   __libc_lock_lock (lock);
 
@@ -173,7 +177,7 @@ _nss_nisplus_setservent (void)
   result = NULL;
 
   if (tablename_val == NULL)
-    status = _nss_create_tablename ();
+    status = _nss_create_tablename (&err);
 
   __libc_lock_unlock (lock);
 
@@ -196,7 +200,7 @@ _nss_nisplus_endservent (void)
 
 static enum nss_status
 internal_nisplus_getservent_r (struct servent *serv, char *buffer,
-                              size_t buflen)
+                              size_t buflen, int *errnop)
 {
   int parse_res;
 
@@ -209,8 +213,12 @@ internal_nisplus_getservent_r (struct servent *serv, char *buffer,
        {
          saved_res = NULL;
           if (tablename_val == NULL)
-            if (_nss_create_tablename () != NSS_STATUS_SUCCESS)
-              return NSS_STATUS_UNAVAIL;
+           {
+             enum nss_status status = _nss_create_tablename (errnop);
+
+             if (status != NSS_STATUS_SUCCESS)
+               return status;
+           }
 
          result = nis_first_entry (tablename_val);
          if (niserr2nss (result->status) != NSS_STATUS_SUCCESS)
@@ -230,11 +238,13 @@ internal_nisplus_getservent_r (struct servent *serv, char *buffer,
            }
        }
 
-      if ((parse_res = _nss_nisplus_parse_servent (result, serv, buffer,
-                                                  buflen)) == -1)
+      parse_res = _nss_nisplus_parse_servent (result, serv, buffer,
+                                             buflen, errnop);
+      if (parse_res == -1)
        {
          nis_freeresult (result);
          result = saved_res;
+         *errnop = ERANGE;
          return NSS_STATUS_TRYAGAIN;
        }
       else
@@ -250,13 +260,13 @@ internal_nisplus_getservent_r (struct servent *serv, char *buffer,
 
 enum nss_status
 _nss_nisplus_getservent_r (struct servent *result, char *buffer,
-                          size_t buflen)
+                          size_t buflen, int *errnop)
 {
   int status;
 
   __libc_lock_lock (lock);
 
-  status = internal_nisplus_getservent_r (result, buffer, buflen);
+  status = internal_nisplus_getservent_r (result, buffer, buflen, errnop);
 
   __libc_lock_unlock (lock);
 
@@ -266,17 +276,21 @@ _nss_nisplus_getservent_r (struct servent *result, char *buffer,
 enum nss_status
 _nss_nisplus_getservbyname_r (const char *name, const char *protocol,
                              struct servent *serv,
-                             char *buffer, size_t buflen)
+                             char *buffer, size_t buflen, int *errnop)
 {
   int parse_res;
 
   if (tablename_val == NULL)
-    if (_nss_create_tablename () != NSS_STATUS_SUCCESS)
-      return NSS_STATUS_UNAVAIL;
+    {
+      enum nss_status status = _nss_create_tablename (errnop);
+
+      if (status != NSS_STATUS_SUCCESS)
+       return status;
+    }
 
   if (name == NULL || protocol == NULL)
     {
-      __set_errno (EINVAL);
+      *errnop = EINVAL;
       return NSS_STATUS_NOTFOUND;
     }
   else
@@ -292,12 +306,11 @@ _nss_nisplus_getservbyname_r (const char *name, const char *protocol,
 
       /* If we do not find it, try it as original name. But if the
          database is correct, we should find it in the first case, too */
-      if ((result->status != NIS_SUCCESS &&
-          result->status != NIS_S_SUCCESS) ||
-         __type_of (result->objects.objects_val) != NIS_ENTRY_OBJ ||
-         strcmp (result->objects.objects_val->EN_data.en_type,
-                 "services_tbl") != 0 ||
-         result->objects.objects_val->EN_data.en_cols.en_cols_len < 4)
+      if ((result->status != NIS_SUCCESS && result->status != NIS_S_SUCCESS)
+         || __type_of (result->objects.objects_val) != NIS_ENTRY_OBJ
+         || strcmp (result->objects.objects_val->EN_data.en_type,
+                    "services_tbl") != 0
+         || result->objects.objects_val->EN_data.en_cols.en_cols_len < 4)
        sprintf (buf, "[cname=%s,proto=%s],%s", name, protocol,
                 tablename_val);
       else
@@ -315,11 +328,15 @@ _nss_nisplus_getservbyname_r (const char *name, const char *protocol,
          return status;
        }
 
-      parse_res = _nss_nisplus_parse_servent (result, serv, buffer, buflen);
+      parse_res = _nss_nisplus_parse_servent (result, serv, buffer, buflen,
+                                             errnop);
       nis_freeresult (result);
 
       if (parse_res == -1)
-       return NSS_STATUS_TRYAGAIN;
+       {
+         *errnop = ERANGE;
+         return NSS_STATUS_TRYAGAIN;
+       }
 
       if (parse_res)
        return NSS_STATUS_SUCCESS;
@@ -331,15 +348,19 @@ _nss_nisplus_getservbyname_r (const char *name, const char *protocol,
 enum nss_status
 _nss_nisplus_getservbynumber_r (const int number, const char *protocol,
                                struct servent *serv,
-                               char *buffer, size_t buflen)
+                               char *buffer, size_t buflen, int *errnop)
 {
   if (tablename_val == NULL)
-    if (_nss_create_tablename () != NSS_STATUS_SUCCESS)
-      return NSS_STATUS_UNAVAIL;
+    {
+      enum nss_status status = _nss_create_tablename (errnop);
+
+      if (status != NSS_STATUS_SUCCESS)
+       return status;
+    }
 
   if (protocol == NULL)
     {
-      __set_errno (EINVAL);
+      *errnop = EINVAL;
       return NSS_STATUS_NOTFOUND;
     }
   else
@@ -361,11 +382,15 @@ _nss_nisplus_getservbynumber_r (const int number, const char *protocol,
          return status;
        }
 
-      parse_res = _nss_nisplus_parse_servent (result, serv, buffer, buflen);
+      parse_res = _nss_nisplus_parse_servent (result, serv, buffer, buflen,
+                                             errnop);
       nis_freeresult (result);
 
       if (parse_res == -1)
-       return NSS_STATUS_TRYAGAIN;
+       {
+         *errnop = ERANGE;
+         return NSS_STATUS_TRYAGAIN;
+       }
 
       if (parse_res)
        return NSS_STATUS_SUCCESS;
index 1b3f68325e25e0105e8a5490d821747704e88e9d..54bbc32f3ca380d622082907d7deb8de8d8d7264 100644 (file)
@@ -34,7 +34,7 @@ static nis_name tablename_val = NULL;
 static u_long tablename_len = 0;
 
 static enum nss_status
-_nss_create_tablename (void)
+_nss_create_tablename (int *errnop)
 {
   if (tablename_val == NULL)
     {
@@ -45,7 +45,10 @@ _nss_create_tablename (void)
       p = __stpcpy (p, nis_local_directory ());
       tablename_val = __strdup (buf);
       if (tablename_val == NULL)
-        return NSS_STATUS_TRYAGAIN;
+       {
+         *errnop = errno;
+         return NSS_STATUS_TRYAGAIN;
+       }
       tablename_len = strlen (tablename_val);
     }
   return NSS_STATUS_SUCCESS;
@@ -55,6 +58,7 @@ enum nss_status
 _nss_nisplus_setspent (void)
 {
   enum nss_status status = NSS_STATUS_SUCCESS;
+  int err;
 
   __libc_lock_lock (lock);
 
@@ -63,7 +67,7 @@ _nss_nisplus_setspent (void)
   result = NULL;
 
   if (tablename_val == NULL)
-    status = _nss_create_tablename ();
+    status = _nss_create_tablename (&err);
 
   __libc_lock_unlock (lock);
 
@@ -85,7 +89,8 @@ _nss_nisplus_endspent (void)
 }
 
 static enum nss_status
-internal_nisplus_getspent_r (struct spwd *sp, char *buffer, size_t buflen)
+internal_nisplus_getspent_r (struct spwd *sp, char *buffer, size_t buflen,
+                            int *errnop)
 {
   int parse_res;
 
@@ -99,8 +104,12 @@ internal_nisplus_getspent_r (struct spwd *sp, char *buffer, size_t buflen)
          saved_res = NULL;
 
           if (tablename_val == NULL)
-            if (_nss_create_tablename () != NSS_STATUS_SUCCESS)
-              return NSS_STATUS_UNAVAIL;
+           {
+             enum nss_status status = _nss_create_tablename (errnop);
+
+             if (status != NSS_STATUS_SUCCESS)
+               return status;
+           }
 
          result = nis_first_entry (tablename_val);
          if (niserr2nss (result->status) != NSS_STATUS_SUCCESS)
@@ -120,11 +129,13 @@ internal_nisplus_getspent_r (struct spwd *sp, char *buffer, size_t buflen)
            }
        }
 
-      if ((parse_res = _nss_nisplus_parse_spent (result, sp, buffer,
-                                                buflen)) == -1)
+      parse_res = _nss_nisplus_parse_spent (result, sp, buffer,
+                                           buflen, errnop);
+      if (parse_res == -1)
        {
          nis_freeresult (result);
          result = saved_res;
+         *errnop = ERANGE;
          return NSS_STATUS_TRYAGAIN;
        }
       else
@@ -138,13 +149,14 @@ internal_nisplus_getspent_r (struct spwd *sp, char *buffer, size_t buflen)
 }
 
 enum nss_status
-_nss_nisplus_getspent_r (struct spwd *result, char *buffer, size_t buflen)
+_nss_nisplus_getspent_r (struct spwd *result, char *buffer, size_t buflen,
+                        int *errnop)
 {
   int status;
 
   __libc_lock_lock (lock);
 
-  status = internal_nisplus_getspent_r (result, buffer, buflen);
+  status = internal_nisplus_getspent_r (result, buffer, buflen, errnop);
 
   __libc_lock_unlock (lock);
 
@@ -153,13 +165,17 @@ _nss_nisplus_getspent_r (struct spwd *result, char *buffer, size_t buflen)
 
 enum nss_status
 _nss_nisplus_getspnam_r (const char *name, struct spwd *sp,
-                    char *buffer, size_t buflen)
+                    char *buffer, size_t buflen, int *errnop)
 {
   int parse_res;
 
   if (tablename_val == NULL)
-    if (_nss_create_tablename () != NSS_STATUS_SUCCESS)
-      return NSS_STATUS_UNAVAIL;
+    {
+      enum nss_status status = _nss_create_tablename (errnop);
+
+      if (status != NSS_STATUS_SUCCESS)
+       return status;
+    }
 
   if (name == NULL || strlen (name) > 8)
     return NSS_STATUS_NOTFOUND;
@@ -180,11 +196,15 @@ _nss_nisplus_getspnam_r (const char *name, struct spwd *sp,
          return status;
        }
 
-      parse_res = _nss_nisplus_parse_spent (result, sp, buffer, buflen);
+      parse_res = _nss_nisplus_parse_spent (result, sp, buffer, buflen,
+                                           errnop);
       nis_freeresult (result);
 
       if (parse_res == -1)
-       return NSS_STATUS_TRYAGAIN;
+       {
+         *errnop = ERANGE;
+         return NSS_STATUS_TRYAGAIN;
+       }
 
       if (parse_res)
        return NSS_STATUS_SUCCESS;
index 18f0bae03aa4a7924ab4df5a73f32e753c4af75c..47df01054eb1ee288df10c5e2ad5f52c144b20a3 100644 (file)
@@ -17,6 +17,7 @@
    write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
    Boston, MA 02111-1307, USA.  */
 
+#include <errno.h>
 #include "nsswitch.h"
 
 /*******************************************************************\
@@ -71,8 +72,8 @@
 
 
 /* Type of the lookup function we need here.  */
-typedef int (*lookup_function) (ADD_PARAMS, LOOKUP_TYPE *, char *, size_t
-                               H_ERRNO_PARM);
+typedef int (*lookup_function) (ADD_PARAMS, LOOKUP_TYPE *, char *, size_t,
+                               int * H_ERRNO_PARM);
 
 /* Some usages of this file might use this variable.  */
 extern struct __res_state _res;
@@ -129,7 +130,8 @@ INTERNAL (REENTRANT_NAME) (ADD_PARAMS, LOOKUP_TYPE *resbuf, char *buffer,
 
   while (no_more == 0)
     {
-      status = (*fct) (ADD_VARIABLES, resbuf, buffer, buflen H_ERRNO_VAR);
+      status = (*fct) (ADD_VARIABLES, resbuf, buffer, buflen,
+                      __errno_location () H_ERRNO_VAR);
 
       no_more = __nss_next (&nip, REENTRANT_NAME_STRING,
                            (void **) &fct, status, 0);
index f2cca259f085e25467ce00f296058db34b74f3f2..1884b0773d37d129acf8f19ce14abd518ffdbf1e 100644 (file)
@@ -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.
 
@@ -17,6 +17,7 @@
    write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
    Boston, MA 02111-1307, USA.  */
 
+#include <errno.h>
 #include <bits/libc-lock.h>
 
 #include "nsswitch.h"
@@ -90,7 +91,8 @@ typedef int (*set_function) (STAYOPEN);
 typedef int (*end_function) (void);
 
 /* Prototype for the setXXXent functions we use here.  */
-typedef int (*get_function) (LOOKUP_TYPE *, char *, size_t H_ERRNO_PARM);
+typedef int (*get_function) (LOOKUP_TYPE *, char *, size_t, int *
+                            H_ERRNO_PARM);
 
 
 /* This handle for the NSS data base is shared between all
@@ -244,7 +246,8 @@ INTERNAL (REENTRANT_GETNAME) (LOOKUP_TYPE *resbuf, char *buffer, size_t buflen,
       int is_last_nip = nip == last_nip;
       service_user *current_nip = nip;
 
-      status = (*fct) (resbuf, buffer, buflen H_ERRNO_VAR);
+      status = (*fct) (resbuf, buffer, buflen, __errno_location ()
+                      H_ERRNO_VAR);
 
       no_more = __nss_next (&nip, GETFUNC_NAME_STRING, (void **) &fct,
                            status, 0);
index 2f781bf3d9318dd7c91ca4a6d73ff5c75bbc0a8d..4d20cae79772f0065907881f8084dfbab68cb827 100644 (file)
@@ -147,9 +147,10 @@ CONCAT(_nss_db_end,ENTNAME) (void)
 /* Do a database lookup for KEY.  */
 static enum nss_status
 lookup (const DBT *key, struct STRUCTURE *result,
-       void *buffer, int buflen H_ERRNO_PROTO)
+       void *buffer, size_t buflen, int *errnop H_ERRNO_PROTO)
 {
   enum nss_status status;
+  int err;
   DBT value;
 
   /* Open the database.  */
@@ -158,9 +159,12 @@ lookup (const DBT *key, struct STRUCTURE *result,
     return status;
 
   /* Succeed iff it matches a value that parses correctly.  */
-  status = (((*db->get) (db, key, &value, 0) == 0 &&
-            parse_line (value.data, result, buffer, buflen))
-           ? NSS_STATUS_SUCCESS : NSS_STATUS_NOTFOUND);
+  err = ((*db->get) (db, key, &value, 0) == 0 &&
+        parse_line (value.data, result, buffer, buflen, errnop));
+  if (err == 0)
+    status = NSS_STATUS_SUCCESS;
+  else
+    status = err < 0 ? NSS_STATUS_TRYAGAIN : NSS_STATUS_NOTFOUND;
 
   if (! keep_db)
     internal_endent ();
@@ -188,7 +192,7 @@ lookup (const DBT *key, struct STRUCTURE *result,
 enum nss_status                                                                      \
 _nss_db_get##name##_r (proto,                                                \
                       struct STRUCTURE *result,                              \
-                      char *buffer, size_t buflen H_ERRNO_PROTO)             \
+                      char *buffer, size_t buflen, int *errnop H_ERRNO_PROTO)\
 {                                                                            \
   DBT key;                                                                   \
   enum nss_status status;                                                    \
@@ -196,7 +200,7 @@ _nss_db_get##name##_r (proto,                                                     \
   key.data = __alloca (size);                                                \
   key.size = KEYPRINTF keypattern;                                           \
   __libc_lock_lock (lock);                                                   \
-  status = lookup (&key, result, buffer, buflen H_ERRNO_ARG);                \
+  status = lookup (&key, result, buffer, buflen, errnop H_ERRNO_ARG);        \
   __libc_lock_unlock (lock);                                                 \
   return status;                                                             \
 }
@@ -208,8 +212,8 @@ _nss_db_get##name##_r (proto,                                                     \
 
 /* Return the next entry from the database file, doing locking.  */
 enum nss_status
-CONCAT(_nss_db_get,ENTNAME_r) (struct STRUCTURE *result,
-                              char *buffer, size_t buflen H_ERRNO_PROTO)
+CONCAT(_nss_db_get,ENTNAME_r) (struct STRUCTURE *result, char *buffer,
+                              size_t buflen, int *errnop H_ERRNO_PROTO)
 {
   /* Return next entry in host file.  */
   enum nss_status status;
@@ -218,7 +222,7 @@ CONCAT(_nss_db_get,ENTNAME_r) (struct STRUCTURE *result,
 
   __libc_lock_lock (lock);
   key.size = 1 + snprintf (key.data = buf, sizeof buf, "0%u", entidx++);
-  status = lookup (&key, result, buffer, buflen H_ERRNO_ARG);
+  status = lookup (&key, result, buffer, buflen, errnop H_ERRNO_ARG);
   __libc_lock_unlock (lock);
 
   return status;
index 32ba4b5f4f8fc5b445f00e19657513e6ae445c28..0e72b92ceb609b049ed6893b0a0f0d261fe89554 100644 (file)
@@ -134,7 +134,7 @@ _nss_db_endaliasent (void)
    the result.  */
 static enum nss_status
 lookup (const DBT *key, struct aliasent *result, char *buffer,
-           size_t buflen)
+       size_t buflen, int *errnop)
 {
   enum nss_status status;
   DBT value;
@@ -154,7 +154,7 @@ lookup (const DBT *key, struct aliasent *result, char *buffer,
       if (buflen < key->size + 1)
        {
        no_more_room:
-         __set_errno (ERANGE);
+         *errnop = ERANGE;
          return NSS_STATUS_TRYAGAIN;
        }
 
@@ -218,7 +218,8 @@ lookup (const DBT *key, struct aliasent *result, char *buffer,
 }
 \f
 enum nss_status
-_nss_db_getaliasent_r (struct aliasent *result, char *buffer, size_t buflen)
+_nss_db_getaliasent_r (struct aliasent *result, char *buffer, size_t buflen,
+                      int *errnop)
 {
   /* Return next entry in host file.  */
   enum nss_status status;
@@ -227,7 +228,7 @@ _nss_db_getaliasent_r (struct aliasent *result, char *buffer, size_t buflen)
 
   __libc_lock_lock (lock);
   key.size = 1 + snprintf (key.data = buf, sizeof buf, "0%u", entidx++);
-  status = lookup (&key, result, buffer, buflen);
+  status = lookup (&key, result, buffer, buflen, errnop);
   __libc_lock_unlock (lock);
 
   return status;
@@ -236,7 +237,7 @@ _nss_db_getaliasent_r (struct aliasent *result, char *buffer, size_t buflen)
 
 enum nss_status
 _nss_db_getaliasbyname_r (const char *name, struct aliasent *result,
-                         char *buffer, size_t buflen)
+                         char *buffer, size_t buflen, int *errnop)
 {
   DBT key;
   enum nss_status status;
@@ -248,7 +249,7 @@ _nss_db_getaliasbyname_r (const char *name, struct aliasent *result,
   memcpy (&((char *) key.data)[1], name, key.size - 1);
 
   __libc_lock_lock (lock);
-  status = lookup (&key, result, buffer, buflen);
+  status = lookup (&key, result, buffer, buflen, errnop);
   __libc_lock_unlock (lock);
 
   return status;
index 4691c0fb9b82ce7aef3809fb15f569cd6cfd5078..d63d1cb1af4970d830d842f4941018d44b09db47 100644 (file)
@@ -112,16 +112,18 @@ _nss_db_endnetgrent (void)
 
 extern enum nss_status _nss_netgroup_parseline (char **cursor,
                                                struct __netgrent *result,
-                                               char *buffer, int buflen);
+                                               char *buffer, size_t buflen,
+                                               int *errnop);
 
 enum nss_status
-_nss_db_getnetgrent_r (struct __netgrent *result, char *buffer, int buflen)
+_nss_db_getnetgrent_r (struct __netgrent *result, char *buffer, size_t buflen,
+                      int *errnop)
 {
   int status;
 
   __libc_lock_lock (lock);
 
-  status = _nss_netgroup_parseline (&cursor, result, buffer, buflen);
+  status = _nss_netgroup_parseline (&cursor, result, buffer, buflen, errnop);
 
   __libc_lock_unlock (lock);
 
index eb0f6fec8fcc84eda27e5b6b597decdab90c453b..e3261ed454da81109abc05b41e86ede12d019bbf 100644 (file)
@@ -162,7 +162,7 @@ CONCAT(_nss_files_end,ENTNAME) (void)
 
 static enum nss_status
 internal_getent (struct STRUCTURE *result,
-                char *buffer, int buflen H_ERRNO_PROTO)
+                char *buffer, int buflen, int *errnop H_ERRNO_PROTO)
 {
   char *p;
   struct parser_data *data = (void *) buffer;
@@ -171,7 +171,7 @@ internal_getent (struct STRUCTURE *result,
 
   if (buflen < (int) sizeof *data + 1)
     {
-      __set_errno (ERANGE);
+      *errnop = ERANGE;
       H_ERRNO_SET (NETDB_INTERNAL);
       return NSS_STATUS_TRYAGAIN;
     }
@@ -185,6 +185,7 @@ internal_getent (struct STRUCTURE *result,
       if (p == NULL)
        {
          /* End of file or read error.  */
+         *errnop = errno;
          H_ERRNO_SET (HOST_NOT_FOUND);
          return NSS_STATUS_NOTFOUND;
        }
@@ -192,7 +193,7 @@ internal_getent (struct STRUCTURE *result,
        {
          /* The line is too long.  Give the user the opportunity to
             enlarge the buffer.  */
-         __set_errno (ERANGE);
+         *errnop = ERANGE;
          H_ERRNO_SET (NETDB_INTERNAL);
          return NSS_STATUS_TRYAGAIN;
        }
@@ -204,7 +205,7 @@ internal_getent (struct STRUCTURE *result,
   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_result = parse_line (p, result, data, buflen)));
+        || ! (parse_result = parse_line (p, result, data, buflen, errnop)));
 
   /* Filled in RESULT with the next entry from the database file.  */
   return parse_result == -1 ? NSS_STATUS_TRYAGAIN : NSS_STATUS_SUCCESS;
@@ -213,8 +214,8 @@ internal_getent (struct STRUCTURE *result,
 
 /* Return the next entry from the database file, doing locking.  */
 enum nss_status
-CONCAT(_nss_files_get,ENTNAME_r) (struct STRUCTURE *result,
-                                 char *buffer, size_t buflen H_ERRNO_PROTO)
+CONCAT(_nss_files_get,ENTNAME_r) (struct STRUCTURE *result, char *buffer,
+                                 size_t buflen, int *errnop H_ERRNO_PROTO)
 {
   /* Return next entry in host file.  */
   enum nss_status status = NSS_STATUS_SUCCESS;
@@ -237,7 +238,8 @@ CONCAT(_nss_files_get,ENTNAME_r) (struct STRUCTURE *result,
 
       if (status == NSS_STATUS_SUCCESS)
        {
-         status = internal_getent (result, buffer, buflen H_ERRNO_ARG);
+         status = internal_getent (result, buffer, buflen, errnop
+                                   H_ERRNO_ARG);
 
          /* Remember this position if we were successful.  If the
             operation failed we give the user a chance to repeat the
@@ -270,8 +272,8 @@ CONCAT(_nss_files_get,ENTNAME_r) (struct STRUCTURE *result,
 #define DB_LOOKUP(name, keysize, keypattern, break_if_match, proto...)       \
 enum nss_status                                                                      \
 _nss_files_get##name##_r (proto,                                             \
-                         struct STRUCTURE *result,                           \
-                         char *buffer, size_t buflen H_ERRNO_PROTO)          \
+                         struct STRUCTURE *result, char *buffer,             \
+                         size_t buflen, int *errnop H_ERRNO_PROTO)           \
 {                                                                            \
   enum nss_status status;                                                    \
                                                                              \
@@ -285,7 +287,8 @@ _nss_files_get##name##_r (proto,                                          \
       /* Tell getent function that we have repositioned the file pointer.  */ \
       last_use = getby;                                                              \
                                                                              \
-      while ((status = internal_getent (result, buffer, buflen H_ERRNO_ARG))  \
+      while ((status = internal_getent (result, buffer, buflen, errnop       \
+                                       H_ERRNO_ARG))                         \
             == NSS_STATUS_SUCCESS)                                           \
        { break_if_match }                                                    \
                                                                              \
index bf4fa8a2f09e222b002087cf38ac27dd14d84680..7eb22bb18778f4f3ec137f0eca5f941016ad6613 100644 (file)
@@ -131,7 +131,7 @@ _nss_files_endaliasent (void)
 /* Parsing the database file into `struct aliasent' data structures.  */
 static enum nss_status
 get_next_alias (const char *match, struct aliasent *result,
-               char *buffer, size_t buflen)
+               char *buffer, int *errnop, size_t buflen)
 {
   enum nss_status status = NSS_STATUS_NOTFOUND;
   int ignore = 0;
@@ -159,7 +159,7 @@ get_next_alias (const char *match, struct aliasent *result,
        {
          /* The line is too long for our buffer.  */
        no_more_room:
-         __set_errno (ERANGE);
+         *errnop = ERANGE;
          status = NSS_STATUS_TRYAGAIN;
          break;
        }
@@ -364,7 +364,8 @@ get_next_alias (const char *match, struct aliasent *result,
 
 
 enum nss_status
-_nss_files_getaliasent_r (struct aliasent *result, char *buffer, size_t buflen)
+_nss_files_getaliasent_r (struct aliasent *result, char *buffer, size_t buflen,
+                         int *errnop)
 {
   /* Return next entry in host file.  */
   enum nss_status status = NSS_STATUS_SUCCESS;
@@ -391,7 +392,7 @@ _nss_files_getaliasent_r (struct aliasent *result, char *buffer, size_t buflen)
 
          /* Read lines until we get a definite result.  */
          do
-           status = get_next_alias (NULL, result, buffer, buflen);
+           status = get_next_alias (NULL, result, buffer, buflen, errnop);
          while (status == NSS_STATUS_RETURN);
 
          /* If we successfully read an entry remember this position.  */
@@ -410,7 +411,7 @@ _nss_files_getaliasent_r (struct aliasent *result, char *buffer, size_t buflen)
 
 enum nss_status
 _nss_files_getaliasbyname_r (const char *name, struct aliasent *result,
-                            char *buffer, size_t buflen)
+                            char *buffer, size_t buflen, int *errnop)
 {
   /* Return next entry in host file.  */
   enum nss_status status = NSS_STATUS_SUCCESS;
@@ -433,7 +434,7 @@ _nss_files_getaliasbyname_r (const char *name, struct aliasent *result,
 
       /* Read lines until we get a definite result.  */
       do
-       status = get_next_alias (name, result, buffer, buflen);
+       status = get_next_alias (name, result, buffer, buflen, errnop);
       while (status == NSS_STATUS_RETURN);
     }
 
index 7552d4c3b1a7b04508638d0b8284e444376c9701..eb6e673ad09c79d0796b759f7c97efbc0b6148a9 100644 (file)
@@ -162,7 +162,7 @@ _nss_files_endnetgrent (struct __netgrent *result)
 
 enum nss_status
 _nss_netgroup_parseline (char **cursor, struct __netgrent *result,
-                        char *buffer, int buflen)
+                        char *buffer, size_t buflen, int *errnop)
 {
   enum nss_status status;
   const char *host, *user, *domain;
@@ -227,7 +227,7 @@ _nss_netgroup_parseline (char **cursor, struct __netgrent *result,
      to the private buffer we have to make sure it is big enough.  */
   if (cp - host > buflen)
     {
-      __set_errno (ERANGE);
+      *errnop = ERANGE;
       status = NSS_STATUS_UNAVAIL;
     }
   else
@@ -258,11 +258,13 @@ _nss_netgroup_parseline (char **cursor, struct __netgrent *result,
 
 
 enum nss_status
-_nss_files_getnetgrent_r (struct __netgrent *result, char *buffer, int buflen)
+_nss_files_getnetgrent_r (struct __netgrent *result, char *buffer,
+                         size_t buflen, int *errnop)
 {
   enum nss_status status;
 
-  status = _nss_netgroup_parseline (&result->cursor, result, buffer, buflen);
+  status = _nss_netgroup_parseline (&result->cursor, result, buffer, buflen,
+                                   errnop);
 
   return status;
 }
index acf673da9005f00b1e5b01fc896db3a158d50f62..76df1c6ff060eb7aa38a0fc43b853ef940f0cec1 100644 (file)
@@ -69,7 +69,7 @@ struct parser_data
 
 /* The parser is defined in a different module.  */
 extern int parse_line (char *line, struct STRUCTURE *result,
-                      struct parser_data *data, size_t datalen);
+                      struct parser_data *data, size_t datalen, int *errnop);
 
 # define LINE_PARSER(EOLSET, BODY) /* Do nothing */
 
@@ -80,7 +80,7 @@ extern int parse_line (char *line, struct STRUCTURE *result,
 # define LINE_PARSER(EOLSET, BODY)                                           \
 parser_stclass int                                                           \
 parse_line (char *line, struct STRUCTURE *result,                            \
-           struct parser_data *data, size_t datalen)                         \
+           struct parser_data *data, size_t datalen, int *errnop)            \
 {                                                                            \
   ENTDATA_DECL (data)                                                        \
   char *p = strpbrk (line, EOLSET "\n");                                     \
@@ -148,7 +148,7 @@ parse_line (char *line, struct STRUCTURE *result,                         \
 
 #  define TRAILING_LIST_PARSER                                               \
 {                                                                            \
-  char **list = parse_list (line, data, datalen);                            \
+  char **list = parse_list (line, data, datalen, errnop);                    \
   if (list)                                                                  \
     result->TRAILING_LIST_MEMBER = list;                                     \
   else                                                                               \
@@ -156,7 +156,7 @@ parse_line (char *line, struct STRUCTURE *result,                         \
 }
 
 static inline char **
-parse_list (char *line, struct parser_data *data, size_t datalen)
+parse_list (char *line, struct parser_data *data, size_t datalen, int *errnop)
 {
   char *eol, **list, **p;
 
@@ -183,7 +183,7 @@ parse_list (char *line, struct parser_data *data, size_t datalen)
       if ((size_t) ((char *) &p[1] - (char *) data) > datalen)
        {
          /* We cannot fit another pointer in the buffer.  */
-         __set_errno (ERANGE);
+         *errnop = ERANGE;
          return NULL;
        }
       if (*line == '\0')
index 4774885ecf7489b8c733b038794578a0ed501789..e931405ecb43e11d2ae4e1fbd6f921fe3a40cebc 100644 (file)
@@ -51,7 +51,7 @@ __BEGIN_DECLS
    allowed without complaint.  __WAIT_STATUS_DEFN is the type used in
    the actual function definitions.  */
 
-# if !defined __GNUC__ || __GNUC__ < 2
+# if !defined __GNUC__ || __GNUC__ < 2 || defined __cplusplus
 #  define __WAIT_STATUS                __ptr_t
 #  define __WAIT_STATUS_DEFN   __ptr_t
 # else
index 9bf33976756033265b5d99127a0b2c786fc4bbce..7699901177c48ffdae8132014c0f9e3970c3c940 100644 (file)
@@ -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
@@ -17,6 +17,7 @@
    Boston, MA 02111-1307, USA.  */
 
 #include <ctype.h>
+#include <errno.h>
 #include <stdio.h>
 #include <pwd.h>
 
@@ -27,7 +28,7 @@
 #define ENTNAME                pwent
 struct pwent_data {};
 
-#include "../nss/nss_files/files-parse.c"
+#include <nss/nss_files/files-parse.c>
 LINE_PARSER
 (,
  STRING_FIELD (result->pw_name, ISCOLON, 0);
@@ -86,7 +87,8 @@ __fgetpwent_r (FILE *stream, struct passwd *resbuf, char *buffer,
     } 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_line (p, resbuf, (void *) buffer, buflen,
+                          __errno_location ()));
 
   *result = resbuf;
   return 0;
index 4eb9dfcb7a6f3251f5e8450baf30fb28d1d89964..e0f03d78a05032fc8ececdf7a47c4c2cd1c24e06 100644 (file)
@@ -28,7 +28,8 @@ extra-libs-others := $(extra-libs)
 
 librt-routines := aio_cancel aio_error aio_fsync aio_misc aio_read     \
                  aio_read64 aio_return aio_suspend aio_write           \
-                 aio_write64 lio_listio lio_listio64 aio_sigqueue
+                 aio_write64 lio_listio lio_listio64 aio_sigqueue      \
+                 aio_notify
 
 librt-map := librt.map
 
index 561776c2d3909f708fda9f4c75c8089971a2f39e..a49b8c7a678b85e02e345c893af18cdec127bd6f 100644 (file)
--- a/rt/aio.h
+++ b/rt/aio.h
@@ -43,8 +43,6 @@ struct aiocb
   struct sigevent aio_sigevent;        /* Signal number and value.  */
 
   /* Internal members.  */
-  struct aiocb *__last_fd;
-  struct aiocb *__next_fd;
   struct aiocb *__next_prio;
   int __abs_prio;
   int __policy;
@@ -53,10 +51,11 @@ struct aiocb
 
 #ifndef __USE_FILE_OFFSET64
   __off_t aio_offset;          /* File offset.  */
+  char __pad[sizeof (__off64_t) - sizeof (__off_t)];
 #else
   __off64_t aio_offset;                /* File offset.  */
 #endif
-  int __unused[32];
+  char __unused[32];
 };
 
 /* The same for the 64bit offsets.  */
@@ -71,20 +70,33 @@ struct aiocb64
   struct sigevent aio_sigevent;        /* Signal number and value.  */
 
   /* Internal members.  */
-  struct aiocb64 *__last_fd;
-  struct aiocb64 *__next_fd;
-  struct aiocb64 *__next_prio;
   int __abs_prio;
   int __policy;
   int __error_code;
   __ssize_t __return_value;
 
   __off64_t aio_offset;                /* File offset.  */
-  int __unused[32];
+  char __unused[32];
 };
 #endif
 
 
+#ifdef __USE_GNU
+/* To customize the implementation one can use the following struct.
+   This implementation follows the one in Irix.  */
+struct aioinit
+  {
+    int aio_threads;           /* Maximal number of threads.  */
+    int aio_num;               /* Number of expected simultanious requests. */
+    int aio_locks;             /* Not used.  */
+    int aio_usedba;            /* Not used.  */
+    int aio_debug;             /* Not used.  */
+    int aio_numusers;          /* Not used.  */
+    int aio_reserved[2];
+  };
+#endif
+
+
 /* Return values of cancelation function.  */
 enum
 {
@@ -104,12 +116,8 @@ enum
 #define LIO_READ LIO_READ
   LIO_WRITE,
 #define LIO_WRITE LIO_WRITE
-  LIO_NOP,
+  LIO_NOP
 #define LIO_NOP LIO_NOP
-  __LIO_DSYNC,
-  __LIO_SYNC,
-  __LIO_READ64 = LIO_READ | 128,
-  __LIO_WRITE64 = LIO_WRITE | 128
 };
 
 
@@ -123,6 +131,13 @@ enum
 };
 
 
+/* Allow user to specify optimization.  */
+#ifdef __USE_GNU
+extern void __aio_init __P ((__const struct aioinit *__init));
+extern void aio_init __P ((__const struct aioinit *__init));
+#endif
+
+
 /* Enqueue read request for given number of bytes and the given priority.  */
 #ifndef __USE_FILE_OFFSET64
 extern int aio_read __P ((struct aiocb *__aiocbp));
index f2d938965032841c6940370b9b83b2aea1f4cd10..e802a8533f8f5a86af01583ef47ed92971cfbbaf 100644 (file)
@@ -30,7 +30,6 @@
 #undef aio_cancel64
 
 #include <errno.h>
-#include <pthread.h>
 
 #include "aio_misc.h"
 
@@ -43,128 +42,106 @@ aio_cancel (fildes, aiocbp)
      int fildes;
      struct aiocb *aiocbp;
 {
-  struct aiocb *firstp;
+  struct requestlist *req = NULL;
   int result = AIO_ALLDONE;
 
-  /* Request the semaphore.  */
-  sem_wait (&__aio_requests_sema);
+  /* Request the mutex.  */
+  pthread_mutex_lock (&__aio_requests_mutex);
 
-  /* Search for the list of requests associated with the given file
-     descriptor.  */
-  for (firstp = (struct aiocb *) __aio_requests; firstp != NULL;
-       firstp = firstp->__next_fd)
-    if (firstp->aio_fildes == fildes)
-      break;
-
-  /* If the file descriptor is not found all work seems to done
-     already.  Otherwise try to cancel the request(s).  */
-  if (firstp != NULL)
+  /* We are asked to cancel a specific AIO request.  */
+  if (aiocbp != NULL)
     {
-      if (aiocbp != NULL)
+      /* If the AIO request is not for this descriptor it has no value
+        to look for the request block.  */
+      if (aiocbp->aio_fildes == fildes)
        {
-         /* Locate the entry corresponding to the AIOCBP parameter.  */
-         if (aiocbp == firstp)
-           /* The requests is currently handled, therefore don't
-              cancel it and signal this to the user.  */
-           result = AIO_NOTCANCELED;
-         else
+         struct requestlist *last = NULL;
+
+         req = __aio_find_req_fd (fildes);
+
+         while (req->aiocbp != (aiocb_union *) aiocbp)
            {
-             while (firstp->__next_prio != NULL
-                    && aiocbp != firstp->__next_prio)
-               firstp = firstp->__next_prio;
-
-             if (firstp->__next_prio != NULL)
-               {
-                 /* The request the user wants to cancel is in the
-                    queue.  Simply remove it.  */
-                 firstp->__next_prio = aiocbp->__next_prio;
-
-                 /* Mark as canceled.  */
-                 aiocbp->__error_code = ECANCELED;
-                 aiocbp->__return_value = -1;
-
-                 /* Send the signal to notify about canceled
-                    processing of the request.  */
-                 if (aiocbp->aio_sigevent.sigev_notify == SIGEV_THREAD)
-                   {
-                     /* We have to start a thread.  */
-                     pthread_t tid;
-                     pthread_attr_t attr, *pattr;
-
-                     pattr = (pthread_attr_t *)
-                       aiocbp->aio_sigevent.sigev_notify_attributes;
-                     if (pattr == NULL)
-                       {
-                         pthread_attr_init (&attr);
-                         pthread_attr_setdetachstate (&attr,
-                                                      PTHREAD_CREATE_DETACHED);
-                         pattr = &attr;
-                       }
-
-                     pthread_create (&tid, pattr,
-                                     (void *(*) (void *))
-                                     aiocbp->aio_sigevent.sigev_notify_function,
-                                     aiocbp->aio_sigevent.sigev_value.sival_ptr);
-                   }
-                 else if (aiocbp->aio_sigevent.sigev_notify == SIGEV_SIGNAL)
-                   /* We have to send a signal.  */
-                   __aio_sigqueue (aiocbp->aio_sigevent.sigev_signo,
-                                   aiocbp->aio_sigevent.sigev_value);
-
-                 result = AIO_CANCELED;
-               }
+             last = req;
+             req = req->next_prio;
            }
-       }
-      else
-       {
-         /* First dequeue all waiting requests.  */
-         aiocbp = firstp;
 
-         while ((firstp = firstp->__next_prio) != NULL)
+         /* Don't remove the entry if a thread is already working on it.  */
+         if (req->running == allocated)
+           result = AIO_NOTCANCELED;
+         else
            {
-             firstp->__error_code = ECANCELED;
-             firstp->__return_value = -1;
-
-
-             /* Send the signal to notify about canceled processing
-                of the request.  */
-             if (firstp->aio_sigevent.sigev_notify == SIGEV_THREAD)
-               {
-                 /* We have to start a thread.  */
-                 pthread_t tid;
-                 pthread_attr_t attr, *pattr;
-
-                 pattr = (pthread_attr_t *)
-                   aiocbp->aio_sigevent.sigev_notify_attributes;
-                 if (pattr == NULL)
-                   {
-                     pthread_attr_init (&attr);
-                     pthread_attr_setdetachstate (&attr,
-                                                  PTHREAD_CREATE_DETACHED);
-                     pattr = &attr;
-                   }
-
-                 pthread_create (&tid, pattr,
-                                 (void *(*) (void *))
-                                 firstp->aio_sigevent.sigev_notify_function,
-                                 firstp->aio_sigevent.sigev_value.sival_ptr);
-               }
-             else if (firstp->aio_sigevent.sigev_notify == SIGEV_SIGNAL)
-               /* We have to send a signal.  */
-               __aio_sigqueue (firstp->aio_sigevent.sigev_signo,
-                               firstp->aio_sigevent.sigev_value);
+             /* We can remove the entry.  */
+             if (last != NULL)
+               last->next_prio = req->next_prio;
+             else
+               if (req->next_prio == NULL)
+                 {
+                   if (req->last_fd != NULL)
+                     req->last_fd->next_fd = req->next_fd;
+                   if (req->next_fd != NULL)
+                     req->next_fd->last_fd = req->last_fd;
+                 }
+               else
+                 {
+                   if (req->last_fd != NULL)
+                     req->last_fd->next_fd = req->next_prio;
+                   if (req->next_fd != NULL)
+                     req->next_fd->last_fd = req->next_prio;
+                   req->next_prio->last_fd = req->last_fd;
+                   req->next_prio->next_fd = req->next_fd;
+
+                   /* Mark this entry as runnable.  */
+                   req->next_prio->running = yes;
+                 }
+
+             result = AIO_CANCELED;
            }
 
-         /* We have to signal that not all requests could be canceled
-            since the first requests is currently processed.  */
-         result = AIO_NOTCANCELED;
-
-         aiocbp->__next_prio = NULL;
+         req->next_prio = NULL;
        }
     }
+  else
+    {
+      /* Find the beginning of the list of all requests for this
+        desriptor.  */
+      req = __aio_find_req_fd (fildes);
+
+      /* If any request is worked on by a thread it must be the first.
+        So either we can delete all requests or all but the first.  */
+      if (req != NULL)
+       if (req->running == allocated)
+         {
+           struct requestlist *old = req;
+           req = req->next_prio;
+           old->next_prio = NULL;
+
+           result = AIO_NOTCANCELED;
+         }
+       else
+         {
+           /* Remove entry from the file descriptor list.  */
+           if (req->last_fd != NULL)
+             req->last_fd->next_fd = req->next_fd;
+           if (req->next_fd != NULL)
+             req->next_fd->last_fd = req->last_fd;
+
+           result = AIO_CANCELED;
+         }
+    }
+
+  /* Mark requests as canceled and send signal.  */
+  while (req != NULL)
+    {
+      struct requestlist *old = req;
+      req->aiocbp->aiocb.__error_code = ECANCELED;
+      req->aiocbp->aiocb.__return_value = -1;
+      __aio_notify (req);
+      req = req->next_prio;
+      __aio_free_request (old);
+    }
 
-  /* Release the semaphore.  */
-  sem_post (&__aio_requests_sema);
+  /* Release the mutex.  */
+  pthread_mutex_unlock (&__aio_requests_mutex);
 
   return result;
 }
index 6daaca1e97eb2093e2cd90fd58325284c06842fd..c813654b6195320921ab2ca48e83b5bc8db2fee1 100644 (file)
@@ -36,7 +36,7 @@ int
 aio_fsync (int op, struct aiocb *aiocbp)
 {
   return __aio_enqueue_request ((aiocb_union *) aiocbp,
-                               op == O_SYNC ? __LIO_SYNC : __LIO_DSYNC, 1);
+                               op == O_SYNC ? LIO_SYNC : LIO_DSYNC) != NULL;
 }
 
 weak_alias (aio_fsync, aio_fsync64)
index e4bb12c500d662f5d0b53d22b9960d570a8e1648..6ea30c2158813c6a8d262afe3d5208c8fa7f621d 100644 (file)
@@ -21,7 +21,6 @@
 #include <aio.h>
 #include <errno.h>
 #include <pthread.h>
-#include <semaphore.h>
 #include <stdlib.h>
 #include <unistd.h>
 #include <sys/stat.h>
 #include "aio_misc.h"
 
 
-/* We need a list of pending operations.  This is sorted according to
-   the priority given in the aio_reqprio member.  */
-aiocb_union *__aio_requests;
+/* Pool of request list entries.  */
+static struct requestlist **pool;
 
-/* Since the list is global we need a semaphore protecting it.  */
-sem_t __aio_requests_sema;
+/* Number of total and allocated pool entries.  */
+static size_t pool_tab_size;
+static size_t pool_size;
 
+/* We implement a two dimensional array but allocate each row separately.
+   The macro below determines how many entries should be used per row.
+   It should better be a power of two.  */
+#define ENTRIES_PER_ROW        16
 
-/* The initialization function.  It gets automatically called if any
-   aio_* function is used in the program.  */
-static void
-__attribute__ ((unused))
-aio_initialize (void)
+/* The row table is incremented in units of this.  */
+#define ROW_STEP       8
+
+/* List of available entries.  */
+static struct requestlist *freelist;
+
+/* List of request waiting to be processed.  */
+static struct requestlist *runlist;
+
+/* Structure list of all currently processed requests.  */
+static struct requestlist *requests;
+
+/* Number of threads currently running.  */
+static int nthreads;
+
+
+/* These are the values used to optimize the use of AIO.  The user can
+   overwrite them by using the `aio_init' function.  */
+static struct aioinit optim =
+{
+  20,  /* int aio_threads;     Maximal number of threads.  */
+  256, /* int aio_num;         Number of expected simultanious requests. */
+  0,
+  0,
+  0,
+  0,
+  { 0, }
+};
+
+
+/* Since the list is global we need a mutex protecting it.  */
+pthread_mutex_t __aio_requests_mutex = PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP;
+
+
+/* Functions to handle request list pool.  */
+static struct requestlist *
+get_elem (void)
 {
-  /* Initialize the semaphore.  We allow exactly one user at a time.  */
-  sem_init (&__aio_requests_sema, 0, 1);
+  struct requestlist *result;
+
+  if (freelist == NULL)
+    {
+      struct requestlist *new_row;
+      size_t new_size;
+
+      /* Compute new size.  */
+      new_size = pool_size ? pool_size + ENTRIES_PER_ROW : optim.aio_num;
+
+      if ((new_size / ENTRIES_PER_ROW) >= pool_tab_size)
+       {
+         size_t new_tab_size = new_size / ENTRIES_PER_ROW;
+         struct requestlist **new_tab;
+
+         new_tab = (struct requestlist **)
+           realloc (pool, (new_tab_size * sizeof (struct requestlist *)));
+
+         if (new_tab == NULL)
+           return NULL;
+
+         pool_tab_size = new_tab_size;
+         pool = new_tab;
+       }
+
+      if (pool_size == 0)
+       {
+         size_t cnt;
+
+         new_row = (struct requestlist *)
+           calloc (new_size, sizeof (struct requestlist));
+
+         if (new_row == NULL)
+           return NULL;
+
+         for (cnt = 0; cnt < new_size / ENTRIES_PER_ROW; ++cnt)
+           pool[cnt] = &new_row[cnt * ENTRIES_PER_ROW];
+       }
+      else
+       {
+         /* Allocat one new row.  */
+         new_row = (struct requestlist *)
+           calloc (ENTRIES_PER_ROW, sizeof (struct requestlist));
+         if (new_row == NULL)
+           return NULL;
+
+         pool[new_size / ENTRIES_PER_ROW] = new_row;
+       }
+
+      /* Put all the new entries in the freelist.  */
+      do
+       {
+         new_row->next_prio = freelist;
+         freelist = new_row++;
+       }
+      while (++pool_size < new_size);
+    }
+
+  result = freelist;
+  freelist = freelist->next_prio;
+
+  return result;
 }
 
-text_set_element (__libc_subinit, aio_initialize);
+
+void
+__aio_free_req (struct requestlist *elem)
+{
+  elem->running = no;
+  elem->next_prio = freelist;
+  freelist = elem;
+}
+
+
+struct requestlist *
+__aio_find_req (aiocb_union *elem)
+{
+  struct requestlist *runp = requests;
+  int fildes = elem->aiocb.aio_fildes;
+
+  while (runp != NULL && runp->aiocbp->aiocb.aio_fildes < fildes)
+    runp = runp->next_fd;
+
+  if (runp != NULL)
+    if (runp->aiocbp->aiocb.aio_fildes != fildes)
+      runp = NULL;
+    else
+      while (runp != NULL && runp->aiocbp != elem)
+       runp = runp->next_prio;
+
+  return runp;
+}
+
+
+struct requestlist *
+__aio_find_req_fd (int fildes)
+{
+  struct requestlist *runp = requests;
+
+  while (runp != NULL && runp->aiocbp->aiocb.aio_fildes < fildes)
+    runp = runp->next_fd;
+
+  return (runp != NULL && runp->aiocbp->aiocb.aio_fildes == fildes
+         ? runp : NULL);
+}
 
 
 /* The thread handler.  */
 static void *handle_fildes_io (void *arg);
 
 
+/* User optimization.  */
+void
+__aio_init (const struct aioinit *init)
+{
+  /* Get the mutex.  */
+  pthread_mutex_lock (&__aio_requests_mutex);
+
+  /* Only allow writing new values if the table is not yet allocated.  */
+  if (pool == NULL)
+    {
+      optim.aio_threads = init->aio_threads < 1 ? 1 : init->aio_threads;
+      optim.aio_num = (init->aio_num < ENTRIES_PER_ROW
+                      ? ENTRIES_PER_ROW
+                      : init->aio_num & ~ENTRIES_PER_ROW);
+    }
+
+  /* Release the mutex.  */
+  pthread_mutex_unlock (&__aio_requests_mutex);
+}
+weak_alias (__aio_init, aio_init)
+
+
 /* The main function of the async I/O handling.  It enqueues requests
    and if necessary starts and handles threads.  */
-int
-__aio_enqueue_request (aiocb_union *aiocbp, int operation, int require_lock)
+struct requestlist *
+__aio_enqueue_request (aiocb_union *aiocbp, int operation)
 {
-  int result;
+  int result = 0;
   int policy, prio;
   struct sched_param param;
-  aiocb_union *runp;
+  struct requestlist *last, *runp, *newp;
+  int running = no;
 
   if (aiocbp->aiocb.aio_reqprio < 0
       || aiocbp->aiocb.aio_reqprio > AIO_PRIO_DELTA_MAX)
@@ -71,94 +229,160 @@ __aio_enqueue_request (aiocb_union *aiocbp, int operation, int require_lock)
       __set_errno (EINVAL);
       aiocbp->aiocb.__error_code = EINVAL;
       aiocbp->aiocb.__return_value = -1;
-      return -1;
-    }
-
-  if (pthread_getschedparam (pthread_self (), &policy, &param) < 0)
-    {
-      /* Something went wrong.  */
-      aiocbp->aiocb.__error_code = errno;
-      aiocbp->aiocb.__return_value = -1;
-      return -1;
+      return NULL;
     }
 
   /* Compute priority for this request.  */
+  pthread_getschedparam (pthread_self (), &policy, &param);
   prio = param.sched_priority - aiocbp->aiocb.aio_reqprio;
 
+  /* Get the mutex.  */
+  pthread_mutex_lock (&__aio_requests_mutex);
 
-  /* Get the semaphore.  */
-  if (require_lock)
-    sem_wait (&__aio_requests_sema);
-
-  runp = __aio_requests;
+  last = NULL;
+  runp = requests;
   /* First look whether the current file descriptor is currently
      worked with.  */
-  while (runp != NULL && runp->aiocb.aio_fildes < aiocbp->aiocb.aio_fildes)
-    runp = (aiocb_union *) runp->aiocb.__next_fd;
+  while (runp != NULL
+        && runp->aiocbp->aiocb.aio_fildes < aiocbp->aiocb.aio_fildes)
+    {
+      last = runp;
+      runp = runp->next_fd;
+    }
 
-  if (runp != NULL)
+  /* Get a new element for the waiting list.  */
+  newp = get_elem ();
+  if (newp == NULL)
+    {
+      __set_errno (EAGAIN);
+      pthread_mutex_unlock (&__aio_requests_mutex);
+      return NULL;
+    }
+  newp->aiocbp = aiocbp;
+  newp->waiting = NULL;
+
+  aiocbp->aiocb.__abs_prio = prio;
+  aiocbp->aiocb.__policy = policy;
+  aiocbp->aiocb.aio_lio_opcode = operation;
+  aiocbp->aiocb.__error_code = EINPROGRESS;
+  aiocbp->aiocb.__return_value = 0;
+
+  if (runp != NULL
+      && runp->aiocbp->aiocb.aio_fildes == aiocbp->aiocb.aio_fildes)
     {
       /* The current file descriptor is worked on.  It makes no sense
-        to start another thread since this new thread would have to
-        wait for the previous one to terminate.  Simply enqueue it
-        after the running one according to the priority.  */
-      while (runp->aiocb.__next_prio != NULL
-            && runp->aiocb.__next_prio->__abs_prio >= prio)
-       runp = (aiocb_union *) runp->aiocb.__next_prio;
-
-      aiocbp->aiocb.__next_prio = runp->aiocb.__next_prio;
-      aiocbp->aiocb.__abs_prio = prio;
-      aiocbp->aiocb.__policy = policy;
-      aiocbp->aiocb.aio_lio_opcode = operation;
-      aiocbp->aiocb.__error_code = EINPROGRESS;
-      aiocbp->aiocb.__return_value = 0;
-      runp->aiocb.__next_prio = (struct aiocb *) aiocbp;
-
-      result = 0;
+        to start another thread since this new thread would fight
+        with the running thread for the resources.  But we also cannot
+        say that the thread processing this desriptor shall imeediately
+        after finishing the current job process this request if there
+        are other threads in the running queue which have a higher
+        priority.  */
+
+      /* Simply enqueue it after the running one according to the
+        priority.  */
+      while (runp->next_prio != NULL
+            && runp->next_prio->aiocbp->aiocb.__abs_prio >= prio)
+       runp = runp->next_prio;
+
+      newp->next_prio = runp->next_prio;
+      runp->next_prio = newp;
+
+      running = queued;
     }
   else
     {
-      /* We create a new thread for this file descriptor.  The
+      /* Enqueue this request for a new descriptor.  */
+      if (last == NULL)
+       {
+         newp->last_fd = NULL;
+         newp->next_fd = requests;
+         if (requests != NULL)
+           requests->last_fd = newp;
+         requests = newp;
+       }
+      else
+       {
+         newp->next_fd = last->next_fd;
+         newp->last_fd = last;
+         last->next_fd = newp;
+         if (newp->next_fd != NULL)
+           newp->next_fd->last_fd = newp;
+       }
+
+      newp->next_prio = NULL;
+    }
+
+  if (running == no)
+    {
+      /* We try to create a new thread for this file descriptor.  The
         function which gets called will handle all available requests
         for this descriptor and when all are processed it will
-        terminate.  */
-      pthread_t thid;
-      pthread_attr_t attr;
-
-      /* First enqueue the request (the list is empty).  */
-      aiocbp->aiocb.__next_fd = NULL;
-      aiocbp->aiocb.__last_fd = NULL;
-
-      aiocbp->aiocb.__next_prio = NULL;
-      aiocbp->aiocb.__abs_prio = prio;
-      aiocbp->aiocb.__policy = policy;
-      aiocbp->aiocb.aio_lio_opcode = operation;
-      aiocbp->aiocb.__error_code = EINPROGRESS;
-      aiocbp->aiocb.__return_value = 0;
-
-      /* Make sure the thread is created detached.  */
-      pthread_attr_init (&attr);
-      pthread_attr_setdetachstate (&attr, PTHREAD_CREATE_DETACHED);
-
-      /* Now try to start a thread.  */
-      if (pthread_create (&thid, &attr, handle_fildes_io, aiocbp) < 0)
+        terminate.
+
+        If no new thread can be created or if the specified limit of
+        threads for AIO is reached we queue the request.  */
+
+      /* See if we can create a thread.  */
+      if (nthreads < optim.aio_threads)
        {
-         result = -1;
-         aiocbp->aiocb.__error_code = errno;
-         aiocbp->aiocb.__return_value = -1;
+         pthread_t thid;
+         pthread_attr_t attr;
+
+         /* Make sure the thread is created detached.  */
+         pthread_attr_init (&attr);
+         pthread_attr_setdetachstate (&attr, PTHREAD_CREATE_DETACHED);
+
+         /* Now try to start a thread.  */
+         if (pthread_create (&thid, &attr, handle_fildes_io, newp) == 0)
+           {
+             /* We managed to enqueue the request.  All errors which can
+                happen now can be recognized by calls to `aio_return' and
+                `aio_error'.  */
+             running = allocated;
+             ++nthreads;
+           }
+         else if (nthreads == 0)
+           /* We cannot create a thread in the moment and there is
+              also no thread running.  This is a problem.  `errno' is
+              set to EAGAIN if this is only a temporary problem.  */
+           result = -1;
+       }
+    }
+
+  /* Enqueue the request in the run queue if it is not yet running.  */
+  if (running < yes && result == 0)
+    {
+      if (runlist == NULL || runlist->aiocbp->aiocb.__abs_prio < prio)
+       {
+         newp->next_run = runlist;
+         runlist = newp;
        }
       else
-       /* We managed to enqueue the request.  All errors which can
-          happen now can be recognized by calls to `aio_return' and
-          `aio_error'.  */
-         result = 0;
+       {
+         runp = runlist;
+
+         while (runp->next_run != NULL
+                && runp->next_run->aiocbp->aiocb.__abs_prio >= prio)
+           runp = runp->next_run;
+
+         newp->next_run = runp->next_run;
+         runp->next_run = newp;
+       }
     }
 
-  /* Release the semaphore.  */
-  if (require_lock)
-    sem_post (&__aio_requests_sema);
+  if (result == 0)
+    newp->running = running;
+  else
+    {
+      /* Something went wrong.  */
+      __aio_free_req (newp);
+      newp = NULL;
+    }
 
-  return result;
+  /* Release the mutex.  */
+  pthread_mutex_unlock (&__aio_requests_mutex);
+
+  return newp;
 }
 
 
@@ -167,140 +391,156 @@ handle_fildes_io (void *arg)
 {
   pthread_t self = pthread_self ();
   struct sched_param param;
-  aiocb_union *runp = (aiocb_union *) arg;
+  struct requestlist *runp = (struct requestlist *) arg;
+  aiocb_union *aiocbp = runp->aiocbp;
   int policy;
-  int fildes = runp->aiocb.aio_fildes; /* This is always the same.  */
+  int fildes = runp->aiocbp->aiocb.aio_fildes;
 
   pthread_getschedparam (self, &policy, &param);
 
   do
     {
       /* Change the priority to the requested value (if necessary).  */
-      if (runp->aiocb.__abs_prio != param.sched_priority
-         || runp->aiocb.__policy != policy)
+      if (aiocbp->aiocb.__abs_prio != param.sched_priority
+         || aiocbp->aiocb.__policy != policy)
        {
-         param.sched_priority = runp->aiocb.__abs_prio;
-         policy = runp->aiocb.__policy;
+         param.sched_priority = aiocbp->aiocb.__abs_prio;
+         policy = aiocbp->aiocb.__policy;
          pthread_setschedparam (self, policy, &param);
        }
 
       /* Process request pointed to by RUNP.  We must not be disturbed
         by signals.  */
-      if ((runp->aiocb.aio_lio_opcode & 127) == LIO_READ)
+      if ((aiocbp->aiocb.aio_lio_opcode & 127) == LIO_READ)
        {
-         if (runp->aiocb.aio_lio_opcode & 128)
-           runp->aiocb.__return_value =
+         if (aiocbp->aiocb.aio_lio_opcode & 128)
+           aiocbp->aiocb.__return_value =
              TEMP_FAILURE_RETRY (__pread64 (fildes,
-                                            (void *) runp->aiocb64.aio_buf,
-                                            runp->aiocb64.aio_nbytes,
-                                            runp->aiocb64.aio_offset));
+                                            (void *) aiocbp->aiocb64.aio_buf,
+                                            aiocbp->aiocb64.aio_nbytes,
+                                            aiocbp->aiocb64.aio_offset));
          else
-           runp->aiocb.__return_value =
+           aiocbp->aiocb.__return_value =
              TEMP_FAILURE_RETRY (__pread (fildes,
-                                          (void *) runp->aiocb.aio_buf,
-                                          runp->aiocb.aio_nbytes,
-                                          runp->aiocb.aio_offset));
+                                          (void *) aiocbp->aiocb.aio_buf,
+                                          aiocbp->aiocb.aio_nbytes,
+                                          aiocbp->aiocb.aio_offset));
        }
-      else if ((runp->aiocb.aio_lio_opcode & 127) == LIO_WRITE)
+      else if ((aiocbp->aiocb.aio_lio_opcode & 127) == LIO_WRITE)
        {
-         if (runp->aiocb.aio_lio_opcode & 128)
-           runp->aiocb.__return_value =
+         if (aiocbp->aiocb.aio_lio_opcode & 128)
+           aiocbp->aiocb.__return_value =
              TEMP_FAILURE_RETRY (__pwrite64 (fildes,
-                                             (const void *) runp->aiocb64.aio_buf,
-                                             runp->aiocb64.aio_nbytes,
-                                             runp->aiocb64.aio_offset));
+                                             (const void *) aiocbp->aiocb64.aio_buf,
+                                             aiocbp->aiocb64.aio_nbytes,
+                                             aiocbp->aiocb64.aio_offset));
          else
-           runp->aiocb.__return_value =
+           aiocbp->aiocb.__return_value =
              TEMP_FAILURE_RETRY (__pwrite (fildes,
-                                           (const void *) runp->aiocb.aio_buf,
-                                           runp->aiocb.aio_nbytes,
-                                           runp->aiocb.aio_offset));
+                                           (const void *) aiocbp->aiocb.aio_buf,
+                                           aiocbp->aiocb.aio_nbytes,
+                                           aiocbp->aiocb.aio_offset));
        }
-      else if (runp->aiocb.aio_lio_opcode == __LIO_DSYNC)
-       runp->aiocb.__return_value = TEMP_FAILURE_RETRY (fdatasync (fildes));
-      else if (runp->aiocb.aio_lio_opcode == __LIO_SYNC)
-       runp->aiocb.__return_value = TEMP_FAILURE_RETRY (fsync (fildes));
+      else if (aiocbp->aiocb.aio_lio_opcode == LIO_DSYNC)
+       aiocbp->aiocb.__return_value = TEMP_FAILURE_RETRY (fdatasync (fildes));
+      else if (aiocbp->aiocb.aio_lio_opcode == LIO_SYNC)
+       aiocbp->aiocb.__return_value = TEMP_FAILURE_RETRY (fsync (fildes));
       else
        {
          /* This is an invalid opcode.  */
-         runp->aiocb.__return_value = -1;
+         aiocbp->aiocb.__return_value = -1;
          __set_errno (EINVAL);
        }
 
-      if (runp->aiocb.__return_value == -1)
-       runp->aiocb.__error_code = errno;
+      /* Get the mutex.  */
+      pthread_mutex_lock (&__aio_requests_mutex);
+
+      if (aiocbp->aiocb.__return_value == -1)
+       aiocbp->aiocb.__error_code = errno;
       else
-       runp->aiocb.__error_code = 0;
+       aiocbp->aiocb.__error_code = 0;
 
       /* Send the signal to notify about finished processing of the
         request.  */
-      if (runp->aiocb.aio_sigevent.sigev_notify == SIGEV_THREAD)
+      __aio_notify (runp);
+
+      /* Now dequeue the current request.  */
+      if (runp->next_prio == NULL)
        {
-         /* We have to start a thread.  */
-         pthread_t tid;
-         pthread_attr_t attr, *pattr;
+         /* No outstanding request for this descriptor.  Process the
+            runlist if necessary.  */
+         if (runp->next_fd != NULL)
+           runp->next_fd->last_fd = runp->last_fd;
+         if (runp->last_fd != NULL)
+           runp->last_fd->next_fd = runp->next_fd;
+       }
+      else
+       {
+         runp->next_prio->last_fd = runp->last_fd;
+         runp->next_prio->next_fd = runp->next_fd;
+         runp->next_prio->running = yes;
+         if (runp->next_fd != NULL)
+           runp->next_fd->last_fd = runp->next_prio;
+         if (runp->last_fd != NULL)
+           runp->last_fd->next_fd = runp->next_prio;
+       }
+
+      /* Free the old element.  */
+      __aio_free_req (runp);
 
-         pattr = (pthread_attr_t *)
-           runp->aiocb.aio_sigevent.sigev_notify_attributes;
-         if (pattr == NULL)
+      runp = freelist;
+      if (runp != NULL)
+       {
+         /* We must not run requests which are not marked `running'.  */
+         if (runp->running == yes)
            {
-             pthread_attr_init (&attr);
-             pthread_attr_setdetachstate (&attr, PTHREAD_CREATE_DETACHED);
-             pattr = &attr;
+             freelist = runp->next_run;
+             runp->running = allocated;
            }
-
-         if (pthread_create (&tid,
-                             (pthread_attr_t *)
-                             runp->aiocb.aio_sigevent.sigev_notify_attributes,
-                             (void *(*) (void *))
-                             runp->aiocb.aio_sigevent.sigev_notify_function,
-                             runp->aiocb.aio_sigevent.sigev_value.sival_ptr)
-             < 0)
+         else
            {
-             /* XXX What shall we do if already an error is set by
-                read/write/fsync?  */
-             runp->aiocb.__error_code = errno;
-             runp->aiocb.__return_value = -1;
+             struct requestlist *old;
+
+             do
+               {
+                 old = runp;
+                 runp = runp->next_run;
+               }
+             while (runp != NULL && runp->running != yes);
+
+             if (runp != NULL)
+               old->next_run = runp->next_run;
            }
        }
-      else if (runp->aiocb.aio_sigevent.sigev_notify == SIGEV_SIGNAL)
-       /* We have to send a signal.  */
-       if (__aio_sigqueue (runp->aiocb.aio_sigevent.sigev_signo,
-                           runp->aiocb.aio_sigevent.sigev_value) < 0)
-         {
-           /* XXX What shall we do if already an error is set by
-              read/write/fsync?  */
-           runp->aiocb.__error_code = errno;
-           runp->aiocb.__return_value = -1;
-         }
-
-      /* Get the semaphore.  */
-      sem_wait (&__aio_requests_sema);
 
-      /* Now dequeue the current request.  */
-      if (runp->aiocb.__next_prio == NULL)
-       {
-         if (runp->aiocb.__next_fd != NULL)
-           runp->aiocb.__next_fd->__last_fd = runp->aiocb.__last_fd;
-         if (runp->aiocb.__last_fd != NULL)
-           runp->aiocb.__last_fd->__next_fd = runp->aiocb.__next_fd;
-         runp = NULL;
-       }
-      else
-       {
-         runp->aiocb.__next_prio->__last_fd = runp->aiocb.__last_fd;
-         runp->aiocb.__next_prio->__next_fd = runp->aiocb.__next_fd;
-         if (runp->aiocb.__next_fd != NULL)
-           runp->aiocb.__next_fd->__last_fd = runp->aiocb.__next_prio;
-         if (runp->aiocb.__last_fd != NULL)
-           runp->aiocb.__last_fd->__next_fd = runp->aiocb.__next_prio;
-         runp = (aiocb_union *) runp->aiocb.__next_prio;
-       }
+      /* If no request to work on we will stop the thread.  */
+      if (runp == NULL)
+       --nthreads;
 
-      /* Release the semaphore.  */
-      sem_post (&__aio_requests_sema);
+      /* Release the mutex.  */
+      pthread_mutex_unlock (&__aio_requests_mutex);
     }
   while (runp != NULL);
 
   pthread_exit (NULL);
 }
+
+
+/* Free allocated resources.  */
+static void
+__attribute__ ((unused))
+free_res (void)
+{
+  size_t row;
+
+  /* The first block of rows as specified in OPTIM is allocated in
+     one chunk.  */
+  free (pool[0]);
+
+  for (row = optim.aio_num / ENTRIES_PER_ROW; row < pool_tab_size; ++row)
+    free (pool[row]);
+
+  free (pool);
+}
+
+text_set_element (__libc_subfreeres, free_res);
index c2eb9fcea1c9b448157efebae31fbc4494e7e3ff..af8e2479baa456402aaf490d7bd8f564a106ecb4 100644 (file)
 #ifndef _AIO_MISC_H
 #define _AIO_MISC_H    1
 
-#include <semaphore.h>
+#include <aio.h>
+#include <pthread.h>
+
+
+/* Extend the operation enum.  */
+enum
+{
+  LIO_DSYNC = LIO_READ + 1,
+  LIO_SYNC,
+  LIO_READ64 = LIO_READ | 128,
+  LIO_WRITE64 = LIO_WRITE | 128
+};
+
 
 /* Union of the two request types.  */
 typedef union
@@ -28,18 +40,73 @@ typedef union
     struct aiocb64 aiocb64;
   } aiocb_union;
 
-/* List of enqueued requests.  */
-extern aiocb_union *__aio_requests;
+
+/* Used to synchronize.  */
+struct waitlist
+  {
+    struct waitlist *next;
+
+    pthread_cond_t *cond;
+    volatile int *counterp;
+    /* The next field is used in asynchronous `lio_listio' operations.  */
+    struct sigevent *sigevp;
+  };
+
+
+/* Status of a request.  */
+enum
+{
+  no,
+  queued,
+  yes,
+  allocated
+};
+
+
+/* Used to queue requests..  */
+struct requestlist
+  {
+    int running;
+
+    struct requestlist *last_fd;
+    struct requestlist *next_fd;
+    struct requestlist *next_prio;
+    struct requestlist *next_run;
+
+    /* Pointer to the actual data.  */
+    aiocb_union *aiocbp;
+
+    /* List of waiting processes.  */
+    struct waitlist *waiting;
+  };
+
 
 /* Lock for global I/O list of requests.  */
-extern sem_t __aio_requests_sema;
+extern pthread_mutex_t __aio_requests_mutex;
 
 
 /* Enqueue request.  */
-extern int __aio_enqueue_request (aiocb_union *aiocbp, int operation,
-                                 int require_lock);
+extern struct requestlist *__aio_enqueue_request (aiocb_union *aiocbp,
+                                                 int operation)
+     internal_function;
+
+/* Find request entry for given AIO control block.  */
+extern struct requestlist *__aio_find_req (aiocb_union *elem)
+     internal_function;
+
+/* Find request entry for given file descriptor.  */
+extern struct requestlist *__aio_find_req_fd (int fildes) internal_function;
+
+/* Release the entry for the request.  */
+extern void __aio_free_request (struct requestlist *req) internal_function;
+
+/* Notify initiator of request and tell this everybody listening.  */
+extern void __aio_notify (struct requestlist *req) internal_function;
+
+/* Notify initiator of request.  */
+extern int __aio_notify_only (struct sigevent *sigev) internal_function;
 
 /* Send the signal.  */
-extern int __aio_sigqueue (int sig, const union sigval val);
+extern int __aio_sigqueue (int sig, const union sigval val) internal_function;
 
 #endif /* aio_misc.h */
diff --git a/rt/aio_notify.c b/rt/aio_notify.c
new file mode 100644 (file)
index 0000000..be2e1e2
--- /dev/null
@@ -0,0 +1,97 @@
+/* Notify initiator of AIO request.
+   Copyright (C) 1997 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Library General Public License as
+   published by the Free Software Foundation; either version 2 of the
+   License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Library General Public License for more details.
+
+   You should have received a copy of the GNU Library General Public
+   License along with the GNU C Library; see the file COPYING.LIB.  If not,
+   write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+   Boston, MA 02111-1307, USA.  */
+
+#include <pthread.h>
+#include <stdlib.h>
+#include "aio_misc.h"
+
+int
+__aio_notify_only (struct sigevent *sigev)
+{
+  int result = 0;
+
+  /* Send the signal to notify about finished processing of the request.  */
+  if (sigev->sigev_notify == SIGEV_THREAD)
+    {
+      /* We have to start a thread.  */
+      pthread_t tid;
+      pthread_attr_t attr, *pattr;
+
+      pattr = (pthread_attr_t *) sigev->sigev_notify_attributes;
+      if (pattr == NULL)
+       {
+         pthread_attr_init (&attr);
+         pthread_attr_setdetachstate (&attr, PTHREAD_CREATE_DETACHED);
+         pattr = &attr;
+       }
+
+      if (pthread_create (&tid, pattr,
+                         (void *(*) (void *)) sigev->sigev_notify_function,
+                         sigev->sigev_value.sival_ptr) < 0)
+       result = -1;
+    }
+  else if (sigev->sigev_notify == SIGEV_SIGNAL)
+    /* We have to send a signal.  */
+    if (__aio_sigqueue (sigev->sigev_signo, sigev->sigev_value) < 0)
+      result = -1;
+
+  return result;
+}
+
+
+void
+__aio_notify (struct requestlist *req)
+{
+  struct waitlist *waitlist;
+  struct aiocb *aiocbp = &req->aiocbp->aiocb;
+
+  if (__aio_notify_only (&aiocbp->aio_sigevent) != 0)
+    {
+      /* XXX What shall we do if already an error is set by
+        read/write/fsync?  */
+      aiocbp->__error_code = errno;
+      aiocbp->__return_value = -1;
+    }
+
+  /* Now also notify possibly waiting threads.  */
+  waitlist = req->waiting;
+  while (waitlist != NULL)
+    {
+      struct waitlist *next = waitlist->next;
+
+      /* Decrement the counter.  This is used in both cases.  */
+      --*waitlist->counterp;
+
+      if (waitlist->sigevp == NULL)
+       pthread_cond_signal (waitlist->cond);
+      else
+       /* This is part of a asynchronous `lio_listio' operation.  If
+          this request is the last one, send the signal.  */
+       if (*waitlist->counterp == 0)
+         {
+           __aio_notify_only (waitlist->sigevp);
+           /* This is tricky.  See lio_listio.c for the reason why
+              this works.  */
+           free ((void *) waitlist->counterp);
+         }
+
+      waitlist = next;
+    }
+}
index 8286ba9334b6fbd9b991cc31c8e362e3f3ba7457..871ce99767084308d5f8f3a28af72469796ca0cf 100644 (file)
@@ -27,5 +27,5 @@ int
 aio_read (aiocbp)
      struct aiocb *aiocbp;
 {
-  return __aio_enqueue_request ((aiocb_union *) aiocbp, LIO_READ, 1);
+  return __aio_enqueue_request ((aiocb_union *) aiocbp, LIO_READ) != NULL;
 }
index bf808fb3daf9ccdf050b8991f7d49c6cc5dd9e53..b194dda6db90713276849f5f7f6f5a7e95be9600 100644 (file)
@@ -27,5 +27,5 @@ int
 aio_read64 (aiocbp)
      struct aiocb64 *aiocbp;
 {
-  return __aio_enqueue_request ((aiocb_union *) aiocbp, __LIO_READ64, 1);
+  return __aio_enqueue_request ((aiocb_union *) aiocbp, LIO_READ64) != NULL;
 }
index 75bf9ba94bc7427f1f928d58338a847c713cedfe..6123b7baa07ccdbfd46035dab06343869ae5b59c 100644 (file)
@@ -40,16 +40,89 @@ aio_suspend (list, nent, timeout)
      int nent;
      const struct timespec *timeout;
 {
+  pthread_cond_t cond;
+  struct waitlist waitlist[nent];
+  struct requestlist *requestlist[nent];
   int cnt;
+  int result = 0;
+
+  /* Request the mutex.  */
+  pthread_mutex_lock (&__aio_requests_mutex);
 
   /* First look whether there is already a terminated request.  */
   for (cnt = 0; cnt < nent; ++cnt)
     if (list[cnt] != NULL && list[cnt]->__error_code != EINPROGRESS)
-      return 0;
+      break;
+
+  if (cnt == nent)
+    {
+      int oldstate;
+
+      /* There is not yet a finished request.  Signal the request that
+        we are working for it.  */
+      for (cnt = 0; cnt < nent; ++cnt)
+       if (list[cnt] != NULL && list[cnt]->__error_code == EINPROGRESS)
+         {
+           requestlist[cnt] = __aio_find_req ((aiocb_union *) list[cnt]);
+
+           if (requestlist[cnt] != NULL)
+             {
+               waitlist[cnt].cond = &cond;
+               waitlist[cnt].next = requestlist[cnt]->waiting;
+               waitlist[cnt].counterp = NULL;
+               waitlist[cnt].sigevp = NULL;
+               requestlist[cnt]->waiting = &waitlist[cnt];
+             }
+         }
+
+      /* Since `pthread_cond_wait'/`pthread_cond_timedwait' are cancelation
+        points we must be careful.  We added entries to the waiting lists
+        which we must remove.  So defer cancelation for now.  */
+      pthread_setcancelstate (PTHREAD_CANCEL_DISABLE, &oldstate);
+
+      if (timeout == NULL)
+       result = pthread_cond_wait (&cond, &__aio_requests_mutex);
+      else
+       result = pthread_cond_timedwait (&cond, &__aio_requests_mutex,
+                                        timeout);
+
+      /* Now remove the entry in the waiting list for all requests
+        which didn't terminate  */
+      for (cnt = 0; cnt < nent; ++cnt)
+       if (list[cnt] != NULL && list[cnt]->__error_code == EINPROGRESS
+           && requestlist[cnt] != NULL)
+         {
+           struct waitlist **listp = &requestlist[cnt]->waiting;
+
+           /* There is the chance that we cannot find our entry anymore.
+              This could happen if the request terminated and restarted
+              again.  */
+           while (*listp != NULL && *listp != &waitlist[cnt])
+             listp = &(*listp)->next;
+
+           if (*listp != NULL)
+             *listp = (*listp)->next;
+         }
+
+      /* Now it's time to restore the cancelation state.  */
+      pthread_setcancelstate (oldstate, NULL);
+
+      if (result != 0)
+       {
+         /* An error occurred.  Possibly it's EINTR.  We have to translate
+            the timeout error report of `pthread_cond_timedwait' to the
+            form expected from `aio_suspend'.  */
+         if (result == ETIMEDOUT)
+           __set_errno (EAGAIN);
+
+         result = -1;
+       }
+    }
 
-  /* XXX We have to write code which waits.  */
+  /* Release the mutex.  */
+  pthread_mutex_unlock (&__aio_requests_mutex);
 
-  return -1;
+  return result;
 }
 
 weak_alias (aio_suspend, aio_suspend64)
index 80b827c1aa6bf6154fdcffb9142d2b5d29864bda..8801d89110691520234acddfcd4d026cbd6a7ef3 100644 (file)
@@ -27,5 +27,5 @@ int
 aio_write (aiocbp)
      struct aiocb *aiocbp;
 {
-  return __aio_enqueue_request ((aiocb_union *) aiocbp, LIO_WRITE, 1);
+  return __aio_enqueue_request ((aiocb_union *) aiocbp, LIO_WRITE) != NULL;
 }
index 477ce2cbe4864d23e00b848e4584b4d127f3875e..4d599b10621685931566647905bff9747609b7e2 100644 (file)
@@ -27,5 +27,5 @@ int
 aio_write64 (aiocbp)
      struct aiocb64 *aiocbp;
 {
-  return __aio_enqueue_request ((aiocb_union *) aiocbp, __LIO_WRITE64, 1);
+  return __aio_enqueue_request ((aiocb_union *) aiocbp, LIO_WRITE64) != NULL;
 }
index 73df5c2f5c90cd8e4a826b613816d276c269d781..b389c6a5f6913cbf011e1edb9c6cbe0610e12044 100644 (file)
 
 #include <aio.h>
 #include <errno.h>
-#include <semaphore.h>
+#include <stdlib.h>
 
 #include "aio_misc.h"
 
 
+/* We need this special structure to handle asynchronous I/O.  */
+struct async_waitlist
+  {
+    int counter;
+    struct sigevent sigev;
+    struct waitlist list[0];
+  };
+
+
 int
 lio_listio (mode, list, nent, sig)
      int mode;
@@ -32,8 +41,9 @@ lio_listio (mode, list, nent, sig)
      int nent;
      struct sigevent *sig;
 {
+  struct requestlist *requests[nent];
   int cnt;
-  int total = 0;
+  volatile int total = 0;
   int result = 0;
 
   /* Check arguments.  */
@@ -43,26 +53,100 @@ lio_listio (mode, list, nent, sig)
       return -1;
     }
 
-  /* Request the semaphore.  */
-  sem_wait (&__aio_requests_sema);
+  /* Request the mutex.  */
+  pthread_mutex_lock (&__aio_requests_mutex);
 
   /* Now we can enqueue all requests.  Since we already acquired the
-     semaphore the enqueue function need not do this.  */
+     mutex the enqueue function need not do this.  */
   for (cnt = 0; cnt < nent; ++cnt)
     if (list[cnt] != NULL && list[cnt]->aio_lio_opcode != LIO_NOP)
-      if (__aio_enqueue_request ((aiocb_union *) list[cnt],
-                                list[cnt]->aio_lio_opcode, 0) >= 0)
-       /* Successfully enqueued.  */
-       ++total;
+      {
+       requests[cnt] =  __aio_enqueue_request ((aiocb_union *) list[cnt],
+                                               list[cnt]->aio_lio_opcode);
+
+       if (requests[cnt] != NULL)
+         /* Successfully enqueued.  */
+         ++total;
+       else
+         /* Signal that we've seen an error.  `errno' and the error code
+            of the aiocb will tell more.  */
+         result = -1;
+      }
+
+  if (total == 0)
+    {
+      /* We don't have anything to do except signalling if we work
+        asynchronously.  */
+      if (mode == LIO_NOWAIT)
+       __aio_notify_only (sig);
+    }
+  else if (mode == LIO_WAIT)
+    {
+      pthread_cond_t cond;
+      struct waitlist waitlist[nent];
+      int oldstate;
+
+      total = 0;
+      for (cnt = 0; cnt < nent; ++cnt)
+       if (list[cnt] != NULL && list[cnt]->aio_lio_opcode != LIO_NOP
+           && requests[cnt] != NULL)
+         {
+           waitlist[cnt].cond = &cond;
+           waitlist[cnt].next = requests[cnt]->waiting;
+           waitlist[cnt].counterp = NULL;
+           waitlist[cnt].sigevp = NULL;
+           requests[cnt]->waiting = &waitlist[cnt];
+           ++total;
+         }
+
+      /* Since `pthread_cond_wait'/`pthread_cond_timedwait' are cancelation
+        points we must be careful.  We added entries to the waiting lists
+        which we must remove.  So defer cancelation for now.  */
+      pthread_setcancelstate (PTHREAD_CANCEL_DISABLE, &oldstate);
+
+      while (total > 0)
+       if (pthread_cond_wait (&cond, &__aio_requests_mutex) == 0)
+         --total;
+
+      /* Now it's time to restore the cancelation state.  */
+      pthread_setcancelstate (oldstate, NULL);
+    }
+  else
+    {
+      struct async_waitlist *waitlist;
+
+      waitlist = (struct async_waitlist *)
+       malloc (sizeof (struct async_waitlist)
+               + (nent * sizeof (struct waitlist)));
+
+      if (waitlist == NULL)
+       {
+         __set_errno (EAGAIN);
+         result = -1;
+       }
       else
-       /* Signal that we've seen an error.  `errno' and the error code
-          of the aiocb will tell more.  */
-       result = -1;
+       {
+         total = 0;
 
+         for (cnt = 0; cnt < nent; ++cnt)
+           if (list[cnt] != NULL && list[cnt]->aio_lio_opcode != LIO_NOP
+               && requests[cnt] != NULL)
+             {
+               waitlist->list[cnt].cond = NULL;
+               waitlist->list[cnt].next = requests[cnt]->waiting;
+               waitlist->list[cnt].counterp = &waitlist->counter;
+               waitlist->list[cnt].sigevp = &waitlist->sigev;
+               requests[cnt]->waiting = &waitlist->list[cnt];
+               ++total;
+             }
 
+         waitlist->counter = total;
+         waitlist->sigev = *sig;
+       }
+    }
 
-  /* Release the semaphore.  */
-  sem_post (&__aio_requests_sema);
+  /* Release the mutex.  */
+  pthread_mutex_unlock (&__aio_requests_mutex);
 
   return result;
 }
index b17e9edae2c89c9bda9a879b848b1e5d01f11ca8..19f56adab1f1fec87754c05b139a6c81c36e4ad9 100644 (file)
 
 #include <aio.h>
 #include <errno.h>
-#include <semaphore.h>
+#include <stdlib.h>
 
 #include "aio_misc.h"
 
 
+/* We need this special structure to handle asynchronous I/O.  */
+struct async_waitlist
+  {
+    int counter;
+    struct sigevent sigev;
+    struct waitlist list[0];
+  };
+
+
 int
 lio_listio64 (mode, list, nent, sig)
      int mode;
@@ -32,8 +41,9 @@ lio_listio64 (mode, list, nent, sig)
      int nent;
      struct sigevent *sig;
 {
+  struct requestlist *requests[nent];
   int cnt;
-  int total = 0;
+  volatile int total = 0;
   int result = 0;
 
   /* Check arguments.  */
@@ -43,24 +53,99 @@ lio_listio64 (mode, list, nent, sig)
       return -1;
     }
 
-  /* Request the semaphore.  */
-  sem_wait (&__aio_requests_sema);
+  /* Request the mutex.  */
+  pthread_mutex_lock (&__aio_requests_mutex);
 
   /* Now we can enqueue all requests.  Since we already acquired the
-     semaphore the enqueue function need not do this.  */
+     mutex the enqueue function need not do this.  */
   for (cnt = 0; cnt < nent; ++cnt)
     if (list[cnt] != NULL && list[cnt]->aio_lio_opcode != LIO_NOP)
-      if (__aio_enqueue_request ((aiocb_union *) list[cnt],
-                                list[cnt]->aio_lio_opcode | 128, 0) >= 0)
-       /* Successfully enqueued.  */
-       ++total;
+      {
+       requests[cnt] = __aio_enqueue_request ((aiocb_union *) list[cnt],
+                                              (list[cnt]->aio_lio_opcode
+                                               | 128));
+       if (requests[cnt] != NULL)
+         /* Successfully enqueued.  */
+         ++total;
+       else
+         /* Signal that we've seen an error.  `errno' and the error code
+            of the aiocb will tell more.  */
+         result = -1;
+      }
+
+  if (total == 0)
+    {
+      /* We don't have anything to do except signalling if we work
+        asynchronously.  */
+      if (mode == LIO_NOWAIT)
+       __aio_notify_only (sig);
+    }
+  else if (mode == LIO_WAIT)
+    {
+      pthread_cond_t cond;
+      struct waitlist waitlist[nent];
+      int oldstate;
+
+      total = 0;
+      for (cnt = 0; cnt < nent; ++cnt)
+       if (list[cnt] != NULL && list[cnt]->aio_lio_opcode != LIO_NOP
+           && requests[cnt] != NULL)
+         {
+           waitlist[cnt].cond = &cond;
+           waitlist[cnt].next = requests[cnt]->waiting;
+           waitlist[cnt].counterp = &total;
+           waitlist[cnt].sigevp = NULL;
+           requests[cnt]->waiting = &waitlist[cnt];
+           ++total;
+         }
+
+      /* Since `pthread_cond_wait'/`pthread_cond_timedwait' are cancelation
+        points we must be careful.  We added entries to the waiting lists
+        which we must remove.  So defer cancelation for now.  */
+      pthread_setcancelstate (PTHREAD_CANCEL_DISABLE, &oldstate);
+
+      while (total > 0)
+       pthread_cond_wait (&cond, &__aio_requests_mutex);
+
+      /* Now it's time to restore the cancelation state.  */
+      pthread_setcancelstate (oldstate, NULL);
+    }
+  else
+    {
+      struct async_waitlist *waitlist;
+
+      waitlist = (struct async_waitlist *)
+       malloc (sizeof (struct async_waitlist)
+               + (nent * sizeof (struct waitlist)));
+
+      if (waitlist == NULL)
+       {
+         __set_errno (EAGAIN);
+         result = -1;
+       }
       else
-       /* Signal that we've seen an error.  `errno' and the error code
-          of the aiocb will tell more.  */
-       result = -1;
+       {
+         total = 0;
+
+         for (cnt = 0; cnt < nent; ++cnt)
+           if (list[cnt] != NULL && list[cnt]->aio_lio_opcode != LIO_NOP
+               && requests[cnt] != NULL)
+             {
+               waitlist->list[cnt].cond = NULL;
+               waitlist->list[cnt].next = requests[cnt]->waiting;
+               waitlist->list[cnt].counterp = &waitlist->counter;
+               waitlist->list[cnt].sigevp = &waitlist->sigev;
+               requests[cnt]->waiting = &waitlist->list[cnt];
+               ++total;
+             }
+
+         waitlist->counter = total;
+         waitlist->sigev = *sig;
+       }
+    }
 
-  /* Release the semaphore.  */
-  sem_post (&__aio_requests_sema);
+  /* Release the mutex.  */
+  pthread_mutex_unlock (&__aio_requests_mutex);
 
   return result;
 }
index 403eecf76102463b9549e3f93eb0b8b32d9a2733..8c4638d40de1c4798072ea5f2b724a7d6825355e 100644 (file)
@@ -17,6 +17,7 @@
    Boston, MA 02111-1307, USA.  */
 
 #include <ctype.h>
+#include <errno.h>
 #include <shadow.h>
 #include <stdio.h>
 
@@ -28,7 +29,7 @@
 #define        EXTERN_PARSER   1
 struct spent_data {};
 
-#include "../nss/nss_files/files-parse.c"
+#include <nss/nss_files/files-parse.c>
 
 
 /* Read one shadow entry from the given stream.  */
@@ -53,7 +54,8 @@ __fgetspent_r (FILE *stream, struct spwd *resbuf, char *buffer, size_t buflen,
     } 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 (buffer, (void *) resbuf, NULL, 0));
+            ! parse_line (buffer, (void *) resbuf, NULL, 0,
+                          __errno_location ()));
 
   *result = resbuf;
   return 0;
index 01f0115164ec4a2f49c0e90da7aa857bdccee021..f3e322aa879f9810a9c40d5384791246784539e4 100644 (file)
@@ -17,6 +17,7 @@
    Boston, MA 02111-1307, USA.  */
 
 #include <ctype.h>
+#include <errno.h>
 #include <shadow.h>
 #include <stdio.h>
 #include <string.h>
@@ -91,7 +92,7 @@ __sgetspent_r (const char *string, struct spwd *resbuf, char *buffer,
               size_t buflen, struct spwd **result)
 {
   int parse_result = parse_line (strncpy (buffer, string, buflen),
-                                resbuf, NULL, 0);
+                                resbuf, NULL, 0, __errno_location ());
   *result = parse_result > 0 ? resbuf : NULL;
 
   return *result == NULL ? errno : 0;
index 3c221d7c99a0cee644f3acf1d21b7d0c8a907aef..988a81da5c9b4000a855dd37f226b8f65e7cd0cd 100644 (file)
@@ -56,22 +56,14 @@ alpha-.*-linux.*    libresolv=2.1
 # Interface revision of nss_* modules.  This must match NSS_SHLIB_REVISION
 # in nss/nsswitch.h, which determines the library names used for service
 # names given in /etc/nsswitch.conf.
-alpha-.*-linux.*       libnss_files=1.1
-alpha-.*-linux.*       libnss_dns=1.1
-alpha-.*-linux.*       libnss_db=1.1
-alpha-.*-linux.*       libnss_compat=1.1
-alpha-.*-linux.*       libnss_nis=1.1
-alpha-.*-linux.*       libnss_nisplus=1.1
-alpha-.*-linux.*       libnss_ldap=1.1
-alpha-.*-linux.*       libnss_hesiod=1.1
-.*-.*-.*               libnss_files=1
-.*-.*-.*               libnss_dns=1
-.*-.*-.*               libnss_db=1
-.*-.*-.*               libnss_compat=1
-.*-.*-.*               libnss_nis=1
-.*-.*-.*               libnss_nisplus=1
-.*-.*-.*               libnss_ldap=1
-.*-.*-.*               libnss_hesiod=1
+.*-.*-.*               libnss_files=2
+.*-.*-.*               libnss_dns=2
+.*-.*-.*               libnss_db=2
+.*-.*-.*               libnss_compat=2
+.*-.*-.*               libnss_nis=2
+.*-.*-.*               libnss_nisplus=2
+.*-.*-.*               libnss_ldap=2
+.*-.*-.*               libnss_hesiod=2
 
 # Version for libnsl with YP and NIS+ functions.
 alpha-.*-linux.*       libnsl=1.1
index 3f65ae99a33ef49fb5dc66c45ae99cb32cb89729..bc93087066fb4b5ae046bba82965193932f0799d 100644 (file)
@@ -166,7 +166,7 @@ elf_machine_runtime_setup (struct link_map *l, int lazy, int profile)
        mov     $26, $18
        addq    $17, $17, $17
        /* Do the fixup */
-       bsr     $26, " #fixup_name "..ng
+       bsr     $26, " ASM_ALPHA_NG_SYMBOL_PREFIX #fixup_name "..ng
        /* Move the destination address into position.  */
        mov     $0, $27
        /* Restore program registers.  */
@@ -221,7 +221,7 @@ _start:
 0:     ldgp    $gp, 0($gp)
        /* Pass pointer to argument block to _dl_start.  */
        mov     $sp, $16
-       bsr     $26, _dl_start..ng
+       bsr     $26, "ASM_ALPHA_NG_SYMBOL_PREFIX"_dl_start..ng
        .end _start
        /* FALLTHRU */
        .globl _dl_start_user
index 366cdf8ce2295f94bd46e6516e2f93849d304ebb..d0745895621255934e4a37627bd5f1f130859f91 100644 (file)
@@ -26,3 +26,12 @@ struct dirent
     char d_name[1];            /* Variable length.  */
     int d_fileno;
   };
+
+#ifdef __USE_LARGEFILE64
+struct dirent64
+  {
+    char d_name[1];            /* Variable length.  */
+    int d_fileno;
+  };
+#endif
+
index d0ebeb56c8346a9bcb0ee6b516026a776ab1a58b..e72836d3c742f3bd426bca4d693ef7ceb9679394 100644 (file)
@@ -21,6 +21,8 @@
 # error "Never use <bits/resource.h> directly; include <sys/resource.h> instead."
 #endif
 
+#include <bits/types.h>
+
 /* These are the values for 4.4 BSD and GNU.  Earlier BSD systems have a
    subset of these kinds of resource limit.  In systems where `getrlimit'
    and `setrlimit' are not system calls, these are the values used by the C
index 9fad4538d7872114a97fa06db86e76a3a79c581f..c442d53643ec1c22387189ecd1d3d537ed960186 100644 (file)
@@ -34,7 +34,7 @@ typedef unsigned long int __sigset_t;
    trouble can be caused by functions being defined (e.g., any global
    register vars declared later will cause compilation errors).  */
 
-#if !defined (_SIGSET_H_fns) && defined (_SIGNAL_H)
+#if !defined _SIGSET_H_fns && defined _SIGNAL_H
 #define _SIGSET_H_fns 1
 
 #ifndef _EXTERN_INLINE
index cdbd39f91d97fa30f0fe1d4fba6302e05a62420f..f608e2c99622fcdf664b55ee7923f540365d8578 100644 (file)
@@ -39,8 +39,8 @@
    microsecond but also has a range of years.  */
 struct timeval
   {
-    time_t tv_sec;             /* Seconds.  */
-    time_t tv_usec;            /* Microseconds.  */
+    __time_t tv_sec;           /* Seconds.  */
+    __time_t tv_usec;          /* Microseconds.  */
   };
 # endif        /* struct timeval */
 #endif /* need timeval */
index bd38cb4def7b92c4cf49cfc725d36018c517b72a..59e6b0140b760332c06611b8126876f836b84f69 100644 (file)
@@ -25,7 +25,7 @@ int
 getpeername (fd, addr, len)
      int fd;
      __SOCKADDR_ARG addr;
-     size_t *len;
+     socklen_t *len;
 {
   __set_errno (ENOSYS);
   return -1;
index 8c20b7ead0d4d776835802cd0891a84cb33f2cbb..6caf258e24993a32faf9ac5982478570a44cdd55 100644 (file)
@@ -23,9 +23,9 @@
 /* Do system call CALLNO, passing it the remaining arguments.
    This only makes sense in certain operating systems.  */
 
-int
+long int
 syscall (callno)
-     int callno;
+     long int callno;
 {
   __set_errno (ENOSYS);
   return -1;
index 8c0e851d6de8db15c8a847c5fe8534effe0660cf..9a8dadaed366087de9c1027341ffe10a312b0902 100644 (file)
    write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
    Boston, MA 02111-1307, USA.  */
 
-#include <errno.h>
 #include <unistd.h>
 
 /* Sleep USECONDS microseconds, or until a previously set timer goes off.  */
-unsigned int
+void
 usleep (useconds)
      unsigned int useconds;
 {
-  __set_errno (ENOSYS);
-  return -1;
 }
 
 stub_warning (usleep)
index 6f1db03f2dc20420779754da3cc8024481a2c1e3..026447e7b3f5fbce1b8d89d39be6849eee868deb 100644 (file)
@@ -22,8 +22,7 @@
 /* Wait for a child to die.  When one does, put its status in *STAT_LOC
    and return its process ID.  For errors, return (pid_t) -1.  */
 __pid_t
-__wait (stat_loc)
-     __WAIT_STATUS_DEFN stat_loc;
+__wait (__WAIT_STATUS_DEFN stat_loc)
 {
   __set_errno (ENOSYS);
   return -1;
index 4df9d420df28740287a68ed23f4399bdb7a44d48..b15f0243fceb059770707c6ee3c83ad0bb9fa476 100644 (file)
    there.  If the WUNTRACED bit is set in OPTIONS, return status for stopped
    children; otherwise don't.  */
 pid_t
-__wait3 (stat_loc, options, usage)
-     __WAIT_STATUS_DEFN stat_loc;
-     int options;
-     struct rusage *usage;
+__wait3 (__WAIT_STATUS_DEFN stat_loc, int options, struct rusage *usage)
 {
   if ((options & ~(WNOHANG|WUNTRACED)) != 0)
     {
index d29d80c73e83a8375d8dffb19f7a52044282abca..b2a9169d136a13e8810a23b1bc6548950b9426d6 100644 (file)
 #include <errno.h>
 
 pid_t
-__wait4 (pid, stat_loc, options, usage)
-     pid_t pid;
-     __WAIT_STATUS_DEFN stat_loc;
-     int options;
-     struct rusage *usage;
+__wait4 (__pid_t pid, __WAIT_STATUS stat_loc, int options, 
+        struct rusage *usage)
 {
   __set_errno (ENOSYS);
   return (pid_t) -1;
index 65806a2e683a566f286c9ccbbfae7b72b1a46840..ef4a021881ec381da2ae7b497f7f15e7d612787e 100644 (file)
@@ -54,4 +54,7 @@ __pwrite (int fd, const void *buf, size_t nbyte, off_t offset)
 
   return result;
 }
+
+#ifndef __pwrite
 weak_alias (__pwrite, pwrite)
+#endif
index 777710b08a4a5c153b2c13331ed6f1bc6cde3ad7..efc559dcbcecd7d8de879bfbde1867e12f0791ad 100644 (file)
@@ -1,4 +1,4 @@
-/* Copyright (C) 1991, 1994, 1995, 1996 Free Software Foundation, Inc.
+/* Copyright (C) 1991, 1994, 1995, 1996, 1997 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
 
    The GNU C Library is free software; you can redistribute it and/or
@@ -35,7 +35,7 @@ __sigblock (mask)
   else if (sizeof (unsigned long int) == sizeof (set))
     *(unsigned long int *) &set = (unsigned int) mask;
   else
-    for (sig = 1; sig < NSIG; ++sig)
+    for (sig = 1; sig < NSIG && sig <= sizeof (mask) * 8; ++sig)
       if ((mask & sigmask (sig)) && __sigaddset (&set, sig) < 0)
        return -1;
 
@@ -47,7 +47,7 @@ __sigblock (mask)
   else if (sizeof (unsigned long int) == sizeof (oset))
     mask = *(unsigned long int*) &oset;
   else
-    for (sig = 1, mask = 0; sig < NSIG; ++sig)
+    for (sig = 1, mask = 0; sig < NSIG && sig <= sizeof (mask) * 8; ++sig)
       if (__sigismember (&oset, sig))
        mask |= sigmask (sig);
 
index 034719870d5d90325c507d7eeb229720a4cada5f..fbbdafa3c92055ef7fd84c2d6926533e67efc023 100644 (file)
@@ -1,4 +1,4 @@
-/* Copyright (C) 1991, 1994, 1995, 1996 Free Software Foundation, Inc.
+/* Copyright (C) 1991, 1994, 1995, 1996, 1997 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
 
    The GNU C Library is free software; you can redistribute it and/or
@@ -34,7 +34,7 @@ __sigsetmask (int mask)
   else if (sizeof (unsigned long int) == sizeof (set))
     *(unsigned long int *) &set = (unsigned int) mask;
   else
-    for (sig = 1; sig < NSIG; ++sig)
+    for (sig = 1; sig < NSIG && sig <= sizeof (mask) * 8; ++sig)
       if ((mask & sigmask (sig)) && __sigaddset (&set, sig) < 0)
        return -1;
 
@@ -46,7 +46,7 @@ __sigsetmask (int mask)
   else if (sizeof (unsigned long int) == sizeof (oset))
     mask = *(unsigned long int *) &oset;
   else
-    for (sig = 1, mask = 0; sig < NSIG; ++sig)
+    for (sig = 1, mask = 0; sig < NSIG && sig <= sizeof (mask) * 8; ++sig)
       if (__sigismember (&oset, sig))
        mask |= sigmask (sig);
 
index 59d30f2d29fdf3a3c4135e9c7195559b8d1a6ca3..12285fad66c5f18f88e97ed13d6485540706bb4b 100644 (file)
@@ -1,4 +1,4 @@
-/* Copyright (C) 1991, 92, 94, 95, 96 Free Software Foundation, Inc.
+/* Copyright (C) 1991, 92, 94, 95, 96, 97 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
 
    The GNU C Library is free software; you can redistribute it and/or
@@ -62,7 +62,7 @@ convert_mask (set, mask)
       if (__sigemptyset (set) < 0)
        return -1;
 
-      for (sig = 1; sig < NSIG; ++sig)
+      for (sig = 1; sig < NSIG && sig <= sizeof (mask) * 8; ++sig)
        if ((mask & sigmask (sig)) && __sigaddset (set, sig) < 0)
          return -1;
     }
@@ -138,9 +138,9 @@ __sigvec (sig, vec, ovec)
       else if (sizeof (unsigned long int) == sizeof (sigset_t))
        mask = *(unsigned long int *) &old.sa_mask;
       else
-       for (i = 1; i < NSIG; ++i)
-         if (__sigismember(&old.sa_mask, i))
-           mask |= sigmask(i);
+       for (i = 1; i < NSIG && i <= sizeof (mask) * 8; ++i)
+         if (__sigismember (&old.sa_mask, i))
+           mask |= sigmask (i);
 
       ovec->sv_mask = mask;
       ovec->sv_flags = 0;
index f5020dcb7eea0e476ee72077d5537ab95d8eac52..97dbbd9ce3519646e6b8278ce461c20fb5f1ff0a 100644 (file)
@@ -51,6 +51,7 @@
 # define ESTALE                23
 # define EISDIR                24
 # define EOPNOTSUPP    25      /* Operation not supported.  */
+# define ENOTTY                26
 #endif
 
 #define __set_errno(val) errno = (val)
index 2e33b3c2c69c7aac4237577f668c7c900d30ae95..114d726c6d49e77547267e1c0c4d21c3e85cf967 100644 (file)
@@ -21,6 +21,7 @@
 #include <errno.h>
 #include <unistd.h>
 
+#define _STDIO_H
 #include <bits/stdio_lim.h>
 #include "filedesc.h"
 
index a35d1cf04353cf007e6287a101fb52b80df182a4..d6a12a606a3a0e1ddceed410a00858643466600b 100644 (file)
@@ -26,6 +26,7 @@
 #ifndef __FILEDESC_h
 #define __FILEDESC_h
 
+#define _STDIO_H
 #include <bits/stdio_lim.h>
 
 #ifndef __DECLARE_FILE_DESCRIPTORS__
index ffea9ef4bb0fca87815e4bbec09628183c462a50..6903e0b6cd02ddab7e85ec8b91d7faa9215f037e 100644 (file)
@@ -111,7 +111,8 @@ endif
 
 ifeq ($(subdir),signal)
 sysdep_routines += rt_sigsuspend rt_sigprocmask rt_sigtimedwait        \
-                  rt_sigqueueinfo rt_sigaction
+                  rt_sigqueueinfo rt_sigaction rt_sigpending   \
+                  rt_sigreturn
 endif
 
 common-generated += bits/stdio_lim.h bits/stdio_lim.d
diff --git a/sysdeps/unix/sysv/linux/arm/syscalls.list b/sysdeps/unix/sysv/linux/arm/syscalls.list
new file mode 100644 (file)
index 0000000..392a257
--- /dev/null
@@ -0,0 +1,6 @@
+# File name    Caller  Syscall name    # args  Strong name     Weak names
+
+s_getgroups    getgroups getgroups     2       __syscall_getgroups
+s_llseek       llseek  _llseek         5       __sys_llseek
+s_setgroups    setgroups setgroups     2       __syscall_setgroups
+vm86           -       vm86            1       __vm86          vm86
index 22ce79b3f0e864c460dd36fbe5729b1090c57ad9..9e14aa815fe53cce81fc4bc59945e21bf56a13bb 100644 (file)
@@ -18,6 +18,7 @@
    Boston, MA 02111-1307, USA.  */
 
 #include <sysdep.h>
+#include <asm/errno.h>
 
 /* Please consult the file sysdeps/unix/sysv/linux/i386/sysdep.h for
    more information about the value -4095 used below.*/
        .text
 ENTRY (__syscall_pread64)
 
+#ifndef __NR_pread
+       movl    $-ENOSYS,%eax
+# ifndef PIC
+       jmp     syscall_error
+# endif
+#else
+
        PUSHARGS_5              /* Save register contents.  */
 
        /* Load arguments.  This is unfortunately a little bit of a problem
@@ -41,5 +49,6 @@ ENTRY (__syscall_pread64)
        cmpl    $-4095, %eax    /* Check %eax for error.  */
        jae     syscall_error   /* Jump to error handler if error.  */
        ret                     /* Return to caller.  */
+#endif
 
 PSEUDO_END (__syscall_pread64)
index 6a1987b72e37c18fbc3729fa37ca832e3d3039e8..a21fe2f99fd27c326918205fadebeaf9023e6889 100644 (file)
@@ -18,6 +18,7 @@
    Boston, MA 02111-1307, USA.  */
 
 #include <sysdep.h>
+#include <asm/errno.h>
 
 /* Please consult the file sysdeps/unix/sysv/linux/i386/sysdep.h for
    more information about the value -4095 used below.*/
        .text
 ENTRY (__syscall_pwrite64)
 
+#ifndef __NR_pwrite
+       movl    $-ENOSYS,%eax
+# ifndef PIC
+       jmp     syscall_error
+# endif
+#else
+
        PUSHARGS_5              /* Save register contents.  */
 
        /* Load arguments.  This is unfortunately a little bit of a problem
@@ -41,5 +49,6 @@ ENTRY (__syscall_pwrite64)
        cmpl    $-4095, %eax    /* Check %eax for error.  */
        jae     syscall_error   /* Jump to error handler if error.  */
        ret                     /* Return to caller.  */
+#endif
 
 PSEUDO_END (__syscall_pwrite64)
index 90d61a08a1c7d8da79f5946877d23f527ce00f56..05d187c4322fcdf9bd5d272faae33d1e5310512b 100644 (file)
@@ -47,19 +47,24 @@ __sigaction (int sig, const struct sigaction *act, struct sigaction *oact)
   /* First try the RT signals.  */
   if (__libc_have_rt_sigs)
     {
-      struct sigaction nact;
+      struct sigaction nact, *nactp;
 
-      nact.sa_handler = act->sa_handler;
-      memcpy (&nact.sa_mask, &act->sa_mask, sizeof (sigset_t));
-      nact.sa_flags = act->sa_flags;
+      if (act)
+       {
+         nact.sa_handler = act->sa_handler;
+         memcpy (&nact.sa_mask, &act->sa_mask, sizeof (sigset_t));
+         nact.sa_flags = act->sa_flags;
 
-      nact.sa_restorer = ((act->sa_flags & SA_NOMASK)
-                         ? &&restore_nomask : &&restore);
+         nact.sa_restorer = ((act->sa_flags & SA_NOMASK)
+                             ? &&restore_nomask : &&restore);
+         nactp = &nact;
+       }
+      else
+       nactp = NULL;
 
       /* XXX The size argument hopefully will have to be changed to the
         real size of the user-level sigset_t.  */
-      result = __syscall_rt_sigaction (sig, &nact, oact,
-                                      _NSIG / (8 * sizeof (long int)));
+      result = __syscall_rt_sigaction (sig, nactp, oact, _NSIG / 8);
 
       if (result >= 0 || errno != ENOSYS)
        return result;
index eeb26eb663c6c7f969ec942c4e9bdac954f7dcb3..eb0d301fa16b3e91f57e6c1d5a8cc60ad7300c02 100644 (file)
    write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
    Boston, MA 02111-1307, USA.  */
 
+#include <errno.h>
 #include <unistd.h>
 
+extern ssize_t __syscall_pread64 (int fd, void *buf, size_t count,
+                                 off_t offset_hi, off_t offset_lo);
+
+static ssize_t __emulate_pread (int fd, void *buf, size_t count,
+                               off_t offset) internal_function;
+
+
 ssize_t
-__pread (int fd, void *buf, size_t nbytes, off_t offset)
+__pread (fd, buf, count, offset)
+     int fd;
+     void *buf;
+     size_t count;
+     off_t offset;
 {
-  return __pread64 (fd, buf, nbytes, (off64_t) offset);
+  ssize_t result;
+
+  /* First try the syscall.  */
+  result = __syscall_pread64 (fd, buf, count, 0, offset);
+  if (result == -1 && errno == ENOSYS)
+    /* No system call available.  Use the emulation.  */
+    result = __emulate_pread (fd, buf, count, offset);
+
+  return result;
 }
 
 weak_alias (__pread, pread)
+
+#define __pread(fd, buf, count, offset) \
+     static internal_function __emulate_pread (fd, buf, count, offset)
+#include <sysdeps/posix/pread.c>
index d8695db2a88dd26501a37143794294d99940a3d1..9ab3259fc61cf174c8460d48901ec060a9a95be1 100644 (file)
    write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
    Boston, MA 02111-1307, USA.  */
 
+#include <errno.h>
 #include <unistd.h>
 
+extern ssize_t __syscall_pwrite64 (int fd, const void *buf, size_t count,
+                                  off_t offset_hi, off_t offset_lo);
+
+static ssize_t __emulate_pwrite (int fd, const void *buf, size_t count,
+                                off_t offset) internal_function;
+
+
 ssize_t
-__pwrite (int fd, const void *buf, size_t nbytes, off_t offset)
+__pwrite (fd, buf, count, offset)
+     int fd;
+     const void *buf;
+     size_t count;
+     off_t offset;
 {
-  return __pwrite64 (fd, buf, nbytes, (off64_t) offset);
+  ssize_t result;
+
+  /* First try the syscall.  */
+  result = __syscall_pwrite64 (fd, buf, count, 0, offset);
+  if (result == -1 && errno == ENOSYS)
+    /* No system call available.  Use the emulation.  */
+    result = __emulate_pwrite (fd, buf, count, offset);
+
+  return result;
 }
 
 weak_alias (__pwrite, pwrite)
+
+#define __pwrite(fd, buf, count, offset) \
+     static internal_function __emulate_pwrite (fd, buf, count, offset)
+#include <sysdeps/posix/pwrite.c>
index 161f1b0529c912834d21ef305cdb0dbfc7755cfe..1412c381d030cd5090442fa9a8e9b6783d76c769 100644 (file)
@@ -49,8 +49,7 @@ __sigaction (sig, act, oact)
     {
       /* XXX The size argument hopefully will have to be changed to the
         real size of the user-level sigset_t.  */
-      int result = __syscall_rt_sigaction (sig, act, oact,
-                                          _NSIG / (8 * sizeof (long int)));
+      int result = __syscall_rt_sigaction (sig, act, oact, _NSIG / 8);
 
       if (result >= 0 || errno != ENOSYS)
        return result;
index 7b26bfbf12983d4ea4cd6df7adf6811781dc52e8..4cecb8dc605a11c57f6e7950a589fc4408316013 100644 (file)
@@ -40,8 +40,7 @@ sigpending (set)
     {
       /* XXX The size argument hopefully will have to be changed to the
         real size of the user-level sigset_t.  */
-      int result = __syscall_rt_sigpending (set,
-                                           _NSIG / (8 * sizeof (long int)));
+      int result = __syscall_rt_sigpending (set, _NSIG / 8);
 
       if (result >= 0 || errno != ENOSYS)
        return result;
index f436ba8f2cc5259d37abd143ea83d16390e3058d..dc262c88f4f9a6639b43a1bb915ce9e4fb3bee3e 100644 (file)
@@ -41,8 +41,7 @@ __sigprocmask (how, set, oset)
     {
       /* XXX The size argument hopefully will have to be changed to the
         real size of the user-level sigset_t.  */
-      int result = __syscall_rt_sigprocmask (how, set, oset,
-                                            _NSIG / (8 * sizeof (long int)));
+      int result = __syscall_rt_sigprocmask (how, set, oset, _NSIG / 8);
 
       if (result >= 0 || errno != ENOSYS)
        return result;
index ecef3d67adc3d220d9f6c913d514b4f170755cf0..540dfdf388b594417f0fafaad236267107b9b0c4 100644 (file)
@@ -38,8 +38,7 @@ __sigreturn (scp)
     {
       /* XXX The size argument hopefully will have to be changed to the
         real size of the user-level sigset_t.  */
-      int result = __syscall_rt_sigreturn (scp,
-                                          _NSIG / (8 * sizeof (long int)));
+      int result = __syscall_rt_sigreturn (scp, _NSIG / 8);
 
       if (result >= 0 || errno != ENOSYS)
        return result;
index faea1c35e14b30afbfc77cf5c0004ed5973cbf57..2cf34eb9b1cef179a853451a0ee93e8b08ca2224 100644 (file)
@@ -21,7 +21,7 @@
 #include <unistd.h>
 
 extern int __syscall_sigsuspend (int, unsigned long int, unsigned long int);
-extern int __syscall_rt_sigsuspend (sigset_t *, size_t);
+extern int __syscall_rt_sigsuspend (const sigset_t *, size_t);
 
 
 /* The variable is shared between all wrappers around signal handling
@@ -40,8 +40,7 @@ __sigsuspend (set)
     {
       /* XXX The size argument hopefully will have to be changed to the
         real size of the user-level sigset_t.  */
-      int result = __syscall_rt_sigsuspend (set,
-                                           _NSIG / (8 * sizeof (long int)));
+      int result = __syscall_rt_sigsuspend (set, _NSIG / 8);
 
       if (result >= 0 || errno != ENOSYS)
        return result;
index b022ec35f72128fbdc830ee412998a830b108f14..90854c64d9ccc04b77ddaacf7caf44f9ebf1717f 100644 (file)
@@ -31,7 +31,6 @@ __sigtimedwait (set, info, timeout)
 {
   /* XXX The size argument hopefully will have to be changed to the
      real size of the user-level sigset_t.  */
-  return __syscall_rt_sigtimedwait (set, info, timeout,
-                                   _NSIG / (8 * sizeof (long int)));
+  return __syscall_rt_sigtimedwait (set, info, timeout, _NSIG / 8);
 }
 weak_alias (__sigtimedwait, sigtimedwait)
index ac98fb46e097aa2d820d5cc0bcfb5972849b9844..5f41ba054b6a249b7be05b7feb74de3d4b27f545 100644 (file)
@@ -30,7 +30,6 @@ __sigwaitinfo (set, info)
 {
   /* XXX The size argument hopefully will have to be changed to the
      real size of the user-level sigset_t.  */
-  return __syscall_rt_sigtimedwait (set, info, NULL,
-                                   _NSIG / (8 * sizeof (long int)));
+  return __syscall_rt_sigtimedwait (set, info, NULL, _NSIG / 8);
 }
 weak_alias (__sigwaitinfo, sigwaitinfo)
index 08dceca3f622fa52ecc5ab72b7c24659f9cc2500..ed760af2ab9a8042324c4eb7b7ff7d2614e201b8 100644 (file)
@@ -35,13 +35,13 @@ pipe                -       pipe            1       __pipe          pipe
 prctl          EXTRA   prctl           5       prctl
 query_module   EXTRA   query_module    5       query_module
 quotactl       EXTRA   quotactl        4       quotactl
-rt_sigaction   sigaction       rt_sigaction    4       __syscall_rt_sigaction
-rt_sigpending  sigpendding     rt_sigpending   2       __syscall_rt_sigpending
-rt_sigprocmask sigprocmask     rt_sigprocmask  4       __syscall_rt_sigprocmask
-rt_sigqueueinfo        sigqueue        rt_sigqueueinfo 3       __syscall_rt_sigqueueinfo
-rt_sigreturn   sigreturn       rt_sigreturn    1       __syscall_rt_sigreturn
-rt_sigsuspend  sigsuspend      rt_sigsuspend   2       __syscall_rt_sigsuspend
-rt_sigtimedwait        sigtimedwait    rt_sigtimedwait 4       __syscall_rt_sigtimedwait
+rt_sigaction   -       rt_sigaction    4       __syscall_rt_sigaction
+rt_sigpending  -       rt_sigpending   2       __syscall_rt_sigpending
+rt_sigprocmask -       rt_sigprocmask  4       __syscall_rt_sigprocmask
+rt_sigqueueinfo        -       rt_sigqueueinfo 3       __syscall_rt_sigqueueinfo
+rt_sigreturn   -       rt_sigreturn    1       __syscall_rt_sigreturn
+rt_sigsuspend        rt_sigsuspend   2       __syscall_rt_sigsuspend
+rt_sigtimedwait        -       rt_sigtimedwait 4       __syscall_rt_sigtimedwait
 s_getdents     EXTRA   getdents        3       __getdents
 s_getpriority  getpriority getpriority 2       __syscall_getpriority
 s_poll         poll    poll            3       __syscall_poll
index 5661d79d1dd6e468269c75ae25fe0319f3053fe1..36bfb62e73c1169ca12483d34be0b8daad94cc70 100644 (file)
@@ -1 +1,5 @@
 inttypes.h
+strtoimax.c
+strtoumax.c
+wcstoimax.c
+wcstoumax.c
index 87ced71ec1c45212a2a3edee36a761d53159fe5f..b22eaee1770b016dec9aa15600e0a81c656b1910 100644 (file)
@@ -1,3 +1,5 @@
 ifeq ($(subdir),stdlib)
 sysdep_headers += inttypes.h
+
+sysdep_routines += strtoimax strtoumax wcstoimax wcstoumax
 endif
index 371b40bb3db2db0e3b2b5fa4eab3878f446683f8..f569be5b5168065b8c6de806c8c4dada9e42cacc 100644 (file)
@@ -373,57 +373,84 @@ typedef unsigned long long int uint_fast64_t;
 /* Macros for string conversion.  */
 
 /* Like `strtol' but convert to `intmax_t'.  */
-#define strtoimax(nptr, endptr, base) \
-    __strtoll_internal (nptr, endptr, base, 0)
+extern intmax_t strtoimax __P ((__const char *__restrict __nptr,
+                               char **__restrict __endptr, int __base));
 
-#ifndef __strtoll_internal_defined
+/* Like `strtoul' but convert to `uintmax_t'.  */
+extern uintmax_t strtoumax __P ((__const char * __restrict __nptr,
+                                char ** __restrict __endptr, int __base));
+
+/* Like `wcstol' but convert to `intmax_t'.  */
+extern intmax_t wcstoimax __P ((__const wchar_t * __restrict __nptr,
+                               wchar_t **__restrict __endptr, int __base));
+
+/* Like `wcstoul' but convert to `uintmax_t'.  */
+extern uintmax_t wcstoumax __P ((__const wchar_t * __restrict __nptr,
+                                wchar_t ** __restrict __endptr, int __base));
+
+#if defined __GNUC__ && __GNUC__ >= 2 && defined __OPTIMIZE__
+
+/* Like `strtol' but convert to `intmax_t'.  */
+# ifndef __strtoll_internal_defined
 extern long long int __strtoll_internal __P ((__const char *__restrict __nptr,
                                              char **__restrict __endptr,
                                              int __base, int __group));
-# define __strtoll_internal_defined    1
-#endif
-
+#  define __strtoll_internal_defined   1
+# endif
+extern __inline intmax_t
+strtoimax (__const char *__restrict nptr, char **__restrict endptr, int base)
+{
+  return __strtoll_internal (nptr, endptr, base, 0);
+}
 
 /* Like `strtoul' but convert to `uintmax_t'.  */
-#define strtoumax(nptr, endptr, base) \
-    __strtoull_internal (nptr, endptr, base, 0)
-
-#ifndef __strtoull_internal_defined
+# ifndef __strtoull_internal_defined
 extern unsigned long long int __strtoull_internal __P ((__const char *
                                                        __restrict __nptr,
                                                        char **
                                                        __restrict __endptr,
                                                        int __base,
                                                        int __group));
-# define __strtoull_internal_defined   1
-#endif
-
+#  define __strtoull_internal_defined  1
+# endif
+extern __inline uintmax_t
+strtoumax (__const char *__restrict nptr, char **__restrict endptr, int base)
+{
+  return __strtoull_internal (nptr, endptr, base, 0);
+}
 
 /* Like `wcstol' but convert to `intmax_t'.  */
-#define wcstoimax(nptr, endptr, base) \
-    __wcstoll_internal (nptr, endptr, base, 0)
-
-#ifndef __wcstoll_internal_defined
+# ifndef __wcstoll_internal_defined
 extern long long int __wcstoll_internal __P ((__const wchar_t *
                                              __restrict __nptr,
                                              wchar_t **__restrict __endptr,
                                              int __base, int __group));
-# define __wcstoll_internal_defined    1
-#endif
+#  define __wcstoll_internal_defined   1
+# endif
+extern __inline intmax_t
+wcstoimax (__const wchar_t *__restrict nptr, wchar_t **__restrict endptr,
+          int base)
+{
+  return __wcstoll_internal (nptr, endptr, base, 0);
+}
 
 
 /* Like `wcstoul' but convert to `uintmax_t'.  */
-#define wcstoumax(nptr, endptr, base) \
-    __wcstoull_internal (nptr, endptr, base, 0)
-
-#ifndef __wcstoull_internal_defined
+# ifndef __wcstoull_internal_defined
 extern unsigned long long int __wcstoull_internal __P ((__const wchar_t *
                                                        __restrict __nptr,
                                                        wchar_t **
                                                        __restrict __endptr,
                                                        int __base,
                                                        int __group));
-# define __wcstoull_internal_defined   1
-#endif
+#  define __wcstoull_internal_defined  1
+# endif
+extern __inline uintmax_t
+wcstoumax (__const wchar_t *__restrict nptr, wchar_t **__restrict endptr,
+          int base)
+{
+  return __wcstoull_internal (nptr, endptr, base, 0);
+}
+#endif /* GCC and Optimization.  */
 
 #endif /* inttypes.h */
diff --git a/sysdeps/wordsize-32/strtoimax.c b/sysdeps/wordsize-32/strtoimax.c
new file mode 100644 (file)
index 0000000..a57bc3a
--- /dev/null
@@ -0,0 +1,28 @@
+/* Convert string to maximal integer.
+   Copyright (C) 1997 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Library General Public License as
+   published by the Free Software Foundation; either version 2 of the
+   License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Library General Public License for more details.
+
+   You should have received a copy of the GNU Library General Public
+   License along with the GNU C Library; see the file COPYING.LIB.  If not,
+   write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+   Boston, MA 02111-1307, USA.  */
+
+#include <inttypes.h>
+#include <stdlib.h>
+
+intmax_t
+strtoimax (const char *__restrict nptr, char **__restrict endptr, int base)
+{
+  return __strtoll_internal (nptr, endptr, base, 0);
+}
diff --git a/sysdeps/wordsize-32/strtoumax.c b/sysdeps/wordsize-32/strtoumax.c
new file mode 100644 (file)
index 0000000..6b05ad9
--- /dev/null
@@ -0,0 +1,28 @@
+/* Convert string to maximal unsigned integer.
+   Copyright (C) 1997 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Library General Public License as
+   published by the Free Software Foundation; either version 2 of the
+   License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Library General Public License for more details.
+
+   You should have received a copy of the GNU Library General Public
+   License along with the GNU C Library; see the file COPYING.LIB.  If not,
+   write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+   Boston, MA 02111-1307, USA.  */
+
+#include <inttypes.h>
+#include <stdlib.h>
+
+uintmax_t
+strtoumax (const char *__restrict nptr, char **__restrict endptr, int base)
+{
+  return __strtoull_internal (nptr, endptr, base, 0);
+}
diff --git a/sysdeps/wordsize-32/wcstoimax.c b/sysdeps/wordsize-32/wcstoimax.c
new file mode 100644 (file)
index 0000000..63e78d1
--- /dev/null
@@ -0,0 +1,29 @@
+/* Convert wide-character string to maximal integer.
+   Copyright (C) 1997 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Library General Public License as
+   published by the Free Software Foundation; either version 2 of the
+   License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Library General Public License for more details.
+
+   You should have received a copy of the GNU Library General Public
+   License along with the GNU C Library; see the file COPYING.LIB.  If not,
+   write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+   Boston, MA 02111-1307, USA.  */
+
+#include <inttypes.h>
+#include <wchar.h>
+
+intmax_t
+wcstoimax (const wchar_t *__restrict nptr, wchar_t **__restrict endptr,
+          int base)
+{
+  return __wcstoll_internal (nptr, endptr, base, 0);
+}
diff --git a/sysdeps/wordsize-32/wcstoumax.c b/sysdeps/wordsize-32/wcstoumax.c
new file mode 100644 (file)
index 0000000..b6f29f4
--- /dev/null
@@ -0,0 +1,29 @@
+/* Convert wide-character string to maximal unsigned integer.
+   Copyright (C) 1997 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Library General Public License as
+   published by the Free Software Foundation; either version 2 of the
+   License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Library General Public License for more details.
+
+   You should have received a copy of the GNU Library General Public
+   License along with the GNU C Library; see the file COPYING.LIB.  If not,
+   write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+   Boston, MA 02111-1307, USA.  */
+
+#include <inttypes.h>
+#include <wchar.h>
+
+uintmax_t
+wcstoumax (const wchar_t *__restrict nptr, wchar_t **__restrict endptr,
+          int base)
+{
+  return __wcstoull_internal (nptr, endptr, base, 0);
+}
index 5661d79d1dd6e468269c75ae25fe0319f3053fe1..36bfb62e73c1169ca12483d34be0b8daad94cc70 100644 (file)
@@ -1 +1,5 @@
 inttypes.h
+strtoimax.c
+strtoumax.c
+wcstoimax.c
+wcstoumax.c
index 87ced71ec1c45212a2a3edee36a761d53159fe5f..b22eaee1770b016dec9aa15600e0a81c656b1910 100644 (file)
@@ -1,3 +1,5 @@
 ifeq ($(subdir),stdlib)
 sysdep_headers += inttypes.h
+
+sysdep_routines += strtoimax strtoumax wcstoimax wcstoumax
 endif
index 5f11fc9cb1106bc81c1a3bc966887582eab0670b..c62d516c4b3a5740b158fb58a07ea479a5ee9464 100644 (file)
@@ -373,53 +373,80 @@ typedef unsigned long int uint_fast64_t;
 /* Macros for string conversion.  */
 
 /* Like `strtol' but convert to `intmax_t'.  */
-#define strtoimax(nptr, endptr, base) \
-    __strtol_internal (nptr, endptr, base, 0)
+extern intmax_t strtoimax __P ((__const char *__restrict __nptr,
+                               char **__restrict __endptr, int __base));
 
-#ifndef __strtol_internal_defined
+/* Like `strtoul' but convert to `uintmax_t'.  */
+extern uintmax_t strtoumax __P ((__const char * __restrict __nptr,
+                                char ** __restrict __endptr, int __base));
+
+/* Like `wcstol' but convert to `intmax_t'.  */
+extern intmax_t wcstoimax __P ((__const wchar_t * __restrict __nptr,
+                               wchar_t **__restrict __endptr, int __base));
+
+/* Like `wcstoul' but convert to `uintmax_t'.  */
+extern uintmax_t wcstoumax __P ((__const wchar_t * __restrict __nptr,
+                                wchar_t ** __restrict __endptr, int __base));
+
+#if defined __GNUC__ && __GNUC__ >= 2 && defined __OPTIMIZE__
+
+/* Like `strtol' but convert to `intmax_t'.  */
+# ifndef __strtol_internal_defined
 extern long int __strtol_internal __P ((__const char *__restrict __nptr,
                                        char **__restrict __endptr,
                                        int __base, int __group));
-# define __strtol_internal_defined     1
-#endif
-
+#  define __strtol_internal_defined    1
+# endif
+extern __inline intmax_t
+strtoimax (__const char *__restrict nptr, char **__restrict endptr, int base)
+{
+  return __strtol_internal (nptr, endptr, base, 0);
+}
 
 /* Like `strtoul' but convert to `uintmax_t'.  */
-#define strtoumax(nptr, endptr, base) \
-    __strtoul_internal (nptr, endptr, base, 0)
-
-#ifndef __strtoul_internal_defined
+# ifndef __strtoul_internal_defined
 extern unsigned long int __strtoul_internal __P ((__const char *
                                                  __restrict __nptr,
-                                                 char **__restrict __endptr,
+                                                 char ** __restrict __endptr,
                                                  int __base, int __group));
-# define __strtoul_internal_defined    1
-#endif
-
+#  define __strtoul_internal_defined   1
+# endif
+extern __inline uintmax_t
+strtoumax (__const char *__restrict nptr, char **__restrict endptr, int base)
+{
+  return __strtoul_internal (nptr, endptr, base, 0);
+}
 
 /* Like `wcstol' but convert to `intmax_t'.  */
-#define wcstoimax(nptr, endptr, base) \
-    __wcstol_internal (nptr, endptr, base, 0)
-
-#ifndef __wcstol_internal_defined
-extern long int __wcstol_internal __P ((__const wchar_t *__restrict __nptr,
+# ifndef __wcstol_internal_defined
+extern long int __wcstol_internal __P ((__const wchar_t * __restrict __nptr,
                                        wchar_t **__restrict __endptr,
                                        int __base, int __group));
-# define __wcstol_internal_defined     1
-#endif
+#  define __wcstol_internal_defined    1
+# endif
+extern __inline intmax_t
+wcstoimax (__const wchar_t *__restrict nptr, wchar_t **__restrict endptr,
+          int base)
+{
+  return __wcstol_internal (nptr, endptr, base, 0);
+}
 
 
 /* Like `wcstoul' but convert to `uintmax_t'.  */
-#define wcstoumax(nptr, endptr, base) \
-    __wcstoul_internal (nptr, endptr, base, 0)
-
-#ifndef __wcstoul_internal_defined
+# ifndef __wcstoul_internal_defined
 extern unsigned long int __wcstoul_internal __P ((__const wchar_t *
                                                  __restrict __nptr,
                                                  wchar_t **
                                                  __restrict __endptr,
                                                  int __base, int __group));
-# define __wcstoul_internal_defined    1
-#endif
+#  define __wcstoul_internal_defined   1
+# endif
+extern __inline uintmax_t
+wcstoumax (__const wchar_t *__restrict nptr, wchar_t **__restrict endptr,
+          int base)
+{
+  return __wcstoul_internal (nptr, endptr, base, 0);
+}
+#endif /* GCC and Optimization.  */
 
 #endif /* inttypes.h */
diff --git a/sysdeps/wordsize-64/strtoimax.c b/sysdeps/wordsize-64/strtoimax.c
new file mode 100644 (file)
index 0000000..f26f271
--- /dev/null
@@ -0,0 +1,28 @@
+/* Convert string to maximal integer.
+   Copyright (C) 1997 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Library General Public License as
+   published by the Free Software Foundation; either version 2 of the
+   License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Library General Public License for more details.
+
+   You should have received a copy of the GNU Library General Public
+   License along with the GNU C Library; see the file COPYING.LIB.  If not,
+   write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+   Boston, MA 02111-1307, USA.  */
+
+#include <inttypes.h>
+#include <stdlib.h>
+
+intmax_t
+strtoimax (const char *__restrict nptr, char **__restrict endptr, int base)
+{
+  return __strtol_internal (nptr, endptr, base, 0);
+}
diff --git a/sysdeps/wordsize-64/strtoumax.c b/sysdeps/wordsize-64/strtoumax.c
new file mode 100644 (file)
index 0000000..90d9be9
--- /dev/null
@@ -0,0 +1,28 @@
+/* Convert string to maximal unsigned integer.
+   Copyright (C) 1997 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Library General Public License as
+   published by the Free Software Foundation; either version 2 of the
+   License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Library General Public License for more details.
+
+   You should have received a copy of the GNU Library General Public
+   License along with the GNU C Library; see the file COPYING.LIB.  If not,
+   write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+   Boston, MA 02111-1307, USA.  */
+
+#include <inttypes.h>
+#include <stdlib.h>
+
+uintmax_t
+strtoumax (const char *__restrict nptr, char **__restrict endptr, int base)
+{
+  return __strtoul_internal (nptr, endptr, base, 0);
+}
diff --git a/sysdeps/wordsize-64/wcstoimax.c b/sysdeps/wordsize-64/wcstoimax.c
new file mode 100644 (file)
index 0000000..d6d992b
--- /dev/null
@@ -0,0 +1,29 @@
+/* Convert wide-character string to maximal integer.
+   Copyright (C) 1997 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Library General Public License as
+   published by the Free Software Foundation; either version 2 of the
+   License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Library General Public License for more details.
+
+   You should have received a copy of the GNU Library General Public
+   License along with the GNU C Library; see the file COPYING.LIB.  If not,
+   write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+   Boston, MA 02111-1307, USA.  */
+
+#include <inttypes.h>
+#include <wchar.h>
+
+intmax_t
+wcstoimax (const wchar_t *__restrict nptr, wchar_t **__restrict endptr,
+          int base)
+{
+  return __wcstol_internal (nptr, endptr, base, 0);
+}
diff --git a/sysdeps/wordsize-64/wcstoumax.c b/sysdeps/wordsize-64/wcstoumax.c
new file mode 100644 (file)
index 0000000..c206525
--- /dev/null
@@ -0,0 +1,29 @@
+/* Convert wide-character string to maximal unsigned integer.
+   Copyright (C) 1997 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Library General Public License as
+   published by the Free Software Foundation; either version 2 of the
+   License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Library General Public License for more details.
+
+   You should have received a copy of the GNU Library General Public
+   License along with the GNU C Library; see the file COPYING.LIB.  If not,
+   write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+   Boston, MA 02111-1307, USA.  */
+
+#include <inttypes.h>
+#include <wchar.h>
+
+uintmax_t
+wcstoumax (const wchar_t *__restrict nptr, wchar_t **__restrict endptr,
+          int base)
+{
+  return __wcstoul_internal (nptr, endptr, base, 0);
+}
index 3e039adfa4eee8ddc33748d66435b1cb34e6c92b..c9276dab01808659f5e5411e637c2d051d55f93e 100644 (file)
@@ -192,6 +192,17 @@ extern size_t strftime __P ((char *__restrict __s, size_t __maxsize,
                             __const char *__restrict __format,
                             __const struct tm *__restrict __tp));
 
+#ifdef __USE_ISOC9X
+/* Format TP into S according to FORMAT.
+   Write no more than MAXSIZE characters and return the number
+   of characters written, or 0 if it would exceed MAXSIZE.  */
+extern size_t strfxtime __P ((char *__restrict __s, size_t __maxsize,
+                             __const char *__restrict __format,
+                             __const struct tmx *__restrict __tp));
+
+
+#endif
+
 # ifdef __USE_XOPEN
 /* Parse S according to FORMAT and store binary time information in TP.
    The return value is a pointer to the first unparsed character in S.  */