Allow -p PID to take comma or whitespace-separated list of PIDs
* defs.h: Clarify meaning of TCB_ATTACHED. No code changes.
* strace.c (process_opt_p_list): New function.
(main): Call process_opt_p_list to process -p PIDs argument.
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
diff --git a/strace.c b/strace.c
index d774611..5e2f9c6 100644
--- a/strace.c
+++ b/strace.c
@@ -420,6 +420,45 @@
}
}
+static void process_opt_p_list(char *opt)
+{
+ while (*opt) {
+ /*
+ * We accept -p PID,PID; -p "`pidof PROG`"; -p "`pgrep PROG`".
+ * pidof uses space as delim, pgrep uses newline. :(
+ */
+ int pid;
+ struct tcb *tcp;
+ char *delim = opt + strcspn(opt, ", \n\t");
+ char c = *delim;
+
+ *delim = '\0';
+ pid = atoi(opt); /* TODO: stricter parsing of the number? */
+ if (pid <= 0) {
+ error_msg("Invalid process id: '%s'", opt);
+ *delim = c;
+ return;
+ }
+ if (pid == strace_tracer_pid) {
+ error_msg("I'm sorry, I can't let you do that, Dave.");
+ *delim = c;
+ return;
+ }
+ *delim = c;
+ tcp = alloc_tcb(pid, 0);
+ tcp->flags |= TCB_ATTACHED;
+ /*
+ * pflag_seen says how many PIDs we handled,
+ * not how many -p opts there were.
+ * Used to decide whether to print pid prefix in logs.
+ */
+ pflag_seen++;
+ if (c == '\0')
+ break;
+ opt = delim + 1;
+ }
+}
+
static void
startup_attach(void)
{
@@ -1019,7 +1058,7 @@
main(int argc, char *argv[])
{
struct tcb *tcp;
- int c, pid = 0;
+ int c;
int optF = 0;
struct sigaction sa;
@@ -1126,18 +1165,7 @@
set_overhead(atoi(optarg));
break;
case 'p':
- pid = atoi(optarg);
- if (pid <= 0) {
- error_msg("Invalid process id: '%s'", optarg);
- break;
- }
- if (pid == strace_tracer_pid) {
- error_msg("I'm sorry, I can't let you do that, Dave.");
- break;
- }
- tcp = alloc_tcb(pid, 0);
- tcp->flags |= TCB_ATTACHED;
- pflag_seen++;
+ process_opt_p_list(optarg);
break;
case 'P':
tracing_paths = 1;