strace.c revision f95397afb8aadf017b2d3d42056c5929dbf16775
1/*
2 * Copyright (c) 1991, 1992 Paul Kranenburg <pk@cs.few.eur.nl>
3 * Copyright (c) 1993 Branko Lankester <branko@hacktic.nl>
4 * Copyright (c) 1993, 1994, 1995, 1996 Rick Sladkey <jrs@world.std.com>
5 * Copyright (c) 1996-1999 Wichert Akkerman <wichert@cistron.nl>
6 * All rights reserved.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 * 1. Redistributions of source code must retain the above copyright
12 *    notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 *    notice, this list of conditions and the following disclaimer in the
15 *    documentation and/or other materials provided with the distribution.
16 * 3. The name of the author may not be used to endorse or promote products
17 *    derived from this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
20 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
21 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
22 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
23 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
24 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
28 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 *
30 *	$Id$
31 */
32
33#include "defs.h"
34
35#include <sys/types.h>
36#include <stdarg.h>
37#include <signal.h>
38#include <errno.h>
39#include <sys/param.h>
40#include <fcntl.h>
41#include <sys/resource.h>
42#include <sys/wait.h>
43#include <sys/stat.h>
44#include <pwd.h>
45#include <grp.h>
46#include <string.h>
47#include <limits.h>
48#include <dirent.h>
49
50#ifdef LINUX
51# include <asm/unistd.h>
52# if defined __NR_tgkill
53#  define my_tgkill(pid, tid, sig) syscall(__NR_tgkill, (pid), (tid), (sig))
54# elif defined __NR_tkill
55#  define my_tgkill(pid, tid, sig) syscall(__NR_tkill, (tid), (sig))
56# else
57   /* kill() may choose arbitrarily the target task of the process group
58      while we later wait on a that specific TID.  PID process waits become
59      TID task specific waits for a process under ptrace(2).  */
60#  warning "Neither tkill(2) nor tgkill(2) available, risk of strace hangs!"
61#  define my_tgkill(pid, tid, sig) kill((tid), (sig))
62# endif
63#endif
64
65#if defined(IA64) && defined(LINUX)
66# include <asm/ptrace_offsets.h>
67#endif
68
69#ifdef USE_PROCFS
70#include <poll.h>
71#endif
72
73#ifdef SVR4
74#include <sys/stropts.h>
75#ifdef HAVE_MP_PROCFS
76#ifdef HAVE_SYS_UIO_H
77#include <sys/uio.h>
78#endif
79#endif
80#endif
81extern char **environ;
82extern int optind;
83extern char *optarg;
84
85
86int debug = 0, followfork = 0;
87unsigned int ptrace_setoptions = 0;
88/* Which WSTOPSIG(status) value marks syscall traps? */
89static unsigned int syscall_trap_sig = SIGTRAP;
90int dtime = 0, xflag = 0, qflag = 0;
91cflag_t cflag = CFLAG_NONE;
92static int iflag = 0, interactive = 0, pflag_seen = 0, rflag = 0, tflag = 0;
93/*
94 * daemonized_tracer supports -D option.
95 * With this option, strace forks twice.
96 * Unlike normal case, with -D *grandparent* process exec's,
97 * becoming a traced process. Child exits (this prevents traced process
98 * from having children it doesn't expect to have), and grandchild
99 * attaches to grandparent similarly to strace -p PID.
100 * This allows for more transparent interaction in cases
101 * when process and its parent are communicating via signals,
102 * wait() etc. Without -D, strace process gets lodged in between,
103 * disrupting parent<->child link.
104 */
105static bool daemonized_tracer = 0;
106
107/* Sometimes we want to print only succeeding syscalls. */
108int not_failing_only = 0;
109
110/* Show path associated with fd arguments */
111int show_fd_path = 0;
112
113/* are we filtering traces based on paths? */
114int tracing_paths = 0;
115
116static int exit_code = 0;
117static int strace_child = 0;
118static int strace_tracer_pid = 0;
119
120static char *username = NULL;
121uid_t run_uid;
122gid_t run_gid;
123
124int acolumn = DEFAULT_ACOLUMN;
125int max_strlen = DEFAULT_STRLEN;
126static char *outfname = NULL;
127FILE *outf;
128static int curcol;
129struct tcb **tcbtab;
130static unsigned int nprocs, tcbtabsize;
131const char *progname;
132
133static int detach(struct tcb *tcp, int sig);
134static int trace(void);
135static void cleanup(void);
136static void interrupt(int sig);
137static sigset_t empty_set, blocked_set;
138
139#ifdef HAVE_SIG_ATOMIC_T
140static volatile sig_atomic_t interrupted;
141#else /* !HAVE_SIG_ATOMIC_T */
142static volatile int interrupted;
143#endif /* !HAVE_SIG_ATOMIC_T */
144
145#ifdef USE_PROCFS
146
147static struct tcb *pfd2tcb(int pfd);
148static void reaper(int sig);
149static void rebuild_pollv(void);
150static struct pollfd *pollv;
151
152#ifndef HAVE_POLLABLE_PROCFS
153
154static void proc_poll_open(void);
155static void proc_poller(int pfd);
156
157struct proc_pollfd {
158	int fd;
159	int revents;
160	int pid;
161};
162
163static int poller_pid;
164static int proc_poll_pipe[2] = { -1, -1 };
165
166#endif /* !HAVE_POLLABLE_PROCFS */
167
168#ifdef HAVE_MP_PROCFS
169#define POLLWANT	POLLWRNORM
170#else
171#define POLLWANT	POLLPRI
172#endif
173#endif /* USE_PROCFS */
174
175static void
176usage(FILE *ofp, int exitval)
177{
178	fprintf(ofp, "\
179usage: strace [-CdDffhiqrtttTvVxxy] [-a column] [-e expr] ... [-o file]\n\
180              [-p pid] ... [-s strsize] [-u username] [-E var=val] ...\n\
181              [-P path] [command [arg ...]]\n\
182   or: strace -c [-D] [-e expr] ... [-O overhead] [-S sortby] [-E var=val] ...\n\
183              [command [arg ...]]\n\
184-c -- count time, calls, and errors for each syscall and report summary\n\
185-C -- like -c but also print regular output while processes are running\n\
186-f -- follow forks, -ff -- with output into separate files\n\
187-F -- attempt to follow vforks, -h -- print help message\n\
188-i -- print instruction pointer at time of syscall\n\
189-q -- suppress messages about attaching, detaching, etc.\n\
190-r -- print relative timestamp, -t -- absolute timestamp, -tt -- with usecs\n\
191-T -- print time spent in each syscall, -V -- print version\n\
192-v -- verbose mode: print unabbreviated argv, stat, termio[s], etc. args\n\
193-x -- print non-ascii strings in hex, -xx -- print all strings in hex\n\
194-y -- print paths associated with file descriptor arguments\n\
195-a column -- alignment COLUMN for printing syscall results (default %d)\n\
196-e expr -- a qualifying expression: option=[!]all or option=[!]val1[,val2]...\n\
197   options: trace, abbrev, verbose, raw, signal, read, or write\n\
198-o file -- send trace output to FILE instead of stderr\n\
199-O overhead -- set overhead for tracing syscalls to OVERHEAD usecs\n\
200-p pid -- trace process with process id PID, may be repeated\n\
201-D -- run tracer process as a detached grandchild, not as parent\n\
202-s strsize -- limit length of print strings to STRSIZE chars (default %d)\n\
203-S sortby -- sort syscall counts by: time, calls, name, nothing (default %s)\n\
204-u username -- run command as username handling setuid and/or setgid\n\
205-E var=val -- put var=val in the environment for command\n\
206-E var -- remove var from the environment for command\n\
207-P path -- trace accesses to path\n\
208" /* this is broken, so don't document it
209-z -- print only succeeding syscalls\n\
210  */
211, DEFAULT_ACOLUMN, DEFAULT_STRLEN, DEFAULT_SORTBY);
212	exit(exitval);
213}
214
215static void die(void) __attribute__ ((noreturn));
216static void die(void)
217{
218	if (strace_tracer_pid == getpid()) {
219		cflag = 0;
220		cleanup();
221	}
222	exit(1);
223}
224
225static void verror_msg(int err_no, const char *fmt, va_list p)
226{
227	fflush(NULL);
228	fprintf(stderr, "%s: ", progname);
229	vfprintf(stderr, fmt, p);
230	if (err_no)
231		fprintf(stderr, ": %s\n", strerror(err_no));
232	else
233		putc('\n', stderr);
234	fflush(stderr);
235}
236
237void error_msg(const char *fmt, ...)
238{
239	va_list p;
240	va_start(p, fmt);
241	verror_msg(0, fmt, p);
242	va_end(p);
243}
244
245void error_msg_and_die(const char *fmt, ...)
246{
247	va_list p;
248	va_start(p, fmt);
249	verror_msg(0, fmt, p);
250	die();
251}
252
253void perror_msg(const char *fmt, ...)
254{
255	va_list p;
256	va_start(p, fmt);
257	verror_msg(errno, fmt, p);
258	va_end(p);
259}
260
261void perror_msg_and_die(const char *fmt, ...)
262{
263	va_list p;
264	va_start(p, fmt);
265	verror_msg(errno, fmt, p);
266	die();
267}
268
269#ifdef SVR4
270#ifdef MIPS
271void
272foobar()
273{
274}
275#endif /* MIPS */
276#endif /* SVR4 */
277
278/* Glue for systems without a MMU that cannot provide fork() */
279#ifdef HAVE_FORK
280# define strace_vforked 0
281#else
282# define strace_vforked 1
283# define fork()         vfork()
284#endif
285
286static void
287set_cloexec_flag(int fd)
288{
289	int flags, newflags;
290
291	flags = fcntl(fd, F_GETFD);
292	if (flags < 0) {
293		/* Can happen only if fd is bad.
294		 * Should never happen: if it does, we have a bug
295		 * in the caller. Therefore we just abort
296		 * instead of propagating the error.
297		 */
298		perror_msg_and_die("fcntl(%d, F_GETFD)", fd);
299	}
300
301	newflags = flags | FD_CLOEXEC;
302	if (flags == newflags)
303		return;
304
305	fcntl(fd, F_SETFD, newflags); /* never fails */
306}
307
308/*
309 * When strace is setuid executable, we have to swap uids
310 * before and after filesystem and process management operations.
311 */
312static void
313swap_uid(void)
314{
315#ifndef SVR4
316	int euid = geteuid(), uid = getuid();
317
318	if (euid != uid && setreuid(euid, uid) < 0) {
319		perror_msg_and_die("setreuid");
320	}
321#endif
322}
323
324#if _LFS64_LARGEFILE
325# define fopen_for_output fopen64
326#else
327# define fopen_for_output fopen
328#endif
329
330static FILE *
331strace_fopen(const char *path)
332{
333	FILE *fp;
334
335	swap_uid();
336	fp = fopen_for_output(path, "w");
337	if (!fp)
338		perror_msg_and_die("Can't fopen '%s'", path);
339	swap_uid();
340	set_cloexec_flag(fileno(fp));
341	return fp;
342}
343
344static int popen_pid = 0;
345
346#ifndef _PATH_BSHELL
347# define _PATH_BSHELL "/bin/sh"
348#endif
349
350/*
351 * We cannot use standard popen(3) here because we have to distinguish
352 * popen child process from other processes we trace, and standard popen(3)
353 * does not export its child's pid.
354 */
355static FILE *
356strace_popen(const char *command)
357{
358	FILE *fp;
359	int fds[2];
360
361	swap_uid();
362	if (pipe(fds) < 0)
363		perror_msg_and_die("pipe");
364
365	set_cloexec_flag(fds[1]); /* never fails */
366
367	popen_pid = vfork();
368	if (popen_pid == -1)
369		perror_msg_and_die("vfork");
370
371	if (popen_pid == 0) {
372		/* child */
373		close(fds[1]);
374		if (fds[0] != 0) {
375			if (dup2(fds[0], 0))
376				perror_msg_and_die("dup2");
377			close(fds[0]);
378		}
379		execl(_PATH_BSHELL, "sh", "-c", command, NULL);
380		perror_msg_and_die("Can't execute '%s'", _PATH_BSHELL);
381	}
382
383	/* parent */
384	close(fds[0]);
385	swap_uid();
386	fp = fdopen(fds[1], "w");
387	if (!fp)
388		error_msg_and_die("Out of memory");
389	return fp;
390}
391
392static void
393newoutf(struct tcb *tcp)
394{
395	if (outfname && followfork > 1) {
396		char name[520 + sizeof(int) * 3];
397		sprintf(name, "%.512s.%u", outfname, tcp->pid);
398		tcp->outf = strace_fopen(name);
399	}
400}
401
402static void
403startup_attach(void)
404{
405	int tcbi;
406	struct tcb *tcp;
407
408	/*
409	 * Block user interruptions as we would leave the traced
410	 * process stopped (process state T) if we would terminate in
411	 * between PTRACE_ATTACH and wait4 () on SIGSTOP.
412	 * We rely on cleanup() from this point on.
413	 */
414	if (interactive)
415		sigprocmask(SIG_BLOCK, &blocked_set, NULL);
416
417	if (daemonized_tracer) {
418		pid_t pid = fork();
419		if (pid < 0) {
420			_exit(1);
421		}
422		if (pid) { /* parent */
423			/*
424			 * Wait for grandchild to attach to straced process
425			 * (grandparent). Grandchild SIGKILLs us after it attached.
426			 * Grandparent's wait() is unblocked by our death,
427			 * it proceeds to exec the straced program.
428			 */
429			pause();
430			_exit(0); /* paranoia */
431		}
432		/* grandchild */
433		/* We will be the tracer process. Remember our new pid: */
434		strace_tracer_pid = getpid();
435	}
436
437	for (tcbi = 0; tcbi < tcbtabsize; tcbi++) {
438		tcp = tcbtab[tcbi];
439		if (!(tcp->flags & TCB_INUSE) || !(tcp->flags & TCB_ATTACHED))
440			continue;
441#ifdef LINUX
442		if (tcp->flags & TCB_CLONE_THREAD)
443			continue;
444#endif
445		/* Reinitialize the output since it may have changed. */
446		tcp->outf = outf;
447		newoutf(tcp);
448
449#ifdef USE_PROCFS
450		if (proc_open(tcp, 1) < 0) {
451			fprintf(stderr, "trouble opening proc file\n");
452			droptcb(tcp);
453			continue;
454		}
455#else /* !USE_PROCFS */
456# ifdef LINUX
457		if (followfork && !daemonized_tracer) {
458			char procdir[sizeof("/proc/%d/task") + sizeof(int) * 3];
459			DIR *dir;
460
461			sprintf(procdir, "/proc/%d/task", tcp->pid);
462			dir = opendir(procdir);
463			if (dir != NULL) {
464				unsigned int ntid = 0, nerr = 0;
465				struct dirent *de;
466				int tid;
467				while ((de = readdir(dir)) != NULL) {
468					if (de->d_fileno == 0)
469						continue;
470					tid = atoi(de->d_name);
471					if (tid <= 0)
472						continue;
473					++ntid;
474					if (ptrace(PTRACE_ATTACH, tid, (char *) 1, 0) < 0) {
475						++nerr;
476						if (debug)
477							fprintf(stderr, "attach to pid %d failed\n", tid);
478					}
479					else {
480						if (debug)
481							fprintf(stderr, "attach to pid %d succeeded\n", tid);
482						if (tid != tcbtab[tcbi]->pid) {
483							tcp = alloctcb(tid);
484							tcp->flags |= TCB_ATTACHED|TCB_CLONE_THREAD;
485							tcbtab[tcbi]->nclone_threads++;
486							tcp->parent = tcbtab[tcbi];
487						}
488					}
489					if (interactive) {
490						sigprocmask(SIG_SETMASK, &empty_set, NULL);
491						if (interrupted)
492							return;
493						sigprocmask(SIG_BLOCK, &blocked_set, NULL);
494					}
495				}
496				closedir(dir);
497				ntid -= nerr;
498				if (ntid == 0) {
499					perror("attach: ptrace(PTRACE_ATTACH, ...)");
500					droptcb(tcp);
501					continue;
502				}
503				if (!qflag) {
504					fprintf(stderr, ntid > 1
505? "Process %u attached with %u threads - interrupt to quit\n"
506: "Process %u attached - interrupt to quit\n",
507						tcbtab[tcbi]->pid, ntid);
508				}
509				continue;
510			} /* if (opendir worked) */
511		} /* if (-f) */
512# endif
513		if (ptrace(PTRACE_ATTACH, tcp->pid, (char *) 1, 0) < 0) {
514			perror("attach: ptrace(PTRACE_ATTACH, ...)");
515			droptcb(tcp);
516			continue;
517		}
518		if (debug)
519			fprintf(stderr, "attach to pid %d (main) succeeded\n", tcp->pid);
520		/* INTERRUPTED is going to be checked at the top of TRACE.  */
521
522		if (daemonized_tracer) {
523			/*
524			 * It is our grandparent we trace, not a -p PID.
525			 * Don't want to just detach on exit, so...
526			 */
527			tcp->flags &= ~TCB_ATTACHED;
528			/*
529			 * Make parent go away.
530			 * Also makes grandparent's wait() unblock.
531			 */
532			kill(getppid(), SIGKILL);
533		}
534
535#endif /* !USE_PROCFS */
536		if (!qflag)
537			fprintf(stderr,
538				"Process %u attached - interrupt to quit\n",
539				tcp->pid);
540	} /* for each tcbtab[] */
541
542	if (interactive)
543		sigprocmask(SIG_SETMASK, &empty_set, NULL);
544}
545
546static void
547startup_child(char **argv)
548{
549	struct stat statbuf;
550	const char *filename;
551	char pathname[MAXPATHLEN];
552	int pid = 0;
553	struct tcb *tcp;
554
555	filename = argv[0];
556	if (strchr(filename, '/')) {
557		if (strlen(filename) > sizeof pathname - 1) {
558			errno = ENAMETOOLONG;
559			perror_msg_and_die("exec");
560		}
561		strcpy(pathname, filename);
562	}
563#ifdef USE_DEBUGGING_EXEC
564	/*
565	 * Debuggers customarily check the current directory
566	 * first regardless of the path but doing that gives
567	 * security geeks a panic attack.
568	 */
569	else if (stat(filename, &statbuf) == 0)
570		strcpy(pathname, filename);
571#endif /* USE_DEBUGGING_EXEC */
572	else {
573		const char *path;
574		int m, n, len;
575
576		for (path = getenv("PATH"); path && *path; path += m) {
577			if (strchr(path, ':')) {
578				n = strchr(path, ':') - path;
579				m = n + 1;
580			}
581			else
582				m = n = strlen(path);
583			if (n == 0) {
584				if (!getcwd(pathname, MAXPATHLEN))
585					continue;
586				len = strlen(pathname);
587			}
588			else if (n > sizeof pathname - 1)
589				continue;
590			else {
591				strncpy(pathname, path, n);
592				len = n;
593			}
594			if (len && pathname[len - 1] != '/')
595				pathname[len++] = '/';
596			strcpy(pathname + len, filename);
597			if (stat(pathname, &statbuf) == 0 &&
598			    /* Accept only regular files
599			       with some execute bits set.
600			       XXX not perfect, might still fail */
601			    S_ISREG(statbuf.st_mode) &&
602			    (statbuf.st_mode & 0111))
603				break;
604		}
605	}
606	if (stat(pathname, &statbuf) < 0) {
607		perror_msg_and_die("Can't stat '%s'", filename);
608	}
609	strace_child = pid = fork();
610	if (pid < 0) {
611		perror_msg_and_die("fork");
612	}
613	if ((pid != 0 && daemonized_tracer) /* -D: parent to become a traced process */
614	 || (pid == 0 && !daemonized_tracer) /* not -D: child to become a traced process */
615	) {
616		pid = getpid();
617#ifdef USE_PROCFS
618		if (outf != stderr) close(fileno(outf));
619#ifdef MIPS
620		/* Kludge for SGI, see proc_open for details. */
621		sa.sa_handler = foobar;
622		sa.sa_flags = 0;
623		sigemptyset(&sa.sa_mask);
624		sigaction(SIGINT, &sa, NULL);
625#endif /* MIPS */
626#ifndef FREEBSD
627		pause();
628#else /* FREEBSD */
629		kill(pid, SIGSTOP); /* stop HERE */
630#endif /* FREEBSD */
631#else /* !USE_PROCFS */
632		if (outf != stderr)
633			close(fileno(outf));
634
635		if (!daemonized_tracer) {
636			if (ptrace(PTRACE_TRACEME, 0, (char *) 1, 0) < 0) {
637				perror_msg_and_die("ptrace(PTRACE_TRACEME, ...)");
638			}
639			if (debug)
640				kill(pid, SIGSTOP);
641		}
642
643		if (username != NULL || geteuid() == 0) {
644			uid_t run_euid = run_uid;
645			gid_t run_egid = run_gid;
646
647			if (statbuf.st_mode & S_ISUID)
648				run_euid = statbuf.st_uid;
649			if (statbuf.st_mode & S_ISGID)
650				run_egid = statbuf.st_gid;
651
652			/*
653			 * It is important to set groups before we
654			 * lose privileges on setuid.
655			 */
656			if (username != NULL) {
657				if (initgroups(username, run_gid) < 0) {
658					perror_msg_and_die("initgroups");
659				}
660				if (setregid(run_gid, run_egid) < 0) {
661					perror_msg_and_die("setregid");
662				}
663				if (setreuid(run_uid, run_euid) < 0) {
664					perror_msg_and_die("setreuid");
665				}
666			}
667		}
668		else
669			setreuid(run_uid, run_uid);
670
671		if (!daemonized_tracer) {
672			/*
673			 * Induce an immediate stop so that the parent
674			 * will resume us with PTRACE_SYSCALL and display
675			 * this execve call normally.
676			 * Unless of course we're on a no-MMU system where
677			 * we vfork()-ed, so we cannot stop the child.
678			 */
679			if (!strace_vforked)
680				kill(getpid(), SIGSTOP);
681		} else {
682			struct sigaction sv_sigchld;
683			sigaction(SIGCHLD, NULL, &sv_sigchld);
684			/*
685			 * Make sure it is not SIG_IGN, otherwise wait
686			 * will not block.
687			 */
688			signal(SIGCHLD, SIG_DFL);
689			/*
690			 * Wait for grandchild to attach to us.
691			 * It kills child after that, and wait() unblocks.
692			 */
693			alarm(3);
694			wait(NULL);
695			alarm(0);
696			sigaction(SIGCHLD, &sv_sigchld, NULL);
697		}
698#endif /* !USE_PROCFS */
699
700		execv(pathname, argv);
701		perror_msg_and_die("exec");
702	}
703
704	/* We are the tracer.  */
705	/* With -D, we are *child* here, IOW: different pid. Fetch it. */
706	strace_tracer_pid = getpid();
707
708	tcp = alloctcb(daemonized_tracer ? getppid() : pid);
709	if (daemonized_tracer) {
710		/* We want subsequent startup_attach() to attach to it.  */
711		tcp->flags |= TCB_ATTACHED;
712	}
713#ifdef USE_PROCFS
714	if (proc_open(tcp, 0) < 0) {
715		perror_msg_and_die("trouble opening proc file");
716	}
717#endif /* USE_PROCFS */
718}
719
720#ifdef LINUX
721/*
722 * Test whether the kernel support PTRACE_O_TRACECLONE et al options.
723 * First fork a new child, call ptrace with PTRACE_SETOPTIONS on it,
724 * and then see which options are supported by the kernel.
725 */
726static int
727test_ptrace_setoptions_followfork(void)
728{
729	int pid, expected_grandchild = 0, found_grandchild = 0;
730	const unsigned int test_options = PTRACE_O_TRACECLONE |
731					  PTRACE_O_TRACEFORK |
732					  PTRACE_O_TRACEVFORK;
733
734	if ((pid = fork()) < 0)
735		return -1;
736	else if (pid == 0) {
737		if (ptrace(PTRACE_TRACEME, 0, (char *)1, 0) < 0)
738			_exit(1);
739		kill(getpid(), SIGSTOP);
740		_exit(fork() < 0);
741	}
742
743	while (1) {
744		int status, tracee_pid;
745
746		tracee_pid = wait(&status);
747		if (tracee_pid == -1) {
748			if (errno == EINTR)
749				continue;
750			else if (errno == ECHILD)
751				break;
752			perror("test_ptrace_setoptions_followfork");
753			return -1;
754		}
755		if (tracee_pid != pid) {
756			found_grandchild = tracee_pid;
757			if (ptrace(PTRACE_CONT, tracee_pid, 0, 0) < 0 &&
758			    errno != ESRCH)
759				kill(tracee_pid, SIGKILL);
760		}
761		else if (WIFSTOPPED(status)) {
762			switch (WSTOPSIG(status)) {
763			case SIGSTOP:
764				if (ptrace(PTRACE_SETOPTIONS, pid,
765					   NULL, test_options) < 0) {
766					kill(pid, SIGKILL);
767					return -1;
768				}
769				break;
770			case SIGTRAP:
771				if (status >> 16 == PTRACE_EVENT_FORK) {
772					long msg = 0;
773
774					if (ptrace(PTRACE_GETEVENTMSG, pid,
775						   NULL, (long) &msg) == 0)
776						expected_grandchild = msg;
777				}
778				break;
779			}
780			if (ptrace(PTRACE_SYSCALL, pid, 0, 0) < 0 &&
781			    errno != ESRCH)
782				kill(pid, SIGKILL);
783		}
784	}
785	if (expected_grandchild && expected_grandchild == found_grandchild)
786		ptrace_setoptions |= test_options;
787	return 0;
788}
789
790/*
791 * Test whether the kernel support PTRACE_O_TRACESYSGOOD.
792 * First fork a new child, call ptrace(PTRACE_SETOPTIONS) on it,
793 * and then see whether it will stop with (SIGTRAP | 0x80).
794 *
795 * Use of this option enables correct handling of user-generated SIGTRAPs,
796 * and SIGTRAPs generated by special instructions such as int3 on x86:
797 * _start:	.globl	_start
798 *		int3
799 *		movl	$42, %ebx
800 *		movl	$1, %eax
801 *		int	$0x80
802 * (compile with: "gcc -nostartfiles -nostdlib -o int3 int3.S")
803 */
804static void
805test_ptrace_setoptions_for_all(void)
806{
807	const unsigned int test_options = PTRACE_O_TRACESYSGOOD | PTRACE_O_TRACEEXEC;
808	int pid;
809	int it_worked = 0;
810
811	pid = fork();
812	if (pid < 0)
813		perror_msg_and_die("fork");
814
815	if (pid == 0) {
816		pid = getpid();
817		if (ptrace(PTRACE_TRACEME, 0L, 0L, 0L) < 0)
818			/* Note: exits with exitcode 1 */
819			perror_msg_and_die("%s: PTRACE_TRACEME doesn't work", __func__);
820		kill(pid, SIGSTOP);
821		_exit(0); /* parent should see entry into this syscall */
822	}
823
824	while (1) {
825		int status, tracee_pid;
826
827		errno = 0;
828		tracee_pid = wait(&status);
829		if (tracee_pid <= 0) {
830			if (errno == EINTR)
831				continue;
832			kill(pid, SIGKILL);
833			perror_msg_and_die("%s: unexpected wait result %d", __func__, tracee_pid);
834		}
835		if (WIFEXITED(status)) {
836			if (WEXITSTATUS(status) == 0)
837				break;
838			/* PTRACE_TRACEME failed in child. This is fatal. */
839			exit(1);
840		}
841		if (!WIFSTOPPED(status)) {
842			kill(pid, SIGKILL);
843			error_msg_and_die("%s: unexpected wait status %x", __func__, status);
844		}
845		if (WSTOPSIG(status) == SIGSTOP) {
846			/*
847			 * We don't check "options aren't accepted" error.
848			 * If it happens, we'll never get (SIGTRAP | 0x80),
849			 * and thus will decide to not use the option.
850			 * IOW: the outcome of the test will be correct.
851			 */
852			if (ptrace(PTRACE_SETOPTIONS, pid, 0L, test_options) < 0)
853				if (errno != EINVAL)
854					perror_msg("PTRACE_SETOPTIONS");
855		}
856		if (WSTOPSIG(status) == (SIGTRAP | 0x80)) {
857			it_worked = 1;
858		}
859		if (ptrace(PTRACE_SYSCALL, pid, 0L, 0L) < 0) {
860			kill(pid, SIGKILL);
861			perror_msg_and_die("PTRACE_SYSCALL doesn't work");
862		}
863	}
864
865	if (it_worked) {
866		syscall_trap_sig = (SIGTRAP | 0x80);
867		ptrace_setoptions |= test_options;
868		if (debug)
869			fprintf(stderr, "ptrace_setoptions = %#x\n",
870				ptrace_setoptions);
871		return;
872	}
873
874	fprintf(stderr,
875		"Test for PTRACE_O_TRACESYSGOOD failed, giving up using this feature.\n");
876}
877#endif
878
879int
880main(int argc, char *argv[])
881{
882	struct tcb *tcp;
883	int c, pid = 0;
884	int optF = 0;
885	struct sigaction sa;
886
887	progname = argv[0] ? argv[0] : "strace";
888
889	strace_tracer_pid = getpid();
890
891	/* Allocate the initial tcbtab.  */
892	tcbtabsize = argc;	/* Surely enough for all -p args.  */
893	tcbtab = calloc(tcbtabsize, sizeof(tcbtab[0]));
894	if (tcbtab == NULL)
895		error_msg_and_die("Out of memory");
896	tcp = calloc(tcbtabsize, sizeof(*tcp));
897	if (tcp == NULL)
898		error_msg_and_die("Out of memory");
899	for (c = 0; c < tcbtabsize; c++)
900		tcbtab[c] = tcp++;
901
902	outf = stderr;
903	interactive = 1;
904	set_sortby(DEFAULT_SORTBY);
905	set_personality(DEFAULT_PERSONALITY);
906	qualify("trace=all");
907	qualify("abbrev=all");
908	qualify("verbose=all");
909	qualify("signal=all");
910	while ((c = getopt(argc, argv,
911		"+cCdfFhiqrtTvVxyz"
912#ifndef USE_PROCFS
913		"D"
914#endif
915		"a:e:o:O:p:s:S:u:E:P:")) != EOF) {
916		switch (c) {
917		case 'c':
918			if (cflag == CFLAG_BOTH) {
919				error_msg_and_die("-c and -C are mutually exclusive options");
920			}
921			cflag = CFLAG_ONLY_STATS;
922			break;
923		case 'C':
924			if (cflag == CFLAG_ONLY_STATS) {
925				error_msg_and_die("-c and -C are mutually exclusive options");
926			}
927			cflag = CFLAG_BOTH;
928			break;
929		case 'd':
930			debug++;
931			break;
932#ifndef USE_PROCFS
933		case 'D':
934			daemonized_tracer = 1;
935			break;
936#endif
937		case 'F':
938			optF = 1;
939			break;
940		case 'f':
941			followfork++;
942			break;
943		case 'h':
944			usage(stdout, 0);
945			break;
946		case 'i':
947			iflag++;
948			break;
949		case 'q':
950			qflag++;
951			break;
952		case 'r':
953			rflag++;
954			tflag++;
955			break;
956		case 't':
957			tflag++;
958			break;
959		case 'T':
960			dtime++;
961			break;
962		case 'x':
963			xflag++;
964			break;
965		case 'y':
966			show_fd_path = 1;
967			break;
968		case 'v':
969			qualify("abbrev=none");
970			break;
971		case 'V':
972			printf("%s -- version %s\n", PACKAGE_NAME, VERSION);
973			exit(0);
974			break;
975		case 'z':
976			not_failing_only = 1;
977			break;
978		case 'a':
979			acolumn = atoi(optarg);
980			break;
981		case 'e':
982			qualify(optarg);
983			break;
984		case 'o':
985			outfname = strdup(optarg);
986			break;
987		case 'O':
988			set_overhead(atoi(optarg));
989			break;
990		case 'p':
991			if ((pid = atoi(optarg)) <= 0) {
992				error_msg("Invalid process id: '%s'", optarg);
993				break;
994			}
995			if (pid == strace_tracer_pid) {
996				error_msg("I'm sorry, I can't let you do that, Dave.");
997				break;
998			}
999			tcp = alloc_tcb(pid, 0);
1000			tcp->flags |= TCB_ATTACHED;
1001			pflag_seen++;
1002			break;
1003		case 'P':
1004			tracing_paths = 1;
1005			if (pathtrace_select(optarg)) {
1006				error_msg_and_die("Failed to select path '%s'", optarg);
1007			}
1008			break;
1009		case 's':
1010			max_strlen = atoi(optarg);
1011			if (max_strlen < 0) {
1012				error_msg_and_die("Invalid -s argument: '%s'", optarg);
1013			}
1014			break;
1015		case 'S':
1016			set_sortby(optarg);
1017			break;
1018		case 'u':
1019			username = strdup(optarg);
1020			break;
1021		case 'E':
1022			if (putenv(optarg) < 0) {
1023				error_msg_and_die("Out of memory");
1024			}
1025			break;
1026		default:
1027			usage(stderr, 1);
1028			break;
1029		}
1030	}
1031
1032	if ((optind == argc) == !pflag_seen)
1033		usage(stderr, 1);
1034
1035	if (pflag_seen && daemonized_tracer) {
1036		error_msg_and_die("-D and -p are mutually exclusive options");
1037	}
1038
1039	if (!followfork)
1040		followfork = optF;
1041
1042	if (followfork > 1 && cflag) {
1043		error_msg_and_die("(-c or -C) and -ff are mutually exclusive options");
1044	}
1045
1046	/* See if they want to run as another user. */
1047	if (username != NULL) {
1048		struct passwd *pent;
1049
1050		if (getuid() != 0 || geteuid() != 0) {
1051			error_msg_and_die("You must be root to use the -u option");
1052		}
1053		if ((pent = getpwnam(username)) == NULL) {
1054			error_msg_and_die("Cannot find user '%s'", username);
1055		}
1056		run_uid = pent->pw_uid;
1057		run_gid = pent->pw_gid;
1058	}
1059	else {
1060		run_uid = getuid();
1061		run_gid = getgid();
1062	}
1063
1064#ifdef LINUX
1065	if (followfork) {
1066		if (test_ptrace_setoptions_followfork() < 0) {
1067			fprintf(stderr,
1068				"Test for options supported by PTRACE_SETOPTIONS "
1069				"failed, giving up using this feature.\n");
1070			ptrace_setoptions = 0;
1071		}
1072		if (debug)
1073			fprintf(stderr, "ptrace_setoptions = %#x\n",
1074				ptrace_setoptions);
1075	}
1076	test_ptrace_setoptions_for_all();
1077#endif
1078
1079	/* Check if they want to redirect the output. */
1080	if (outfname) {
1081		/* See if they want to pipe the output. */
1082		if (outfname[0] == '|' || outfname[0] == '!') {
1083			/*
1084			 * We can't do the <outfname>.PID funny business
1085			 * when using popen, so prohibit it.
1086			 */
1087			if (followfork > 1)
1088				error_msg_and_die("Piping the output and -ff are mutually exclusive");
1089			outf = strace_popen(outfname + 1);
1090		}
1091		else if (followfork <= 1)
1092			outf = strace_fopen(outfname);
1093	}
1094
1095	if (!outfname || outfname[0] == '|' || outfname[0] == '!') {
1096		static char buf[BUFSIZ];
1097		setvbuf(outf, buf, _IOLBF, BUFSIZ);
1098	}
1099	if (outfname && optind < argc) {
1100		interactive = 0;
1101		qflag = 1;
1102	}
1103
1104	/* Valid states here:
1105	   optind < argc	pflag_seen	outfname	interactive
1106	   1			0		0		1
1107	   0			1		0		1
1108	   1			0		1		0
1109	   0			1		1		1
1110	 */
1111
1112	/* STARTUP_CHILD must be called before the signal handlers get
1113	   installed below as they are inherited into the spawned process.
1114	   Also we do not need to be protected by them as during interruption
1115	   in the STARTUP_CHILD mode we kill the spawned process anyway.  */
1116	if (!pflag_seen)
1117		startup_child(&argv[optind]);
1118
1119	sigemptyset(&empty_set);
1120	sigemptyset(&blocked_set);
1121	sa.sa_handler = SIG_IGN;
1122	sigemptyset(&sa.sa_mask);
1123	sa.sa_flags = 0;
1124	sigaction(SIGTTOU, &sa, NULL);
1125	sigaction(SIGTTIN, &sa, NULL);
1126	if (interactive) {
1127		sigaddset(&blocked_set, SIGHUP);
1128		sigaddset(&blocked_set, SIGINT);
1129		sigaddset(&blocked_set, SIGQUIT);
1130		sigaddset(&blocked_set, SIGPIPE);
1131		sigaddset(&blocked_set, SIGTERM);
1132		sa.sa_handler = interrupt;
1133#ifdef SUNOS4
1134		/* POSIX signals on sunos4.1 are a little broken. */
1135		sa.sa_flags = SA_INTERRUPT;
1136#endif /* SUNOS4 */
1137	}
1138	sigaction(SIGHUP, &sa, NULL);
1139	sigaction(SIGINT, &sa, NULL);
1140	sigaction(SIGQUIT, &sa, NULL);
1141	sigaction(SIGPIPE, &sa, NULL);
1142	sigaction(SIGTERM, &sa, NULL);
1143#ifdef USE_PROCFS
1144	sa.sa_handler = reaper;
1145	sigaction(SIGCHLD, &sa, NULL);
1146#else
1147	/* Make sure SIGCHLD has the default action so that waitpid
1148	   definitely works without losing track of children.  The user
1149	   should not have given us a bogus state to inherit, but he might
1150	   have.  Arguably we should detect SIG_IGN here and pass it on
1151	   to children, but probably noone really needs that.  */
1152	sa.sa_handler = SIG_DFL;
1153	sigaction(SIGCHLD, &sa, NULL);
1154#endif /* USE_PROCFS */
1155
1156	if (pflag_seen || daemonized_tracer)
1157		startup_attach();
1158
1159	if (trace() < 0)
1160		exit(1);
1161	cleanup();
1162	fflush(NULL);
1163	if (exit_code > 0xff) {
1164		/* Child was killed by a signal, mimic that.  */
1165		exit_code &= 0xff;
1166		signal(exit_code, SIG_DFL);
1167		raise(exit_code);
1168		/* Paranoia - what if this signal is not fatal?
1169		   Exit with 128 + signo then.  */
1170		exit_code += 128;
1171	}
1172	exit(exit_code);
1173}
1174
1175static void
1176expand_tcbtab(void)
1177{
1178	/* Allocate some more TCBs and expand the table.
1179	   We don't want to relocate the TCBs because our
1180	   callers have pointers and it would be a pain.
1181	   So tcbtab is a table of pointers.  Since we never
1182	   free the TCBs, we allocate a single chunk of many.  */
1183	int i = tcbtabsize;
1184	struct tcb *newtcbs = calloc(tcbtabsize, sizeof(newtcbs[0]));
1185	struct tcb **newtab = realloc(tcbtab, tcbtabsize * 2 * sizeof(tcbtab[0]));
1186	if (newtab == NULL || newtcbs == NULL)
1187		error_msg_and_die("expand_tcbtab: out of memory");
1188	tcbtabsize *= 2;
1189	tcbtab = newtab;
1190	while (i < tcbtabsize)
1191		tcbtab[i++] = newtcbs++;
1192}
1193
1194struct tcb *
1195alloc_tcb(int pid, int command_options_parsed)
1196{
1197	int i;
1198	struct tcb *tcp;
1199
1200	if (nprocs == tcbtabsize)
1201		expand_tcbtab();
1202
1203	for (i = 0; i < tcbtabsize; i++) {
1204		tcp = tcbtab[i];
1205		if ((tcp->flags & TCB_INUSE) == 0) {
1206			memset(tcp, 0, sizeof(*tcp));
1207			tcp->pid = pid;
1208			tcp->flags = TCB_INUSE | TCB_STARTUP;
1209			tcp->outf = outf; /* Initialise to current out file */
1210			tcp->pfd = -1;
1211			nprocs++;
1212			if (debug)
1213				fprintf(stderr, "new tcb for pid %d, active tcbs:%d\n", tcp->pid, nprocs);
1214			if (command_options_parsed)
1215				newoutf(tcp);
1216			return tcp;
1217		}
1218	}
1219	error_msg_and_die("bug in alloc_tcb");
1220}
1221
1222#ifdef USE_PROCFS
1223int
1224proc_open(struct tcb *tcp, int attaching)
1225{
1226	char proc[32];
1227	long arg;
1228#ifdef SVR4
1229	int i;
1230	sysset_t syscalls;
1231	sigset_t signals;
1232	fltset_t faults;
1233#endif
1234#ifndef HAVE_POLLABLE_PROCFS
1235	static int last_pfd;
1236#endif
1237
1238#ifdef HAVE_MP_PROCFS
1239	/* Open the process pseudo-files in /proc. */
1240	sprintf(proc, "/proc/%d/ctl", tcp->pid);
1241	if ((tcp->pfd = open(proc, O_WRONLY|O_EXCL)) < 0) {
1242		perror("strace: open(\"/proc/...\", ...)");
1243		return -1;
1244	}
1245	set_cloexec_flag(tcp->pfd);
1246	sprintf(proc, "/proc/%d/status", tcp->pid);
1247	if ((tcp->pfd_stat = open(proc, O_RDONLY|O_EXCL)) < 0) {
1248		perror("strace: open(\"/proc/...\", ...)");
1249		return -1;
1250	}
1251	set_cloexec_flag(tcp->pfd_stat);
1252	sprintf(proc, "/proc/%d/as", tcp->pid);
1253	if ((tcp->pfd_as = open(proc, O_RDONLY|O_EXCL)) < 0) {
1254		perror("strace: open(\"/proc/...\", ...)");
1255		return -1;
1256	}
1257	set_cloexec_flag(tcp->pfd_as);
1258#else
1259	/* Open the process pseudo-file in /proc. */
1260#ifndef FREEBSD
1261	sprintf(proc, "/proc/%d", tcp->pid);
1262	tcp->pfd = open(proc, O_RDWR|O_EXCL);
1263#else /* FREEBSD */
1264	sprintf(proc, "/proc/%d/mem", tcp->pid);
1265	tcp->pfd = open(proc, O_RDWR);
1266#endif /* FREEBSD */
1267	if (tcp->pfd < 0) {
1268		perror("strace: open(\"/proc/...\", ...)");
1269		return -1;
1270	}
1271	set_cloexec_flag(tcp->pfd);
1272#endif
1273#ifdef FREEBSD
1274	sprintf(proc, "/proc/%d/regs", tcp->pid);
1275	if ((tcp->pfd_reg = open(proc, O_RDONLY)) < 0) {
1276		perror("strace: open(\"/proc/.../regs\", ...)");
1277		return -1;
1278	}
1279	if (cflag) {
1280		sprintf(proc, "/proc/%d/status", tcp->pid);
1281		if ((tcp->pfd_status = open(proc, O_RDONLY)) < 0) {
1282			perror("strace: open(\"/proc/.../status\", ...)");
1283			return -1;
1284		}
1285	} else
1286		tcp->pfd_status = -1;
1287#endif /* FREEBSD */
1288	rebuild_pollv();
1289	if (!attaching) {
1290		/*
1291		 * Wait for the child to pause.  Because of a race
1292		 * condition we have to poll for the event.
1293		 */
1294		for (;;) {
1295			if (IOCTL_STATUS(tcp) < 0) {
1296				perror("strace: PIOCSTATUS");
1297				return -1;
1298			}
1299			if (tcp->status.PR_FLAGS & PR_ASLEEP)
1300				break;
1301		}
1302	}
1303#ifndef FREEBSD
1304	/* Stop the process so that we own the stop. */
1305	if (IOCTL(tcp->pfd, PIOCSTOP, (char *)NULL) < 0) {
1306		perror("strace: PIOCSTOP");
1307		return -1;
1308	}
1309#endif
1310#ifdef PIOCSET
1311	/* Set Run-on-Last-Close. */
1312	arg = PR_RLC;
1313	if (IOCTL(tcp->pfd, PIOCSET, &arg) < 0) {
1314		perror("PIOCSET PR_RLC");
1315		return -1;
1316	}
1317	/* Set or Reset Inherit-on-Fork. */
1318	arg = PR_FORK;
1319	if (IOCTL(tcp->pfd, followfork ? PIOCSET : PIOCRESET, &arg) < 0) {
1320		perror("PIOC{SET,RESET} PR_FORK");
1321		return -1;
1322	}
1323#else  /* !PIOCSET */
1324#ifndef FREEBSD
1325	if (ioctl(tcp->pfd, PIOCSRLC) < 0) {
1326		perror("PIOCSRLC");
1327		return -1;
1328	}
1329	if (ioctl(tcp->pfd, followfork ? PIOCSFORK : PIOCRFORK) < 0) {
1330		perror("PIOC{S,R}FORK");
1331		return -1;
1332	}
1333#else /* FREEBSD */
1334	/* just unset the PF_LINGER flag for the Run-on-Last-Close. */
1335	if (ioctl(tcp->pfd, PIOCGFL, &arg) < 0) {
1336	        perror("PIOCGFL");
1337		return -1;
1338	}
1339	arg &= ~PF_LINGER;
1340	if (ioctl(tcp->pfd, PIOCSFL, arg) < 0) {
1341		perror("PIOCSFL");
1342		return -1;
1343	}
1344#endif /* FREEBSD */
1345#endif /* !PIOCSET */
1346#ifndef FREEBSD
1347	/* Enable all syscall entries we care about. */
1348	premptyset(&syscalls);
1349	for (i = 1; i < MAX_QUALS; ++i) {
1350		if (i > (sizeof syscalls) * CHAR_BIT) break;
1351		if (qual_flags[i] & QUAL_TRACE) praddset(&syscalls, i);
1352	}
1353	praddset(&syscalls, SYS_execve);
1354	if (followfork) {
1355		praddset(&syscalls, SYS_fork);
1356#ifdef SYS_forkall
1357		praddset(&syscalls, SYS_forkall);
1358#endif
1359#ifdef SYS_fork1
1360		praddset(&syscalls, SYS_fork1);
1361#endif
1362#ifdef SYS_rfork1
1363		praddset(&syscalls, SYS_rfork1);
1364#endif
1365#ifdef SYS_rforkall
1366		praddset(&syscalls, SYS_rforkall);
1367#endif
1368	}
1369	if (IOCTL(tcp->pfd, PIOCSENTRY, &syscalls) < 0) {
1370		perror("PIOCSENTRY");
1371		return -1;
1372	}
1373	/* Enable the syscall exits. */
1374	if (IOCTL(tcp->pfd, PIOCSEXIT, &syscalls) < 0) {
1375		perror("PIOSEXIT");
1376		return -1;
1377	}
1378	/* Enable signals we care about. */
1379	premptyset(&signals);
1380	for (i = 1; i < MAX_QUALS; ++i) {
1381		if (i > (sizeof signals) * CHAR_BIT) break;
1382		if (qual_flags[i] & QUAL_SIGNAL) praddset(&signals, i);
1383	}
1384	if (IOCTL(tcp->pfd, PIOCSTRACE, &signals) < 0) {
1385		perror("PIOCSTRACE");
1386		return -1;
1387	}
1388	/* Enable faults we care about */
1389	premptyset(&faults);
1390	for (i = 1; i < MAX_QUALS; ++i) {
1391		if (i > (sizeof faults) * CHAR_BIT) break;
1392		if (qual_flags[i] & QUAL_FAULT) praddset(&faults, i);
1393	}
1394	if (IOCTL(tcp->pfd, PIOCSFAULT, &faults) < 0) {
1395		perror("PIOCSFAULT");
1396		return -1;
1397	}
1398#else /* FREEBSD */
1399	/* set events flags. */
1400	arg = S_SIG | S_SCE | S_SCX;
1401	if (ioctl(tcp->pfd, PIOCBIS, arg) < 0) {
1402		perror("PIOCBIS");
1403		return -1;
1404	}
1405#endif /* FREEBSD */
1406	if (!attaching) {
1407#ifdef MIPS
1408		/*
1409		 * The SGI PRSABORT doesn't work for pause() so
1410		 * we send it a caught signal to wake it up.
1411		 */
1412		kill(tcp->pid, SIGINT);
1413#else /* !MIPS */
1414#ifdef PRSABORT
1415		/* The child is in a pause(), abort it. */
1416		arg = PRSABORT;
1417		if (IOCTL(tcp->pfd, PIOCRUN, &arg) < 0) {
1418			perror("PIOCRUN");
1419			return -1;
1420		}
1421#endif
1422#endif /* !MIPS*/
1423#ifdef FREEBSD
1424		/* wake up the child if it received the SIGSTOP */
1425		kill(tcp->pid, SIGCONT);
1426#endif
1427		for (;;) {
1428			/* Wait for the child to do something. */
1429			if (IOCTL_WSTOP(tcp) < 0) {
1430				perror("PIOCWSTOP");
1431				return -1;
1432			}
1433			if (tcp->status.PR_WHY == PR_SYSENTRY) {
1434				tcp->flags &= ~TCB_INSYSCALL;
1435				get_scno(tcp);
1436				if (known_scno(tcp) == SYS_execve)
1437					break;
1438			}
1439			/* Set it running: maybe execve will be next. */
1440#ifndef FREEBSD
1441			arg = 0;
1442			if (IOCTL(tcp->pfd, PIOCRUN, &arg) < 0) {
1443#else /* FREEBSD */
1444			if (IOCTL(tcp->pfd, PIOCRUN, 0) < 0) {
1445#endif /* FREEBSD */
1446				perror("PIOCRUN");
1447				return -1;
1448			}
1449#ifdef FREEBSD
1450			/* handle the case where we "opened" the child before
1451			   it did the kill -STOP */
1452			if (tcp->status.PR_WHY == PR_SIGNALLED &&
1453			    tcp->status.PR_WHAT == SIGSTOP)
1454			        kill(tcp->pid, SIGCONT);
1455#endif
1456		}
1457#ifndef FREEBSD
1458	}
1459#else /* FREEBSD */
1460	} else {
1461		if (attaching < 2) {
1462			/* We are attaching to an already running process.
1463			 * Try to figure out the state of the process in syscalls,
1464			 * to handle the first event well.
1465			 * This is done by having a look at the "wchan" property of the
1466			 * process, which tells where it is stopped (if it is). */
1467			FILE * status;
1468			char wchan[20]; /* should be enough */
1469
1470			sprintf(proc, "/proc/%d/status", tcp->pid);
1471			status = fopen(proc, "r");
1472			if (status &&
1473			    (fscanf(status, "%*s %*d %*d %*d %*d %*d,%*d %*s %*d,%*d"
1474				    "%*d,%*d %*d,%*d %19s", wchan) == 1) &&
1475			    strcmp(wchan, "nochan") && strcmp(wchan, "spread") &&
1476			    strcmp(wchan, "stopevent")) {
1477				/* The process is asleep in the middle of a syscall.
1478				   Fake the syscall entry event */
1479				tcp->flags &= ~(TCB_INSYSCALL|TCB_STARTUP);
1480				tcp->status.PR_WHY = PR_SYSENTRY;
1481				trace_syscall(tcp);
1482			}
1483			if (status)
1484				fclose(status);
1485		} /* otherwise it's a fork being followed */
1486	}
1487#endif /* FREEBSD */
1488#ifndef HAVE_POLLABLE_PROCFS
1489	if (proc_poll_pipe[0] != -1)
1490		proc_poller(tcp->pfd);
1491	else if (nprocs > 1) {
1492		proc_poll_open();
1493		proc_poller(last_pfd);
1494		proc_poller(tcp->pfd);
1495	}
1496	last_pfd = tcp->pfd;
1497#endif /* !HAVE_POLLABLE_PROCFS */
1498	return 0;
1499}
1500
1501#endif /* USE_PROCFS */
1502
1503struct tcb *
1504pid2tcb(int pid)
1505{
1506	int i;
1507
1508	if (pid <= 0)
1509		return NULL;
1510
1511	for (i = 0; i < tcbtabsize; i++) {
1512		struct tcb *tcp = tcbtab[i];
1513		if (tcp->pid == pid && (tcp->flags & TCB_INUSE))
1514			return tcp;
1515	}
1516
1517	return NULL;
1518}
1519
1520#ifdef USE_PROCFS
1521
1522static struct tcb *
1523first_used_tcb(void)
1524{
1525	int i;
1526	struct tcb *tcp;
1527	for (i = 0; i < tcbtabsize; i++) {
1528		tcp = tcbtab[i];
1529		if (tcp->flags & TCB_INUSE)
1530			return tcp;
1531	}
1532	return NULL;
1533}
1534
1535static struct tcb *
1536pfd2tcb(int pfd)
1537{
1538	int i;
1539
1540	for (i = 0; i < tcbtabsize; i++) {
1541		struct tcb *tcp = tcbtab[i];
1542		if (tcp->pfd != pfd)
1543			continue;
1544		if (tcp->flags & TCB_INUSE)
1545			return tcp;
1546	}
1547	return NULL;
1548}
1549
1550#endif /* USE_PROCFS */
1551
1552void
1553droptcb(struct tcb *tcp)
1554{
1555	if (tcp->pid == 0)
1556		return;
1557#ifdef TCB_CLONE_THREAD
1558	if (tcp->nclone_threads > 0) {
1559		/* There are other threads left in this process, but this
1560		   is the one whose PID represents the whole process.
1561		   We need to keep this record around as a zombie until
1562		   all the threads die.  */
1563		tcp->flags |= TCB_EXITING;
1564		return;
1565	}
1566#endif
1567	nprocs--;
1568	if (debug)
1569		fprintf(stderr, "dropped tcb for pid %d, %d remain\n", tcp->pid, nprocs);
1570	tcp->pid = 0;
1571
1572	if (tcp->parent != NULL) {
1573#ifdef TCB_CLONE_THREAD
1574		if (tcp->flags & TCB_CLONE_THREAD)
1575			tcp->parent->nclone_threads--;
1576#endif
1577#ifdef LINUX
1578		/* Update fields like NCLONE_DETACHED, only
1579		   for zombie group leader that has already reported
1580		   and been short-circuited at the top of this
1581		   function.  The same condition as at the top of DETACH.  */
1582		if ((tcp->flags & TCB_CLONE_THREAD) &&
1583		    tcp->parent->nclone_threads == 0 &&
1584		    (tcp->parent->flags & TCB_EXITING))
1585			droptcb(tcp->parent);
1586#endif
1587		tcp->parent = NULL;
1588	}
1589
1590	tcp->flags = 0;
1591	if (tcp->pfd != -1) {
1592		close(tcp->pfd);
1593		tcp->pfd = -1;
1594#ifdef FREEBSD
1595		if (tcp->pfd_reg != -1) {
1596		        close(tcp->pfd_reg);
1597		        tcp->pfd_reg = -1;
1598		}
1599		if (tcp->pfd_status != -1) {
1600			close(tcp->pfd_status);
1601			tcp->pfd_status = -1;
1602		}
1603#endif /* !FREEBSD */
1604#ifdef USE_PROCFS
1605		rebuild_pollv(); /* Note, flags needs to be cleared by now.  */
1606#endif
1607	}
1608
1609	if (outfname && followfork > 1 && tcp->outf)
1610		fclose(tcp->outf);
1611
1612	tcp->outf = 0;
1613}
1614
1615/* detach traced process; continue with sig
1616   Never call DETACH twice on the same process as both unattached and
1617   attached-unstopped processes give the same ESRCH.  For unattached process we
1618   would SIGSTOP it and wait for its SIGSTOP notification forever.  */
1619
1620static int
1621detach(struct tcb *tcp, int sig)
1622{
1623	int error = 0;
1624#ifdef LINUX
1625	int status, catch_sigstop;
1626	struct tcb *zombie = NULL;
1627
1628	/* If the group leader is lingering only because of this other
1629	   thread now dying, then detach the leader as well.  */
1630	if ((tcp->flags & TCB_CLONE_THREAD) &&
1631	    tcp->parent->nclone_threads == 1 &&
1632	    (tcp->parent->flags & TCB_EXITING))
1633		zombie = tcp->parent;
1634#endif
1635
1636	if (tcp->flags & TCB_BPTSET)
1637		clearbpt(tcp);
1638
1639#ifdef LINUX
1640	/*
1641	 * Linux wrongly insists the child be stopped
1642	 * before detaching.  Arghh.  We go through hoops
1643	 * to make a clean break of things.
1644	 */
1645#if defined(SPARC)
1646#undef PTRACE_DETACH
1647#define PTRACE_DETACH PTRACE_SUNDETACH
1648#endif
1649	/*
1650	 * On TCB_STARTUP we did PTRACE_ATTACH but still did not get the
1651	 * expected SIGSTOP.  We must catch exactly one as otherwise the
1652	 * detached process would be left stopped (process state T).
1653	 */
1654	catch_sigstop = (tcp->flags & TCB_STARTUP);
1655	if ((error = ptrace(PTRACE_DETACH, tcp->pid, (char *) 1, sig)) == 0) {
1656		/* On a clear day, you can see forever. */
1657	}
1658	else if (errno != ESRCH) {
1659		/* Shouldn't happen. */
1660		perror("detach: ptrace(PTRACE_DETACH, ...)");
1661	}
1662	else if (my_tgkill((tcp->flags & TCB_CLONE_THREAD ? tcp->parent->pid
1663							  : tcp->pid),
1664			   tcp->pid, 0) < 0) {
1665		if (errno != ESRCH)
1666			perror("detach: checking sanity");
1667	}
1668	else if (!catch_sigstop && my_tgkill((tcp->flags & TCB_CLONE_THREAD
1669					      ? tcp->parent->pid : tcp->pid),
1670					     tcp->pid, SIGSTOP) < 0) {
1671		if (errno != ESRCH)
1672			perror("detach: stopping child");
1673	}
1674	else
1675		catch_sigstop = 1;
1676	if (catch_sigstop) {
1677		for (;;) {
1678#ifdef __WALL
1679			if (wait4(tcp->pid, &status, __WALL, NULL) < 0) {
1680				if (errno == ECHILD) /* Already gone.  */
1681					break;
1682				if (errno != EINVAL) {
1683					perror("detach: waiting");
1684					break;
1685				}
1686#endif /* __WALL */
1687				/* No __WALL here.  */
1688				if (waitpid(tcp->pid, &status, 0) < 0) {
1689					if (errno != ECHILD) {
1690						perror("detach: waiting");
1691						break;
1692					}
1693#ifdef __WCLONE
1694					/* If no processes, try clones.  */
1695					if (wait4(tcp->pid, &status, __WCLONE,
1696						  NULL) < 0) {
1697						if (errno != ECHILD)
1698							perror("detach: waiting");
1699						break;
1700					}
1701#endif /* __WCLONE */
1702				}
1703#ifdef __WALL
1704			}
1705#endif
1706			if (!WIFSTOPPED(status)) {
1707				/* Au revoir, mon ami. */
1708				break;
1709			}
1710			if (WSTOPSIG(status) == SIGSTOP) {
1711				ptrace_restart(PTRACE_DETACH, tcp, sig);
1712				break;
1713			}
1714			error = ptrace_restart(PTRACE_CONT, tcp,
1715					WSTOPSIG(status) == syscall_trap_sig ? 0
1716					: WSTOPSIG(status));
1717			if (error < 0)
1718				break;
1719		}
1720	}
1721#endif /* LINUX */
1722
1723#if defined(SUNOS4)
1724	/* PTRACE_DETACH won't respect `sig' argument, so we post it here. */
1725	if (sig && kill(tcp->pid, sig) < 0)
1726		perror("detach: kill");
1727	sig = 0;
1728	error = ptrace_restart(PTRACE_DETACH, tcp, sig);
1729#endif /* SUNOS4 */
1730
1731	if (!qflag)
1732		fprintf(stderr, "Process %u detached\n", tcp->pid);
1733
1734	droptcb(tcp);
1735
1736#ifdef LINUX
1737	if (zombie != NULL) {
1738		/* TCP no longer exists therefore you must not detach() it.  */
1739		droptcb(zombie);
1740	}
1741#endif
1742
1743	return error;
1744}
1745
1746#ifdef USE_PROCFS
1747
1748static void reaper(int sig)
1749{
1750	int pid;
1751	int status;
1752
1753	while ((pid = waitpid(-1, &status, WNOHANG)) > 0) {
1754	}
1755}
1756
1757#endif /* USE_PROCFS */
1758
1759static void
1760cleanup(void)
1761{
1762	int i;
1763	struct tcb *tcp;
1764
1765	for (i = 0; i < tcbtabsize; i++) {
1766		tcp = tcbtab[i];
1767		if (!(tcp->flags & TCB_INUSE))
1768			continue;
1769		if (debug)
1770			fprintf(stderr,
1771				"cleanup: looking at pid %u\n", tcp->pid);
1772		if (tcp_last &&
1773		    (!outfname || followfork < 2 || tcp_last == tcp)) {
1774			tprintf(" <unfinished ...>");
1775			printtrailer();
1776		}
1777		if (tcp->flags & TCB_ATTACHED)
1778			detach(tcp, 0);
1779		else {
1780			kill(tcp->pid, SIGCONT);
1781			kill(tcp->pid, SIGTERM);
1782		}
1783	}
1784	if (cflag)
1785		call_summary(outf);
1786}
1787
1788static void
1789interrupt(int sig)
1790{
1791	interrupted = 1;
1792}
1793
1794#ifndef HAVE_STRERROR
1795
1796#if !HAVE_DECL_SYS_ERRLIST
1797extern int sys_nerr;
1798extern char *sys_errlist[];
1799#endif /* HAVE_DECL_SYS_ERRLIST */
1800
1801const char *
1802strerror(int err_no)
1803{
1804	static char buf[64];
1805
1806	if (err_no < 1 || err_no >= sys_nerr) {
1807		sprintf(buf, "Unknown error %d", err_no);
1808		return buf;
1809	}
1810	return sys_errlist[err_no];
1811}
1812
1813#endif /* HAVE_STERRROR */
1814
1815#ifndef HAVE_STRSIGNAL
1816
1817#if defined HAVE_SYS_SIGLIST && !defined HAVE_DECL_SYS_SIGLIST
1818extern char *sys_siglist[];
1819#endif
1820#if defined HAVE_SYS__SIGLIST && !defined HAVE_DECL__SYS_SIGLIST
1821extern char *_sys_siglist[];
1822#endif
1823
1824const char *
1825strsignal(int sig)
1826{
1827	static char buf[64];
1828
1829	if (sig < 1 || sig >= NSIG) {
1830		sprintf(buf, "Unknown signal %d", sig);
1831		return buf;
1832	}
1833#ifdef HAVE__SYS_SIGLIST
1834	return _sys_siglist[sig];
1835#else
1836	return sys_siglist[sig];
1837#endif
1838}
1839
1840#endif /* HAVE_STRSIGNAL */
1841
1842#ifdef USE_PROCFS
1843
1844static void
1845rebuild_pollv(void)
1846{
1847	int i, j;
1848
1849	if (pollv != NULL)
1850		free(pollv);
1851	pollv = (struct pollfd *) malloc(nprocs * sizeof pollv[0]);
1852	if (pollv == NULL) {
1853		error_msg_and_die("Out of memory");
1854	}
1855
1856	for (i = j = 0; i < tcbtabsize; i++) {
1857		struct tcb *tcp = tcbtab[i];
1858		if (!(tcp->flags & TCB_INUSE))
1859			continue;
1860		pollv[j].fd = tcp->pfd;
1861		pollv[j].events = POLLWANT;
1862		j++;
1863	}
1864	if (j != nprocs) {
1865		error_msg_and_die("proc miscount");
1866	}
1867}
1868
1869#ifndef HAVE_POLLABLE_PROCFS
1870
1871static void
1872proc_poll_open(void)
1873{
1874	int i;
1875
1876	if (pipe(proc_poll_pipe) < 0) {
1877		perror_msg_and_die("pipe");
1878	}
1879	for (i = 0; i < 2; i++) {
1880		set_cloexec_flag(proc_poll_pipe[i]);
1881	}
1882}
1883
1884static int
1885proc_poll(struct pollfd *pollv, int nfds, int timeout)
1886{
1887	int i;
1888	int n;
1889	struct proc_pollfd pollinfo;
1890
1891	if ((n = read(proc_poll_pipe[0], &pollinfo, sizeof(pollinfo))) < 0)
1892		return n;
1893	if (n != sizeof(struct proc_pollfd)) {
1894		error_msg_and_die("panic: short read: %d", n);
1895	}
1896	for (i = 0; i < nprocs; i++) {
1897		if (pollv[i].fd == pollinfo.fd)
1898			pollv[i].revents = pollinfo.revents;
1899		else
1900			pollv[i].revents = 0;
1901	}
1902	poller_pid = pollinfo.pid;
1903	return 1;
1904}
1905
1906static void
1907wakeup_handler(int sig)
1908{
1909}
1910
1911static void
1912proc_poller(int pfd)
1913{
1914	struct proc_pollfd pollinfo;
1915	struct sigaction sa;
1916	sigset_t blocked_set, empty_set;
1917	int i;
1918	int n;
1919	struct rlimit rl;
1920#ifdef FREEBSD
1921	struct procfs_status pfs;
1922#endif /* FREEBSD */
1923
1924	switch (fork()) {
1925	case -1:
1926		perror_msg_and_die("fork");
1927	case 0:
1928		break;
1929	default:
1930		return;
1931	}
1932
1933	sa.sa_handler = interactive ? SIG_DFL : SIG_IGN;
1934	sa.sa_flags = 0;
1935	sigemptyset(&sa.sa_mask);
1936	sigaction(SIGHUP, &sa, NULL);
1937	sigaction(SIGINT, &sa, NULL);
1938	sigaction(SIGQUIT, &sa, NULL);
1939	sigaction(SIGPIPE, &sa, NULL);
1940	sigaction(SIGTERM, &sa, NULL);
1941	sa.sa_handler = wakeup_handler;
1942	sigaction(SIGUSR1, &sa, NULL);
1943	sigemptyset(&blocked_set);
1944	sigaddset(&blocked_set, SIGUSR1);
1945	sigprocmask(SIG_BLOCK, &blocked_set, NULL);
1946	sigemptyset(&empty_set);
1947
1948	if (getrlimit(RLIMIT_NOFILE, &rl) < 0) {
1949		perror_msg_and_die("getrlimit(RLIMIT_NOFILE, ...)");
1950	}
1951	n = rl.rlim_cur;
1952	for (i = 0; i < n; i++) {
1953		if (i != pfd && i != proc_poll_pipe[1])
1954			close(i);
1955	}
1956
1957	pollinfo.fd = pfd;
1958	pollinfo.pid = getpid();
1959	for (;;) {
1960#ifndef FREEBSD
1961		if (ioctl(pfd, PIOCWSTOP, NULL) < 0)
1962#else
1963		if (ioctl(pfd, PIOCWSTOP, &pfs) < 0)
1964#endif
1965		{
1966			switch (errno) {
1967			case EINTR:
1968				continue;
1969			case EBADF:
1970				pollinfo.revents = POLLERR;
1971				break;
1972			case ENOENT:
1973				pollinfo.revents = POLLHUP;
1974				break;
1975			default:
1976				perror("proc_poller: PIOCWSTOP");
1977			}
1978			write(proc_poll_pipe[1], &pollinfo, sizeof(pollinfo));
1979			_exit(0);
1980		}
1981		pollinfo.revents = POLLWANT;
1982		write(proc_poll_pipe[1], &pollinfo, sizeof(pollinfo));
1983		sigsuspend(&empty_set);
1984	}
1985}
1986
1987#endif /* !HAVE_POLLABLE_PROCFS */
1988
1989static int
1990choose_pfd()
1991{
1992	int i, j;
1993	struct tcb *tcp;
1994
1995	static int last;
1996
1997	if (followfork < 2 &&
1998	    last < nprocs && (pollv[last].revents & POLLWANT)) {
1999		/*
2000		 * The previous process is ready to run again.  We'll
2001		 * let it do so if it is currently in a syscall.  This
2002		 * heuristic improves the readability of the trace.
2003		 */
2004		tcp = pfd2tcb(pollv[last].fd);
2005		if (tcp && (tcp->flags & TCB_INSYSCALL))
2006			return pollv[last].fd;
2007	}
2008
2009	for (i = 0; i < nprocs; i++) {
2010		/* Let competing children run round robin. */
2011		j = (i + last + 1) % nprocs;
2012		if (pollv[j].revents & (POLLHUP | POLLERR)) {
2013			tcp = pfd2tcb(pollv[j].fd);
2014			if (!tcp) {
2015				error_msg_and_die("lost proc");
2016			}
2017			droptcb(tcp);
2018			return -1;
2019		}
2020		if (pollv[j].revents & POLLWANT) {
2021			last = j;
2022			return pollv[j].fd;
2023		}
2024	}
2025	error_msg_and_die("nothing ready");
2026}
2027
2028static int
2029trace(void)
2030{
2031#ifdef POLL_HACK
2032	struct tcb *in_syscall = NULL;
2033#endif
2034	struct tcb *tcp;
2035	int pfd;
2036	int what;
2037	int ioctl_result = 0, ioctl_errno = 0;
2038	long arg;
2039
2040	for (;;) {
2041		if (interactive)
2042			sigprocmask(SIG_SETMASK, &empty_set, NULL);
2043
2044		if (nprocs == 0)
2045			break;
2046
2047		switch (nprocs) {
2048		case 1:
2049#ifndef HAVE_POLLABLE_PROCFS
2050			if (proc_poll_pipe[0] == -1) {
2051#endif
2052				tcp = first_used_tcb();
2053				if (!tcp)
2054					continue;
2055				pfd = tcp->pfd;
2056				if (pfd == -1)
2057					continue;
2058				break;
2059#ifndef HAVE_POLLABLE_PROCFS
2060			}
2061			/* fall through ... */
2062#endif /* !HAVE_POLLABLE_PROCFS */
2063		default:
2064#ifdef HAVE_POLLABLE_PROCFS
2065#ifdef POLL_HACK
2066		        /* On some systems (e.g. UnixWare) we get too much ugly
2067			   "unfinished..." stuff when multiple proceses are in
2068			   syscalls.  Here's a nasty hack */
2069
2070			if (in_syscall) {
2071				struct pollfd pv;
2072				tcp = in_syscall;
2073				in_syscall = NULL;
2074				pv.fd = tcp->pfd;
2075				pv.events = POLLWANT;
2076				if ((what = poll(&pv, 1, 1)) < 0) {
2077					if (interrupted)
2078						return 0;
2079					continue;
2080				}
2081				else if (what == 1 && pv.revents & POLLWANT) {
2082					goto FOUND;
2083				}
2084			}
2085#endif
2086
2087			if (poll(pollv, nprocs, INFTIM) < 0) {
2088				if (interrupted)
2089					return 0;
2090				continue;
2091			}
2092#else /* !HAVE_POLLABLE_PROCFS */
2093			if (proc_poll(pollv, nprocs, INFTIM) < 0) {
2094				if (interrupted)
2095					return 0;
2096				continue;
2097			}
2098#endif /* !HAVE_POLLABLE_PROCFS */
2099			pfd = choose_pfd();
2100			if (pfd == -1)
2101				continue;
2102			break;
2103		}
2104
2105		/* Look up `pfd' in our table. */
2106		if ((tcp = pfd2tcb(pfd)) == NULL) {
2107			error_msg_and_die("unknown pfd: %u", pfd);
2108		}
2109#ifdef POLL_HACK
2110	FOUND:
2111#endif
2112		/* Get the status of the process. */
2113		if (!interrupted) {
2114#ifndef FREEBSD
2115			ioctl_result = IOCTL_WSTOP(tcp);
2116#else /* FREEBSD */
2117			/* Thanks to some scheduling mystery, the first poller
2118			   sometimes waits for the already processed end of fork
2119			   event. Doing a non blocking poll here solves the problem. */
2120			if (proc_poll_pipe[0] != -1)
2121				ioctl_result = IOCTL_STATUS(tcp);
2122			else
2123				ioctl_result = IOCTL_WSTOP(tcp);
2124#endif /* FREEBSD */
2125			ioctl_errno = errno;
2126#ifndef HAVE_POLLABLE_PROCFS
2127			if (proc_poll_pipe[0] != -1) {
2128				if (ioctl_result < 0)
2129					kill(poller_pid, SIGKILL);
2130				else
2131					kill(poller_pid, SIGUSR1);
2132			}
2133#endif /* !HAVE_POLLABLE_PROCFS */
2134		}
2135		if (interrupted)
2136			return 0;
2137
2138		if (interactive)
2139			sigprocmask(SIG_BLOCK, &blocked_set, NULL);
2140
2141		if (ioctl_result < 0) {
2142			/* Find out what happened if it failed. */
2143			switch (ioctl_errno) {
2144			case EINTR:
2145			case EBADF:
2146				continue;
2147#ifdef FREEBSD
2148			case ENOTTY:
2149#endif
2150			case ENOENT:
2151				droptcb(tcp);
2152				continue;
2153			default:
2154				perror_msg_and_die("PIOCWSTOP");
2155			}
2156		}
2157
2158#ifdef FREEBSD
2159		if ((tcp->flags & TCB_STARTUP) && (tcp->status.PR_WHY == PR_SYSEXIT)) {
2160			/* discard first event for a syscall we never entered */
2161			IOCTL(tcp->pfd, PIOCRUN, 0);
2162			continue;
2163		}
2164#endif
2165
2166		/* clear the just started flag */
2167		tcp->flags &= ~TCB_STARTUP;
2168
2169		/* set current output file */
2170		outf = tcp->outf;
2171		curcol = tcp->curcol;
2172
2173		if (cflag) {
2174			struct timeval stime;
2175#ifdef FREEBSD
2176			char buf[1024];
2177			int len;
2178
2179			if ((len = pread(tcp->pfd_status, buf, sizeof(buf) - 1, 0)) > 0) {
2180				buf[len] = '\0';
2181				sscanf(buf,
2182				       "%*s %*d %*d %*d %*d %*d,%*d %*s %*d,%*d %*d,%*d %ld,%ld",
2183				       &stime.tv_sec, &stime.tv_usec);
2184			} else
2185				stime.tv_sec = stime.tv_usec = 0;
2186#else /* !FREEBSD */
2187			stime.tv_sec = tcp->status.pr_stime.tv_sec;
2188			stime.tv_usec = tcp->status.pr_stime.tv_nsec/1000;
2189#endif /* !FREEBSD */
2190			tv_sub(&tcp->dtime, &stime, &tcp->stime);
2191			tcp->stime = stime;
2192		}
2193		what = tcp->status.PR_WHAT;
2194		switch (tcp->status.PR_WHY) {
2195#ifndef FREEBSD
2196		case PR_REQUESTED:
2197			if (tcp->status.PR_FLAGS & PR_ASLEEP) {
2198				tcp->status.PR_WHY = PR_SYSENTRY;
2199				if (trace_syscall(tcp) < 0) {
2200					error_msg_and_die("syscall trouble");
2201				}
2202			}
2203			break;
2204#endif /* !FREEBSD */
2205		case PR_SYSENTRY:
2206#ifdef POLL_HACK
2207		        in_syscall = tcp;
2208#endif
2209		case PR_SYSEXIT:
2210			if (trace_syscall(tcp) < 0) {
2211				error_msg_and_die("syscall trouble");
2212			}
2213			break;
2214		case PR_SIGNALLED:
2215			if (cflag != CFLAG_ONLY_STATS
2216			    && (qual_flags[what] & QUAL_SIGNAL)) {
2217				printleader(tcp);
2218				tprintf("--- %s (%s) ---",
2219					signame(what), strsignal(what));
2220				printtrailer();
2221#ifdef PR_INFO
2222				if (tcp->status.PR_INFO.si_signo == what) {
2223					printleader(tcp);
2224					tprintf("    siginfo=");
2225					printsiginfo(&tcp->status.PR_INFO, 1);
2226					printtrailer();
2227				}
2228#endif
2229			}
2230			break;
2231		case PR_FAULTED:
2232			if (cflag != CFLAGS_ONLY_STATS
2233			    && (qual_flags[what] & QUAL_FAULT)) {
2234				printleader(tcp);
2235				tprintf("=== FAULT %d ===", what);
2236				printtrailer();
2237			}
2238			break;
2239#ifdef FREEBSD
2240		case 0: /* handle case we polled for nothing */
2241			continue;
2242#endif
2243		default:
2244			error_msg_and_die("odd stop %d", tcp->status.PR_WHY);
2245			break;
2246		}
2247		/* Remember current print column before continuing. */
2248		tcp->curcol = curcol;
2249		arg = 0;
2250#ifndef FREEBSD
2251		if (IOCTL(tcp->pfd, PIOCRUN, &arg) < 0)
2252#else
2253		if (IOCTL(tcp->pfd, PIOCRUN, 0) < 0)
2254#endif
2255		{
2256			perror_msg_and_die("PIOCRUN");
2257		}
2258	}
2259	return 0;
2260}
2261
2262#else /* !USE_PROCFS */
2263
2264#ifdef TCB_GROUP_EXITING
2265/* Handle an exit detach or death signal that is taking all the
2266   related clone threads with it.  This is called in three circumstances:
2267   SIG == -1	TCP has already died (TCB_ATTACHED is clear, strace is parent).
2268   SIG == 0	Continuing TCP will perform an exit_group syscall.
2269   SIG == other	Continuing TCP with SIG will kill the process.
2270*/
2271static int
2272handle_group_exit(struct tcb *tcp, int sig)
2273{
2274	/* We need to locate our records of all the clone threads
2275	   related to TCP, either its children or siblings.  */
2276	struct tcb *leader = NULL;
2277
2278	if (tcp->flags & TCB_CLONE_THREAD)
2279		leader = tcp->parent;
2280
2281	if (sig < 0) {
2282		if (leader != NULL && leader != tcp
2283		 && !(leader->flags & TCB_GROUP_EXITING)
2284		 && !(tcp->flags & TCB_STARTUP)
2285		) {
2286			fprintf(stderr,
2287				"PANIC: handle_group_exit: %d leader %d\n",
2288				tcp->pid, leader ? leader->pid : -1);
2289		}
2290		/* TCP no longer exists therefore you must not detach() it.  */
2291		droptcb(tcp);	/* Already died.  */
2292	}
2293	else {
2294		/* Mark that we are taking the process down.  */
2295		tcp->flags |= TCB_EXITING | TCB_GROUP_EXITING;
2296		if (tcp->flags & TCB_ATTACHED) {
2297			detach(tcp, sig);
2298			if (leader != NULL && leader != tcp)
2299				leader->flags |= TCB_GROUP_EXITING;
2300		} else {
2301			if (ptrace_restart(PTRACE_CONT, tcp, sig) < 0) {
2302				cleanup();
2303				return -1;
2304			}
2305			if (leader != NULL) {
2306				leader->flags |= TCB_GROUP_EXITING;
2307				if (leader != tcp)
2308					droptcb(tcp);
2309			}
2310			/* The leader will report to us as parent now,
2311			   and then we'll get to the SIG==-1 case.  */
2312			return 0;
2313		}
2314	}
2315
2316	return 0;
2317}
2318#endif
2319
2320#ifdef LINUX
2321static int
2322handle_ptrace_event(int status, struct tcb *tcp)
2323{
2324	if (status >> 16 == PTRACE_EVENT_VFORK ||
2325	    status >> 16 == PTRACE_EVENT_CLONE ||
2326	    status >> 16 == PTRACE_EVENT_FORK) {
2327		long childpid;
2328
2329		if (do_ptrace(PTRACE_GETEVENTMSG, tcp, NULL, &childpid) < 0) {
2330			if (errno != ESRCH) {
2331				error_msg_and_die("Cannot get new child's pid");
2332			}
2333			return -1;
2334		}
2335		return handle_new_child(tcp, childpid, 0);
2336	}
2337	if (status >> 16 == PTRACE_EVENT_EXEC) {
2338		return 0;
2339	}
2340	/* Some PTRACE_EVENT_foo we didn't ask for?! */
2341	error_msg("Unexpected status %x on pid %d", status, tcp->pid);
2342	return 1;
2343}
2344#endif
2345
2346static int
2347trace()
2348{
2349	int pid;
2350	int wait_errno;
2351	int status;
2352	struct tcb *tcp;
2353#ifdef LINUX
2354	struct rusage ru;
2355#ifdef __WALL
2356	static int wait4_options = __WALL;
2357#endif
2358#endif /* LINUX */
2359
2360	while (nprocs != 0) {
2361		if (interrupted)
2362			return 0;
2363		if (interactive)
2364			sigprocmask(SIG_SETMASK, &empty_set, NULL);
2365#ifdef LINUX
2366#ifdef __WALL
2367		pid = wait4(-1, &status, wait4_options, cflag ? &ru : NULL);
2368		if (pid < 0 && (wait4_options & __WALL) && errno == EINVAL) {
2369			/* this kernel does not support __WALL */
2370			wait4_options &= ~__WALL;
2371			errno = 0;
2372			pid = wait4(-1, &status, wait4_options,
2373					cflag ? &ru : NULL);
2374		}
2375		if (pid < 0 && !(wait4_options & __WALL) && errno == ECHILD) {
2376			/* most likely a "cloned" process */
2377			pid = wait4(-1, &status, __WCLONE,
2378					cflag ? &ru : NULL);
2379			if (pid == -1) {
2380				perror_msg("wait4(__WCLONE) failed");
2381			}
2382		}
2383#else
2384		pid = wait4(-1, &status, 0, cflag ? &ru : NULL);
2385#endif /* __WALL */
2386#endif /* LINUX */
2387#ifdef SUNOS4
2388		pid = wait(&status);
2389#endif /* SUNOS4 */
2390		wait_errno = errno;
2391		if (interactive)
2392			sigprocmask(SIG_BLOCK, &blocked_set, NULL);
2393
2394		if (pid == -1) {
2395			switch (wait_errno) {
2396			case EINTR:
2397				continue;
2398			case ECHILD:
2399				/*
2400				 * We would like to verify this case
2401				 * but sometimes a race in Solbourne's
2402				 * version of SunOS sometimes reports
2403				 * ECHILD before sending us SIGCHILD.
2404				 */
2405				return 0;
2406			default:
2407				errno = wait_errno;
2408				perror("strace: wait");
2409				return -1;
2410			}
2411		}
2412		if (pid == popen_pid) {
2413			if (WIFEXITED(status) || WIFSIGNALED(status))
2414				popen_pid = 0;
2415			continue;
2416		}
2417		if (debug) {
2418			char buf[sizeof("WIFEXITED,exitcode=%u") + sizeof(int)*3 /*paranoia:*/ + 16];
2419#ifdef LINUX
2420			unsigned ev = (unsigned)status >> 16;
2421			if (ev) {
2422				static const char *const event_names[] = {
2423					[PTRACE_EVENT_CLONE] = "CLONE",
2424					[PTRACE_EVENT_FORK]  = "FORK",
2425					[PTRACE_EVENT_VFORK] = "VFORK",
2426					[PTRACE_EVENT_VFORK_DONE] = "VFORK_DONE",
2427					[PTRACE_EVENT_EXEC]  = "EXEC",
2428					[PTRACE_EVENT_EXIT]  = "EXIT",
2429				};
2430				const char *e;
2431				if (ev < ARRAY_SIZE(event_names))
2432					e = event_names[ev];
2433				else {
2434					sprintf(buf, "?? (%u)", ev);
2435					e = buf;
2436				}
2437				fprintf(stderr, " PTRACE_EVENT_%s", e);
2438			}
2439#endif
2440			strcpy(buf, "???");
2441			if (WIFSIGNALED(status))
2442#ifdef WCOREDUMP
2443				sprintf(buf, "WIFSIGNALED,%ssig=%s",
2444						WCOREDUMP(status) ? "core," : "",
2445						signame(WTERMSIG(status)));
2446#else
2447				sprintf(buf, "WIFSIGNALED,sig=%s",
2448						signame(WTERMSIG(status)));
2449#endif
2450			if (WIFEXITED(status))
2451				sprintf(buf, "WIFEXITED,exitcode=%u", WEXITSTATUS(status));
2452			if (WIFSTOPPED(status))
2453				sprintf(buf, "WIFSTOPPED,sig=%s", signame(WSTOPSIG(status)));
2454			if (WIFCONTINUED(status))
2455				strcpy(buf, "WIFCONTINUED");
2456			fprintf(stderr, " [wait(0x%04x) = %u] %s\n", status, pid, buf);
2457		}
2458
2459		/* Look up `pid' in our table. */
2460		if ((tcp = pid2tcb(pid)) == NULL) {
2461#ifdef LINUX
2462			if (followfork) {
2463				/* This is needed to go with the CLONE_PTRACE
2464				   changes in process.c/util.c: we might see
2465				   the child's initial trap before we see the
2466				   parent return from the clone syscall.
2467				   Leave the child suspended until the parent
2468				   returns from its system call.  Only then
2469				   will we have the association of parent and
2470				   child so that we know how to do clearbpt
2471				   in the child.  */
2472				tcp = alloctcb(pid);
2473				tcp->flags |= TCB_ATTACHED | TCB_SUSPENDED;
2474				if (!qflag)
2475					fprintf(stderr, "\
2476Process %d attached (waiting for parent)\n",
2477						pid);
2478			}
2479			else
2480				/* This can happen if a clone call used
2481				   CLONE_PTRACE itself.  */
2482#endif
2483			{
2484				if (WIFSTOPPED(status))
2485					ptrace(PTRACE_CONT, pid, (char *) 1, 0);
2486				error_msg_and_die("Unknown pid: %u", pid);
2487			}
2488		}
2489		/* set current output file */
2490		outf = tcp->outf;
2491		curcol = tcp->curcol;
2492		if (cflag) {
2493#ifdef LINUX
2494			tv_sub(&tcp->dtime, &ru.ru_stime, &tcp->stime);
2495			tcp->stime = ru.ru_stime;
2496#endif /* !LINUX */
2497		}
2498
2499		if (tcp->flags & TCB_SUSPENDED) {
2500			/*
2501			 * Apparently, doing any ptrace() call on a stopped
2502			 * process, provokes the kernel to report the process
2503			 * status again on a subsequent wait(), even if the
2504			 * process has not been actually restarted.
2505			 * Since we have inspected the arguments of suspended
2506			 * processes we end up here testing for this case.
2507			 */
2508			continue;
2509		}
2510		if (WIFSIGNALED(status)) {
2511			if (pid == strace_child)
2512				exit_code = 0x100 | WTERMSIG(status);
2513			if (cflag != CFLAG_ONLY_STATS
2514			    && (qual_flags[WTERMSIG(status)] & QUAL_SIGNAL)) {
2515				printleader(tcp);
2516				tprintf("+++ killed by %s %s+++",
2517					signame(WTERMSIG(status)),
2518#ifdef WCOREDUMP
2519					WCOREDUMP(status) ? "(core dumped) " :
2520#endif
2521					"");
2522				printtrailer();
2523			}
2524#ifdef TCB_GROUP_EXITING
2525			handle_group_exit(tcp, -1);
2526#else
2527			droptcb(tcp);
2528#endif
2529			continue;
2530		}
2531		if (WIFEXITED(status)) {
2532			if (pid == strace_child)
2533				exit_code = WEXITSTATUS(status);
2534			if ((tcp->flags & (TCB_ATTACHED|TCB_STARTUP)) == TCB_ATTACHED
2535#ifdef TCB_GROUP_EXITING
2536			    && !(tcp->parent && (tcp->parent->flags & TCB_GROUP_EXITING))
2537			    && !(tcp->flags & TCB_GROUP_EXITING)
2538#endif
2539			) {
2540				fprintf(stderr,
2541					"PANIC: attached pid %u exited with %d\n",
2542					pid, WEXITSTATUS(status));
2543			}
2544			if (tcp == tcp_last) {
2545				if ((tcp->flags & (TCB_INSYSCALL|TCB_REPRINT)) == TCB_INSYSCALL)
2546					tprintf(" <unfinished ... exit status %d>\n",
2547						WEXITSTATUS(status));
2548				tcp_last = NULL;
2549			}
2550#ifdef TCB_GROUP_EXITING
2551			handle_group_exit(tcp, -1);
2552#else
2553			droptcb(tcp);
2554#endif
2555			continue;
2556		}
2557		if (!WIFSTOPPED(status)) {
2558			fprintf(stderr, "PANIC: pid %u not stopped\n", pid);
2559			droptcb(tcp);
2560			continue;
2561		}
2562
2563		if (status >> 16) {
2564			if (handle_ptrace_event(status, tcp) != 1)
2565				goto tracing;
2566		}
2567
2568		/*
2569		 * Interestingly, the process may stop
2570		 * with STOPSIG equal to some other signal
2571		 * than SIGSTOP if we happend to attach
2572		 * just before the process takes a signal.
2573		 * A no-MMU vforked child won't send up a signal,
2574		 * so skip the first (lost) execve notification.
2575		 */
2576		if ((tcp->flags & TCB_STARTUP) &&
2577		    (WSTOPSIG(status) == SIGSTOP || strace_vforked)) {
2578			/*
2579			 * This flag is there to keep us in sync.
2580			 * Next time this process stops it should
2581			 * really be entering a system call.
2582			 */
2583			tcp->flags &= ~TCB_STARTUP;
2584			if (tcp->flags & TCB_BPTSET) {
2585				/*
2586				 * One example is a breakpoint inherited from
2587				 * parent through fork ().
2588				 */
2589				if (clearbpt(tcp) < 0) /* Pretty fatal */ {
2590					droptcb(tcp);
2591					cleanup();
2592					return -1;
2593				}
2594			}
2595#ifdef LINUX
2596			/* If options were not set for this tracee yet */
2597			if (tcp->parent == NULL) {
2598				if (ptrace_setoptions) {
2599					if (debug)
2600						fprintf(stderr, "setting opts %x on pid %d\n", ptrace_setoptions, tcp->pid);
2601					if (ptrace(PTRACE_SETOPTIONS, tcp->pid, NULL, ptrace_setoptions) < 0) {
2602						if (errno != ESRCH) {
2603							/* Should never happen, really */
2604							perror_msg_and_die("PTRACE_SETOPTIONS");
2605						}
2606					}
2607				}
2608			}
2609#endif
2610			goto tracing;
2611		}
2612
2613		if (WSTOPSIG(status) != syscall_trap_sig) {
2614			if (WSTOPSIG(status) == SIGSTOP &&
2615					(tcp->flags & TCB_SIGTRAPPED)) {
2616				/*
2617				 * Trapped attempt to block SIGTRAP
2618				 * Hope we are back in control now.
2619				 */
2620				tcp->flags &= ~(TCB_INSYSCALL | TCB_SIGTRAPPED);
2621				if (ptrace_restart(PTRACE_SYSCALL, tcp, 0) < 0) {
2622					cleanup();
2623					return -1;
2624				}
2625				continue;
2626			}
2627			if (cflag != CFLAG_ONLY_STATS
2628			    && (qual_flags[WSTOPSIG(status)] & QUAL_SIGNAL)) {
2629				siginfo_t si;
2630#if defined(PT_CR_IPSR) && defined(PT_CR_IIP)
2631				long pc = 0;
2632				long psr = 0;
2633
2634				upeek(tcp, PT_CR_IPSR, &psr);
2635				upeek(tcp, PT_CR_IIP, &pc);
2636
2637# define PSR_RI	41
2638				pc += (psr >> PSR_RI) & 0x3;
2639# define PC_FORMAT_STR	" @ %lx"
2640# define PC_FORMAT_ARG	pc
2641#else
2642# define PC_FORMAT_STR	"%s"
2643# define PC_FORMAT_ARG	""
2644#endif
2645				printleader(tcp);
2646				if (ptrace(PTRACE_GETSIGINFO, pid, 0, &si) == 0) {
2647					tprintf("--- ");
2648					printsiginfo(&si, verbose(tcp));
2649					tprintf(" (%s)" PC_FORMAT_STR " ---",
2650						strsignal(WSTOPSIG(status)),
2651						PC_FORMAT_ARG);
2652				} else
2653					tprintf("--- %s by %s" PC_FORMAT_STR " ---",
2654						strsignal(WSTOPSIG(status)),
2655						signame(WSTOPSIG(status)),
2656						PC_FORMAT_ARG);
2657				printtrailer();
2658			}
2659			if (((tcp->flags & TCB_ATTACHED) ||
2660			     tcp->nclone_threads > 0) &&
2661				!sigishandled(tcp, WSTOPSIG(status))) {
2662#ifdef TCB_GROUP_EXITING
2663				handle_group_exit(tcp, WSTOPSIG(status));
2664#else
2665				detach(tcp, WSTOPSIG(status));
2666#endif
2667				continue;
2668			}
2669			if (ptrace_restart(PTRACE_SYSCALL, tcp, WSTOPSIG(status)) < 0) {
2670				cleanup();
2671				return -1;
2672			}
2673			tcp->flags &= ~TCB_SUSPENDED;
2674			continue;
2675		}
2676		/* we handled the STATUS, we are permitted to interrupt now. */
2677		if (interrupted)
2678			return 0;
2679		if (trace_syscall(tcp) < 0 && !tcp->ptrace_errno) {
2680			/* ptrace() failed in trace_syscall() with ESRCH.
2681			 * Likely a result of process disappearing mid-flight.
2682			 * Observed case: exit_group() terminating
2683			 * all processes in thread group. In this case, threads
2684			 * "disappear" in an unpredictable moment without any
2685			 * notification to strace via wait().
2686			 */
2687			if (tcp->flags & TCB_ATTACHED) {
2688				if (tcp_last) {
2689					/* Do we have dangling line "syscall(param, param"?
2690					 * Finish the line then. We cannot
2691					 */
2692					tcp_last->flags |= TCB_REPRINT;
2693					tprintf(" <unfinished ...>");
2694					printtrailer();
2695				}
2696				detach(tcp, 0);
2697			} else {
2698				ptrace(PTRACE_KILL,
2699					tcp->pid, (char *) 1, SIGTERM);
2700				droptcb(tcp);
2701			}
2702			continue;
2703		}
2704		if (tcp->flags & TCB_EXITING) {
2705#ifdef TCB_GROUP_EXITING
2706			if (tcp->flags & TCB_GROUP_EXITING) {
2707				if (handle_group_exit(tcp, 0) < 0)
2708					return -1;
2709				continue;
2710			}
2711#endif
2712			if (tcp->flags & TCB_ATTACHED)
2713				detach(tcp, 0);
2714			else if (ptrace_restart(PTRACE_CONT, tcp, 0) < 0) {
2715				cleanup();
2716				return -1;
2717			}
2718			continue;
2719		}
2720		if (tcp->flags & TCB_SUSPENDED) {
2721			if (!qflag)
2722				fprintf(stderr, "Process %u suspended\n", pid);
2723			continue;
2724		}
2725	tracing:
2726		/* Remember current print column before continuing. */
2727		tcp->curcol = curcol;
2728		if (ptrace_restart(PTRACE_SYSCALL, tcp, 0) < 0) {
2729			cleanup();
2730			return -1;
2731		}
2732	}
2733	return 0;
2734}
2735
2736#endif /* !USE_PROCFS */
2737
2738#include <stdarg.h>
2739
2740void
2741tprintf(const char *fmt, ...)
2742{
2743	va_list args;
2744
2745	va_start(args, fmt);
2746	if (outf) {
2747		int n = vfprintf(outf, fmt, args);
2748		if (n < 0) {
2749			if (outf != stderr)
2750				perror(outfname == NULL
2751				       ? "<writing to pipe>" : outfname);
2752		} else
2753			curcol += n;
2754	}
2755	va_end(args);
2756	return;
2757}
2758
2759void
2760printleader(struct tcb *tcp)
2761{
2762	if (tcp_last) {
2763		if (tcp_last->ptrace_errno) {
2764			if (tcp_last->flags & TCB_INSYSCALL) {
2765				tprintf(" <unavailable>) ");
2766				tabto(acolumn);
2767			}
2768			tprintf("= ? <unavailable>\n");
2769			tcp_last->ptrace_errno = 0;
2770		} else if (!outfname || followfork < 2 || tcp_last == tcp) {
2771			tcp_last->flags |= TCB_REPRINT;
2772			tprintf(" <unfinished ...>\n");
2773		}
2774	}
2775	curcol = 0;
2776	if ((followfork == 1 || pflag_seen > 1) && outfname)
2777		tprintf("%-5d ", tcp->pid);
2778	else if (nprocs > 1 && !outfname)
2779		tprintf("[pid %5u] ", tcp->pid);
2780	if (tflag) {
2781		char str[sizeof("HH:MM:SS")];
2782		struct timeval tv, dtv;
2783		static struct timeval otv;
2784
2785		gettimeofday(&tv, NULL);
2786		if (rflag) {
2787			if (otv.tv_sec == 0)
2788				otv = tv;
2789			tv_sub(&dtv, &tv, &otv);
2790			tprintf("%6ld.%06ld ",
2791				(long) dtv.tv_sec, (long) dtv.tv_usec);
2792			otv = tv;
2793		}
2794		else if (tflag > 2) {
2795			tprintf("%ld.%06ld ",
2796				(long) tv.tv_sec, (long) tv.tv_usec);
2797		}
2798		else {
2799			time_t local = tv.tv_sec;
2800			strftime(str, sizeof(str), "%T", localtime(&local));
2801			if (tflag > 1)
2802				tprintf("%s.%06ld ", str, (long) tv.tv_usec);
2803			else
2804				tprintf("%s ", str);
2805		}
2806	}
2807	if (iflag)
2808		printcall(tcp);
2809}
2810
2811void
2812tabto(int col)
2813{
2814	if (curcol < col)
2815		tprintf("%*s", col - curcol, "");
2816}
2817
2818void
2819printtrailer(void)
2820{
2821	tprintf("\n");
2822	tcp_last = NULL;
2823}
2824
2825#ifdef HAVE_MP_PROCFS
2826
2827int
2828mp_ioctl(int fd, int cmd, void *arg, int size)
2829{
2830	struct iovec iov[2];
2831	int n = 1;
2832
2833	iov[0].iov_base = &cmd;
2834	iov[0].iov_len = sizeof cmd;
2835	if (arg) {
2836		++n;
2837		iov[1].iov_base = arg;
2838		iov[1].iov_len = size;
2839	}
2840
2841	return writev(fd, iov, n);
2842}
2843
2844#endif
2845