Update. cvs/libc-ud-970723
authorUlrich Drepper <drepper@redhat.com>
Thu, 24 Jul 1997 01:36:01 +0000 (01:36 +0000)
committerUlrich Drepper <drepper@redhat.com>
Thu, 24 Jul 1997 01:36:01 +0000 (01:36 +0000)
1997-07-24 03:14  Ulrich Drepper  <drepper@cygnus.com>

* elf/dl-deps.c: Complete rewrite to handle DT_AUXILIARY correctly.

* inet/Makefile (tests): Add htontest.
* inet/htontest.c: New file.

* inet/netinet/in.h: Cleanup optimization of ntoh/hton functions
when they are no noops.
* sysdeps/alpha/htonl.S: Don't define __ protected names.
* sysdeps/alpha/htons.S: Likewise.
* sysdeps/generic/htonl.c: Likewise.
* sysdeps/generic/htons.c: Likewise.
* sysdeps/i386/htonl.S: Likewise.
* sysdeps/i386/htons.S: Likewise.
* sysdeps/i386/i486/htonl.S: Likewise.
* sysdeps/vax/htonl.s: Likewise.
* sysdeps/vax/htons.s: Likewise.

* string/Makefile (headers): Add byteswap.h and bits/byteswap.h.
* string/byteswap.h: New file.
* sysdeps/generic/bits/byteswap.h: New file.
* sysdeps/i386/bits/byteswap.h: New file.
* sysdeps/generic/bits/htontoh.h: Removed.
* sysdeps/i386/bits/htontoh.h: Removed.

* misc/search.h: General cleanup.  Don't define reentrant hsearch
functions uless __USE_GNU.

* nss/nsswitch.c: Pretty print.

* sunrpc/clnt_udp.c (clntudp_call): Initialize outlen to prevent
warning.

* sysdeps/unix/i386/sysdep.h (DO_CALL): Use lcall, binutils have
been fixed meanwhile.
Reported by Zack Weinberg <zack@rabi.phys.columbia.edu>.

1997-07-24 00:53  Philip Blundell  <Philip.Blundell@pobox.com>

* db/hash/hash.c (init_hash): Only use statbuf.st_blksize if it
exists for this port.

1997-07-24 00:12  Philip Blundell  <Philip.Blundell@pobox.com>

* sysdeps/standalone/arm/bits/errno.h (ESTALE): Add.

1997-07-22  Andreas Schwab  <schwab@issan.informatik.uni-dortmund.de>

* manual/argp.texi (Argp Option Vectors): Use @minus, not @math,
to format a proper minus sign.

1997-07-22  Andreas Schwab  <schwab@issan.informatik.uni-dortmund.de>

* sysdeps/m68k/fpu/fraiseexcpt.c: Don't handle FE_INEXACT
specially, the standard doesn't require it.

* math/test-fenv.c (test_exceptions): Add IGNORE_INEXACT argument,
if non-zero then don't test inexact flag.  Callers changed.
(set_single_exc): Ignore inexact flag if underflow or overflow
exception is raised.

1997-07-23 05:10  Ulrich Drepper  <drepper@cygnus.com>

* sysdeps/unix/sysv/linux/sys/fsuid.h: New file.
Provided by Michael Deutschmann <ldeutsch@mail.netshop.net>.
* sysdeps/unix/sysv/linux/Makefile (headers): Add sys/fsuid.h.
* sysdeps/unix/sysv/linux/Dist: Add sys/fsuid.h.

1997-07-16 10:09  Fila Kolodny  <fila@ibi.com>

* resolv/gethnamaddr.c: Define MAXHOSTNAMELEN as 256, since RFC 1034
and 1035 state that a fully qualified domain name cannot exceed 255
octets in length.
* resolv/nss_dns/dns-host.c: Likewise.

1997-07-22 09:54  H.J. Lu   <hjl@gnu.ai.mit.edu>

* inet/netinet/in.h (htons): Fix typos.

* sysdeps/i386/bits/htontoh.h (__ntohs): Return the value.

1997-07-22 11:47  Ulrich Drepper  <drepper@cygnus.com>

* nss/nsswitch.c (nss_lookup_function): Include function.def, not
functions.def.
Patch by Klaus Espenlaub <kespenla@hydra.informatik.uni-ulm.de>.

32 files changed:
ChangeLog
bits/byteswap.h [new file with mode: 0644]
elf/dl-deps.c
inet/Makefile
inet/htontest.c [new file with mode: 0644]
inet/netinet/in.h
manual/argp.texi
math/test-fenv.c
misc/search.h
nss/nsswitch.c
resolv/gethnamaddr.c
resolv/nss_dns/dns-host.c
string/Makefile
string/byteswap.h [new file with mode: 0644]
sunrpc/clnt_udp.c
sysdeps/alpha/htonl.S
sysdeps/alpha/htons.S
sysdeps/generic/bits/byteswap.h [new file with mode: 0644]
sysdeps/generic/htonl.c
sysdeps/generic/htons.c
sysdeps/i386/bits/byteswap.h [new file with mode: 0644]
sysdeps/i386/bits/htontoh.h [deleted file]
sysdeps/i386/htonl.S
sysdeps/i386/htons.S
sysdeps/i386/i486/htonl.S
sysdeps/m68k/fpu/fraiseexcpt.c
sysdeps/unix/i386/sysdep.h
sysdeps/unix/sysv/linux/Dist
sysdeps/unix/sysv/linux/Makefile
sysdeps/unix/sysv/linux/sys/fsuid.h [moved from sysdeps/generic/bits/htontoh.h with 69% similarity]
sysdeps/vax/htonl.s
sysdeps/vax/htons.s

index 0e0750c..9f3ed37 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,91 @@
+1997-07-24 03:14  Ulrich Drepper  <drepper@cygnus.com>
+
+       * elf/dl-deps.c: Complete rewrite to handle DT_AUXILIARY correctly.
+
+       * inet/Makefile (tests): Add htontest.
+       * inet/htontest.c: New file.
+
+       * inet/netinet/in.h: Cleanup optimization of ntoh/hton functions
+       when they are no noops.
+       * sysdeps/alpha/htonl.S: Don't define __ protected names.
+       * sysdeps/alpha/htons.S: Likewise.
+       * sysdeps/generic/htonl.c: Likewise.
+       * sysdeps/generic/htons.c: Likewise.
+       * sysdeps/i386/htonl.S: Likewise.
+       * sysdeps/i386/htons.S: Likewise.
+       * sysdeps/i386/i486/htonl.S: Likewise.
+       * sysdeps/vax/htonl.s: Likewise.
+       * sysdeps/vax/htons.s: Likewise.
+
+       * string/Makefile (headers): Add byteswap.h and bits/byteswap.h.
+       * string/byteswap.h: New file.
+       * sysdeps/generic/bits/byteswap.h: New file.
+       * sysdeps/i386/bits/byteswap.h: New file.
+       * sysdeps/generic/bits/htontoh.h: Removed.
+       * sysdeps/i386/bits/htontoh.h: Removed.
+
+       * misc/search.h: General cleanup.  Don't define reentrant hsearch
+       functions uless __USE_GNU.
+
+       * nss/nsswitch.c: Pretty print.
+
+       * sunrpc/clnt_udp.c (clntudp_call): Initialize outlen to prevent
+       warning.
+
+       * sysdeps/unix/i386/sysdep.h (DO_CALL): Use lcall, binutils have
+       been fixed meanwhile.
+       Reported by Zack Weinberg <zack@rabi.phys.columbia.edu>.
+
+1997-07-24 00:53  Philip Blundell  <Philip.Blundell@pobox.com>
+
+       * db/hash/hash.c (init_hash): Only use statbuf.st_blksize if it
+       exists for this port.
+
+1997-07-24 00:12  Philip Blundell  <Philip.Blundell@pobox.com>
+
+       * sysdeps/standalone/arm/bits/errno.h (ESTALE): Add.
+
+1997-07-22  Andreas Schwab  <schwab@issan.informatik.uni-dortmund.de>
+
+       * manual/argp.texi (Argp Option Vectors): Use @minus, not @math,
+       to format a proper minus sign.
+
+1997-07-22  Andreas Schwab  <schwab@issan.informatik.uni-dortmund.de>
+
+       * sysdeps/m68k/fpu/fraiseexcpt.c: Don't handle FE_INEXACT
+       specially, the standard doesn't require it.
+
+       * math/test-fenv.c (test_exceptions): Add IGNORE_INEXACT argument,
+       if non-zero then don't test inexact flag.  Callers changed.
+       (set_single_exc): Ignore inexact flag if underflow or overflow
+       exception is raised.
+
+1997-07-23 05:10  Ulrich Drepper  <drepper@cygnus.com>
+
+       * sysdeps/unix/sysv/linux/sys/fsuid.h: New file.
+       Provided by Michael Deutschmann <ldeutsch@mail.netshop.net>.
+       * sysdeps/unix/sysv/linux/Makefile (headers): Add sys/fsuid.h.
+       * sysdeps/unix/sysv/linux/Dist: Add sys/fsuid.h.
+
+1997-07-16 10:09  Fila Kolodny  <fila@ibi.com>
+
+       * resolv/gethnamaddr.c: Define MAXHOSTNAMELEN as 256, since RFC 1034
+       and 1035 state that a fully qualified domain name cannot exceed 255
+       octets in length.
+       * resolv/nss_dns/dns-host.c: Likewise.
+
+1997-07-22 09:54  H.J. Lu   <hjl@gnu.ai.mit.edu>
+
+       * inet/netinet/in.h (htons): Fix typos.
+
+       * sysdeps/i386/bits/htontoh.h (__ntohs): Return the value.
+
+1997-07-22 11:47  Ulrich Drepper  <drepper@cygnus.com>
+
+       * nss/nsswitch.c (nss_lookup_function): Include function.def, not
+       functions.def.
+       Patch by Klaus Espenlaub <kespenla@hydra.informatik.uni-ulm.de>.
+
 1997-07-22 01:35  Ulrich Drepper  <drepper@cygnus.com>
 
        * Makerules (+make-deps): Use $(CFLAGS) in run of $(+mkdep) so
