diff options
| -rw-r--r-- | MakeTAGS | 13 | ||||
| -rw-r--r-- | Makerules | 9 | ||||
| -rw-r--r-- | config.make.in | 1 | ||||
| -rw-r--r-- | configure.in | 2 | ||||
| -rw-r--r-- | elf/dl-load.c | 42 | ||||
| -rw-r--r-- | elf/dl-lookup.c | 19 | ||||
| -rw-r--r-- | elf/dl-reloc.c | 4 | ||||
| -rw-r--r-- | elf/dl-runtime.c | 4 | ||||
| -rw-r--r-- | elf/dl-symbol.c | 2 | ||||
| -rw-r--r-- | elf/dlsym.c | 2 | ||||
| -rw-r--r-- | elf/link.h | 14 | ||||
| -rw-r--r-- | elf/rtld.c | 4 | ||||
| -rw-r--r-- | manual/examples/strdupa.c | 19 | ||||
| -rw-r--r-- | manual/libc.texinfo | 9 | ||||
| -rw-r--r-- | manual/nss.texi | 586 | ||||
| -rw-r--r-- | manual/nsswitch.texi | 16 | ||||
| -rw-r--r-- | manual/string.texi | 77 | ||||
| -rw-r--r-- | manual/users.texi | 18 | ||||
| -rw-r--r-- | nss/nsswitch.c | 2 | ||||
| -rw-r--r-- | po/SYS_libc.pot | 1378 | ||||
| -rw-r--r-- | po/header.pot | 1 | ||||
| -rw-r--r-- | shadow/sgetspent_r.c | 2 | ||||
| -rw-r--r-- | stdlib/strtod.c | 2 | ||||
| -rw-r--r-- | string/strdup.c | 4 | ||||
| -rw-r--r-- | sysdeps/alpha/dl-machine.h | 4 | ||||
| -rw-r--r-- | sysdeps/i386/dl-machine.h | 10 | ||||
| -rw-r--r-- | sysdeps/m68k/dl-machine.h | 18 | ||||
| -rw-r--r-- | sysdeps/mips/dl-machine.h | 2 | ||||
| -rw-r--r-- | sysdeps/unix/sysv/linux/i386/clone.S | 1 | ||||
| -rw-r--r-- | sysdeps/unix/sysv/linux/m68k/clone.S | 75 |
30 files changed, 2080 insertions, 260 deletions
@@ -132,8 +132,8 @@ endif define extract @rm -f $@.new -$(XGETTEXT) --keyword=_ --keyword=N_ --add-comments=TRANS --sort-output -d - \ - $(XGETTEXTFLAGS-$(@F)) > $@.new $^ +$(XGETTEXT) --keyword=_ --keyword=N_ --add-comments=TRANS --sort-output \ + --omit-header -n -d - $(XGETTEXTFLAGS-$(@F)) > $@.new $^ mv -f $@.new $@ endef @@ -146,15 +146,12 @@ else endif $P/siglist.pot: $(common-objpfx)siglist.c; $(extract) -$P/errlist.pot: $(..)sysdeps/gnu/errlist.c; $(extract) -# Extract all strings from these files; their strings are not marked. +# Extract all strings from this file; its strings are not marked. # Their surroundings are also not interesting. XGETTEXTFLAGS-siglist.pot = -a --no-location -XGETTEXTFLAGS-errlist.pot = -a --no-location -all-pot = $P/libc-top.pot $P/subdirs.pot \ - $P/siglist.pot $P/errlist.pot +all-pot = $P/libc-top.pot $P/subdirs.pot $P/siglist.pot ifndef subdir # Collect all the subdir messages, massaging the file names in comments @@ -173,7 +170,7 @@ $P/SYS_libc.pot: $(all-pot) @rm -f $@.new sed -e 's/VERSION/$(version)/' -e "s/DATE/`date +'%Y-%m-%d %k:%M'`/" \ po/header.pot > $@.new - $(XGETTEXT) -d - -n -s --omit-header $^ >> $@.new + $(XGETTEXT) -d - --omit-header -n -s $^ >> $@.new mv -f $@.new $@ test ! -d CVS || cvs ci -m'Regenerated from source files' $@ @@ -454,9 +454,10 @@ endef object-suffixes-left := $(object-suffixes) include $(o-iterator) define do-ar +topdir=`cd $(..).; pwd`; \ $(patsubst %,cd %;,$(objdir)) \ -$(AUTOLOCK) ${O%-lib}.lck $(AR) cru$(verbose) ${O%-lib} \ - $(patsubst $(objpfx)%,%,$^) +$$topdir/autolock.sh ${O%-lib}.lck $(AR) cru$(verbose) ${O%-lib} \ + $(patsubst $(objpfx)%,%,$^) rm -f $@ touch $@ endef @@ -474,7 +475,9 @@ define o-iterator-doit $(common-objpfx)$(patsubst %,$(libtype$o),c)($(ar-symtab-name)): \ $(common-objpfx)$(patsubst %,$(libtype$o),c)(\ $(patsubst $(objpfx)%,%,$(o-objects))) $(subdirs-stamp-o); \ - $(AUTOLOCK) $$(common-objpfx)$$(patsubst %,$$(libtype$o),c).lck \ + topdir=`cd $(..).; pwd`; \ + $$$$topdir/autolock.sh \ + $$(common-objpfx)$$(patsubst %,$$(libtype$o),c).lck \ $$(RANLIB) $$(common-objpfx)$$(patsubst %,$$(libtype$o),c) endef ifndef subdir diff --git a/config.make.in b/config.make.in index a496e29f0d..b099199c36 100644 --- a/config.make.in +++ b/config.make.in @@ -34,7 +34,6 @@ CC = @CC@ BUILD_CC = @BUILD_CC@ CFLAGS = @CFLAGS@ AR = @AR@ -AUTOLOCK = @AUTOLOCK@ RANLIB = @RANLIB@ AS = $(CC) -c diff --git a/configure.in b/configure.in index aebc785904..631a035e92 100644 --- a/configure.in +++ b/configure.in @@ -308,8 +308,6 @@ fi AC_PROG_CPP AC_CHECK_TOOL(AR, ar) AC_CHECK_TOOL(RANLIB, ranlib, :) -AUTOLOCK="`(cd $srcdir; pwd)`/autolock.sh" -AC_SUBST(AUTOLOCK) AC_CACHE_CHECK(for signed size_t type, libc_cv_signed_size_t, [dnl echo '#include <stddef.h> diff --git a/elf/dl-load.c b/elf/dl-load.c index 8ccc838b2b..6fd6a6cbe0 100644 --- a/elf/dl-load.c +++ b/elf/dl-load.c @@ -70,11 +70,25 @@ int _dl_zerofd = -1; size_t _dl_pagesize; +/* Local version of `strdup' function. */ +static inline char * +local_strdup (const char *s) +{ + size_t len = strlen (s) + 1; + void *new = malloc (len); + + if (new == NULL) + return NULL; + + return (char *) memcpy (new, s, len); +} + + /* Map in the shared object NAME, actually located in REALNAME, and already opened on FD. */ struct link_map * -_dl_map_object_from_fd (const char *name, int fd, char *realname, +_dl_map_object_from_fd (char *name, int fd, char *realname, struct link_map *loader, int l_type) { struct link_map *l = NULL; @@ -96,6 +110,7 @@ _dl_map_object_from_fd (const char *name, int fd, char *realname, l->l_next->l_prev = l->l_prev; free (l); } + free (name); free (realname); _dl_signal_error (code, name, msg); } @@ -142,6 +157,7 @@ _dl_map_object_from_fd (const char *name, int fd, char *realname, /* The object is already loaded. Just bump its reference count and return it. */ __close (fd); + free (name); free (realname); ++l->l_opencount; return l; @@ -524,11 +540,8 @@ _dl_map_object (struct link_map *loader, const char *name, int type) fd = __open (cached, O_RDONLY); if (fd != -1) { - size_t cl = strlen (cached) + 1; - realname = malloc (cl); - if (realname) - memcpy (realname, cached, cl); - else + realname = local_strdup (cached); + if (realname == NULL) { __close (fd); fd = -1; @@ -548,11 +561,8 @@ _dl_map_object (struct link_map *loader, const char *name, int type) fd = __open (name, O_RDONLY); if (fd != -1) { - size_t len = strlen (name) + 1; - realname = malloc (len); - if (realname) - memcpy (realname, name, len); - else + realname = local_strdup (name); + if (realname == NULL) { __close (fd); fd = -1; @@ -560,6 +570,16 @@ _dl_map_object (struct link_map *loader, const char *name, int type) } } + if (fd != -1) + { + name = local_strdup (name); + if (name == NULL) + { + __close (fd); + fd = -1; + } + } + if (fd == -1) _dl_signal_error (errno, name, "cannot open shared object file"); diff --git a/elf/dl-lookup.c b/elf/dl-lookup.c index 44f91fca7d..e57887bfdd 100644 --- a/elf/dl-lookup.c +++ b/elf/dl-lookup.c @@ -45,16 +45,16 @@ _dl_elf_hash (const char *name) } /* Search loaded objects' symbol tables for a definition of the symbol - UNDEF_NAME. The chosen value can't be RELOC_ADDR. If NOPLT is nonzero, - then a PLT entry cannot satisfy the reference; some different binding - must be found. */ + UNDEF_NAME. FLAGS is a set of flags. If DL_LOOKUP_NOEXEC is set, + then don't search the executable for a definition; this used for + copy relocs. If DL_LOOKUP_NOPLT is set, then a PLT entry cannot + satisfy the reference; some different binding must be found. */ ElfW(Addr) _dl_lookup_symbol (const char *undef_name, const ElfW(Sym) **ref, struct link_map *symbol_scope[], const char *reference_name, - ElfW(Addr) reloc_addr, - int noplt) + int flags) { const unsigned long int hash = _dl_elf_hash (undef_name); struct @@ -75,6 +75,10 @@ _dl_lookup_symbol (const char *undef_name, const ElfW(Sym) **ref, map = (*scope)->l_searchlist[i]; + /* Don't search the executable when resolving a copy reloc. */ + if (flags & DL_LOOKUP_NOEXEC && map->l_type == lt_executable) + continue; + symtab = ((void *) map->l_addr + map->l_info[DT_SYMTAB]->d_un.d_ptr); strtab = ((void *) map->l_addr + map->l_info[DT_STRTAB]->d_un.d_ptr); @@ -87,9 +91,8 @@ _dl_lookup_symbol (const char *undef_name, const ElfW(Sym) **ref, const ElfW(Sym) *sym = &symtab[symidx]; if (sym->st_value == 0 || /* No value. */ - /* Cannot resolve to the location being filled in. */ - reloc_addr == map->l_addr + sym->st_value || - (noplt && sym->st_shndx == SHN_UNDEF)) /* Reject PLT. */ + ((flags & DL_LOOKUP_NOPLT) != 0 /* Reject PLT entry. */ + && sym->st_shndx == SHN_UNDEF)) continue; switch (ELFW(ST_TYPE) (sym->st_info)) diff --git a/elf/dl-reloc.c b/elf/dl-reloc.c index 5adf0f6dac..fa424a4d01 100644 --- a/elf/dl-reloc.c +++ b/elf/dl-reloc.c @@ -57,9 +57,9 @@ _dl_relocate_object (struct link_map *l, struct link_map *scope[], int lazy) = ((void *) l->l_addr + l->l_info[DT_STRTAB]->d_un.d_ptr); /* This macro is used as a callback from the ELF_DYNAMIC_RELOCATE code. */ -#define RESOLVE(ref, reloc_addr, noplt) \ +#define RESOLVE(ref, flags) \ (_dl_lookup_symbol (strtab + (*ref)->st_name, ref, scope, \ - l->l_name, reloc_addr, noplt)) + l->l_name, flags)) #include "dynamic-link.h" ELF_DYNAMIC_RELOCATE (l, lazy); diff --git a/elf/dl-runtime.c b/elf/dl-runtime.c index 16e037914b..4e7b5296d4 100644 --- a/elf/dl-runtime.c +++ b/elf/dl-runtime.c @@ -122,9 +122,9 @@ fixup ( { /* This macro is used as a callback from the elf_machine_relplt code. */ -#define RESOLVE(ref, reloc_addr, noplt) \ +#define RESOLVE(ref, flags) \ (_dl_lookup_symbol (strtab + (*ref)->st_name, ref, scope, \ - l->l_name, reloc_addr, noplt)) + l->l_name, flags)) #include "dynamic-link.h" /* Perform the specified relocation. */ diff --git a/elf/dl-symbol.c b/elf/dl-symbol.c index 7977e69ab6..04dd122ef1 100644 --- a/elf/dl-symbol.c +++ b/elf/dl-symbol.c @@ -28,6 +28,6 @@ _dl_symbol_value (struct link_map *map, const char *name) ElfW(Addr) loadbase; const ElfW(Sym) *ref = NULL; struct link_map *scope[2] = { map, NULL }; - loadbase = _dl_lookup_symbol (name, &ref, scope, map->l_name, 0, 0); + loadbase = _dl_lookup_symbol (name, &ref, scope, map->l_name, 0); return loadbase + ref->st_value; } diff --git a/elf/dlsym.c b/elf/dlsym.c index 256eba800e..98e36290c2 100644 --- a/elf/dlsym.c +++ b/elf/dlsym.c @@ -44,7 +44,7 @@ dlsym (void *handle, const char *name) scope = &(_dl_global_scope ?: _dl_default_scope)[2]; owner = NULL; } - loadbase = _dl_lookup_symbol (name, &ref, scope, owner, 0, 0); + loadbase = _dl_lookup_symbol (name, &ref, scope, owner, 0); } return _dlerror_run (doit) ? NULL : (void *) (loadbase + ref->st_value); diff --git a/elf/link.h b/elf/link.h index fa96613478..a9637000e5 100644 --- a/elf/link.h +++ b/elf/link.h @@ -224,16 +224,18 @@ extern void _dl_close (struct link_map *map); null-terminated list of object scopes to search; each object's l_searchlist (i.e. the segment of the dependency tree starting at that object) is searched in turn. REFERENCE_NAME should name the object - containing the reference; it is used in error messages. RELOC_ADDR is - the address being fixed up and the chosen symbol cannot be one with this - value. If NOPLT is nonzero, then the reference must not be resolved to - a PLT entry. */ + containing the reference; it is used in error messages. FLAGS is a + set of flags: */ +#define DL_LOOKUP_NOEXEC 1 /* Don't search the executable for a + definition; this is used for copy + relocs. */ +#define DL_LOOKUP_NOPLT 2 /* The reference must not be resolved + to a PLT entry. */ extern ElfW(Addr) _dl_lookup_symbol (const char *undef, const ElfW(Sym) **sym, struct link_map *symbol_scope[], const char *reference_name, - ElfW(Addr) reloc_addr, - int noplt); + int flags); /* Look up symbol NAME in MAP's scope and return its run-time address. */ extern ElfW(Addr) _dl_symbol_value (struct link_map *map, const char *name); diff --git a/elf/rtld.c b/elf/rtld.c index fe5d269de2..308c2f4d6d 100644 --- a/elf/rtld.c +++ b/elf/rtld.c @@ -62,7 +62,7 @@ _dl_start (void *arg) /* This #define produces dynamic linking inline functions for bootstrap relocation instead of general-purpose relocation. */ #define RTLD_BOOTSTRAP -#define RESOLVE(sym, reloc_addr, noplt) bootstrap_map.l_addr +#define RESOLVE(sym, flags) bootstrap_map.l_addr #include "dynamic-link.h" /* Figure out the run-time load address of the dynamic linker itself. */ @@ -369,7 +369,7 @@ of this helper program; chances are you did not intend to run this program.\n", const ElfW(Sym) *ref = NULL; ElfW(Addr) loadbase = _dl_lookup_symbol (_dl_argv[i], &ref, &_dl_default_scope[2], - "argument", 0, 0); + "argument", 0); char buf[20], *bp; buf[sizeof buf - 1] = '\0'; bp = _itoa (ref->st_value, &buf[sizeof buf - 1], 16, 0); diff --git a/manual/examples/strdupa.c b/manual/examples/strdupa.c new file mode 100644 index 0000000000..7d6ef39947 --- /dev/null +++ b/manual/examples/strdupa.c @@ -0,0 +1,19 @@ +#include <paths.h> +#include <string.h> +#include <stdio.h> + +const char path[] = _PATH_STDPATH; + +int +main (void) +{ + char *wr_path = strdupa (path); + char *cp = strtok (wr_path, ":"); + + while (cp != NULL) + { + puts (cp); + cp = strtok (NULL, ":"); + } + return 0; +} diff --git a/manual/libc.texinfo b/manual/libc.texinfo index 7a8c1c3327..8622e04fcb 100644 --- a/manual/libc.texinfo +++ b/manual/libc.texinfo @@ -137,6 +137,7 @@ of the GNU C Library. * Process Startup:: Writing the beginning and end of your program. * Processes:: How to create processes and run other programs. * Job Control:: All about process groups and sessions. +* Name Service Switch:: Accessing the various system databases. * Users and Groups:: How users are identified and classified. * System Information:: Getting information about the hardware and software configuration @@ -806,6 +807,13 @@ Functions for Job Control * Process Group Functions:: Functions for manipulating process groups. * Terminal Access Functions:: Functions for controlling terminal access. +Name Service Switch + +* NSS Basics:: What is this NSS good for. +* NSS Configuration File:: Configuring NSS. +* NSS Module Internals:: How does it work internally. +* Extending NSS:: What to do to add services or databases. + Users and Groups * User and Group IDs:: Each user and group has a unique numeric ID. @@ -961,6 +969,7 @@ Porting the GNU C Library @include startup.texi @include process.texi @include job.texi +@include nss.texi @include users.texi @include sysinfo.texi @include conf.texi diff --git a/manual/nss.texi b/manual/nss.texi new file mode 100644 index 0000000000..cd1f4af0ec --- /dev/null +++ b/manual/nss.texi @@ -0,0 +1,586 @@ +@c each section should have index entries corresponding to the section title + +@node Name Service Switch +@chapter System Databases and Name Service Switch + +Various functions in the C Library need to be configured to work +correctly in the local environment. Traditionally, this was done by +using files (e.g., @file{/etc/passwd}), but other nameservices (line the +Network Information Service (NIS) and the Domain Name Service (DNS)) +became popular, and were hacked into the C library, usually with a fixed +search order @pxref{frobnicate, frobnicate, ,jargon}. + +The GNU C Library contains a cleaner solution of this problem. It is +designed after a method used by Sun Microsystems in the C library of +@w{Solaris 2}. GNU C Library follows their name and calls this +scheme @dfn{Name Service Switch} (NSS). + +Though the interface might be similar to Sun's version there is no +common code. We never saw any source code of Sun's implementation and +so the internal interface are incompatible. This is also manifest in the +file names we use as we will see later. + + +@menu +* NSS Basics:: What is this NSS good for. +* NSS Configuration File:: Configuring NSS. +* NSS Module Internals:: How does it work internally. +* Extending NSS:: What to do to add services or databases. +@end menu + +@node NSS Basics, NSS Configuration File, Name Service Switch, Name Service Switch +@section NSS Basics + +The basic idea is to put the implementation of the different services +offered to access the databases in separate modules. This has some +advantages: + +@enumerate +@item +Contributors can add new services without adding them to GNU C Library. +@item +The modules can be updated separately. +@item +The C library image is smaller. +@end enumerate + +To fulfill the first goal above the ABI of the modules will be described +below. For getting the implementation of a new service right it is +important to understand how the functions in the modules get called. +They are in no way designed to be used by the programmer directly. +Instead the programmer should only use the documented and standardized +functions to access the databases. + +@noindent +The databases available in the NSS are + +@cindex ethers +@cindex group +@cindex hosts +@cindex network +@cindex protocols +@cindex passwd +@cindex rpc +@cindex services +@cindex shadow +@vtable @code +@item ethers +Ethernet numbers, +@comment @pxref{Ethernet Numbers}. +@item group +Groups of users, @pxref{Group Database}. +@item hosts +Host names and numbers, @pxref{Host Names}. +@item network +Network names and numbers, @pxref{Networks Database}. +@item protocols +Network protocols, @pxref{Protocols Database}. +@item passwd +User passwords, @pxref{User Database}. +@item rpc +Remote procedure call names and numbers, +@comment @pxref{RPC Database}. +@item services +Network services, @pxref{Services Database}. +@item shadow +Shadow user passwords, +@comment @pxref{Shadow Password Database}. +@end vtable + +@noindent +There will be some more added later (@code{aliases}, @code{automount}, +@code{bootparams}, @code{netgroup}, @code{netmasks}, and +@code{publickey}). |
