#include <libintl.h>
#include <stdio.h>
#include <string.h>
+#include <signal.h>
#ifndef STAP_SCRIPT_FILENAME
#error "STAP_SCRIPT_FILENAME is required"
for (argp = args; *argp; argp++)
{
if (argp > args)
- fputs (", ", stderr);
- fprintf (stderr, "'%s'", *argp);
+ fputc (' ', stderr);
+ fputs (*argp, stderr);
}
fputc ('\n', stderr);
}
{
char **args, **argp;
- args = xmalloc (sizeof (*args) * argc * 2);
+ args = xmalloc (sizeof (*args) * argc * 2 + 32);
argp = args;
- *argp++ = argv[0];
+ *argp++ = "stap";
for (;;)
{
if (optind < argc)
{
- size_t len;
+ pid_t child;
int i;
- char *d;
- const char *s;
+ static char kill_s[64];
+ static char opt_s[64];
- *argp++ = "-c";
-
- len = 32;
- for (i = optind; i < argc; i++)
- len += 3 + strlen (argv[i]) * 4;
-
- d = *argp++ = xmalloc (len);
- d = stpcpy (d, "(exec");
- for (i = optind; i < argc; i++)
+ child = fork ();
+ switch (child)
{
- *d++ = ' ';
- *d++ = '\'';
- for (s = argv[optind]; *s; s++)
- switch (*s)
- {
- case '\'':
- d = stpcpy (d, "'\\''");
- break;
- case '\\':
- *d++ = '\\';
- /* FALLTHRU */
- default:
- *d++ = *s;
- }
- *d++ = '\'';
+ case -1:
+ error (EXIT_FAILURE, errno, _("Error calling fork"));
+ case 0:
+ i = raise (SIGSTOP);
+ if (i != 0)
+ error (EXIT_FAILURE, errno, _("Error calling raise (SIGSTOP)"));
+
+ execvp (argv[optind], &argv[optind]);
+ error (EXIT_FAILURE, errno, "Error executing child command");
+ default:
+ break;
}
- *d++ = ')';
- *d++ = 0;
+
+ /* FIXME: Call `kill -CONT' from the systamtap script. How? */
+ i = sprintf (kill_s, "kill -CONT %lu; "
+ "while [ -e /proc/%lu/root ]; do sleep 0.1; done",
+ (unsigned long) child, (unsigned long) child);
+ if (i <= 0)
+ error (EXIT_FAILURE, errno, _("Error calling sprintf"));
+ *argp++ = "-c";
+ *argp++ = kill_s;
+ i = sprintf (opt_s, "opt_child=%lu", (unsigned long) child);
+ if (i <= 0)
+ error (EXIT_FAILURE, errno, _("Error calling sprintf"));
+ *argp++ = "-G";
+ *argp++ = opt_s;
}
*argp++ = opt_Z;
*argp = NULL;