diff --git a/bits/byteswap.h b/bits/byteswap.h
new file mode 100644 (file)
index 0000000..9404cc4
--- /dev/null
@@ -0,0 +1,43 @@
+/* Macros to swap the order of bytes in integer values.
+   Copyright (C) 1997 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.  */
+
+#ifndef _BITS_BYTESWAP_H
+#define _BITS_BYTESWAP_H       1
+
+/* Swap bytes in 16 bit value.  */
+#define __bswap_16(x) \
+     ((((x) >> 8) & 0xff) | (((x) & 0xff) << 8))
+
+/* Swap bytes in 32 bit value.  */
+#define __bswap_32(x) \
+     ((((x) & 0xff000000) >> 24) | (((x) & 0x00ff0000) >>  8) |                      \
+      (((x) & 0x0000ff00) <<  8) | (((x) & 0x000000ff) << 24))
+
+#if defined __GNUC__ && __GNUC__ >= 2
+/* Swap bytes in 64 bit value.  */
+# define __bswap_64(x) \
+     ({ union { unsigned long long int __ll;                                 \
+               unsigned long int __l[2]; } __v, __r;                         \
+        __v.__ll = (x);                                                              \
+       __r.__l[0] = __bswap_32 (__v.__l[1]);                                 \
+       __r.__l[1] = __bswap_32 (__v.__l[0]);                                 \
+       __r.__ll; })
+#endif
+
+#endif /* bits/byteswap.h */
index e2fd340..36f5ee0 100644 (file)
 #include <dlfcn.h>
 #include <stdlib.h>
 
+#include <assert.h>
+
+/* Whether an shared object references one or more auxiliary objects
+   is signaled by the AUXTAG entry in l_info.  */
+#define AUXTAG (DT_NUM + DT_PROCNUM + DT_VERSIONTAGNUM \
+                + DT_EXTRATAGIDX (DT_AUXILIARY))
+
+
+/* When loading auxiliary objects we must ignore errors.  It's ok if
+   an object is missing.  */
 struct openaux_args
-{
-  /* The arguments to openaux.  */
-  struct link_map *map;
-  int trace_mode;
-  const char *strtab;
-  ElfW(Dyn) *d;
+  {
+    /* The arguments to openaux.  */
+    struct link_map *map;
+    int trace_mode;
+    const char *strtab;
+    const ElfW(Dyn) *d;
 
-  /* The return value of openaux.  */
-  struct link_map *aux;
-};
+    /* The return value of openaux.  */
+    struct link_map *aux;
+  };
 
 static void
 openaux (void *a)
@@ -45,78 +55,56 @@ openaux (void *a)
                              args->trace_mode);
 }
 
+
+
+/* We use a very special kind of list to track the three kinds paths
+   through the list of loaded shared objects.  We have to
+
+   - go through all objects in the correct order, which includes the
+     possible recursive loading of auxiliary objects and dependencies
+
+   - produce a flat list with unique members of all involved objects
+
+   - produce a flat list of all shared objects.
+*/
+struct list
+  {
+    int done;                  /* Nonzero if this map was processed.  */
+    struct link_map *map;      /* The data.  */
+
+    struct list *unique;       /* Elements for normal list.  */
+    struct list *dup;          /* Elements in complete list.  */
+  };
+
+
 void
 _dl_map_object_deps (struct link_map *map,
                     struct link_map **preloads, unsigned int npreloads,
                     int trace_mode)
 {
-  struct list
-    {
-      struct link_map *map;
-      struct list *next;
-    };
-  struct list *head, *tailp, *scanp;
-  struct list duphead, *duptailp;
-  unsigned int nduplist;
-  unsigned int nlist, naux, i;
+  struct list known[1 + npreloads + 1];
+  struct list *runp, *head, *utail, *dtail;
+  unsigned int nlist, nduplist, i;
+
   inline void preload (struct link_map *map)
     {
-      head[nlist].next = &head[nlist + 1];
-      head[nlist++].map = map;
+      known[nlist].done = 0;
+      known[nlist].map = map;
+
+      known[nlist].unique = &known[nlist + 1];
+      known[nlist].dup = &known[nlist + 1];
 
+      ++nlist;
       /* 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 the list.  */
       map->l_reserved = 1;
     }
 
-  naux = nlist = 0;
-
-  /* XXX The AUXILIARY implementation isn't correct in the moment. XXX
-     XXX The problem is that we currently do not handle auxiliary  XXX
-     XXX entries in the loaded objects.                                   XXX */
-
-#define AUXTAG (DT_NUM + DT_PROCNUM + DT_VERSIONTAGNUM \
-                + DT_EXTRATAGIDX (DT_AUXILIARY))
-
-  /* First determine the number of auxiliary objects we have to load.  */
-  if (map->l_info[AUXTAG])
-    {
-      ElfW(Dyn) *d;
-      for (d = map->l_ld; d->d_tag != DT_NULL; ++d)
-       if (d->d_tag == DT_AUXILIARY)
-         ++naux;
-    }
-
-  /* Now we can allocate the array for the linker maps. */
-  head = (struct list *) alloca (sizeof (struct list)
-                                * (naux + npreloads + 2));
-
-  /* Load the auxiliary objects, even before the object itself.  */
-  if (map->l_info[AUXTAG])
-    {
-      /* There is at least one auxiliary library specified.  We try to
-        load it, and if we can, use its symbols in preference to our
-        own.  But if we can't load it, we just silently ignore it.  */
-      struct openaux_args args;
-      args.strtab
-       = ((void *) map->l_addr + map->l_info[DT_STRTAB]->d_un.d_ptr);
-      args.map = map;
-      args.trace_mode = trace_mode;
-
-      for (args.d = map->l_ld; args.d->d_tag != DT_NULL; ++args.d)
-       if (args.d->d_tag == DT_AUXILIARY)
-         {
-           char *errstring;
-           const char *objname;
-           if (! _dl_catch_error (&errstring, &objname, openaux, &args))
-             /* The auxiliary object is actually there.  Use it as
-                the first search element, even before MAP itself.  */
-             preload (args.aux);
-         }
-    }
+  /* No loaded object so far.  */
+  nlist = 0;
 
