Thu Jan 24 17:47:59 2013 UTC ()
use O_CLOEXEC.


(christos)
diff -r1.45 -r1.46 src/usr.bin/ktrace/ktrace.c

cvs diff -r1.45 -r1.46 src/usr.bin/ktrace/ktrace.c (switch to unified diff)

--- src/usr.bin/ktrace/ktrace.c 2011/09/16 15:39:26 1.45
+++ src/usr.bin/ktrace/ktrace.c 2013/01/24 17:47:58 1.46
@@ -1,416 +1,402 @@ @@ -1,416 +1,402 @@
1/* $NetBSD: ktrace.c,v 1.45 2011/09/16 15:39:26 joerg Exp $ */ 1/* $NetBSD: ktrace.c,v 1.46 2013/01/24 17:47:58 christos Exp $ */
2 2
3/*- 3/*-
4 * Copyright (c) 1988, 1993 4 * Copyright (c) 1988, 1993
5 * The Regents of the University of California. All rights reserved. 5 * The Regents of the University of California. All rights reserved.
6 * 6 *
7 * Redistribution and use in source and binary forms, with or without 7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions 8 * modification, are permitted provided that the following conditions
9 * are met: 9 * are met:
10 * 1. Redistributions of source code must retain the above copyright 10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer. 11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright 12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the 13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution. 14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the University nor the names of its contributors 15 * 3. Neither the name of the University nor the names of its contributors
16 * may be used to endorse or promote products derived from this software 16 * may be used to endorse or promote products derived from this software
17 * without specific prior written permission. 17 * without specific prior written permission.
18 * 18 *
19 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 19 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 22 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE. 29 * SUCH DAMAGE.
30 */ 30 */
31 31
32#include <sys/cdefs.h> 32#include <sys/cdefs.h>
33#ifndef lint 33#ifndef lint
34__COPYRIGHT("@(#) Copyright (c) 1988, 1993\ 34__COPYRIGHT("@(#) Copyright (c) 1988, 1993\
35 The Regents of the University of California. All rights reserved."); 35 The Regents of the University of California. All rights reserved.");
36#endif /* not lint */ 36#endif /* not lint */
37 37
38#ifndef lint 38#ifndef lint
39#if 0 39#if 0
40static char sccsid[] = "@(#)ktrace.c 8.2 (Berkeley) 4/28/95"; 40static char sccsid[] = "@(#)ktrace.c 8.2 (Berkeley) 4/28/95";
41#else 41#else
42__RCSID("$NetBSD: ktrace.c,v 1.45 2011/09/16 15:39:26 joerg Exp $"); 42__RCSID("$NetBSD: ktrace.c,v 1.46 2013/01/24 17:47:58 christos Exp $");
43#endif 43#endif
44#endif /* not lint */ 44#endif /* not lint */
45 45
46#include <sys/param.h> 46#include <sys/param.h>
47#include <sys/stat.h> 47#include <sys/stat.h>
48#include <sys/wait.h> 48#include <sys/wait.h>
49#include <sys/file.h> 49#include <sys/file.h>
50#include <sys/time.h> 50#include <sys/time.h>
51#include <sys/uio.h> 51#include <sys/uio.h>
52#include <sys/ktrace.h> 52#include <sys/ktrace.h>
53#include <sys/socket.h> 53#include <sys/socket.h>
54 54
55#include <err.h> 55#include <err.h>
56#include <errno.h> 56#include <errno.h>
57#include <stdio.h> 57#include <stdio.h>
58#include <stdlib.h> 58#include <stdlib.h>
59#include <string.h> 59#include <string.h>
60#include <unistd.h> 60#include <unistd.h>
61#include <signal.h> 61#include <signal.h>
62 62
63#include "ktrace.h" 63#include "ktrace.h"
64 64
65#ifdef KTRUSS 65#ifdef KTRUSS
66#include "setemul.h" 66#include "setemul.h"
67#endif 67#endif
68 68
69static int rpid(char *); 69static int rpid(char *);
70__dead static void usage(void); 70__dead static void usage(void);
71static int do_ktrace(const char *, int, int, int, int, int); 71static int do_ktrace(const char *, int, int, int, int, int);
72__dead static void no_ktrace(int); 72__dead static void no_ktrace(int);
73static void fset(int fd, int flag); 
74static void fclear(int fd, int flag); 73static void fclear(int fd, int flag);
75 74
76#ifdef KTRUSS 75#ifdef KTRUSS
77extern int timestamp, decimal, fancy, tail, maxdata; 76extern int timestamp, decimal, fancy, tail, maxdata;
78#endif 77#endif
79 78
80int 79int
81main(int argc, char *argv[]) 80main(int argc, char *argv[])
82{ 81{
83 enum { NOTSET, CLEAR, CLEARALL } clear; 82 enum { NOTSET, CLEAR, CLEARALL } clear;
84 int block, append, ch, fd, trset, ops, pid, pidset, synclog, trpoints; 83 int block, append, ch, fd, trset, ops, pid, pidset, synclog, trpoints;
85 int vers; 84 int vers;
86 const char *outfile; 85 const char *outfile;
87#ifdef KTRUSS 86#ifdef KTRUSS
88 const char *infile; 87 const char *infile;
89 const char *emul_name = "netbsd"; 88 const char *emul_name = "netbsd";
90#endif 89#endif
91 90
92 clear = NOTSET; 91 clear = NOTSET;
93 append = ops = pidset = trset = synclog = 0; 92 append = ops = pidset = trset = synclog = 0;
94 trpoints = 0; 93 trpoints = 0;
95 block = 1; 94 block = 1;
96 vers = 2; 95 vers = 2;
97 pid = 0; /* Appease GCC */ 96 pid = 0; /* Appease GCC */
98 97
99#ifdef KTRUSS 98#ifdef KTRUSS
100# define OPTIONS "aCce:df:g:ilm:no:p:RTt:v:" 99# define OPTIONS "aCce:df:g:ilm:no:p:RTt:v:"
101 outfile = infile = NULL; 100 outfile = infile = NULL;
102#else 101#else
103# define OPTIONS "aCcdf:g:ip:st:v:" 102# define OPTIONS "aCcdf:g:ip:st:v:"
104 outfile = DEF_TRACEFILE; 103 outfile = DEF_TRACEFILE;
105#endif 104#endif
106 105
107 while ((ch = getopt(argc, argv, OPTIONS)) != -1) 106 while ((ch = getopt(argc, argv, OPTIONS)) != -1)
108 switch (ch) { 107 switch (ch) {
109 case 'a': 108 case 'a':
110 append = 1; 109 append = 1;
111 break; 110 break;
112 case 'C': 111 case 'C':
113 clear = CLEARALL; 112 clear = CLEARALL;
114 pidset = 1; 113 pidset = 1;
115 break; 114 break;
116 case 'c': 115 case 'c':
117 clear = CLEAR; 116 clear = CLEAR;
118 pidset = 1; 117 pidset = 1;
119 break; 118 break;
120 case 'd': 119 case 'd':
121 ops |= KTRFLAG_DESCEND; 120 ops |= KTRFLAG_DESCEND;
122 break; 121 break;
123#ifdef KTRUSS 122#ifdef KTRUSS
124 case 'e': 123 case 'e':
125 emul_name = strdup(optarg); /* it's safer to copy it */ 124 emul_name = strdup(optarg); /* it's safer to copy it */
126 break; 125 break;
127 case 'f': 126 case 'f':
128 infile = optarg; 127 infile = optarg;
129 break; 128 break;
130#else 129#else
131 case 'f': 130 case 'f':
132 outfile = optarg; 131 outfile = optarg;
133 break; 132 break;
134#endif 133#endif
135 case 'g': 134 case 'g':
136 pid = -rpid(optarg); 135 pid = -rpid(optarg);
137 pidset = 1; 136 pidset = 1;
138 break; 137 break;
139 case 'i': 138 case 'i':
140 trpoints |= KTRFAC_INHERIT; 139 trpoints |= KTRFAC_INHERIT;
141 break; 140 break;
142#ifdef KTRUSS 141#ifdef KTRUSS
143 case 'l': 142 case 'l':
144 tail = 1; 143 tail = 1;
145 break; 144 break;
146 case 'm': 145 case 'm':
147 maxdata = atoi(optarg); 146 maxdata = atoi(optarg);
148 break; 147 break;
149 case 'o': 148 case 'o':
150 outfile = optarg; 149 outfile = optarg;
151 break; 150 break;
152#endif 151#endif
153 case 'n': 152 case 'n':
154 block = 0; 153 block = 0;
155 break; 154 break;
156 case 'p': 155 case 'p':
157 pid = rpid(optarg); 156 pid = rpid(optarg);
158 pidset = 1; 157 pidset = 1;
159 break; 158 break;
160#ifdef KTRUSS 159#ifdef KTRUSS
161 case 'R': 160 case 'R':
162 timestamp = 2; /* relative timestamp */ 161 timestamp = 2; /* relative timestamp */
163 break; 162 break;
164#else 163#else
165 case 's': 164 case 's':
166 synclog = 1; 165 synclog = 1;
167 break; 166 break;
168#endif 167#endif
169#ifdef KTRUSS 168#ifdef KTRUSS
170 case 'T': 169 case 'T':
171 timestamp = 1; 170 timestamp = 1;
172 break; 171 break;
173#endif 172#endif
174 case 't': 173 case 't':
175 trset = 1; 174 trset = 1;
176 trpoints = getpoints(trpoints, optarg); 175 trpoints = getpoints(trpoints, optarg);
177 if (trpoints < 0) { 176 if (trpoints < 0) {
178 warnx("unknown facility in %s", optarg); 177 warnx("unknown facility in %s", optarg);
179 usage(); 178 usage();
180 } 179 }
181 break; 180 break;
182 case 'v': 181 case 'v':
183 vers = atoi(optarg); 182 vers = atoi(optarg);
184 break; 183 break;
185 default: 184 default:
186 usage(); 185 usage();
187 } 186 }
188 argv += optind; 187 argv += optind;
189 argc -= optind; 188 argc -= optind;
190 189
191 if (!trset) 190 if (!trset)
192 trpoints |= clear == NOTSET ? DEF_POINTS : ALL_POINTS; 191 trpoints |= clear == NOTSET ? DEF_POINTS : ALL_POINTS;
193 192
194 if ((pidset && *argv) || (!pidset && !*argv)) { 193 if ((pidset && *argv) || (!pidset && !*argv)) {
195#ifdef KTRUSS 194#ifdef KTRUSS
196 if (!infile) 195 if (!infile)
197#endif 196#endif
198 usage(); 197 usage();
199 } 198 }
200 199
201#ifdef KTRUSS 200#ifdef KTRUSS
202 if (clear == CLEAR && outfile == NULL && pid == 0) 201 if (clear == CLEAR && outfile == NULL && pid == 0)
203 usage(); 202 usage();
204 203
205 if (infile) { 204 if (infile) {
206 dumpfile(infile, 0, trpoints); 205 dumpfile(infile, 0, trpoints);
207 exit(0); 206 exit(0);
208 } 207 }
209 208
210 setemul(emul_name, 0, 0); 209 setemul(emul_name, 0, 0);
211#endif 210#endif
212 211
213 /* 212 /*
214 * For cleaner traces, initialize malloc now rather 213 * For cleaner traces, initialize malloc now rather
215 * than in a traced subprocess. 214 * than in a traced subprocess.
216 */ 215 */
217 free(malloc(1)); 216 free(malloc(1));
218 217
219 (void)signal(SIGSYS, no_ktrace); 218 (void)signal(SIGSYS, no_ktrace);
220 if (clear != NOTSET) { 219 if (clear != NOTSET) {
221 if (clear == CLEARALL) { 220 if (clear == CLEARALL) {
222 ops = KTROP_CLEAR | KTRFLAG_DESCEND; 221 ops = KTROP_CLEAR | KTRFLAG_DESCEND;
223 trpoints = ALL_POINTS; 222 trpoints = ALL_POINTS;
224 pid = 1; 223 pid = 1;
225 } else 224 } else
226 ops |= pid ? KTROP_CLEAR : KTROP_CLEARFILE; 225 ops |= pid ? KTROP_CLEAR : KTROP_CLEARFILE;
227 226
228 (void)do_ktrace(outfile, vers, ops, trpoints, pid, block); 227 (void)do_ktrace(outfile, vers, ops, trpoints, pid, block);
229 exit(0); 228 exit(0);
230 } 229 }
231 230
232 if (outfile && strcmp(outfile, "-")) { 231 if (outfile && strcmp(outfile, "-")) {
233 if ((fd = open(outfile, O_CREAT | O_WRONLY | 232 if ((fd = open(outfile, O_CREAT | O_WRONLY |
234 (append ? 0 : O_TRUNC) | (synclog ? 0 : O_SYNC), 233 (append ? 0 : O_TRUNC) | (synclog ? 0 : O_SYNC),
235 DEFFILEMODE)) < 0) 234 DEFFILEMODE)) < 0)
236 err(EXIT_FAILURE, "%s", outfile); 235 err(EXIT_FAILURE, "%s", outfile);
237 (void)close(fd); 236 (void)close(fd);
238 } 237 }
239 238
240 if (*argv) { 239 if (*argv) {
241#ifdef KTRUSS 240#ifdef KTRUSS
242 if (do_ktrace(outfile, vers, ops, trpoints, getpid(), block) == 1) { 241 if (do_ktrace(outfile, vers, ops, trpoints, getpid(), block) == 1) {
243 execvp(argv[0], &argv[0]); 242 execvp(argv[0], &argv[0]);
244 err(EXIT_FAILURE, "exec of '%s' failed", argv[0]); 243 err(EXIT_FAILURE, "exec of '%s' failed", argv[0]);
245 } 244 }
246#else 245#else
247 (void)do_ktrace(outfile, vers, ops, trpoints, getpid(), block); 246 (void)do_ktrace(outfile, vers, ops, trpoints, getpid(), block);
248 execvp(argv[0], &argv[0]); 247 execvp(argv[0], &argv[0]);
249 err(EXIT_FAILURE, "exec of '%s' failed", argv[0]); 248 err(EXIT_FAILURE, "exec of '%s' failed", argv[0]);
250#endif 249#endif
251 } else 250 } else
252 (void)do_ktrace(outfile, vers, ops, trpoints, pid, block); 251 (void)do_ktrace(outfile, vers, ops, trpoints, pid, block);
253 return 0; 252 return 0;
254} 253}
255 254
256static int 255static int
257rpid(char *p) 256rpid(char *p)
258{ 257{
259 static int first; 258 static int first;
260 259
261 if (first++) { 260 if (first++) {
262 warnx("only one -g or -p flag is permitted."); 261 warnx("only one -g or -p flag is permitted.");
263 usage(); 262 usage();
264 } 263 }
265 if (!*p) { 264 if (!*p) {
266 warnx("illegal process id."); 265 warnx("illegal process id.");
267 usage(); 266 usage();
268 } 267 }
269 return (atoi(p)); 268 return (atoi(p));
270} 269}
271 270
272static void 271static void
273fset(int fd, int flag) 
274{ 
275 int oflag = fcntl(fd, F_GETFL, 0); 
276 
277 if (oflag == -1) 
278 err(EXIT_FAILURE, "Cannot get file flags"); 
279 if (fcntl(fd, F_SETFL, oflag | flag) == -1) 
280 err(EXIT_FAILURE, "Cannot set file flags"); 
281} 
282 
283static void 
284fclear(int fd, int flag) 272fclear(int fd, int flag)
285{ 273{
286 int oflag = fcntl(fd, F_GETFL, 0); 274 int oflag = fcntl(fd, F_GETFL, 0);
287 275
288 if (oflag == -1) 276 if (oflag == -1)
289 err(EXIT_FAILURE, "Cannot get file flags"); 277 err(EXIT_FAILURE, "Cannot get file flags");
290 if (fcntl(fd, F_SETFL, oflag & ~flag) == -1) 278 if (fcntl(fd, F_SETFL, oflag & ~flag) == -1)
291 err(EXIT_FAILURE, "Cannot set file flags"); 279 err(EXIT_FAILURE, "Cannot set file flags");
292} 280}
293 281
294static void 282static void
295usage(void) 283usage(void)
296{ 284{
297 285
298#define TRPOINTS "[AaceilmnSsuvw+-]" 286#define TRPOINTS "[AaceilmnSsuvw+-]"
299#ifdef KTRUSS 287#ifdef KTRUSS
300 (void)fprintf(stderr, "usage:\t%s " 288 (void)fprintf(stderr, "usage:\t%s "
301 "[-aCcdilnRT] [-e emulation] [-f infile] [-g pgrp] " 289 "[-aCcdilnRT] [-e emulation] [-f infile] [-g pgrp] "
302 "[-m maxdata]\n\t " 290 "[-m maxdata]\n\t "
303 "[-o outfile] [-p pid] [-t " TRPOINTS "]\n", getprogname()); 291 "[-o outfile] [-p pid] [-t " TRPOINTS "]\n", getprogname());
304 (void)fprintf(stderr, "\t%s " 292 (void)fprintf(stderr, "\t%s "
305 "[-adinRT] [-e emulation] [-m maxdata] [-o outfile]\n\t " 293 "[-adinRT] [-e emulation] [-m maxdata] [-o outfile]\n\t "
306 "[-t " TRPOINTS "] [-v vers] command\n", 294 "[-t " TRPOINTS "] [-v vers] command\n",
307 getprogname()); 295 getprogname());
308#else 296#else
309 (void)fprintf(stderr, "usage:\t%s " 297 (void)fprintf(stderr, "usage:\t%s "
310 "[-aCcdins] [-f trfile] [-g pgrp] [-p pid] [-t " TRPOINTS "]\n", 298 "[-aCcdins] [-f trfile] [-g pgrp] [-p pid] [-t " TRPOINTS "]\n",
311 getprogname()); 299 getprogname());
312 (void)fprintf(stderr, "\t%s " 300 (void)fprintf(stderr, "\t%s "
313 "[-adis] [-f trfile] [-t " TRPOINTS "] command\n", 301 "[-adis] [-f trfile] [-t " TRPOINTS "] command\n",
314 getprogname()); 302 getprogname());
315#endif 303#endif
316 exit(1); 304 exit(1);
317} 305}
318 306
319static const char *ktracefile = NULL; 307static const char *ktracefile = NULL;
320static void 308static void
321/*ARGSUSED*/ 309/*ARGSUSED*/
322no_ktrace(int sig) 310no_ktrace(int sig)
323{ 311{
324 312
325 if (ktracefile) 313 if (ktracefile)
326 (void)unlink(ktracefile); 314 (void)unlink(ktracefile);
327 (void)errx(EXIT_FAILURE, 315 (void)errx(EXIT_FAILURE,
328 "ktrace(2) system call not supported in the running" 316 "ktrace(2) system call not supported in the running"
329 " kernel; re-compile kernel with `options KTRACE'"); 317 " kernel; re-compile kernel with `options KTRACE'");
330} 318}
331 319
332static int 320static int
333do_ktrace(const char *tracefile, int vers, int ops, int trpoints, int pid, 321do_ktrace(const char *tracefile, int vers, int ops, int trpoints, int pid,
334 int block) 322 int block)
335{ 323{
336 int ret; 324 int ret;
337 ops |= vers << KTRFAC_VER_SHIFT; 325 ops |= vers << KTRFAC_VER_SHIFT;
338 326
339 if (KTROP(ops) == KTROP_SET && 327 if (KTROP(ops) == KTROP_SET &&
340 (!tracefile || strcmp(tracefile, "-") == 0)) { 328 (!tracefile || strcmp(tracefile, "-") == 0)) {
341 int pi[2], dofork; 329 int pi[2], dofork;
342 330
343 if (pipe(pi) < 0) 331 if (pipe2(pi, O_CLOEXEC) == -1)
344 err(EXIT_FAILURE, "pipe(2)"); 332 err(EXIT_FAILURE, "pipe(2)");
345 333
346 fset(pi[0], FD_CLOEXEC); 
347 fset(pi[1], FD_CLOEXEC); 
348 dofork = (pid == getpid()); 334 dofork = (pid == getpid());
349 335
350 if (dofork) { 336 if (dofork) {
351#ifdef KTRUSS 337#ifdef KTRUSS
352 /* 338 /*
353 * Create a child process and trace it. 339 * Create a child process and trace it.
354 */ 340 */
355 pid = fork(); 341 pid = fork();
356 if (pid == -1) 342 if (pid == -1)
357 err(EXIT_FAILURE, "fork"); 343 err(EXIT_FAILURE, "fork");
358 else if (pid == 0) { 344 else if (pid == 0) {
359 pid = getpid(); 345 pid = getpid();
360 goto trace_and_exec; 346 goto trace_and_exec;
361 } 347 }
362#else 348#else
363 int fpid; 349 int fpid;
364 350
365 /* 351 /*
366 * Create a dumper process and we will be 352 * Create a dumper process and we will be
367 * traced. 353 * traced.
368 */ 354 */
369 fpid = fork(); 355 fpid = fork();
370 if (fpid == -1) 356 if (fpid == -1)
371 err(EXIT_FAILURE, "fork"); 357 err(EXIT_FAILURE, "fork");
372 else if (fpid != 0) 358 else if (fpid != 0)
373 goto trace_and_exec; 359 goto trace_and_exec;
374#endif 360#endif
375 (void)close(pi[1]); 361 (void)close(pi[1]);
376 } else { 362 } else {
377 ret = fktrace(pi[1], ops, trpoints, pid); 363 ret = fktrace(pi[1], ops, trpoints, pid);
378 if (ret == -1) 364 if (ret == -1)
379 err(EXIT_FAILURE, "fd %d, pid %d", 365 err(EXIT_FAILURE, "fd %d, pid %d",
380 pi[1], pid); 366 pi[1], pid);
381 if (block) 367 if (block)
382 fclear(pi[1], O_NONBLOCK); 368 fclear(pi[1], O_NONBLOCK);
383 } 369 }
384#ifdef KTRUSS 370#ifdef KTRUSS
385 dumpfile(NULL, pi[0], trpoints); 371 dumpfile(NULL, pi[0], trpoints);
386 waitpid(pid, NULL, 0); 372 waitpid(pid, NULL, 0);
387#else 373#else
388 { 374 {
389 char buf[BUFSIZ]; 375 char buf[BUFSIZ];
390 int n; 376 int n;
391 377
392 while ((n = 378 while ((n =
393 read(pi[0], buf, sizeof(buf))) > 0) 379 read(pi[0], buf, sizeof(buf))) > 0)
394 if (write(STDOUT_FILENO, buf, (size_t)n) == -1) 380 if (write(STDOUT_FILENO, buf, (size_t)n) == -1)
395 warn("write failed"); 381 warn("write failed");
396 } 382 }
397 if (dofork) 383 if (dofork)
398 _exit(0); 384 _exit(0);
399#endif 385#endif
400 return 0; 386 return 0;
401 387
402trace_and_exec: 388trace_and_exec:
403 (void)close(pi[0]); 389 (void)close(pi[0]);
404 ret = fktrace(pi[1], ops, trpoints, pid); 390 ret = fktrace(pi[1], ops, trpoints, pid);
405 if (ret == -1) 391 if (ret == -1)
406 err(EXIT_FAILURE, "fd %d, pid %d", pi[1], pid); 392 err(EXIT_FAILURE, "fd %d, pid %d", pi[1], pid);
407 if (block) 393 if (block)
408 fclear(pi[1], O_NONBLOCK); 394 fclear(pi[1], O_NONBLOCK);
409 } else { 395 } else {
410 ret = ktrace(ktracefile = tracefile, ops, trpoints, pid); 396 ret = ktrace(ktracefile = tracefile, ops, trpoints, pid);
411 if (ret == -1) 397 if (ret == -1)
412 err(EXIT_FAILURE, "file %s, pid %d", 398 err(EXIT_FAILURE, "file %s, pid %d",
413 tracefile != NULL ? tracefile : "NULL", pid); 399 tracefile != NULL ? tracefile : "NULL", pid);
414 } 400 }
415 return 1; 401 return 1;
416} 402}