aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--MakeTAGS13
-rw-r--r--Makerules9
-rw-r--r--config.make.in1
-rw-r--r--configure.in2
-rw-r--r--elf/dl-load.c42
-rw-r--r--elf/dl-lookup.c19
-rw-r--r--elf/dl-reloc.c4
-rw-r--r--elf/dl-runtime.c4
-rw-r--r--elf/dl-symbol.c2
-rw-r--r--elf/dlsym.c2
-rw-r--r--elf/link.h14
-rw-r--r--elf/rtld.c4
-rw-r--r--manual/examples/strdupa.c19
-rw-r--r--manual/libc.texinfo9
-rw-r--r--manual/nss.texi586
-rw-r--r--manual/nsswitch.texi16
-rw-r--r--manual/string.texi77
-rw-r--r--manual/users.texi18
-rw-r--r--nss/nsswitch.c2
-rw-r--r--po/SYS_libc.pot1378
-rw-r--r--po/header.pot1
-rw-r--r--shadow/sgetspent_r.c2
-rw-r--r--stdlib/strtod.c2
-rw-r--r--string/strdup.c4
-rw-r--r--sysdeps/alpha/dl-machine.h4
-rw-r--r--sysdeps/i386/dl-machine.h10
-rw-r--r--sysdeps/m68k/dl-machine.h18
-rw-r--r--sysdeps/mips/dl-machine.h2
-rw-r--r--sysdeps/unix/sysv/linux/i386/clone.S1
-rw-r--r--sysdeps/unix/sysv/linux/m68k/clone.S75
30 files changed, 2080 insertions, 260 deletions
diff --git a/MakeTAGS b/MakeTAGS
index 10b837c9cb..0416493489 100644
--- a/MakeTAGS
+++ b/MakeTAGS
@@ -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' $@
diff --git a/Makerules b/Makerules
index 14f5b5b54b..f82408146a 100644
--- a/Makerules
+++ b/Makerules
@@ -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}).