aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorUlrich Drepper <drepper@redhat.com>1997-12-08 03:06:47 +0000
committerUlrich Drepper <drepper@redhat.com>1997-12-08 03:06:47 +0000
commitd71b808a96f0fd1b6cd82c41698b518bf345692b (patch)
tree7b86cfd6b465c72888d7e85a61c08cafabf5747b
parentUpdate. (diff)
downloadglibc-d71b808a96f0fd1b6cd82c41698b518bf345692b.tar.gz
glibc-d71b808a96f0fd1b6cd82c41698b518bf345692b.tar.bz2
glibc-d71b808a96f0fd1b6cd82c41698b518bf345692b.zip
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.
-rw-r--r--ChangeLog199
-rw-r--r--FAQ.in3
-rw-r--r--Makeconfig2
-rw-r--r--Makefile2
-rw-r--r--bits/dirent.h9
-rw-r--r--bits/resource.h2
-rw-r--r--bits/sigset.h2
-rw-r--r--bits/time.h4
-rw-r--r--config.h.in3
-rwxr-xr-xconfigure171
-rw-r--r--configure.in23
-rw-r--r--grp/fgetgrent_r.c6
-rw-r--r--hesiod/nss_hesiod/hesiod-grp.c20
-rw-r--r--hesiod/nss_hesiod/hesiod-pwd.c20
-rw-r--r--hesiod/nss_hesiod/hesiod-service.c16
-rw-r--r--inet/getnetgrent_r.c14
-rw-r--r--inet/netgroup.h2
-rw-r--r--io/sys/stat.h2
-rw-r--r--libc.map17
-rw-r--r--malloc/malloc.c2
-rw-r--r--nis/nisplus-parser.h10
-rw-r--r--nis/nss_compat/compat-grp.c155
-rw-r--r--nis/nss_compat/compat-pwd.c236
-rw-r--r--nis/nss_compat/compat-spwd.c161
-rw-r--r--nis/nss_nis/nis-alias.c36
-rw-r--r--nis/nss_nis/nis-ethers.c31
-rw-r--r--nis/nss_nis/nis-grp.c34
-rw-r--r--nis/nss_nis/nis-hosts.c46
-rw-r--r--nis/nss_nis/nis-netgrp.c7
-rw-r--r--nis/nss_nis/nis-network.c32
-rw-r--r--nis/nss_nis/nis-proto.c31
-rw-r--r--nis/nss_nis/nis-publickey.c11
-rw-r--r--nis/nss_nis/nis-pwd.c34
-rw-r--r--nis/nss_nis/nis-rpc.c24
-rw-r--r--nis/nss_nis/nis-service.c38
-rw-r--r--nis/nss_nis/nis-spwd.c27
-rw-r--r--nis/nss_nisplus/nisplus-alias.c73
-rw-r--r--nis/nss_nisplus/nisplus-ethers.c96
-rw-r--r--nis/nss_nisplus/nisplus-grp.c59
-rw-r--r--nis/nss_nisplus/nisplus-hosts.c131
-rw-r--r--nis/nss_nisplus/nisplus-netgrp.c16
-rw-r--r--nis/nss_nisplus/nisplus-network.c125
-rw-r--r--nis/nss_nisplus/nisplus-parser.c96
-rw-r--r--nis/nss_nisplus/nisplus-proto.c93
-rw-r--r--nis/nss_nisplus/nisplus-publickey.c60
-rw-r--r--nis/nss_nisplus/nisplus-pwd.c78
-rw-r--r--nis/nss_nisplus/nisplus-rpc.c103
-rw-r--r--nis/nss_nisplus/nisplus-service.c99
-rw-r--r--nis/nss_nisplus/nisplus-spwd.c50
-rw-r--r--nss/getXXbyYY_r.c8
-rw-r--r--nss/getXXent_r.c9
-rw-r--r--nss/nss_db/db-XXX.c22
-rw-r--r--nss/nss_db/db-alias.c13
-rw-r--r--nss/nss_db/db-netgrp.c8
-rw-r--r--nss/nss_files/files-XXX.c23
-rw-r--r--nss/nss_files/files-alias.c13
-rw-r--r--nss/nss_files/files-netgrp.c10
-rw-r--r--nss/nss_files/files-parse.c10
-rw-r--r--posix/sys/wait.h2
-rw-r--r--pwd/fgetpwent_r.c8
-rw-r--r--rt/Makefile3
-rw-r--r--rt/aio.h39
-rw-r--r--rt/aio_cancel.c195
-rw-r--r--rt/aio_fsync.c2
-rw-r--r--rt/aio_misc.c588
-rw-r--r--rt/aio_misc.h81
-rw-r--r--rt/aio_notify.c97
-rw-r--r--rt/aio_read.c2
-rw-r--r--rt/aio_read64.c2
-rw-r--r--rt/aio_suspend.c79
-rw-r--r--rt/aio_write.c2
-rw-r--r--rt/aio_write64.c2
-rw-r--r--rt/lio_listio.c112
-rw-r--r--rt/lio_listio64.c113
-rw-r--r--shadow/fgetspent_r.c6
-rw-r--r--shadow/sgetspent_r.c3
-rw-r--r--shlib-versions24
-rw-r--r--sysdeps/alpha/dl-machine.h4
-rw-r--r--sysdeps/generic/bits/dirent.h9
-rw-r--r--sysdeps/generic/bits/resource.h2
-rw-r--r--sysdeps/generic/bits/sigset.h2
-rw-r--r--sysdeps/generic/bits/time.h4
-rw-r--r--sysdeps/generic/getpeername.c2
-rw-r--r--sysdeps/generic/syscall.c4
-rw-r--r--sysdeps/generic/usleep.c5
-rw-r--r--sysdeps/generic/wait.c3
-rw-r--r--sysdeps/generic/wait3.c5
-rw-r--r--sysdeps/generic/wait4.c7
-rw-r--r--sysdeps/posix/pwrite.c3
-rw-r--r--sysdeps/posix/sigblock.c6
-rw-r--r--sysdeps/posix/sigsetmask.c6
-rw-r--r--sysdeps/posix/sigvec.c10
-rw-r--r--sysdeps/standalone/arm/bits/errno.h1
-rw-r--r--sysdeps/standalone/close.c1
-rw-r--r--sysdeps/standalone/filedesc.h1
-rw-r--r--sysdeps/unix/sysv/linux/Makefile3
-rw-r--r--sysdeps/unix/sysv/linux/arm/syscalls.list6
-rw-r--r--sysdeps/unix/sysv/linux/i386/s_pread64.S9
-rw-r--r--sysdeps/unix/sysv/linux/i386/s_pwrite64.S9
-rw-r--r--sysdeps/unix/sysv/linux/i386/sigaction.c21
-rw-r--r--sysdeps/unix/sysv/linux/pread.c28
-rw-r--r--sysdeps/unix/sysv/linux/pwrite.c28
-rw-r--r--sysdeps/unix/sysv/linux/sigaction.c3
-rw-r--r--sysdeps/unix/sysv/linux/sigpending.c3
-rw-r--r--sysdeps/unix/sysv/linux/sigprocmask.c3
-rw-r--r--sysdeps/unix/sysv/linux/sigreturn.c3
-rw-r--r--sysdeps/unix/sysv/linux/sigsuspend.c5
-rw-r--r--sysdeps/unix/sysv/linux/sigtimedwait.c3
-rw-r--r--sysdeps/unix/sysv/linux/sigwaitinfo.c3
-rw-r--r--sysdeps/unix/sysv/linux/syscalls.list14
-rw-r--r--sysdeps/wordsize-32/Dist4
-rw-r--r--sysdeps/wordsize-32/Makefile2
-rw-r--r--sysdeps/wordsize-32/inttypes.h77
-rw-r--r--sysdeps/wordsize-32/strtoimax.c28
-rw-r--r--sysdeps/wordsize-32/strtoumax.c28
-rw-r--r--sysdeps/wordsize-32/wcstoimax.c29
-rw-r--r--sysdeps/wordsize-32/wcstoumax.c29
-rw-r--r--sysdeps/wordsize-64/Dist4
-rw-r--r--sysdeps/wordsize-64/Makefile2
-rw-r--r--sysdeps/wordsize-64/inttypes.h81
-rw-r--r--sysdeps/wordsize-64/strtoimax.c28
-rw-r--r--sysdeps/wordsize-64/strtoumax.c28
-rw-r--r--sysdeps/wordsize-64/wcstoimax.c29
-rw-r--r--sysdeps/wordsize-64/wcstoumax.c29
-rw-r--r--time/time.h11
125 files changed, 3143 insertions, 1469 deletions
diff --git a/ChangeLog b/ChangeLog
index f9a3fce48e..fc0222df14 100644
--- 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 770bef4133..edc0c29e7a 100644
--- 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>
Local Variables:
mode:outline
diff --git a/Makeconfig b/Makeconfig
index 44afe0fe30..1f0f96e8a3 100644
--- a/Makeconfig
+++ b/Makeconfig
@@ -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
diff --git a/Makefile b/Makefile
index 2c0785b8d3..dbacf8b669 100644
--- 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
diff --git a/bits/dirent.h b/bits/dirent.h
index 366cdf8ce2..d074589562 100644
--- a/bits/dirent.h
+++ b/bits/dirent.h
@@ -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
+
diff --git a/bits/resource.h b/bits/resource.h
index d0ebeb56c8..e72836d3c7 100644
--- a/bits/resource.h
+++ b/bits/resource.h
@@ -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
diff --git a/bits/sigset.h b/bits/sigset.h
index 9fad4538d7..c442d53643 100644
--- a/bits/sigset.h
+++ b/bits/sigset.h
@@ -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
diff --git a/bits/time.h b/bits/time.h
index cdbd39f91d..f608e2c996 100644
--- a/bits/time.h
+++ b/bits/time.h
@@ -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 */
diff --git a/config.h.in b/config.h.in
index f2fa9167d3..a38900b64a 100644
--- a/config.h.in
+++ b/config.h.in
@@ -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
diff --git a/configure b/configure
index b6fd050e16..133194c598 100755
--- 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
diff --git a/configure.in b/configure.in
index 80fe259b32..939fda8a4e 100644
--- a/configure.in
+++ b/configure.in
@@ -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"
diff --git a/grp/fgetgrent_r.c b/grp/fgetgrent_r.c
index 44298c5ba6..b142f908e6 100644
--- a/grp/fgetgrent_r.c
+++ b/grp/fgetgrent_r.c
@@ -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)
{
diff --git a/hesiod/nss_hesiod/hesiod-grp.c b/hesiod/nss_hesiod/hesiod-grp.c
index 7b0832dbe3..e08b9dca8c 100644
--- a/hesiod/nss_hesiod/hesiod-grp.c
+++ b/hesiod/nss_hesiod/hesiod-grp.c
@@ -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);
diff --git a/hesiod/nss_hesiod/hesiod-pwd.c b/hesiod/nss_hesiod/hesiod-pwd.c
index bb2a4c8785..ce97443164 100644
--- a/hesiod/nss_hesiod/hesiod-pwd.c
+++ b/hesiod/nss_hesiod/hesiod-pwd.c
@@ -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);
diff --git a/hesiod/nss_hesiod/hesiod-service.c b/hesiod/nss_hesiod/hesiod-service.c
index f74877f748..e0ca965310 100644
--- a/hesiod/nss_hesiod/hesiod-service.c
+++ b/hesiod/nss_hesiod/hesiod-service.c
@@ -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);
diff --git a/inet/getnetgrent_r.c b/inet/getnetgrent_r.c
index a388d86ba8..d7a2b58b78 100644
--- a/inet/getnetgrent_r.c
+++ b/inet/getnetgrent_r.c
@@ -92,7 +92,8 @@ free_memory (struct __netgrent *data)
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);
diff --git a/inet/netgroup.h b/inet/netgroup.h
index a37244c52e..804a201dda 100644
--- a/inet/netgroup.h
+++ b/inet/netgroup.h
@@ -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 */
diff --git a/io/sys/stat.h b/io/sys/stat.h
index 01bc00165e..d57b8d6ee8 100644
--- a/io/sys/stat.h
+++ b/io/sys/stat.h
@@ -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)
diff --git a/libc.map b/libc.map
index a4b880b52b..d133f22757 100644
--- 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;
diff --git a/malloc/malloc.c b/malloc/malloc.c
index 7f80b9ad60..058c156be4 100644
--- a/malloc/malloc.c
+++ b/malloc/malloc.c
@@ -510,7 +510,7 @@ do { \
*/
#ifndef HAVE_MREMAP
-#define HAVE_MREMAP defined(__linux__)
+#define HAVE_MREMAP defined(__linux__) && !defined(__arm__)
#endif
#if HAVE_MMAP
diff --git a/nis/nisplus-parser.h b/nis/nisplus-parser.h
index b24ca46507..2d54edba28 100644
--- a/nis/nisplus-parser.h
+++ b/nis/nisplus-parser.h
@@ -17,18 +17,18 @@
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
diff --git a/nis/nss_compat/compat-grp.c b/nis/nss_compat/compat-grp.c
index 6d4ca25e5d..a586d1fbbf 100644
--- a/nis/nss_compat/compat-grp.c
+++ b/nis/nss_compat/compat-grp.c
@@ -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);
diff --git a/nis/nss_compat/compat-pwd.c b/nis/nss_compat/compat-pwd.c
index 38a7e2f205..c8e6f9cc8d 100644
--- a/nis/nss_compat/compat-pwd.c
+++ b/nis/nss_compat/compat-pwd.c
@@ -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);
diff --git a/nis/nss_compat/compat-spwd.c b/nis/nss_compat/compat-spwd.c
index 5da19d3feb..92224f8ae7 100644
--- a/nis/nss_compat/compat-spwd.c
+++ b/nis/nss_compat/compat-spwd.c
@@ -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);
diff --git a/nis/nss_nis/nis-alias.c b/nis/nss_nis/nis-alias.c
index e187716bb0..0d0294082d 100644
--- a/nis/nss_nis/nis-alias.c
+++ b/nis/nss_nis/nis-alias.c
@@ -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
diff --git a/nis/nss_nis/nis-ethers.c b/nis/nss_nis/nis-ethers.c
index e54262409c..365f9c9c1d 100644
--- a/nis/nss_nis/nis-ethers.c
+++ b/nis/nss_nis/nis-ethers.c
@@ -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)
diff --git a/nis/nss_nis/nis-grp.c b/nis/nss_nis/nis-grp.c
index 7897e21881..98cc4fd878 100644
--- a/nis/nss_nis/nis-grp.c
+++ b/nis/nss_nis/nis-grp.c
@@ -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)
diff --git a/nis/nss_nis/nis-hosts.c b/nis/nss_nis/nis-hosts.c
index da7cef5ada..f08a624c37 100644
--- a/nis/nss_nis/nis-hosts.c
+++ b/nis/nss_nis/nis-hosts.c
@@ -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)
diff --git a/nis/nss_nis/nis-netgrp.c b/nis/nss_nis/nis-netgrp.c
index ce8762a1e5..d170b56f50 100644
--- a/nis/nss_nis/nis-netgrp.c
+++ b/nis/nss_nis/nis-netgrp.c
@@ -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);
diff --git a/nis/nss_nis/nis-network.c b/nis/nss_nis/nis-network.c
index c17ba81a62..4fcf729b34 100644
--- a/nis/nss_nis/nis-network.c
+++ b/nis/nss_nis/nis-network.c
@@ -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)
{
diff --git a/nis/nss_nis/nis-proto.c b/nis/nss_nis/nis-proto.c
index eb09bb4ec7..e0c976041d 100644
--- a/nis/nss_nis/nis-proto.c
+++ b/nis/nss_nis/nis-proto.c
@@ -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)
diff --git a/nis/nss_nis/nis-publickey.c b/nis/nss_nis/nis-publickey.c
index 4c921f4853..1c485d9d23 100644
--- a/nis/nss_nis/nis-publickey.c
+++ b/nis/nss_nis/nis-publickey.c
@@ -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;
diff --git a/nis/nss_nis/nis-pwd.c b/nis/nss_nis/nis-pwd.c
index f693db17ea..8924886e1e 100644
--- a/nis/nss_nis/nis-pwd.c
+++ b/nis/nss_nis/nis-pwd.c
@@ -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)
diff --git a/nis/nss_nis/nis-rpc.c b/nis/nss_nis/nis-rpc.c
index cd1f0db9b5..274ef04b7a 100644
--- a/nis/nss_nis/nis-rpc.c
+++ b/nis/nss_nis/nis-rpc.c
@@ -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)
{
diff --git a/nis/nss_nis/nis-service.c b/nis/nss_nis/nis-service.c
index 5ec89c8677..c55b3e0191 100644
--- a/nis/nss_nis/nis-service.c
+++ b/nis/nss_nis/nis-service.c
@@ -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);
diff --git a/nis/nss_nis/nis-spwd.c b/nis/nss_nis/nis-spwd.c
index 0263f4e313..5be010d433 100644
--- a/nis/nss_nis/nis-spwd.c
+++ b/nis/nss_nis/nis-spwd.c
@@ -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)
diff --git a/nis/nss_nisplus/nisplus-alias.c b/nis/nss_nisplus/nisplus-alias.c
index 76c6f25813..381ad18228 100644
--- a/nis/nss_nisplus/nisplus-alias.c
+++ b/nis/nss_nisplus/nisplus-alias.c
@@ -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)
diff --git a/nis/nss_nisplus/nisplus-ethers.c b/nis/nss_nisplus/nisplus-ethers.c
index 8ca6935cc7..76805f1403 100644
--- a/nis/nss_nisplus/nisplus-ethers.c
+++ b/nis/nss_nisplus/nisplus-ethers.c
@@ -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;
}
diff --git a/nis/nss_nisplus/nisplus-grp.c b/nis/nss_nisplus/nisplus-grp.c
index fb200321d2..4ac048ef05 100644
--- a/nis/nss_nisplus/nisplus-grp.c
+++ b/nis/nss_nisplus/nisplus-grp.c
@@ -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;
diff --git a/nis/nss_nisplus/nisplus-hosts.c b/nis/nss_nisplus/nisplus-hosts.c
index d1aa5ef787..8514a63e8a 100644
--- a/nis/nss_nisplus/nisplus-hosts.c
+++ b/nis/nss_nisplus/nisplus-hosts.c
@@ -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;
}
diff --git a/nis/nss_nisplus/nisplus-netgrp.c b/nis/nss_nisplus/nisplus-netgrp.c
index 2a2f4b5ec9..5d5b727292 100644
--- a/nis/nss_nisplus/nisplus-netgrp.c
+++ b/nis/nss_nisplus/nisplus-netgrp.c
@@ -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);
diff --git a/nis/nss_nisplus/nisplus-network.c b/nis/nss_nisplus/nisplus-network.c
index e548017068..b39a54fe03 100644
--- a/nis/nss_nisplus/nisplus-network.c
+++ b/nis/nss_nisplus/nisplus-network.c
@@ -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;
}
diff --git a/nis/nss_nisplus/nisplus-parser.c b/nis/nss_nisplus/nisplus-parser.c
index b700fa66b4..fa4073e6d8 100644
--- a/nis/nss_nisplus/nisplus-parser.c
+++ b/nis/nss_nisplus/nisplus-parser.c
@@ -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;
diff --git a/nis/nss_nisplus/nisplus-proto.c b/nis/nss_nisplus/nisplus-proto.c
index 2cbd9fe2fa..262276f301 100644
--- a/nis/nss_nisplus/nisplus-proto.c
+++ b/nis/nss_nisplus/nisplus-proto.c
@@ -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;
diff --git a/nis/nss_nisplus/nisplus-publickey.c b/nis/nss_nisplus/nisplus-publickey.c
index aa2a6f0c3a..24d217b804 100644
--- a/nis/nss_nisplus/nisplus-publickey.c
+++ b/nis/nss_nisplus/nisplus-publickey.c
@@ -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;
diff --git a/nis/nss_nisplus/nisplus-pwd.c b/nis/nss_nisplus/nisplus-pwd.c
index 3974defa47..18114ad7e5 100644
--- a/nis/nss_nisplus/nisplus-pwd.c
+++ b/nis/nss_nisplus/nisplus-pwd.c
@@ -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;
diff --git a/nis/nss_nisplus/nisplus-rpc.c b/nis/nss_nisplus/nisplus-rpc.c
index 77a7248305..452fb4cc5e 100644
--- a/nis/nss_nisplus/nisplus-rpc.c
+++ b/nis/nss_nisplus/nisplus-rpc.c
@@ -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;
diff --git a/nis/nss_nisplus/nisplus-service.c b/nis/nss_nisplus/nisplus-service.c
index 95a8cfa74b..1cb1aec8d7 100644
--- a/nis/nss_nisplus/nisplus-service.c
+++ b/nis/nss_nisplus/nisplus-service.c
@@ -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;
diff --git a/nis/nss_nisplus/nisplus-spwd.c b/nis/nss_nisplus/nisplus-spwd.c
index 1b3f68325e..54bbc32f3c 100644
--- a/nis/nss_nisplus/nisplus-spwd.c
+++ b/nis/nss_nisplus/nisplus-spwd.c
@@ -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;
diff --git a/nss/getXXbyYY_r.c b/nss/getXXbyYY_r.c
index 18f0bae03a..47df01054e 100644
--- a/nss/getXXbyYY_r.c
+++ b/nss/getXXbyYY_r.c
@@ -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);
diff --git a/nss/getXXent_r.c b/nss/getXXent_r.c
index f2cca259f0..1884b0773d 100644
--- a/nss/getXXent_r.c
+++ b/nss/getXXent_r.c
@@ -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);
diff --git a/nss/nss_db/db-XXX.c b/nss/nss_db/db-XXX.c
index 2f781bf3d9..4d20cae797 100644
--- a/nss/nss_db/db-XXX.c
+++ b/nss/nss_db/db-XXX.c
@@ -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;
diff --git a/nss/nss_db/db-alias.c b/nss/nss_db/db-alias.c
index 32ba4b5f4f..0e72b92ceb 100644
--- a/nss/nss_db/db-alias.c
+++ b/nss/nss_db/db-alias.c
@@ -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,
}
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;
diff --git a/nss/nss_db/db-netgrp.c b/nss/nss_db/db-netgrp.c
index 4691c0fb9b..d63d1cb1af 100644
--- a/nss/nss_db/db-netgrp.c
+++ b/nss/nss_db/db-netgrp.c
@@ -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);
diff --git a/nss/nss_files/files-XXX.c b/nss/nss_files/files-XXX.c
index eb0f6fec8f..e3261ed454 100644
--- a/nss/nss_files/files-XXX.c
+++ b/nss/nss_files/files-XXX.c
@@ -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 } \
\
diff --git a/nss/nss_files/files-alias.c b/nss/nss_files/files-alias.c
index bf4fa8a2f0..7eb22bb187 100644
--- a/nss/nss_files/files-alias.c
+++ b/nss/nss_files/files-alias.c
@@ -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);
}
diff --git a/nss/nss_files/files-netgrp.c b/nss/nss_files/files-netgrp.c
index 7552d4c3b1..eb6e673ad0 100644
--- a/nss/nss_files/files-netgrp.c
+++ b/nss/nss_files/files-netgrp.c
@@ -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;
}
diff --git a/nss/nss_files/files-parse.c b/nss/nss_files/files-parse.c
index acf673da90..76df1c6ff0 100644
--- a/nss/nss_files/files-parse.c
+++ b/nss/nss_files/files-parse.c
@@ -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')
diff --git a/posix/sys/wait.h b/posix/sys/wait.h
index 4774885ecf..e931405ecb 100644
--- a/posix/sys/wait.h
+++ b/posix/sys/wait.h
@@ -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
diff --git a/pwd/fgetpwent_r.c b/pwd/fgetpwent_r.c
index 9bf3397675..7699901177 100644
--- a/pwd/fgetpwent_r.c
+++ b/pwd/fgetpwent_r.c
@@ -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;
diff --git a/rt/Makefile b/rt/Makefile
index 4eb9dfcb7a..e0f03d78a0 100644
--- a/rt/Makefile
+++ b/rt/Makefile
@@ -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
diff --git a/rt/aio.h b/rt/aio.h
index 561776c2d3..a49b8c7a67 100644
--- 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));
diff --git a/rt/aio_cancel.c b/rt/aio_cancel.c
index f2d9389650..e802a8533f 100644
--- a/rt/aio_cancel.c
+++ b/rt/aio_cancel.c
@@ -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;
}
diff --git a/rt/aio_fsync.c b/rt/aio_fsync.c
index 6daaca1e97..c813654b61 100644
--- a/rt/aio_fsync.c
+++ b/rt/aio_fsync.c
@@ -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)
diff --git a/rt/aio_misc.c b/rt/aio_misc.c
index e4bb12c500..6ea30c2158 100644
--- a/rt/aio_misc.c
+++ b/rt/aio_misc.c
@@ -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>
@@ -29,40 +28,199 @@
#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);
diff --git a/rt/aio_misc.h b/rt/aio_misc.h
index c2eb9fcea1..af8e2479ba 100644
--- a/rt/aio_misc.h
+++ b/rt/aio_misc.h
@@ -19,7 +19,19 @@
#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
index 0000000000..be2e1e246b
--- /dev/null
+++ b/rt/aio_notify.c
@@ -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;
+ }
+}
diff --git a/rt/aio_read.c b/rt/aio_read.c
index 8286ba9334..871ce99767 100644
--- a/rt/aio_read.c
+++ b/rt/aio_read.c
@@ -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;
}
diff --git a/rt/aio_read64.c b/rt/aio_read64.c
index bf808fb3da..b194dda6db 100644
--- a/rt/aio_read64.c
+++ b/rt/aio_read64.c
@@ -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;
}
diff --git a/rt/aio_suspend.c b/rt/aio_suspend.c
index 75bf9ba94b..6123b7baa0 100644
--- a/rt/aio_suspend.c
+++ b/rt/aio_suspend.c
@@ -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)
diff --git a/rt/aio_write.c b/rt/aio_write.c
index 80b827c1aa..8801d89110 100644
--- a/rt/aio_write.c
+++ b/rt/aio_write.c
@@ -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;
}
diff --git a/rt/aio_write64.c b/rt/aio_write64.c
index 477ce2cbe4..4d599b1062 100644
--- a/rt/aio_write64.c
+++ b/rt/aio_write64.c
@@ -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;
}
diff --git a/rt/lio_listio.c b/rt/lio_listio.c
index 73df5c2f5c..b389c6a5f6 100644
--- a/rt/lio_listio.c
+++ b/rt/lio_listio.c
@@ -20,11 +20,20 @@
#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;
}
diff --git a/rt/lio_listio64.c b/rt/lio_listio64.c
index b17e9edae2..19f56adab1 100644
--- a/rt/lio_listio64.c
+++ b/rt/lio_listio64.c
@@ -20,11 +20,20 @@
#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;
}
diff --git a/shadow/fgetspent_r.c b/shadow/fgetspent_r.c
index 403eecf761..8c4638d40d 100644
--- a/shadow/fgetspent_r.c
+++ b/shadow/fgetspent_r.c
@@ -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;
diff --git a/shadow/sgetspent_r.c b/shadow/sgetspent_r.c
index 01f0115164..f3e322aa87 100644
--- a/shadow/sgetspent_r.c
+++ b/shadow/sgetspent_r.c
@@ -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;
diff --git a/shlib-versions b/shlib-versions
index 3c221d7c99..988a81da5c 100644
--- a/shlib-versions
+++ b/shlib-versions
@@ -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
diff --git a/sysdeps/alpha/dl-machine.h b/sysdeps/alpha/dl-machine.h
index 3f65ae99a3..bc93087066 100644
--- a/sysdeps/alpha/dl-machine.h
+++ b/sysdeps/alpha/dl-machine.h
@@ -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
diff --git a/sysdeps/generic/bits/dirent.h b/sysdeps/generic/bits/dirent.h
index 366cdf8ce2..d074589562 100644
--- a/sysdeps/generic/bits/dirent.h
+++ b/sysdeps/generic/bits/dirent.h
@@ -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
+
diff --git a/sysdeps/generic/bits/resource.h b/sysdeps/generic/bits/resource.h
index d0ebeb56c8..e72836d3c7 100644
--- a/sysdeps/generic/bits/resource.h
+++ b/sysdeps/generic/bits/resource.h
@@ -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
diff --git a/sysdeps/generic/bits/sigset.h b/sysdeps/generic/bits/sigset.h
index 9fad4538d7..c442d53643 100644
--- a/sysdeps/generic/bits/sigset.h
+++ b/sysdeps/generic/bits/sigset.h
@@ -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
diff --git a/sysdeps/generic/bits/time.h b/sysdeps/generic/bits/time.h
index cdbd39f91d..f608e2c996 100644
--- a/sysdeps/generic/bits/time.h
+++ b/sysdeps/generic/bits/time.h
@@ -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 */
diff --git a/sysdeps/generic/getpeername.c b/sysdeps/generic/getpeername.c
index bd38cb4def..59e6b0140b 100644
--- a/sysdeps/generic/getpeername.c
+++ b/sysdeps/generic/getpeername.c
@@ -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;
diff --git a/sysdeps/generic/syscall.c b/sysdeps/generic/syscall.c
index 8c20b7ead0..6caf258e24 100644
--- a/sysdeps/generic/syscall.c
+++ b/sysdeps/generic/syscall.c
@@ -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;
diff --git a/sysdeps/generic/usleep.c b/sysdeps/generic/usleep.c
index 8c0e851d6d..9a8dadaed3 100644
--- a/sysdeps/generic/usleep.c
+++ b/sysdeps/generic/usleep.c
@@ -16,16 +16,13 @@
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)
diff --git a/sysdeps/generic/wait.c b/sysdeps/generic/wait.c
index 6f1db03f2d..026447e7b3 100644
--- a/sysdeps/generic/wait.c
+++ b/sysdeps/generic/wait.c
@@ -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;
diff --git a/sysdeps/generic/wait3.c b/sysdeps/generic/wait3.c
index 4df9d420df..b15f0243fc 100644
--- a/sysdeps/generic/wait3.c
+++ b/sysdeps/generic/wait3.c
@@ -26,10 +26,7 @@
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)
{
diff --git a/sysdeps/generic/wait4.c b/sysdeps/generic/wait4.c
index d29d80c73e..b2a9169d13 100644
--- a/sysdeps/generic/wait4.c
+++ b/sysdeps/generic/wait4.c
@@ -21,11 +21,8 @@
#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;
diff --git a/sysdeps/posix/pwrite.c b/sysdeps/posix/pwrite.c
index 65806a2e68..ef4a021881 100644
--- a/sysdeps/posix/pwrite.c
+++ b/sysdeps/posix/pwrite.c
@@ -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
diff --git a/sysdeps/posix/sigblock.c b/sysdeps/posix/sigblock.c
index 777710b08a..efc559dcbc 100644
--- a/sysdeps/posix/sigblock.c
+++ b/sysdeps/posix/sigblock.c
@@ -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);
diff --git a/sysdeps/posix/sigsetmask.c b/sysdeps/posix/sigsetmask.c
index 034719870d..fbbdafa3c9 100644
--- a/sysdeps/posix/sigsetmask.c
+++ b/sysdeps/posix/sigsetmask.c
@@ -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);
diff --git a/sysdeps/posix/sigvec.c b/sysdeps/posix/sigvec.c
index 59d30f2d29..12285fad66 100644
--- a/sysdeps/posix/sigvec.c
+++ b/sysdeps/posix/sigvec.c
@@ -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;
diff --git a/sysdeps/standalone/arm/bits/errno.h b/sysdeps/standalone/arm/bits/errno.h
index f5020dcb7e..97dbbd9ce3 100644
--- a/sysdeps/standalone/arm/bits/errno.h
+++ b/sysdeps/standalone/arm/bits/errno.h
@@ -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)
diff --git a/sysdeps/standalone/close.c b/sysdeps/standalone/close.c
index 2e33b3c2c6..114d726c6d 100644
--- a/sysdeps/standalone/close.c
+++ b/sysdeps/standalone/close.c
@@ -21,6 +21,7 @@
#include <errno.h>
#include <unistd.h>
+#define _STDIO_H
#include <bits/stdio_lim.h>
#include "filedesc.h"
diff --git a/sysdeps/standalone/filedesc.h b/sysdeps/standalone/filedesc.h
index a35d1cf043..d6a12a606a 100644
--- a/sysdeps/standalone/filedesc.h
+++ b/sysdeps/standalone/filedesc.h
@@ -26,6 +26,7 @@
#ifndef __FILEDESC_h
#define __FILEDESC_h
+#define _STDIO_H
#include <bits/stdio_lim.h>
#ifndef __DECLARE_FILE_DESCRIPTORS__
diff --git a/sysdeps/unix/sysv/linux/Makefile b/sysdeps/unix/sysv/linux/Makefile
index ffea9ef4bb..6903e0b6cd 100644
--- a/sysdeps/unix/sysv/linux/Makefile
+++ b/sysdeps/unix/sysv/linux/Makefile
@@ -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
index 0000000000..392a257194
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/arm/syscalls.list
@@ -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
diff --git a/sysdeps/unix/sysv/linux/i386/s_pread64.S b/sysdeps/unix/sysv/linux/i386/s_pread64.S
index 22ce79b3f0..9e14aa815f 100644
--- a/sysdeps/unix/sysv/linux/i386/s_pread64.S
+++ b/sysdeps/unix/sysv/linux/i386/s_pread64.S
@@ -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.*/
@@ -25,6 +26,13 @@
.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)
diff --git a/sysdeps/unix/sysv/linux/i386/s_pwrite64.S b/sysdeps/unix/sysv/linux/i386/s_pwrite64.S
index 6a1987b72e..a21fe2f99f 100644
--- a/sysdeps/unix/sysv/linux/i386/s_pwrite64.S
+++ b/sysdeps/unix/sysv/linux/i386/s_pwrite64.S
@@ -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.*/
@@ -25,6 +26,13 @@
.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)
diff --git a/sysdeps/unix/sysv/linux/i386/sigaction.c b/sysdeps/unix/sysv/linux/i386/sigaction.c
index 90d61a08a1..05d187c432 100644
--- a/sysdeps/unix/sysv/linux/i386/sigaction.c
+++ b/sysdeps/unix/sysv/linux/i386/sigaction.c
@@ -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;
diff --git a/sysdeps/unix/sysv/linux/pread.c b/sysdeps/unix/sysv/linux/pread.c
index eeb26eb663..eb0d301fa1 100644
--- a/sysdeps/unix/sysv/linux/pread.c
+++ b/sysdeps/unix/sysv/linux/pread.c
@@ -17,12 +17,36 @@
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>
diff --git a/sysdeps/unix/sysv/linux/pwrite.c b/sysdeps/unix/sysv/linux/pwrite.c
index d8695db2a8..9ab3259fc6 100644
--- a/sysdeps/unix/sysv/linux/pwrite.c
+++ b/sysdeps/unix/sysv/linux/pwrite.c
@@ -17,12 +17,36 @@
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>
diff --git a/sysdeps/unix/sysv/linux/sigaction.c b/sysdeps/unix/sysv/linux/sigaction.c
index 161f1b0529..1412c381d0 100644
--- a/sysdeps/unix/sysv/linux/sigaction.c
+++ b/sysdeps/unix/sysv/linux/sigaction.c
@@ -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;
diff --git a/sysdeps/unix/sysv/linux/sigpending.c b/sysdeps/unix/sysv/linux/sigpending.c
index 7b26bfbf12..4cecb8dc60 100644
--- a/sysdeps/unix/sysv/linux/sigpending.c
+++ b/sysdeps/unix/sysv/linux/sigpending.c
@@ -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;
diff --git a/sysdeps/unix/sysv/linux/sigprocmask.c b/sysdeps/unix/sysv/linux/sigprocmask.c
index f436ba8f2c..dc262c88f4 100644
--- a/sysdeps/unix/sysv/linux/sigprocmask.c
+++ b/sysdeps/unix/sysv/linux/sigprocmask.c
@@ -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;
diff --git a/sysdeps/unix/sysv/linux/sigreturn.c b/sysdeps/unix/sysv/linux/sigreturn.c
index ecef3d67ad..540dfdf388 100644
--- a/sysdeps/unix/sysv/linux/sigreturn.c
+++ b/sysdeps/unix/sysv/linux/sigreturn.c
@@ -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;
diff --git a/sysdeps/unix/sysv/linux/sigsuspend.c b/sysdeps/unix/sysv/linux/sigsuspend.c
index faea1c35e1..2cf34eb9b1 100644
--- a/sysdeps/unix/sysv/linux/sigsuspend.c
+++ b/sysdeps/unix/sysv/linux/sigsuspend.c
@@ -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;
diff --git a/sysdeps/unix/sysv/linux/sigtimedwait.c b/sysdeps/unix/sysv/linux/sigtimedwait.c
index b022ec35f7..90854c64d9 100644
--- a/sysdeps/unix/sysv/linux/sigtimedwait.c
+++ b/sysdeps/unix/sysv/linux/sigtimedwait.c
@@ -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)
diff --git a/sysdeps/unix/sysv/linux/sigwaitinfo.c b/sysdeps/unix/sysv/linux/sigwaitinfo.c
index ac98fb46e0..5f41ba054b 100644
--- a/sysdeps/unix/sysv/linux/sigwaitinfo.c
+++ b/sysdeps/unix/sysv/linux/sigwaitinfo.c
@@ -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)
diff --git a/sysdeps/unix/sysv/linux/syscalls.list b/sysdeps/unix/sysv/linux/syscalls.list
index 08dceca3f6..ed760af2ab 100644
--- a/sysdeps/unix/sysv/linux/syscalls.list
+++ b/sysdeps/unix/sysv/linux/syscalls.list
@@ -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
diff --git a/sysdeps/wordsize-32/Dist b/sysdeps/wordsize-32/Dist
index 5661d79d1d..36bfb62e73 100644
--- a/sysdeps/wordsize-32/Dist
+++ b/sysdeps/wordsize-32/Dist
@@ -1 +1,5 @@
inttypes.h
+strtoimax.c
+strtoumax.c
+wcstoimax.c
+wcstoumax.c
diff --git a/sysdeps/wordsize-32/Makefile b/sysdeps/wordsize-32/Makefile
index 87ced71ec1..b22eaee177 100644
--- a/sysdeps/wordsize-32/Makefile
+++ b/sysdeps/wordsize-32/Makefile
@@ -1,3 +1,5 @@
ifeq ($(subdir),stdlib)
sysdep_headers += inttypes.h
+
+sysdep_routines += strtoimax strtoumax wcstoimax wcstoumax
endif
diff --git a/sysdeps/wordsize-32/inttypes.h b/sysdeps/wordsize-32/inttypes.h
index 371b40bb3d..f569be5b51 100644
--- a/sysdeps/wordsize-32/inttypes.h
+++ b/sysdeps/wordsize-32/inttypes.h
@@ -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
index 0000000000..a57bc3ae7a
--- /dev/null
+++ b/sysdeps/wordsize-32/strtoimax.c
@@ -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
index 0000000000..6b05ad9629
--- /dev/null
+++ b/sysdeps/wordsize-32/strtoumax.c
@@ -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
index 0000000000..63e78d18d6
--- /dev/null
+++ b/sysdeps/wordsize-32/wcstoimax.c
@@ -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
index 0000000000..b6f29f406b
--- /dev/null
+++ b/sysdeps/wordsize-32/wcstoumax.c
@@ -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);
+}
diff --git a/sysdeps/wordsize-64/Dist b/sysdeps/wordsize-64/Dist
index 5661d79d1d..36bfb62e73 100644
--- a/sysdeps/wordsize-64/Dist
+++ b/sysdeps/wordsize-64/Dist
@@ -1 +1,5 @@
inttypes.h
+strtoimax.c
+strtoumax.c
+wcstoimax.c
+wcstoumax.c
diff --git a/sysdeps/wordsize-64/Makefile b/sysdeps/wordsize-64/Makefile
index 87ced71ec1..b22eaee177 100644
--- a/sysdeps/wordsize-64/Makefile
+++ b/sysdeps/wordsize-64/Makefile
@@ -1,3 +1,5 @@
ifeq ($(subdir),stdlib)
sysdep_headers += inttypes.h
+
+sysdep_routines += strtoimax strtoumax wcstoimax wcstoumax
endif
diff --git a/sysdeps/wordsize-64/inttypes.h b/sysdeps/wordsize-64/inttypes.h
index 5f11fc9cb1..c62d516c4b 100644
--- a/sysdeps/wordsize-64/inttypes.h
+++ b/sysdeps/wordsize-64/inttypes.h
@@ -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
index 0000000000..f26f271b4d
--- /dev/null
+++ b/sysdeps/wordsize-64/strtoimax.c
@@ -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
index 0000000000..90d9be975c
--- /dev/null
+++ b/sysdeps/wordsize-64/strtoumax.c
@@ -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
index 0000000000..d6d992bba7
--- /dev/null
+++ b/sysdeps/wordsize-64/wcstoimax.c
@@ -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
index 0000000000..c2065258ac
--- /dev/null
+++ b/sysdeps/wordsize-64/wcstoumax.c
@@ -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);
+}
diff --git a/time/time.h b/time/time.h
index 3e039adfa4..c9276dab01 100644
--- a/time/time.h
+++ b/time/time.h
@@ -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. */