Last minute change.

Mon Aug 12 04:33:09 1996  Ulrich Drepper  <drepper@cygnus.com>

	* nss/nsswitch.c (__nss_database_lookup): Always release locks
 	before returning.  Reported by Miles Bader.

	(distributes): Add databases.def.
This commit is contained in:
Ulrich Drepper 1996-08-12 02:44:03 +00:00
parent a3e59be8d1
commit a8874eadae
16 changed files with 272 additions and 80 deletions

View file

@ -1,3 +1,8 @@
Mon Aug 12 04:33:09 1996 Ulrich Drepper <drepper@cygnus.com>
* nss/nsswitch.c (__nss_database_lookup): Always release locks
before returning. Reported by Miles Bader.
Mon Aug 12 03:31:58 1996 Ulrich Drepper <drepper@cygnus.com>
* nss/nsswitch.c (__nss_configure_lookup): New function.
@ -11,7 +16,7 @@ Mon Aug 12 03:31:58 1996 Ulrich Drepper <drepper@cygnus.com>
* nss.h: New file. Wrapper around nss/nss.h.
* nss/Makefile (headers): Add nss.h.
(distributes): Add databases.h.
(distributes): Add databases.def.
Sun Aug 11 16:19:42 1996 Ulrich Drepper <drepper@cygnus.com>
@ -27,9 +32,6 @@ Sun Aug 11 16:19:42 1996 Ulrich Drepper <drepper@cygnus.com>
* string/Makefile: Add -fno-builtin for tst-strlen.c, too.
* elf/dl-lookup.c (_dl_lookup_symbol): Allow self-referencing.
Patch by David Mosberger-Tang.
Sun Aug 11 01:12:38 1996 Richard Henderson <rth@tamu.edu>
* sysdeps/alpha/dl-machine.h (elf_alpha_fix_plt): Optimize LD_BIND_NOW

View file

@ -455,8 +455,8 @@ object-suffixes-left := $(object-suffixes)
include $(o-iterator)
define do-ar
$(patsubst %,cd %;,$(objdir)) \
$(AR) cru$(verbose) ${O%-lib} \
$(patsubst $(objpfx)%,%,$^)
$(AUTOLOCK) ${O%-lib}.lck $(AR) cru$(verbose) ${O%-lib} \
$(patsubst $(objpfx)%,%,$^)
rm -f $@
touch $@
endef

45
autolock.sh Executable file
View file

@ -0,0 +1,45 @@
#! /bin/sh
# interlock - wrap program invocation in lock to allow
# parallel builds to work.
# Written by Tom Tromey <tromey@cygnus.com>, Aug 10 1996
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2, or (at your option)
# any later version.
#
# This program 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 General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
# Usage:
# interlock lock-dir-name program args-to-program...
dirname="$1"
program="$2"
shift
shift
while (mkdir $dirname > /dev/null 2>&1 && exit 1 || exit 0); do
# Wait a bit.
sleep 1
done
# Race condition here: if interrupted after the loop but before this
# trap, the lock can be left around.
trap "rmdir $dirname > /dev/null 2>&1" 1 2 3 15
# We have the lock, so run the program.
$program ${1+"$@"}
ret=$?
# Release the lock.
rmdir $dirname > /dev/null 2>&1
exit $ret

View file

@ -34,6 +34,7 @@ CC = @CC@
BUILD_CC = @BUILD_CC@
CFLAGS = @CFLAGS@
AR = @AR@
AUTOLOCK = @AUTOLOCK@
RANLIB = @RANLIB@
AS = $(CC) -c

View file

@ -308,6 +308,8 @@ 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>

1
nss.h Normal file
View file

@ -0,0 +1 @@
#include <nss/nss.h>

View file

@ -21,13 +21,16 @@
#
subdir := nss
headers := nss.h
distribute := nsswitch.h XXX-lookup.c getXXbyYY.c getXXbyYY_r.c \
getXXent.c getXXent_r.c
getXXent.c getXXent_r.c databases.def
# This is the trivial part which goes into libc itself.
routines = nsswitch $(addsuffix -lookup,$(databases))
# These are the databases that go through nss dispatch.
# Caution: if you add a database here, you must add its real name
# in databases.def, too.
databases = proto service hosts network grp pwd rpc ethers \
spwd

View file