-  /* Next load MAP itself.  */
+  /* First load MAP itself.  */
   preload (map);
 
   /* Add the preloaded items after MAP but before any of its dependencies.  */
@@ -124,30 +112,51 @@ _dl_map_object_deps (struct link_map *map,
     preload (preloads[i]);
 
   /* Terminate the lists.  */
-  head[nlist - 1].next = NULL;
-  duphead.next = NULL;
+  known[nlist - 1].unique = NULL;
+  known[nlist - 1].dup = NULL;
+
+  /* Pointer to the first member of the unique and duplicate list.  */
+  head = known;
 
-  /* Start here for adding dependencies to the list.  */
-  tailp = &head[nlist - 1];
+  /* Pointer to last unique object.  */
+  utail = &known[nlist - 1];
+  /* Pointer to last loaded object.  */
+  dtail = &known[nlist - 1];
 
   /* Until now we have the same number of libraries in the normal and
      the list with duplicates.  */
   nduplist = nlist;
-  duptailp = &duphead;
 
-  /* Process each element of the search list, loading each of its immediate
-     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 = head; scanp; scanp = scanp->next)
+  /* Process each element of the search list, loading each of its
+     auxiliary objects and immediate dependencies.  Auxiliary objects
+     will be added in the list before the object itself and
+     dependencies will be appended to the list as we step through it.
+     This produces a flat, ordered list that represents a
+     breadth-first search of the dependency tree.
+
+     The whole process is complicated by the fact that we better
+     should use alloca for the temporary list elements.  But using
+     alloca means we cannot use recursive function calls.  */
+  for (runp = known; runp; )
     {
-      struct link_map *l = scanp->map;
+      struct link_map *l = runp->map;
 
-      if (l->l_info[DT_NEEDED])
+      if (runp->done == 0 && (l->l_info[AUXTAG] || l->l_info[DT_NEEDED]))
        {
-         const char *strtab
-           = ((void *) l->l_addr + l->l_info[DT_STRTAB]->d_un.d_ptr);
+         const char *strtab = ((void *) l->l_addr
+                               + l->l_info[DT_STRTAB]->d_un.d_ptr);
+         struct openaux_args args;
+         struct list *orig;
          const ElfW(Dyn) *d;
+
+         /* Mark map as processed.  */
+         runp->done = 1;
+
+         args.strtab = strtab;
+         args.map = l;
+         args.trace_mode = trace_mode;
+         orig = runp;
+
          for (d = l->l_ld; d->d_tag != DT_NULL; ++d)
            if (d->d_tag == DT_NEEDED)
              {
@@ -156,32 +165,182 @@ _dl_map_object_deps (struct link_map *map,
                  = _dl_map_object (l, strtab + d->d_un.d_val,
                                    l->l_type == lt_executable ? lt_library :
                                    l->l_type, trace_mode);
+               /* Allocate new entry.  */
+               struct list *newp = alloca (sizeof (struct list));
+
+               /* Add it in any case to the duplicate list.  */
+               newp->map = dep;
+               newp->dup = NULL;
+               dtail->dup = newp;
+               dtail = newp;
+               ++nduplist;
 
                if (dep->l_reserved)
                  /* This object is already in the search list we are
-                     building.  Don't add a duplicate pointer.  Release the
-                     reference just added by _dl_map_object.  */
+                    building.  Don't add a duplicate pointer.
+                    Release the reference just added by
+                    _dl_map_object.  */
                  --dep->l_opencount;
                else
                  {
-                   /* Append DEP to the search list.  */
-                   tailp->next = alloca (sizeof *tailp);
-                   tailp = tailp->next;
-                   tailp->map = dep;
-                   tailp->next = NULL;
+                   /* Append DEP to the unique list.  */
+                   newp->done = 0;
+                   newp->unique = NULL;
+                   utail->unique = newp;
+                   utail = newp;
                    ++nlist;
                    /* Set the mark bit that says it's already in the list.  */
                    dep->l_reserved = 1;
                  }
+             }
+           else if (d->d_tag == DT_AUXILIARY)
+             {
+               char *errstring;
+               const char *objname;
 
-               /* In any case append DEP to the duplicates search list.  */
-               duptailp->next = alloca (sizeof *duptailp);
-               duptailp = duptailp->next;
-               duptailp->map = dep;
-               duptailp->next = NULL;
-               ++nduplist;
+               /* Store the tag in the argument structure.  */
+               args.d = d;
+
+               if (_dl_catch_error (&errstring, &objname, openaux, &args))
+                 {
+                   /* We are not interested in the error message.  */
+                   assert (errstring != NULL);
+                   free (errstring);
+                 }
+               else
+                 {
+                   /* The auxiliary object is actually available.
+                      Incorporate the map in all the lists.  */
+
+                   /* Allocate new entry.  This always has to be done.  */
+                   struct list *newp = alloca (sizeof (struct list));
+
+                   /* Copy the content of the current entry over.  */
+                   memcpy (newp, orig, sizeof (*newp));
+
+                   /* Initialize new entry.  */
+                   orig->done = 0;
+                   orig->map = args.aux;
+                   orig->dup = newp;
+
+                   /* We must handle two situations here: the map is new,
+                      so we must add it in all three lists.  If the map
+                      is already known, we have two further possibilities:
+                      - if the object is before the current map in the
+                        search list, we do nothing.  It is already found
+                        early
+                      - if the object is after the current one, we must
+                        move it just before the current map to make sure
+                        the symbols are found early enough
+                   */
+                   if (args.aux->l_reserved)
+                     {
+                       /* The object is already somewhere in the
+                          list.  Locate it first.  */
+                       struct list *late;
+
+                       /* This object is already in the search list
+                          we are building.  Don't add a duplicate
+                          pointer.  Release the reference just added
+                          by _dl_map_object.  */
+                       --args.aux->l_opencount;
+
+                       for (late = orig; late->unique; late = late->unique)
+                         if (late->unique->map == args.aux)
+                           break;
+
+                       if (late->unique)
+                         {
+                           /* The object is somewhere behind the current
+                              position in the search path.  We have to
+                              move it to this earlier position.  */
+                           orig->unique = newp;
+
+                           /* Now remove the later entry from the unique
+                              list.  */
+                           late->unique = late->unique->unique;
+
+                           /* We must move the earlier in the chain.  */
+                           if (args.aux->l_prev)
+                             args.aux->l_prev->l_next = args.aux->l_next;
+                           if (args.aux->l_next)
+                             args.aux->l_next->l_prev = args.aux->l_prev;
+
+                           args.aux->l_prev = newp->map->l_prev;
+                           newp->map->l_prev = args.aux;
+                           if (args.aux->l_prev != NULL)
+                             args.aux->l_prev->l_next = args.aux;
+                           args.aux->l_next = newp->map;
+                         }
+                       else
+                         {
+                           /* The object must be somewhere earlier in
+                              the list.  That's good, we only have to
+                              insert an entry for the duplicate list.  */
+                           orig->unique = NULL;        /* Never used.  */
+
+                           /* Now we have a problem.  The element pointing
+                              to ORIG in the unique list must point to
+                              NEWP now.  This is the only place where we
+                              need this backreference and this situation
+                              is really not that frequent.  So we don't
+                              use a double-linked list but instead search
+                              for the preceding element.  */
+                           late = head;
+                           while (late->unique != orig)
+                             late = late->unique;
+                           late->unique = newp;
+                         }
+                     }
+                   else
+                     {
+                       /* This is easy.  We just add the symbol right
+                          here.  */
+                       orig->unique = newp;
+                       ++nlist;
+                       /* Set the mark bit that says it's already in
+                          the list.  */
+                       args.aux->l_reserved = 1;
+
+                       /* The only problem is that in the double linked
+                          list of all objects we don't have this new
+                          object at the correct place.  Correct this
+                          here.  */
+                       if (args.aux->l_prev)
+                         args.aux->l_prev->l_next = args.aux->l_next;
+                       if (args.aux->l_next)
+                         args.aux->l_next->l_prev = args.aux->l_prev;
+
+                       args.aux->l_prev = newp->map->l_prev;
+                       newp->map->l_prev = args.aux;
+                       if (args.aux->l_prev != NULL)
+                         args.aux->l_prev->l_next = args.aux;
+                       args.aux->l_next = newp->map;
+                     }
+
+                   /* Move the tail pointers if necessary.  */
+                   if (orig == utail)
+                     utail = newp;
+                   if (orig == dtail)
+                     dtail = newp;
+
+                   /* Move on the insert point.  */
+                   orig = newp;
+
+                   /* We always add an entry to the duplicate list.  */
+                   ++nduplist;
+                 }
              }
        }
+      else
+       /* Mark as processed.  */
+       runp->done = 1;
+
+      /* If we have no auxiliary objects just go on to the next map.  */
+      if (runp->done)
+       do
+         runp = runp->unique;
+       while (runp && runp->done);
     }
 
   /* Store the search list we built in the object.  It will be used for
@@ -192,24 +351,26 @@ _dl_map_object_deps (struct link_map *map,
                      "cannot allocate symbol search list");
   map->l_nsearchlist = nlist;
 
-  nlist = 0;
-  for (scanp = head; scanp; scanp = scanp->next)
+  for (nlist = 0, runp = head; runp; runp = runp->unique)
     {
-      map->l_searchlist[nlist++] = scanp->map;
+      map->l_searchlist[nlist++] = runp->map;
 
       /* Now clear all the mark bits we set in the objects on the search list
         to avoid duplicates, so the next call starts fresh.  */
-      scanp->map->l_reserved = 0;
+      runp->map->l_reserved = 0;
     }
 
-  map->l_dupsearchlist = malloc (nduplist * sizeof (struct link_map *));
-  if (map->l_dupsearchlist == NULL)
-    _dl_signal_error (ENOMEM, map->l_name,
-                     "cannot allocate symbol search list");
   map->l_ndupsearchlist = nduplist;
+  if (nlist == nduplist)
+    map->l_dupsearchlist = map->l_searchlist;
+  else
+    {
+      map->l_dupsearchlist = malloc (nduplist * sizeof (struct link_map *));
+      if (map->l_dupsearchlist == NULL)
+       _dl_signal_error (ENOMEM, map->l_name,
+                         "cannot allocate symbol search list");
 
-  for (nlist = 0; nlist < naux + 1 + npreloads; ++nlist)
-    map->l_dupsearchlist[nlist] = head[nlist].map;
-  for (scanp = duphead.next; scanp; scanp = scanp->next)
-    map->l_dupsearchlist[nlist++] = scanp->map;
+      for (nlist = 0, runp = head; runp; runp = runp->dup)
+       map->l_searchlist[nlist++] = runp->map;
+    }
 }
