update from main archive 961008
authordrepper <drepper>
Tue, 8 Oct 1996 23:36:37 +0000 (23:36 +0000)
committerdrepper <drepper>
Tue, 8 Oct 1996 23:36:37 +0000 (23:36 +0000)
db/makedb.c
elf/dl-open.c
gmon/gmon.c
inet/getnetgrent_r.c
inet/netgroup.h
io/test-utime.c
libio/iofgets.c
locale/programs/xmalloc.c

index d30ca2c..eb17a22 100644 (file)
@@ -52,6 +52,7 @@ static void usage __P ((int status)) __attribute__ ((noreturn));
 static int process_input __P ((FILE *input, const char *inname, DB *output,
                               int to_lowercase, int be_quiet));
 static int print_database __P ((DB *db));
+int main __P ((int argc, char *argv[]));
 
 
 int
index 6b8b218..25f2ba6 100644 (file)
@@ -23,7 +23,11 @@ Cambridge, MA 02139, USA.  */
 #include <errno.h>
 
 
-weak_extern (_DYNAMIC)
+extern ElfW(Addr) _dl_sysdep_start (void **start_argptr,
+                                   void (*dl_main) (const ElfW(Phdr) *phdr,
+                                                    ElfW(Word) phnum,
+                                                    ElfW(Addr) *user_entry));
+weak_extern (_dl_sysdep_start)
 
 extern int __libc_multiple_libcs;      /* Defined in init-first.c.  */
 
@@ -141,7 +145,7 @@ _dl_open (const char *file, int mode)
     (*(void (*) (int, char **, char **)) init) (__libc_argc, __libc_argv,
                                                __environ);
 
-  if (_DYNAMIC == NULL)
+  if (_dl_sysdep_start == NULL)
     /* We must be the static _dl_open in libc.a.  A static program that
        has loaded a dynamic object now has competition.  */
     __libc_multiple_libcs = 1;
index 00b5df5..6dc4cb5 100644 (file)
@@ -58,6 +58,11 @@ static int   s_scale;
 
 #define ERR(s) write(2, s, sizeof(s) - 1)
 
+void moncontrol __P ((int mode));
+static void write_hist __P ((int fd));
+static void write_call_graph __P ((int fd));
+static void write_bb_counts __P ((int fd));
+
 /*
  * Control profiling
  *     profiling is what mcount checks to see if
index 52a90d0..ff6d539 100644 (file)
@@ -31,6 +31,16 @@ static service_user *nip;
 /* Remember the first service_entry, it's always the same.  */
 static service_user *startp;
 
+/* A netgroup can consist of names of other netgroups.  We have to
+   track which netgroups were read and which still have to be read.  */
+struct name_list
+{
+  const char *name;
+  struct name_list *next;
+};
+struct name_list *known_groups;
+struct name_list *needed_groups;
+
 
 /* The lookup function for the first entry of this service.  */
 extern int __nss_netgroup_lookup (service_user **nip, const char *name,
@@ -62,30 +72,79 @@ setup (void **fctp, const char *func_name, int all)
   return no_more;
 }
 \f
-int
-setnetgrent (const char *group)
+/* Free used memory.  */
+static void
+free_memory (void)
+{
+  while (known_groups != NULL)
+    {
+      struct name_list *tmp = known_groups;
+      known_groups = known_groups->next;
+      free (tmp->name);
+      free (tmp);
+    }
+
+  while (needed_groups != NULL)
+    {
+      struct name_list *tmp = needed_groups;
+      needed_groups = needed_groups->next;
+      free (tmp->name);
+      free (tmp);
+    }
+}
+\f
+static int
+internal_setnetgrent (const char *group)
 {
   enum nss_status (*fct) (const char *);
   enum nss_status status = NSS_STATUS_UNAVAIL;
+  struct name_list *new_elem;
   int no_more;
 
-  __libc_lock_lock (lock);
-
   /* Cycle through all the services and run their setnetgrent functions.  */
   no_more = setup ((void **) &fct, "setnetgrent", 1);
   while (! no_more)
     {
-      /* Ignore status, we force check in __NSS_NEXT.  */
+      /* Ignore status, we force check in `__nss_next'.  */
       status = (*fct) (group);
 
       no_more = __nss_next (&nip, "setnetgrent", (void **) &fct, status, 0);
     }
 
-  __libc_lock_unlock (lock);
+  /* Add the current group to the list of known groups.  */
+  new_elem = (struct name_list *) malloc (sizeof (struct name_list));
+  if (new_elem == NULL || (new_elem->name = strdup (group)) == NULL)
+    {
+      if (new_elem != NULL)
+       free (new_elem);
+      status == NSS_STATUS_UNAVAIL;
+    }
+  else
+    {
+      new_elem->next = known_groups;
+      known_groups = new_elem;
+    }
 
   return status == NSS_STATUS_SUCCESS;
 }
 
+int
+setnetgrent (const char *group)
+{
+  int result;
+
+  __libc_lock_lock (lock);
+
+  /* Free list of all netgroup names from last run.  */
+  free_memory ();
+
+  result = internal_setnetgrent (group);
+
+  __libc_lock_unlock (lock);
+
+  return result;
+}
+
 
 void
 endnetgrent (void)
