commit-hurd
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[hurd] 01/02: New upstream snapshot


From: Samuel Thibault
Subject: [hurd] 01/02: New upstream snapshot
Date: Sun, 05 Jul 2015 00:41:58 +0000

This is an automated email from the git hooks/post-receive script.

sthibault pushed a commit to branch master
in repository hurd.

commit 3a90599b4f8cabb3b86e6cb1fd3f9531ffb823a5
Author: Samuel Thibault <address@hidden>
Date:   Sat Jul 4 21:35:18 2015 +0000

    New upstream snapshot
---
 configure.ac                          |   8 +
 console-client/timer.h                |   2 +-
 console-client/xkb/kstoucs.c          |  41 ++--
 libdde-linux26/include/linux/device.h |   5 +-
 libdde-linux26/lib/src/arch/l4/pci.c  |   2 +-
 libdiskfs/io-reauthenticate.c         |   3 +
 libdiskfs/node-cache.c                |   1 -
 libnetfs/io-reauthenticate.c          |   3 +
 libps/fmt.c                           |  15 ++
 pfinet/io-ops.c                       |   3 +
 trans/fakeroot.c                      |  10 +-
 utils/Makefile                        |  12 +-
 utils/msgids.c                        | 252 +++++++++++++++++++++
 utils/msgids.h                        |  33 +++
 utils/rpcscan.c                       | 404 ++++++++++++++++++++++++++++++++++
 utils/rpctrace.c                      | 202 +----------------
 utils/vmstat.c                        |   3 +-
 17 files changed, 772 insertions(+), 227 deletions(-)

diff --git a/configure.ac b/configure.ac
index 71f3a0e..b03057b 100644
--- a/configure.ac
+++ b/configure.ac
@@ -292,6 +292,14 @@ PKG_CHECK_MODULES([X11], [x11 xproto],
        have_x11=no])
   ], [have_x11=no])
 ])
+
+AS_IF([test "$have_x11" = "yes"],
+  [AC_MSG_CHECKING([whether AWK is usable])
+   AS_IF([test "$AWK" != ":" && $AWK 'BEGIN { strtonum("1"); }' 2>/dev/null],
+     [AC_MSG_RESULT([yes])],
+     [AC_MSG_RESULT([no])
+      AC_MSG_ERROR([$AWK does not provide required strtonum function])])])
+
 AC_SUBST([have_x11])
 AC_SUBST([XKB_BASE])
 AC_DEFINE_UNQUOTED([X11_PREFIX], "$X11_PREFIX")
diff --git a/console-client/timer.h b/console-client/timer.h
index 4204192..8a923ad 100644
--- a/console-client/timer.h
+++ b/console-client/timer.h
@@ -54,7 +54,7 @@ int timer_remove (struct timer_list *timer);
 /* Change the expiration time of the timer TIMER to EXPIRES.  */
 void timer_change (struct timer_list *timer, long long expires);
 