index 47570f1..0237d0b 100644 (file)
@@ -46,6 +46,8 @@ routines := htonl htons               \
            getaliasent_r getaliasent getaliasname getaliasname_r \
            in6_addr getnameinfo if_index
 
+tests := htontest
+
 # No warnings about losing BSD code.
 CFLAGS-rcmd.c = -w
 CFLAGS-rexec.c = -w
diff --git a/inet/htontest.c b/inet/htontest.c
new file mode 100644 (file)
index 0000000..87167b4
--- /dev/null
@@ -0,0 +1,70 @@
+/* Test hton/ntoh functions.
+   Copyright (C) 1997 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997.
+
+   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 <endian.h>
+#include <stdio.h>
+#include <netinet/in.h>
+
+#if BYTE_ORDER == BIG_ENDIAN
+# define TEST(orig, swapped, fct) \
+  if ((fct (orig)) != (orig)) {                                                      \
+    printf ("Failed for %s -> %#x\n", #fct "(" #orig ")", fct (orig));       \
+    result = 1;                                                                      \
+  }
+#elif BYTE_ORDER == LITTLE_ENDIAN
+# define TEST(orig, swapped, fct) \
+  if ((fct (orig)) != (swapped)) {                                           \
+    printf ("Failed for %s -> %#x\n", #fct "(" #orig ")", fct (orig));       \
+    result = 1;                                                                      \
+  }
+#else
+# error "Bah, what kind of system do you use?"
+#endif
+
+u_int32_t lo = 0x67452301;
+u_int16_t foo = 0x1234;
+
+int
+main (void)
+{
+  int result = 0;
+
+  TEST (0x67452301, 0x01234567, htonl);
+  TEST (0x67452301, 0x01234567, (htonl));
+  TEST (0x67452301, 0x01234567, ntohl);
+  TEST (0x67452301, 0x01234567, (ntohl));
+
+  TEST (lo, 0x01234567, htonl);
+  TEST (lo, 0x01234567, (htonl));
+  TEST (lo, 0x01234567, ntohl);
+  TEST (lo, 0x01234567, (ntohl));
+
+  TEST (0x1234, 0x3412, htons);
+  TEST (0x1234, 0x3412, (htons));
+  TEST (0x1234, 0x3412, ntohs);
+  TEST (0x1234, 0x3412, (ntohs));
+
+  TEST (foo, 0x3412, htons);
+  TEST (foo, 0x3412, (htons));
+  TEST (foo, 0x3412, ntohs);
+  TEST (foo, 0x3412, (ntohs));
+
+  return result;
+}
index ac0d167..d2a366b 100644 (file)
@@ -185,9 +185,9 @@ struct sockaddr_in
 struct sockaddr_in6
   {
     __SOCKADDR_COMMON (sin6_);
-    u_int16_t          sin6_port;      /* Transport layer port # */
-    u_int32_t          sin6_flowinfo;  /* IPv6 flow information */
-    struct in6_addr    sin6_addr;      /* IPv6 address */
+    u_int16_t sin6_port;       /* Transport layer port # */
+    u_int32_t sin6_flowinfo;   /* IPv6 flow information */
+    struct in6_addr sin6_addr; /* IPv6 address */
   };
 
 /* IPv6 multicast request.  */
@@ -197,7 +197,7 @@ struct ipv6_mreq
     struct in6_addr ipv6mr_multiaddr;
 
     /* local IPv6 address of interface */
-    int                ipv6mr_ifindex;
+    int ipv6mr_ifindex;
   };
 
 /* Get system-specific definitions.  */
@@ -210,18 +210,17 @@ struct ipv6_mreq
    this was a short-sighted decision since on different systems the types
    may have different representations but the values are always the same.  */
 
-extern u_int32_t __ntohl __P ((u_int32_t __netlong));
 extern u_int32_t ntohl __P ((u_int32_t __netlong));
-extern u_int16_t __ntohs __P ((u_int16_t __netshort));
 extern u_int16_t ntohs __P ((u_int16_t __netshort));
-extern u_int32_t __htonl __P ((u_int32_t __hostlong));
 extern u_int32_t htonl __P ((u_int32_t __hostlong));
-extern u_int16_t __htons __P ((u_int16_t __hostshort));
 extern u_int16_t htons __P ((u_int16_t __hostshort));
 
 #include <endian.h>
 
-#if __BYTE_ORDER == __BIG_ENDIAN
+/* Get machine dependent optimized versions of byte swapping functions.  */
+#include <bits/byteswap.h>
+
+#if __BYTE_ORDER == __BIG_ENDIAN && defined __OPTIMIZE__
 /* The host byte order is the same as network byte order,
    so these functions are all just identity.  */
 # define ntohl(x)      (x)
@@ -230,26 +229,10 @@ extern u_int16_t htons __P ((u_int16_t __hostshort));
 # define htons(x)      (x)
 #else
 # if __BYTE_ORDER == __LITTLE_ENDIAN && defined __OPTIMIZE__
