diff options
author | Ulrich Drepper <drepper@redhat.com> | 1997-12-08 03:06:47 +0000 |
---|---|---|
committer | Ulrich Drepper <drepper@redhat.com> | 1997-12-08 03:06:47 +0000 |
commit | d71b808a96f0fd1b6cd82c41698b518bf345692b (patch) | |
tree | 7b86cfd6b465c72888d7e85a61c08cafabf5747b | |
parent | 6195235142bd246d972cf1d88b4e208071a3e318 (diff) | |
download | glibc-d71b808a96f0fd1b6cd82c41698b518bf345692b.tar glibc-d71b808a96f0fd1b6cd82c41698b518bf345692b.tar.gz glibc-d71b808a96f0fd1b6cd82c41698b518bf345692b.tar.bz2 glibc-d71b808a96f0fd1b6cd82c41698b518bf345692b.zip |
Update.cvs/libc-ud-971207
1997-12-08 03:24 Ulrich Drepper <drepper@cygnus.com>
* Makeconfig: Define $(rt) to rt if linuxthreads is available.
* Makefile (subdirs): Replace rt by $(rt).
* shlib-versions: Use version .2 for NSS modules.
* grp/fgetgrent_r.c (LINE_PARSER): Call parse_line with extra
argument.
* pwd/fgetpwent_r.c: Likewise.
* spwd/fgetspent_r.c: Likewise.
* spwd/sgetspent_r.c: Likewise.
* hesiod/nss_hesiod/hesiod-grp.c (lookup): Add new argument.
Store error number in *ERRNOP. Little optimization.
* hesiod/nss_hesiod/hesiod-pwd.c: Likewise.
* hesiod/nss_hesiod/hesiod-service.c: Likewise.
* inet/getnetgrent_r.c (__internal_setnetgrent_reuse): Likewise.
(__internal_getnetgrent_r): New argument.
Call __internal_setnetgrent_reuse with new argument.
(__getnetgrent_r): Call __internal_getnetgrent_r with new argument.
* inet/netgroup.h: Add argument to prototypes.
* nis/nisplus-parser.h: Likewise.
* nis/nss_compat/compat-grp.c: Change everything to store error
code through provided pointer and not use errno.
* nis/nss_compat/compat-pwd.c: Likewise.
* nis/nss_compat/compat-spwd.c: Likewise.
* nis/nss_nis/nis-alias.c: Likewise.
* nis/nss_nis/nis-ethers.c: Likewise.
* nis/nss_nis/nis-grp.c: Likewise.
* nis/nss_nis/nis-hosts.c: Likewise.
* nis/nss_nis/nis-netgrp.c: Likewise.
* nis/nss_nis/nis-network.c: Likewise.
* nis/nss_nis/nis-proto.c: Likewise.
* nis/nss_nis/nis-publickey.c: Likewise.
* nis/nss_nis/nis-pwd.c: Likewise.
* nis/nss_nis/nis-rpc.c: Likewise.
* nis/nss_nis/nis-service.c: Likewise.
* nis/nss_nis/nis-spwd.c: Likewise.
* nis/nss_nisplus/nisplus-alias.c: Likewise.
* nis/nss_nisplus/nisplus-ethers.c: Likewise.
* nis/nss_nisplus/nisplus-grp.c: Likewise.
* nis/nss_nisplus/nisplus-hosts.c: Likewise.
* nis/nss_nisplus/nisplus-netgrp.c: Likewise.
* nis/nss_nisplus/nisplus-network.c: Likewise.
* nis/nss_nisplus/nisplus-parser.c: Likewise.
* nis/nss_nisplus/nisplus-proto.c: Likewise.
* nis/nss_nisplus/nisplus-publickey.c: Likewise.
* nis/nss_nisplus/nisplus-pwd.c: Likewise.
* nis/nss_nisplus/nisplus-rpc.c: Likewise.
* nis/nss_nisplus/nisplus-service.c: Likewise.
* nis/nss_nisplus/nisplus-spwd.c: Likewise.
* nss/nss_db/db-XXX.c: Likewise.
* nss/nss_db/db-alias.c: Likewise.
* nss/nss_db/db-netgrp.c: Likewise.
* nss/nss_files/files-XXX.c: Likewise
* nss/nss_files/files-alias.c: Likewise
* nss/nss_files/files-netgrp.c: Likewise
* nss/nss_files/files-parse.c: Likewise
* nss/getXXbyYY_r.c: Call with __errno_location() as value for new
parameter of get functions.
* nss/getXXent_r.c: Likewise.
* localedata/tst-fmon.c: Print debug info if test fails.
* rt/Makefile (routines): Add aio_notify.
* rt/aio.h: Remove non-public definitions. Add aioinit stuff.
* rt/aio_cancel.c: Rewrite to support lio_listio and aio_suspend.
* rt/aio_fsync.c: Likewise.
* rt/aio_misc.c: Likewise.
* rt/aio_misc.h: Likewise.
* rt/aio_read.c: Likewise.
* rt/aio_read64.c: Likewise.
* rt/aio_suspend.c: Likewise.
* rt/aio_write.c: Likewise.
* rt/aio_write64.c: Likewise.
* rt/lio_listio.c: Likewise.
* rt/lio_listio64.c: Likewise.
* rt/aio_notify.c: New file.
* sysdeps/generic/bits/sigset.h: Pretty print.
* sysdeps/posix/pwrite.c: Define weak alias only if function is
really defined as __pwrite.
* sysdeps/unix/sysv/linux/pread.c: Rewrite to use syscall directly
instead of pread64.
* sysdeps/unix/sysv/linux/pwrite.c: Likewise.
* sysdeps/unix/sysv/linux/Makefile [$(subdir)=signal]
(sysdep_routines): Add rt_sigpending and rt_sigreturn.
* sysdeps/unix/sysv/linux/sigaction.c: Use correct value for sigset_t
size in syscall.
* sysdeps/unix/sysv/linux/sigpending.c: Likewise.
* sysdeps/unix/sysv/linux/sigprocmask.c: Likewise.
* sysdeps/unix/sysv/linux/sigreturn.c: Likewise.
* sysdeps/unix/sysv/linux/sigsuspend.c: Likewise.
* sysdeps/unix/sysv/linux/sigtimedwait.c: Likewise.
* sysdeps/unix/sysv/linux/sigwaitinfo.c: Likewise.
* sysdeps/unix/sysv/linux/i386/sigaction.c: Likewise. Take care
for ACT being NULL.
* sysdeps/unix/sysv/linux/syscalls.list: Don't mention user for
RT signals.
* sysdeps/unix/sysv/linux/i386/s_pread64.s: Return ENOSYS if
__NR_pread is not defined.
* sysdeps/unix/sysv/linux/i386/s_pwrite64.s: Return ENOSYS if
__NR_pwrite is not defined.
1997-12-07 11:15 Thorsten Kukuk <kukuk@vt.uni-paderborn.de>
* nis/nss_compat/compat-grp.c: If buffer is to small, set the file
handle for /etc/group back in some more cases.
* nis/nss_compat/compat-pwd.c: If buffer is to small, set the file
handle for /etc/passwd back in some more cases.
* nis/nss_compat/compat-spwd.c: If buffer is to small, set the file
handle for /etc/shadow back in some more cases.
1997-12-06 17:00 H.J. Lu <hjl@gnu.org>
* sysdeps/posix/sigblock.c (__sigblock): Don't check int mask
beyound its size.
* sysdeps/posix/sigsetmask.c (__sigsetmask): Ditto.
* sysdeps/posix/sigvec.c (convert_mask, __sigvec): Ditto.
1997-12-06 04:38 Ulrich Drepper <drepper@cygnus.com>
* sysdeps/wordsize-32/inttypes.h: Rewrite {str,wcs}to{i,u}max
handling. Don't use macros, we need functions. Use inline functions
for optimization.
* sysdeps/wordsize-64/inttypes.h: Likewise.
* sysdeps/wordsize-32/Makefile: Add strtoimax, stroumax, wcstoimax,
and wcstoumax.
* sysdeps/wordsize-64/Makefile: Likewise.
* sysdeps/wordsize-32/Dist: Likewise.
* sysdeps/wordsize-64/Dist: Likewise.
* sysdeps/wordsize-32/strtoimax.c: New file.
* sysdeps/wordsize-32/strtoumax.c: New file.
* sysdeps/wordsize-32/wcstoimax.c: New file.
* sysdeps/wordsize-32/wcstoumax.c: New file.
* sysdeps/wordsize-64/strtoimax.c: New file.
* sysdeps/wordsize-64/strtoumax.c: New file.
* sysdeps/wordsize-64/wcstoimax.c: New file.
* sysdeps/wordsize-64/wcstoumax.c: New file.
1997-12-04 10:40 Philip Blundell <pb@nexus.co.uk>
* sysdeps/generic/wait3.c (__wait3): Use ANSI-style definition so
that transparent union works.
* sysdeps/generic/wait4.c (__wait4): Likewise.
* sysdeps/generic/wait.c (__wait): Likewise.
* sysdeps/generic/getpeername.c (getpeername): Use socklen_t not
size_t.
* sysdeps/generic/syscall.c (syscall): Return value and arg are
long, to match prototype.
* malloc/malloc.c (HAVE_MREMAP): Set to 0 for ARM, as we don't
have mremap() yet.
* sysdeps/generic/usleep.c (usleep): Returns void, to match prototype.
* sysdeps/unix/sysv/linux/arm/syscalls.list: New file.
* sysdeps/generic/bits/time.h: Use __time_t not time_t.
* sysdeps/generic/bits/resource.h: Include <bits/types.h> for
__rlim_t.
* sysdeps/standalone/arm/bits/errno.h (ENOTTY): Added.
* sysdeps/generic/bits/dirent.h (struct dirent64): Added.
* io/sys/stat.h (S_ISLNK): Always false if we don't have
__S_IFLNK.
* sysdeps/standalone/close.c (_STDIO_H): Define before including
<bits/stdio_lim.h>.
* sysdeps/standalone/filedesc.h (_STDIO_H): Likewise.
1997-12-06 01:09 Ulrich Drepper <drepper@cygnus.com>
* posix/sys/wait.h: Don't use transparent unions in C++.
1997-12-05 Andreas Jaeger <aj@arthur.rhein-neckar.de>
* time/time.h: Add strfxtime.
* libc.map: Add tcgetsid, strcasestr, wmemrtombs, wmemrtowcs,
sysv_signal, strfxtime, pread64, pwrite64.
1997-11-30 21:57 Richard Henderson <rth@cygnus.com>
Alpha changes for EGCS:
* config.h.in (ASM_ALPHA_NG_SYMBOL_PREFIX): New entry.
* configure.in (libc_cv_gcc_alpha_ng_prefix): New check.
* sysdeps/alpha/dl-machine.h (_dl_runtime_resolve): Care for prefix.
(_start): Likewise.
* sysdeps/unix/sysv/linux/alpha/init-first.h: Likewise.
125 files changed, 3143 insertions, 1469 deletions
@@ -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. @@ -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 @@ -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 @@ -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) @@ -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 @@ -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, ¶m) < 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, ¶m); 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, ¶m); 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, ¶m); } /* 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. */ |