aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog35
-rw-r--r--NEWS7
-rw-r--r--README.template6
-rw-r--r--elf/Makefile2
-rw-r--r--elf/rtld.c141
-rw-r--r--manual/maint.texi2
-rw-r--r--nscd/nscd_getgr_r.c5
-rw-r--r--nscd/nscd_getpw_r.c5
-rw-r--r--nss/getXXbyYY_r.c26
-rw-r--r--nss/nsswitch.c12
-rw-r--r--sysdeps/generic/dl-sysdep.c26
-rw-r--r--sysdeps/unix/sysv/linux/powerpc/sysdep.h3
12 files changed, 214 insertions, 56 deletions
diff --git a/ChangeLog b/ChangeLog
index dfa32c7..eae4f20 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,38 @@
+1998-03-05 Ulrich Drepper <drepper@cygnus.com>
+
+ * elf/rtld.c: Speed up processing of environment variables. Do
+ only one run on the environment by avoiding to call getenv.
+ * sysdeps/generic/dl-sysdep.c (_dl_next_ld_env_entry): New
+ function. Used by patch above.
+
+1998-03-05 10:25 Ulrich Drepper <drepper@cygnus.com>
+
+ * nss/getXXbyYY_r.c: Don't try to contact nscd every time when it
+ failed. Only do this every NSS_NSCD_RETRY times.
+ * nss/nsswitch.c: Define __nss_nscd_not_available, used by above
+ change.
+ * nscd/nscd_getgr_r.c (__nscd_getgr_r): Return 2 if contacting the
+ daemon failed.
+ * nscd/nscd_getpw_r.c (__nscd_getpw_r): Likewise.
+
+1998-03-05 Ulrich Drepper <drepper@cygnus.com>
+
+ * nss/nsswitch.c (nss_lookup_function): Don't modify errno if NSS
+ module cannot be found. Reported by Andreas Jaeger.
+
+1998-03-05 11:40 Franz Sirl <Franz.Sirl-kernel@lauterbach.com>
+
+ * nscd/nscd_getgr_r.c: Change char to int to avoid compiler warning
+ on platforms which default to unsigned chars.
+ * nscd/nscd_getpw_r.c: Likewise.
+ * sysdeps/unix/sysv/linux/powerpc/sysdep.h: Undefine L before
+ defining it.
+
+1998-03-05 Andreas Jaeger <aj@arthur.rhein-neckar.de>
+
+ * elf/Makefile (install-bin): Change = to += for sprof to install
+ ldd also.
+
1998-03-04 16:12 H.J. Lu <hjl@gnu.org>
* libio/strops.c (_IO_str_seekoff): Handle MODE == 0.
diff --git a/NEWS b/NEWS
index 5da5bfc..9a86da0 100644
--- a/NEWS
+++ b/NEWS
@@ -54,6 +54,11 @@ Version 2.1
* The localedata addon is now part of glibc.
* An implementation of profiling shared libraries was added by Ulrich Drepper.
+
+* Thorsten Kukuk provided an implementation for a caching daemon for NSS
+ (nscd).
+
+* Tim Waugh provided an implementation of the POSIX.2 wordexp function family.
Version 2.0.5
@@ -503,7 +508,7 @@ Version 1.06
`make dvi' will produce a DVI file of the printed manual.
`make info' will produce Info files that you can read on line using C-h i
in Emacs or the `info' program.
- Please send comments on the manual to bug-glibc-manual@prep.ai.mit.edu.
+ Please send comments on the manual to bug-glibc-manual@gnu.org.
* The library now supports SVR4 on i386s (i386-unknown-sysv4).
diff --git a/README.template b/README.template
index 5c7484b..0850475 100644
--- a/README.template
+++ b/README.template
@@ -73,9 +73,9 @@ GNU libc at http://www.gnu.org/software/libc/libc.html.
The GNU C Library is completely documented by the Texinfo manual found
in the `manual/' subdirectory. The manual is still being updated and
-contains some known errors and omissions; we regret that we do not have
-the resources to work on the manual as much as we would like. Please
-send comments on the manual to <bug-glibc-manual@prep.ai.mit.edu>, and
+contains some known errors and omissions; we regret that we do not
+have the resources to work on the manual as much as we would like.
+Please send comments on the manual to <bug-glibc-manual@gnu.org>, and
not to the library bug-reporting address.
The file NOTES contains a description of the feature-test macros used
diff --git a/elf/Makefile b/elf/Makefile
index 0b37b1f..aff64e4 100644
--- a/elf/Makefile
+++ b/elf/Makefile
@@ -61,7 +61,7 @@ generated += ldd
endif
others = sprof
-install-bin = sprof
+install-bin += sprof
ifeq (yes,$(has-ldconfig))
others-static += ldconfig
diff --git a/elf/rtld.c b/elf/rtld.c
index 95830c5..2707da6 100644
--- a/elf/rtld.c
+++ b/elf/rtld.c
@@ -53,6 +53,15 @@ static void print_unresolved (int errcode, const char *objname,
static void print_missing_version (int errcode, const char *objname,
const char *errsting);
+
+/* This is a list of all the modes the dynamic loader can be in. */
+enum mode { normal, list, verify, trace };
+
+/* Process all environments variables the dynamic linker must recognize.
+ Since all of them start with `LD_' we are a bit smarter while finding
+ all the entries. */
+static void process_envvars (enum mode *modep, int *lazyp);
+
int _dl_argc;
char **_dl_argv;
const char *_dl_rpath;
@@ -147,7 +156,6 @@ _dl_start (void *arg)
return _dl_sysdep_start (arg, &dl_main);
}
-
/* Now life is peachy; we can do all normal operations.
On to the real work. */
@@ -260,7 +268,7 @@ dl_main (const ElfW(Phdr) *phdr,
const ElfW(Phdr) *ph;
struct link_map *main_map;
int lazy;
- enum { normal, list, verify, trace } mode;
+ enum mode mode;
struct link_map **preloads;
unsigned int npreloads;
const char *preloadlist;
@@ -268,41 +276,8 @@ dl_main (const ElfW(Phdr) *phdr,
char *file;
int has_interp = 0;
- /* Test whether we want to see the content of the auxiliary array passed
- up from the kernel. */
- if (getenv ("LD_SHOW_AUXV") != NULL)
- _dl_show_auxv ();
-
- mode = getenv ("LD_TRACE_LOADED_OBJECTS") != NULL ? trace : normal;
- _dl_verbose = *(getenv ("LD_WARN") ?: "") == '\0' ? 0 : 1;
-
- /* LAZY is determined by the environment variable LD_WARN and
- LD_BIND_NOW if we trace the binary. */
- if (mode == trace)
- lazy = (_dl_verbose
- ? (*(getenv ("LD_BIND_NOW") ?: "") == '\0' ? 1 : 0) : -1);
- else
- lazy = !__libc_enable_secure && *(getenv ("LD_BIND_NOW") ?: "") == '\0';
-
- /* See whether we want to use profiling. */
- _dl_profile = getenv ("LD_PROFILE");
- if (_dl_profile != NULL)
- if (_dl_profile[0] == '\0')
- /* An empty string is of not much help. Disable profiling. */
- _dl_profile = NULL;
- else
- {
- /* OK, we have the name of a shared object we want to
- profile. It's up to the user to provide a good name, it
- must match the file name or soname of one of the loaded
- objects. Now let's see where we are supposed to place the
- result. */
- _dl_profile_output = getenv ("LD_PROFILE_OUTPUT");
-
- if (_dl_profile_output == NULL || _dl_profile_output[0] == '\0')
- /* This is the default place. */
- _dl_profile_output = "/var/tmp";
- }
+ /* Process the environment variable which control the behaviour. */
+ process_envvars (&mode, &lazy);
/* Set up a flag which tells we are just starting. */
_dl_starting_up = 1;
@@ -930,3 +905,95 @@ print_missing_version (int errcode __attribute__ ((unused)),
_dl_sysdep_error (_dl_argv[0] ?: "<program name unknown>", ": ",
objname, ": ", errstring, "\n", NULL);
}
+
+/* Process all environments variables the dynamic linker must recognize.
+ Since all of them start with `LD_' we are a bit smarter while finding
+ all the entries. */
+static void
+process_envvars (enum mode *modep, int *lazyp)
+{
+ char **runp = NULL;
+ char *envline;
+ enum mode mode = normal;
+ int bind_now = 0;
+
+ /* This is the default place for profiling data file. */
+ _dl_profile_output = "/var/tmp";
+
+ while ((envline = _dl_next_ld_env_entry (&runp)) != NULL)
+ {
+ int result;
+
+ /* Do we bind early? */
+ result = strncmp (&envline[3], "BIND_NOW=", 9);
+ if (result == 0)
+ {
+ bind_now = 1;
+ continue;
+ }
+ if (result < 0)
+ continue;
+
+ /* Which shared object shall be profiled. */
+ result = strncmp (&envline[3], "PROFILE=", 8);
+ if (result == 0)
+ {
+ _dl_profile = &envline[11];
+ if (*_dl_profile == '\0')
+ _dl_profile = NULL;
+ continue;
+ }
+ if (result < 0)
+ continue;
+
+ /* Where to place the profiling data file. */
+ result = strncmp (&envline[3], "PROFILE_OUTPUT=", 15);
+ if (result == 0)
+ {
+ _dl_profile_output = &envline[18];
+ if (*_dl_profile_output == '\0')
+ _dl_profile_output = "/var/tmp";
+ continue;
+ }
+ if (result < 0)
+ continue;
+
+ /* Test whether we want to see the content of the auxiliary
+ array passed up from the kernel. */
+ result = strncmp (&envline[3], "SHOW_AUXV=", 10);
+ if (result == 0)
+ {
+ _dl_show_auxv ();
+ continue;
+ }
+ if (result < 0)
+ continue;
+
+ /* The mode of the dynamic linker can be set. */
+ result = strncmp (&envline[3], "TRACE_LOADED_OBJECTS=", 21);
+ if (result == 0)
+ {
+ mode = trace;
+ continue;
+ }
+ if (result < 0)
+ continue;
+
+ /* Warning level, verbose or not. */
+ result = strncmp (&envline[3], "WARN=", 5);
+ if (result == 0)
+ {
+ _dl_verbose = envline[8] != '\0';
+ continue;
+ }
+ }
+
+ /* LAZY is determined by the environment variable LD_WARN and
+ LD_BIND_NOW if we trace the binary. */
+ if (mode == trace)
+ *lazyp = _dl_verbose ? !bind_now : -1;
+ else
+ *lazyp = !__libc_enable_secure && !bind_now;
+
+ *modep = mode;
+}
diff --git a/manual/maint.texi b/manual/maint.texi
index 560b04e..6225cb4 100644
--- a/manual/maint.texi
+++ b/manual/maint.texi
@@ -377,7 +377,7 @@ doesn't tell you, that's a bug in the manual. Report that too! If the
function's behavior disagrees with the manual, then either the library
or the manual has a bug, so report the disagreement. If you find any
errors or omissions in this manual, please report them to the Internet
-address @email{bug-glibc-manual@@prep.ai.mit.edu}.
+address @email{bug-glibc-manual@@gnu.org}.
@node Source Layout
@appendixsec Adding New Functions
diff --git a/nscd/nscd_getgr_r.c b/nscd/nscd_getgr_r.c
index 596e31f..8129d81 100644
--- a/nscd/nscd_getgr_r.c
+++ b/nscd/nscd_getgr_r.c
@@ -48,7 +48,7 @@ __nscd_getgrgid_r (gid_t gid, struct group *resultbuf, char *buffer,
size_t buflen)
{
char *p = buffer;
- char plen;
+ int plen;
plen = snprintf (buffer, buflen, "%d", gid);
if (plen == -1)
@@ -98,7 +98,8 @@ __nscd_getgr_r (const char *key, request_type type, struct group *resultbuf,
ssize_t nbytes;
if (sock == -1)
- return 1;
+ /* Returning two signals that contacting the daemon failed. */
+ return 2;
req.version = NSCD_VERSION;
req.type = type;
diff --git a/nscd/nscd_getpw_r.c b/nscd/nscd_getpw_r.c
index 4fc78e1..4420b80 100644
--- a/nscd/nscd_getpw_r.c
+++ b/nscd/nscd_getpw_r.c
@@ -48,7 +48,7 @@ __nscd_getpwuid_r (uid_t uid, struct passwd *resultbuf, char *buffer,
size_t buflen)
{
char *p = buffer;
- char plen;
+ int plen;
plen = snprintf (buffer, buflen, "%d", uid);
if (plen == -1)
@@ -98,7 +98,8 @@ __nscd_getpw_r (const char *key, request_type type, struct passwd *resultbuf,
ssize_t nbytes;
if (sock == -1)
- return 1;
+ /* Returning two signals that contacting the daemon failed. */
+ return 2;
req.version = NSCD_VERSION;
req.type = type;
diff --git a/nss/getXXbyYY_r.c b/nss/getXXbyYY_r.c
index a4dc001..8a38b0d 100644
--- a/nss/getXXbyYY_r.c
+++ b/nss/getXXbyYY_r.c
@@ -88,6 +88,12 @@ extern struct __res_state _res;
/* The lookup function for the first entry of this service. */
extern int DB_LOOKUP_FCT (service_user **nip, const char *name, void **fctp);
+/* Nonzero if the NSCD is not available. This variable will be increased
+ whenever we try to use the NSCD but see it is not avilable. So we
+ can recheck the presence every once in a while. */
+extern int __nss_nscd_not_available;
+/* Interval in which we transfer retry to contact the NSCD. */
+#define NSS_NSCD_RETRY 100
int
@@ -111,11 +117,21 @@ INTERNAL (REENTRANT_NAME) (ADD_PARAMS, LOOKUP_TYPE *resbuf, char *buffer,
#endif
#ifdef USE_NSCD
- nscd_status = NSCD_NAME (ADD_VARIABLES, resbuf, buffer, buflen H_ERRNO_VAR);
- if (nscd_status < 1)
+ if (__nss_nscd_not_available && ++__nss_nscd_not_available > NSS_NSCD_RETRY)
+ __nss_nscd_not_available = 0;
+
+ if (!__nss_nscd_not_available)
{
- *result = nscd_status == 0 ? resbuf : NULL;
- return nscd_status;
+ nscd_status = NSCD_NAME (ADD_VARIABLES, resbuf, buffer, buflen
+ H_ERRNO_VAR);
+ if (nscd_status < 1)
+ {
+ *result = nscd_status == 0 ? resbuf : NULL;
+ return nscd_status;
+ }
+ if (nscd_status == 2)
+ /* This return value indicates that contacting the server failed. */
+ __nss_nscd_not_available = 1;
}
#endif
@@ -152,7 +168,7 @@ INTERNAL (REENTRANT_NAME) (ADD_PARAMS, LOOKUP_TYPE *resbuf, char *buffer,
status = (*fct) (ADD_VARIABLES, resbuf, buffer, buflen,
__errno_location () H_ERRNO_VAR);
- /* The the status is NSS_STATUS_TRYAGAIN and errno is ERANGE the
+ /* The status is NSS_STATUS_TRYAGAIN and errno is ERANGE the
provided buffer is too small. In this case we should give
the user the possibility to enlarge the buffer and we should
not simply go on with the next service (even if the TRYAGAIN
diff --git a/nss/nsswitch.c b/nss/nsswitch.c
index 65da26b..2a3e44a 100644
--- a/nss/nsswitch.c
+++ b/nss/nsswitch.c
@@ -69,6 +69,9 @@ static struct
__libc_lock_define_initialized (static, lock)
+/* Nonzero if no NSCD is available. */
+int __nss_nscd_not_available;
+
#if !defined DO_STATIC_NSS || defined PIC
/* String with revision number of the shared object files. */
static const char *const __nss_shlib_revision = LIBNSS_FILES_SO + 15;
@@ -380,7 +383,7 @@ nss_lookup_function (service_user *ni, const char *fct_name)
/* Load the shared library. */
size_t shlen = (7 + strlen (ni->library->name) + 3
+ strlen (__nss_shlib_revision) + 1);
-
+ int saved_errno = errno;
struct do_open_args args;
args.shlib_name = __alloca (shlen);
args.ni = ni;
@@ -393,8 +396,11 @@ nss_lookup_function (service_user *ni, const char *fct_name)
__nss_shlib_revision);
if (nss_dlerror_run (do_open, &args) != 0)
- /* Failed to load the library. */
- ni->library->lib_handle = (void *) -1l;
+ {
+ /* Failed to load the library. */
+ ni->library->lib_handle = (void *) -1l;
+ __set_errno (saved_errno);
+ }
}
if (ni->library->lib_handle == (void *) -1l)
diff --git a/sysdeps/generic/dl-sysdep.c b/sysdeps/generic/dl-sysdep.c
index b007aa6..21b470c 100644
--- a/sysdeps/generic/dl-sysdep.c
+++ b/sysdeps/generic/dl-sysdep.c
@@ -243,3 +243,29 @@ _dl_show_auxv (void)
break;
}
}
+
+/* Walk through the environment of the process and return all entries
+ starting with `LD_'. */
+char *
+_dl_next_ld_env_entry (char ***position)
+{
+ char **current = *position;
+ char *result = NULL;
+
+ if (current == NULL)
+ /* We start over. */
+ current = _environ;
+
+ while (result == NULL && *current != NULL)
+ {
+ if ((*current)[0] == 'L' && (*current)[1] == 'D' && (*current)[2] == '_')
+ result = *current;
+
+ ++current;
+ }
+
+ /* Save current position for next visit. */
+ *position = current;
+
+ return result;
+}
diff --git a/sysdeps/unix/sysv/linux/powerpc/sysdep.h b/sysdeps/unix/sysv/linux/powerpc/sysdep.h
index 944793d..c75e2a8 100644
--- a/sysdeps/unix/sysv/linux/powerpc/sysdep.h
+++ b/sysdeps/unix/sysv/linux/powerpc/sysdep.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 1992, 1997 Free Software Foundation, Inc.
+/* Copyright (C) 1992, 1997, 1998 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
@@ -138,6 +138,7 @@
END (name)
/* Local labels stripped out by the linker. */
+#undef L
#define L(x) .L##x
#endif /* ASSEMBLER */