-#  define ntohl(x)     (__builtin_constant_p (x)                         \
-                        ? __constant_htontohl (x) : __ntohl (x))
-#  define ntohs(x)     (__builtin_constant_p (x)                         \
-                        ? __constant_htontohs (x) : __ntohs (x))
-#  define htonl(x)     (__builtin_constant_p (x)                         \
-                        ? __constant_htontohl (x) : __htonl (x))
-#  define htons(x)     (__builtin_constant_p (x)                         \
-                        ? __constant_htontohl (x) : __htonl (x))
-
-#  define __constant_htontohl(x) \
-       ((((x) & 0xff000000) >> 24) | \
-        (((x) & 0x00ff0000) >>  8) | \
-        (((x) & 0x0000ff00) <<  8) | \
-        (((x) & 0x000000ff) << 24))
-#  define __constant_htontohs(x) \
-       ((((x) & 0x0000ff00) >>  8) | \
-        (((x) & 0x000000ff) << 8))
-
-/* Now get machine dependent optimized versions for the real work.  */
-#  include <bits/htontoh.h>
+#  define ntohl(x)     __bswap_32 (x)
+#  define ntohs(x)     __bswap_16 (x)
+#  define htonl(x)     __bswap_32 (x)
+#  define htons(x)     __bswap_16 (x)
 # endif
 #endif
 
index c049d0e..84b131f 100644 (file)
@@ -271,15 +271,14 @@ group); in this usage, it's conventional to end the string with a
 The group this option is in.
 
 In a long help message, options are sorted alphabetically within each
-group, and the groups presented in the order @math{0, 1, 2,} @dots{},
-@math{@var{n}, -@var{m},} @dots{}, @math{-2, -1}.  Every entry in an
+group, and the groups presented in the order 0, 1, 2, @dots{}, @var{n},
+@minus{}@var{m}, @dots{}, @minus{}2, @minus{}1.  Every entry in an
 options array with this
 field 0 will inherit the group number of the previous entry, or zero if
 it's the first one, unless its a group header (@code{name} and
-@code{key} fields both zero), in which case, the previous entry
-@math{@w{} + 1} is
+@code{key} fields both zero), in which case, the previous entry + 1 is
 the default.  Automagic options such as @samp{--help} are put into group
-@math{-1}.
+@minus{}1.
 
 Note that because of C structure initialization rules, this field
 often need not be specified, because 0 is the right value.
index 9161c33..2c3aeb0 100644 (file)
@@ -85,7 +85,8 @@ test_single_exception (short int exception,
 }
 
 static void
-test_exceptions (const char *test_name, short int exception)
+test_exceptions (const char *test_name, short int exception,
+                int ignore_inexact)
 {
   printf ("Test: %s\n", test_name);
 #ifdef FE_DIVBYZERO
@@ -97,8 +98,9 @@ test_exceptions (const char *test_name, short int exception)
                          "INVALID");
 #endif
 #ifdef FE_INEXACT
-  test_single_exception (exception, INEXACT_EXC, FE_INEXACT,
-                         "INEXACT");
+  if (!ignore_inexact)
+    test_single_exception (exception, INEXACT_EXC, FE_INEXACT,
+                          "INEXACT");
 #endif
 #ifdef FE_UNDERFLOW
   test_single_exception (exception, UNDERFLOW_EXC, FE_UNDERFLOW,
@@ -163,28 +165,32 @@ static void
 set_single_exc (const char *test_name, int fe_exc, fexcept_t exception)
 {
   char str[200];
+  /* The standard allows the inexact exception to be set together with the
+     underflow and overflow exceptions.  So ignore the inexact flag if the
+     others are raised.  */
+  int ignore_inexact = (fe_exc & (UNDERFLOW_EXC | OVERFLOW_EXC)) != 0;
 
   strcpy (str, test_name);
   strcat (str, ": set flag, with rest not set");
   feclearexcept (FE_ALL_EXCEPT);
   feraiseexcept (exception);
-  test_exceptions (str, fe_exc);
+  test_exceptions (str, fe_exc, ignore_inexact);
 
   strcpy (str, test_name);
   strcat (str, ": clear flag, rest also unset");
   feclearexcept (exception);
-  test_exceptions (str, NO_EXC);
+  test_exceptions (str, NO_EXC, ignore_inexact);
 
   strcpy (str, test_name);
   strcat (str, ": set flag, with rest set");
   feraiseexcept (FE_ALL_EXCEPT ^ exception);
   feraiseexcept (exception);
-  test_exceptions (str, ALL_EXC);
+  test_exceptions (str, ALL_EXC, 0);
 
   strcpy (str, test_name);
   strcat (str, ": clear flag, leave rest set");
   feclearexcept (exception);
-  test_exceptions (str, ALL_EXC ^ fe_exc);
+  test_exceptions (str, ALL_EXC ^ fe_exc, 0);
 }
 
 static void
@@ -193,12 +199,12 @@ fe_tests (void)
   /* clear all exceptions and test if all are cleared */
   feclearexcept (FE_ALL_EXCEPT);
   test_exceptions ("feclearexcept (FE_ALL_EXCEPT) clears all exceptions",
-                   NO_EXC);
+                   NO_EXC, 0);
 
   /* raise all exceptions and test if all are raised */
   feraiseexcept (FE_ALL_EXCEPT);
   test_exceptions ("feraiseexcept (FE_ALL_EXCEPT) raises all exceptions",
-                   ALL_EXC);
+                   ALL_EXC, 0);
   feclearexcept (FE_ALL_EXCEPT);
 
 #ifdef FE_DIVBYZERO
@@ -339,7 +345,7 @@ static void
 initial_tests (void)
 {
   test_exceptions ("Initially all exceptions should be cleared",
-                   NO_EXC);
+                   NO_EXC, 0);
   test_rounding ("Rounding direction should be initalized to nearest",
                  FE_TONEAREST);
 }
index ff0672d..2b01064 100644 (file)
@@ -20,7 +20,7 @@
 #ifndef _SEARCH_H
 #define        _SEARCH_H 1
 
-#include <sys/cdefs.h>
+#include <features.h>
 
 #define __need_size_t
 #define __need_NULL
@@ -28,7 +28,7 @@
 
 __BEGIN_DECLS
 
-#if defined(__USE_SVID) || defined(__USE_XOPEN_EXTENDED)
+#if defined __USE_SVID || defined __USE_XOPEN_EXTENDED
 /* Prototype structure for a linked-list data structure.
    This is the type used by the `insque' and `remque' functions.  */
 
@@ -50,7 +50,7 @@ extern void remque __P ((void *__elem));
 
 /* For use with hsearch(3).  */
 #ifndef __COMPAR_FN_T
-#define __COMPAR_FN_T
+# define __COMPAR_FN_T
 typedef int (*__compar_fn_t) __P ((__const __ptr_t, __const __ptr_t));
 #endif
 
@@ -72,6 +72,23 @@ ENTRY;
 /* Opaque type for internal use.  */
 struct _ENTRY;
 
+/* Family of hash table handling functions.  The functions also
+   have reentrant counterparts ending with _r.  The non-reentrant
+   functions all work on a signle internal hashing table.  */
+
+/* Search for entry matching ITEM.key in internal hash table.  If
+   ACTION is `FIND' return found entry or signal error by returning
+   NULL.  If ACTION is `ENTER' replace existing data (if any) with
+   ITEM.data.  */
+extern ENTRY *hsearch __P ((ENTRY __item, ACTION __action));
+
+/* Create a new hashing table which will at most contain NEL elements.  */
+extern int hcreate __P ((size_t __nel));
+
+/* Destroy current internal hashing table.  */
+extern void hdestroy __P ((void));
+
+#ifdef __USE_GNU
 /* Data type for reentrant functions.  */
 struct hsearch_data
   {
@@ -80,16 +97,13 @@ struct hsearch_data
     unsigned int filled;
   };
 
-/* Family of hash table handling functions.  The functions also have
-   reentrant counterparts ending with _r.  */
-extern ENTRY *hsearch __P ((ENTRY __item, ACTION __action));
-extern int hcreate __P ((size_t __nel));
-extern void hdestroy __P ((void));
-
+/* Reentrant versions which can handle multiple hashing tables at the
+   same time.  */
 extern int hsearch_r __P ((ENTRY __item, ACTION __action, ENTRY **__retval,
                           struct hsearch_data *__htab));
 extern int hcreate_r __P ((size_t __nel, struct hsearch_data *htab));
 extern void hdestroy_r __P ((struct hsearch_data *htab));