@@ -103,13 +162,16 @@ endnetgrent (void)
   no_more = setup ((void **) &fct, "endnetgrent", 1);
   while (! no_more)
     {
-      /* Ignore status, we force check in __NSS_NEXT.  */
+      /* Ignore status, we force check in `__nss_next'.  */
       (void) (*fct) ();
 
       no_more = (nip == old_nip
                 || __nss_next (&nip, "endnetgrent", (void **) &fct, 0, 1));
     }
 
+  /* Now free list of all netgroup names from last run.  */
+  free_memory ();
+
   __libc_lock_unlock (lock);
 }
 
@@ -135,14 +197,63 @@ __getnetgrent_r (char **hostp, char **userp, char **domainp,
     {
       status = (*fct) (&result, buffer, buflen);
 
+      if (status == NSS_STATUS_RETURN)
+       {
+         /* This was the last one for this group.  Look at next group
+            if available.  */
+         int found = 0;
+         while (needed_groups != NULL && ! found)
+           {
+             struct name_list *tmp = needed_groups;
+             needed_groups = needed_groups->next;
+             tmp->next = known_groups;
+             known_groups = tmp;
+
+             found = internal_setnetgrent (known_groups->name);
+           }
+
+         if (found)
+           continue;
+       }
+      else if (status == NSS_STATUS_SUCCESS && result.type == group_val)
+       {
+         /* The last entry was a name of another netgroup.  */
+         struct name_list *namep;
+
+         /* Ignore if we've seen the name before.  */
+         for (namep = known_groups; namep != NULL; namep = namep->next)
+           if (strcmp (result.val.group, namep->name) == 0)
+             break;
+         if (namep != NULL)
+           /* Really ignore.  */
+           continue;
+
+         namep = (struct name_list *) malloc (sizeof (struct name_list));
+         if (namep == NULL
+             || (namep->name = strdup (result.val.group)) == NULL)
+           {
+             /* We are out of memory.  */
+             if (namep != NULL)
+               free (namep);
+             status = NSS_STATUS_RETURN;
+           }
+         else
+           {
+             namep->next = needed_groups;
+             needed_groups = namep;
+             /* And get the next entry.  */
+             continue;
+           }
+       }
+
       no_more = __nss_next (&nip, "getnetgrent_r", (void **) &fct, status, 0);
     }
 
   if (status == NSS_STATUS_SUCCESS)
     {
-      *hostp = result.host;
-      *userp = result.user;
-      *domainp = result.domain;
+      *hostp = result.val.triple.host;
+      *userp = result.val.triple.user;
+      *domainp = result.val.triple.domain;
     }
 
   __libc_lock_unlock (lock);
@@ -161,6 +272,10 @@ innetgr (const char *netgroup, const char *host, const char *user,
   int (*getfct) (struct __netgrent *, char *, int);
   int result = 0;
   int no_more;
+  struct name_list *known = NULL;
+  struct name_list *needed = NULL;
+  const char *current_group = netgroup;
+  int real_entry = 0;
 
   __libc_lock_lock (lock);
 
@@ -168,51 +283,117 @@ innetgr (const char *netgroup, const char *host, const char *user,
      not work further.  We can do some optimization here.  Since all
      services must provide the `setnetgrent' function we can do all
      the work during one walk through the service list.  */
-  no_more = setup ((void **) &setfct, "setnetgrent", 1);
-  while (! no_more)
+  while (1)
     {
-      enum nss_status status;
-
-      /* Open netgroup.  */
-      status = (*setfct) (netgroup);
-      if (status == NSS_STATUS_SUCCESS
-         && __nss_lookup (&nip, "getnetgrent_r", (void **) &getfct) == 0)
+      no_more = setup ((void **) &setfct, "setnetgrent", 1);
+      while (! no_more)
        {
-         char buffer[1024];
-         struct __netgrent entry;
+         enum nss_status status;
 
-         while ((*getfct) (&entry, buffer, sizeof buffer)
-                == NSS_STATUS_SUCCESS)
+         /* Open netgroup.  */
+         status = (*setfct) (current_group);
+         if (status == NSS_STATUS_SUCCESS
+             && __nss_lookup (&nip, "getnetgrent_r", (void **) &getfct) == 0)
            {
-             if ((entry.host == NULL || host == NULL
-                  || strcmp (entry.host, host) == 0)
-                 && (entry.user == NULL || user == NULL
-                     || strcmp (entry.user, user) == 0)
-                 && (entry.domain == NULL || domain == NULL
-                     || strcmp (entry.domain, domain) == 0))
+             char buffer[1024];
+             struct __netgrent entry;
+
+             while ((*getfct) (&entry, buffer, sizeof buffer)
+                    == NSS_STATUS_SUCCESS)
                {
-                 result = 1;
-                 break;
+                 if (entry.type == group_val)
+                   {
+                     /* Make sure we haven't seen the name before.  */
+                     struct name_list *namep;
+
+                     for (namep = known; namep != NULL; namep = namep->next)
+                       if (strcmp (entry.val.group, namep->name) == 0)
+                         break;
+                     if (namep == NULL
+                         && strcmp (netgroup, entry.val.group) != 0)
+                       {
+                         namep =
+                           (struct name_list *) malloc (sizeof (*namep));
+                         if (namep == NULL
+                             || ((namep->name = strdup (entry.val.group))
+                                 == NULL))
+                           {
+                             /* Out of memory, simply return.  */
+                             if (namep != NULL)
+                               free (namep);
+                             result = -1;
+                             break;
+                           }
+
+                         namep->next = needed;
+                         needed = namep;
+                       }
+                   }
+                 else
+                   {
+                     real_entry = 1;
+
+                     if ((entry.val.triple.host == NULL || host == NULL
+                          || strcmp (entry.val.triple.host, host) == 0)
+                         && (entry.val.triple.user == NULL || user == NULL
+                             || strcmp (entry.val.triple.user, user) == 0)
+                         && (entry.val.triple.domain == NULL || domain == NULL
+                             || strcmp (entry.val.triple.domain, domain) == 0))
+                       {
+                         result = 1;
+                         break;
+                       }
+                   }
                }
+
+             if (result != 0)
+               break;
+
+             /* If we found one service which does know the given
+                netgroup we don't try further.  */
+             status = NSS_STATUS_RETURN;
            }
 
-         if (result != 0)
-           break;
+         /* Free all resources of the service.  */
+         if (__nss_lookup (&nip, "endnetgrent", (void **) &endfct) == 0)
+           (*endfct) ();
 
-         /* If we found one service which does know the given
-            netgroup we don't try further.  */
-         status = NSS_STATUS_RETURN;
+         /* Look for the next service.  */
+         no_more = __nss_next (&nip, "setnetgrent",
+                               (void **) &setfct, status, 0);
        }
 
-      /* Free all resources of the service.  */
-      if (__nss_lookup (&nip, "endnetgrent", (void **) &endfct) == 0)
-       (*endfct) ();
+      if (result == 0 && needed != NULL)
+       {
+         struct name_list *tmp = needed;
+         needed = tmp->next;
+         tmp->next = known;
+         known = tmp;
+         current_group = known->name;
+         continue;
+       }
 
-      /* Look for the next service.  */
-      no_more = __nss_next (&nip, "setnetgrent", (void **) &setfct, status, 0);
+      /* No way out.  */
+      break;
     }
 
   __libc_lock_unlock (lock);
 
-  return result;
+  /* Free the memory.  */
+  while (known != NULL)
+    {
+      struct name_list *tmp = known;
+      known = known->next;
+      free (tmp->name);
+      free (tmp);
+    }
+  while (needed != NULL)
+    {
+      struct name_list *tmp = needed;
+      needed = needed->next;
+      free (tmp->name);
+      free (tmp);
+    }
+
+  return result == 1;
 }
index e8ea51e..746cd9e 100644 (file)
@@ -22,9 +22,20 @@ Boston, MA 02111-1307, USA.  */
 
 struct __netgrent
 {
-  const char *host;
-  const char *user;
-  const char *domain;
+  enum { triple_val, group_val } type;
+
+  union
+  {
+    struct
+    {
+      const char *host;
+      const char *user;
+      const char *domain;
+    }
+    triple;
+
+    const char *group;
+  } val;
 };
 
 #endif /* netgroup.h */
index ef5ab97..e285141 100644 (file)
@@ -16,10 +16,11 @@ License along with the GNU C Library; see the file COPYING.LIB.  If
 not, write to the Free Software Foundation, Inc., 675 Mass Ave,
 Cambridge, MA 02139, USA.  */
 
-#include <utime.h>
+#include <fcntl.h>
 #include <stdio.h>
 #include <sys/stat.h>
 #include <unistd.h>
+#include <utime.h>
 
 int
 main (int argc, char *argv[])
index 71d677c..79ba1a9 100644 (file)
@@ -37,7 +37,7 @@ _IO_fgets (buf, n, fp)
   if (n <= 0)
     return NULL;
   __libc_cleanup_region_start ((void (*) __P ((void *))) _IO_funlockfile, fp);
-  __flockfile (fp);
+  _IO_flockfile (fp);
   count = _IO_getline (fp, buf, n - 1, '\n', 1);
   if (count == 0 || (fp->_IO_file_flags & _IO_ERR_SEEN))
     result = NULL;
index 2680b8a..0a10fbc 100644 (file)
@@ -1,5 +1,5 @@
 /* xmalloc.c -- malloc with out of memory checking
-   Copyright (C) 1990, 91, 92, 93, 94, 95 Free Software Foundation, Inc.
+   Copyright (C) 1990, 91, 92, 93, 94, 95, 96 Free Software Foundation, Inc.
 
    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
@@ -29,6 +29,7 @@
 
 #if STDC_HEADERS || _LIBC
 #include <stdlib.h>
+static VOID *fixup_null_alloc __P ((size_t n));
 #else
 VOID *calloc ();
 VOID *malloc ();