@ -35,25 +35,26 @@ Boston, MA 02111-1307, USA. */
#define CONCAT3_1(Pre, Name, Post) CONCAT3_2 (Pre, Name, Post)
#define CONCAT3_2(Pre, Name, Post) Pre##Name##Post
#define DATABASE_NAME_SYMBOL CONCAT3_1 (__nss_, DATABASE_NAME, _database)
#define DATABASE_NAME_STRING STRINGIFY1 (DATABASE_NAME)
#define STRINGIFY1(Name) STRINGIFY2 (Name)
#define STRINGIFY2(Name) #Name
#ifndef DEFAULT_CONFIG
#define DEFAULT_CONFIG 0
#define DEFAULT_CONFIG NULL
#endif
static service_user *database = NULL;
service_user *DATABASE_NAME_SYMBOL = NULL;
int
DB_LOOKUP_FCT (service_user **ni, const char *fct_name, void **fctp)
{
if (database == NULL
if (DATABASE_NAME_SYMBOL == NULL
&& __nss_database_lookup (DATABASE_NAME_STRING, DEFAULT_CONFIG,
&database) < 0)
&DATABASE_NAME_SYMBOL) < 0)
return -1;
*ni = database;
*ni = DATABASE_NAME_SYMBOL;
return __nss_lookup (ni, fct_name, fctp);
}

31
nss/databases.def Normal file
View file

@ -0,0 +1,31 @@
/* List of all databases defined for the NSS in GNU C Library.
Copyright (C) 1996 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Ulrich Drepper <drepper@cygnus.com>, 1996.
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. */
/* This list must be kept sorted!!! */
DEFINE_DATABASE (ethers)
DEFINE_DATABASE (group)
DEFINE_DATABASE (hosts)
DEFINE_DATABASE (networks)
DEFINE_DATABASE (passwd)
DEFINE_DATABASE (protocols)
DEFINE_DATABASE (rpc)
DEFINE_DATABASE (services)
DEFINE_DATABASE (shadow)

54
nss/nss.h Normal file
View file

@ -0,0 +1,54 @@
/* Copyright (C) 1996 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
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. */
/* Define interface to NSS. This is meant for the interface functions
and for implementors of new services. */
#ifndef _NSS_H
#define _NSS_H 1
#include <features.h>
/* Revision number of NSS interface (must be a string). */
#define NSS_SHLIB_REVISION ".1"
__BEGIN_DECLS
/* Possible results of lookup using a nss_* function. */
enum nss_status
{
NSS_STATUS_TRYAGAIN = -2,
NSS_STATUS_UNAVAIL,
NSS_STATUS_NOTFOUND,
NSS_STATUS_SUCCESS,
};
/* Overwrite service selection for database DBNAME using specification
in STRING.
This function should only be used by system programs which have to
work around non-existing services (e.e., while booting).
Attention: Using this function repeatedly will slowly eat up the
whole memory since previous selection data cannot be freed. */
extern int __nss_configure_lookup __P ((__const char *__dbname,
__const char *__string));
__END_DECLS
#endif /* nss.h */

View file

