]> granicus.if.org Git - strace/blob - strace.c
Define table entries for sys_stat64, sys_lstat64, and sys_fstat64.
[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 <signal.h>
36 #include <errno.h>
37 #include <sys/param.h>
38 #include <fcntl.h>
39 #include <sys/resource.h>
40 #include <sys/wait.h>
41 #include <sys/stat.h>
42 #include <pwd.h>
43 #include <grp.h>
44 #include <string.h>
45
46 #ifdef SVR4
47 #include <sys/stropts.h>
48 #include <poll.h>
49 #ifdef HAVE_MP_PROCFS
50 #include <sys/uio.h>
51 #endif
52 #endif
53
54 int debug = 0, followfork = 0, followvfork = 0, interactive = 0;
55 int rflag = 0, tflag = 0, dtime = 0, cflag = 0;
56 int iflag = 0, xflag = 0, qflag = 0;
57 int pflag_seen = 0;
58
59 char *username = NULL;
60 uid_t run_uid;
61 gid_t run_gid;
62
63 int acolumn = DEFAULT_ACOLUMN;
64 int max_strlen = DEFAULT_STRLEN;
65 char *outfname = NULL;
66 FILE *outf;
67 struct tcb tcbtab[MAX_PROCS];
68 int nprocs;
69 char *progname;
70 extern char version[];
71 extern char **environ;
72
73 static struct tcb *pid2tcb P((int pid));
74 static int trace P((void));
75 static void cleanup P((void));
76 static void interrupt P((int sig));
77 static sigset_t empty_set, blocked_set;
78
79 #ifdef HAVE_SIG_ATOMIC_T
80 static volatile sig_atomic_t interrupted;
81 #else /* !HAVE_SIG_ATOMIC_T */
82 #ifdef __STDC__
83 static volatile int interrupted;
84 #else /* !__STDC__ */
85 static int interrupted;
86 #endif /* !__STDC__ */
87 #endif /* !HAVE_SIG_ATOMIC_T */
88
89 #ifdef SVR4
90
91 static struct tcb *pfd2tcb P((int pfd));
92 static void reaper P((int sig));
93 static void rebuild_pollv P((void));
94 struct pollfd pollv[MAX_PROCS];
95
96 #ifndef HAVE_POLLABLE_PROCFS
97
98 static void proc_poll_open P((void));
99 static void proc_poller P((int pfd));
100
101 struct proc_pollfd {
102         int fd;
103         int revents;
104         int pid;
105 };
106
107 static int poller_pid;
108 static int proc_poll_pipe[2] = { -1, -1 };
109
110 #endif /* !HAVE_POLLABLE_PROCFS */
111
112 #ifdef HAVE_MP_PROCFS
113 #define POLLWANT        POLLWRNORM
114 #else
115 #define POLLWANT        POLLPRI
116 #endif
117 #endif /* SVR4 */
118
119 static void
120 usage(ofp, exitval)
121 FILE *ofp;
122 int exitval;
123 {
124         fprintf(ofp, "\
125 usage: strace [-dffhiqrtttTvVxx] [-a column] [-e expr] ... [-o file]\n\
126               [-p pid] ... [-s strsize] [-u username] [command [arg ...]]\n\
127    or: strace -c [-e expr] ... [-O overhead] [-S sortby] [command [arg ...]]\n\
128 -c -- count time, calls, and errors for each syscall and report summary\n\
129 -f -- follow forks, -ff -- with output into separate files\n\
130 -F -- attempt to follow vforks, -h -- print help message\n\
131 -i -- print instruction pointer at time of syscall\n\
132 -q -- suppress messages about attaching, detaching, etc.\n\
133 -r -- print relative timestamp, -t -- absolute timestamp, -tt -- with usecs\n\
134 -T -- print time spent in each syscall, -V -- print version\n\
135 -v -- verbose mode: print unabbreviated argv, stat, termio[s], etc. args\n\
136 -x -- print non-ascii strings in hex, -xx -- print all strings in hex\n\
137 -a column -- alignment COLUMN for printing syscall results (default %d)\n\
138 -e expr -- a qualifying expression: option=[!]all or option=[!]val1[,val2]...\n\
139    options: trace, abbrev, verbose, raw, signal, read, or write\n\
140 -o file -- send trace output to FILE instead of stderr\n\
141 -O overhead -- set overhead for tracing syscalls to OVERHEAD usecs\n\
142 -p pid -- trace process with process id PID, may be repeated\n\
143 -s strsize -- limit length of print strings to STRSIZE chars (default %d)\n\
144 -S sortby -- sort syscall counts by: time, calls, name, nothing (default %s)\n\
145 -u username -- run command as username handling setuid and/or setgid\n\
146 ", DEFAULT_ACOLUMN, DEFAULT_STRLEN, DEFAULT_SORTBY);
147         exit(exitval);
148 }
149
150 #ifdef SVR4
151 #ifdef MIPS
152 void
153 foobar()
154 {
155 }
156 #endif /* MIPS */
157 #endif /* SVR4 */
158
159 int
160 main(argc, argv)
161 int argc;
162 char *argv[];
163 {
164         extern int optind;
165         extern char *optarg;
166         struct tcb *tcp;
167         int c, pid = 0;
168         struct sigaction sa;
169
170         static char buf[BUFSIZ];
171
172         progname = argv[0];
173         outf = stderr;
174         interactive = 1;
175         qualify("trace=all");
176         qualify("abbrev=all");
177         qualify("verbose=all");
178         qualify("signal=all");
179         set_sortby(DEFAULT_SORTBY);
180         set_personality(DEFAULT_PERSONALITY);
181         while ((c = getopt(argc, argv,
182                 "+cdfFhiqrtTvVxa:e:o:O:p:s:S:u:")) != EOF) {
183                 switch (c) {
184                 case 'c':
185                         cflag++;
186                         dtime++;
187                         break;
188                 case 'd':
189                         debug++;
190                         break;
191                 case 'f':
192                         followfork++;
193                         break;
194                 case 'F':
195                         followvfork++;
196                         break;
197                 case 'h':
198                         usage(stdout, 0);
199                         break;
200                 case 'i':
201                         iflag++;
202                         break;
203                 case 'q':
204                         qflag++;
205                         break;
206                 case 'r':
207                         rflag++;
208                         tflag++;
209                         break;
210                 case 't':
211                         tflag++;
212                         break;
213                 case 'T':
214                         dtime++;
215                         break;
216                 case 'x':
217                         xflag++;
218                         break;
219                 case 'v':
220                         qualify("abbrev=none");
221                         break;
222                 case 'V':
223                         printf("%s\n", version);
224                         exit(0);
225                         break;
226                 case 'a':
227                         acolumn = atoi(optarg);
228                         break;
229                 case 'e':
230                         qualify(optarg);
231                         break;
232                 case 'o':
233                         outfname = strdup(optarg);
234                         break;
235                 case 'O':
236                         set_overhead(atoi(optarg));
237                         break;
238                 case 'p':
239                         if ((pid = atoi(optarg)) == 0) {
240                                 fprintf(stderr, "%s: Invalid process id: %s\n",
241                                         progname, optarg);
242                                 break;
243                         }
244                         if (pid == getpid()) {
245                                 fprintf(stderr, "%s: I'm sorry, I can't let you do that, Dave.\n", progname);
246                                 break;
247                         }
248                         if ((tcp = alloctcb(pid)) == NULL) {
249                                 fprintf(stderr, "%s: tcb table full, please recompile strace\n",
250                                         progname);
251                                 exit(1);
252                         }
253                         tcp->flags |= TCB_ATTACHED;
254                         pflag_seen++;
255                         break;
256                 case 's':
257                         max_strlen = atoi(optarg);
258                         break;
259                 case 'S':
260                         set_sortby(optarg);
261                         break;
262                 case 'u':
263                         username = strdup(optarg);
264                         break;
265                 default:
266                         usage(stderr, 1);
267                         break;
268                 }
269         }
270
271         /* See if they want to run as another user. */
272         if (username != NULL) {
273                 struct passwd *pent;
274
275                 if (getuid() != 0 || geteuid() != 0) {
276                         fprintf(stderr,
277                                 "%s: you must be root to use the -u option\n",
278                                 progname);
279                         exit(1);
280                 }
281                 if ((pent = getpwnam(username)) == NULL) {
282                         fprintf(stderr, "%s: cannot find user `%s'\n",
283                                 progname, optarg);
284                         exit(1);
285                 }
286                 run_uid = pent->pw_uid;
287                 run_gid = pent->pw_gid;
288         }
289         else {
290                 run_uid = getuid();
291                 run_gid = getgid();
292         }
293
294 #ifndef SVR4
295         setreuid(geteuid(), getuid());
296 #endif
297
298         /* See if they want to pipe the output. */
299         if (outfname && (outfname[0] == '|' || outfname[0] == '!')) {
300                 if ((outf = popen(outfname + 1, "w")) == NULL) {
301                         fprintf(stderr, "%s: can't popen '%s': %s\n",
302                                 progname, outfname + 1, strerror(errno));
303                         exit(1);
304                 }
305                 free(outfname);
306                 outfname = NULL;
307         }
308
309         /* Check if they want to redirect the output. */
310         if (outfname) {
311                 if ((outf = fopen(outfname, "w")) == NULL) {
312                         fprintf(stderr, "%s: can't fopen '%s': %s\n",
313                                 progname, outfname, strerror(errno));
314                         exit(1);
315                 }
316         }
317
318 #ifndef SVR4
319         setreuid(geteuid(), getuid());
320 #endif
321
322         if (!outfname) {
323                 qflag = 1;
324                 setvbuf(outf, buf, _IOLBF, BUFSIZ);
325         }
326         else if (optind < argc)
327                 interactive = 0;
328         else
329                 qflag = 1;
330
331         for (c = 0, tcp = tcbtab; c < MAX_PROCS; c++, tcp++) {
332                 /* Reinitialize the output since it may have changed. */
333                 tcp->outf = outf;
334                 if (!(tcp->flags & TCB_INUSE) || !(tcp->flags & TCB_ATTACHED))
335                         continue;
336 #ifdef SVR4
337                 if (proc_open(tcp, 1) < 0) {
338                         fprintf(stderr, "trouble opening proc file\n");
339                         droptcb(tcp);
340                         continue;
341                 }
342 #else /* !SVR4 */
343                 if (ptrace(PTRACE_ATTACH, tcp->pid, (char *) 1, 0) < 0) {
344                         perror("attach: ptrace(PTRACE_ATTACH, ...)");
345                         droptcb(tcp);
346                         continue;
347                 }
348 #endif /* !SVR4 */
349                 if (!qflag)
350                         fprintf(stderr,
351                                 "Process %u attached - interrupt to quit\n",
352                                 pid);
353         }
354
355         if (optind < argc) {
356                 struct stat statbuf;
357                 char *filename;
358                 char pathname[MAXPATHLEN];
359
360                 filename = argv[optind];
361                 if (strchr(filename, '/'))
362                         strcpy(pathname, filename);
363 #ifdef USE_DEBUGGING_EXEC
364                 /*
365                  * Debuggers customarily check the current directory
366                  * first regardless of the path but doing that gives
367                  * security geeks a panic attack.
368                  */
369                 else if (stat(filename, &statbuf) == 0)
370                         strcpy(pathname, filename);
371 #endif /* USE_DEBUGGING_EXEC */
372                 else {
373                         char *path;
374                         int m, n, len;
375
376                         for (path = getenv("PATH"); path && *path; path += m) {
377                                 if (strchr(path, ':')) {
378                                         n = strchr(path, ':') - path;
379                                         m = n + 1;
380                                 }
381                                 else
382                                         m = n = strlen(path);
383                                 if (n == 0) {
384                                         getcwd(pathname, MAXPATHLEN);
385                                         len = strlen(pathname);
386                                 }
387                                 else {
388                                         strncpy(pathname, path, n);
389                                         len = n;
390                                 }
391                                 if (len && pathname[len - 1] != '/')
392                                         pathname[len++] = '/';
393                                 strcpy(pathname + len, filename);
394                                 if (stat(pathname, &statbuf) == 0)
395                                         break;
396                         }
397                 }
398                 if (stat(pathname, &statbuf) < 0) {
399                         fprintf(stderr, "%s: %s: command not found\n",
400                                 progname, filename);
401                         exit(1);
402                 }
403                 switch (pid = fork()) {
404                 case -1:
405                         perror("strace: fork");
406                         cleanup();
407                         exit(1);
408                         break;
409                 case 0: {
410 #ifdef SVR4
411                         if (outf != stderr) close (fileno (outf));
412 #ifdef MIPS
413                         /* Kludge for SGI, see proc_open for details. */
414                         sa.sa_handler = foobar;
415                         sa.sa_flags = 0;
416                         sigemptyset(&sa.sa_mask);
417                         sigaction(SIGINT, &sa, NULL);
418 #endif /* MIPS */
419                         pause();
420 #else /* !SVR4 */
421                         if (ptrace(PTRACE_TRACEME, 0, (char *) 1, 0) < 0) {
422                                 perror("strace: ptrace(PTRACE_TRACEME, ...)");
423                                 return -1;
424                         }
425                         if (debug)
426                                 kill(getpid(), SIGSTOP);
427
428                         if (username != NULL || geteuid() == 0) {
429                                 uid_t run_euid = run_uid;
430                                 gid_t run_egid = run_gid;
431
432                                 if (statbuf.st_mode & S_ISUID)
433                                         run_euid = statbuf.st_uid;
434                                 if (statbuf.st_mode & S_ISGID)
435                                         run_egid = statbuf.st_gid;
436
437                                 /*
438                                  * It is important to set groups before we
439                                  * lose privileges on setuid.
440                                  */
441                                 if (username != NULL
442                                     && initgroups(username, run_gid) < 0) {
443                                         perror("initgroups");
444                                         exit(1);
445                                 }
446                                 if (setregid(run_gid, run_egid) < 0) {
447                                         perror("setregid");
448                                         exit(1);
449                                 }
450                                 if (setreuid(run_uid, run_euid) < 0) {
451                                         perror("setreuid");
452                                         exit(1);
453                                 }
454                         }
455                         else
456                                 setreuid(run_uid, run_uid);
457 #endif /* !SVR4 */
458
459                         execv(pathname, &argv[optind]);
460                         perror("strace: exec");
461                         _exit(1);
462                         break;
463                 }
464                 default:
465                         if ((tcp = alloctcb(pid)) == NULL) {
466                                 fprintf(stderr, "tcb table full\n");
467                                 cleanup();
468                                 exit(1);
469                         }
470 #ifdef SVR4
471                         if (proc_open(tcp, 0) < 0) {
472                                 fprintf(stderr, "trouble opening proc file\n");
473                                 cleanup();
474                                 exit(1);
475                         }
476 #endif /* SVR4 */
477 #ifndef SVR4
478                         fake_execve(tcp, pathname, &argv[optind], environ);
479 #endif
480                         break;
481                 }
482         }
483         else if (pflag_seen == 0)
484                 usage(stderr, 1);
485
486         sigemptyset(&empty_set);
487         sigemptyset(&blocked_set);
488         sa.sa_handler = SIG_IGN;
489         sigemptyset(&sa.sa_mask);
490         sa.sa_flags = 0;
491         sigaction(SIGTTOU, &sa, NULL);
492         sigaction(SIGTTIN, &sa, NULL);
493         if (interactive) {
494                 sigaddset(&blocked_set, SIGHUP);
495                 sigaddset(&blocked_set, SIGINT);
496                 sigaddset(&blocked_set, SIGQUIT);
497                 sigaddset(&blocked_set, SIGPIPE);
498                 sigaddset(&blocked_set, SIGTERM);
499                 sa.sa_handler = interrupt;
500 #ifdef SUNOS4
501                 /* POSIX signals on sunos4.1 are a little broken. */
502                 sa.sa_flags = SA_INTERRUPT;
503 #endif /* SUNOS4 */
504         }
505         sigaction(SIGHUP, &sa, NULL);
506         sigaction(SIGINT, &sa, NULL);
507         sigaction(SIGQUIT, &sa, NULL);
508         sigaction(SIGPIPE, &sa, NULL);
509         sigaction(SIGTERM, &sa, NULL);
510 #ifdef SVR4
511         sa.sa_handler = reaper;
512         sigaction(SIGCHLD, &sa, NULL);
513 #endif /* SVR4 */
514
515         if (trace() < 0)
516                 exit(1);
517         cleanup();
518         exit(0);
519 }
520
521 void
522 newoutf(tcp)
523 struct tcb *tcp;
524 {
525         char name[MAXPATHLEN];
526         FILE *fp;
527
528         if (outfname && followfork > 1) {
529                 sprintf(name, "%s.%u", outfname, tcp->pid);
530 #ifndef SVR4
531                 setreuid(geteuid(), getuid());
532 #endif
533                 fp = fopen(name, "w");
534 #ifndef SVR4
535                 setreuid(geteuid(), getuid());
536 #endif
537                 if (fp == NULL) {
538                         perror("fopen");
539                         return;
540                 }
541                 tcp->outf = fp;
542         }
543         return;
544 }
545
546 struct tcb *
547 alloctcb(pid)
548 int pid;
549 {
550         int i;
551         struct tcb *tcp;
552
553         for (i = 0, tcp = tcbtab; i < MAX_PROCS; i++, tcp++) {
554                 if ((tcp->flags & TCB_INUSE) == 0) {
555                         tcp->pid = pid;
556                         tcp->parent = NULL;
557                         tcp->nchildren = 0;
558                         tcp->flags = TCB_INUSE | TCB_STARTUP;
559                         tcp->outf = outf; /* Initialise to current out file */
560                         tcp->stime.tv_sec = 0;
561                         tcp->stime.tv_usec = 0;
562                         tcp->pfd = -1;
563                         nprocs++;
564                         return tcp;
565                 }
566         }
567         return NULL;
568 }
569
570 #ifdef SVR4
571 int
572 proc_open(tcp, attaching)
573 struct tcb *tcp;
574 int attaching;
575 {
576         char proc[32];
577         long arg;
578         sysset_t sc_enter, sc_exit;
579         sigset_t signals;
580         fltset_t faults;
581 #ifndef HAVE_POLLABLE_PROCFS
582         static int last_pfd;
583 #endif
584
585 #ifdef HAVE_MP_PROCFS
586         /* Open the process pseudo-files in /proc. */
587         sprintf(proc, "/proc/%d/ctl", tcp->pid);
588         if ((tcp->pfd = open(proc, O_WRONLY|O_EXCL)) < 0) {
589                 perror("strace: open(\"/proc/...\", ...)");
590                 return -1;
591         }
592         if ((arg = fcntl(tcp->pfd, F_GETFD)) < 0) {
593                 perror("F_GETFD");
594                 return -1;
595         }
596         if (fcntl(tcp->pfd, F_SETFD, arg|FD_CLOEXEC) < 0) {
597                 perror("F_SETFD");
598                 return -1;
599         }
600         sprintf(proc, "/proc/%d/status", tcp->pid);
601         if ((tcp->pfd_stat = open(proc, O_RDONLY|O_EXCL)) < 0) {
602                 perror("strace: open(\"/proc/...\", ...)");
603                 return -1;
604         }
605         if ((arg = fcntl(tcp->pfd_stat, F_GETFD)) < 0) {
606                 perror("F_GETFD");
607                 return -1;
608         }
609         if (fcntl(tcp->pfd_stat, F_SETFD, arg|FD_CLOEXEC) < 0) {
610                 perror("F_SETFD");
611                 return -1;
612         }
613         sprintf(proc, "/proc/%d/as", tcp->pid);
614         if ((tcp->pfd_as = open(proc, O_RDONLY|O_EXCL)) < 0) {
615                 perror("strace: open(\"/proc/...\", ...)");
616                 return -1;
617         }
618         if ((arg = fcntl(tcp->pfd_as, F_GETFD)) < 0) {
619                 perror("F_GETFD");
620                 return -1;
621         }
622         if (fcntl(tcp->pfd_as, F_SETFD, arg|FD_CLOEXEC) < 0) {
623                 perror("F_SETFD");
624                 return -1;
625         }
626 #else
627         /* Open the process pseudo-file in /proc. */
628         sprintf(proc, "/proc/%d", tcp->pid);
629         if ((tcp->pfd = open(proc, O_RDWR|O_EXCL)) < 0) {
630                 perror("strace: open(\"/proc/...\", ...)");
631                 return -1;
632         }
633         if ((arg = fcntl(tcp->pfd, F_GETFD)) < 0) {
634                 perror("F_GETFD");
635                 return -1;
636         }
637         if (fcntl(tcp->pfd, F_SETFD, arg|FD_CLOEXEC) < 0) {
638                 perror("F_SETFD");
639                 return -1;
640         }
641 #endif
642         rebuild_pollv();
643         if (!attaching) {
644                 /*
645                  * Wait for the child to pause.  Because of a race
646                  * condition we have to poll for the event.
647                  */
648                 for (;;) {
649                         if (IOCTL_STATUS (tcp) < 0) {
650                                 perror("strace: PIOCSTATUS");
651                                 return -1;
652                         }
653                         if (tcp->status.PR_FLAGS & PR_ASLEEP)
654                                 break;
655                 }
656         }
657         /* Stop the process so that we own the stop. */
658         if (IOCTL(tcp->pfd, PIOCSTOP, NULL) < 0) {
659                 perror("strace: PIOCSTOP");
660                 return -1;
661         }
662 #ifdef PIOCSET
663         /* Set Run-on-Last-Close. */
664         arg = PR_RLC;
665         if (IOCTL(tcp->pfd, PIOCSET, &arg) < 0) {
666                 perror("PIOCSET PR_RLC");
667                 return -1;
668         }
669         /* Set or Reset Inherit-on-Fork. */
670         arg = PR_FORK;
671         if (IOCTL(tcp->pfd, followfork ? PIOCSET : PIOCRESET, &arg) < 0) {
672                 perror("PIOC{SET,RESET} PR_FORK");
673                 return -1;
674         }
675 #else  /* !PIOCSET */
676         if (ioctl(tcp->pfd, PIOCSRLC) < 0) {
677                 perror("PIOCSRLC");
678                 return -1;
679         }
680         if (ioctl(tcp->pfd, followfork ? PIOCSFORK : PIOCRFORK) < 0) {
681                 perror("PIOC{S,R}FORK");
682                 return -1;
683         }
684 #endif /* !PIOCSET */
685         /* Enable all syscall entries. */
686         prfillset(&sc_enter);
687         if (IOCTL(tcp->pfd, PIOCSENTRY, &sc_enter) < 0) {
688                 perror("PIOCSENTRY");
689                 return -1;
690         }
691         /* Enable all syscall exits. */
692         prfillset(&sc_exit);
693         if (IOCTL(tcp->pfd, PIOCSEXIT, &sc_exit) < 0) {
694                 perror("PIOSEXIT");
695                 return -1;
696         }
697         /* Enable all signals. */
698         prfillset(&signals);
699         if (IOCTL(tcp->pfd, PIOCSTRACE, &signals) < 0) {
700                 perror("PIOCSTRACE");
701                 return -1;
702         }
703         /* Enable all faults. */
704         prfillset(&faults);
705         if (IOCTL(tcp->pfd, PIOCSFAULT, &faults) < 0) {
706                 perror("PIOCSFAULT");
707                 return -1;
708         }
709         if (!attaching) {
710 #ifdef MIPS
711                 /*
712                  * The SGI PRSABORT doesn't work for pause() so
713                  * we send it a caught signal to wake it up.
714                  */
715                 kill(tcp->pid, SIGINT);
716 #else /* !MIPS */
717                 /* The child is in a pause(), abort it. */
718                 arg = PRSABORT;
719                 if (IOCTL (tcp->pfd, PIOCRUN, &arg) < 0) {
720                         perror("PIOCRUN");
721                         return -1;
722                 }
723 #endif /* !MIPS */
724                 for (;;) {
725                         /* Wait for the child to do something. */
726                         if (IOCTL_WSTOP (tcp) < 0) {
727                                 perror("PIOCWSTOP");
728                                 return -1;
729                         }
730                         if (tcp->status.PR_WHY == PR_SYSENTRY) {
731 #ifdef HAVE_PR_SYSCALL
732                                 int scno = tcp->status.pr_syscall;
733 #else /* !HAVE_PR_SYSCALL */
734                                 int scno = tcp->status.PR_WHAT;
735 #endif /* !HAVE_PR_SYSCALL */
736                                 if (scno == SYS_execve)
737                                         break;
738                         }
739                         /* Set it running: maybe execve will be next. */
740                         arg = 0;
741                         if (IOCTL(tcp->pfd, PIOCRUN, &arg) < 0) {
742                                 perror("PIOCRUN");
743                                 return -1;
744                         }
745                 }
746         }
747 #ifndef HAVE_POLLABLE_PROCFS
748         if (proc_poll_pipe[0] != -1)
749                 proc_poller(tcp->pfd);
750         else if (nprocs > 1) {
751                 proc_poll_open();
752                 proc_poller(last_pfd);
753                 proc_poller(tcp->pfd);
754         }
755         last_pfd = tcp->pfd;
756 #endif /* !HAVE_POLLABLE_PROCFS */
757         return 0;
758 }
759
760 #endif /* SVR4 */
761
762 static struct tcb *
763 pid2tcb(pid)
764 int pid;
765 {
766         int i;
767         struct tcb *tcp;
768
769         for (i = 0, tcp = tcbtab; i < MAX_PROCS; i++, tcp++) {
770                 if (pid && tcp->pid != pid)
771                         continue;
772                 if (tcp->flags & TCB_INUSE)
773                         return tcp;
774         }
775         return NULL;
776 }
777
778 #ifdef SVR4
779
780 static struct tcb *
781 pfd2tcb(pfd)
782 int pfd;
783 {
784         int i;
785         struct tcb *tcp;
786
787         for (i = 0, tcp = tcbtab; i < MAX_PROCS; i++, tcp++) {
788                 if (tcp->pfd != pfd)
789                         continue;
790                 if (tcp->flags & TCB_INUSE)
791                         return tcp;
792         }
793         return NULL;
794 }
795
796 #endif /* SVR4 */
797
798 void
799 droptcb(tcp)
800 struct tcb *tcp;
801 {
802         if (tcp->pid == 0)
803                 return;
804         nprocs--;
805         tcp->pid = 0;
806         tcp->flags = 0;
807         if (tcp->pfd != -1) {
808                 close(tcp->pfd);
809                 tcp->pfd = -1;
810 #ifdef SVR4
811                 rebuild_pollv();
812 #endif
813         }
814         if (tcp->parent != NULL) {
815                 tcp->parent->nchildren--;
816                 tcp->parent = NULL;
817         }
818 #if 0
819         if (tcp->outf != stderr)
820                 fclose(tcp->outf);
821 #endif
822         tcp->outf = 0;
823 }
824
825 #ifndef SVR4
826
827 static int
828 resume(tcp)
829 struct tcb *tcp;
830 {
831         if (tcp == NULL)
832                 return -1;
833
834         if (!(tcp->flags & TCB_SUSPENDED)) {
835                 fprintf(stderr, "PANIC: pid %u not suspended\n", tcp->pid);
836                 return -1;
837         }
838         tcp->flags &= ~TCB_SUSPENDED;
839
840         if (ptrace(PTRACE_SYSCALL, tcp->pid, (char *) 1, 0) < 0) {
841                 perror("resume: ptrace(PTRACE_SYSCALL, ...)");
842                 return -1;
843         }
844
845         if (!qflag)
846                 fprintf(stderr, "Process %u resumed\n", tcp->pid);
847         return 0;
848 }
849
850 #endif /* !SVR4 */
851
852 /* detach traced process; continue with sig */
853
854 static int
855 detach(tcp, sig)
856 struct tcb *tcp;
857 int sig;
858 {
859         int error = 0;
860 #ifdef LINUX
861         int status;
862 #endif
863
864         if (tcp->flags & TCB_BPTSET)
865                 sig = SIGKILL;
866
867 #ifdef LINUX
868         /*
869          * Linux wrongly insists the child be stopped
870          * before detaching.  Arghh.  We go through hoops
871          * to make a clean break of things.
872          */
873 #if defined(SPARC)
874 #undef PTRACE_DETACH
875 #define PTRACE_DETACH PTRACE_SUNDETACH
876 #endif
877         if ((error = ptrace(PTRACE_DETACH, tcp->pid, (char *) 1, sig)) == 0) {
878                 /* On a clear day, you can see forever. */
879         }
880         else if (errno != ESRCH) {
881                 /* Shouldn't happen. */
882                 perror("detach: ptrace(PTRACE_DETACH, ...)");
883         }
884         else if (kill(tcp->pid, 0) < 0) {
885                 if (errno != ESRCH)
886                         perror("detach: checking sanity");
887         }
888         else if (kill(tcp->pid, SIGSTOP) < 0) {
889                 if (errno != ESRCH)
890                         perror("detach: stopping child");
891         }
892         else {
893                 for (;;) {
894                         if (waitpid(tcp->pid, &status, 0) < 0) {
895                                 if (errno != ECHILD)
896                                         perror("detach: waiting");
897                                 break;
898                         }
899                         if (!WIFSTOPPED(status)) {
900                                 /* Au revoir, mon ami. */
901                                 break;
902                         }
903                         if (WSTOPSIG(status) == SIGSTOP) {
904                                 if ((error = ptrace(PTRACE_DETACH,
905                                     tcp->pid, (char *) 1, sig)) < 0) {
906                                         if (errno != ESRCH)
907                                                 perror("detach: ptrace(PTRACE_DETACH, ...)");
908                                         /* I died trying. */
909                                 }
910                                 break;
911                         }
912                         if ((error = ptrace(PTRACE_CONT, tcp->pid, (char *) 1,
913                             WSTOPSIG(status) == SIGTRAP ?
914                             0 : WSTOPSIG(status))) < 0) {
915                                 if (errno != ESRCH)
916                                         perror("detach: ptrace(PTRACE_CONT, ...)");
917                                 break;
918                         }
919                 }
920         }
921 #endif /* LINUX */
922
923 #if defined(SUNOS4)
924         /* PTRACE_DETACH won't respect `sig' argument, so we post it here. */
925         if (sig && kill(tcp->pid, sig) < 0)
926                 perror("detach: kill");
927         sig = 0;
928         if ((error = ptrace(PTRACE_DETACH, tcp->pid, (char *) 1, sig)) < 0)
929                 perror("detach: ptrace(PTRACE_DETACH, ...)");
930 #endif /* SUNOS4 */
931
932 #ifndef SVR4
933         if (waiting_parent(tcp))
934                 error = resume(tcp->parent);
935 #endif /* !SVR4 */
936
937         if (!qflag)
938                 fprintf(stderr, "Process %u detached\n", tcp->pid);
939
940         droptcb(tcp);
941         return error;
942 }
943
944 #ifdef SVR4
945
946 static void
947 reaper(sig)
948 int sig;
949 {
950         int pid;
951         int status;
952
953         while ((pid = waitpid(-1, &status, WNOHANG)) > 0) {
954 #if 0
955                 struct tcb *tcp;
956
957                 tcp = pid2tcb(pid);
958                 if (tcp)
959                         droptcb(tcp);
960 #endif
961         }
962 }
963
964 #endif /* SVR4 */
965
966 static void
967 cleanup()
968 {
969         int i;
970         struct tcb *tcp;
971
972         for (i = 0, tcp = tcbtab; i < MAX_PROCS; i++, tcp++) {
973                 if (!(tcp->flags & TCB_INUSE))
974                         continue;
975                 if (debug)
976                         fprintf(stderr,
977                                 "cleanup: looking at pid %u\n", tcp->pid);
978                 if (tcp_last &&
979                     (!outfname || followfork < 2 || tcp_last == tcp)) {
980                         tprintf(" <unfinished ...>\n");
981                         tcp_last = NULL;
982                 }
983                 if (tcp->flags & TCB_ATTACHED)
984                         detach(tcp, 0);
985                 else {
986                         kill(tcp->pid, SIGCONT);
987                         kill(tcp->pid, SIGTERM);
988                 }
989         }
990         if (cflag)
991                 call_summary(outf);
992 }
993
994 static void
995 interrupt(sig)
996 int sig;
997 {
998         interrupted = 1;
999 }
1000
1001 #ifndef HAVE_STRERROR
1002
1003 #ifndef SYS_ERRLIST_DECLARED
1004 extern int sys_nerr;
1005 extern char *sys_errlist[];
1006 #endif /* SYS_ERRLIST_DECLARED */
1007
1008 const char *
1009 strerror(errno)
1010 int errno;
1011 {
1012         static char buf[64];
1013
1014         if (errno < 1 || errno >= sys_nerr) {
1015                 sprintf(buf, "Unknown error %d", errno);
1016                 return buf;
1017         }
1018         return sys_errlist[errno];
1019 }
1020
1021 #endif /* HAVE_STERRROR */
1022
1023 #ifndef HAVE_STRSIGNAL
1024
1025 #ifndef SYS_SIGLIST_DECLARED
1026 #ifdef HAVE__SYS_SIGLIST
1027         extern char *_sys_siglist[];
1028 #else
1029         extern char *sys_siglist[];
1030 #endif
1031 #endif /* SYS_SIGLIST_DECLARED */
1032
1033 const char *
1034 strsignal(sig)
1035 int sig;
1036 {
1037         static char buf[64];
1038
1039         if (sig < 1 || sig >= NSIG) {
1040                 sprintf(buf, "Unknown signal %d", sig);
1041                 return buf;
1042         }
1043 #ifdef HAVE__SYS_SIGLIST
1044         return _sys_siglist[sig];
1045 #else
1046         return sys_siglist[sig];
1047 #endif
1048 }
1049
1050 #endif /* HAVE_STRSIGNAL */
1051
1052 #ifdef SVR4
1053
1054 static void
1055 rebuild_pollv()
1056 {
1057         int i, j;
1058         struct tcb *tcp;
1059
1060         for (i = j = 0, tcp = tcbtab; i < MAX_PROCS; i++, tcp++) {
1061                 if (!(tcp->flags & TCB_INUSE))
1062                         continue;
1063                 pollv[j].fd = tcp->pfd;
1064                 pollv[j].events = POLLWANT;
1065                 j++;
1066         }
1067         if (j != nprocs) {
1068                 fprintf(stderr, "strace: proc miscount\n");
1069                 exit(1);
1070         }
1071 }
1072
1073 #ifndef HAVE_POLLABLE_PROCFS
1074
1075 static void
1076 proc_poll_open()
1077 {
1078         int arg;
1079         int i;
1080
1081         if (pipe(proc_poll_pipe) < 0) {
1082                 perror("pipe");
1083                 exit(1);
1084         }
1085         for (i = 0; i < 2; i++) {
1086                 if ((arg = fcntl(proc_poll_pipe[i], F_GETFD)) < 0) {
1087                         perror("F_GETFD");
1088                         exit(1);
1089                 }
1090                 if (fcntl(proc_poll_pipe[i], F_SETFD, arg|FD_CLOEXEC) < 0) {
1091                         perror("F_SETFD");
1092                         exit(1);
1093                 }
1094         }
1095 }
1096
1097 static int
1098 proc_poll(pollv, nfds, timeout)
1099 struct pollfd *pollv;
1100 int nfds;
1101 int timeout;
1102 {
1103         int i;
1104         int n;
1105         struct proc_pollfd pollinfo;
1106
1107         if ((n = read(proc_poll_pipe[0], &pollinfo, sizeof(pollinfo))) < 0)
1108                 return n;
1109         if (n != sizeof(struct proc_pollfd)) {
1110                 fprintf(stderr, "panic: short read: %d\n", n);
1111                 exit(1);
1112         }
1113         for (i = 0; i < nprocs; i++) {
1114                 if (pollv[i].fd == pollinfo.fd)
1115                         pollv[i].revents = pollinfo.revents;
1116                 else
1117                         pollv[i].revents = 0;
1118         }
1119         poller_pid = pollinfo.pid;
1120         return 1;
1121 }
1122
1123 static void
1124 wakeup_handler(sig)
1125 int sig;
1126 {
1127 }
1128
1129 static void
1130 proc_poller(pfd)
1131 int pfd;
1132 {
1133         struct proc_pollfd pollinfo;
1134         struct sigaction sa;
1135         sigset_t blocked_set, empty_set;
1136         int i;
1137         int n;
1138         struct rlimit rl;
1139
1140         switch (fork()) {
1141         case -1:
1142                 perror("fork");
1143                 _exit(0);
1144         case 0:
1145                 break;
1146         default:
1147                 return;
1148         }
1149
1150         sa.sa_handler = interactive ? SIG_DFL : SIG_IGN;
1151         sa.sa_flags = 0;
1152         sigemptyset(&sa.sa_mask);
1153         sigaction(SIGHUP, &sa, NULL);
1154         sigaction(SIGINT, &sa, NULL);
1155         sigaction(SIGQUIT, &sa, NULL);
1156         sigaction(SIGPIPE, &sa, NULL);
1157         sigaction(SIGTERM, &sa, NULL);
1158         sa.sa_handler = wakeup_handler;
1159         sigaction(SIGUSR1, &sa, NULL);
1160         sigemptyset(&blocked_set);
1161         sigaddset(&blocked_set, SIGUSR1);
1162         sigprocmask(SIG_BLOCK, &blocked_set, NULL);
1163         sigemptyset(&empty_set);
1164
1165         if (getrlimit(RLIMIT_NOFILE, &rl) < 0) {
1166                 perror("getrlimit(RLIMIT_NOFILE, ...)");
1167                 _exit(0);
1168         }
1169         n = rl.rlim_cur;
1170         for (i = 0; i < n; i++) {
1171                 if (i != pfd && i != proc_poll_pipe[1])
1172                         close(i);
1173         }
1174
1175         pollinfo.fd = pfd;
1176         pollinfo.pid = getpid();
1177         for (;;) {
1178                 if (ioctl(pfd, PIOCWSTOP, NULL) < 0)
1179                 {
1180                         switch (errno) {
1181                         case EINTR:
1182                                 continue;
1183                         case EBADF:
1184                                 pollinfo.revents = POLLERR;
1185                                 break;
1186                         case ENOENT:
1187                                 pollinfo.revents = POLLHUP;
1188                                 break;
1189                         default:
1190                                 perror("proc_poller: PIOCWSTOP");
1191                         }
1192                         write(proc_poll_pipe[1], &pollinfo, sizeof(pollinfo));
1193                         _exit(0);
1194                 }
1195                 pollinfo.revents = POLLWANT;
1196                 write(proc_poll_pipe[1], &pollinfo, sizeof(pollinfo));
1197                 sigsuspend(&empty_set);
1198         }
1199 }
1200
1201 #endif /* !HAVE_POLLABLE_PROCFS */
1202
1203 static int
1204 choose_pfd()
1205 {
1206         int i, j;
1207         struct tcb *tcp;
1208
1209         static int last;
1210
1211         if (followfork < 2 &&
1212             last < nprocs && (pollv[last].revents & POLLWANT)) {
1213                 /*
1214                  * The previous process is ready to run again.  We'll
1215                  * let it do so if it is currently in a syscall.  This
1216                  * heuristic improves the readability of the trace.
1217                  */
1218                 tcp = pfd2tcb(pollv[last].fd);
1219                 if (tcp && (tcp->flags & TCB_INSYSCALL))
1220                         return pollv[last].fd;
1221         }
1222
1223         for (i = 0; i < nprocs; i++) {
1224                 /* Let competing children run round robin. */
1225                 j = (i + last + 1) % nprocs;
1226                 if (pollv[j].revents & (POLLHUP | POLLERR)) {
1227                         tcp = pfd2tcb(pollv[j].fd);
1228                         if (!tcp) {
1229                                 fprintf(stderr, "strace: lost proc\n");
1230                                 exit(1);
1231                         }
1232                         droptcb(tcp);
1233                         return -1;
1234                 }
1235                 if (pollv[j].revents & POLLWANT) {
1236                         last = j;
1237                         return pollv[j].fd;
1238                 }
1239         }
1240         fprintf(stderr, "strace: nothing ready\n");
1241         exit(1);
1242 }
1243
1244 static int
1245 trace()
1246 {
1247 #ifdef POLL_HACK
1248         struct tcb *in_syscall;
1249 #endif
1250         struct tcb *tcp;
1251         int pfd;
1252         int what;
1253         int ioctl_result = 0, ioctl_errno = 0;
1254         long arg;
1255
1256         for (;;) {
1257                 if (interactive)
1258                         sigprocmask(SIG_SETMASK, &empty_set, NULL);
1259
1260                 if (nprocs == 0)
1261                         break;
1262
1263                 switch (nprocs) {
1264                 case 1:
1265 #ifndef HAVE_POLLABLE_PROCFS
1266                         if (proc_poll_pipe[0] == -1) {
1267 #endif
1268                                 tcp = pid2tcb(0);
1269                                 if (!tcp)
1270                                         continue;
1271                                 pfd = tcp->pfd;
1272                                 if (pfd == -1)
1273                                         continue;
1274                                 break;
1275 #ifndef HAVE_POLLABLE_PROCFS
1276                         }
1277                         /* fall through ... */
1278 #endif /* !HAVE_POLLABLE_PROCFS */
1279                 default:
1280 #ifdef HAVE_POLLABLE_PROCFS
1281 #ifdef POLL_HACK
1282                         /* On some systems (e.g. UnixWare) we get too much ugly
1283                            "unfinished..." stuff when multiple proceses are in
1284                            syscalls.  Here's a nasty hack */
1285                     
1286                         if (in_syscall) {
1287                                 struct pollfd pv;
1288                                 tcp = in_syscall;
1289                                 in_syscall = NULL;
1290                                 pv.fd = tcp->pfd;
1291                                 pv.events = POLLWANT;
1292                                 if ((what = poll (&pv, 1, 1)) < 0) {
1293                                         if (interrupted)
1294                                                 return 0;
1295                                         continue;
1296                                 }
1297                                 else if (what == 1 && pv.revents & POLLWANT) {
1298                                         goto FOUND;
1299                                 }
1300                         }
1301 #endif
1302
1303                         if (poll(pollv, nprocs, INFTIM) < 0) {
1304                                 if (interrupted)
1305                                         return 0;
1306                                 continue;
1307                         }
1308 #else /* !HAVE_POLLABLE_PROCFS */
1309                         if (proc_poll(pollv, nprocs, INFTIM) < 0) {
1310                                 if (interrupted)
1311                                         return 0;
1312                                 continue;
1313                         }
1314 #endif /* !HAVE_POLLABLE_PROCFS */
1315                         pfd = choose_pfd();
1316                         if (pfd == -1)
1317                                 continue;
1318                         break;
1319                 }
1320
1321                 /* Look up `pfd' in our table. */
1322                 if ((tcp = pfd2tcb(pfd)) == NULL) {
1323                         fprintf(stderr, "unknown pfd: %u\n", pfd);
1324                         exit(1);
1325                 }
1326         FOUND:
1327                 /* Get the status of the process. */
1328                 if (!interrupted) {
1329                         ioctl_result = IOCTL_WSTOP (tcp);
1330                         ioctl_errno = errno;
1331 #ifndef HAVE_POLLABLE_PROCFS
1332                         if (proc_poll_pipe[0] != -1) {
1333                                 if (ioctl_result < 0)
1334                                         kill(poller_pid, SIGKILL);
1335                                 else
1336                                         kill(poller_pid, SIGUSR1);
1337                         }
1338 #endif /* !HAVE_POLLABLE_PROCFS */
1339                 }
1340                 if (interrupted)
1341                         return 0;
1342
1343                 if (interactive)
1344                         sigprocmask(SIG_BLOCK, &blocked_set, NULL);
1345
1346                 if (ioctl_result < 0) {
1347                         /* Find out what happened if it failed. */
1348                         switch (ioctl_errno) {
1349                         case EINTR:
1350                         case EBADF:
1351                                 continue;
1352                         case ENOENT:
1353                                 droptcb(tcp);
1354                                 continue;
1355                         default:
1356                                 perror("PIOCWSTOP");
1357                                 exit(1);
1358                         }
1359                 }
1360
1361                 /* clear the just started flag */
1362                 tcp->flags &= ~TCB_STARTUP;
1363
1364                 /* set current output file */
1365                 outf = tcp->outf;
1366
1367                 if (cflag) {
1368                         struct timeval stime;
1369
1370                         stime.tv_sec = tcp->status.pr_stime.tv_sec;
1371                         stime.tv_usec = tcp->status.pr_stime.tv_nsec/1000;
1372                         tv_sub(&tcp->dtime, &stime, &tcp->stime);
1373                         tcp->stime = stime;
1374                 }
1375
1376                 what = tcp->status.PR_WHAT;
1377                 switch (tcp->status.PR_WHY) {
1378                 case PR_REQUESTED:
1379                         if (tcp->status.PR_FLAGS & PR_ASLEEP) {
1380                                 tcp->status.PR_WHY = PR_SYSENTRY;
1381                                 if (trace_syscall(tcp) < 0) {
1382                                         fprintf(stderr, "syscall trouble\n");
1383                                         exit(1);
1384                                 }
1385                         }
1386                         break;
1387                 case PR_SYSENTRY:
1388 #ifdef POLL_HACK
1389                         in_syscall = tcp;
1390 #endif
1391                 case PR_SYSEXIT:
1392                         if (trace_syscall(tcp) < 0) {
1393                                 fprintf(stderr, "syscall trouble\n");
1394                                 exit(1);
1395                         }
1396                         break;
1397                 case PR_SIGNALLED:
1398                         if (!cflag && (qual_flags[what] & QUAL_SIGNAL)) {
1399                                 printleader(tcp);
1400                                 tprintf("--- %s (%s) ---",
1401                                         signame(what), strsignal(what));
1402                                 printtrailer(tcp);
1403                         }
1404                         break;
1405                 case PR_FAULTED:
1406                         if (!cflag && (qual_flags[what] & QUAL_FAULT)) {
1407                                 printleader(tcp);
1408                                 tprintf("=== FAULT %d ===", what);
1409                                 printtrailer(tcp);
1410                         }
1411                         break;
1412                 default:
1413                         fprintf(stderr, "odd stop %d\n", tcp->status.PR_WHY);
1414                         exit(1);
1415                         break;
1416                 }
1417                 arg = 0;
1418                 if (IOCTL (tcp->pfd, PIOCRUN, &arg) < 0) {
1419                         perror("PIOCRUN");
1420                         exit(1);
1421                 }
1422         }
1423         return 0;
1424 }
1425
1426 #else /* !SVR4 */
1427
1428 static int
1429 trace()
1430 {
1431         int pid;
1432         int wait_errno;
1433         int status;
1434         struct tcb *tcp;
1435 #ifdef LINUX
1436         struct rusage ru;
1437 #endif /* LINUX */
1438
1439         while (nprocs != 0) {
1440                 if (interactive)
1441                         sigprocmask(SIG_SETMASK, &empty_set, NULL);
1442 #ifdef LINUX
1443                 pid = wait4(-1, &status, 0, cflag ? &ru : NULL);
1444 #endif /* LINUX */
1445 #ifdef SUNOS4
1446                 pid = wait(&status);
1447 #endif /* SUNOS4 */
1448                 wait_errno = errno;
1449                 if (interactive)
1450                         sigprocmask(SIG_BLOCK, &blocked_set, NULL);
1451
1452                 if (interrupted)
1453                         return 0;
1454
1455                 if (pid == -1) {
1456                         switch (wait_errno) {
1457                         case EINTR:
1458                                 continue;
1459                         case ECHILD:
1460                                 /*
1461                                  * We would like to verify this case
1462                                  * but sometimes a race in Solbourne's
1463                                  * version of SunOS sometimes reports
1464                                  * ECHILD before sending us SIGCHILD.
1465                                  */
1466 #if 0
1467                                 if (nprocs == 0)
1468                                         return 0;
1469                                 fprintf(stderr, "strace: proc miscount\n");
1470                                 exit(1);
1471 #endif
1472                                 return 0;
1473                         default:
1474                                 errno = wait_errno;
1475                                 perror("strace: wait");
1476                                 return -1;
1477                         }
1478                 }
1479                 if (debug)
1480                         fprintf(stderr, " [wait(%#x) = %u]\n", status, pid);
1481
1482                 /* Look up `pid' in our table. */
1483                 if ((tcp = pid2tcb(pid)) == NULL) {
1484                         fprintf(stderr, "unknown pid: %u\n", pid);
1485                         if (WIFSTOPPED(status))
1486                                 ptrace(PTRACE_CONT, pid, (char *) 1, 0);
1487                         exit(1);
1488                 }
1489                 /* set current output file */
1490                 outf = tcp->outf;
1491                 if (cflag) {
1492 #ifdef LINUX
1493                         tv_sub(&tcp->dtime, &ru.ru_stime, &tcp->stime);
1494                         tcp->stime = ru.ru_stime;
1495 #endif /* !LINUX */
1496                 }
1497
1498                 if (tcp->flags & TCB_SUSPENDED) {
1499                         /*
1500                          * Apparently, doing any ptrace() call on a stopped
1501                          * process, provokes the kernel to report the process
1502                          * status again on a subsequent wait(), even if the
1503                          * process has not been actually restarted.
1504                          * Since we have inspected the arguments of suspended
1505                          * processes we end up here testing for this case.
1506                          */
1507                         continue;
1508                 }
1509                 if (WIFSIGNALED(status)) {
1510                         if (!cflag
1511                             && (qual_flags[WTERMSIG(status)] & QUAL_SIGNAL)) {
1512                                 printleader(tcp);
1513                                 tprintf("+++ killed by %s +++",
1514                                         signame(WTERMSIG(status)));
1515                                 printtrailer(tcp);
1516                         }
1517                         droptcb(tcp);
1518                         continue;
1519                 }
1520                 if (WIFEXITED(status)) {
1521                         if (debug)
1522                                 fprintf(stderr, "pid %u exited\n", pid);
1523                         if (tcp->flags & TCB_ATTACHED)
1524                                 fprintf(stderr,
1525                                         "PANIC: attached pid %u exited\n",
1526                                         pid);
1527                         droptcb(tcp);
1528                         continue;
1529                 }
1530                 if (!WIFSTOPPED(status)) {
1531                         fprintf(stderr, "PANIC: pid %u not stopped\n", pid);
1532                         droptcb(tcp);
1533                         continue;
1534                 }
1535                 if (debug)
1536                         fprintf(stderr, "pid %u stopped, [%s]\n",
1537                                 pid, signame(WSTOPSIG(status)));
1538
1539                 if (tcp->flags & TCB_STARTUP) {
1540                         /*
1541                          * This flag is there to keep us in sync.
1542                          * Next time this process stops it should
1543                          * really be entering a system call.
1544                          */
1545                         tcp->flags &= ~TCB_STARTUP;
1546                         if (tcp->flags & TCB_ATTACHED) {
1547                                 /*
1548                                  * Interestingly, the process may stop
1549                                  * with STOPSIG equal to some other signal
1550                                  * than SIGSTOP if we happend to attach
1551                                  * just before the process takes a signal.
1552                                  */
1553                                 if (!WIFSTOPPED(status)) {
1554                                         fprintf(stderr,
1555                                                 "pid %u not stopped\n", pid);
1556                                         detach(tcp, WSTOPSIG(status));
1557                                         continue;
1558                                 }
1559                         }
1560                         else {
1561 #ifdef SUNOS4
1562                                 /* A child of us stopped at exec */
1563                                 if (WSTOPSIG(status) == SIGTRAP && followvfork)
1564                                         fixvfork(tcp);
1565 #endif /* SUNOS4 */
1566                         }
1567                         if (tcp->flags & TCB_BPTSET) {
1568                                 if (clearbpt(tcp) < 0) /* Pretty fatal */ {
1569                                         droptcb(tcp);
1570                                         cleanup();
1571                                         return -1;
1572                                 }
1573                         }
1574                         goto tracing;
1575                 }
1576
1577                 if (WSTOPSIG(status) != SIGTRAP) {
1578                         if (WSTOPSIG(status) == SIGSTOP &&
1579                                         (tcp->flags & TCB_SIGTRAPPED)) {
1580                                 /*
1581                                  * Trapped attempt to block SIGTRAP
1582                                  * Hope we are back in control now.
1583                                  */
1584                                 tcp->flags &= ~(TCB_INSYSCALL | TCB_SIGTRAPPED);
1585                                 if (ptrace(PTRACE_SYSCALL,
1586                                                 pid, (char *) 1, 0) < 0) {
1587                                         perror("trace: ptrace(PTRACE_SYSCALL, ...)");
1588                                         cleanup();
1589                                         return -1;
1590                                 }
1591                                 continue;
1592                         }
1593                         if (!cflag
1594                             && (qual_flags[WSTOPSIG(status)] & QUAL_SIGNAL)) {
1595                                 printleader(tcp);
1596                                 tprintf("--- %s (%s) ---",
1597                                         signame(WSTOPSIG(status)),
1598                                         strsignal(WSTOPSIG(status)));
1599                                 printtrailer(tcp);
1600                         }
1601                         if ((tcp->flags & TCB_ATTACHED) &&
1602                                 !sigishandled(tcp, WSTOPSIG(status))) {
1603                                 detach(tcp, WSTOPSIG(status));
1604                                 continue;
1605                         }
1606                         if (ptrace(PTRACE_SYSCALL, pid, (char *) 1,
1607                                    WSTOPSIG(status)) < 0) {
1608                                 perror("trace: ptrace(PTRACE_SYSCALL, ...)");
1609                                 cleanup();
1610                                 return -1;
1611                         }
1612                         tcp->flags &= ~TCB_SUSPENDED;
1613                         continue;
1614                 }
1615                 if (trace_syscall(tcp) < 0) {
1616                         if (tcp->flags & TCB_ATTACHED)
1617                                 detach(tcp, 0);
1618                         else {
1619                                 ptrace(PTRACE_KILL,
1620                                         tcp->pid, (char *) 1, SIGTERM);
1621                                 droptcb(tcp);
1622                         }
1623                         continue;
1624                 }
1625                 if (tcp->flags & TCB_EXITING) {
1626                         if (tcp->flags & TCB_ATTACHED)
1627                                 detach(tcp, 0);
1628                         else if (ptrace(PTRACE_CONT, pid, (char *) 1, 0) < 0) {
1629                                 perror("strace: ptrace(PTRACE_CONT, ...)");
1630                                 cleanup();
1631                                 return -1;
1632                         }
1633                         continue;
1634                 }
1635                 if (tcp->flags & TCB_SUSPENDED) {
1636                         if (!qflag)
1637                                 fprintf(stderr, "Process %u suspended\n", pid);
1638                         continue;
1639                 }
1640         tracing:
1641                 if (ptrace(PTRACE_SYSCALL, pid, (char *) 1, 0) < 0) {
1642                         perror("trace: ptrace(PTRACE_SYSCALL, ...)");
1643                         cleanup();
1644                         return -1;
1645                 }
1646         }
1647         return 0;
1648 }
1649
1650 #endif /* !SVR4 */
1651
1652 static int curcol;
1653
1654 #ifdef __STDC__
1655 #include <stdarg.h>
1656 #define VA_START(a, b) va_start(a, b)
1657 #else
1658 #include <varargs.h>
1659 #define VA_START(a, b) va_start(a)
1660 #endif
1661
1662 void
1663 #ifdef __STDC__
1664 tprintf(const char *fmt, ...)
1665 #else
1666 tprintf(fmt, va_alist)
1667 char *fmt;
1668 va_dcl
1669 #endif
1670 {
1671         va_list args;
1672
1673         VA_START(args, fmt);
1674         if (outf)
1675                 curcol += vfprintf(outf, fmt, args);
1676         va_end(args);
1677         return;
1678 }
1679
1680 void
1681 printleader(tcp)
1682 struct tcb *tcp;
1683 {
1684         if (tcp_last && (!outfname || followfork < 2 || tcp_last == tcp)) {
1685                 tcp_last->flags |= TCB_REPRINT;
1686                 tprintf(" <unfinished ...>\n");
1687         }
1688         curcol = 0;
1689         if ((followfork == 1 || pflag_seen > 1) && outfname)
1690                 tprintf("%-5d ", tcp->pid);
1691         else if (nprocs > 1 && !outfname)
1692                 tprintf("[pid %5u] ", tcp->pid);
1693         if (tflag) {
1694                 char str[sizeof("HH:MM:SS")];
1695                 struct timeval tv, dtv;
1696                 static struct timeval otv;
1697
1698                 gettimeofday(&tv, NULL);
1699                 if (rflag) {
1700                         if (otv.tv_sec == 0)
1701                                 otv = tv;
1702                         tv_sub(&dtv, &tv, &otv);
1703                         tprintf("%6ld.%06ld ",
1704                                 (long) dtv.tv_sec, (long) dtv.tv_usec);
1705                         otv = tv;
1706                 }
1707                 else if (tflag > 2) {
1708                         tprintf("%ld.%06ld ",
1709                                 (long) tv.tv_sec, (long) tv.tv_usec);
1710                 }
1711                 else {
1712                         time_t local = tv.tv_sec;
1713                         strftime(str, sizeof(str), "%T", localtime(&local));
1714                         if (tflag > 1)
1715                                 tprintf("%s.%06ld ", str, (long) tv.tv_usec);
1716                         else
1717                                 tprintf("%s ", str);
1718                 }
1719         }
1720         if (iflag)
1721                 printcall(tcp);
1722 }
1723
1724 void
1725 tabto(col)
1726 int col;
1727 {
1728         if (curcol < col)
1729                 tprintf("%*s", col - curcol, "");
1730 }
1731
1732 void
1733 printtrailer(tcp)
1734 struct tcb *tcp;
1735 {
1736         tprintf("\n");
1737         tcp_last = NULL;
1738 }
1739
1740 #ifdef HAVE_MP_PROCFS
1741
1742 int mp_ioctl (int fd, int cmd, void *arg, int size) {
1743
1744         struct iovec iov[2];
1745         int n = 1;
1746         
1747         iov[0].iov_base = &cmd;
1748         iov[0].iov_len = sizeof cmd;
1749         if (arg) {
1750                 ++n;
1751                 iov[1].iov_base = arg;
1752                 iov[1].iov_len = size;
1753         }
1754         
1755         return writev (fd, iov, n);
1756 }
1757
1758 #endif