From dbe31b9a738993b563382c602d092c970bdc79ae Mon Sep 17 00:00:00 2001 From: Roland McGrath Date: Fri, 5 Jul 1996 19:18:13 +0000 Subject: [PATCH] * nss/nss_files/files-parse.c (parse_list): Set EOL from LINE if it points within DATA->linebuffer; otherwise use all of DATA->linebuffer itself, no need to skip past a NUL. * nss/nsswitch.h (known_function): Comment fix. * nss/nsswitch.c (nss_lookup_function): Rewritten using __tsearch directly. Do the lookup and insertion with a single call, and fill in the tree node afterwards if new. (known_compare, nss_find_entry, nss_insert_entry): Functions removed. * misc/sys/select.h: #define __need_timespec before incl. (struct timeval): Add bodiless decl for scope. * time/time.h (struct timespec): Rename members from `ts_*' to `tv_*'. Move struct timespec defn outside [_TIME_H] so it can be got with #define __need_timespec. * time/sys/time.h (TIMEVAL_TO_TIMESPEC): Use `tv_*' instead of `ts_*' for `struct timespec' member names. (TIMESPEC_TO_TIMEVAL): Likewise. * nss/Makefile (extra-libs-others): New variable. * extra-lib.mk: Don't test for $($(lib)-no-lib-dep). Instead match $(lib) in $(extra-libs-others). * sunrpc/Makefile (extra-libs-others): New variable. (librpcsvc-no-lib-dep): Variable removed. Thu Jul 4 05:21:59 1996 David Mosberger-Tang * login/utmp.h: Fix typos. * misc/syslog.c (vsyslog): Use __send instead of send and __connect instead of connect to avoid name-space collisions (e.g., with psgetty). --- ChangeLog | 36 ++++++++ extra-lib.mk | 2 +- login/utmp.h | 4 +- misc/sys/select.h | 11 ++- misc/syslog.c | 7 +- nss/Makefile | 3 + nss/nss_files/files-parse.c | 11 ++- nss/nsswitch.c | 216 ++++++++++++++++++++++---------------------- nss/nsswitch.h | 4 +- sunrpc/Makefile | 2 +- time/sys/time.h | 8 +- time/time.h | 29 ++++-- 12 files changed, 197 insertions(+), 136 deletions(-) diff --git a/ChangeLog b/ChangeLog index ec8b1c9..4bb6819 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,33 @@ Fri Jul 5 12:22:51 1996 Roland McGrath + * nss/nss_files/files-parse.c (parse_list): Set EOL from LINE if it + points within DATA->linebuffer; otherwise use all of DATA->linebuffer + itself, no need to skip past a NUL. + + * nss/nsswitch.h (known_function): Comment fix. + * nss/nsswitch.c (nss_lookup_function): Rewritten using __tsearch + directly. Do the lookup and insertion with a single call, and fill in + the tree node afterwards if new. + (known_compare, nss_find_entry, nss_insert_entry): Functions removed. + + * misc/sys/select.h: #define __need_timespec before incl. + (struct timeval): Add bodiless decl for scope. + + * time/time.h (struct timespec): Rename members from `ts_*' to `tv_*'. + Move struct timespec defn outside [_TIME_H] so it can be got with + #define __need_timespec. + + * time/sys/time.h (TIMEVAL_TO_TIMESPEC): Use `tv_*' instead of `ts_*' + for `struct timespec' member names. + (TIMESPEC_TO_TIMEVAL): Likewise. + + * nss/Makefile (extra-libs-others): New variable. + + * extra-lib.mk: Don't test for $($(lib)-no-lib-dep). Instead match + $(lib) in $(extra-libs-others). + * sunrpc/Makefile (extra-libs-others): New variable. + (librpcsvc-no-lib-dep): Variable removed. + * elf/rtld.c: Define RTLD_BOOTSTRAP before #include "dynamic-link.h". * sysdeps/i386/dl-machine.h (elf_machine_rel): Remove weak decl for _dl_rtld_map. @@ -10,6 +38,14 @@ Fri Jul 5 12:22:51 1996 Roland McGrath * posix/unistd.h [__USE_BSD]: Declare getdomainname, setdomainname. +Thu Jul 4 05:21:59 1996 David Mosberger-Tang + + * login/utmp.h: Fix typos. + + * misc/syslog.c (vsyslog): Use __send instead of send and + __connect instead of connect to avoid name-space collisions (e.g., + with psgetty). + Wed Jul 3 16:29:41 1996 Roland McGrath * nss/getXXbyYY_r.c (REENTRANT_NAME): Cast FCT in __nss_next call. diff --git a/extra-lib.mk b/extra-lib.mk index 5368a03..46eef03 100644 --- a/extra-lib.mk +++ b/extra-lib.mk @@ -25,7 +25,7 @@ alltypes-$(lib) := $(foreach o,$(object-suffixes-$(lib)),\ $(objpfx)$(patsubst %,$(libtype$o),\ $(lib:lib%=%))) -ifeq (,$($(lib)-no-lib-dep)) +ifeq (,$(filter $(lib),extra-libs-others)) lib-noranlib: $(alltypes-$(lib)) ifeq (yes,$(build-shared)) lib-noranlib: $(objpfx)$(lib).so$($(lib).so-version) diff --git a/login/utmp.h b/login/utmp.h index e9c1734..0109d50 100644 --- a/login/utmp.h +++ b/login/utmp.h @@ -76,7 +76,7 @@ extern struct utmp *pututline __P ((__const struct utmp *__utmp_ptr)); #ifdef __USE_REENTRANT -/* Define the data structure needed for the reentrent version. */ +/* Define the data structure needed for the reentrant version. */ struct utmp_data { int ut_fd; @@ -85,7 +85,7 @@ struct utmp_data }; -/* Reentrent versions of the file for handling utmp files. */ +/* Reentrant versions of the file for handling utmp files. */ extern int getutent_r __P ((struct utmp **__utmp, struct utmp_data *__utmp_data)); diff --git a/misc/sys/select.h b/misc/sys/select.h index ece1916..320df02 100644 --- a/misc/sys/select.h +++ b/misc/sys/select.h @@ -28,14 +28,17 @@ Boston, MA 02111-1307, USA. */ #include /* Get definition of timer specification structures. */ -/* XXX this is wrong. 1003.1gD6.1 says `struct timespec' - is defined by , and that is all. - However, since a program is required to include - before using select/pselect anyway, perhaps it doesn't matter. */ +#define __need_timespec #include __BEGIN_DECLS +/* This declaration puts `struct timeval' in global scope even if + has not been included to define it. That way the + `select' prototype below will not conflict with a later definition + of `struct timeval'. */ +struct timeval; + /* Representation of a set of file descriptors. */ #define fd_set __fd_set diff --git a/misc/syslog.c b/misc/syslog.c index 068a89e..bcac6c7 100644 --- a/misc/syslog.c +++ b/misc/syslog.c @@ -163,7 +163,7 @@ vsyslog(pri, fmt, ap) /* Get connected, output the message to the local logger. */ if (!connected) openlog(LogTag, LogStat | LOG_NDELAY, 0); - if (send(LogFile, buf, bufsize, 0) < 0) + if (__send(LogFile, buf, bufsize, 0) < 0) { /* * Output the message to the console; don't worry about blocking, @@ -205,11 +205,12 @@ openlog(ident, logstat, logfac) } } if (LogFile != -1 && !connected) - if (connect(LogFile, &SyslogAddr, sizeof(SyslogAddr)) == -1) { + if (__connect(LogFile, &SyslogAddr, sizeof(SyslogAddr)) == -1) + { (void)close(LogFile); LogFile = -1; } else - connected = 1; + connected = 1; } void diff --git a/nss/Makefile b/nss/Makefile index 8df173c..b80ed76 100644 --- a/nss/Makefile +++ b/nss/Makefile @@ -34,6 +34,9 @@ databases = proto service hosts network grp pwd rpc ethers services := files dns db extra-libs = $(services:%=libnss_%) +# These libraries will be built in the `others' pass rather than +# the `lib' pass, because they depend on libc.so being built already. +extra-libs-others = $(extra-libs) # The sources are found in the appropriate subdir. subdir-dirs = $(services:%=nss_%) diff --git a/nss/nss_files/files-parse.c b/nss/nss_files/files-parse.c index 8930780..1f3b138 100644 --- a/nss/nss_files/files-parse.c +++ b/nss/nss_files/files-parse.c @@ -128,8 +128,15 @@ parse_list (char *line, struct parser_data *data, int datalen) { char *eol, **list, **p; - /* Find the end of the line buffer. */ - eol = strchr (data->linebuffer, '\0') + 1; + if (line >= data->linebuffer && line < (char *) data + datalen) + /* Find the end of the line buffer, we will use the space in DATA after + it for storing the vector of pointers. */ + eol = strchr (line, '\0') + 1; + else + /* LINE does not point within DATA->linebuffer, so that space is + not being used for scratch space right now. We can use all of + it for the pointer vector storage. */ + eol = data->linebuffer; /* Adjust the pointer so it is aligned for storing pointers. */ eol += __alignof__ (char *) - 1; eol -= (eol - (char *) 0) % __alignof__ (char *); diff --git a/nss/nsswitch.c b/nss/nsswitch.c index c748eb1..c92f33b 100644 --- a/nss/nsswitch.c +++ b/nss/nsswitch.c @@ -32,10 +32,6 @@ Boston, MA 02111-1307, USA. */ /* Prototypes for the local functions. */ static void nss_init (void); static void *nss_lookup_function (service_user *ni, const char *fct_name); -static int nss_find_entry (struct entry **knownp, const char *key, - void **valp); -static void nss_insert_entry (struct entry **knownp, const char *key, - void *val); static name_database *nss_parse_file (const char *fname); static name_database_entry *nss_getline (char *line); static service_user *nss_parse_service_list (const char *line); @@ -191,131 +187,133 @@ nss_dlerror_run (void (*operate) (void)) static void * nss_lookup_function (service_user *ni, const char *fct_name) { - void *result; - - /* Determine whether current function is loaded. */ - if (nss_find_entry (&ni->known, fct_name, &result) >= 0) - return result; + /* Comparison function for searching NI->known tree. */ + int known_compare (const void *p1, const void *p2) + { + return p1 == p2 ? 0 : strcmp (*(const char *const *) p1, + *(const char *const *) p2); + } + void **found, *result; /* We now modify global data. Protect it. */ __libc_lock_lock (lock); - if (ni->library == NULL) - { - /* This service has not yet been used. Fetch the service library - for it, creating a new one if need be. If there is no service - table from the file, this static variable holds the head of the - service_library list made from the default configuration. */ - static name_database default_table; - ni->library = nss_new_service (service_table ?: &default_table, - ni->name); - if (ni->library == NULL) - { - /* This only happens when out of memory. */ - __libc_lock_unlock (lock); - return NULL; - } - } - - if (ni->library->lib_handle == NULL) + /* Search the tree of functions previously requested. Data in the + tree are `known_function' structures, whose first member is a + `const char *', the lookup key. The search returns a pointer to + the tree node structure; the first member of the is a pointer to + our structure (i.e. what will be a `known_function'); since the + first member of that is the lookup key string, &FCT_NAME is close + enough to a pointer to our structure to use as a lookup key that + will be passed to `known_compare' (above). */ + + found = __tsearch (&fct_name, (void **) &ni->known, &known_compare); + if (*found != &fct_name) + /* The search found an existing structure in the tree. */ + result = ((known_function *) *found)->fct_ptr; + else { - /* Load the shared library. */ - size_t shlen = (7 + strlen (ni->library->name) + 3 - + sizeof (NSS_SHLIB_REVISION)); - char shlib_name[shlen]; + /* This name was not known before. Now we have a node in the tree + (in the proper sorted position for FCT_NAME) that points to + &FCT_NAME instead of any real `known_function' structure. + Allocate a new structure and fill it in. */ - void do_open (void) + known_function *known = malloc (sizeof *known); + if (! known) { - /* Open and relocate the shared object. */ - ni->library->lib_handle = _dl_open (shlib_name, RTLD_LAZY); + remove_from_tree: + /* Oops. We can't instantiate this node properly. + Remove it from the tree. */ + __tdelete (&fct_name, (void **) &ni->known, &known_compare); + result = NULL; } - - /* Construct name. */ - __stpcpy (__stpcpy (__stpcpy (shlib_name, "libnss_"), ni->library->name), - ".so" NSS_SHLIB_REVISION); - - if (nss_dlerror_run (do_open) != 0) - /* Failed to load the library. */ - ni->library->lib_handle = (void *) -1; - } - - if (ni->library->lib_handle == (void *) -1) - /* Library not found => function not found. */ - result = NULL; - else - { - /* Get the desired function. Again, GNU ld.so magic ahead. */ - size_t namlen = (5 + strlen (ni->library->name) + 1 - + strlen (fct_name) + 1); - char name[namlen]; - struct link_map *map = ni->library->lib_handle; - ElfW(Addr) loadbase; - const ElfW(Sym) *ref = NULL; - void get_sym (void) + else { - struct link_map *scope[2] = { map, NULL }; - loadbase = _dl_lookup_symbol (name, &ref, scope, map->l_name, 0, 0); - } - - __stpcpy (__stpcpy (__stpcpy (__stpcpy (name, "_nss_"), - ni->library->name), - "_"), - fct_name); - - result = (nss_dlerror_run (get_sym) - ? NULL : (void *) (loadbase + ref->st_value)); - } - - /* Remember function pointer for the usage. */ - nss_insert_entry (&ni->known, fct_name, result); - - /* Remove the lock. */ - __libc_lock_unlock (lock); - - return result; -} - - -static int -known_compare (const void *p1, const void *p2) -{ - known_function *v1 = (known_function *) p1; - known_function *v2 = (known_function *) p2; - - return strcmp (v1->fct_name, v2->fct_name); -} + /* Point the tree node at this new structure. */ + *found = known; + known->fct_name = fct_name; + if (ni->library == NULL) + { + /* This service has not yet been used. Fetch the service + library for it, creating a new one if need be. If there + is no service table from the file, this static variable + holds the head of the service_library list made from the + default configuration. */ + static name_database default_table; + ni->library = nss_new_service (service_table ?: &default_table, + ni->name); + if (ni->library == NULL) + { + /* This only happens when out of memory. */ + free (known); + goto remove_from_tree; + } + } -static int -nss_find_entry (struct entry **knownp, const char *key, void **valp) -{ - known_function looking_for = { fct_name: key }; - struct entry **found; + if (ni->library->lib_handle == NULL) + { + /* Load the shared library. */ + size_t shlen = (7 + strlen (ni->library->name) + 3 + + sizeof (NSS_SHLIB_REVISION)); + char shlib_name[shlen]; - found = __tfind (&looking_for, (const void **) knownp, known_compare); + void do_open (void) + { + /* Open and relocate the shared object. */ + ni->library->lib_handle = _dl_open (shlib_name, RTLD_LAZY); + } - if (found == NULL) - return -1; + /* Construct shared object name. */ + __stpcpy (__stpcpy (__stpcpy (shlib_name, "libnss_"), + ni->library->name), + ".so" NSS_SHLIB_REVISION); - *valp = ((known_function *) (*found)->key)->fct_ptr; + if (nss_dlerror_run (do_open) != 0) + /* Failed to load the library. */ + ni->library->lib_handle = (void *) -1; + } - return 0; -} + if (ni->library->lib_handle == (void *) -1) + /* Library not found => function not found. */ + result = NULL; + else + { + /* Get the desired function. Again, GNU ld.so magic ahead. */ + size_t namlen = (5 + strlen (ni->library->name) + 1 + + strlen (fct_name) + 1); + char name[namlen]; + struct link_map *map = ni->library->lib_handle; + ElfW(Addr) loadbase; + const ElfW(Sym) *ref = NULL; + void get_sym (void) + { + struct link_map *scope[2] = { map, NULL }; + loadbase = _dl_lookup_symbol (name, &ref, + scope, map->l_name, 0, 0); + } + /* Construct the function name. */ + __stpcpy (__stpcpy (__stpcpy (__stpcpy (name, "_nss_"), + ni->library->name), + "_"), + fct_name); -static void -nss_insert_entry (struct entry **knownp, const char *key, void *val) -{ - known_function *to_insert; + /* Look up the symbol. */ + result = (nss_dlerror_run (get_sym) + ? NULL : (void *) (loadbase + ref->st_value)); + } - to_insert = (known_function *) malloc (sizeof (known_function)); - if (to_insert == NULL) - return; + /* Remember function pointer for later calls. Even if null, we + record it so a second try needn't search the library again. */ + known->fct_ptr = result; + } + } - to_insert->fct_name = key; - to_insert->fct_ptr = val; + /* Remove the lock. */ + __libc_lock_unlock (lock); - __tsearch (to_insert, (void **) knownp, known_compare); + return result; } diff --git a/nss/nsswitch.h b/nss/nsswitch.h index d95d432..c4d4d11 100644 --- a/nss/nsswitch.h +++ b/nss/nsswitch.h @@ -60,7 +60,9 @@ typedef struct service_library } service_library; -/* For mappng a function name to a function pointer. */ +/* For mapping a function name to a function pointer. It is known in + nsswitch.c:nss_lookup_function that a string pointer for the lookup key + is the first member. */ typedef struct { const char *fct_name; diff --git a/sunrpc/Makefile b/sunrpc/Makefile index d7101fe..428e6a1 100644 --- a/sunrpc/Makefile +++ b/sunrpc/Makefile @@ -74,10 +74,10 @@ distribute := rpc_util.h rpc_parse.h rpc_scan.h $(rpcgen-objs:.o=.c) etc.rpc extra-objs = $(rpcgen-objs) extra-libs := librpcsvc +extra-libs-others := librpcsvc # Make it in `others' pass, not `lib' pass. librpcsvc-routines = $(rpcsvc:%.x=x%) librpcsvc-inhibit-o = .so # Build no shared rpcsvc library. omit-deps = $(librpcsvc-routines) -librpcsvc-no-lib-dep = t # Don't depend on this in `make lib' pass. # Sun's code is not too clean. override +gccwarn := -w diff --git a/time/sys/time.h b/time/sys/time.h index c075333..ca82d87 100644 --- a/time/sys/time.h +++ b/time/sys/time.h @@ -35,12 +35,12 @@ struct timeval /* Macros for converting between `struct timeval' and `struct timespec'. */ #define TIMEVAL_TO_TIMESPEC(tv, ts) { \ - (ts)->ts_sec = (tv)->tv_sec; \ - (ts)->ts_nsec = (tv)->tv_usec * 1000; \ + (ts)->tv_sec = (tv)->tv_sec; \ + (ts)->tv_nsec = (tv)->tv_usec * 1000; \ } #define TIMESPEC_TO_TIMEVAL(tv, ts) { \ - (tv)->tv_sec = (ts)->ts_sec; \ - (tv)->tv_usec = (ts)->ts_nsec / 1000; \ + (tv)->tv_sec = (ts)->tv_sec; \ + (tv)->tv_usec = (ts)->tv_nsec / 1000; \ } diff --git a/time/time.h b/time/time.h index 5926d80..596351b 100644 --- a/time/time.h +++ b/time/time.h @@ -22,7 +22,8 @@ Cambridge, MA 02139, USA. */ #ifndef _TIME_H -#if !defined(__need_time_t) && !defined(__need_clock_t) +#if (! defined (__need_time_t) && !defined(__need_clock_t) && \ + ! defined (__need_timespec)) #define _TIME_H 1 #include @@ -78,6 +79,24 @@ typedef __time_t time_t; #undef __need_time_t +#if ! defined(__timespec_defined) && \ + ((defined (_TIME_H) && defined (__USE_POSIX)) || \ + defined (__need_timespec)) +#define __timespec_defined 1 + +/* POSIX.4 structure for a time value. This is like a `struct timeval' but + has nanoseconds instead of microseconds. */ +struct timespec + { + long int tv_sec; /* Seconds. */ + long int tv_nsec; /* Nanoseconds. */ + }; + +#endif /* timespec not defined and or need timespec. */ +#undef __need_timespec + + + #ifdef _TIME_H /* Used by other time functions. */ struct tm @@ -229,14 +248,6 @@ extern int dysize __P ((int __year)); #endif -/* POSIX.4 structure for a time value. This is like a `struct timeval' but - has nanoseconds instead of microseconds. */ -struct timespec - { - long int ts_sec; /* Seconds. */ - long int ts_nsec; /* Nanoseconds. */ - }; - #ifdef __USE_POSIX /* Pause execution for a number of nanoseconds. */ extern int nanosleep __P ((__const struct timespec *__requested_time, -- 2.7.4