diff options
author | Justus Winter <4winter@informatik.uni-hamburg.de> | 2015-05-31 00:26:40 +0200 |
---|---|---|
committer | Justus Winter <4winter@informatik.uni-hamburg.de> | 2015-06-30 17:10:00 +0200 |
commit | 74fb5209f06edcf0b52bdf44ba805cb5f6cd41c8 (patch) | |
tree | 3481be39655a9f72626722dab60ba6be08285116 /utils/rpctrace.c | |
parent | f57ed76faed9e9e922ba93dd3bf8740974eb718a (diff) |
utils: split-off the message id parsing
* utils/rpctrace.c: Move all the code handling the message id files...
* utils/msgids.c: ... to a new file.
* utils/msgids.h: And add the relevand declarations.
* utils/Makefile (SRCS): Add the new file.
Diffstat (limited to 'utils/rpctrace.c')
-rw-r--r-- | utils/rpctrace.c | 202 |
1 files changed, 8 insertions, 194 deletions
diff --git a/utils/rpctrace.c b/utils/rpctrace.c index 48daa078..d53b510f 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, |