diff options
34 files changed, 621 insertions, 134 deletions
@@ -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); |