[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), ¬ify_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