+#endif
 
 
 /* The tsearch routines are very interesting. They make many
@@ -108,26 +122,26 @@ VISIT;
 
 /* Search for an entry matching the given KEY in the tree pointed to
    by *ROOTP and insert a new element if not found.  */
-extern void *tsearch __P ((__const void * __key, void **__rootp,
+extern void *tsearch __P ((__const void *__key, void **__rootp,
                           __compar_fn_t compar));
-extern void *__tsearch __P ((__const void * __key, void **__rootp,
+extern void *__tsearch __P ((__const void *__key, void **__rootp,
                             __compar_fn_t compar));
 
 /* Search for an entry matching the given KEY in the tree pointed to
    by *ROOTP.  If no matching entry is available return NULL.  */
-extern void *tfind __P ((__const void * __key, void *__const * __rootp,
+extern void *tfind __P ((__const void *__key, void *__const *__rootp,
                         __compar_fn_t compar));
-extern void *__tfind __P ((__const void * __key, void *__const * __rootp,
+extern void *__tfind __P ((__const void *__key, void *__const *__rootp,
                           __compar_fn_t compar));
 
 /* Remove the element matching KEY from the tree pointed to by *ROOTP.  */
-extern void *tdelete __P ((__const void * __key, void ** __rootp,
+extern void *tdelete __P ((__const void *__key, void **__rootp,
                           __compar_fn_t compar));
-extern void *__tdelete __P ((__const void * __key, void ** __rootp,
+extern void *__tdelete __P ((__const void *__key, void **__rootp,
                             __compar_fn_t compar));
 
 #ifndef __ACTION_FN_T
-#define __ACTION_FN_T
+# define __ACTION_FN_T
 typedef void (*__action_fn_t) __P ((__const void *__nodep,
                                    VISIT __value,
                                    int __level));
@@ -135,9 +149,9 @@ typedef void (*__action_fn_t) __P ((__const void *__nodep,
 
 /* Walk through the whole tree and call the ACTION callback for every node
    or leaf.  */
-extern void twalk __P ((__const void * __root, __action_fn_t action));
+extern void twalk __P ((__const void *__root, __action_fn_t action));
 
-extern void __twalk __P ((__const void * __root, __action_fn_t action));
+extern void __twalk __P ((__const void *__root, __action_fn_t action));
 
 #ifdef __USE_GNU
 /* Callback type for function to free a tree node.  If the keys are atomic
@@ -152,14 +166,14 @@ extern void tdestroy __P ((void *__root, __free_fn_t freefct));
 
 /* Perform linear search for KEY by comparing by COMPAR in an array
    [BASE,BASE+NMEMB*SIZE).  */
-extern void * lfind __P ((__const void *__key, __const void *__base,
-                         size_t *__nmemb, size_t __size,
-                         __compar_fn_t __compar));
+extern void *lfind __P ((__const void *__key, __const void *__base,
+                        size_t *__nmemb, size_t __size,
+                        __compar_fn_t __compar));
 
 /* Perform linear search for KEY by comparing by COMPAR function in
    array [BASE,BASE+NMEMB*SIZE) and insert entry if not found.  */
-extern void * lsearch __P ((__const void *__key, void *__base, size_t *__nmemb,
-                           size_t __size, __compar_fn_t __compar));
+extern void *lsearch __P ((__const void *__key, void *__base, size_t *__nmemb,
+                          size_t __size, __compar_fn_t __compar));
 
 __END_DECLS
 
index 16cf0e8..7dd3e05 100644 (file)
@@ -426,13 +426,13 @@ nss_lookup_function (service_user *ni, const char *fct_name)
            extern void _nss_##h##_get##nm##_r (void);
 # define DEFINE_GETBY(h,nm,ky)                                               \
            extern void _nss_##h##_get##nm##by##ky##_r (void);
-# include "functions.def"
+# include "function.def"
 # undef DEFINE_ENT
 # undef DEFINE_GET
 # undef DEFINE_GETBY
 # define DEFINE_ENT(h,nm)                                                    \
-           { #h"_get"#nm"ent_r", _nss_##h##_get##nm##ent_r },        \
-           { #h"_end"#nm"ent", _nss_##h##_end##nm##ent },            \
+           { #h"_get"#nm"ent_r", _nss_##h##_get##nm##ent_r },                \
+           { #h"_end"#nm"ent", _nss_##h##_end##nm##ent },                    \
            { #h"_set"#nm"ent", _nss_##h##_set##nm##ent },
 # define DEFINE_GET(h,nm)                                                    \
            { #h"_get"#nm"_r", _nss_##h##_get##nm##_r },
@@ -440,7 +440,7 @@ nss_lookup_function (service_user *ni, const char *fct_name)
            { #h"_get"#nm"by"#ky"_r", _nss_##h##_get##nm##by##ky##_r },
            static struct fct_tbl { const char *fname; void *fp; } *tp, tbl[] =
              {
-# include "functions.def"
+# include "function.def"
                { NULL, NULL }
              };
            size_t namlen = (5 + strlen (ni->library->name) + 1
index f2def79..49aea2a 100644 (file)
@@ -123,6 +123,12 @@ static void addrsort __P((char **, int));
 #define        MAXPACKET       1024
 #endif
 
+/* As per RFC 1034 and 1035 a host name cannot exceed 255 octets in length.  */
+#ifdef MAXHOSTNAMELEN
+# undef MAXHOSTNAMELEN
+#endif
+#define MAXHOSTNAMELEN 256
+
 typedef union {
     HEADER hdr;
     u_char buf[MAXPACKET];
index 19ca33e..f772184 100644 (file)
 #else
 # define MAXPACKET     1024
 #endif
+/* As per RFC 1034 and 1035 a host name cannot exceed 255 octets in length.  */
+#ifdef MAXHOSTNAMELEN
+# undef MAXHOSTNAMELEN
+#endif
+#define MAXHOSTNAMELEN 256
 
 static const char AskedForGot[] = "\
 gethostby*.getanswer: asked for \"%s\", got \"%s\"";
index 8eed493..3b895dc 100644 (file)
@@ -22,7 +22,7 @@
 subdir := string
 
 headers        := string.h strings.h memory.h endian.h bits/endian.h \
-          argz.h envz.h
+          argz.h envz.h byteswap.h bits/byteswap.h
 
 routines       := strcat strchr strcmp strcoll strcpy strcspn          \
                   strverscmp strdup strndup                            \
diff --git a/string/byteswap.h b/string/byteswap.h
new file mode 100644 (file)
index 0000000..4a3e680
--- /dev/null
@@ -0,0 +1,40 @@
+/* Copyright (C) 1997 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.  */
+
+#ifndef _BYTESWAP_H
+#define _BYTESWAP_H    1
+
+/* Get the machine specific, optimized definitions.  */
+#include <bits/byteswap.h>
+
+
+/* The following definitions must all be macros since otherwise some
+   of the possible optimizations are not possible.  */
+
+/* Return a value with all bytes in the 16 bit argument swapped.  */
+#define bswap_16(x) __bswap_16 (x)
+
+/* Return a value with all bytes in the 32 bit argument swapped.  */
+#define bswap_32(x) __bswap_32 (x)
+
+#if defined __GNUC__ && __GNUC__ >= 2
+/* Return a value with all bytes in the 64 bit argument swapped.  */
+# define bswap_64(x) __bswap_64 (x)
+#endif
+
+#endif /* byteswap.h */
index 5faf46c..a54e1d5 100644 (file)
@@ -231,7 +231,7 @@ clntudp_call (cl, proc, xargs, argsp, xresults, resultsp, utimeout)
 {
   struct cu_data *cu = (struct cu_data *) cl->cl_private;
   XDR *xdrs;
-  int outlen;
+  int outlen = 0;
   int inlen;
   size_t fromlen;
 #ifdef FD_SETSIZE
index c6e09f1..4308192 100644 (file)
@@ -1,4 +1,4 @@
-/* Copyright (C) 1996 Free Software Foundation, Inc.
+/* Copyright (C) 1996, 1997 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
@@ -18,7 +18,7 @@
 
 #include <sysdep.h>
 
-ENTRY(__htonl)
+ENTRY(htonl)
 #ifdef PROF
        ldgp    gp, 0(pv)
        .set noat
@@ -43,6 +43,4 @@ ENTRY(__htonl)
 
        END(__htonl)
 
-strong_alias_asm(__htonl, __ntohl)
-weak_alias(__htonl, htonl)
-weak_alias(__htonl, ntohl)
+weak_alias(htonl, ntohl)
index 8d3aefe..f65f0e0 100644 (file)
@@ -1,4 +1,4 @@
-/* Copyright (C) 1996 Free Software Foundation, Inc.
+/* Copyright (C) 1996, 1997 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
@@ -18,7 +18,7 @@
 
 #include <sysdep.h>
 
-ENTRY(__htons)
+ENTRY(htons)
 #ifdef PROF
        ldgp    gp, 0(pv)
        .set noat
@@ -37,6 +37,4 @@ ENTRY(__htons)
 
        END(__htons)
 
-strong_alias_asm(__htons, __ntohs)
-weak_alias(__htons, htons)
-weak_alias(__htons, ntohs)
+weak_alias(htons, ntohs)
diff --git a/sysdeps/generic/bits/byteswap.h b/sysdeps/generic/bits/byteswap.h
new file mode 100644 (file)
index 0000000..9404cc4
--- /dev/null
@@ -0,0 +1,43 @@
+/* Macros to swap the order of bytes in integer values.
+   Copyright (C) 1997 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.  */
+
+#ifndef _BITS_BYTESWAP_H
+#define _BITS_BYTESWAP_H       1
+
+/* Swap bytes in 16 bit value.  */
+#define __bswap_16(x) \
+     ((((x) >> 8) & 0xff) | (((x) & 0xff) << 8))
+
+/* Swap bytes in 32 bit value.  */
+#define __bswap_32(x) \
+     ((((x) & 0xff000000) >> 24) | (((x) & 0x00ff0000) >>  8) |                      \
+      (((x) & 0x0000ff00) <<  8) | (((x) & 0x000000ff) << 24))
+
+#if defined __GNUC__ && __GNUC__ >= 2
+/* Swap bytes in 64 bit value.  */
+# define __bswap_64(x) \
+     ({ union { unsigned long long int __ll;                                 \
+               unsigned long int __l[2]; } __v, __r;                         \
+        __v.__ll = (x);                                                              \
+       __r.__l[0] = __bswap_32 (__v.__l[1]);                                 \
+       __r.__l[1] = __bswap_32 (__v.__l[0]);                                 \
+       __r.__ll; })
+#endif
+
+#endif /* bits/byteswap.h */
index d460d40..f433075 100644 (file)
 #include <netinet/in.h>
 
 #undef htonl
+#undef ntohl
 
 u_int32_t
-__htonl (x)
+htonl (x)
      u_int32_t x;
 {
-#if BYTE_ORDER == LITTLE_ENDIAN
-  x = (x << 24) | ((x & 0xff00) << 8) | ((x & 0xff0000) >> 8) | (x >> 24);
-#endif
-
+#if BYTE_ORDER == BIG_ENDIAN
   return x;
+#elif BYTE_ORDER == LITTLE_ENDIAN
+  return __bswap_32 (x);
+#else
+# error "What kind of system is this?"
+#endif
 }
-strong_alias (__htonl, __ntohl)
-weak_alias (__htonl, htonl)
-weak_alias (__ntohl, ntohl)
+weak_alias (htonl, ntohl)
index a0a0e81..8914f74 100644 (file)
 #include <netinet/in.h>
 
 #undef htons
+#undef ntohs
 
 u_int16_t
 __htons (x)
      u_int16_t x;
 {
-#if BYTE_ORDER == LITTLE_ENDIAN
-  x = (x << 8) | (x >> 8);
-#endif
-
+#if BYTE_ORDER == BIG_ENDIAN
   return x;
+#elif BYTE_ORDER == LITTLE_ENDIAN
+  return __bswap_16 (x);
+#else
+# error "What kind of system is this?"
+#endif
 }
-strong_alias (__htons, __ntohs)
-weak_alias (__htons, htons)
-weak_alias (__ntohs, ntohs)
+weak_alias (htons, ntohs)
diff --git a/sysdeps/i386/bits/byteswap.h b/sysdeps/i386/bits/byteswap.h
new file mode 100644 (file)
index 0000000..326962e
--- /dev/null
@@ -0,0 +1,92 @@
+/* Macros to swap the order of bytes in integer values.
+   Copyright (C) 1997 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.  */
+
+#ifndef _BITS_BYTESWAP_H
+#define _BITS_BYTESWAP_H       1
+
+/* Swap bytes in 16 bit value.  */
+#define __bswap_constant_16(x) \
+     ((((x) >> 8) & 0xff) | (((x) & 0xff) << 8))
+
+#if defined __GNUC__ && __GNUC__ >= 2
+# define __bswap_16(x) \
+     ({ register unsigned short int __v;                                     \
+       if (__builtin_constant_p (x))                                         \
+         __v = __bswap_constant_16 (x);                                      \
+       else                                                                  \
+         __asm__ __volatile__ ("rorw $8, %w0"                                \
+                               : "=q" (__v)                                  \
+                               : "0" ((unsigned short int) (x))              \
+                               : "cc");                                      \
+       __v; })
+#else
+/* This is better than nothing.  */
+# define __bswap_16(x) __bswap_constant_16 (x)
+#endif
+
+
+/* Swap bytes in 32 bit value.  */
+#define __bswap_constant_32(x) \
+     ((((x) & 0xff000000) >> 24) | (((x) & 0x00ff0000) >>  8) |                      \
+      (((x) & 0x0000ff00) <<  8) | (((x) & 0x000000ff) << 24))
+
+#if defined __GNUC__ && __GNUC__ >= 2
+/* To swap the bytes in a word the i486 processors and up provide the
+   `bswap' opcode.  On i386 we have to use three instructions.  */
+# if !defined __i486__ && !defined __pentium__ && !defined __pentiumpro__
+#  define __bswap_32(x) \
+     ({ register unsigned int __v;                                           \
+       if (__builtin_constant_p (x))                                         \
+         __v = __bswap_constant_32 (x);                                      \
+       else                                                                  \
+         __asm__ __volatile__ ("rorw $8, %w0;"                               \
+                               "rorl $16, %0;"                               \
+                               "rorw $8, %w0"                                \
+                               : "=q" (__v)                                  \
+                               : "0" ((unsigned int) (x))                    \
+                               : "cc");                                      \
+       __v; })
+# else
+#  define __bswap_32(x) \
+     ({ register unsigned int __v;                                           \
+       if (__builtin_constant_p (x))                                         \
+         __v = __bswap_constant_32 (x);                                      \
+       else                                                                  \
+         __asm__ __volatile__ ("bswap %0"                                    \
+                               : "=r" (__v)                                  \
+                               : "0" ((unsigned int) (x)));                  \
+       __v; })
+# endif
+#else
+# define __bswap_32(x) __bswap_constant_32 (x)
+#endif
+
+
+#if defined __GNUC__ && __GNUC__ >= 2
+/* Swap bytes in 64 bit value.  */
+# define __bswap_64(x) \
+     ({ union { unsigned long long int __ll;                                 \
+               unsigned long int __l[2]; } __v, __r;                         \
+        __v.__ll = (x);                                                              \
+       __r.__l[0] = __bswap_32 (__v.__l[1]);                                 \
+       __r.__l[1] = __bswap_32 (__v.__l[0]);                                 \
+       __r.__ll; })
+#endif
+
+#endif /* bits/byteswap.h */
diff --git a/sysdeps/i386/bits/htontoh.h b/sysdeps/i386/bits/htontoh.h
deleted file mode 100644 (file)
index 590b509..0000000
+++ /dev/null
@@ -1,79 +0,0 @@
-/* Copyright (C) 1997 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.  */
-
-#ifndef _NETINET_IN_H
-# error "Don't include this file directly, use <netinet/in.h>"
-#endif
-
-#if defined __GNUC__ && __GNUC__ >= 2
-/* We can use inline assembler instructions to optimize the code.  */
-
-/* To swap the bytes in a word the i486 processors and up provide the
-   `bswap' opcode.  On i386 we have to use three instructions.  */
-# if !defined __i486__ && !defined __pentium__ && !defined __pentiumpro__
-
-extern __inline u_int32_t
-__ntohl (u_int32_t netlong)
-{
-  register u_int32_t hostlong;
-
-  __asm__ ("rorw $8, %w0; rorl $16, %0; rorw $8, %w0"
-          : "=r" (hostlong)
-          : "0" (netlong));
-
-  return hostlong;
-}
-
-# else
-
-extern __inline u_int32_t
-__ntohl (u_int32_t netlong)
-{
-  register u_int32_t hostlong;
-
-  __asm__ ("bswap %0" : "=r" (hostlong) : "0" (netlong));
-
-  return hostlong;
-}
-
-# endif
-
-/* For a short word we have a simple solution.  */
-extern __inline u_int16_t
-__ntohs (u_int16_t netshort)
-{
-  register u_int16_t hostshort;
-
-  __asm__ ("rorw $8, %w0" : "=r" (hostshort) : "0" (netshort));
-}
-
-
-/* The other direction can be handled with the same functions.  */
-extern __inline u_int32_t
-__htonl (u_int32_t hostlong)
-{
-  return __ntohl (hostlong);
-}
-
-extern __inline u_int16_t
-__htons (u_int16_t hostshort)
-{
-  return __ntohs (hostshort);
-}
-
-#endif /* GNU CC */
index 73dd1e9..9c87be6 100644 (file)
 */
 
        .text
-ENTRY (__htonl)
+ENTRY (htonl)
        movl    4(%esp), %eax
        rorw    $8, %ax
        rorl    $16, %eax
        rorw    $8, %ax
        ret
-END (__htonl)
+END (htonl)
 
-strong_alias (__htonl, __ntohl)
-weak_alias (__htonl, htonl)
-weak_alias (__ntohl, ntohl)
+weak_alias (htonl, ntohl)
index 5d0f59c..b0539c5 100644 (file)
 */
 
        .text
-ENTRY (__htons)
+ENTRY (htons)
        movl    4(%esp), %eax
        andl    $0xffff, %eax
        rorw    $8, %ax
        ret
-END (__htons)
+END (htons)
 
-strong_alias (__htons, __ntohs)
-weak_alias (__htons, htons)
-weak_alias (__ntohs, ntohs)
+weak_alias (htons, ntohs)
index cf3a94f..a61b339 100644 (file)
 */
 
        .text
-ENTRY (__htonl)
+ENTRY (htonl)
        movl    4(%esp), %eax
        bswap   %eax
        ret
-END (__htonl)
+END (htonl)
 
-strong_alias (__htonl, __ntohl)
-weak_alias (__htonl, htonl)
-weak_alias (__ntohl, ntohl)
+weak_alias (htonl, ntohl)
index d509604..bc49c9c 100644 (file)
@@ -48,43 +48,17 @@ feraiseexcept (int excepts)
   /* Next: overflow.  */
   if (excepts & FE_OVERFLOW)
     {
-      /* We cannot raise the overflow exception without also setting the
-        inexact flag.  Restore it after the operation, unless it should
-        be set anyway.  */
       long double d = LDBL_MAX;
-      fexcept_t fpsr;
 
-      __asm__ ("fmove%.l %/fpsr,%0" : "=dm" (fpsr));
-      __asm__ __volatile__ ("fmul%.x %0,%0" : "=f" (d) : "0" (d));
-      if (!((excepts | fpsr) & FE_INEXACT))
-       {
-         __asm__ ("fmove%.l %/fpsr,%0" : "=dm" (fpsr));
-         fpsr &= ~FE_INEXACT;
-         __asm__ __volatile__ ("fmove%.l %0,%/fpsr" : : "dm" (fpsr));
-       }
-      else
-       __asm__ ("fnop");
+      __asm__ __volatile__ ("fmul%.x %0,%0; fnop" : "=f" (d) : "0" (d));
     }
 
   /* Next: underflow.  */
   if (excepts & FE_UNDERFLOW)
     {
-      /* We cannot raise the underflow exception without also setting the
-        inexact flag.  Restore it after the operation, unless it should
-        be set anyway.  */
       long double d = -LDBL_MAX;
-      fexcept_t fpsr;
 
-      __asm__ ("fmove%.l %/fpsr,%0" : "=dm" (fpsr));
-      __asm__ __volatile__ ("fetox%.x %0" : "=f" (d) : "0" (d));
-      if (!((excepts | fpsr) & FE_INEXACT))
-       {
-         __asm__ ("fmove%.l %/fpsr,%0" : "=dm" (fpsr));
-         fpsr &= ~FE_INEXACT;
-         __asm__ __volatile__ ("fmove%.l %0,%/fpsr" : : "dm" (fpsr));
-       }
-      else
-       __asm__ ("fnop");
+      __asm__ __volatile__ ("fetox%.x %0; fnop" : "=f" (d) : "0" (d));
     }
 
   /* Last: inexact.  */
index 08bc0ba..97fb1dc 100644 (file)
@@ -26,9 +26,7 @@
 
 #define DO_CALL(syscall_name, args)                                          \
   lea SYS_ify (syscall_name), %eax;                                          \
-  /* lcall $7, $0; */                                                        \
-  /* Above loses; GAS bug.  */                                               \
-  .byte 0x9a, 0, 0, 0, 0, 7, 0
+  lcall $7, $0
 
 #define        r0              %eax    /* Normal return-value register.  */
 #define        r1              %edx    /* Secondary return-value register.  */
index 9272c06..bdc333a 100644 (file)
@@ -30,6 +30,7 @@ netipx/ipx.h
 nfs/nfs.h
 sys/acct.h
 sys/debugreg.h
+sys/fsuid.h
 sys/io.h
 sys/kd.h
 sys/kdaemon.h
index 1c5da4b..ed9ae87 100644 (file)
@@ -11,7 +11,7 @@ sysdep_headers += sys/mount.h sys/acct.h sys/sysctl.h sys/mtio.h \
                  sys/module.h sys/io.h sys/klog.h sys/kdaemon.h \
                  sys/user.h sys/sysmacros.h sys/procfs.h \
                  sys/debugreg.h sys/kd.h sys/soundcard.h sys/vt.h \
-                 sys/quota.h
+                 sys/quota.h sys/fsuid.h
 
 install-others += $(inst_includedir)/bits/syscall.h
 
similarity index 69%
rename from sysdeps/generic/bits/htontoh.h
rename to sysdeps/unix/sysv/linux/sys/fsuid.h
index fa4efed..8185b95 100644 (file)
    write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
    Boston, MA 02111-1307, USA.  */
 
-#ifndef _NETINET_IN_H
-# error "Don't include this file directly, use <netinet/in.h>"
-#endif
+#ifndef _SYS_FSUID_H
+#define _SYS_FSUID_H   1
 
-/* We cannot give generic optimized versions here.  */
+#include <features.h>
+#include <gnu/types.h>
+
+__BEGIN_DECLS
+
+/* Change uid used for file access control to UID, without affecting
+   other priveledges (such as who can send signals at the process).  */
+extern int setfsuid __P ((__uid_t __uid));
+
+/* Ditto for group id. */
+extern int setfsgid __P ((__gid_t __gid));
+
+__END_DECLS
+
+#endif /* fsuid.h */
index 93e13ea..ba39986 100644 (file)
 
 #include "DEFS.h"
 
-ENTRY(__htonl, 0)
+ENTRY(htonl, 0)
        rotl    $-8,4(ap),r0
        insv    r0,$16,$8,r0
        movb    7(ap),r0
        ret
-strong_alias (__htonl, __ntohl)
-weak_alias (__htonl, htonl)
-weak_alias (__ntohl, ntohl)
+weak_alias (htonl, ntohl)
index 16964c2..1e781a1 100644 (file)
@@ -28,6 +28,4 @@ ENTRY(htons, 0)
        movb    5(ap),r0
        movzwl  r0,r0
        ret
-strong_alias (__htons, __ntohs)
-weak_alias (__htons, htons)
-weak_alias (__ntohs, ntohs)
+weak_alias (htons, ntohs)