summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRoland McGrath <roland@gnu.org>1996-07-14 06:04:09 +0000
committerRoland McGrath <roland@gnu.org>1996-07-14 06:04:09 +0000
commit2064087b5f1a0a3a189fcd6a3012376f5545be31 (patch)
tree6f02a4e4364004352f2d785146b5dc12444e83b9
parent842907c6f8e6022f443175072e65bc516eb0973b (diff)
Sun Jul 14 01:51:39 1996 Roland McGrath <roland@delasyd.gnu.ai.mit.edu>cvs/libc-960714
* manual/Makefile (glibc-targets): Variable and targets removed. Sat Jul 13 23:50:17 1996 Roland McGrath <roland@delasyd.gnu.ai.mit.edu> * manual/Makefile (lib): New phony target. Depend on stamp files. ($(objpfx)stamp%-$(subdir)): New rule to create them when necessary. 1996-07-13 Paul Eggert <eggert@twinsun.com> * time/strftime.c (strftime): Use space padding for %e, %k, %l, to match Emacs format-time-string specification. (DO_NUMBER_SPACEPAD): Renamed from DO_NUMBER_NOPAD. Sat Jul 13 20:17:38 1996 Roland McGrath <roland@delasyd.gnu.ai.mit.edu> * elf/dl-deps.c (_dl_map_object_deps): Take new args PRELOADS and NPRELOADS, vector of `struct link_map *'s; add them to the searchlist between MAP and its deps. * elf/link.h: Fix decl. * elf/rtld.c (dl_main): If not secure, parse LD_PRELOAD for colon-separated list of names, map those and pass vector of ptrs as PRELOADS list to _dl_map_object_deps. * elf/dl-runtime.c (_dl_object_relocation_scope): Pass new args to _dl_map_object_deps with empty preload list. * elf/dl-open.c (_dl_open): Likewise. * sysdeps/mach/hurd/dl-sysdep.c (_dl_sysdep_open_zero_fill): Function removed. (__mmap): Pass MACH_PORT_NULL for memobj port when (flags & MAP_ANON). * sysdeps/generic/dl-sysdep.c (_dl_sysdep_open_zero_fill): Conditionalize defn on [! MAP_ANON]. * elf/dl-minimal.c (malloc): Conditionalize use of _dl_zerofd on [! MAP_ANON]. * elf/rtld.c (dl_main): Likewise. * elf/dl-load.c (_dl_zerofd): Conditionalize defn on [! MAP_ANON]. (_dl_map_object_from_fd): Conditionalize initialization of _dl_zerofd. * elf/dl-fini.c (_dl_fini): Skip finalizer for executable itself. Sat Jul 13 02:47:53 1996 David Mosberger-Tang <davidm@azstarnet.com> * stdlib/random.c (__random): Declare as int32_t to be in sync with declaration. * socket/Makefile (headers): Add socketbits.h. * misc/mntent.c (endmntent): Allow for NULL stream. SunOS does it that way. * grp/initgroups.c (initgroups): Add groups that user is a member of, not the ones he is _not_ a member of. * nss/nsswitch.c (known_compare): Make known_compare() a static instead of a local function. The latter are difficult to debug and slow to execute on certain platforms. * sysdeps/posix/ttyname_r.c (ttyname_r): Use sizeof (dev) - 1 in place of sizeof (dev). The size of a literal string includes the NUL byte. * sysdeps/unix/getlogin.c (getlogin): Initialize ut_fd with -1. Thu Jul 11 16:59:10 1996 David Mosberger-Tang <davidm@azstarnet.com> * misc/mntent.c (addmntent): Seek to end of file before writing entry. Return 1 on error, not -1. Tue Jul 9 19:08:05 1996 David Mosberger-Tang <davidm@azstarnet.com> * sysdeps/unix/sysv/linux/syscalls.list: Mark bdflush as EXTRA syscall. Fri Jul 5 18:44:55 1996 David Mosberger-Tang <davidm@azstarnet.com> * sysdeps/unix/sysv/linux/alpha/ioperm.c (port_to_cpu_addr): Size shift amount for Jensen must be 5 not 4. Sat Jul 13 20:04:28 1996 Roland McGrath <roland@delasyd.gnu.ai.mit.edu> * socket/sys/socket.h (struct osockaddr): New type. Sat Jul 13 03:50:53 1996 Ulrich Drepper <drepper@cygnus.com> * misc/Makefile (routines): Add qefgcvt and qefgcvt_r. * misc/efgcvt.c, misc/efgcvt_r.c: Change code so that the `double' and `long double' versions can be generated. * misc/qefgcvt.c, misc/qefgcvt_r.c: New files. Define macros so that included efgcvt{,_r}.c file generate `long double' versions. * stdlib/stdlib.h: Add prototypes for q[efg]cvt() and q[ef]cvt_r() functions. * manual/startup.texi: Document new getsubopt function. * manual/examples/subopt.c: New example program for documenting getsubopt function. Fri Jul 12 23:58:37 1996 Ulrich Drepper <drepper@cygnus.com> * stdlib/Makefile (routines): Add getsubopt. * stdlib/stdlib.h: Add prototype for getsubopt. * stdlib/getsubopt.c: New file. Implement getsubopt function to handle suboption parsing.
-rw-r--r--ChangeLog111
-rw-r--r--elf/dl-deps.c23
-rw-r--r--elf/dl-fini.c6
-rw-r--r--elf/dl-load.c12
-rw-r--r--elf/dl-minimal.c11
-rw-r--r--elf/dl-open.c2
-rw-r--r--elf/dl-runtime.c2
-rw-r--r--elf/link.h10
-rw-r--r--elf/rtld.c47
-rw-r--r--grp/initgroups.c39
-rw-r--r--manual/Makefile23
-rw-r--r--manual/examples/subopt.c75
-rw-r--r--manual/startup.texi68
-rw-r--r--misc/Makefile2
-rw-r--r--misc/efgcvt.c23
-rw-r--r--misc/efgcvt_r.c38
-rw-r--r--misc/mntent.c11
-rw-r--r--misc/qefgcvt.c26
-rw-r--r--misc/qefgcvt_r.c26
-rw-r--r--nss/nsswitch.c15
-rw-r--r--socket/Makefile2
-rw-r--r--socket/sys/socket.h9
-rw-r--r--stdlib/Makefile2
-rw-r--r--stdlib/getsubopt.c77
-rw-r--r--stdlib/random.c2
-rw-r--r--stdlib/stdlib.h27
-rw-r--r--sys/socket.h1
-rw-r--r--sysdeps/generic/dl-sysdep.c4
-rw-r--r--sysdeps/mach/hurd/dl-sysdep.c12
-rw-r--r--sysdeps/posix/ttyname_r.c10
-rw-r--r--sysdeps/unix/getlogin.c4
-rw-r--r--sysdeps/unix/sysv/linux/alpha/ioperm.c17
-rw-r--r--sysdeps/unix/sysv/linux/syscalls.list2
-rw-r--r--time/strftime.c16
34 files changed, 621 insertions, 134 deletions
diff --git a/ChangeLog b/ChangeLog
index 294d9b0735..77e7e0b546 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,108 @@
+Sun Jul 14 01:51:39 1996 Roland McGrath <roland@delasyd.gnu.ai.mit.edu>
+
+ * manual/Makefile (glibc-targets): Variable and targets removed.
+
+Sat Jul 13 23:50:17 1996 Roland McGrath <roland@delasyd.gnu.ai.mit.edu>
+
+ * manual/Makefile (lib): New phony target. Depend on stamp files.
+ ($(objpfx)stamp%-$(subdir)): New rule to create them when necessary.
+
+1996-07-13 Paul Eggert <eggert@twinsun.com>
+
+ * time/strftime.c (strftime): Use space padding for %e, %k, %l,
+ to match Emacs format-time-string specification.
+ (DO_NUMBER_SPACEPAD): Renamed from DO_NUMBER_NOPAD.
+
+Sat Jul 13 20:17:38 1996 Roland McGrath <roland@delasyd.gnu.ai.mit.edu>
+
+ * elf/dl-deps.c (_dl_map_object_deps): Take new args PRELOADS and
+ NPRELOADS, vector of `struct link_map *'s; add them to the searchlist
+ between MAP and its deps.
+ * elf/link.h: Fix decl.
+ * elf/rtld.c (dl_main): If not secure, parse LD_PRELOAD for
+ colon-separated list of names, map those and pass vector of ptrs as
+ PRELOADS list to _dl_map_object_deps.
+ * elf/dl-runtime.c (_dl_object_relocation_scope): Pass new args to
+ _dl_map_object_deps with empty preload list.
+ * elf/dl-open.c (_dl_open): Likewise.
+
+ * sysdeps/mach/hurd/dl-sysdep.c (_dl_sysdep_open_zero_fill): Function
+ removed.
+ (__mmap): Pass MACH_PORT_NULL for memobj port when (flags & MAP_ANON).
+ * sysdeps/generic/dl-sysdep.c (_dl_sysdep_open_zero_fill):
+ Conditionalize defn on [! MAP_ANON].
+ * elf/dl-minimal.c (malloc): Conditionalize use of _dl_zerofd
+ on [! MAP_ANON].
+ * elf/rtld.c (dl_main): Likewise.
+ * elf/dl-load.c (_dl_zerofd): Conditionalize defn on [! MAP_ANON].
+ (_dl_map_object_from_fd): Conditionalize initialization of _dl_zerofd.
+
+ * elf/dl-fini.c (_dl_fini): Skip finalizer for executable itself.
+
+Sat Jul 13 02:47:53 1996 David Mosberger-Tang <davidm@azstarnet.com>
+
+ * stdlib/random.c (__random): Declare as int32_t to be in sync
+ with declaration.
+
+ * socket/Makefile (headers): Add socketbits.h.
+
+ * misc/mntent.c (endmntent): Allow for NULL stream. SunOS does
+ it that way.
+
+ * grp/initgroups.c (initgroups): Add groups that user is a member
+ of, not the ones he is _not_ a member of.
+
+ * nss/nsswitch.c (known_compare): Make known_compare() a static
+ instead of a local function. The latter are difficult to debug
+ and slow to execute on certain platforms.
+
+ * sysdeps/posix/ttyname_r.c (ttyname_r): Use sizeof (dev) - 1 in
+ place of sizeof (dev). The size of a literal string includes the
+ NUL byte.
+
+ * sysdeps/unix/getlogin.c (getlogin): Initialize ut_fd with -1.
+
+Thu Jul 11 16:59:10 1996 David Mosberger-Tang <davidm@azstarnet.com>
+
+ * misc/mntent.c (addmntent): Seek to end of file before writing
+ entry. Return 1 on error, not -1.
+
+Tue Jul 9 19:08:05 1996 David Mosberger-Tang <davidm@azstarnet.com>
+
+ * sysdeps/unix/sysv/linux/syscalls.list: Mark bdflush as EXTRA
+ syscall.
+
+Fri Jul 5 18:44:55 1996 David Mosberger-Tang <davidm@azstarnet.com>
+
+ * sysdeps/unix/sysv/linux/alpha/ioperm.c (port_to_cpu_addr): Size
+ shift amount for Jensen must be 5 not 4.
+
+Sat Jul 13 20:04:28 1996 Roland McGrath <roland@delasyd.gnu.ai.mit.edu>
+
+ * socket/sys/socket.h (struct osockaddr): New type.
+
+Sat Jul 13 03:50:53 1996 Ulrich Drepper <drepper@cygnus.com>
+
+ * misc/Makefile (routines): Add qefgcvt and qefgcvt_r.
+ * misc/efgcvt.c, misc/efgcvt_r.c: Change code so that the `double'
+ and `long double' versions can be generated.
+ * misc/qefgcvt.c, misc/qefgcvt_r.c: New files. Define macros
+ so that included efgcvt{,_r}.c file generate `long double'
+ versions.
+ * stdlib/stdlib.h: Add prototypes for q[efg]cvt() and q[ef]cvt_r()
+ functions.
+
+ * manual/startup.texi: Document new getsubopt function.
+ * manual/examples/subopt.c: New example program for documenting
+ getsubopt function.
+
+Fri Jul 12 23:58:37 1996 Ulrich Drepper <drepper@cygnus.com>
+
+ * stdlib/Makefile (routines): Add getsubopt.
+ * stdlib/stdlib.h: Add prototype for getsubopt.
+ * stdlib/getsubopt.c: New file. Implement getsubopt function
+ to handle suboption parsing.
+
Thu Jul 11 20:09:55 1996 Roland McGrath <roland@delasyd.gnu.ai.mit.edu>
* inet/getnetent_r.c: Define NEED_H_ERRNO.
@@ -712,12 +817,6 @@ Fri Jun 28 02:41:08 1996 Roland McGrath <roland@delasyd.gnu.ai.mit.edu>
* string/string.h: Don't define memccpy as macro for [__OPTIMIZE__].
-Thu Jun 27 23:43:22 1996 Richard Henderson <rth@tamu.edu>
-
- * sysdeps/alpha/dl-machine.h (elf_machine_rela): The Alpha's
- address-of operation and plt format conspire to require all
- dynamic relocs to be resolved to actual symbols not plt entries.
-
Thu Jun 27 02:49:28 1996 Ulrich Drepper <drepper@cygnus.com>
* catgets/gencat.c: Add casts to avoid signed<->unsigned warnings.
diff --git a/elf/dl-deps.c b/elf/dl-deps.c
index 9fe974d982..28733ab60d 100644
--- a/elf/dl-deps.c
+++ b/elf/dl-deps.c
@@ -23,20 +23,29 @@ Cambridge, MA 02139, USA. */
#include <stdlib.h>
void
-_dl_map_object_deps (struct link_map *map)
+_dl_map_object_deps (struct link_map *map,
+ struct link_map **preloads, unsigned int npreloads)
{
struct list
{
struct link_map *map;
struct list *next;
};
- struct list head, *tailp, *scanp;
+ struct list head[1 + npreloads], *tailp, *scanp;
unsigned int nlist;
/* Start the search list with one element: MAP itself. */
- head.map = map;
- head.next = NULL;
- nlist = 1;
+ head[0].map = map;
+
+ /* Add the preloaded items after MAP but before any of its dependencies. */
+ for (nlist = 0; nlist < npreloads; ++nlist)
+ {
+ head[nlist].next = &head[nlist + 1];
+ head[nlist + 1].map = preloads[nlist];
+ }
+
+ /* Terminate the list. */
+ head[nlist++].next = NULL;
/* We use `l_reserved' as a mark bit to detect objects we have already
put in the search list and avoid adding duplicate elements later in
@@ -47,7 +56,7 @@ _dl_map_object_deps (struct link_map *map)
dependencies and appending them to the list as we step through it.
This produces a flat, ordered list that represents a breadth-first
search of the dependency tree. */
- for (scanp = tailp = &head; scanp; scanp = scanp->next)
+ for (scanp = tailp = head; scanp; scanp = scanp->next)
{
struct link_map *l = scanp->map;
@@ -91,7 +100,7 @@ _dl_map_object_deps (struct link_map *map)
map->l_nsearchlist = nlist;
nlist = 0;
- for (scanp = &head; scanp; scanp = scanp->next)
+ for (scanp = head; scanp; scanp = scanp->next)
{
map->l_searchlist[nlist++] = scanp->map;
diff --git a/elf/dl-fini.c b/elf/dl-fini.c
index 36b4390663..9f4233aca0 100644
--- a/elf/dl-fini.c
+++ b/elf/dl-fini.c
@@ -25,9 +25,11 @@ _dl_fini (void)
struct link_map *l;
for (l = _dl_loaded; l; l = l->l_next)
- if (l->l_init_called && l->l_info[DT_FINI])
+ if (l->l_init_called)
{
- (*(void (*) (void)) (l->l_addr + l->l_info[DT_FINI]->d_un.d_ptr)) ();
+ if (l->l_info[DT_FINI] &&
+ !(l->l_name[0] == '\0' && l->l_type == lt_executable))
+ (*(void (*) (void)) (l->l_addr + l->l_info[DT_FINI]->d_un.d_ptr)) ();
/* Make sure nothing happens if we are called twice. */
l->l_init_called = 0;
}
diff --git a/elf/dl-load.c b/elf/dl-load.c
index ff7f5cf487..29ac0bfd87 100644
--- a/elf/dl-load.c
+++ b/elf/dl-load.c
@@ -59,7 +59,14 @@ Cambridge, MA 02139, USA. */
#define STRING(x) #x
+#ifdef MAP_ANON
+/* The fd is not examined when using MAP_ANON. */
+#define ANONFD -1
+#else
int _dl_zerofd = -1;
+#define ANONFD _dl_zerofd
+#endif
+
size_t _dl_pagesize;
@@ -176,6 +183,8 @@ _dl_map_object_from_fd (const char *name, int fd, char *realname,
if (header->e_phentsize != sizeof (ElfW(Phdr)))
LOSE ("ELF file's phentsize not the expected size");
+#ifndef MAP_ANON
+#define MAP_ANON 0
if (_dl_zerofd == -1)
{
_dl_zerofd = _dl_sysdep_open_zero_fill ();
@@ -185,6 +194,7 @@ _dl_map_object_from_fd (const char *name, int fd, char *realname,
_dl_signal_error (errno, NULL, "cannot open zero fill device");
}
}
+#endif
/* Enter the new object in the list of loaded objects. */
l = _dl_new_object (realname, name, l_type);
@@ -329,7 +339,7 @@ _dl_map_object_from_fd (const char *name, int fd, char *realname,
caddr_t mapat;
mapat = __mmap ((caddr_t) zeropage, zeroend - zeropage,
c->prot, MAP_ANON|MAP_PRIVATE|MAP_FIXED,
- _dl_zerofd, 0);
+ ANONFD, 0);
if (mapat == (caddr_t) -1)
lose (errno, "cannot map zero-fill pages");
}
diff --git a/elf/dl-minimal.c b/elf/dl-minimal.c
index fd7bf05497..61615cd9a9 100644
--- a/elf/dl-minimal.c
+++ b/elf/dl-minimal.c
@@ -33,13 +33,18 @@ static void *alloc_ptr, *alloc_end, *alloc_last_block;
void * weak_function
malloc (size_t n)
{
+#ifdef MAP_ANON
+#define _dl_zerofd (-1)
+#else
extern int _dl_zerofd;
- if (_dl_pagesize == 0)
- _dl_pagesize = __getpagesize ();
-
if (_dl_zerofd == -1)
_dl_zerofd = _dl_sysdep_open_zero_fill ();
+#define MAP_ANON 0
+#endif
+
+ if (_dl_pagesize == 0)
+ _dl_pagesize = __getpagesize ();
if (alloc_end == 0)
{
diff --git a/elf/dl-open.c b/elf/dl-open.c
index c24920f933..058c3e5a39 100644
--- a/elf/dl-open.c
+++ b/elf/dl-open.c
@@ -39,7 +39,7 @@ _dl_open (const char *file, int mode)
return new;
/* Load that object's dependencies. */
- _dl_map_object_deps (new);
+ _dl_map_object_deps (new, NULL, 0);
/* Relocate the objects loaded. We do this in reverse order so that copy
diff --git a/elf/dl-runtime.c b/elf/dl-runtime.c
index 8ad2c0ffa4..cdacd756ef 100644
--- a/elf/dl-runtime.c
+++ b/elf/dl-runtime.c
@@ -41,7 +41,7 @@ _dl_object_relocation_scope (struct link_map *l)
if (! l->l_searchlist)
/* We must construct the searchlist for this object. */
- _dl_map_object_deps (l);
+ _dl_map_object_deps (l, NULL, 0);
/* The primary scope is this object itself and its
dependencies. */
diff --git a/elf/link.h b/elf/link.h
index 1e0104a4ea..fa96613478 100644
--- a/elf/link.h
+++ b/elf/link.h
@@ -196,9 +196,13 @@ extern int _dlerror_run (void (*operate) (void));
extern struct link_map *_dl_map_object (struct link_map *loader,
const char *name, int type);
-/* Call _dl_map_object on the dependencies of MAP, and
- set up MAP->l_searchlist. */
-extern void _dl_map_object_deps (struct link_map *map);
+/* Call _dl_map_object on the dependencies of MAP, and set up
+ MAP->l_searchlist. PRELOADS points to a vector of NPRELOADS previously
+ loaded objects that will be inserted into MAP->l_searchlist after MAP
+ but before its dependencies. */
+extern void _dl_map_object_deps (struct link_map *map,
+ struct link_map **preloads,
+ unsigned int npreloads);
/* Cache the locations of MAP's hash table. */
extern void _dl_setup_hash (struct link_map *map);
diff --git a/elf/rtld.c b/elf/rtld.c
index 6baa7a868a..2e23d9cb38 100644
--- a/elf/rtld.c
+++ b/elf/rtld.c
@@ -21,6 +21,7 @@ Cambridge, MA 02139, USA. */
#include <stddef.h>
#include <stdlib.h>
#include <unistd.h>
+#include <sys/mman.h> /* Check if MAP_ANON is defined. */
#include "../stdio-common/_itoa.h"
@@ -124,6 +125,8 @@ dl_main (const ElfW(Phdr) *phdr,
struct link_map *l;
int lazy;
int list_only = 0;
+ struct link_map **preloads;
+ unsigned int npreloads;
if (*user_entry == (ElfW(Addr)) &_start)
{
@@ -247,12 +250,52 @@ of this helper program; chances are you did not intend to run this program.\n",
l->l_next = &_dl_rtld_map;
_dl_rtld_map.l_prev = l;
- /* Load all the libraries specified by DT_NEEDED entries. */
- _dl_map_object_deps (l);
+ preloads = NULL;
+ npreloads = 0;
+ if (! _dl_secure)
+ {
+ const char *preloadlist = getenv ("LD_PRELOAD");
+ if (preloadlist)
+ {
+ /* The LD_PRELOAD environment variable gives a colon-separated
+ list of libraries that are loaded before the executable's
+ dependencies and prepended to the global scope list. */
+ char *list = strdupa (preloadlist);
+ char *p;
+ while ((p = strsep (&list, ":")) != NULL)
+ {
+ (void) _dl_map_object (NULL, p, lt_library);
+ ++npreloads;
+ }
+
+ if (npreloads != 0)
+ {
+ /* Set up PRELOADS with a vector of the preloaded libraries. */
+ struct link_map *l;
+ unsigned int i;
+ preloads = __alloca (npreloads * sizeof preloads[0]);
+ l = _dl_rtld_map.l_next; /* End of the chain before preloads. */
+ i = 0;
+ do
+ {
+ preloads[i++] = l;
+ l = l->l_next;
+ } while (l);
+ assert (i == npreloads);
+ }
+ }
+ }
+
+ /* Load all the libraries specified by DT_NEEDED entries. If LD_PRELOAD
+ specified some libraries to load, these are inserted before the actual
+ dependencies in the executable's searchlist for symbol resolution. */
+ _dl_map_object_deps (l, preloads, npreloads);
+#ifndef MAP_ANON
/* We are done mapping things, so close the zero-fill descriptor. */
__close (_dl_zerofd);
_dl_zerofd = -1;
+#endif
/* Remove _dl_rtld_map from the chain. */
_dl_rtld_map.l_prev->l_next = _dl_rtld_map.l_next;
diff --git a/grp/initgroups.c b/grp/initgroups.c
index 73c15c6479..35af575ac7 100644
--- a/grp/initgroups.c
+++ b/grp/initgroups.c
@@ -70,28 +70,27 @@ initgroups (user, group)
register char **m;
for (m = g->gr_mem; *m != NULL; ++m)
- if (!strcmp (*m, user))
- break;
-
- if (*m == NULL)
- {
- /* Matched the user. Insert this group. */
- if (n == ngroups && limit <= 0)
- {
- /* Need a bigger buffer. */
- groups = memcpy (__alloca (ngroups * 2 * sizeof *groups),
- groups, ngroups * sizeof *groups);
- ngroups *= 2;
- }
-
- groups[n++] = g->gr_gid;
-
- if (n == limit)
- /* Can't take any more groups; stop searching. */
+ if (strcmp (*m, user) == 0)
+ {
+ /* Matches user. Insert this group. */
+ if (n == ngroups && limit <= 0)
+ {
+ /* Need a bigger buffer. */
+ groups = memcpy (__alloca (ngroups * 2 * sizeof *groups),
+ groups, ngroups * sizeof *groups);
+ ngroups *= 2;
+ }
+
+ groups[n++] = g->gr_gid;
+
+ if (n == limit)
+ /* Can't take any more groups; stop searching. */
+ goto done;
+
break;
- }
+ }
}
-
+done:
endgrent ();
return setgroups (n, groups);
diff --git a/manual/Makefile b/manual/Makefile
index 7197ecf7a9..eb9fff71ee 100644
--- a/manual/Makefile
+++ b/manual/Makefile
@@ -105,11 +105,6 @@ glibc-doc-$(edition).tar: $(doc-only-dist) $(distribute)
uuencode $< < $< > $@.new
mv -f $@.new $@
-# The parent makefile sometimes invokes us with targets `subdir_REAL-TARGET'.
-subdir_%: % ;
-# For targets we don't define, do nothing.
-subdir_%: ;
-
.PHONY: mostlyclean distclean realclean clean
mostlyclean:
-rm -f libc.dvi libc.info*
@@ -151,20 +146,22 @@ endif
TAGS: $(minimal-dist)
$(ETAGS) -o $@ $^
-# These are targets that each glibc subdirectory is expected to understand.
-# ../Rules defines them for code subdirectories; for us, they are no-ops.
-glibc-targets := subdir_lib objects objs others tests subdir_lint.out \
- subdir_echo-headers subdir_echo-distinfo stubs
-.PHONY: $(glibc-targets)
-$(glibc-targets):
+# The parent makefile sometimes invokes us with targets `subdir_REAL-TARGET'.
+subdir_%: % ;
+# For targets we don't define, do nothing.
+subdir_%: ;
+# Create stamp files if they don't exist, so the parent makefile's rules for
+# updating the library archives are happy with us, and never think we have
+# changed the library.
+.PHONY: lib stubs
+lib: $(foreach o,$(object-suffixes),$(objpfx)stamp$o-$(subdir))
stubs: $(common-objpfx)stub-manual
-$(common-objpfx)stub-manual ../po/manual.pot:
+$(objpfx)stamp%-$(subdir) $(common-objpfx)stub-manual ../po/manual.pot:
cp /dev/null $@
# The top-level glibc Makefile expects subdir_install to update the stubs file.
subdir_install: stubs
-
# Get rid of these variables if they came from the parent.
routines =
diff --git a/manual/examples/subopt.c b/manual/examples/subopt.c
new file mode 100644
index 0000000000..4a89f6441e
--- /dev/null
+++ b/manual/examples/subopt.c
@@ -0,0 +1,75 @@
+#include <stdio.h>
+#include <stdlib.h>
+
+int do_all;
+const char *type;
+int read_size;
+int write_size;
+int read_only;
+
+enum
+{
+ RO_OPTION = 0,
+ RW_OPTION,
+ READ_SIZE_OPTION,
+ WRITE_SIZE_OPTION
+};
+
+const char *mount_opts[] =
+{
+ [RO_OPTION] = "ro",
+ [RW_OPTION] = "rw",
+ [READ_SIZE_OPTION] = "rsize",
+ [WRITE_SIZE_OPTION] = "wsize"
+};
+
+int
+main (int argc, char *argv[])
+{
+ char *subopts, *value;
+ int opt;
+
+ while ((opt = getopt (argc, argv, "at:o:")) != EOF)
+ switch (opt)
+ {
+ case 'a':
+ do_all = 1;
+ break;
+ case 't':
+ type = optarg;
+ break;
+ case 'o':
+ subopts = optarg;
+ while (*subopts != '\0')
+ switch (getsubopt (&subopts, mount_opts, &value))
+ {
+ case RO_OPTION:
+ read_only = 1;
+ break;
+ case RW_OPTION:
+ read_only = 0;
+ break;
+ case READ_SIZE_OPTION:
+ if (value == NULL)
+ abort ();
+ read_size = atoi (value);
+ break;
+ case WRITE_SIZE_OPTION:
+ if (value == NULL)
+ abort ();
+ write_size = atoi (value);
+ break;
+ default:
+ /* Unknown suboption. */
+ printf ("Unknown suboption `%s'\n", value);
+ break;
+ }
+ break;
+ default:
+ abort ();
+ }
+
+ /* Do the real work. */
+
+ return 0;
+}
diff --git a/manual/startup.texi b/manual/startup.texi
index 654a4e8376..1313d4c2a7 100644
--- a/manual/startup.texi
+++ b/manual/startup.texi
@@ -83,12 +83,14 @@ allow this three-argument form, so to be portable it is best to write
@code{main} to take two arguments, and use the value of @code{environ}.
@menu
-* Argument Syntax:: By convention, options start with a hyphen.
-* Parsing Options:: The @code{getopt} function.
-* Example of Getopt:: An example of parsing options with @code{getopt}.
-* Long Options:: GNU suggests utilities accept long-named options.
+* Argument Syntax:: By convention, options start with a hyphen.
+* Parsing Options:: The @code{getopt} function.
+* Example of Getopt:: An example of parsing options with @code{getopt}.
+* Long Options:: GNU suggests utilities accept long-named options.
Here is how to do that.
-* Long Option Example:: An example of using @code{getopt_long}.
+* Long Option Example:: An example of using @code{getopt_long}.
+* Suboptions:: Some programs need more detailed options.
+* Suboptions Example:: This shows how it could be done for @code{mount}.
@end menu
@node Argument Syntax
@@ -409,6 +411,58 @@ When @code{getopt_long} has no more options to handle, it returns
@include longopt.c.texi
@end smallexample
+@node Suboptions
+@subsection Parsing of Suboptions
+
+Having a single level of options is sometimes not enough. There might
+be too many options which have to be available or a set of options is
+closely related.
+
+For this case some programs use suboptions. One of the most prominent
+programs is certainly @code{mount}(8). The @code{-o} option take one
+argument which itself is a comma separated list of options. To ease the
+programming of code like this the function @code{getsubopt} is
+available.
+
+@comment stdlib.h
+@deftypefun int getsubopt (char **@var{optionp}, const char* const *@var{tokens}, char **@var{valuep})
+
+The @var{optionp} parameter must be a pointer to a variable containing
+the address of the string to process. When the function returns the
+reference is updated to point to the next suboption or to the
+terminating @samp{\0} character if there is no more suboption available.
+
+The @var{tokens} parameter references an array of strings containing the
+known suboptions. All strings must be @samp{\0} terminated and to mark
+the end a null pointer must be stored. When @code{getsubopt} finds a
+possible legal suboption it compares it with all strings available in
+the @var{tokens} array and returns the index in the string as the
+indicator.
+
+In case the suboption has an associated value introduced by a @samp{=}
+character, a pointer to the value is returned in @var{valuep}. The
+string is @samp{\0} terminated. If no argument is available
+@var{valuep} is set to the null pointer. By doing this the caller can
+check whether a necessary value is given or whether no unexpected value
+is present.
+
+In case the next suboption in the string is not mentioned in the
+@var{tokens} array the starting address of the suboption including a
+possible value is returned in @var{valuep} and the return value of the
+function is @samp{-1}.
+@end deftypefun
+
+@node Suboptions Example
+@subsection Parsing of Suboptions Example
+
+The code which might appear in the @code{mount}(8) program is a perfect
+example of the use of @code{getsubopt}:
+
+@smallexample
+@include subopt.c.texi
+@end smallexample
+
+
@node Environment Variables
@section Environment Variables
@@ -448,9 +502,9 @@ character, since this is assumed to terminate the string.
@menu
-* Environment Access:: How to get and set the values of
+* Environment Access:: How to get and set the values of
environment variables.
-* Standard Environment:: These environment variables have
+* Standard Environment:: These environment variables have
standard interpretations.
@end menu
diff --git a/misc/Makefile b/misc/Makefile
index 4ffad986ab..01e223836f 100644
--- a/misc/Makefile
+++ b/misc/Makefile
@@ -52,7 +52,7 @@ routines := brk sbrk sstk ioctl \
insremque getttyent getusershell getpass ttyslot \
syslog syscall daemon \
mmap munmap mprotect msync madvise \
- efgcvt efgcvt_r \
+ efgcvt efgcvt_r qefgcvt qefgcvt_r \
hsearch hsearch_r tsearch lsearch \
err error
aux := init-misc
diff --git a/misc/efgcvt.c b/misc/efgcvt.c
index e8a05176e6..73be3e1c5c 100644
--- a/misc/efgcvt.c
+++ b/misc/efgcvt.c
@@ -21,11 +21,20 @@ Cambridge, MA 02139, USA. */
#include <stdlib.h>
#include <float.h>
+#ifndef FLOAT_TYPE
+#define FLOAT_TYPE double
+#define FUNC_PREFIX
+#define FLOAT_FMT_FLAG
#define MAXDIG (DBL_DIG + DBL_MAX_10_EXP)
+#endif
+
+#define APPEND(a, b) APPEND2 (a, b)
+#define APPEND2(a, b) a##b
+
char *
-fcvt (value, ndigit, decpt, sign)
- double value;
+APPEND (FUNC_PREFIX, fcvt) (value, ndigit, decpt, sign)
+ FLOAT_TYPE value;
int ndigit, *decpt, *sign;
{
static char buf[MAXDIG];
@@ -36,8 +45,8 @@ fcvt (value, ndigit, decpt, sign)
}
char *
-ecvt (value, ndigit, decpt, sign)
- double value;
+APPEND (FUNC_PREFIX, ecvt) (value, ndigit, decpt, sign)
+ FLOAT_TYPE value;
int ndigit, *decpt, *sign;
{
static char buf[MAXDIG];
@@ -48,11 +57,11 @@ ecvt (value, ndigit, decpt, sign)
}
char *
-gcvt (value, ndigit, buf)
- double value;
+APPEND (FUNC_PREFIX, gcvt) (value, ndigit, buf)
+ FLOAT_TYPE value;
int ndigit;
char *buf;
{
- sprintf (buf, "%.*g", ndigit, value);
+ sprintf (buf, "%.*" FLOAT_FMT_FLAG "g", ndigit, value);
return buf;
}
diff --git a/misc/efgcvt_r.c b/misc/efgcvt_r.c
index 6a65583a6a..cbd5c271ba 100644
--- a/misc/efgcvt_r.c
+++ b/misc/efgcvt_r.c
@@ -1,5 +1,5 @@
/* [efg]cvt -- compatibility functions for floating point formatting,
- reentrent versions.
+ reentrant versions.
Copyright (C) 1995, 1996 Free Software Foundation, Inc.
This file is part of the GNU C Library.
@@ -25,9 +25,24 @@ Boston, MA 02111-1307, USA. */
#include <math.h>
#include <stdlib.h>
+#ifndef FLOAT_TYPE
+#define FLOAT_TYPE double
+#define FUNC_PREFIX
+#define FLOAT_FMT_FLAG
+#define FLOAT_NAME_EXT
+#endif
+
+#define APPEND(a, b) APPEND2 (a, b)
+#define APPEND2(a, b) a##b
+
+#define FLOOR APPEND(floor, FLOAT_NAME_EXT)
+#define FABS APPEND(fabs, FLOAT_NAME_EXT)
+#define LOG10 APPEND(log10, FLOAT_NAME_EXT)
+
+
int
-fcvt_r (value, ndigit, decpt, sign, buf, len)
- double value;
+APPEND (FUNC_PREFIX, fcvt_r) (value, ndigit, decpt, sign, buf, len)
+ FLOAT_TYPE value;
int ndigit, *decpt, *sign;
char *buf;
size_t len;
@@ -44,7 +59,7 @@ fcvt_r (value, ndigit, decpt, sign, buf, len)
if (*sign)
value = - value;
- n = snprintf (buf, len, "%.*f", ndigit, value);
+ n = snprintf (buf, len, "%.*" FLOAT_FMT_FLAG "f", ndigit, value);
if (n < 0)
return -1;
@@ -60,33 +75,34 @@ fcvt_r (value, ndigit, decpt, sign, buf, len)
return 0;
}
-weak_extern (floor) weak_extern (log10) weak_extern (fabs)
+#define weak_extern2(name) weak_extern (name)
+weak_extern2 (FLOOR) weak_extern2 (LOG10) weak_extern2 (FABS)
int
-ecvt_r (value, ndigit, decpt, sign, buf, len)
- double value;
+APPEND (FUNC_PREFIX, ecvt_r) (value, ndigit, decpt, sign, buf, len)
+ FLOAT_TYPE value;
int ndigit, *decpt, *sign;
char *buf;
size_t len;
{
- double (*log10_function) (double) = &log10;
+ FLOAT_TYPE (*log10_function) (FLOAT_TYPE) = &LOG10;
if (log10_function)
{
/* Use the reasonable code if -lm is included. */
- ndigit -= (int) floor (log10 (fabs (value)));
+ ndigit -= (int) FLOOR (LOG10 (FABS (value)));
if (ndigit < 0)
ndigit = 0;
}
else
{
/* Slow code that doesn't require -lm functions. */
- double d;
+ FLOAT_TYPE d;
for (d = value < 0.0 ? - value : value;
ndigit > 0 && d >= 10.0;
d *= 0.1)
--ndigit;
}
- return fcvt_r (value, ndigit, decpt, sign, buf, len);
+ return APPEND (FUNC_PREFIX, fcvt_r) (value, ndigit, decpt, sign, buf, len);
}
diff --git a/misc/mntent.c b/misc/mntent.c
index 6cf74c2160..0aa1fb8cde 100644
--- a/misc/mntent.c
+++ b/misc/mntent.c
@@ -34,9 +34,9 @@ setmntent (const char *file, const char *mode)
int
endmntent (FILE *stream)
{
- if (fclose (stream) != 0)
- return 0;
- return 1;
+ if (stream) /* SunOS 4.x allows for NULL stream */
+ fclose (stream);
+ return 1; /* SunOS 4.x says to always return 1 */
}
@@ -92,6 +92,9 @@ getmntent (FILE *stream)
int
addmntent (FILE *stream, const struct mntent *mnt)
{
+ if (fseek (stream, 0, SEEK_END))
+ return 1;
+
return (fprintf (stream, "%s %s %s %s %d %d\n",
mnt->mnt_fsname,
mnt->mnt_dir,
@@ -99,7 +102,7 @@ addmntent (FILE *stream, const struct mntent *mnt)
mnt->mnt_opts,
mnt->mnt_freq,
mnt->mnt_passno)
- < 0 ? -1 : 0);
+ < 0 ? 1 : 0);
}
/* Search MNT->mnt_opts for an option matching OPT.
diff --git a/misc/qefgcvt.c b/misc/qefgcvt.c
new file mode 100644
index 0000000000..2015fb8d4f
--- /dev/null
+++ b/misc/qefgcvt.c
@@ -0,0 +1,26 @@
+/* q[efg]cvt -- compatibility functions for floating point formatting,
+ long double version.
+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 FLOAT_TYPE long double
+#define FUNC_PREFIX q
+#define FLOAT_FMT_FLAG "L"
+#define MAXDIG (LDBL_DIG + LDBL_MAX_10_EXP)
+
+#include "efgcvt.c"
diff --git a/misc/qefgcvt_r.c b/misc/qefgcvt_r.c
new file mode 100644
index 0000000000..67cf44880c
--- /dev/null
+++ b/misc/qefgcvt_r.c
@@ -0,0 +1,26 @@
+/* [efg]cvt -- compatibility functions for floating point formatting,
+ reentrant, long double versions.
+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 FLOAT_TYPE long double
+#define FUNC_PREFIX q
+#define FLOAT_FMT_FLAG "L"
+#define FLOAT_NAME_EXT l
+
+#include "efgcvt_r.c"
diff --git a/nss/nsswitch.c b/nss/nsswitch.c
index c92f33b45f..d259165269 100644
--- a/nss/nsswitch.c
+++ b/nss/nsswitch.c
@@ -184,15 +184,18 @@ nss_dlerror_run (void (*operate) (void))
}
+/* Comparison function for searching NI->known tree. */
+static int
+known_compare (const void *p1, const void *p2)
+{
+ return p1 == p2 ? 0 : strcmp (*(const char *const *) p1,
+ *(const char *const *) p2);
+}
+
+
static void *
nss_lookup_function (service_user *ni, const char *fct_name)
{
- /* 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. */
diff --git a/socket/Makefile b/socket/Makefile
index 78388fd41d..adae887d11 100644
--- a/socket/Makefile
+++ b/socket/Makefile
@@ -21,7 +21,7 @@
#
subdir := socket
-headers := sys/socket.h sys/un.h sockaddrcom.h
+headers := sys/socket.h sys/un.h sockaddrcom.h socketbits.h
routines := accept bind connect getpeername getsockname getsockopt \
listen recv recvfrom recvmsg send sendmsg sendto \
diff --git a/socket/sys/socket.h b/socket/sys/socket.h
index 172c897af7..9c3c3e73fe 100644
--- a/socket/sys/socket.h
+++ b/socket/sys/socket.h
@@ -33,6 +33,15 @@ __BEGIN_DECLS
`struct msghdr', and `struct linger' types. */
#include <socketbits.h>
+#ifdef __USE_BSD
+/* This is the 4.3 BSD `struct sockaddr' format, which is used as wire
+ format in the grotty old 4.3 `talk' protocol. */
+struct osockaddr
+ {
+ unsigned short int sa_family;
+ unsigned char sa_data[14];
+ };
+#endif
/* This is the type we use for generic socket address arguments.
diff --git a/stdlib/Makefile b/stdlib/Makefile
index aa072082cc..66f28ffe5c 100644
--- a/stdlib/Makefile
+++ b/stdlib/Makefile
@@ -42,7 +42,7 @@ routines := \
strtof strtod strtold \
system canonicalize \
a64l l64a \
- rpmatch strfmon
+ rpmatch strfmon getsubopt
distribute := exit.h grouping.h
tests := tst-strtol tst-strtod testmb testrand testsort testdiv \
diff --git a/stdlib/getsubopt.c b/stdlib/getsubopt.c
new file mode 100644
index 0000000000..f5ecea4faa
--- /dev/null
+++ b/stdlib/getsubopt.c
@@ -0,0 +1,77 @@
+/* getsubopt -- parse comma separate list into words
+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. */
+
+#include <stdlib.h>
+#include <string.h>
+
+
+/* Parse comma separated suboption from *OPTIONP and match against
+ strings in TOKENS. If found return index and set *VALUEP to
+ optional value introduced by an equal sign. If the suboption is
+ not part of TOKENS return in *VALUEP beginning of unknown
+ suboption. On exit *OPTIONP is set to the beginning of the next
+ otken or at the terminating NUL character. */
+int
+getsubopt (optionp, tokens, valuep)
+ char **optionp;
+ const char *const *tokens;
+ char **valuep;
+{
+ char *endp, *vstart;
+ int cnt;
+
+ if (**optionp == '\0')
+ return -1;
+
+ /* Find end of next token. */
+ endp = strchr (*optionp, ',');
+ if (endp == NULL)
+ endp = strchr (*optionp, '\0');
+
+ /* Find start of value. */
+ vstart = memchr (*optionp, '=', endp - *optionp);
+ if (vstart == NULL)
+ vstart = endp;
+
+ /* Try to match the characters between *OPTIONP and VSTART against
+ one of the TOKENS. */
+ for (cnt = 0; tokens[cnt] != NULL; ++cnt)
+ if (memcmp (*optionp, tokens[cnt], vstart - *optionp) == 0
+ && tokens[cnt][vstart - *optionp] == '\0')
+ {
+ /* We found the current option in TOKENS. */
+ *valuep = vstart != endp ? vstart : NULL;
+
+ if (*endp != '\0')
+ *endp++ = '\0';
+ *optionp = endp;
+
+ return cnt;
+ }
+
+ /* The current suboption does not match any option. */
+ *valuep = *optionp;
+
+ if (*endp != '\0')
+ *endp++ = '\0';
+ *optionp = endp;
+
+ return -1;
+}
diff --git a/stdlib/random.c b/stdlib/random.c
index 0ab8f05e5f..6d2ee85f3e 100644
--- a/stdlib/random.c
+++ b/stdlib/random.c
@@ -239,7 +239,7 @@ weak_alias (__setstate, setstate)
rear pointers can't wrap on the same call by not testing the rear
pointer if the front one has wrapped. Returns a 31-bit random number. */
-int
+int32_t
__random ()
{
int32_t retval;
diff --git a/stdlib/stdlib.h b/stdlib/stdlib.h
index 1feedcfae3..5e7f8386b8 100644
--- a/stdlib/stdlib.h
+++ b/stdlib/stdlib.h
@@ -469,12 +469,27 @@ char *fcvt __P ((double __value, int __ndigit, int *__decpt, int *sign));
be written to BUF. */
char *gcvt __P ((double __value, int __ndigit, char *__buf));
+/* Long double versions of above functions. */
+char *qecvt __P ((__long_double_t __value, int __ndigit, int *__decpt,
+ int *sign));
+char *qfcvt __P ((__long_double_t __value, int __ndigit, int *__decpt,
+ int *sign));
+char *qgcvt __P ((__long_double_t __value, int __ndigit, char *__buf));
+
+
+#ifdef __USE_REENTRANT
/* Reentrant version of the functions above which provide their own
buffers. */
int ecvt_r __P ((double __value, int __ndigit, int *__decpt, int *sign,
char *__buf, size_t __len));
int fcvt_r __P ((double __value, int __ndigit, int *__decpt, int *sign,
char *__buf, size_t __len));
+
+int qecvt_r __P ((__long_double_t __value, int __ndigit, int *__decpt,
+ int *sign, char *__buf, size_t __len));
+int qfcvt_r __P ((__long_double_t __value, int __ndigit, int *__decpt,
+ int *sign, char *__buf, size_t __len));
+#endif
#endif
@@ -509,6 +524,18 @@ extern int rpmatch __P ((__const char *__response));
#endif
+#ifdef __USE_MISC
+/* Parse comma separated suboption from *OPTIONP and match against
+ strings in TOKENS. If found return index and set *VALUEP to
+ optional value introduced by an equal sign. If the suboption is
+ not part of TOKENS return in *VALUEP beginning of unknown
+ suboption. On exit *OPTIONP is set to the beginning of the next
+ otken or at the terminating NUL character. */
+extern int getsubopt __P ((char **__optionp, __const char *__const *__tokens,
+ char **__valuep));
+#endif
+
+
__END_DECLS
#endif /* stdlib.h */
diff --git a/sys/socket.h b/sys/socket.h
new file mode 100644
index 0000000000..999a683016
--- /dev/null
+++ b/sys/socket.h
@@ -0,0 +1 @@
+#include <socket/sys/socket.h>
diff --git a/sysdeps/generic/dl-sysdep.c b/sysdeps/generic/dl-sysdep.c
index 9fab0f0922..8f9e782205 100644
--- a/sysdeps/generic/dl-sysdep.c
+++ b/sysdeps/generic/dl-sysdep.c
@@ -109,11 +109,15 @@ _dl_sysdep_start_cleanup (void)
{
}
+#ifndef MAP_ANON
+/* This is only needed if the system doesn't support MAP_ANON. */
+
int
_dl_sysdep_open_zero_fill (void)
{
return __open ("/dev/zero", O_RDONLY);
}
+#endif
void
_dl_sysdep_fatal (const char *msg, ...)
diff --git a/sysdeps/mach/hurd/dl-sysdep.c b/sysdeps/mach/hurd/dl-sysdep.c
index cffc51e1ce..ee2bf73469 100644
--- a/sysdeps/mach/hurd/dl-sysdep.c
+++ b/sysdeps/mach/hurd/dl-sysdep.c
@@ -210,15 +210,6 @@ _dl_sysdep_start_cleanup (void)
__mach_port_deallocate (__mach_task_self (), __mach_task_self_);
}
-int
-_dl_sysdep_open_zero_fill (void)
-{
- /* The minimal mmap below uses the fd as a memory object port.
- The real mmap used for dlopen ignores the fd for MAP_ANON. */
- return (int) MACH_PORT_NULL;
-}
-
-
void
_dl_sysdep_fatal (const char *msg, ...)
{
@@ -523,7 +514,8 @@ __mmap (caddr_t addr, size_t len, int prot, int flags, int fd, off_t offset)
err = __vm_map (__mach_task_self (),
&mapaddr, (vm_size_t) len, 0 /*ELF_MACHINE_USER_ADDRESS_MASK*/,
!(flags & MAP_FIXED),
- (mach_port_t) fd, (vm_offset_t) offset,
+ (flags & MAP_ANON) ? MACH_PORT_NULL : (mach_port_t) fd,
+ (vm_offset_t) offset,
flags & (MAP_COPY|MAP_PRIVATE),
vmprot, VM_PROT_ALL,
(flags & MAP_SHARED) ? VM_INHERIT_SHARE : VM_INHERIT_COPY);
diff --git a/sysdeps/posix/ttyname_r.c b/sysdeps/posix/ttyname_r.c
index 30f058314d..4450a83326 100644
--- a/sysdeps/posix/ttyname_r.c
+++ b/sysdeps/posix/ttyname_r.c
@@ -48,7 +48,7 @@ ttyname_r (fd, buf, buflen)
/* Test for the absolute minimal size. This makes life easier inside
the loop. */
- if (buflen < (int) (sizeof (dev) + 2))
+ if (buflen < (int) (sizeof (dev) + 1))
{
errno = EINVAL;
return -1;
@@ -64,16 +64,16 @@ ttyname_r (fd, buf, buflen)
return -1;
/* Prepare the result buffer. */
- memcpy (buf, dev, sizeof (dev));
- buf[sizeof (dev)] = '/';
- buflen -= sizeof (dev) + 1;
+ memcpy (buf, dev, sizeof (dev) - 1);
+ buf[sizeof (dev) - 1] = '/';
+ buflen -= sizeof (dev);
while ((d = readdir (dirstream)) != NULL)
if (d->d_fileno == myino)
{
char *cp;
- cp = __stpncpy (&buf[sizeof (dev) + 1], d->d_name,
+ cp = __stpncpy (&buf[sizeof (dev)], d->d_name,
MIN ((int) (_D_EXACT_NAMLEN (d) + 1), buflen));
cp[0] = '\0';
diff --git a/sysdeps/unix/getlogin.c b/sysdeps/unix/getlogin.c
index 7446f25786..246b488f51 100644
--- a/sysdeps/unix/getlogin.c
+++ b/sysdeps/unix/getlogin.c
@@ -35,7 +35,7 @@ DEFUN_VOID(getlogin)
char tty_pathname[2 + 2 * NAME_MAX];
char *real_tty_path = tty_pathname;
char *result = NULL;
- static struct utmp_data utmp_data;
+ static struct utmp_data utmp_data = { ut_fd: -1 };
struct utmp *ut, line;
{
@@ -48,7 +48,7 @@ DEFUN_VOID(getlogin)
err = errno;
(void) close (d);
- if (errno != 0)
+ if (err != 0)
{
errno = err;
return NULL;
diff --git a/sysdeps/unix/sysv/linux/alpha/ioperm.c b/sysdeps/unix/sysv/linux/alpha/ioperm.c
index b9630a8273..cee5f482bb 100644
--- a/sysdeps/unix/sysv/linux/alpha/ioperm.c
+++ b/sysdeps/unix/sysv/linux/alpha/ioperm.c
@@ -116,13 +116,9 @@ static inline unsigned long
port_to_cpu_addr (unsigned long port, int iosys, int size)
{
if (iosys == IOSYS_JENSEN)
- {
- return (port << 7) + ((size - 1) << 4) + io.base;
- }
+ return (port << 7) + ((size - 1) << 5) + io.base;
else
- {
- return (port << 5) + ((size - 1) << 3) + io.base;
- }
+ return (port << 5) + ((size - 1) << 3) + io.base;
}
@@ -303,17 +299,18 @@ init_iosys (void)
}
else
{
- char name[256];
FILE * fp;
fp = fopen (PATH_CPUINFO, "r");
if (!fp)
return -1;
- while ((n = fscanf (fp, "%256[^:]: %256[^\n]\n", name, systype)) != EOF)
+ while ((n = fscanf (fp, "system type : %256[^\n]\n", systype))
+ != EOF)
{
- if (n == 2 && strncmp (name, "system type", 11) == 0) {
+ if (n == 1)
break;
- }
+ else
+ fgets (systype, 256, fp);
}
fclose(fp);
diff --git a/sysdeps/unix/sysv/linux/syscalls.list b/sysdeps/unix/sysv/linux/syscalls.list
index d29577ff6c..73b5de9b98 100644
--- a/sysdeps/unix/sysv/linux/syscalls.list
+++ b/sysdeps/unix/sysv/linux/syscalls.list
@@ -1,7 +1,7 @@
# File name Caller Syscall name # args Strong name Weak names
adjtimex adjtime adjtimex 1 __adjtimex
-bdflush - bdflush 2 bdflush
+bdflush EXTRA bdflush 2 bdflush
create_module EXTRA create_module 3 create_module
delete_module EXTRA delete_module 3 delete_module
fdatasync - fdatasync 1 fdatasync
diff --git a/time/strftime.c b/time/strftime.c
index 1af2f83023..69d7103bfb 100644
--- a/time/strftime.c
+++ b/time/strftime.c
@@ -305,8 +305,8 @@ strftime (s, maxsize, format, tp)
#define DO_NUMBER(digits, value) \
maxdigits = digits; number_value = value; goto do_number
-#define DO_NUMBER_NOPAD(digits, value) \
- maxdigits = digits; number_value = value; goto do_number_nopad
+#define DO_NUMBER_SPACEPAD(digits, value) \
+ maxdigits = digits; number_value = value; goto do_number_spacepad
case 'C':
DO_NUMBER (2, (1900 + tp->tm_year) / 100);
@@ -325,14 +325,14 @@ strftime (s, maxsize, format, tp)
DO_NUMBER (2, tp->tm_mday);
case 'e': /* GNU extension: %d, but blank-padded. */
- DO_NUMBER_NOPAD (2, tp->tm_mday);
+ DO_NUMBER_SPACEPAD (2, tp->tm_mday);
/* All numeric formats set MAXDIGITS and NUMBER_VALUE and then
jump to one of these two labels. */
- do_number_nopad:
- /* Force `-' flag. */
- pad = pad_none;
+ do_number_spacepad:
+ /* Force `_' flag. */
+ pad = pad_space;
do_number:
{
@@ -373,10 +373,10 @@ strftime (s, maxsize, format, tp)
DO_NUMBER (2, hour12);
case 'k': /* GNU extension. */
- DO_NUMBER_NOPAD (2, tp->tm_hour);
+ DO_NUMBER_SPACEPAD (2, tp->tm_hour);
case 'l': /* GNU extension. */
- DO_NUMBER_NOPAD (2, hour12);
+ DO_NUMBER_SPACEPAD (2, hour12);
case 'j':
DO_NUMBER (3, 1 + tp->tm_yday);