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