@ -19,6 +19,7 @@ Boston, MA 02111-1307, USA. */
#include <ctype.h>
#include <dlfcn.h>
#include <errno.h>
#include <netdb.h>
#include <libc-lock.h>
#include <search.h>
@ -30,7 +31,6 @@ Boston, MA 02111-1307, USA. */
#include "../elf/link.h" /* We need some help from ld.so. */
/* Prototypes for the local functions. */
static void nss_init (void);
static void *nss_lookup_function (service_user *ni, const char *fct_name);
static name_database *nss_parse_file (const char *fname);
static name_database_entry *nss_getline (char *line);
@ -39,6 +39,27 @@ static service_library *nss_new_service (name_database *database,
const char *name);
/* Declare external database variables. */
#define DEFINE_DATABASE(name) \
extern service_user *__nss_##name##_database; \
weak_extern (__nss_##name##_database)
#include "databases.def"
#undef DEFINE_DATABASE
/* Structure to map database name to variable. */
static struct
{
const char *name;
service_user **dbp;
} databases[] =
{
#define DEFINE_DATABASE(name) \
{ #name, &__nss_##name##_database },
#include "databases.def"
#undef DEFINE_DATABASE
};
__libc_lock_define_initialized (static, lock)
@ -50,35 +71,29 @@ static int nss_initialized;
static name_database *service_table;
static void
nss_init (void)
{
/* Prevent multiple threads to change the service table. */
__libc_lock_lock (lock);
if (service_table == NULL)
service_table = nss_parse_file (_PATH_NSSWITCH_CONF);
__libc_lock_unlock (lock);
}
/* -1 == database not found
0 == database entry pointer stored */
int
__nss_database_lookup (const char *database, const char *defconfig,
service_user **ni)
{
name_database_entry *entry;
/* Prevent multiple threads to change the service table. */
__libc_lock_lock (lock);
if (nss_initialized == 0)
nss_init ();
/* Reconsider database variable in case some other thread called
`__nss_configure_lookup' while we waited for the lock. */
if (*ni != NULL)
return 0;
if (nss_initialized == 0 && service_table == NULL)
/* Read config file. */
service_table = nss_parse_file (_PATH_NSSWITCH_CONF);
/* Test whether configuration data is available. */
if (service_table)
if (service_table != NULL)
{
/* Return first `service_user' entry for DATABASE.
XXX Will use perfect hashing function for known databases. */
/* Return first `service_user' entry for DATABASE. */
name_database_entry *entry;
/* XXX Could use some faster mechanism here. But each database is
only requested once and so this might not be critical. */
@ -91,17 +106,14 @@ __nss_database_lookup (const char *database, const char *defconfig,
}
/* No configuration data is available, either because nsswitch.conf
doesn't exist or because it doesn't have a line for this database. */
entry = malloc (sizeof *entry);
if (entry == NULL)
return -1;
entry->name = database;
/* DEFCONFIG specifies the default service list for this database,
or null to use the most common default. */
entry->service = nss_parse_service_list (defconfig ?:
"compat [NOTFOUND=return] files");
doesn't exist or because it doesn't has a line for this database.
DEFCONFIG specifies the default service list for this database,
or null to use the most common default. */
*ni = nss_parse_service_list (defconfig ?: "compat [NOTFOUND=return] files");
__libc_lock_unlock (lock);
*ni = entry->service;
return 0;
}
@ -168,6 +180,48 @@ __nss_next (service_user **ni, const char *fct_name, void **fctp, int status,
}
int
__nss_configure_lookup (const char *dbname, const char *service_line)
{
service_user *new_db;
size_t cnt;
for (cnt = 0; cnt < sizeof databases; ++cnt)
if (strcmp (dbname, databases[cnt].name) == 0)
break;
if (cnt == sizeof databases)
{
errno = EINVAL;
return -1;
}
/* Test whether it is really used. */
if (databases[cnt].dbp == NULL)
/* Nothing to do, but we could do. */
return 0;
/* Try to generate new data. */
new_db = nss_parse_service_list (service_line);
if (new_db == NULL)
{
/* Illegal service specification. */
errno = EINVAL;
return -1;
}
/* Prevent multiple threads to change the service table. */
__libc_lock_lock (lock);
/* Install new rules. */
*databases[cnt].dbp = new_db;
__libc_lock_unlock (lock);
return 0;
}
static int
nss_dlerror_run (void (*operate) (void))
{
@ -385,7 +439,9 @@ nss_parse_file (const char *fname)
}
/* Read the source names: `<source> ( "[" <status> "=" <action> "]" )*'. */
/* Read the source names:
`( <source> ( "[" "!"? (<status> "=" <action> )+ "]" )? )*'
*/
static service_user *
nss_parse_service_list (const char *line)
{

View file

@ -23,24 +23,11 @@ Boston, MA 02111-1307, USA. */
#include <arpa/nameser.h>
#include <netinet/in.h>
#include <nss.h>
#include <resolv.h>
#include <search.h>
/* Revision number of NSS interface (must be a string). */
#define NSS_SHLIB_REVISION ".1"
/* Possible results of lookup using a nss_* function. */
enum nss_status
{
NSS_STATUS_TRYAGAIN = -2,
NSS_STATUS_UNAVAIL,
NSS_STATUS_NOTFOUND,
NSS_STATUS_SUCCESS,
};
/* Actions performed after lookup finished. */
typedef enum
{

View file

@ -45,3 +45,5 @@ distribute := memcopy.h pagecopy.h
include ../Rules
tester-ENV = LANGUAGE=C
CFLAGS-tester.c = -fno-builtin
CFLAGS-tst-strlen.c = -fno-builtin

View file

@ -29,8 +29,8 @@ division. The C compiler expects the functions
These are not normal C functions: instead of the normal calling
sequence, these expect their arguments in registers t10 and t11, and
return the result in t12 (aka pv). Registers AT and v0 may be
clobbered (assembly temporary), anything else must be saved. */
return the result in t12 (aka pv). Register AT may be clobbered
(assembly temporary), anything else must be saved. */
#include <sysdep.h>

View file

@ -135,8 +135,8 @@ _dl_runtime_resolve:
stq $29, 160($sp)
.mask 0x27ff01ff, -168
/* Set up our $gp */
br $gp, .+4
ldgp $gp, 0($gp)
br $gp, 0f
0: ldgp $gp, 0($gp)
.prologue 1
/* Set up the arguments for _dl_runtime_resolve. */
/* $16 = link_map out of plt0 */
@ -145,7 +145,7 @@ _dl_runtime_resolve:
mov $28, $17
/* Do the fixup */
bsr $26, fixup..ng
/* Move the destination address to a safe place. */
/* Move the destination address into position. */
mov $0, $27
/* Restore program registers. */
ldq $26, 0($sp)
@ -169,19 +169,16 @@ _dl_runtime_resolve:
ldq $24, 144($sp)
ldq $25, 152($sp)
ldq $29, 160($sp)
/* Flush the Icache after having modified the .plt code. */
imb
/* Clean up and turn control to the destination */
lda $sp, 168($sp)
jmp $31, ($27)
.end _dl_runtime_resolve");
/* The PLT uses Elf_Rel relocs. */
/* The PLT uses Elf64_Rela relocs. */
#define elf_machine_relplt elf_machine_rela
/* Mask identifying addresses reserved for the user program,
where the dynamic linker should not map anything. */
/* FIXME */
#define ELF_MACHINE_USER_ADDRESS_MASK (~0x1FFFFFFFFUL)
/* Initial entry point code for the dynamic linker.
The C function `_dl_start' is the real entry point;
its return value is the user program's entry point. */
@ -191,8 +188,8 @@ _dl_runtime_resolve:
.globl _start
.globl _dl_start_user
_start:
br $gp,.+4
ldgp $gp, 0($gp)
br $gp,0f
0: ldgp $gp, 0($gp)
/* Pass pointer to argument block to _dl_start. */
mov $sp, $16
bsr $26, _dl_start..ng
@ -226,7 +223,7 @@ _dl_start_user:
mov $9, $27
jmp ($9)");
/* Nonzero iff TYPE describes relocation of a PLT entry, so
/* Nonzero iff TYPE describes relocation of a PLT entry, so
PLT entries should not be allowed to define the value. */
#define elf_machine_pltrel_p(type) ((type) == R_ALPHA_JMP_SLOT)
@ -302,9 +299,10 @@ elf_alpha_fix_plt(struct link_map *l,
plte[2] = 0x6bfb0000;
}
/* Flush the instruction cache now that we've diddled. Tag it as
modifying memory to checkpoint memory writes during optimization. */
asm volatile("call_pal 0x86" : : : "memory");
/* At this point, if we've been doing runtime resolution, Icache is dirty.
This will be taken care of in _dl_runtime_resolve. If instead we are
doing this as part of non-lazy startup relocation, that bit of code
hasn't made it into Icache yet, so there's nothing to clean up. */
}
/* Perform the relocation specified by RELOC and SYM (which is fully resolved).

View file

@ -22,6 +22,11 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
extern void *__curbrk;
extern int __brk (void *addr);
#ifdef PIC
extern int __libc_is_static;
weak_extern (__libc_is_static)
#endif
/* Extend the process's data space by INCREMENT.
If INCREMENT is negative, shrink data space by - INCREMENT.
Return start of new space allocated, or -1 for errors. */
@ -30,12 +35,16 @@ __sbrk (ptrdiff_t increment)
{
void *oldbrk;
/* Always update __curbrk from the kernel's brk value. That way two
separate instances of __brk and __sbrk can share the heap, returning
interleaved pieces of it. This happens when libc.so is loaded by
dlopen in a statically-linked program that already uses __brk. */
if (__brk (0) < 0)
return (void *) -1;
/* If this is not part of the dynamic library or the library is used
via dynamic loading in a statically linked program update
__curbrk from the kernel's brk value. That way two separate
instances of __brk and __sbrk can share the heap, returning
interleaved pieces of it. */
#ifdef PIC
if (__curbrk == NULL || &__libc_is_static == NULL)
#endif
if (__brk (0) < 0)
return (void *) -1;
if (increment == 0)
return __curbrk;