Implement simultaneous use of -p option and tracing of a command

* strace.c (init): Allow -p option along with a command.
(startup_child): In -D mode, record the parent of the tracer process
as strace_child.
(startup_attach): Save trace_tracer_pid before -D mode fork.
When tracing a command in -f mode, do not check for the command's
threads as it has no threads at this moment.
Never attach to the tracer process.
In -D mode, never attach to the parent of the tracer process,
terminate that process only once at the end of startup_attach,
and reset strace_child.
* strace.1: Document that -p option can be used along with tracing
of a command.
* NEWS: Mention it.
* tests/attach-p-cmd-cmd.c: New file.
* tests/attach-p-cmd-p.c: Likewise.
* tests/attach-p-cmd.test: New test.
* tests/.gitignore: Add attach-p-cmd-cmd and attach-p-cmd-p.
* tests/Makefile.am (check_PROGRAMS): Likewise.
(TESTS): Add attach-p-cmd.test.

This fixes Debian bug #549942.
diff --git a/strace.c b/strace.c
index 7792a5c..614b85f 100644
--- a/strace.c
+++ b/strace.c
@@ -973,6 +973,7 @@
 static void
 startup_attach(void)
 {
+	pid_t parent_pid = strace_tracer_pid;
 	unsigned int tcbi;
 	struct tcb *tcp;
 
@@ -1015,7 +1016,13 @@
 		if (tcp->flags & TCB_ATTACHED)
 			continue; /* no, we already attached it */
 
-		if (followfork && !daemonized_tracer) {
+		if (tcp->pid == parent_pid || tcp->pid == strace_tracer_pid) {
+			errno = EPERM;
+			perror_msg("attach: %d", tcp->pid);
+			droptcb(tcp);
+			continue;
+		}
+		if (followfork && tcp->pid != strace_child) {
 			char procdir[sizeof("/proc/%d/task") + sizeof(int) * 3];
 			DIR *dir;
 
@@ -1092,18 +1099,19 @@
 		if (debug_flag)
 			error_msg("attach to pid %d (main) succeeded", tcp->pid);
 
-		if (daemonized_tracer) {
-			/*
-			 * Make parent go away.
-			 * Also makes grandparent's wait() unblock.
-			 */
-			kill(getppid(), SIGKILL);
-		}
-
 		if (!qflag)
 			error_msg("Process %u attached", tcp->pid);
 	} /* for each tcbtab[] */
 
+	if (daemonized_tracer) {
+		/*
+		 * Make parent go away.
+		 * Also makes grandparent's wait() unblock.
+		 */
+		kill(parent_pid, SIGKILL);
+		strace_child = 0;
+	}
+
  ret:
 	if (interactive)
 		sigprocmask(SIG_SETMASK, &empty_set, NULL);
@@ -1317,11 +1325,10 @@
 		newoutf(tcp);
 	}
 	else {
-		/* With -D, we are *child* here, IOW: different pid. Fetch it: */
+		/* With -D, we are *child* here, the tracee is our parent. */
+		strace_child = strace_tracer_pid;
 		strace_tracer_pid = getpid();
-		/* The tracee is our parent: */
-		pid = getppid();
-		alloctcb(pid);
+		alloctcb(strace_child);
 		/* attaching will be done later, by startup_attach */
 		/* note: we don't do newoutf(tcp) here either! */
 
@@ -1619,13 +1626,12 @@
 	memset(acolumn_spaces, ' ', acolumn);
 	acolumn_spaces[acolumn] = '\0';
 
-	/* Must have PROG [ARGS], or -p PID. Not both. */
-	if (!argv[0] == !nprocs) {
+	if (!argv[0] && !nprocs) {
 		error_msg_and_help("must have PROG [ARGS] or -p PID");
 	}
 
-	if (nprocs != 0 && daemonized_tracer) {
-		error_msg_and_help("-D and -p are mutually exclusive");
+	if (!argv[0] && daemonized_tracer) {
+		error_msg_and_help("PROG [ARGS] must be specified with -D");
 	}
 
 	if (!followfork)
@@ -1722,9 +1728,9 @@
 		opt_intr = INTR_WHILE_WAIT;
 
 	/* argv[0]	-pPID	-oFILE	Default interactive setting
-	 * yes		0	0	INTR_WHILE_WAIT
+	 * yes		*	0	INTR_WHILE_WAIT
 	 * no		1	0	INTR_WHILE_WAIT
-	 * yes		0	1	INTR_NEVER
+	 * yes		*	1	INTR_NEVER
 	 * no		1	1	INTR_WHILE_WAIT
 	 */