strace.c revision b310a0c26b3b31d52aa4b25549e06113284bd5bb
176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman/* 276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * Copyright (c) 1991, 1992 Paul Kranenburg <pk@cs.few.eur.nl> 376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * Copyright (c) 1993 Branko Lankester <branko@hacktic.nl> 476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * Copyright (c) 1993, 1994, 1995, 1996 Rick Sladkey <jrs@world.std.com> 54dc8a2aec63e4fb5ee2688544c4de323ed5de3efWichert Akkerman * Copyright (c) 1996-1999 Wichert Akkerman <wichert@cistron.nl> 676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * All rights reserved. 776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * 876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * Redistribution and use in source and binary forms, with or without 976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * modification, are permitted provided that the following conditions 1076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * are met: 1176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * 1. Redistributions of source code must retain the above copyright 1276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * notice, this list of conditions and the following disclaimer. 1376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * 2. Redistributions in binary form must reproduce the above copyright 1476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * notice, this list of conditions and the following disclaimer in the 1576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * documentation and/or other materials provided with the distribution. 1676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * 3. The name of the author may not be used to endorse or promote products 1776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * derived from this software without specific prior written permission. 1876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * 1976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 2076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 2176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 2276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 2376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 2476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 2576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 2676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 2776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 2876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 2976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * 3076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * $Id$ 3176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman */ 3276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 332ee6e45f36566e8735b35ffad40bfcc626a25a98Wichert Akkerman#include <sys/types.h> 3476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#include "defs.h" 3576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 3676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#include <signal.h> 3776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#include <errno.h> 3876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#include <sys/param.h> 3976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#include <fcntl.h> 4076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#include <sys/resource.h> 4176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#include <sys/wait.h> 4276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#include <sys/stat.h> 4376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#include <pwd.h> 4476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#include <grp.h> 4576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#include <string.h> 4619e49984acc8f12dfaf0b7835ad17ca24f854c47John Hughes#include <limits.h> 4776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 487b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman#if defined(IA64) && defined(LINUX) 497b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman# include <asm/ptrace_offsets.h> 507b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman#endif 517b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman 52bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman#ifdef USE_PROCFS 53bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman#include <poll.h> 54bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman#endif 55bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman 5676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#ifdef SVR4 5776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#include <sys/stropts.h> 58ea78f0f77185f7d6d0b2055805139d96e1be816cWichert Akkerman#ifdef HAVE_MP_PROCFS 591d08dcf46dd4b2cfe3e27723c05b0aec9955c591John Hughes#ifdef HAVE_SYS_UIO_H 609ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman#include <sys/uio.h> 619ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman#endif 6276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif 631d08dcf46dd4b2cfe3e27723c05b0aec9955c591John Hughes#endif 6476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 6576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanint debug = 0, followfork = 0, followvfork = 0, interactive = 0; 6676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanint rflag = 0, tflag = 0, dtime = 0, cflag = 0; 6776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanint iflag = 0, xflag = 0, qflag = 0; 6876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanint pflag_seen = 0; 6976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 7017f8fb3484e94976882f65b7a3aaffc6f24cd75dMichal Ludvig/* Sometimes we want to print only succeeding syscalls. */ 7117f8fb3484e94976882f65b7a3aaffc6f24cd75dMichal Ludvigint not_failing_only = 0; 7217f8fb3484e94976882f65b7a3aaffc6f24cd75dMichal Ludvig 7376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanchar *username = NULL; 7476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanuid_t run_uid; 7576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermangid_t run_gid; 7676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 7776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanint acolumn = DEFAULT_ACOLUMN; 7876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanint max_strlen = DEFAULT_STRLEN; 7976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanchar *outfname = NULL; 8076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert AkkermanFILE *outf; 81ee9d435275fd7abf736992f84b5053ee16ec4fc7Roland McGrathstruct tcb **tcbtab; 82ee9d435275fd7abf736992f84b5053ee16ec4fc7Roland McGrathunsigned int nprocs, tcbtabsize; 8376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanchar *progname; 8476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanextern char **environ; 8576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 8676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanstatic int trace P((void)); 8776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanstatic void cleanup P((void)); 8876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanstatic void interrupt P((int sig)); 8976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanstatic sigset_t empty_set, blocked_set; 9076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 9176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#ifdef HAVE_SIG_ATOMIC_T 9276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanstatic volatile sig_atomic_t interrupted; 9376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#else /* !HAVE_SIG_ATOMIC_T */ 9476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#ifdef __STDC__ 9576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanstatic volatile int interrupted; 9676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#else /* !__STDC__ */ 9776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanstatic int interrupted; 9876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif /* !__STDC__ */ 9976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif /* !HAVE_SIG_ATOMIC_T */ 10076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 101bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman#ifdef USE_PROCFS 10276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 10376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanstatic struct tcb *pfd2tcb P((int pfd)); 10476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanstatic void reaper P((int sig)); 10576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanstatic void rebuild_pollv P((void)); 106ee9d435275fd7abf736992f84b5053ee16ec4fc7Roland McGrathstatic struct pollfd *pollv; 10776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 10876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#ifndef HAVE_POLLABLE_PROCFS 10976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 11076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanstatic void proc_poll_open P((void)); 11176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanstatic void proc_poller P((int pfd)); 11276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 11376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanstruct proc_pollfd { 11476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman int fd; 11576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman int revents; 11676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman int pid; 11776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman}; 11876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 11976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanstatic int poller_pid; 12076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanstatic int proc_poll_pipe[2] = { -1, -1 }; 12176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 12276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif /* !HAVE_POLLABLE_PROCFS */ 12376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 124ea78f0f77185f7d6d0b2055805139d96e1be816cWichert Akkerman#ifdef HAVE_MP_PROCFS 1259ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman#define POLLWANT POLLWRNORM 1269ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman#else 1279ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman#define POLLWANT POLLPRI 1289ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman#endif 129bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman#endif /* USE_PROCFS */ 13076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 13176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanstatic void 13276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanusage(ofp, exitval) 13376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert AkkermanFILE *ofp; 13476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanint exitval; 13576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{ 13676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman fprintf(ofp, "\ 13776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanusage: strace [-dffhiqrtttTvVxx] [-a column] [-e expr] ... [-o file]\n\ 138de6e53308ca58da7d357f8114afc74fff7a18043Roland McGrath [-p pid] ... [-s strsize] [-u username] [-E var=val] ...\n\ 139de6e53308ca58da7d357f8114afc74fff7a18043Roland McGrath [command [arg ...]]\n\ 140de6e53308ca58da7d357f8114afc74fff7a18043Roland McGrath or: strace -c [-e expr] ... [-O overhead] [-S sortby] [-E var=val] ...\n\ 141de6e53308ca58da7d357f8114afc74fff7a18043Roland McGrath [command [arg ...]]\n\ 14276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman-c -- count time, calls, and errors for each syscall and report summary\n\ 14376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman-f -- follow forks, -ff -- with output into separate files\n\ 14476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman-F -- attempt to follow vforks, -h -- print help message\n\ 14576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman-i -- print instruction pointer at time of syscall\n\ 14676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman-q -- suppress messages about attaching, detaching, etc.\n\ 14776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman-r -- print relative timestamp, -t -- absolute timestamp, -tt -- with usecs\n\ 14876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman-T -- print time spent in each syscall, -V -- print version\n\ 14976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman-v -- verbose mode: print unabbreviated argv, stat, termio[s], etc. args\n\ 15076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman-x -- print non-ascii strings in hex, -xx -- print all strings in hex\n\ 15176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman-a column -- alignment COLUMN for printing syscall results (default %d)\n\ 15276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman-e expr -- a qualifying expression: option=[!]all or option=[!]val1[,val2]...\n\ 15376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman options: trace, abbrev, verbose, raw, signal, read, or write\n\ 15476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman-o file -- send trace output to FILE instead of stderr\n\ 15576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman-O overhead -- set overhead for tracing syscalls to OVERHEAD usecs\n\ 15676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman-p pid -- trace process with process id PID, may be repeated\n\ 15776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman-s strsize -- limit length of print strings to STRSIZE chars (default %d)\n\ 15876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman-S sortby -- sort syscall counts by: time, calls, name, nothing (default %s)\n\ 15976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman-u username -- run command as username handling setuid and/or setgid\n\ 160de6e53308ca58da7d357f8114afc74fff7a18043Roland McGrath-E var=val -- put var=val in the environment for command\n\ 161de6e53308ca58da7d357f8114afc74fff7a18043Roland McGrath-E var -- remove var from the environment for command\n\ 162de6e53308ca58da7d357f8114afc74fff7a18043Roland McGrath" /* this is broken, so don't document it 16317f8fb3484e94976882f65b7a3aaffc6f24cd75dMichal Ludvig-z -- print only succeeding syscalls\n\ 164de6e53308ca58da7d357f8114afc74fff7a18043Roland McGrath */ 165de6e53308ca58da7d357f8114afc74fff7a18043Roland McGrath, DEFAULT_ACOLUMN, DEFAULT_STRLEN, DEFAULT_SORTBY); 16676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman exit(exitval); 16776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman} 16876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 16976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#ifdef SVR4 17076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#ifdef MIPS 17176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanvoid 17276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanfoobar() 17376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{ 17476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman} 17576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif /* MIPS */ 17676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif /* SVR4 */ 17776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 17876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanint 17976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanmain(argc, argv) 18076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanint argc; 18176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanchar *argv[]; 18276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{ 18376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman extern int optind; 18476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman extern char *optarg; 18576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman struct tcb *tcp; 18676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman int c, pid = 0; 18776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman struct sigaction sa; 18876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 18976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman static char buf[BUFSIZ]; 19076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 191ee9d435275fd7abf736992f84b5053ee16ec4fc7Roland McGrath /* Allocate the initial tcbtab. */ 192ee9d435275fd7abf736992f84b5053ee16ec4fc7Roland McGrath tcbtabsize = argc; /* Surely enough for all -p args. */ 193ee9d435275fd7abf736992f84b5053ee16ec4fc7Roland McGrath tcbtab = (struct tcb **) malloc (tcbtabsize * sizeof tcbtab[0]); 194ee9d435275fd7abf736992f84b5053ee16ec4fc7Roland McGrath tcbtab[0] = (struct tcb *) calloc (tcbtabsize, sizeof *tcbtab[0]); 195ee9d435275fd7abf736992f84b5053ee16ec4fc7Roland McGrath for (tcp = tcbtab[0]; tcp < &tcbtab[0][tcbtabsize]; ++tcp) 196ee9d435275fd7abf736992f84b5053ee16ec4fc7Roland McGrath tcbtab[tcp - tcbtab[0]] = &tcbtab[0][tcp - tcbtab[0]]; 197ee9d435275fd7abf736992f84b5053ee16ec4fc7Roland McGrath 19876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman progname = argv[0]; 19976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman outf = stderr; 20076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman interactive = 1; 20176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman qualify("trace=all"); 20276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman qualify("abbrev=all"); 20376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman qualify("verbose=all"); 20476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman qualify("signal=all"); 20576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman set_sortby(DEFAULT_SORTBY); 20676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman set_personality(DEFAULT_PERSONALITY); 20776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman while ((c = getopt(argc, argv, 208de6e53308ca58da7d357f8114afc74fff7a18043Roland McGrath "+cdfFhiqrtTvVxza:e:o:O:p:s:S:u:E:")) != EOF) { 20976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman switch (c) { 21076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman case 'c': 21176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman cflag++; 21276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman dtime++; 21376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman break; 21476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman case 'd': 21576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman debug++; 21676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman break; 21776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman case 'f': 21876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman followfork++; 21976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman break; 22076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman case 'F': 22176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman followvfork++; 22276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman break; 22376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman case 'h': 22476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman usage(stdout, 0); 22576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman break; 22676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman case 'i': 22776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman iflag++; 22876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman break; 22976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman case 'q': 23076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman qflag++; 23176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman break; 23276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman case 'r': 23376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman rflag++; 23476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tflag++; 23576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman break; 23676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman case 't': 23776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tflag++; 23876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman break; 23976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman case 'T': 24076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman dtime++; 24176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman break; 24276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman case 'x': 24376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman xflag++; 24476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman break; 24576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman case 'v': 24676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman qualify("abbrev=none"); 24776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman break; 24876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman case 'V': 2499c9a2534e361b683f1e4e08804b7166a01475bf1Roland McGrath printf("%s -- version %s\n", PACKAGE_NAME, VERSION); 25076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman exit(0); 25176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman break; 25217f8fb3484e94976882f65b7a3aaffc6f24cd75dMichal Ludvig case 'z': 25317f8fb3484e94976882f65b7a3aaffc6f24cd75dMichal Ludvig not_failing_only = 1; 25417f8fb3484e94976882f65b7a3aaffc6f24cd75dMichal Ludvig break; 25576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman case 'a': 25676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman acolumn = atoi(optarg); 25776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman break; 25876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman case 'e': 25976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman qualify(optarg); 26076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman break; 26176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman case 'o': 26276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman outfname = strdup(optarg); 26376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman break; 26476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman case 'O': 26576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman set_overhead(atoi(optarg)); 26676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman break; 26776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman case 'p': 268de6e53308ca58da7d357f8114afc74fff7a18043Roland McGrath if ((pid = atoi(optarg)) <= 0) { 26976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman fprintf(stderr, "%s: Invalid process id: %s\n", 27076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman progname, optarg); 27176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman break; 27276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 27376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (pid == getpid()) { 27454a4767f8609abfe2d7cb1802bc9e8dca97dd08fWichert Akkerman fprintf(stderr, "%s: I'm sorry, I can't let you do that, Dave.\n", progname); 27576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman break; 27676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 27776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if ((tcp = alloctcb(pid)) == NULL) { 278de6e53308ca58da7d357f8114afc74fff7a18043Roland McGrath fprintf(stderr, "%s: out of memory\n", 27976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman progname); 28076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman exit(1); 28176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 28276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tcp->flags |= TCB_ATTACHED; 28376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman pflag_seen++; 28476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman break; 28576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman case 's': 28676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman max_strlen = atoi(optarg); 28776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman break; 28876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman case 'S': 28976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman set_sortby(optarg); 29076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman break; 29176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman case 'u': 29276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman username = strdup(optarg); 29376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman break; 294de6e53308ca58da7d357f8114afc74fff7a18043Roland McGrath case 'E': 295de6e53308ca58da7d357f8114afc74fff7a18043Roland McGrath if (putenv(optarg) < 0) { 296de6e53308ca58da7d357f8114afc74fff7a18043Roland McGrath fprintf(stderr, "%s: out of memory\n", 297de6e53308ca58da7d357f8114afc74fff7a18043Roland McGrath progname); 298de6e53308ca58da7d357f8114afc74fff7a18043Roland McGrath exit(1); 299de6e53308ca58da7d357f8114afc74fff7a18043Roland McGrath } 300de6e53308ca58da7d357f8114afc74fff7a18043Roland McGrath break; 30176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman default: 30276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman usage(stderr, 1); 30376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman break; 30476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 30576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 30676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 30776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman /* See if they want to run as another user. */ 30876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (username != NULL) { 30976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman struct passwd *pent; 31076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 31176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (getuid() != 0 || geteuid() != 0) { 31276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman fprintf(stderr, 31376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman "%s: you must be root to use the -u option\n", 31476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman progname); 31576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman exit(1); 31676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 31776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if ((pent = getpwnam(username)) == NULL) { 31876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman fprintf(stderr, "%s: cannot find user `%s'\n", 31976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman progname, optarg); 32076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman exit(1); 32176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 32276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman run_uid = pent->pw_uid; 32376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman run_gid = pent->pw_gid; 32476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 32576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman else { 32676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman run_uid = getuid(); 32776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman run_gid = getgid(); 32876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 32976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 33076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#ifndef SVR4 33176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman setreuid(geteuid(), getuid()); 33276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif 33376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 33476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman /* See if they want to pipe the output. */ 33576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (outfname && (outfname[0] == '|' || outfname[0] == '!')) { 33676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if ((outf = popen(outfname + 1, "w")) == NULL) { 33776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman fprintf(stderr, "%s: can't popen '%s': %s\n", 33876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman progname, outfname + 1, strerror(errno)); 33976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman exit(1); 34076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 34176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman free(outfname); 34276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman outfname = NULL; 34376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 34476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 34576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman /* Check if they want to redirect the output. */ 34676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (outfname) { 34754b4f79216c819ec93aaf5031acb1772fccef7a9Wichert Akkerman long f; 34854b4f79216c819ec93aaf5031acb1772fccef7a9Wichert Akkerman 34976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if ((outf = fopen(outfname, "w")) == NULL) { 35076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman fprintf(stderr, "%s: can't fopen '%s': %s\n", 35176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman progname, outfname, strerror(errno)); 35276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman exit(1); 35376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 35454b4f79216c819ec93aaf5031acb1772fccef7a9Wichert Akkerman 35554b4f79216c819ec93aaf5031acb1772fccef7a9Wichert Akkerman if ((f=fcntl(fileno(outf), F_GETFD)) < 0 ) { 35654b4f79216c819ec93aaf5031acb1772fccef7a9Wichert Akkerman perror("failed to get flags for outputfile"); 35754b4f79216c819ec93aaf5031acb1772fccef7a9Wichert Akkerman exit(1); 35854b4f79216c819ec93aaf5031acb1772fccef7a9Wichert Akkerman } 35954b4f79216c819ec93aaf5031acb1772fccef7a9Wichert Akkerman 36054b4f79216c819ec93aaf5031acb1772fccef7a9Wichert Akkerman if (fcntl(fileno(outf), F_SETFD, f|FD_CLOEXEC) < 0 ) { 36154b4f79216c819ec93aaf5031acb1772fccef7a9Wichert Akkerman perror("failed to set flags for outputfile"); 36254b4f79216c819ec93aaf5031acb1772fccef7a9Wichert Akkerman exit(1); 36354b4f79216c819ec93aaf5031acb1772fccef7a9Wichert Akkerman } 36476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 36576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 36676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#ifndef SVR4 36776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman setreuid(geteuid(), getuid()); 36876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif 36976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 37076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (!outfname) { 37176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman setvbuf(outf, buf, _IOLBF, BUFSIZ); 37276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 373369310502bfca4b202d72be9452c8cdb55bb6d5eRoland McGrath else if (optind < argc) { 37476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman interactive = 0; 37576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman qflag = 1; 376369310502bfca4b202d72be9452c8cdb55bb6d5eRoland McGrath } 37776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 378ee9d435275fd7abf736992f84b5053ee16ec4fc7Roland McGrath for (c = 0; c < tcbtabsize; c++) { 379ee9d435275fd7abf736992f84b5053ee16ec4fc7Roland McGrath tcp = tcbtab[c]; 38076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman /* Reinitialize the output since it may have changed. */ 38176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tcp->outf = outf; 38276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (!(tcp->flags & TCB_INUSE) || !(tcp->flags & TCB_ATTACHED)) 38376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman continue; 384bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman#ifdef USE_PROCFS 38576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (proc_open(tcp, 1) < 0) { 38676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman fprintf(stderr, "trouble opening proc file\n"); 38776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman droptcb(tcp); 38876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman continue; 38976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 390bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman#else /* !USE_PROCFS */ 39176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (ptrace(PTRACE_ATTACH, tcp->pid, (char *) 1, 0) < 0) { 39276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman perror("attach: ptrace(PTRACE_ATTACH, ...)"); 39376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman droptcb(tcp); 39476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman continue; 39576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 396bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman#endif /* !USE_PROCFS */ 39776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (!qflag) 39876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman fprintf(stderr, 39976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman "Process %u attached - interrupt to quit\n", 40076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman pid); 40176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 40276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 40376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (optind < argc) { 40476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman struct stat statbuf; 40576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman char *filename; 40676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman char pathname[MAXPATHLEN]; 40776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 40876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman filename = argv[optind]; 40976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (strchr(filename, '/')) 41076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman strcpy(pathname, filename); 41176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#ifdef USE_DEBUGGING_EXEC 41276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman /* 41376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * Debuggers customarily check the current directory 41476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * first regardless of the path but doing that gives 41576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * security geeks a panic attack. 41676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman */ 41776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman else if (stat(filename, &statbuf) == 0) 41876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman strcpy(pathname, filename); 41976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif /* USE_DEBUGGING_EXEC */ 42076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman else { 42176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman char *path; 42276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman int m, n, len; 42376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 42476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman for (path = getenv("PATH"); path && *path; path += m) { 42576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (strchr(path, ':')) { 42676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman n = strchr(path, ':') - path; 42776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman m = n + 1; 42876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 42976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman else 43076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman m = n = strlen(path); 43176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (n == 0) { 43276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman getcwd(pathname, MAXPATHLEN); 43376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman len = strlen(pathname); 43476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 43576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman else { 43676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman strncpy(pathname, path, n); 43776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman len = n; 43876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 43976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (len && pathname[len - 1] != '/') 44076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman pathname[len++] = '/'; 44176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman strcpy(pathname + len, filename); 442ed64516fa4f4ce25308a1f2ad3b84f8734c3e783Roland McGrath if (stat(pathname, &statbuf) == 0 && 443ed64516fa4f4ce25308a1f2ad3b84f8734c3e783Roland McGrath /* Accept only regular files 444ed64516fa4f4ce25308a1f2ad3b84f8734c3e783Roland McGrath with some execute bits set. 445ed64516fa4f4ce25308a1f2ad3b84f8734c3e783Roland McGrath XXX not perfect, might still fail */ 446ed64516fa4f4ce25308a1f2ad3b84f8734c3e783Roland McGrath S_ISREG(statbuf.st_mode) && 447ed64516fa4f4ce25308a1f2ad3b84f8734c3e783Roland McGrath (statbuf.st_mode & 0111)) 44876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman break; 44976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 45076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 45176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (stat(pathname, &statbuf) < 0) { 45276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman fprintf(stderr, "%s: %s: command not found\n", 45376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman progname, filename); 45476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman exit(1); 45576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 45676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman switch (pid = fork()) { 45776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman case -1: 45876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman perror("strace: fork"); 45976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman cleanup(); 46076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman exit(1); 46176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman break; 46276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman case 0: { 463bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman#ifdef USE_PROCFS 464bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman if (outf != stderr) close (fileno (outf)); 46576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#ifdef MIPS 46676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman /* Kludge for SGI, see proc_open for details. */ 46776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman sa.sa_handler = foobar; 46876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman sa.sa_flags = 0; 46976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman sigemptyset(&sa.sa_mask); 47076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman sigaction(SIGINT, &sa, NULL); 47176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif /* MIPS */ 472bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman#ifndef FREEBSD 47376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman pause(); 474bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman#else /* FREEBSD */ 475bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman kill(getpid(), SIGSTOP); /* stop HERE */ 476553a609807074e95eed5a0bffba334b7fb3d3751Roland McGrath#endif /* FREEBSD */ 477bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman#else /* !USE_PROCFS */ 478553a609807074e95eed5a0bffba334b7fb3d3751Roland McGrath if (outf!=stderr) 4797987cdf192632516d6ba493b0a9943f5a3a7c362Wichert Akkerman close(fileno (outf)); 480bd4125c6bcd20e8f014b682b31d6fc5d0fef3ed0Wichert Akkerman 48176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (ptrace(PTRACE_TRACEME, 0, (char *) 1, 0) < 0) { 48276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman perror("strace: ptrace(PTRACE_TRACEME, ...)"); 48376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 48476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 48576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (debug) 48676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman kill(getpid(), SIGSTOP); 48776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 48876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (username != NULL || geteuid() == 0) { 48976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman uid_t run_euid = run_uid; 49076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman gid_t run_egid = run_gid; 49176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 49276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (statbuf.st_mode & S_ISUID) 49376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman run_euid = statbuf.st_uid; 49476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (statbuf.st_mode & S_ISGID) 49576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman run_egid = statbuf.st_gid; 49676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 49776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman /* 49876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * It is important to set groups before we 49976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * lose privileges on setuid. 50076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman */ 5015ae21ead9f83597452f9a0517e8a51fa4823f921Wichert Akkerman if (username != NULL) { 5025ae21ead9f83597452f9a0517e8a51fa4823f921Wichert Akkerman if (initgroups(username, run_gid) < 0) { 5035ae21ead9f83597452f9a0517e8a51fa4823f921Wichert Akkerman perror("initgroups"); 5045ae21ead9f83597452f9a0517e8a51fa4823f921Wichert Akkerman exit(1); 5055ae21ead9f83597452f9a0517e8a51fa4823f921Wichert Akkerman } 5065ae21ead9f83597452f9a0517e8a51fa4823f921Wichert Akkerman if (setregid(run_gid, run_egid) < 0) { 5075ae21ead9f83597452f9a0517e8a51fa4823f921Wichert Akkerman perror("setregid"); 5085ae21ead9f83597452f9a0517e8a51fa4823f921Wichert Akkerman exit(1); 5095ae21ead9f83597452f9a0517e8a51fa4823f921Wichert Akkerman } 5105ae21ead9f83597452f9a0517e8a51fa4823f921Wichert Akkerman if (setreuid(run_uid, run_euid) < 0) { 5115ae21ead9f83597452f9a0517e8a51fa4823f921Wichert Akkerman perror("setreuid"); 5125ae21ead9f83597452f9a0517e8a51fa4823f921Wichert Akkerman exit(1); 5135ae21ead9f83597452f9a0517e8a51fa4823f921Wichert Akkerman } 51476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 51576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 51676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman else 51776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman setreuid(run_uid, run_uid); 518bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman#endif /* !USE_PROCFS */ 51976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 52076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman execv(pathname, &argv[optind]); 52176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman perror("strace: exec"); 52276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman _exit(1); 52376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman break; 52476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 52576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman default: 52676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if ((tcp = alloctcb(pid)) == NULL) { 52776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman fprintf(stderr, "tcb table full\n"); 52876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman cleanup(); 52976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman exit(1); 53076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 531bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman#ifdef USE_PROCFS 53276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (proc_open(tcp, 0) < 0) { 53376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman fprintf(stderr, "trouble opening proc file\n"); 53476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman cleanup(); 53576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman exit(1); 53676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 537bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman#endif /* USE_PROCFS */ 538bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman#ifndef USE_PROCFS 53976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman fake_execve(tcp, pathname, &argv[optind], environ); 540bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman#endif /* !USE_PROCFS */ 54176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman break; 54276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 54376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 54476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman else if (pflag_seen == 0) 54576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman usage(stderr, 1); 54676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 54776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman sigemptyset(&empty_set); 54876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman sigemptyset(&blocked_set); 54976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman sa.sa_handler = SIG_IGN; 55076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman sigemptyset(&sa.sa_mask); 55176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman sa.sa_flags = 0; 55276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman sigaction(SIGTTOU, &sa, NULL); 55376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman sigaction(SIGTTIN, &sa, NULL); 55476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (interactive) { 55576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman sigaddset(&blocked_set, SIGHUP); 55676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman sigaddset(&blocked_set, SIGINT); 55776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman sigaddset(&blocked_set, SIGQUIT); 55876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman sigaddset(&blocked_set, SIGPIPE); 55976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman sigaddset(&blocked_set, SIGTERM); 56076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman sa.sa_handler = interrupt; 56176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#ifdef SUNOS4 56276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman /* POSIX signals on sunos4.1 are a little broken. */ 56376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman sa.sa_flags = SA_INTERRUPT; 56476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif /* SUNOS4 */ 56576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 56676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman sigaction(SIGHUP, &sa, NULL); 56776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman sigaction(SIGINT, &sa, NULL); 56876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman sigaction(SIGQUIT, &sa, NULL); 56976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman sigaction(SIGPIPE, &sa, NULL); 57076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman sigaction(SIGTERM, &sa, NULL); 571bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman#ifdef USE_PROCFS 57276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman sa.sa_handler = reaper; 57376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman sigaction(SIGCHLD, &sa, NULL); 574553a609807074e95eed5a0bffba334b7fb3d3751Roland McGrath#else 575553a609807074e95eed5a0bffba334b7fb3d3751Roland McGrath /* Make sure SIGCHLD has the default action so that waitpid 576553a609807074e95eed5a0bffba334b7fb3d3751Roland McGrath definitely works without losing track of children. The user 577553a609807074e95eed5a0bffba334b7fb3d3751Roland McGrath should not have given us a bogus state to inherit, but he might 578553a609807074e95eed5a0bffba334b7fb3d3751Roland McGrath have. Arguably we should detect SIG_IGN here and pass it on 579553a609807074e95eed5a0bffba334b7fb3d3751Roland McGrath to children, but probably noone really needs that. */ 580553a609807074e95eed5a0bffba334b7fb3d3751Roland McGrath sa.sa_handler = SIG_DFL; 581553a609807074e95eed5a0bffba334b7fb3d3751Roland McGrath sigaction(SIGCHLD, &sa, NULL); 582bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman#endif /* USE_PROCFS */ 58376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 58476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (trace() < 0) 58576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman exit(1); 58676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman cleanup(); 58776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman exit(0); 58876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman} 58976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 59076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanvoid 59176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermannewoutf(tcp) 59276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanstruct tcb *tcp; 59376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{ 59476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman char name[MAXPATHLEN]; 59576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman FILE *fp; 59676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 59776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (outfname && followfork > 1) { 59876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman sprintf(name, "%s.%u", outfname, tcp->pid); 59976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#ifndef SVR4 60076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman setreuid(geteuid(), getuid()); 60176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif 60276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman fp = fopen(name, "w"); 60376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#ifndef SVR4 60476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman setreuid(geteuid(), getuid()); 60576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif 60676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (fp == NULL) { 60776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman perror("fopen"); 60876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return; 60976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 61076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tcp->outf = fp; 61176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 61276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return; 61376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman} 61476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 61576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanstruct tcb * 61676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanalloctcb(pid) 61776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanint pid; 61876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{ 61976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman int i; 62076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman struct tcb *tcp; 62176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 622ee9d435275fd7abf736992f84b5053ee16ec4fc7Roland McGrath for (i = 0; i < tcbtabsize; i++) { 623ee9d435275fd7abf736992f84b5053ee16ec4fc7Roland McGrath tcp = tcbtab[i]; 62476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if ((tcp->flags & TCB_INUSE) == 0) { 62576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tcp->pid = pid; 62676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tcp->parent = NULL; 62776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tcp->nchildren = 0; 6280962345a5775e0eea75c3ec408fb4807e851e7f0Roland McGrath tcp->nzombies = 0; 629e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath#ifdef TCB_CLONE_THREAD 630e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath tcp->nclone_threads = tcp->nclone_detached = 0; 631e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath tcp->nclone_waiting = 0; 632e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath#endif 63376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tcp->flags = TCB_INUSE | TCB_STARTUP; 63476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tcp->outf = outf; /* Initialise to current out file */ 63576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tcp->stime.tv_sec = 0; 63676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tcp->stime.tv_usec = 0; 63776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tcp->pfd = -1; 63876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman nprocs++; 63976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return tcp; 64076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 64176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 64276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return NULL; 64376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman} 64476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 645bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman#ifdef USE_PROCFS 64676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanint 64776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanproc_open(tcp, attaching) 64876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanstruct tcb *tcp; 64976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanint attaching; 65076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{ 65176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman char proc[32]; 65276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman long arg; 653bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman#ifdef SVR4 65419e49984acc8f12dfaf0b7835ad17ca24f854c47John Hughes int i; 65519e49984acc8f12dfaf0b7835ad17ca24f854c47John Hughes sysset_t syscalls; 65676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman sigset_t signals; 65776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman fltset_t faults; 658bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman#endif 65976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#ifndef HAVE_POLLABLE_PROCFS 66076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman static int last_pfd; 66176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif 66276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 663ea78f0f77185f7d6d0b2055805139d96e1be816cWichert Akkerman#ifdef HAVE_MP_PROCFS 6649ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman /* Open the process pseudo-files in /proc. */ 6659ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman sprintf(proc, "/proc/%d/ctl", tcp->pid); 6669ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman if ((tcp->pfd = open(proc, O_WRONLY|O_EXCL)) < 0) { 6679ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman perror("strace: open(\"/proc/...\", ...)"); 6689ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman return -1; 6699ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman } 6709ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman if ((arg = fcntl(tcp->pfd, F_GETFD)) < 0) { 6719ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman perror("F_GETFD"); 6729ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman return -1; 6739ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman } 6749ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman if (fcntl(tcp->pfd, F_SETFD, arg|FD_CLOEXEC) < 0) { 6759ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman perror("F_SETFD"); 6769ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman return -1; 6779ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman } 6789ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman sprintf(proc, "/proc/%d/status", tcp->pid); 6799ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman if ((tcp->pfd_stat = open(proc, O_RDONLY|O_EXCL)) < 0) { 6809ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman perror("strace: open(\"/proc/...\", ...)"); 6819ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman return -1; 6829ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman } 6839ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman if ((arg = fcntl(tcp->pfd_stat, F_GETFD)) < 0) { 6849ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman perror("F_GETFD"); 6859ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman return -1; 6869ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman } 6879ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman if (fcntl(tcp->pfd_stat, F_SETFD, arg|FD_CLOEXEC) < 0) { 6889ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman perror("F_SETFD"); 6899ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman return -1; 6909ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman } 6919ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman sprintf(proc, "/proc/%d/as", tcp->pid); 6929ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman if ((tcp->pfd_as = open(proc, O_RDONLY|O_EXCL)) < 0) { 6939ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman perror("strace: open(\"/proc/...\", ...)"); 6949ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman return -1; 6959ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman } 6969ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman if ((arg = fcntl(tcp->pfd_as, F_GETFD)) < 0) { 6979ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman perror("F_GETFD"); 6989ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman return -1; 6999ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman } 7009ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman if (fcntl(tcp->pfd_as, F_SETFD, arg|FD_CLOEXEC) < 0) { 7019ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman perror("F_SETFD"); 7029ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman return -1; 7039ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman } 7049ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman#else 70576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman /* Open the process pseudo-file in /proc. */ 706bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman#ifndef FREEBSD 70776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman sprintf(proc, "/proc/%d", tcp->pid); 70876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if ((tcp->pfd = open(proc, O_RDWR|O_EXCL)) < 0) { 709bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman#else /* FREEBSD */ 710bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman sprintf(proc, "/proc/%d/mem", tcp->pid); 711bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman if ((tcp->pfd = open(proc, O_RDWR)) < 0) { 712bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman#endif /* FREEBSD */ 71376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman perror("strace: open(\"/proc/...\", ...)"); 71476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 71576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 7169ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman if ((arg = fcntl(tcp->pfd, F_GETFD)) < 0) { 7179ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman perror("F_GETFD"); 7189ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman return -1; 7199ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman } 7209ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman if (fcntl(tcp->pfd, F_SETFD, arg|FD_CLOEXEC) < 0) { 7219ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman perror("F_SETFD"); 7229ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman return -1; 7239ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman } 7249ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman#endif 725bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman#ifdef FREEBSD 726bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman sprintf(proc, "/proc/%d/regs", tcp->pid); 727bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman if ((tcp->pfd_reg = open(proc, O_RDONLY)) < 0) { 728bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman perror("strace: open(\"/proc/.../regs\", ...)"); 729bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman return -1; 730bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman } 731bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman if (cflag) { 732bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman sprintf(proc, "/proc/%d/status", tcp->pid); 733bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman if ((tcp->pfd_status = open(proc, O_RDONLY)) < 0) { 734bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman perror("strace: open(\"/proc/.../status\", ...)"); 735bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman return -1; 736bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman } 737bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman } else 738bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman tcp->pfd_status = -1; 739bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman#endif /* FREEBSD */ 74076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman rebuild_pollv(); 74176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (!attaching) { 74276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman /* 74376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * Wait for the child to pause. Because of a race 74476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * condition we have to poll for the event. 74576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman */ 74676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman for (;;) { 7479ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman if (IOCTL_STATUS (tcp) < 0) { 74876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman perror("strace: PIOCSTATUS"); 74976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 75076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 7519ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman if (tcp->status.PR_FLAGS & PR_ASLEEP) 752bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman break; 75376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 75476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 755bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman#ifndef FREEBSD 75676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman /* Stop the process so that we own the stop. */ 75716a03d2e97415afe6cf34172a0aea97a95a0b160Wichert Akkerman if (IOCTL(tcp->pfd, PIOCSTOP, (char *)NULL) < 0) { 75876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman perror("strace: PIOCSTOP"); 75976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 76076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 761553a609807074e95eed5a0bffba334b7fb3d3751Roland McGrath#endif 76276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#ifdef PIOCSET 76376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman /* Set Run-on-Last-Close. */ 76476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman arg = PR_RLC; 7659ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman if (IOCTL(tcp->pfd, PIOCSET, &arg) < 0) { 76676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman perror("PIOCSET PR_RLC"); 76776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 76876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 76976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman /* Set or Reset Inherit-on-Fork. */ 77076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman arg = PR_FORK; 7719ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman if (IOCTL(tcp->pfd, followfork ? PIOCSET : PIOCRESET, &arg) < 0) { 77276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman perror("PIOC{SET,RESET} PR_FORK"); 77376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 77476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 77576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#else /* !PIOCSET */ 776553a609807074e95eed5a0bffba334b7fb3d3751Roland McGrath#ifndef FREEBSD 77776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (ioctl(tcp->pfd, PIOCSRLC) < 0) { 77876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman perror("PIOCSRLC"); 77976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 78076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 78176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (ioctl(tcp->pfd, followfork ? PIOCSFORK : PIOCRFORK) < 0) { 78276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman perror("PIOC{S,R}FORK"); 78376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 78476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 785bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman#else /* FREEBSD */ 786bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman /* just unset the PF_LINGER flag for the Run-on-Last-Close. */ 787bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman if (ioctl(tcp->pfd, PIOCGFL, &arg) < 0) { 788bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman perror("PIOCGFL"); 789bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman return -1; 790bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman } 791bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman arg &= ~PF_LINGER; 792bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman if (ioctl(tcp->pfd, PIOCSFL, arg) < 0) { 793bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman perror("PIOCSFL"); 794bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman return -1; 795bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman } 796bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman#endif /* FREEBSD */ 79776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif /* !PIOCSET */ 798bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman#ifndef FREEBSD 79919e49984acc8f12dfaf0b7835ad17ca24f854c47John Hughes /* Enable all syscall entries we care about. */ 80019e49984acc8f12dfaf0b7835ad17ca24f854c47John Hughes premptyset(&syscalls); 80119e49984acc8f12dfaf0b7835ad17ca24f854c47John Hughes for (i = 1; i < MAX_QUALS; ++i) { 80219e49984acc8f12dfaf0b7835ad17ca24f854c47John Hughes if (i > (sizeof syscalls) * CHAR_BIT) break; 80319e49984acc8f12dfaf0b7835ad17ca24f854c47John Hughes if (qual_flags [i] & QUAL_TRACE) praddset (&syscalls, i); 80419e49984acc8f12dfaf0b7835ad17ca24f854c47John Hughes } 80519e49984acc8f12dfaf0b7835ad17ca24f854c47John Hughes praddset (&syscalls, SYS_execve); 80619e49984acc8f12dfaf0b7835ad17ca24f854c47John Hughes if (followfork) { 80719e49984acc8f12dfaf0b7835ad17ca24f854c47John Hughes praddset (&syscalls, SYS_fork); 80819e49984acc8f12dfaf0b7835ad17ca24f854c47John Hughes#ifdef SYS_forkall 80919e49984acc8f12dfaf0b7835ad17ca24f854c47John Hughes praddset (&syscalls, SYS_forkall); 81019e49984acc8f12dfaf0b7835ad17ca24f854c47John Hughes#endif 811553a609807074e95eed5a0bffba334b7fb3d3751Roland McGrath#ifdef SYS_fork1 81219e49984acc8f12dfaf0b7835ad17ca24f854c47John Hughes praddset (&syscalls, SYS_fork1); 81319e49984acc8f12dfaf0b7835ad17ca24f854c47John Hughes#endif 81419e49984acc8f12dfaf0b7835ad17ca24f854c47John Hughes#ifdef SYS_rfork1 81519e49984acc8f12dfaf0b7835ad17ca24f854c47John Hughes praddset (&syscalls, SYS_rfork1); 81619e49984acc8f12dfaf0b7835ad17ca24f854c47John Hughes#endif 81719e49984acc8f12dfaf0b7835ad17ca24f854c47John Hughes#ifdef SYS_rforkall 81819e49984acc8f12dfaf0b7835ad17ca24f854c47John Hughes praddset (&syscalls, SYS_rforkall); 81919e49984acc8f12dfaf0b7835ad17ca24f854c47John Hughes#endif 82019e49984acc8f12dfaf0b7835ad17ca24f854c47John Hughes } 82119e49984acc8f12dfaf0b7835ad17ca24f854c47John Hughes if (IOCTL(tcp->pfd, PIOCSENTRY, &syscalls) < 0) { 82276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman perror("PIOCSENTRY"); 82376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 82476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 82519e49984acc8f12dfaf0b7835ad17ca24f854c47John Hughes /* Enable the syscall exits. */ 82619e49984acc8f12dfaf0b7835ad17ca24f854c47John Hughes if (IOCTL(tcp->pfd, PIOCSEXIT, &syscalls) < 0) { 82776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman perror("PIOSEXIT"); 82876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 82976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 83019e49984acc8f12dfaf0b7835ad17ca24f854c47John Hughes /* Enable signals we care about. */ 83119e49984acc8f12dfaf0b7835ad17ca24f854c47John Hughes premptyset(&signals); 83219e49984acc8f12dfaf0b7835ad17ca24f854c47John Hughes for (i = 1; i < MAX_QUALS; ++i) { 83319e49984acc8f12dfaf0b7835ad17ca24f854c47John Hughes if (i > (sizeof signals) * CHAR_BIT) break; 83419e49984acc8f12dfaf0b7835ad17ca24f854c47John Hughes if (qual_flags [i] & QUAL_SIGNAL) praddset (&signals, i); 83519e49984acc8f12dfaf0b7835ad17ca24f854c47John Hughes } 8369ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman if (IOCTL(tcp->pfd, PIOCSTRACE, &signals) < 0) { 83776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman perror("PIOCSTRACE"); 83876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 83976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 84019e49984acc8f12dfaf0b7835ad17ca24f854c47John Hughes /* Enable faults we care about */ 84119e49984acc8f12dfaf0b7835ad17ca24f854c47John Hughes premptyset(&faults); 84219e49984acc8f12dfaf0b7835ad17ca24f854c47John Hughes for (i = 1; i < MAX_QUALS; ++i) { 84319e49984acc8f12dfaf0b7835ad17ca24f854c47John Hughes if (i > (sizeof faults) * CHAR_BIT) break; 84419e49984acc8f12dfaf0b7835ad17ca24f854c47John Hughes if (qual_flags [i] & QUAL_FAULT) praddset (&faults, i); 84519e49984acc8f12dfaf0b7835ad17ca24f854c47John Hughes } 8469ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman if (IOCTL(tcp->pfd, PIOCSFAULT, &faults) < 0) { 84776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman perror("PIOCSFAULT"); 84876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 84976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 850bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman#else /* FREEBSD */ 851bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman /* set events flags. */ 852bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman arg = S_SIG | S_SCE | S_SCX ; 853bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman if(ioctl(tcp->pfd, PIOCBIS, arg) < 0) { 854bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman perror("PIOCBIS"); 855bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman return -1; 856bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman } 857bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman#endif /* FREEBSD */ 85876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (!attaching) { 85976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#ifdef MIPS 86076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman /* 86176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * The SGI PRSABORT doesn't work for pause() so 86276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * we send it a caught signal to wake it up. 86376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman */ 86476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman kill(tcp->pid, SIGINT); 86576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#else /* !MIPS */ 866553a609807074e95eed5a0bffba334b7fb3d3751Roland McGrath#ifdef PRSABORT 86776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman /* The child is in a pause(), abort it. */ 8689ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman arg = PRSABORT; 8699ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman if (IOCTL (tcp->pfd, PIOCRUN, &arg) < 0) { 87076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman perror("PIOCRUN"); 87176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 87276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 873553a609807074e95eed5a0bffba334b7fb3d3751Roland McGrath#endif 874bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman#endif /* !MIPS*/ 875bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman#ifdef FREEBSD 876bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman /* wake up the child if it received the SIGSTOP */ 877bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman kill(tcp->pid, SIGCONT); 878553a609807074e95eed5a0bffba334b7fb3d3751Roland McGrath#endif 87976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman for (;;) { 88076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman /* Wait for the child to do something. */ 8819ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman if (IOCTL_WSTOP (tcp) < 0) { 88276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman perror("PIOCWSTOP"); 88376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 88476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 8859ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman if (tcp->status.PR_WHY == PR_SYSENTRY) { 886bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman tcp->flags &= ~TCB_INSYSCALL; 887bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman get_scno(tcp); 888bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman if (tcp->scno == SYS_execve) 88976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman break; 89076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 89176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman /* Set it running: maybe execve will be next. */ 892bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman#ifndef FREEBSD 8939ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman arg = 0; 8949ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman if (IOCTL(tcp->pfd, PIOCRUN, &arg) < 0) { 895bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman#else /* FREEBSD */ 896bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman if (IOCTL(tcp->pfd, PIOCRUN, 0) < 0) { 897553a609807074e95eed5a0bffba334b7fb3d3751Roland McGrath#endif /* FREEBSD */ 89876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman perror("PIOCRUN"); 89976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 90076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 901bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman#ifdef FREEBSD 902bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman /* handle the case where we "opened" the child before 903bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman it did the kill -STOP */ 904bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman if (tcp->status.PR_WHY == PR_SIGNALLED && 905bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman tcp->status.PR_WHAT == SIGSTOP) 906bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman kill(tcp->pid, SIGCONT); 907553a609807074e95eed5a0bffba334b7fb3d3751Roland McGrath#endif 90876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 909bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman#ifndef FREEBSD 91076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 911bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman#else /* FREEBSD */ 912bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman } else { 913553a609807074e95eed5a0bffba334b7fb3d3751Roland McGrath if (attaching < 2) { 9142e4ffe59b588159eb80e236f068278ba47735932Wichert Akkerman /* We are attaching to an already running process. 9152e4ffe59b588159eb80e236f068278ba47735932Wichert Akkerman * Try to figure out the state of the process in syscalls, 9162e4ffe59b588159eb80e236f068278ba47735932Wichert Akkerman * to handle the first event well. 9172e4ffe59b588159eb80e236f068278ba47735932Wichert Akkerman * This is done by having a look at the "wchan" property of the 9182e4ffe59b588159eb80e236f068278ba47735932Wichert Akkerman * process, which tells where it is stopped (if it is). */ 9192e4ffe59b588159eb80e236f068278ba47735932Wichert Akkerman FILE * status; 9202e4ffe59b588159eb80e236f068278ba47735932Wichert Akkerman char wchan[20]; /* should be enough */ 921553a609807074e95eed5a0bffba334b7fb3d3751Roland McGrath 9222e4ffe59b588159eb80e236f068278ba47735932Wichert Akkerman sprintf(proc, "/proc/%d/status", tcp->pid); 9232e4ffe59b588159eb80e236f068278ba47735932Wichert Akkerman status = fopen(proc, "r"); 9242e4ffe59b588159eb80e236f068278ba47735932Wichert Akkerman if (status && 9252e4ffe59b588159eb80e236f068278ba47735932Wichert Akkerman (fscanf(status, "%*s %*d %*d %*d %*d %*d,%*d %*s %*d,%*d" 9262e4ffe59b588159eb80e236f068278ba47735932Wichert Akkerman "%*d,%*d %*d,%*d %19s", wchan) == 1) && 9272e4ffe59b588159eb80e236f068278ba47735932Wichert Akkerman strcmp(wchan, "nochan") && strcmp(wchan, "spread") && 9282e4ffe59b588159eb80e236f068278ba47735932Wichert Akkerman strcmp(wchan, "stopevent")) { 9292e4ffe59b588159eb80e236f068278ba47735932Wichert Akkerman /* The process is asleep in the middle of a syscall. 9302e4ffe59b588159eb80e236f068278ba47735932Wichert Akkerman Fake the syscall entry event */ 9312e4ffe59b588159eb80e236f068278ba47735932Wichert Akkerman tcp->flags &= ~(TCB_INSYSCALL|TCB_STARTUP); 9322e4ffe59b588159eb80e236f068278ba47735932Wichert Akkerman tcp->status.PR_WHY = PR_SYSENTRY; 9332e4ffe59b588159eb80e236f068278ba47735932Wichert Akkerman trace_syscall(tcp); 9342e4ffe59b588159eb80e236f068278ba47735932Wichert Akkerman } 9352e4ffe59b588159eb80e236f068278ba47735932Wichert Akkerman if (status) 9362e4ffe59b588159eb80e236f068278ba47735932Wichert Akkerman fclose(status); 9372e4ffe59b588159eb80e236f068278ba47735932Wichert Akkerman } /* otherwise it's a fork being followed */ 938bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman } 939bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman#endif /* FREEBSD */ 94076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#ifndef HAVE_POLLABLE_PROCFS 94176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (proc_poll_pipe[0] != -1) 94276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman proc_poller(tcp->pfd); 94376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman else if (nprocs > 1) { 94476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman proc_poll_open(); 94576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman proc_poller(last_pfd); 94676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman proc_poller(tcp->pfd); 94776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 94876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman last_pfd = tcp->pfd; 94976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif /* !HAVE_POLLABLE_PROCFS */ 95076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return 0; 95176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman} 95276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 953bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman#endif /* USE_PROCFS */ 95476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 955e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrathstruct tcb * 95676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanpid2tcb(pid) 95776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanint pid; 95876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{ 95976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman int i; 96076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman struct tcb *tcp; 96176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 962ee9d435275fd7abf736992f84b5053ee16ec4fc7Roland McGrath for (i = 0; i < tcbtabsize; i++) { 963ee9d435275fd7abf736992f84b5053ee16ec4fc7Roland McGrath tcp = tcbtab[i]; 96476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (pid && tcp->pid != pid) 96576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman continue; 96676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (tcp->flags & TCB_INUSE) 96776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return tcp; 96876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 96976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return NULL; 97076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman} 97176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 972bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman#ifdef USE_PROCFS 97376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 97476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanstatic struct tcb * 97576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanpfd2tcb(pfd) 97676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanint pfd; 97776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{ 97876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman int i; 97976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 980ca16be8be9521b61bd2c5d945aa115519ebcb4daRoland McGrath for (i = 0; i < tcbtabsize; i++) { 981ca16be8be9521b61bd2c5d945aa115519ebcb4daRoland McGrath struct tcb *tcp = tcbtab[i]; 98276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (tcp->pfd != pfd) 98376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman continue; 98476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (tcp->flags & TCB_INUSE) 98576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return tcp; 98676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 98776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return NULL; 98876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman} 98976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 990bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman#endif /* USE_PROCFS */ 99176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 99276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanvoid 99376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermandroptcb(tcp) 99476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanstruct tcb *tcp; 99576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{ 99676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (tcp->pid == 0) 99776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return; 998e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath#ifdef TCB_CLONE_THREAD 999e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath if (tcp->nclone_threads > 0) { 1000e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath /* There are other threads left in this process, but this 1001e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath is the one whose PID represents the whole process. 1002e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath We need to keep this record around as a zombie until 1003e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath all the threads die. */ 1004e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath tcp->flags |= TCB_EXITING; 1005e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath return; 1006e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath } 1007e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath#endif 100876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman nprocs--; 100976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tcp->pid = 0; 1010eb8ebdad122a20ecae0ce8e3e60cb71d8e4a7152Wichert Akkerman 1011e29341c02f4fb658a34bca1f36c5d587257970d6Roland McGrath if (tcp->parent != NULL) { 1012e29341c02f4fb658a34bca1f36c5d587257970d6Roland McGrath tcp->parent->nchildren--; 1013e29341c02f4fb658a34bca1f36c5d587257970d6Roland McGrath#ifdef TCB_CLONE_THREAD 1014e29341c02f4fb658a34bca1f36c5d587257970d6Roland McGrath if (tcp->flags & TCB_CLONE_DETACHED) 1015e29341c02f4fb658a34bca1f36c5d587257970d6Roland McGrath tcp->parent->nclone_detached--; 1016e29341c02f4fb658a34bca1f36c5d587257970d6Roland McGrath if (tcp->flags & TCB_CLONE_THREAD) 1017e29341c02f4fb658a34bca1f36c5d587257970d6Roland McGrath tcp->parent->nclone_threads--; 1018e29341c02f4fb658a34bca1f36c5d587257970d6Roland McGrath#endif 10190962345a5775e0eea75c3ec408fb4807e851e7f0Roland McGrath#ifdef TCB_CLONE_DETACHED 10200962345a5775e0eea75c3ec408fb4807e851e7f0Roland McGrath if (!(tcp->flags & TCB_CLONE_DETACHED)) 10210962345a5775e0eea75c3ec408fb4807e851e7f0Roland McGrath#endif 10220962345a5775e0eea75c3ec408fb4807e851e7f0Roland McGrath tcp->parent->nzombies++; 1023e29341c02f4fb658a34bca1f36c5d587257970d6Roland McGrath tcp->parent = NULL; 1024e29341c02f4fb658a34bca1f36c5d587257970d6Roland McGrath } 1025e29341c02f4fb658a34bca1f36c5d587257970d6Roland McGrath 1026e29341c02f4fb658a34bca1f36c5d587257970d6Roland McGrath tcp->flags = 0; 102776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (tcp->pfd != -1) { 102876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman close(tcp->pfd); 102976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tcp->pfd = -1; 1030bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman#ifdef FREEBSD 1031bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman if (tcp->pfd_reg != -1) { 1032bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman close(tcp->pfd_reg); 1033bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman tcp->pfd_reg = -1; 1034bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman } 1035bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman if (tcp->pfd_status != -1) { 1036bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman close(tcp->pfd_status); 1037bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman tcp->pfd_status = -1; 1038bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman } 1039553a609807074e95eed5a0bffba334b7fb3d3751Roland McGrath#endif /* !FREEBSD */ 1040bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman#ifdef USE_PROCFS 1041e29341c02f4fb658a34bca1f36c5d587257970d6Roland McGrath rebuild_pollv(); /* Note, flags needs to be cleared by now. */ 104276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif 104376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 1044eb8ebdad122a20ecae0ce8e3e60cb71d8e4a7152Wichert Akkerman 1045822f0c9a84a4c992cc126766c83726e7275a5572Wichert Akkerman if (outfname && followfork > 1 && tcp->outf) 104676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman fclose(tcp->outf); 1047eb8ebdad122a20ecae0ce8e3e60cb71d8e4a7152Wichert Akkerman 104876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tcp->outf = 0; 104976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman} 105076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 1051bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman#ifndef USE_PROCFS 105276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 105376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanstatic int 105476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanresume(tcp) 105576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanstruct tcb *tcp; 105676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{ 105776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (tcp == NULL) 105876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 105976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 106076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (!(tcp->flags & TCB_SUSPENDED)) { 106176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman fprintf(stderr, "PANIC: pid %u not suspended\n", tcp->pid); 106276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 106376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 106476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tcp->flags &= ~TCB_SUSPENDED; 1065e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath#ifdef TCB_CLONE_THREAD 1066e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath if (tcp->flags & TCB_CLONE_THREAD) 1067e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath tcp->parent->nclone_waiting--; 1068e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath#endif 106976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 107076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (ptrace(PTRACE_SYSCALL, tcp->pid, (char *) 1, 0) < 0) { 107176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman perror("resume: ptrace(PTRACE_SYSCALL, ...)"); 107276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 107376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 107476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 107576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (!qflag) 107676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman fprintf(stderr, "Process %u resumed\n", tcp->pid); 107776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return 0; 107876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman} 107976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 1080bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman#endif /* !USE_PROCFS */ 108176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 108276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman/* detach traced process; continue with sig */ 108376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 108476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanstatic int 108576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermandetach(tcp, sig) 108676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanstruct tcb *tcp; 108776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanint sig; 108876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{ 108976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman int error = 0; 1090ca16be8be9521b61bd2c5d945aa115519ebcb4daRoland McGrath#ifdef LINUX 1091e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath int status, resumed; 1092ca16be8be9521b61bd2c5d945aa115519ebcb4daRoland McGrath#endif 109376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 109476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (tcp->flags & TCB_BPTSET) 109576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman sig = SIGKILL; 109676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 109776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#ifdef LINUX 109876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman /* 109976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * Linux wrongly insists the child be stopped 11007bf10474b981aa27f6b8c5b5e3f563d21f2eafcaRoland McGrath * before detaching. Arghh. We go through hoops 11017bf10474b981aa27f6b8c5b5e3f563d21f2eafcaRoland McGrath * to make a clean break of things. 110276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman */ 11037bf10474b981aa27f6b8c5b5e3f563d21f2eafcaRoland McGrath#if defined(SPARC) 11047bf10474b981aa27f6b8c5b5e3f563d21f2eafcaRoland McGrath#undef PTRACE_DETACH 11057bf10474b981aa27f6b8c5b5e3f563d21f2eafcaRoland McGrath#define PTRACE_DETACH PTRACE_SUNDETACH 11067bf10474b981aa27f6b8c5b5e3f563d21f2eafcaRoland McGrath#endif 110776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if ((error = ptrace(PTRACE_DETACH, tcp->pid, (char *) 1, sig)) == 0) { 110876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman /* On a clear day, you can see forever. */ 11097bf10474b981aa27f6b8c5b5e3f563d21f2eafcaRoland McGrath } 11107bf10474b981aa27f6b8c5b5e3f563d21f2eafcaRoland McGrath else if (errno != ESRCH) { 11117bf10474b981aa27f6b8c5b5e3f563d21f2eafcaRoland McGrath /* Shouldn't happen. */ 11127bf10474b981aa27f6b8c5b5e3f563d21f2eafcaRoland McGrath perror("detach: ptrace(PTRACE_DETACH, ...)"); 11137bf10474b981aa27f6b8c5b5e3f563d21f2eafcaRoland McGrath } 11147bf10474b981aa27f6b8c5b5e3f563d21f2eafcaRoland McGrath else if (kill(tcp->pid, 0) < 0) { 11157bf10474b981aa27f6b8c5b5e3f563d21f2eafcaRoland McGrath if (errno != ESRCH) 11167bf10474b981aa27f6b8c5b5e3f563d21f2eafcaRoland McGrath perror("detach: checking sanity"); 11177bf10474b981aa27f6b8c5b5e3f563d21f2eafcaRoland McGrath } 11187bf10474b981aa27f6b8c5b5e3f563d21f2eafcaRoland McGrath else if (kill(tcp->pid, SIGSTOP) < 0) { 11197bf10474b981aa27f6b8c5b5e3f563d21f2eafcaRoland McGrath if (errno != ESRCH) 11207bf10474b981aa27f6b8c5b5e3f563d21f2eafcaRoland McGrath perror("detach: stopping child"); 11217bf10474b981aa27f6b8c5b5e3f563d21f2eafcaRoland McGrath } 11227bf10474b981aa27f6b8c5b5e3f563d21f2eafcaRoland McGrath else { 112376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman for (;;) { 11247508cb4678141d146d819120f6b5b428c103882eRoland McGrath#ifdef __WALL 11257508cb4678141d146d819120f6b5b428c103882eRoland McGrath if (wait4(tcp->pid, &status, __WALL, NULL) < 0) { 11267508cb4678141d146d819120f6b5b428c103882eRoland McGrath if (errno == ECHILD) /* Already gone. */ 11277508cb4678141d146d819120f6b5b428c103882eRoland McGrath break; 11287508cb4678141d146d819120f6b5b428c103882eRoland McGrath if (errno != EINVAL) { 112976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman perror("detach: waiting"); 11307508cb4678141d146d819120f6b5b428c103882eRoland McGrath break; 11317508cb4678141d146d819120f6b5b428c103882eRoland McGrath } 11327508cb4678141d146d819120f6b5b428c103882eRoland McGrath#endif /* __WALL */ 11337508cb4678141d146d819120f6b5b428c103882eRoland McGrath /* No __WALL here. */ 11347508cb4678141d146d819120f6b5b428c103882eRoland McGrath if (waitpid(tcp->pid, &status, 0) < 0) { 11357508cb4678141d146d819120f6b5b428c103882eRoland McGrath if (errno != ECHILD) { 11367508cb4678141d146d819120f6b5b428c103882eRoland McGrath perror("detach: waiting"); 11377508cb4678141d146d819120f6b5b428c103882eRoland McGrath break; 11387508cb4678141d146d819120f6b5b428c103882eRoland McGrath } 11397508cb4678141d146d819120f6b5b428c103882eRoland McGrath#ifdef __WCLONE 11407508cb4678141d146d819120f6b5b428c103882eRoland McGrath /* If no processes, try clones. */ 11417508cb4678141d146d819120f6b5b428c103882eRoland McGrath if (wait4(tcp->pid, &status, __WCLONE, 11427508cb4678141d146d819120f6b5b428c103882eRoland McGrath NULL) < 0) { 11437508cb4678141d146d819120f6b5b428c103882eRoland McGrath if (errno != ECHILD) 11447508cb4678141d146d819120f6b5b428c103882eRoland McGrath perror("detach: waiting"); 11457508cb4678141d146d819120f6b5b428c103882eRoland McGrath break; 11467508cb4678141d146d819120f6b5b428c103882eRoland McGrath } 11477508cb4678141d146d819120f6b5b428c103882eRoland McGrath#endif /* __WCLONE */ 11487508cb4678141d146d819120f6b5b428c103882eRoland McGrath } 11497508cb4678141d146d819120f6b5b428c103882eRoland McGrath#ifdef __WALL 115076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 11517508cb4678141d146d819120f6b5b428c103882eRoland McGrath#endif 115276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (!WIFSTOPPED(status)) { 115376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman /* Au revoir, mon ami. */ 115476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman break; 115576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 115676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (WSTOPSIG(status) == SIGSTOP) { 115776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if ((error = ptrace(PTRACE_DETACH, 11587bf10474b981aa27f6b8c5b5e3f563d21f2eafcaRoland McGrath tcp->pid, (char *) 1, sig)) < 0) { 115976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (errno != ESRCH) 116076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman perror("detach: ptrace(PTRACE_DETACH, ...)"); 116176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman /* I died trying. */ 116276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 116376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman break; 116476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 116576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if ((error = ptrace(PTRACE_CONT, tcp->pid, (char *) 1, 11667bf10474b981aa27f6b8c5b5e3f563d21f2eafcaRoland McGrath WSTOPSIG(status) == SIGTRAP ? 11677bf10474b981aa27f6b8c5b5e3f563d21f2eafcaRoland McGrath 0 : WSTOPSIG(status))) < 0) { 116876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (errno != ESRCH) 116976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman perror("detach: ptrace(PTRACE_CONT, ...)"); 117076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman break; 117176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 117276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 117376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 11747bf10474b981aa27f6b8c5b5e3f563d21f2eafcaRoland McGrath#endif /* LINUX */ 117576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 117676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#if defined(SUNOS4) 117776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman /* PTRACE_DETACH won't respect `sig' argument, so we post it here. */ 117876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (sig && kill(tcp->pid, sig) < 0) 117976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman perror("detach: kill"); 118076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman sig = 0; 118176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if ((error = ptrace(PTRACE_DETACH, tcp->pid, (char *) 1, sig)) < 0) 118276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman perror("detach: ptrace(PTRACE_DETACH, ...)"); 118376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif /* SUNOS4 */ 118476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 1185bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman#ifndef USE_PROCFS 1186e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath resumed = 0; 1187e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath 1188e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath /* XXX This won't always be quite right (but it never was). 1189e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath A waiter with argument 0 or < -1 is waiting for any pid in 1190e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath a particular pgrp, which this child might or might not be 1191e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath in. The waiter will only wake up if it's argument is -1 1192e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath or if it's waiting for tcp->pid's pgrp. It makes a 1193e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath difference to wake up a waiter when there might be more 1194e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath traced children, because it could get a false ECHILD 1195e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath error. OTOH, if this was the last child in the pgrp, then 1196e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath it ought to wake up and get ECHILD. We would have to 1197e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath search the system for all pid's in the pgrp to be sure. 1198e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath 1199e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath && (t->waitpid == -1 || 1200e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath (t->waitpid == 0 && getpgid (tcp->pid) == getpgid (t->pid)) 1201e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath || (t->waitpid < 0 && t->waitpid == -getpid (t->pid))) 1202e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath */ 1203e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath 1204e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath if (tcp->parent && 1205e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath (tcp->parent->flags & TCB_SUSPENDED) && 1206e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath (tcp->parent->waitpid <= 0 || tcp->parent->waitpid == tcp->pid)) { 1207e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath error = resume(tcp->parent); 1208e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath ++resumed; 1209e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath } 1210e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath#ifdef TCB_CLONE_THREAD 1211e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath if (tcp->parent && tcp->parent->nclone_waiting > 0) { 1212e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath /* Some other threads of our parent are waiting too. */ 1213e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath unsigned int i; 1214e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath 1215e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath /* Resume all the threads that were waiting for this PID. */ 1216e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath for (i = 0; i < tcbtabsize; i++) { 1217e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath struct tcb *t = tcbtab[i]; 1218e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath if (t->parent == tcp->parent && t != tcp 1219e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath && ((t->flags & (TCB_CLONE_THREAD|TCB_SUSPENDED)) 1220e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath == (TCB_CLONE_THREAD|TCB_SUSPENDED)) 1221e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath && t->waitpid == tcp->pid) { 1222e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath error |= resume (t); 1223e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath ++resumed; 1224e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath } 1225e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath } 1226e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath if (resumed == 0) 1227e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath /* Noone was waiting for this PID in particular, 1228e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath so now we might need to resume some wildcarders. */ 1229e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath for (i = 0; i < tcbtabsize; i++) { 1230e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath struct tcb *t = tcbtab[i]; 1231e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath if (t->parent == tcp->parent && t != tcp 1232e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath && ((t->flags 1233e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath & (TCB_CLONE_THREAD|TCB_SUSPENDED)) 1234e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath == (TCB_CLONE_THREAD|TCB_SUSPENDED)) 1235e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath && t->waitpid <= 0 1236e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath ) { 1237e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath error |= resume (t); 1238e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath break; 1239e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath } 1240e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath } 1241e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath } 1242e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath#endif 1243e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath 1244bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman#endif /* !USE_PROCFS */ 124576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 124676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (!qflag) 124776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman fprintf(stderr, "Process %u detached\n", tcp->pid); 124876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 124976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman droptcb(tcp); 125076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return error; 125176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman} 125276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 1253bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman#ifdef USE_PROCFS 125476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 125576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanstatic void 125676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanreaper(sig) 125776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanint sig; 125876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{ 125976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman int pid; 126076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman int status; 126176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 126276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman while ((pid = waitpid(-1, &status, WNOHANG)) > 0) { 126376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#if 0 126476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman struct tcb *tcp; 126576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 126676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tcp = pid2tcb(pid); 126776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (tcp) 126876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman droptcb(tcp); 126976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif 127076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 127176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman} 127276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 1273bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman#endif /* USE_PROCFS */ 127476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 127576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanstatic void 127676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermancleanup() 127776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{ 127876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman int i; 127976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman struct tcb *tcp; 128076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 1281ee9d435275fd7abf736992f84b5053ee16ec4fc7Roland McGrath for (i = 0; i < tcbtabsize; i++) { 1282ee9d435275fd7abf736992f84b5053ee16ec4fc7Roland McGrath tcp = tcbtab[i]; 128376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (!(tcp->flags & TCB_INUSE)) 128476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman continue; 128576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (debug) 128676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman fprintf(stderr, 128776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman "cleanup: looking at pid %u\n", tcp->pid); 128876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (tcp_last && 128976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman (!outfname || followfork < 2 || tcp_last == tcp)) { 129076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tprintf(" <unfinished ...>\n"); 129176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tcp_last = NULL; 129276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 129376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (tcp->flags & TCB_ATTACHED) 129476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman detach(tcp, 0); 129576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman else { 129676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman kill(tcp->pid, SIGCONT); 129776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman kill(tcp->pid, SIGTERM); 129876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 129976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 130076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (cflag) 130176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman call_summary(outf); 130276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman} 130376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 130476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanstatic void 130576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermaninterrupt(sig) 130676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanint sig; 130776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{ 130876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman interrupted = 1; 130976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman} 131076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 131176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#ifndef HAVE_STRERROR 131276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 13136d2b34971b33d379c89c36c5ad1b0c6d5d12c453Roland McGrath#if !HAVE_DECL_SYS_ERRLIST 131476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanextern int sys_nerr; 131576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanextern char *sys_errlist[]; 13166d2b34971b33d379c89c36c5ad1b0c6d5d12c453Roland McGrath#endif /* HAVE_DECL_SYS_ERRLIST */ 131776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 131876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanconst char * 131976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanstrerror(errno) 132076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanint errno; 132176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{ 132276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman static char buf[64]; 132376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 132476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (errno < 1 || errno >= sys_nerr) { 132576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman sprintf(buf, "Unknown error %d", errno); 132676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return buf; 132776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 132876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return sys_errlist[errno]; 132976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman} 133076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 133176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif /* HAVE_STERRROR */ 133276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 133376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#ifndef HAVE_STRSIGNAL 133476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 13358f474e087ebb77b57eb87f4fdc557d53c64ca933Roland McGrath#if defined HAVE_SYS_SIGLIST && !defined HAVE_DECL_SYS_SIGLIST 13366d2b34971b33d379c89c36c5ad1b0c6d5d12c453Roland McGrathextern char *sys_siglist[]; 133776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif 13388f474e087ebb77b57eb87f4fdc557d53c64ca933Roland McGrath#if defined HAVE_SYS__SIGLIST && !defined HAVE_DECL__SYS_SIGLIST 13398f474e087ebb77b57eb87f4fdc557d53c64ca933Roland McGrathextern char *_sys_siglist[]; 13408f474e087ebb77b57eb87f4fdc557d53c64ca933Roland McGrath#endif 134176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 134276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanconst char * 134376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanstrsignal(sig) 134476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanint sig; 134576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{ 134676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman static char buf[64]; 134776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 134876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (sig < 1 || sig >= NSIG) { 134976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman sprintf(buf, "Unknown signal %d", sig); 135076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return buf; 135176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 135276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#ifdef HAVE__SYS_SIGLIST 135376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return _sys_siglist[sig]; 135476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#else 135576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return sys_siglist[sig]; 135676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif 135776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman} 135876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 135976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif /* HAVE_STRSIGNAL */ 136076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 1361bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman#ifdef USE_PROCFS 136276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 136376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanstatic void 136476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanrebuild_pollv() 136576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{ 136676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman int i, j; 136776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 1368ee9d435275fd7abf736992f84b5053ee16ec4fc7Roland McGrath if (pollv != NULL) 1369ee9d435275fd7abf736992f84b5053ee16ec4fc7Roland McGrath free (pollv); 1370c012d223a6b915f06ef32b8aaa52b984015d192eRoland McGrath pollv = (struct pollfd *) malloc(nprocs * sizeof pollv[0]); 1371ee9d435275fd7abf736992f84b5053ee16ec4fc7Roland McGrath if (pollv == NULL) { 1372ee9d435275fd7abf736992f84b5053ee16ec4fc7Roland McGrath fprintf(stderr, "strace: out of memory for poll vector\n"); 1373ee9d435275fd7abf736992f84b5053ee16ec4fc7Roland McGrath exit(1); 1374ee9d435275fd7abf736992f84b5053ee16ec4fc7Roland McGrath } 1375ee9d435275fd7abf736992f84b5053ee16ec4fc7Roland McGrath 1376ca16be8be9521b61bd2c5d945aa115519ebcb4daRoland McGrath for (i = j = 0; i < tcbtabsize; i++) { 1377ca16be8be9521b61bd2c5d945aa115519ebcb4daRoland McGrath struct tcb *tcp = tcbtab[i]; 137876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (!(tcp->flags & TCB_INUSE)) 137976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman continue; 138076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman pollv[j].fd = tcp->pfd; 13819ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman pollv[j].events = POLLWANT; 138276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman j++; 138376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 138476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (j != nprocs) { 138576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman fprintf(stderr, "strace: proc miscount\n"); 138676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman exit(1); 138776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 138876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman} 138976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 139076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#ifndef HAVE_POLLABLE_PROCFS 139176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 139276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanstatic void 139376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanproc_poll_open() 139476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{ 139576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman int arg; 139676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman int i; 139776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 139876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (pipe(proc_poll_pipe) < 0) { 139976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman perror("pipe"); 140076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman exit(1); 140176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 140276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman for (i = 0; i < 2; i++) { 140376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if ((arg = fcntl(proc_poll_pipe[i], F_GETFD)) < 0) { 140476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman perror("F_GETFD"); 140576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman exit(1); 140676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 140776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (fcntl(proc_poll_pipe[i], F_SETFD, arg|FD_CLOEXEC) < 0) { 140876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman perror("F_SETFD"); 140976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman exit(1); 141076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 141176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 141276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman} 141376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 141476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanstatic int 141576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanproc_poll(pollv, nfds, timeout) 141676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanstruct pollfd *pollv; 141776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanint nfds; 141876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanint timeout; 141976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{ 142076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman int i; 142176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman int n; 142276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman struct proc_pollfd pollinfo; 142376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 142476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if ((n = read(proc_poll_pipe[0], &pollinfo, sizeof(pollinfo))) < 0) 142576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return n; 142676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (n != sizeof(struct proc_pollfd)) { 142776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman fprintf(stderr, "panic: short read: %d\n", n); 142876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman exit(1); 142976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 143076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman for (i = 0; i < nprocs; i++) { 143176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (pollv[i].fd == pollinfo.fd) 143276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman pollv[i].revents = pollinfo.revents; 143376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman else 143476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman pollv[i].revents = 0; 143576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 143676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman poller_pid = pollinfo.pid; 143776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return 1; 143876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman} 143976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 144076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanstatic void 144176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanwakeup_handler(sig) 144276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanint sig; 144376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{ 144476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman} 144576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 144676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanstatic void 144776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanproc_poller(pfd) 144876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanint pfd; 144976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{ 145076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman struct proc_pollfd pollinfo; 145176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman struct sigaction sa; 145276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman sigset_t blocked_set, empty_set; 145376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman int i; 145476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman int n; 145576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman struct rlimit rl; 1456bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman#ifdef FREEBSD 1457bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman struct procfs_status pfs; 1458bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman#endif /* FREEBSD */ 145976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 146076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman switch (fork()) { 146176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman case -1: 146276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman perror("fork"); 146376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman _exit(0); 146476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman case 0: 146576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman break; 146676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman default: 146776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return; 146876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 146976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 147076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman sa.sa_handler = interactive ? SIG_DFL : SIG_IGN; 147176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman sa.sa_flags = 0; 147276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman sigemptyset(&sa.sa_mask); 147376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman sigaction(SIGHUP, &sa, NULL); 147476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman sigaction(SIGINT, &sa, NULL); 147576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman sigaction(SIGQUIT, &sa, NULL); 147676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman sigaction(SIGPIPE, &sa, NULL); 147776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman sigaction(SIGTERM, &sa, NULL); 147876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman sa.sa_handler = wakeup_handler; 147976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman sigaction(SIGUSR1, &sa, NULL); 148076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman sigemptyset(&blocked_set); 148176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman sigaddset(&blocked_set, SIGUSR1); 148276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman sigprocmask(SIG_BLOCK, &blocked_set, NULL); 148376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman sigemptyset(&empty_set); 148476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 148576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (getrlimit(RLIMIT_NOFILE, &rl) < 0) { 148676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman perror("getrlimit(RLIMIT_NOFILE, ...)"); 148776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman _exit(0); 148876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 148976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman n = rl.rlim_cur; 149076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman for (i = 0; i < n; i++) { 149176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (i != pfd && i != proc_poll_pipe[1]) 149276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman close(i); 149376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 149476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 149576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman pollinfo.fd = pfd; 149676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman pollinfo.pid = getpid(); 149776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman for (;;) { 1498bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman#ifndef FREEBSD 1499bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman if (ioctl(pfd, PIOCWSTOP, NULL) < 0) 1500bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman#else /* FREEBSD */ 1501bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman if (ioctl(pfd, PIOCWSTOP, &pfs) < 0) 1502bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman#endif /* FREEBSD */ 15039ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman { 150476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman switch (errno) { 150576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman case EINTR: 150676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman continue; 150776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman case EBADF: 150876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman pollinfo.revents = POLLERR; 150976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman break; 151076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman case ENOENT: 151176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman pollinfo.revents = POLLHUP; 151276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman break; 151376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman default: 151476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman perror("proc_poller: PIOCWSTOP"); 151576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 151676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman write(proc_poll_pipe[1], &pollinfo, sizeof(pollinfo)); 151776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman _exit(0); 151876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 15199ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman pollinfo.revents = POLLWANT; 152076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman write(proc_poll_pipe[1], &pollinfo, sizeof(pollinfo)); 152176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman sigsuspend(&empty_set); 152276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 152376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman} 152476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 152576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif /* !HAVE_POLLABLE_PROCFS */ 152676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 152776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanstatic int 152876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanchoose_pfd() 152976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{ 153076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman int i, j; 153176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman struct tcb *tcp; 153276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 153376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman static int last; 153476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 153576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (followfork < 2 && 15369ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman last < nprocs && (pollv[last].revents & POLLWANT)) { 153776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman /* 153876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * The previous process is ready to run again. We'll 153976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * let it do so if it is currently in a syscall. This 154076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * heuristic improves the readability of the trace. 154176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman */ 154276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tcp = pfd2tcb(pollv[last].fd); 154376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (tcp && (tcp->flags & TCB_INSYSCALL)) 154476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return pollv[last].fd; 154576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 154676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 154776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman for (i = 0; i < nprocs; i++) { 154876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman /* Let competing children run round robin. */ 154976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman j = (i + last + 1) % nprocs; 155076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (pollv[j].revents & (POLLHUP | POLLERR)) { 155176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tcp = pfd2tcb(pollv[j].fd); 155276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (!tcp) { 155376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman fprintf(stderr, "strace: lost proc\n"); 155476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman exit(1); 155576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 155676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman droptcb(tcp); 155776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 155876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 15599ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman if (pollv[j].revents & POLLWANT) { 156076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman last = j; 156176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return pollv[j].fd; 156276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 156376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 156476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman fprintf(stderr, "strace: nothing ready\n"); 156576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman exit(1); 156676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman} 156776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 156876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanstatic int 156976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermantrace() 157076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{ 15719dbf15466e9c178ac4090eba2c1232e2fe0706f9Wichert Akkerman#ifdef POLL_HACK 1572d870b3c31a0139b335a66a829169bacc74624c44John Hughes struct tcb *in_syscall = NULL; 15739dbf15466e9c178ac4090eba2c1232e2fe0706f9Wichert Akkerman#endif 157476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman struct tcb *tcp; 157576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman int pfd; 157676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman int what; 157776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman int ioctl_result = 0, ioctl_errno = 0; 15789ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman long arg; 157976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 158076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman for (;;) { 158176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (interactive) 158276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman sigprocmask(SIG_SETMASK, &empty_set, NULL); 158376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 158476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (nprocs == 0) 158576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman break; 158676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 158776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman switch (nprocs) { 158876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman case 1: 158976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#ifndef HAVE_POLLABLE_PROCFS 159076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (proc_poll_pipe[0] == -1) { 159176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif 159276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tcp = pid2tcb(0); 159376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (!tcp) 159476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman continue; 159576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman pfd = tcp->pfd; 159676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (pfd == -1) 159776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman continue; 159876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman break; 159976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#ifndef HAVE_POLLABLE_PROCFS 160076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 160176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman /* fall through ... */ 160276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif /* !HAVE_POLLABLE_PROCFS */ 160376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman default: 160476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#ifdef HAVE_POLLABLE_PROCFS 16059dbf15466e9c178ac4090eba2c1232e2fe0706f9Wichert Akkerman#ifdef POLL_HACK 16069dbf15466e9c178ac4090eba2c1232e2fe0706f9Wichert Akkerman /* On some systems (e.g. UnixWare) we get too much ugly 16079dbf15466e9c178ac4090eba2c1232e2fe0706f9Wichert Akkerman "unfinished..." stuff when multiple proceses are in 16089dbf15466e9c178ac4090eba2c1232e2fe0706f9Wichert Akkerman syscalls. Here's a nasty hack */ 1609553a609807074e95eed5a0bffba334b7fb3d3751Roland McGrath 16109dbf15466e9c178ac4090eba2c1232e2fe0706f9Wichert Akkerman if (in_syscall) { 16119dbf15466e9c178ac4090eba2c1232e2fe0706f9Wichert Akkerman struct pollfd pv; 16129dbf15466e9c178ac4090eba2c1232e2fe0706f9Wichert Akkerman tcp = in_syscall; 16139dbf15466e9c178ac4090eba2c1232e2fe0706f9Wichert Akkerman in_syscall = NULL; 16149dbf15466e9c178ac4090eba2c1232e2fe0706f9Wichert Akkerman pv.fd = tcp->pfd; 16159dbf15466e9c178ac4090eba2c1232e2fe0706f9Wichert Akkerman pv.events = POLLWANT; 16169dbf15466e9c178ac4090eba2c1232e2fe0706f9Wichert Akkerman if ((what = poll (&pv, 1, 1)) < 0) { 16179dbf15466e9c178ac4090eba2c1232e2fe0706f9Wichert Akkerman if (interrupted) 16189dbf15466e9c178ac4090eba2c1232e2fe0706f9Wichert Akkerman return 0; 16199dbf15466e9c178ac4090eba2c1232e2fe0706f9Wichert Akkerman continue; 16209dbf15466e9c178ac4090eba2c1232e2fe0706f9Wichert Akkerman } 16219dbf15466e9c178ac4090eba2c1232e2fe0706f9Wichert Akkerman else if (what == 1 && pv.revents & POLLWANT) { 16229dbf15466e9c178ac4090eba2c1232e2fe0706f9Wichert Akkerman goto FOUND; 16239dbf15466e9c178ac4090eba2c1232e2fe0706f9Wichert Akkerman } 16249dbf15466e9c178ac4090eba2c1232e2fe0706f9Wichert Akkerman } 16259dbf15466e9c178ac4090eba2c1232e2fe0706f9Wichert Akkerman#endif 16269dbf15466e9c178ac4090eba2c1232e2fe0706f9Wichert Akkerman 162776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (poll(pollv, nprocs, INFTIM) < 0) { 162876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (interrupted) 162976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return 0; 163076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman continue; 163176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 163276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#else /* !HAVE_POLLABLE_PROCFS */ 163376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (proc_poll(pollv, nprocs, INFTIM) < 0) { 163476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (interrupted) 163576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return 0; 163676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman continue; 163776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 163876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif /* !HAVE_POLLABLE_PROCFS */ 163976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman pfd = choose_pfd(); 164076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (pfd == -1) 164176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman continue; 164276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman break; 164376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 164476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 164576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman /* Look up `pfd' in our table. */ 164676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if ((tcp = pfd2tcb(pfd)) == NULL) { 164776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman fprintf(stderr, "unknown pfd: %u\n", pfd); 164876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman exit(1); 164976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 1650b664308560d655bc1fb333663eb0d0fb3395409fJohn Hughes#ifdef POLL_HACK 16519dbf15466e9c178ac4090eba2c1232e2fe0706f9Wichert Akkerman FOUND: 1652b664308560d655bc1fb333663eb0d0fb3395409fJohn Hughes#endif 165376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman /* Get the status of the process. */ 165476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (!interrupted) { 1655bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman#ifndef FREEBSD 16569ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman ioctl_result = IOCTL_WSTOP (tcp); 1657bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman#else /* FREEBSD */ 1658bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman /* Thanks to some scheduling mystery, the first poller 1659bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman sometimes waits for the already processed end of fork 1660bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman event. Doing a non blocking poll here solves the problem. */ 1661bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman if (proc_poll_pipe[0] != -1) 1662bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman ioctl_result = IOCTL_STATUS (tcp); 1663bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman else 1664bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman ioctl_result = IOCTL_WSTOP (tcp); 1665553a609807074e95eed5a0bffba334b7fb3d3751Roland McGrath#endif /* FREEBSD */ 166676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman ioctl_errno = errno; 166776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#ifndef HAVE_POLLABLE_PROCFS 166876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (proc_poll_pipe[0] != -1) { 166976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (ioctl_result < 0) 167076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman kill(poller_pid, SIGKILL); 167176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman else 167276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman kill(poller_pid, SIGUSR1); 167376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 167476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif /* !HAVE_POLLABLE_PROCFS */ 167576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 167676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (interrupted) 167776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return 0; 167876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 167976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (interactive) 168076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman sigprocmask(SIG_BLOCK, &blocked_set, NULL); 168176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 168276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (ioctl_result < 0) { 168376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman /* Find out what happened if it failed. */ 168476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman switch (ioctl_errno) { 168576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman case EINTR: 168676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman case EBADF: 168776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman continue; 1688bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman#ifdef FREEBSD 1689bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman case ENOTTY: 1690553a609807074e95eed5a0bffba334b7fb3d3751Roland McGrath#endif 169176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman case ENOENT: 169276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman droptcb(tcp); 169376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman continue; 169476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman default: 169576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman perror("PIOCWSTOP"); 169676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman exit(1); 169776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 169876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 169976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 17002e4ffe59b588159eb80e236f068278ba47735932Wichert Akkerman#ifdef FREEBSD 17012e4ffe59b588159eb80e236f068278ba47735932Wichert Akkerman if ((tcp->flags & TCB_STARTUP) && (tcp->status.PR_WHY == PR_SYSEXIT)) { 17022e4ffe59b588159eb80e236f068278ba47735932Wichert Akkerman /* discard first event for a syscall we never entered */ 17032e4ffe59b588159eb80e236f068278ba47735932Wichert Akkerman IOCTL (tcp->pfd, PIOCRUN, 0); 17042e4ffe59b588159eb80e236f068278ba47735932Wichert Akkerman continue; 17052e4ffe59b588159eb80e236f068278ba47735932Wichert Akkerman } 1706553a609807074e95eed5a0bffba334b7fb3d3751Roland McGrath#endif 1707553a609807074e95eed5a0bffba334b7fb3d3751Roland McGrath 170876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman /* clear the just started flag */ 170976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tcp->flags &= ~TCB_STARTUP; 171076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 171176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman /* set current output file */ 171276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman outf = tcp->outf; 171376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 171476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (cflag) { 171576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman struct timeval stime; 1716bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman#ifdef FREEBSD 1717bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman char buf[1024]; 1718bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman int len; 1719bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman 1720bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman if ((len = pread(tcp->pfd_status, buf, sizeof(buf) - 1, 0)) > 0) { 1721bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman buf[len] = '\0'; 1722bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman sscanf(buf, 1723bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman "%*s %*d %*d %*d %*d %*d,%*d %*s %*d,%*d %*d,%*d %ld,%ld", 1724bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman &stime.tv_sec, &stime.tv_usec); 1725bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman } else 1726bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman stime.tv_sec = stime.tv_usec = 0; 1727553a609807074e95eed5a0bffba334b7fb3d3751Roland McGrath#else /* !FREEBSD */ 172876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman stime.tv_sec = tcp->status.pr_stime.tv_sec; 172976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman stime.tv_usec = tcp->status.pr_stime.tv_nsec/1000; 1730bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman#endif /* !FREEBSD */ 173176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tv_sub(&tcp->dtime, &stime, &tcp->stime); 173276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tcp->stime = stime; 173376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 17349ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman what = tcp->status.PR_WHAT; 17359ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman switch (tcp->status.PR_WHY) { 1736bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman#ifndef FREEBSD 173776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman case PR_REQUESTED: 17389ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman if (tcp->status.PR_FLAGS & PR_ASLEEP) { 17399ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman tcp->status.PR_WHY = PR_SYSENTRY; 174076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (trace_syscall(tcp) < 0) { 174176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman fprintf(stderr, "syscall trouble\n"); 174276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman exit(1); 174376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 174476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 174576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman break; 1746bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman#endif /* !FREEBSD */ 174776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman case PR_SYSENTRY: 17489dbf15466e9c178ac4090eba2c1232e2fe0706f9Wichert Akkerman#ifdef POLL_HACK 17499dbf15466e9c178ac4090eba2c1232e2fe0706f9Wichert Akkerman in_syscall = tcp; 17509dbf15466e9c178ac4090eba2c1232e2fe0706f9Wichert Akkerman#endif 175176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman case PR_SYSEXIT: 175276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (trace_syscall(tcp) < 0) { 175376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman fprintf(stderr, "syscall trouble\n"); 175476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman exit(1); 175576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 175676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman break; 175776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman case PR_SIGNALLED: 175876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (!cflag && (qual_flags[what] & QUAL_SIGNAL)) { 175976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman printleader(tcp); 176076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tprintf("--- %s (%s) ---", 1761ce780fc9e6067b15b65ca2904c698c77503bf635Nate Sammons signame(what), strsignal(what)); 176276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman printtrailer(tcp); 17635826589d8e210c2d34c8ce496d5b7a0f54188ef0John Hughes#ifdef PR_INFO 17645826589d8e210c2d34c8ce496d5b7a0f54188ef0John Hughes if (tcp->status.PR_INFO.si_signo == what) { 17655826589d8e210c2d34c8ce496d5b7a0f54188ef0John Hughes printleader(tcp); 17665826589d8e210c2d34c8ce496d5b7a0f54188ef0John Hughes tprintf(" siginfo="); 17675826589d8e210c2d34c8ce496d5b7a0f54188ef0John Hughes printsiginfo(&tcp->status.PR_INFO, 1); 17685826589d8e210c2d34c8ce496d5b7a0f54188ef0John Hughes printtrailer(tcp); 17695826589d8e210c2d34c8ce496d5b7a0f54188ef0John Hughes } 17705826589d8e210c2d34c8ce496d5b7a0f54188ef0John Hughes#endif 177176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 177276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman break; 177376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman case PR_FAULTED: 177476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (!cflag && (qual_flags[what] & QUAL_FAULT)) { 177576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman printleader(tcp); 177676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tprintf("=== FAULT %d ===", what); 177776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman printtrailer(tcp); 177876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 177976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman break; 1780bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman#ifdef FREEBSD 1781bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman case 0: /* handle case we polled for nothing */ 1782bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman continue; 1783553a609807074e95eed5a0bffba334b7fb3d3751Roland McGrath#endif 178476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman default: 17859ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman fprintf(stderr, "odd stop %d\n", tcp->status.PR_WHY); 178676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman exit(1); 178776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman break; 178876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 17899ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman arg = 0; 1790553a609807074e95eed5a0bffba334b7fb3d3751Roland McGrath#ifndef FREEBSD 17919ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman if (IOCTL (tcp->pfd, PIOCRUN, &arg) < 0) { 1792553a609807074e95eed5a0bffba334b7fb3d3751Roland McGrath#else 1793bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman if (IOCTL (tcp->pfd, PIOCRUN, 0) < 0) { 1794553a609807074e95eed5a0bffba334b7fb3d3751Roland McGrath#endif 179576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman perror("PIOCRUN"); 179676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman exit(1); 179776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 179876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 179976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return 0; 180076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman} 180176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 1802bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman#else /* !USE_PROCFS */ 180376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 1804e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath#ifdef TCB_GROUP_EXITING 1805e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath/* Handle an exit detach or death signal that is taking all the 1806e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath related clone threads with it. This is called in three circumstances: 1807e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath SIG == -1 TCP has already died (TCB_ATTACHED is clear, strace is parent). 1808e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath SIG == 0 Continuing TCP will perform an exit_group syscall. 1809e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath SIG == other Continuing TCP with SIG will kill the process. 1810e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath*/ 1811e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrathstatic int 1812e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrathhandle_group_exit(struct tcb *tcp, int sig) 1813e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath{ 1814e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath /* We need to locate our records of all the clone threads 1815e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath related to TCP, either its children or siblings. */ 1816e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath struct tcb *leader = ((tcp->flags & TCB_CLONE_THREAD) 1817e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath ? tcp->parent 1818e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath : tcp->nclone_detached > 0 1819e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath ? tcp : NULL); 1820e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath 1821e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath if (sig < 0) { 1822e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath if (leader != NULL && leader != tcp) 1823e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath fprintf(stderr, 1824e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath "PANIC: handle_group_exit: %d leader %d\n", 1825e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath tcp->pid, leader ? leader->pid : -1); 1826e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath droptcb(tcp); /* Already died. */ 1827e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath } 1828e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath else { 1829e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath if (tcp->flags & TCB_ATTACHED) { 1830e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath if (leader != NULL && leader != tcp) { 1831e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath /* We need to detach the leader so that the 1832e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath process death will be reported to its real 1833e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath parent. But we kill it first to prevent 1834e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath it doing anything before we kill the whole 1835e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath process in a moment. We can use 1836e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath PTRACE_KILL on a thread that's not already 1837e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath stopped. Then the value we pass in 1838e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath PTRACE_DETACH just sets the death 1839e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath signal reported to the real parent. */ 1840e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath ptrace(PTRACE_KILL, leader->pid, 0, 0); 1841e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath if (debug) 1842e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath fprintf(stderr, 1843e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath " [%d exit %d kills %d]\n", 1844e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath tcp->pid, sig, leader->pid); 1845e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath detach(leader, sig); 1846e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath } 1847e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath detach(tcp, sig); 1848e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath } 1849e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath else if (ptrace(PTRACE_CONT, tcp->pid, (char *) 1, sig) < 0) { 1850e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath perror("strace: ptrace(PTRACE_CONT, ...)"); 1851e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath cleanup(); 1852e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath return -1; 1853e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath } 1854e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath else { 1855e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath if (leader != NULL && leader != tcp) 1856e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath droptcb(tcp); 1857e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath /* The leader will report to us as parent now, 1858e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath and then we'll get to the SIG==-1 case. */ 1859e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath return 0; 1860e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath } 1861e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath } 1862e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath 1863e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath /* Note that TCP and LEADER are no longer valid, 1864e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath but we can still compare against them. */ 1865e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath if (leader != NULL) { 1866e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath unsigned int i; 1867e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath for (i = 0; i < tcbtabsize; i++) { 1868e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath struct tcb *t = tcbtab[i]; 1869e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath if (t != tcp && (t->flags & TCB_CLONE_DETACHED) 1870e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath && t->parent == leader) 1871e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath droptcb(t); 1872e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath } 1873e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath } 1874e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath 1875e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath return 0; 1876e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath} 1877e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath#endif 1878e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath 187976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanstatic int 188076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermantrace() 188176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{ 188276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman int pid; 188376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman int wait_errno; 188476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman int status; 188576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman struct tcb *tcp; 188676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#ifdef LINUX 188776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman struct rusage ru; 18882f1d87e74ff68004b99901f964a1cbab89da09dbWichert Akkerman#ifdef __WALL 18892f1d87e74ff68004b99901f964a1cbab89da09dbWichert Akkerman static int wait4_options = __WALL; 18902f1d87e74ff68004b99901f964a1cbab89da09dbWichert Akkerman#endif 189176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif /* LINUX */ 189276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 189376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman while (nprocs != 0) { 189476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (interactive) 189576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman sigprocmask(SIG_SETMASK, &empty_set, NULL); 189676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#ifdef LINUX 18972f1d87e74ff68004b99901f964a1cbab89da09dbWichert Akkerman#ifdef __WALL 18982f1d87e74ff68004b99901f964a1cbab89da09dbWichert Akkerman pid = wait4(-1, &status, wait4_options, cflag ? &ru : NULL); 18995bc05558bb9f9acd1f895ea128f3326ef4b03338Roland McGrath if (pid < 0 && (wait4_options & __WALL) && errno == EINVAL) { 19002f1d87e74ff68004b99901f964a1cbab89da09dbWichert Akkerman /* this kernel does not support __WALL */ 19012f1d87e74ff68004b99901f964a1cbab89da09dbWichert Akkerman wait4_options &= ~__WALL; 19022f1d87e74ff68004b99901f964a1cbab89da09dbWichert Akkerman errno = 0; 19032f1d87e74ff68004b99901f964a1cbab89da09dbWichert Akkerman pid = wait4(-1, &status, wait4_options, 19042f1d87e74ff68004b99901f964a1cbab89da09dbWichert Akkerman cflag ? &ru : NULL); 19052f1d87e74ff68004b99901f964a1cbab89da09dbWichert Akkerman } 19065bc05558bb9f9acd1f895ea128f3326ef4b03338Roland McGrath if (pid < 0 && !(wait4_options & __WALL) && errno == ECHILD) { 19072f1d87e74ff68004b99901f964a1cbab89da09dbWichert Akkerman /* most likely a "cloned" process */ 19082f1d87e74ff68004b99901f964a1cbab89da09dbWichert Akkerman pid = wait4(-1, &status, __WCLONE, 19092f1d87e74ff68004b99901f964a1cbab89da09dbWichert Akkerman cflag ? &ru : NULL); 19102f1d87e74ff68004b99901f964a1cbab89da09dbWichert Akkerman if (pid == -1) { 19112f1d87e74ff68004b99901f964a1cbab89da09dbWichert Akkerman fprintf(stderr, "strace: clone wait4 " 19122f1d87e74ff68004b99901f964a1cbab89da09dbWichert Akkerman "failed: %s\n", strerror(errno)); 19132f1d87e74ff68004b99901f964a1cbab89da09dbWichert Akkerman } 19142f1d87e74ff68004b99901f964a1cbab89da09dbWichert Akkerman } 19152f1d87e74ff68004b99901f964a1cbab89da09dbWichert Akkerman#else 191676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman pid = wait4(-1, &status, 0, cflag ? &ru : NULL); 19172f1d87e74ff68004b99901f964a1cbab89da09dbWichert Akkerman#endif /* __WALL */ 191876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif /* LINUX */ 191976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#ifdef SUNOS4 192076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman pid = wait(&status); 192176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif /* SUNOS4 */ 192276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman wait_errno = errno; 192376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (interactive) 192476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman sigprocmask(SIG_BLOCK, &blocked_set, NULL); 192576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 192676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (interrupted) 192776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return 0; 192876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 192976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (pid == -1) { 193076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman switch (wait_errno) { 193176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman case EINTR: 193276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman continue; 193376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman case ECHILD: 193476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman /* 193576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * We would like to verify this case 193676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * but sometimes a race in Solbourne's 193776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * version of SunOS sometimes reports 193876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * ECHILD before sending us SIGCHILD. 193976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman */ 194076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#if 0 194176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (nprocs == 0) 194276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return 0; 194376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman fprintf(stderr, "strace: proc miscount\n"); 194476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman exit(1); 194576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif 194676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return 0; 194776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman default: 194876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman errno = wait_errno; 194976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman perror("strace: wait"); 195076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 195176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 195276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 195376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (debug) 195476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman fprintf(stderr, " [wait(%#x) = %u]\n", status, pid); 195576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 195676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman /* Look up `pid' in our table. */ 195776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if ((tcp = pid2tcb(pid)) == NULL) { 1958e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath#ifdef LINUX 1959e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath if (followfork || followvfork) { 1960e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath /* This is needed to go with the CLONE_PTRACE 1961e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath changes in process.c/util.c: we might see 1962e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath the child's initial trap before we see the 1963e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath parent return from the clone syscall. 1964e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath Leave the child suspended until the parent 1965e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath returns from its system call. Only then 1966e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath will we have the association of parent and 1967e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath child so that we know how to do clearbpt 1968e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath in the child. */ 1969e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath if ((tcp = alloctcb(pid)) == NULL) { 1970e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath fprintf(stderr, " [tcb table full]\n"); 1971e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath kill(pid, SIGKILL); /* XXX */ 1972e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath return 0; 1973e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath } 1974e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath tcp->flags |= TCB_ATTACHED | TCB_SUSPENDED; 1975e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath newoutf(tcp); 1976e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath if (!qflag) 1977e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath fprintf(stderr, "\ 1978e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrathProcess %d attached (waiting for parent)\n", 1979e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath pid); 19808b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman } 1981e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath else 1982e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath /* This can happen if a clone call used 1983e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath CLONE_PTRACE itself. */ 19848b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman#endif 1985e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath { 1986e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath fprintf(stderr, "unknown pid: %u\n", pid); 1987e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath if (WIFSTOPPED(status)) 1988e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath ptrace(PTRACE_CONT, pid, (char *) 1, 0); 1989e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath exit(1); 1990e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath } 199176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 199276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman /* set current output file */ 199376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman outf = tcp->outf; 199476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (cflag) { 199576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#ifdef LINUX 199676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tv_sub(&tcp->dtime, &ru.ru_stime, &tcp->stime); 199776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tcp->stime = ru.ru_stime; 199876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif /* !LINUX */ 199976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 200076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 200176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (tcp->flags & TCB_SUSPENDED) { 200276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman /* 200376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * Apparently, doing any ptrace() call on a stopped 200476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * process, provokes the kernel to report the process 200576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * status again on a subsequent wait(), even if the 200676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * process has not been actually restarted. 200776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * Since we have inspected the arguments of suspended 200876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * processes we end up here testing for this case. 200976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman */ 201076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman continue; 201176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 201276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (WIFSIGNALED(status)) { 201376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (!cflag 201476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman && (qual_flags[WTERMSIG(status)] & QUAL_SIGNAL)) { 201576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman printleader(tcp); 201676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tprintf("+++ killed by %s +++", 2017ce780fc9e6067b15b65ca2904c698c77503bf635Nate Sammons signame(WTERMSIG(status))); 201876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman printtrailer(tcp); 201976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 2020e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath#ifdef TCB_GROUP_EXITING 2021e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath handle_group_exit(tcp, -1); 2022e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath#else 202376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman droptcb(tcp); 2024e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath#endif 202576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman continue; 202676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 202776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (WIFEXITED(status)) { 202876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (debug) 202976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman fprintf(stderr, "pid %u exited\n", pid); 203076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (tcp->flags & TCB_ATTACHED) 203176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman fprintf(stderr, 203276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman "PANIC: attached pid %u exited\n", 203376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman pid); 20340a396906981a03f93c07cb912585d0679dd50899Roland McGrath if (tcp == tcp_last) { 20350a396906981a03f93c07cb912585d0679dd50899Roland McGrath if ((tcp->flags & (TCB_INSYSCALL|TCB_REPRINT)) 20360a396906981a03f93c07cb912585d0679dd50899Roland McGrath == TCB_INSYSCALL) 20370a396906981a03f93c07cb912585d0679dd50899Roland McGrath tprintf(" <unfinished ... exit status %d>\n", 20380a396906981a03f93c07cb912585d0679dd50899Roland McGrath WEXITSTATUS(status)); 20390a396906981a03f93c07cb912585d0679dd50899Roland McGrath tcp_last = NULL; 20400a396906981a03f93c07cb912585d0679dd50899Roland McGrath } 2041e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath#ifdef TCB_GROUP_EXITING 2042e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath handle_group_exit(tcp, -1); 2043e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath#else 204476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman droptcb(tcp); 2045e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath#endif 204676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman continue; 204776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 204876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (!WIFSTOPPED(status)) { 204976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman fprintf(stderr, "PANIC: pid %u not stopped\n", pid); 205076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman droptcb(tcp); 205176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman continue; 205276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 205376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (debug) 205476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman fprintf(stderr, "pid %u stopped, [%s]\n", 2055ce780fc9e6067b15b65ca2904c698c77503bf635Nate Sammons pid, signame(WSTOPSIG(status))); 205676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 205776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (tcp->flags & TCB_STARTUP) { 205876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman /* 205976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * This flag is there to keep us in sync. 206076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * Next time this process stops it should 206176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * really be entering a system call. 206276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman */ 206376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tcp->flags &= ~TCB_STARTUP; 206476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (tcp->flags & TCB_ATTACHED) { 206576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman /* 206676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * Interestingly, the process may stop 206776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * with STOPSIG equal to some other signal 206876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * than SIGSTOP if we happend to attach 206976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * just before the process takes a signal. 207076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman */ 207176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (!WIFSTOPPED(status)) { 207276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman fprintf(stderr, 207376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman "pid %u not stopped\n", pid); 207476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman detach(tcp, WSTOPSIG(status)); 207576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman continue; 207676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 207776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 207876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman else { 207976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#ifdef SUNOS4 208076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman /* A child of us stopped at exec */ 208176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (WSTOPSIG(status) == SIGTRAP && followvfork) 208276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman fixvfork(tcp); 208376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif /* SUNOS4 */ 208476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 208576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (tcp->flags & TCB_BPTSET) { 208676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (clearbpt(tcp) < 0) /* Pretty fatal */ { 208776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman droptcb(tcp); 208876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman cleanup(); 208976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 209076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 209176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 209276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman goto tracing; 209376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 209476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 209576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (WSTOPSIG(status) != SIGTRAP) { 209676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (WSTOPSIG(status) == SIGSTOP && 209776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman (tcp->flags & TCB_SIGTRAPPED)) { 209876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman /* 209976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * Trapped attempt to block SIGTRAP 210076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * Hope we are back in control now. 210176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman */ 210276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tcp->flags &= ~(TCB_INSYSCALL | TCB_SIGTRAPPED); 210376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (ptrace(PTRACE_SYSCALL, 210476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman pid, (char *) 1, 0) < 0) { 210576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman perror("trace: ptrace(PTRACE_SYSCALL, ...)"); 210676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman cleanup(); 210776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 210876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 210976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman continue; 211076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 211176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (!cflag 211276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman && (qual_flags[WSTOPSIG(status)] & QUAL_SIGNAL)) { 21137b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman unsigned long addr = 0, pc = 0; 21147b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman#ifdef PT_GETSIGINFO 21157b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman# define PSR_RI 41 21167b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman struct siginfo si; 21177b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman unsigned long psr; 21187b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman 21197b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman upeek(pid, PT_CR_IPSR, &psr); 21207b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman upeek(pid, PT_CR_IIP, &pc); 21217b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman 21227b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman pc += (psr >> PSR_RI) & 0x3; 21237b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman ptrace(PT_GETSIGINFO, pid, 0, (long) &si); 21247b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman addr = (unsigned long) si.si_addr; 21257b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman#endif 212676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman printleader(tcp); 21277b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman tprintf("--- %s (%s) @ %lx (%lx) ---", 2128ce780fc9e6067b15b65ca2904c698c77503bf635Nate Sammons signame(WSTOPSIG(status)), 21297b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman strsignal(WSTOPSIG(status)), pc, addr); 213076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman printtrailer(tcp); 213176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 213276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if ((tcp->flags & TCB_ATTACHED) && 213376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman !sigishandled(tcp, WSTOPSIG(status))) { 2134e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath#ifdef TCB_GROUP_EXITING 2135e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath handle_group_exit(tcp, WSTOPSIG(status)); 2136e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath#else 213776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman detach(tcp, WSTOPSIG(status)); 2138e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath#endif 213976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman continue; 214076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 214176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (ptrace(PTRACE_SYSCALL, pid, (char *) 1, 214276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman WSTOPSIG(status)) < 0) { 214376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman perror("trace: ptrace(PTRACE_SYSCALL, ...)"); 214476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman cleanup(); 214576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 214676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 214776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tcp->flags &= ~TCB_SUSPENDED; 214876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman continue; 214976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 215076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (trace_syscall(tcp) < 0) { 215176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (tcp->flags & TCB_ATTACHED) 215276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman detach(tcp, 0); 215376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman else { 215476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman ptrace(PTRACE_KILL, 215576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tcp->pid, (char *) 1, SIGTERM); 215676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman droptcb(tcp); 215776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 215876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman continue; 215976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 216076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (tcp->flags & TCB_EXITING) { 2161e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath#ifdef TCB_GROUP_EXITING 2162e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath if (tcp->flags & TCB_GROUP_EXITING) { 2163e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath if (handle_group_exit(tcp, 0) < 0) 2164e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath return -1; 2165e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath continue; 2166e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath } 2167e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath#endif 216876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (tcp->flags & TCB_ATTACHED) 216976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman detach(tcp, 0); 217076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman else if (ptrace(PTRACE_CONT, pid, (char *) 1, 0) < 0) { 217176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman perror("strace: ptrace(PTRACE_CONT, ...)"); 217276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman cleanup(); 217376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 217476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 217576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman continue; 217676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 217776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (tcp->flags & TCB_SUSPENDED) { 217876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (!qflag) 217976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman fprintf(stderr, "Process %u suspended\n", pid); 218076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman continue; 218176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 218276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tracing: 218376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (ptrace(PTRACE_SYSCALL, pid, (char *) 1, 0) < 0) { 218476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman perror("trace: ptrace(PTRACE_SYSCALL, ...)"); 218576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman cleanup(); 218676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 218776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 218876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 218976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return 0; 219076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman} 219176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 2192bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman#endif /* !USE_PROCFS */ 219376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 219476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanstatic int curcol; 219576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 219676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#ifdef __STDC__ 219776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#include <stdarg.h> 219876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#define VA_START(a, b) va_start(a, b) 219976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#else 220076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#include <varargs.h> 220176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#define VA_START(a, b) va_start(a) 220276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif 220376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 220476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanvoid 220576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#ifdef __STDC__ 220676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermantprintf(const char *fmt, ...) 220776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#else 220876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermantprintf(fmt, va_alist) 220976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanchar *fmt; 221076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanva_dcl 221176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif 221276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{ 221376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman va_list args; 221476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 221576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman VA_START(args, fmt); 2216b310a0c26b3b31d52aa4b25549e06113284bd5bbRoland McGrath if (outf) { 2217b310a0c26b3b31d52aa4b25549e06113284bd5bbRoland McGrath int n = vfprintf(outf, fmt, args); 2218b310a0c26b3b31d52aa4b25549e06113284bd5bbRoland McGrath if (n < 0 && outf != stderr) 2219b310a0c26b3b31d52aa4b25549e06113284bd5bbRoland McGrath perror(outfname == NULL 2220b310a0c26b3b31d52aa4b25549e06113284bd5bbRoland McGrath ? "<writing to pipe>" : outfname); 2221b310a0c26b3b31d52aa4b25549e06113284bd5bbRoland McGrath else 2222b310a0c26b3b31d52aa4b25549e06113284bd5bbRoland McGrath curcol += n; 2223b310a0c26b3b31d52aa4b25549e06113284bd5bbRoland McGrath } 222476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman va_end(args); 222576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return; 222676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman} 222776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 222876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanvoid 222976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanprintleader(tcp) 223076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanstruct tcb *tcp; 223176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{ 223276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (tcp_last && (!outfname || followfork < 2 || tcp_last == tcp)) { 223376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tcp_last->flags |= TCB_REPRINT; 223476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tprintf(" <unfinished ...>\n"); 223576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 223676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman curcol = 0; 223776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if ((followfork == 1 || pflag_seen > 1) && outfname) 223876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tprintf("%-5d ", tcp->pid); 223976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman else if (nprocs > 1 && !outfname) 224076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tprintf("[pid %5u] ", tcp->pid); 224176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (tflag) { 224276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman char str[sizeof("HH:MM:SS")]; 224376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman struct timeval tv, dtv; 224476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman static struct timeval otv; 224576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 224676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman gettimeofday(&tv, NULL); 224776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (rflag) { 224876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (otv.tv_sec == 0) 224976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman otv = tv; 225076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tv_sub(&dtv, &tv, &otv); 225176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tprintf("%6ld.%06ld ", 225276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman (long) dtv.tv_sec, (long) dtv.tv_usec); 225376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman otv = tv; 225476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 225576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman else if (tflag > 2) { 225676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tprintf("%ld.%06ld ", 225776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman (long) tv.tv_sec, (long) tv.tv_usec); 225876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 225976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman else { 226076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman time_t local = tv.tv_sec; 226176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman strftime(str, sizeof(str), "%T", localtime(&local)); 226276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (tflag > 1) 226376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tprintf("%s.%06ld ", str, (long) tv.tv_usec); 226476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman else 226576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tprintf("%s ", str); 226676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 226776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 226876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (iflag) 226976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman printcall(tcp); 227076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman} 227176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 227276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanvoid 227376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermantabto(col) 227476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanint col; 227576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{ 227676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (curcol < col) 227776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tprintf("%*s", col - curcol, ""); 227876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman} 227976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 228076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanvoid 228176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanprinttrailer(tcp) 228276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanstruct tcb *tcp; 228376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{ 228476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tprintf("\n"); 228576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tcp_last = NULL; 228676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman} 22879ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman 2288ea78f0f77185f7d6d0b2055805139d96e1be816cWichert Akkerman#ifdef HAVE_MP_PROCFS 22899ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman 22909ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkermanint mp_ioctl (int fd, int cmd, void *arg, int size) { 22919ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman 22929ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman struct iovec iov[2]; 22939ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman int n = 1; 2294553a609807074e95eed5a0bffba334b7fb3d3751Roland McGrath 22959ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman iov[0].iov_base = &cmd; 22969ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman iov[0].iov_len = sizeof cmd; 22979ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman if (arg) { 22989ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman ++n; 22999ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman iov[1].iov_base = arg; 23009ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman iov[1].iov_len = size; 23019ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman } 2302553a609807074e95eed5a0bffba334b7fb3d3751Roland McGrath 23039ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman return writev (fd, iov, n); 23049ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman} 23059ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman 23069ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman#endif 2307