-extern inline long long
+static inline long long
 fetch_jiffies ()
 {
   extern volatile struct mapped_time_value *timer_mapped_time;
diff --git a/console-client/xkb/kstoucs.c b/console-client/xkb/kstoucs.c
index 0211e9e..eb47bde 100644
--- a/console-client/xkb/kstoucs.c
+++ b/console-client/xkb/kstoucs.c
@@ -1,3 +1,5 @@
+#include <assert.h>
+
 struct ksmap {
   int keysym;
   unsigned int ucs;
@@ -5,6 +7,28 @@ struct ksmap {
 
 #include "kstoucs_map.c"
 
+/* Binary search through `kstoucs_map'.  */
+static unsigned int
+find_ucs (int keysym, struct ksmap *first, struct ksmap *last)
+{
+  struct ksmap *middle = first + (last - first) / 2;
+
+  assert (first <= last);
+
+  if (middle->keysym == keysym)
+    return middle->ucs; /* base case: needle found. */
+  else if (first == last) /* empty search space */
+    return 0;
+  /* recursive cases: halve search space. */
+  else if (middle->keysym < keysym)
+    return find_ucs (keysym, middle+1, last);
+  else if (middle->keysym > keysym)
+    /* don't remove middle from the range to compensate
+       for rounding down in it's calculation */
+    return find_ucs (keysym, first, middle);
+  return 0;
+}
+
 unsigned int
 KeySymToUcs4 (int keysym)
 {
@@ -23,23 +47,6 @@ unsigned int doit (int keysym)
   if ((keysym & 0xff000000) == 0x01000000)
     return (keysym & 0x00ffffff);
 
-  unsigned int
-  find_ucs (int keysym, struct ksmap *first, struct ksmap *last)
-  {
-    struct ksmap *middle = first + (last - first) / 2;
-
-    if (middle->keysym == keysym)
-      return middle->ucs; /* base case: needle found. */
-    else if (middle == first && middle == last)
-      return 0; /* base case: empty search space. */
-    /* recursive cases: halve search space. */
-    else if (middle->keysym < keysym)
-      return find_ucs (keysym, middle+1, last);
-    else if (middle->keysym > keysym)
-      return find_ucs (keysym, first, middle-1);
-    return 0;
-  }
-
   #define NUM_KEYSYMS (sizeof kstoucs_map / sizeof(struct ksmap))
   return find_ucs(keysym, &kstoucs_map[0], &kstoucs_map[NUM_KEYSYMS - 1]);
 #ifdef XKB_DEBUG
diff --git a/libdde-linux26/include/linux/device.h 
b/libdde-linux26/include/linux/device.h
index 41b4227..3dc6e94 100644
--- a/libdde-linux26/include/linux/device.h
+++ b/libdde-linux26/include/linux/device.h
@@ -553,7 +553,10 @@ extern const char *dev_driver_string(const struct device 
*dev);
        printk(level "%s %s: " format , dev_driver_string(dev) , \
               dev_name(dev) , ## arg)
 #else
-#define dev_printk(level, dev, format, arg...) 
+#include <stdio.h>
+#define dev_printk(level, dev, format, arg...)                 \
+       fprintf(stderr, level "%s %s: " format,                 \
+              dev_driver_string(dev), dev_name(dev), ## arg)
 #endif
 
 #define dev_emerg(dev, format, arg...)         \
diff --git a/libdde-linux26/lib/src/arch/l4/pci.c 
b/libdde-linux26/lib/src/arch/l4/pci.c
index b50a735..6dd8e87 100644
--- a/libdde-linux26/lib/src/arch/l4/pci.c
+++ b/libdde-linux26/lib/src/arch/l4/pci.c
@@ -171,7 +171,7 @@ int pcibios_enable_device(struct pci_dev *dev, int mask)
        return pcibios_enable_irq(dev);
 #endif
        WARN_UNIMPL;
-       return -1;
+       return 0;
 }
 
 
/*******************************************************************************************
diff --git a/libdiskfs/io-reauthenticate.c b/libdiskfs/io-reauthenticate.c
index 649315f..985db49 100644
--- a/libdiskfs/io-reauthenticate.c
+++ b/libdiskfs/io-reauthenticate.c
@@ -49,8 +49,11 @@ diskfs_S_io_reauthenticate (struct protid *cred,
   newright = ports_get_send_right (newcred);
   assert (newright != MACH_PORT_NULL);
 
+  /* Release the node lock while blocking on the auth server and client.  */
+  pthread_mutex_unlock (&cred->po->np->lock);
   err = iohelp_reauth (&user, diskfs_auth_server_port, rend_port,
                       newright, 1);
+  pthread_mutex_lock (&cred->po->np->lock);
   if (! err)
     {
       diskfs_finish_protid (newcred, user);
diff --git a/libdiskfs/node-cache.c b/libdiskfs/node-cache.c
index 6b70da8..a76474a 100644
--- a/libdiskfs/node-cache.c
+++ b/libdiskfs/node-cache.c
@@ -199,7 +199,6 @@ diskfs_node_iterate (error_t (*fun)(struct node *))
   if (node_list == NULL)
     {
       pthread_rwlock_unlock (&nodecache_lock);
-      error (0, 0, "unable to allocate temporary node table");
       return ENOMEM;
     }
 
diff --git a/libnetfs/io-reauthenticate.c b/libnetfs/io-reauthenticate.c
index 1d2d935..f4f50d5 100644
--- a/libnetfs/io-reauthenticate.c
+++ b/libnetfs/io-reauthenticate.c
@@ -37,8 +37,11 @@ netfs_S_io_reauthenticate (struct protid *user, mach_port_t 
rend_port)
   newright = ports_get_send_right (newpi);
   assert (newright != MACH_PORT_NULL);
 
+  /* Release the node lock while blocking on the auth server and client.  */
+  pthread_mutex_unlock (&user->po->np->lock);
   err = iohelp_reauth (&newpi->user, netfs_auth_server_port, rend_port,
                       newright, 1);
+  pthread_mutex_lock (&user->po->np->lock);
 
   mach_port_deallocate (mach_task_self (), rend_port);
   mach_port_deallocate (mach_task_self (), newright);
diff --git a/libps/fmt.c b/libps/fmt.c
index 0465555..580b097 100644
--- a/libps/fmt.c
+++ b/libps/fmt.c
@@ -68,6 +68,8 @@ _fmt_create (char *src, int posix, struct ps_fmt_specs 
*fmt_specs,
   src = new_fmt->src;
   while (*src != '\0')
     {
+      char *start = src;
+
       if (field - fields == fields_alloced)
        /* Time to grow FIELDS to make room for more.  */
        {
@@ -172,6 +174,19 @@ _fmt_create (char *src, int posix, struct ps_fmt_specs 
*fmt_specs,
            /* This field spec doesn't have a name, so use its flags fields
               to set the global ones, and skip it.  */
            {
+             /* if we didn't use any chars, don't loop indefinitely */
+             if (src == start)
+               {
+                 if (err_string)
+                   asprintf (err_string, "%s: Unknown format spec", src);
+
+                 FREE (new_fmt->src);
+                 FREE (new_fmt);
+                 FREE (fields);
+
+                 return EINVAL;
+               }
+
              global_clr_flags = clr_flags;
              global_inv_flags = inv_flags;
              continue;
diff --git a/pfinet/io-ops.c b/pfinet/io-ops.c
index cc666cd..742d64f 100644
--- a/pfinet/io-ops.c
+++ b/pfinet/io-ops.c
@@ -379,6 +379,8 @@ S_io_reauthenticate (struct sock_user *user,
   auth = getauth ();
   newright = ports_get_send_right (newuser);
   assert (newright != MACH_PORT_NULL);
+  /* Release the global lock while blocking on the auth server and client.  */
+  pthread_mutex_unlock (&global_lock);
   do
     err = auth_server_authenticate (auth,
                                    rend,
@@ -390,6 +392,7 @@ S_io_reauthenticate (struct sock_user *user,
                                    &gen_gids, &gengidlen,
                                    &aux_gids, &auxgidlen);
   while (err == EINTR);
+  pthread_mutex_lock (&global_lock);
   mach_port_deallocate (mach_task_self (), rend);
   mach_port_deallocate (mach_task_self (), newright);
   mach_port_deallocate (mach_task_self (), auth);
diff --git a/trans/fakeroot.c b/trans/fakeroot.c
index 63303a0..4275152 100644
--- a/trans/fakeroot.c
+++ b/trans/fakeroot.c
@@ -554,13 +554,11 @@ netfs_attempt_chmod (struct iouser *cred, struct node 
*np, mode_t mode)
 
   /* Make sure that `check_openmodes' will still always be able to reopen
      it.  */
-  real_mode = mode;
   nn = netfs_node_netnode (np);
-  if (nn->openmodes & O_READ)
-    real_mode |= S_IRUSR;
-  if (nn->openmodes & O_WRITE)
-    real_mode |= S_IWUSR;
-  if (nn->openmodes & O_EXEC)
+  real_mode = mode;
+  real_mode |= S_IRUSR;
+  real_mode |= S_IWUSR;
+  if (S_ISDIR (mode) || (nn->openmodes & O_EXEC))
     real_mode |= S_IXUSR;
 
   /* We don't bother with error checking since the fake mode change should
diff --git a/utils/Makefile b/utils/Makefile
index 241b060..955789b 100644
--- a/utils/Makefile
+++ b/utils/Makefile
@@ -22,7 +22,7 @@ targets = shd ps settrans showtrans syncfs fsysopts \
        storeinfo login w uptime ids loginpr sush vmstat portinfo \
        devprobe vminfo addauth rmauth unsu setauth ftpcp ftpdir storecat \
        storeread msgport rpctrace mount gcore fakeauth fakeroot remap \
-       umount nullauth
+       umount nullauth rpcscan
 
 special-targets = loginpr sush uptime fakeroot remap
 SRCS = shd.c ps.c settrans.c syncfs.c showtrans.c addauth.c rmauth.c \
@@ -31,7 +31,7 @@ SRCS = shd.c ps.c settrans.c syncfs.c showtrans.c addauth.c 
rmauth.c \
        parse.c frobauth.c frobauth-mod.c setauth.c pids.c nonsugid.c \
        unsu.c ftpcp.c ftpdir.c storeread.c storecat.c msgport.c \
        rpctrace.c mount.c gcore.c fakeauth.c fakeroot.sh remap.sh \
-       nullauth.c match-options.c
+       nullauth.c match-options.c msgids.c rpcscan.c
 
 OBJS = $(filter-out %.sh,$(SRCS:.c=.o))
 HURDLIBS = ps ihash store fshelp ports ftpconn shouldbeinlibc
@@ -62,13 +62,15 @@ ftpcp ftpdir: ../libftpconn/libftpconn.a
 settrans: ../libfshelp/libfshelp.a ../libports/libports.a
 ps w ids settrans syncfs showtrans fsysopts storeinfo login vmstat portinfo \
   devprobe vminfo addauth rmauth setauth unsu ftpcp ftpdir storeread \
-  storecat msgport mount umount nullauth: \
+  storecat msgport mount umount nullauth rpctrace: \
        ../libshouldbeinlibc/libshouldbeinlibc.a
 
 $(filter-out $(special-targets), $(targets)): %: %.o
 
-rpctrace: ../libports/libports.a ../libihash/libihash.a
-rpctrace-CPPFLAGS = -DDATADIR=\"${datadir}\"
+rpctrace: ../libports/libports.a
+rpctrace rpcscan: msgids.o \
+         ../libihash/libihash.a
+msgids-CPPFLAGS = -DDATADIR=\"${datadir}\"
 
 fakeauth: authServer.o auth_requestUser.o interruptServer.o \
          ../libports/libports.a ../libihash/libihash.a \
diff --git a/utils/msgids.c b/utils/msgids.c
new file mode 100644
index 0000000..4bc08de
--- /dev/null
+++ b/utils/msgids.c
@@ -0,0 +1,252 @@
+/* Translate message ids to symbolic names.
+
+   Copyright (C) 1998-2015 Free Software Foundation, Inc.
+
+   This file is part of the GNU Hurd.
+
+   The GNU Hurd is free software; you can redistribute it and/or
+   modify it under the terms of the GNU General Public License as
+   published by the Free Software Foundation; either version 2, or (at
+   your option) any later version.
+
+   The GNU Hurd is distributed in the hope that it will be useful, but
+   WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with the GNU Hurd.  If not, see <http://www.gnu.org/licenses/>.  */
+
+#include <argp.h>
+#include <argz.h>
+#include <dirent.h>
+#include <errno.h>
+#include <error.h>
+#include <fnmatch.h>
+#include <hurd/ihash.h>
+#include <mach.h>
+#include <stdbool.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "msgids.h"
+
+static void
+msgid_ihash_cleanup (void *element, void *arg)
+{
+  struct msgid_info *info = element;
+  free (info->name);
+  free (info->subsystem);
+  free (info);
+}
+
+static struct hurd_ihash msgid_ihash
+  = HURD_IHASH_INITIALIZER (HURD_IHASH_NO_LOCP);
+
+/* Parse a file of RPC names and message IDs as output by mig's -list
+   option: "subsystem base-id routine n request-id reply-id".  Put each
+   request-id value into `msgid_ihash' with the routine name as its value.  */
+static error_t
+parse_msgid_list (const char *filename)
+{
+  FILE *fp;
+  char *buffer = NULL;
+  size_t bufsize = 0;
+  unsigned int lineno = 0;
+  char *name, *subsystem;
+  unsigned int msgid;
+  error_t err;
+
+  fp = fopen (filename, "r");
+  if (fp == NULL)
+    return errno;
+
+  while (getline (&buffer, &bufsize, fp) > 0)
+    {
+      ++lineno;
+      if (buffer[0] == '#' || buffer[0] == '\0')
+       continue;
+      if (sscanf (buffer, "%ms %*u %ms %*u %u %*u\n",
+                 &subsystem, &name, &msgid) != 3)
+       error (0, 0, "%s:%u: invalid format in RPC list file",
+              filename, lineno);
+      else
+       {
+         struct msgid_info *info = malloc (sizeof *info);
+         if (info == 0)
+           error (1, errno, "malloc");
+         info->name = name;
+         info->subsystem = subsystem;
+         err = hurd_ihash_add (&msgid_ihash, msgid, info);
+         if (err)
+           return err;
+       }
+    }
+
+  free (buffer);
+  fclose (fp);
+  return 0;
+}
+
+/* Look for a name describing MSGID.  We check the table directly, and
+   also check if this looks like the ID of a reply message whose request
+   ID is already in the table.  */
+const struct msgid_info *
+msgid_info (mach_msg_id_t msgid)
+{
+  const struct msgid_info *info = hurd_ihash_find (&msgid_ihash, msgid);
+  if (info == 0 && (msgid / 100) % 2 == 1)
+    {
+      /* This message ID is not in the table, and its number makes it
+        what should be an RPC reply message ID.  So look up the message
+        ID of the corresponding RPC request and synthesize a name from
+        that.  Then stash that name in the table so the next time the
+        lookup will match directly.  */
+      info = hurd_ihash_find (&msgid_ihash, msgid - 100);
+      if (info != 0)
+       {
+         struct msgid_info *reply_info = malloc (sizeof *info);
+         if (reply_info != 0)
+           {
+             reply_info->subsystem = strdup (info->subsystem);
+             reply_info->name = 0;
+             asprintf (&reply_info->name, "%s-reply", info->name);
+             hurd_ihash_add (&msgid_ihash, msgid, reply_info);
+             info = reply_info;
+           }
+         else
+           info = 0;
+       }
+    }
+  return info;
+}
+
+static int
+msgids_file_p (const struct dirent *eps)
+{
+  return fnmatch ("*.msgids", eps->d_name, 0) != FNM_NOMATCH;
+}
+
+static void
+scan_msgids_dir (char **argz, size_t *argz_len, char *dir, bool append)
+{
+  struct dirent **eps;
+  int n;
+
+  n = scandir (dir, &eps, msgids_file_p, NULL);
+  if (n >= 0)
+    {
+      for (int cnt = 0; cnt < n; ++cnt)
+       {
+         char *msgids_file;
+
+         if (asprintf (&msgids_file, "%s/%s", dir, eps[cnt]->d_name) < 0)
+           error (1, errno, "asprintf");
+
+         if (append == TRUE)
+           {
+             if (argz_add (argz, argz_len, msgids_file) != 0)
+               error (1, errno, "argz_add");
+           }
+         else
+           {
+             if (argz_insert (argz, argz_len, *argz, msgids_file) != 0)
+               error (1, errno, "argz_insert");
+           }
+         free (msgids_file);
+       }
+    }
+
+  /* If the directory couldn't be scanned for whatever reason, just ignore
+     it. */
+}
+
+/* Argument parsing.  */
+
+static char *msgids_files_argz = NULL;
+static size_t msgids_files_argz_len = 0;
+static bool nostdinc = FALSE;
+
+#define STD_MSGIDS_DIR DATADIR "/msgids/"
+#define OPT_NOSTDINC -1
+
+static const struct argp_option options[] =
+{
+  {"nostdinc", OPT_NOSTDINC, 0, 0,
+   "Do not search inside the standard system directory, `" STD_MSGIDS_DIR
+   "', for `.msgids' files.", 0},
+  {"rpc-list", 'i', "FILE", 0,
+   "Read FILE for assocations of message ID numbers to names.", 0},
+  {0, 'I', "DIR", 0,
+   "Add the directory DIR to the list of directories to be searched for files "
+   "containing message ID numbers.", 0},
+  {0}
+};
+
+/* Parse our options...  */
+static error_t parse_opt (int key, char *arg, struct argp_state *state)
+{
+  switch (key)
+    {
+    case ARGP_KEY_INIT:
+      hurd_ihash_set_cleanup (&msgid_ihash, msgid_ihash_cleanup, 0);
+      break;
+
+    case OPT_NOSTDINC:
+      nostdinc = TRUE;
+      break;
+
+    case 'i':
+      if (argz_add (&msgids_files_argz, &msgids_files_argz_len,
+                   arg) != 0)
+       error (1, errno, "argz_add");
+      break;
+
+    case 'I':
+      scan_msgids_dir (&msgids_files_argz, &msgids_files_argz_len,
+                      arg, TRUE);
+      break;
+
+    case ARGP_KEY_NO_ARGS:
+      return 0;
+
+    case ARGP_KEY_ARG:
+      return EINVAL;
+
+    case ARGP_KEY_END:
+      /* Insert the files from STD_MSGIDS_DIR at the beginning of the
+        list, so that their content can be overridden by subsequently
+        parsed files.  */
+      if (nostdinc == FALSE)
+       scan_msgids_dir (&msgids_files_argz, &msgids_files_argz_len,
+                        STD_MSGIDS_DIR, FALSE);
+
+      if (msgids_files_argz != NULL)
+       {
+         error_t err = 0;
+         char *msgids_file = NULL;
+
+         while (! err
+                && (msgids_file = argz_next (msgids_files_argz,
+                                             msgids_files_argz_len,
+                                             msgids_file)))
+           err = parse_msgid_list (msgids_file);
+
+         free (msgids_files_argz);
+         if (err)
+           argp_failure (state, 1, err, "%s", msgids_file);
+       }
+      break;
+
+    default:
+      return ARGP_ERR_UNKNOWN;
+    }
+  return 0;
+}
+
+const struct argp msgid_argp = {
+  .options = options,
+  .parser = parse_opt,
+  .doc = "msgid doc",
+};
diff --git a/utils/msgids.h b/utils/msgids.h
new file mode 100644
index 0000000..6bd2372
--- /dev/null
+++ b/utils/msgids.h
@@ -0,0 +1,33 @@
+/* Translate message ids to symbolic names.
+
+   Copyright (C) 1998-2015 Free Software Foundation, Inc.
+
+   This file is part of the GNU Hurd.
+
+   The GNU Hurd is free software; you can redistribute it and/or
+   modify it under the terms of the GNU General Public License as
+   published by the Free Software Foundation; either version 2, or (at
+   your option) any later version.
+
+   The GNU Hurd is distributed in the hope that it will be useful, but
+   WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with the GNU Hurd.  If not, see <http://www.gnu.org/licenses/>.  */
+
+#ifndef _HURD_MSGIDS_H_
+#define _HURD_MSGIDS_H_
+
+/* We map message ids to procedure and subsystem names.  */
+struct msgid_info
+{
+  char *name;
+  char *subsystem;
+};
+
+const struct msgid_info *msgid_info (mach_msg_id_t msgid);
+const struct argp msgid_argp;
+
+#endif /* _HURD_MSGIDS_H_ */
diff --git a/utils/rpcscan.c b/utils/rpcscan.c
new file mode 100644
index 0000000..2270ea8
--- /dev/null
+++ b/utils/rpcscan.c
@@ -0,0 +1,404 @@
+/* An RPC scanner for the Hurd.
+
+   Copyright (C) 2015 Free Software Foundation, Inc.
+
+   This file is part of the GNU Hurd.
+
+   The GNU Hurd is free software; you can redistribute it and/or
+   modify it under the terms of the GNU General Public License as
+   published by the Free Software Foundation; either version 2, or (at
+   your option) any later version.
+
+   The GNU Hurd is distributed in the hope that it will be useful, but
+   WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with the GNU Hurd.  If not, see <http://www.gnu.org/licenses/>.  */
+
+#include <mach.h>
+#include <hurd.h>
+#include <hurd/ihash.h>
+#include <mach/message.h>
+#include <unistd.h>
+#include <argp.h>
+#include <error.h>
+#include <string.h>
+#include <version.h>
+#include <sys/wait.h>
+#include <inttypes.h>
+#include <stdbool.h>
+#include <stddef.h>
+#include <argz.h>
+
+#include "msgids.h"
+
+/* Send messages with arbitrary message ids.  */
+struct Request {
+  mach_msg_header_t Head;
+} RequestTemplate;
+
+struct Reply {
+  mach_msg_header_t Head;
+  mach_msg_type_t RetCodeType;
+  kern_return_t RetCode;
+  char Body[4096];
+};
+
+union {
+  struct Request Request;
+  struct Reply Reply;
+} Message;
+
+error_t
+setup (mach_port_t request, mach_msg_type_name_t requestType)
+{
+  RequestTemplate.Head.msgh_remote_port = request;
+  if (! MACH_PORT_VALID (RequestTemplate.Head.msgh_local_port))
+    RequestTemplate.Head.msgh_local_port = mach_reply_port ();
+  RequestTemplate.Head.msgh_bits =
+    MACH_MSGH_BITS (requestType, MACH_MSG_TYPE_MAKE_SEND_ONCE);
+  return 0;
+}
+
+error_t
+send (mach_msg_id_t msgid)
+{
+  error_t err;
+  Message.Request = RequestTemplate;
+  Message.Request.Head.msgh_id = msgid;
+  err = mach_msg (&Message.Request.Head,
+                 MACH_SEND_MSG|MACH_RCV_MSG|MACH_MSG_OPTION_NONE,
+                 sizeof Message.Request,
+                 sizeof Message.Reply,
+                 Message.Request.Head.msgh_local_port,
+                 MACH_MSG_TIMEOUT_NONE,
+                 MACH_PORT_NULL);
+  if (err)
+    return err;
+
+  /* XXX typecheck */
+  return Message.Reply.RetCode;
+}
+
+typedef error_t (*setup_function_t) ();
+setup_function_t setup_target;
+void *setup_argument;
+
+error_t
+setup_task_target (void)
+{
+  error_t err;
+  static task_t task;
+  static mach_msg_type_name_t taskType = MACH_MSG_TYPE_COPY_SEND;
+
+  if (MACH_PORT_VALID (task))
+    {
+      task_terminate (task);
+      mach_port_deallocate (mach_task_self (), task);
+    }
+
+  err = task_create (mach_task_self (), 0, &task);
+  if (err)
+    return err;
+
+  return setup (task, taskType);
+}
+
+error_t
+setup_thread_target (void)
+{
+  error_t err;
+  static task_t task;
+  static thread_t thread;
+
+  if (MACH_PORT_VALID (thread))
+    {
+      thread_terminate (thread);
+      mach_port_deallocate (mach_task_self (), thread);
+    }
+
+  if (MACH_PORT_VALID (task))
+    {
+      task_terminate (task);
+      mach_port_deallocate (mach_task_self (), task);
+    }
+
+  err = task_create (mach_task_self (), 0, &task);
+  if (err)
+    return err;
+
+  err = thread_create (task, &thread);
+  if (err)
+    return err;
+
+  return setup (thread, MACH_MSG_TYPE_COPY_SEND);
+}
+
+error_t
+setup_proc_target (void)
+{
+  error_t err;
+  static task_t task;
+  static process_t proc, target;
+  static mach_msg_type_name_t targetType = MACH_MSG_TYPE_COPY_SEND;
+
+  if (! MACH_PORT_VALID (proc))
+    proc = getproc ();
+  if (MACH_PORT_VALID (task))
+    mach_port_deallocate (mach_task_self (), task);
+  if (MACH_PORT_VALID (target))
+    mach_port_deallocate (mach_task_self (), target);
+
+  err = task_create (mach_task_self (), 0, &task);
+  if (err)
+    return err;
+
+  err = proc_task2proc (proc, task, &target);
+  if (err)
+    return err;
+
+  return setup (target, targetType);
+}
+
+error_t
+setup_auth_target (void)
+{
+  static auth_t auth;
+  static mach_msg_type_name_t authType = MACH_MSG_TYPE_COPY_SEND;
+
+  if (MACH_PORT_VALID (auth))
+    mach_port_deallocate (mach_task_self (), auth);
+
+  auth = getauth ();
+  if (! MACH_PORT_VALID (auth))
+    return errno;
+
+  return setup (auth, authType);
+}
+
+error_t
+setup_hurd_target (void)
+{
+  char *name = (char *) setup_argument;
+  mach_port_t request;
+  mach_msg_type_name_t requestType;
+
+  request = file_name_lookup (name, 0, 0);
+  if (! MACH_PORT_VALID (request))
+    return errno;
+  requestType = MACH_MSG_TYPE_COPY_SEND;
+
+  return setup (request, requestType);
+}
+
+task_t extract_target_task;
+mach_port_t extract_target_port;
+mach_msg_type_name_t extract_target_type;
+
+error_t
+setup_extract_target (void)
+{
+  error_t err;
+  char *name = (char *) setup_argument;
+  mach_port_t request;
+  mach_msg_type_name_t requestType;
+
+  err = mach_port_extract_right (extract_target_task,
+                                 extract_target_port,
+                                 extract_target_type,
+                                 &request,
+                                 &requestType);
+  if (err)
+    error (1, err, "mach_port_extract_right");
+  if (err)
+    return err;
+  requestType = MACH_MSG_TYPE_COPY_SEND;
+  return setup (request, requestType);
+}
+
+const char *argp_program_version = STANDARD_HURD_VERSION (rpcscan);
+
+char **cmd_argv;
+int verbose;
+int numeric;
+int subsystem;
+
+#define OPT_TARGET_TASK                -1
+#define OPT_TARGET_THREAD      -2
+#define OPT_TARGET_PROC                -3
+#define OPT_TARGET_AUTH                -4
+#define OPT_TARGET_EXTRACT     -5
+
+static const struct argp_option options[] =
+{
+  {NULL, 0, NULL, OPTION_DOC, "Target selection", 1},
+  {"task", OPT_TARGET_TASK, NULL, 0, "target a task port", 1},
+  {"thread", OPT_TARGET_THREAD, NULL, 0, "target a thread port", 1},
+  {"proc", OPT_TARGET_PROC, NULL, 0, "target a proc port", 1},
+  {"auth", OPT_TARGET_AUTH, NULL, 0, "target an auth port", 1},
+  {"extract", OPT_TARGET_EXTRACT, "PID.PORT", 0, "target port PORT of PID", 1},
+
+  {NULL, 0, NULL, OPTION_DOC, "Options", 2},
+  {"verbose", 'v', NULL, 0, "be verbose", 2},
+  {"numeric", 'n', NULL, 0, "show numeric message ids", 2},
+  {"subsystem", 's', NULL, 0, "show subsystem names", 2},
+  {0}
+};
+
+static const char args_doc[] = "[FILE]";
+static const char doc[] = "Scan a given Mach port.";
+
+/* Parse our options...         */
+error_t
+parse_opt (int key, char *arg, struct argp_state *state)
+{
+  error_t err;
+  switch (key)
+    {
+    case 'v':
+      verbose = 1;
+      break;
+
+    case 'n':
+      numeric = 1;
+      break;
+
+    case 's':
+      subsystem = 1;
+      break;
+
+#define SELECT_TARGET(target)                                  \
+      if (setup_target)                                                \
+       argp_error (state, "Multiple targets specified.");      \
+      setup_target = target;
+
+    case OPT_TARGET_TASK:
+      SELECT_TARGET (setup_task_target);
+      break;
+
+    case OPT_TARGET_THREAD:
+      SELECT_TARGET (setup_thread_target);
+      break;
+
+    case OPT_TARGET_PROC:
+      SELECT_TARGET (setup_proc_target);
+      break;
+
+    case OPT_TARGET_AUTH:
+      SELECT_TARGET (setup_auth_target);
+      break;
+
+    case OPT_TARGET_EXTRACT:;
+      process_t proc;
+      pid_t pid;
+      char *end;
+
+      pid = strtol (arg, &end, 10);
+      if (arg == end || *end != '.')
+        argp_error (state, "Expected format PID.PORT, got `%s'.", arg);
+
+      arg = end + 1;
+      extract_target_port = strtol (arg, &end, 10);
+      if (arg == end || *end != '\0')
+        argp_error (state, "Expected format PORT, got `%s'.", arg);
+
+      proc = getproc ();
+      err = proc_pid2task (proc, pid, &extract_target_task);
+      if (err)
+        argp_failure (state, 1, err,
+                      "Could not get task of process %d", pid);
+
+      extract_target_type = MACH_MSG_TYPE_COPY_SEND; /* XXX */
+      SELECT_TARGET (setup_extract_target);
+      break;
+
+    case ARGP_KEY_ARG:
+      SELECT_TARGET (setup_hurd_target);
+      setup_argument = arg;
+      break;
+#undef SELECT_TARGET
+
+    case ARGP_KEY_NO_ARGS:
+      if (setup_target == NULL)
+       argp_usage (state);
+      break;
+
+    default:
+      return ARGP_ERR_UNKNOWN;
+    }
+  return 0;
+}
+
+const struct argp_child children[] =
+  {
+    { .argp=&msgid_argp, },
+    { 0 }
+  };
+
+const struct argp argp = { options, parse_opt, args_doc, doc, &children };
+
+void
+format_msgid (char *buf, size_t len, mach_msg_id_t id)
+{
+  if (numeric)
+  numeric:
+    snprintf (buf, len, "%d", id);
+  else
+    {
+      const struct msgid_info *info;
+      info = msgid_info (id);
+      if (info == NULL)
+        goto numeric;
+
+      if (subsystem)
+        snprintf (buf, len, "%s/%s", info->subsystem, info->name);
+      else
+        snprintf (buf, len, "%s", info->name);
+    }
+}
+
+int
+main (int argc, char **argv)
+{
+  error_t err;
+  mach_msg_id_t msgid;
+
+  /* Parse our arguments.  */
+  argp_parse (&argp, argc, argv, ARGP_IN_ORDER, 0, 0);
+
+  err = setup_target ();
+  if (err)
+    /* Initial setup failed.  Bail out.  */
+    error (1, err, "%s",
+       setup_target == setup_hurd_target? (char *) setup_argument: "setup");
+
+  for (msgid = 0; msgid < 500000; msgid++)
+    {
+      err = send (msgid);
+      switch (err)
+       {
+       case MACH_SEND_INVALID_DEST:
+         err = setup_target ();
+         if (err)
+           error (1, err, "setup");
+         msgid--;      /* redo */
+         continue;
+
+       case MIG_BAD_ID:
+         /* do nothing */
+         break;
+
+       default:;
+          char buf[80];
+          format_msgid (buf, sizeof buf, msgid);
+          if (verbose)
+            error (0, err, "%s", buf);
+          else
+            fprintf (stdout, "%s\n", buf);
+       }
+    }
+
+  return EXIT_SUCCESS;
+}
diff --git a/utils/rpctrace.c b/utils/rpctrace.c
index 48daa07..d53b510 100644
--- a/utils/rpctrace.c
+++ b/utils/rpctrace.c
@@ -26,9 +26,7 @@
 #include <mach/message.h>
 #include <assert.h>
 #include <fcntl.h>
-#include <fnmatch.h>
 #include <sys/stat.h>
-#include <dirent.h>
 #include <unistd.h>
 #include <argp.h>
 #include <error.h>
@@ -41,24 +39,15 @@
 #include <argz.h>
 #include <envz.h>
 
-const char *argp_program_version = STANDARD_HURD_VERSION (rpctrace);
+#include "msgids.h"
 
-#define STD_MSGIDS_DIR DATADIR "/msgids/"
+const char *argp_program_version = STANDARD_HURD_VERSION (rpctrace);
 
 static unsigned strsize = 80;
 
-#define OPT_NOSTDINC -1
 static const struct argp_option options[] =
 {
   {"output", 'o', "FILE", 0, "Send trace output to FILE instead of stderr."},
-  {"nostdinc", OPT_NOSTDINC, 0, 0, 
-   "Do not search inside the standard system directory, `" STD_MSGIDS_DIR
-   "', for `.msgids' files."},
-  {"rpc-list", 'i', "FILE", 0,
-   "Read FILE for assocations of message ID numbers to names."},
-  {0, 'I', "DIR", 0,
-   "Add the directory DIR to the list of directories to be searched for files "
-   "containing message ID numbers."},
   {0, 's', "SIZE", 0, "Specify the maximum string size to print (the default 
is 80)."},
   {0, 'E', "var[=value]", 0,
    "Set/change (var=value) or remove (var) an environment variable among the "
@@ -71,23 +60,6 @@ static const struct argp_option options[] =
 static const char args_doc[] = "COMMAND [ARG...]";
 static const char doc[] = "Trace Mach Remote Procedure Calls.";
 
-/* The msgid_ihash table maps msgh_id values to names.  */
-
-struct msgid_info
-{
-  char *name;
-  char *subsystem;
-};
-
-static void
-msgid_ihash_cleanup (void *element, void *arg)
-{
-  struct msgid_info *info = element;
-  free (info->name);
-  free (info->subsystem);
-  free (info);
-}
-
 /* This structure stores the information of the traced task. */
 struct task_info
 {
@@ -95,9 +67,6 @@ struct task_info
   boolean_t threads_wrapped;   /* All threads of the task has been wrapped? */
 };
 
-static struct hurd_ihash msgid_ihash
-  = HURD_IHASH_INITIALIZER (HURD_IHASH_NO_LOCP);
-
 static struct hurd_ihash task_ihash
   = HURD_IHASH_INITIALIZER (HURD_IHASH_NO_LOCP);
 
@@ -126,86 +95,6 @@ remove_task (task_t task)
   hurd_ihash_remove (&task_ihash, task);
 }
 
-/* Parse a file of RPC names and message IDs as output by mig's -list
-   option: "subsystem base-id routine n request-id reply-id".  Put each
-   request-id value into `msgid_ihash' with the routine name as its value.  */
-static void
-parse_msgid_list (const char *filename)
-{
-  FILE *fp;
-  char *buffer = NULL;
-  size_t bufsize = 0;
-  unsigned int lineno = 0;
-  char *name, *subsystem;
-  unsigned int msgid;
-  error_t err;
-
-  fp = fopen (filename, "r");
-  if (fp == 0)
-    {
-      error (2, errno, "%s", filename);
-      return;
-    }
-
-  while (getline (&buffer, &bufsize, fp) > 0)
-    {
-      ++lineno;
-      if (buffer[0] == '#' || buffer[0] == '\0')
-       continue;
-      if (sscanf (buffer, "%ms %*u %ms %*u %u %*u\n",
-                 &subsystem, &name, &msgid) != 3)
-       error (0, 0, "%s:%u: invalid format in RPC list file",
-              filename, lineno);
-      else
-       {
-         struct msgid_info *info = malloc (sizeof *info);
-         if (info == 0)
-           error (1, errno, "malloc");
-         info->name = name;
-         info->subsystem = subsystem;
-         err = hurd_ihash_add (&msgid_ihash, msgid, info);
-         if (err)
-           error (1, err, "hurd_ihash_add");
-       }
-    }
-
-  free (buffer);
-  fclose (fp);
-}
-
-/* Look for a name describing MSGID.  We check the table directly, and
-   also check if this looks like the ID of a reply message whose request
-   ID is already in the table.  */
-static const struct msgid_info *
-msgid_info (mach_msg_id_t msgid)
-{
-  const struct msgid_info *info = hurd_ihash_find (&msgid_ihash, msgid);
-  if (info == 0 && (msgid / 100) % 2 == 1)
-    {
-      /* This message ID is not in the table, and its number makes it
-        what should be an RPC reply message ID.  So look up the message
-        ID of the corresponding RPC request and synthesize a name from
-        that.  Then stash that name in the table so the next time the
-        lookup will match directly.  */
-      info = hurd_ihash_find (&msgid_ihash, msgid - 100);
-      if (info != 0)
-       {
-         struct msgid_info *reply_info = malloc (sizeof *info);
-         if (reply_info != 0)
-           {
-             reply_info->subsystem = strdup (info->subsystem);
-             reply_info->name = 0;
-             asprintf (&reply_info->name, "%s-reply", info->name);
-             hurd_ihash_add (&msgid_ihash, msgid, reply_info);
-             info = reply_info;
-           }
-         else
-           info = 0;
-       }
-    }
-  return info;
-}
-
 static const char *
 msgid_name (mach_msg_id_t msgid)
 {
@@ -1781,55 +1670,9 @@ traced_spawn (char **argv, char **envp)
   return pid;
 }
 
-
-static void
-scan_msgids_dir (char **argz, size_t *argz_len, char *dir, bool append)
-{
-  struct dirent **eps;
-  int n;
-           
-  int
-    msgids_file_p (const struct dirent *eps)
-    {
-      if (fnmatch ("*.msgids", eps->d_name, 0) != FNM_NOMATCH)
-        return 1;
-      return 0;
-    }
-           
-  n = scandir (dir, &eps, msgids_file_p, NULL);
-  if (n >= 0)
-    {
-      for (int cnt = 0; cnt < n; ++cnt)
-       {
-         char *msgids_file;
-
-         if (asprintf (&msgids_file, "%s/%s", dir, eps[cnt]->d_name) < 0)
-           error (1, errno, "asprintf");
-
-         if (append == TRUE)
-           {
-             if (argz_add (argz, argz_len, msgids_file) != 0)
-               error (1, errno, "argz_add");
-           }
-         else
-           {
-             if (argz_insert (argz, argz_len, *argz, msgids_file) != 0)
-               error (1, errno, "argz_insert");
-           }
-         free (msgids_file);
-       }
-    }
-
-  /* If the directory couldn't be scanned for whatever reason, just ignore
-     it. */
-}
-
 int
 main (int argc, char **argv, char **envp)
 {
-  char *msgids_files_argz = NULL;
-  size_t msgids_files_argz_len = 0;
-  bool nostdinc = FALSE;
   const char *outfile = 0;
   char **cmd_argv = 0;
   pthread_t thread;
@@ -1847,21 +1690,6 @@ main (int argc, char **argv, char **envp)
          outfile = arg;
          break;
 
-       case OPT_NOSTDINC:
-         nostdinc = TRUE;
-         break;
-
-       case 'i':
-         if (argz_add (&msgids_files_argz, &msgids_files_argz_len, 
-                       arg) != 0)
-           error (1, errno, "argz_add");
-         break;
-
-       case 'I':
-         scan_msgids_dir (&msgids_files_argz, &msgids_files_argz_len,
-                         arg, TRUE);
-         break;
-
        case 's':
          strsize = atoi (arg);
          break;
@@ -1908,7 +1736,12 @@ main (int argc, char **argv, char **envp)
        }
       return 0;
     }
-  const struct argp argp = { options, parse_opt, args_doc, doc };
+  const struct argp_child children[] =
+    {
+      { .argp=&msgid_argp, },
+      { 0 }
+    };
+  const struct argp argp = { options, parse_opt, args_doc, doc, &children };
 
   /* Parse our arguments.  */
   argp_parse (&argp, argc, argv, ARGP_IN_ORDER, 0, 0);
@@ -1917,23 +1750,6 @@ main (int argc, char **argv, char **envp)
                            &unknown_task);
   assert_perror (err);
 
-  /* Insert the files from STD_MSGIDS_DIR at the beginning of the list, so that
-     their content can be overridden by subsequently parsed files.  */
-  if (nostdinc == FALSE)
-    scan_msgids_dir (&msgids_files_argz, &msgids_files_argz_len,
-                   STD_MSGIDS_DIR, FALSE);
-
-  if (msgids_files_argz != NULL)
-    {
-      char *msgids_file = NULL;
-
-      while ((msgids_file = argz_next (msgids_files_argz,
-                                      msgids_files_argz_len, msgids_file)))
-       parse_msgid_list (msgids_file);
-
-      free (msgids_files_argz);
-    }
-
   if (outfile)
     {
       ostream = fopen (outfile, "w");
@@ -1951,8 +1767,6 @@ main (int argc, char **argv, char **envp)
                           sizeof (*notify_pi), &notify_pi);
   assert_perror (err);
 
-  hurd_ihash_set_cleanup (&msgid_ihash, msgid_ihash_cleanup, 0);
-
   /* Spawn a single thread that will receive intercepted messages, print
      them, and interpose on the ports they carry.  The access to the
      `traced_info' and ihash data structures is all single-threaded,
diff --git a/utils/vmstat.c b/utils/vmstat.c
index e394484..92a3672 100644
--- a/utils/vmstat.c
+++ b/utils/vmstat.c
@@ -242,7 +242,8 @@ vm_state_get_field (struct vm_state *state, const struct 
field *field)
 static val_t
 get_memobj_hit_ratio (struct vm_state *state, const struct field *field)
 {
-  return state->vmstats.hits * 100 / state->vmstats.lookups;
+  return (val_t)
+    ((float) state->vmstats.hits * 100. / (float) state->vmstats.lookups);
 }
 
 /* Makes sure STATE contains a default pager port and associated info, and

-- 
Alioth's /usr/local/bin/git-commit-notice on 
/srv/git.debian.org/git/pkg-hurd/hurd.git



reply via email to

[Prev in Thread] Current Thread [Next in Thread]