1 /*-
2 * Copyright (c) 1988, 1993
3 * The Regents of the University of California. All rights reserved.
4 *
5 * %sccs.include.redist.c%
6 */
7
8 #ifndef lint
9 static char copyright[] =
10 "@(#) Copyright (c) 1988, 1993\n\
11 The Regents of the University of California. All rights reserved.\n";
12 #endif /* not lint */
13
14 #ifndef lint
15 static char sccsid[] = "@(#)ktrace.c 8.2 (Berkeley) 04/28/95";
16 #endif /* not lint */
17
18 #include <sys/param.h>
19 #include <sys/stat.h>
20 #include <sys/file.h>
21 #include <sys/time.h>
22 #include <sys/errno.h>
23 #include <sys/uio.h>
24 #include <sys/ktrace.h>
25
26 #include <err.h>
27 #include <stdio.h>
28 #include <unistd.h>
29
30 #include "ktrace.h"
31
32 void no_ktrace __P((int));
33 void usage __P((void));
34
main(argc,argv)35 main(argc, argv)
36 int argc;
37 char **argv;
38 {
39 enum { NOTSET, CLEAR, CLEARALL } clear;
40 int append, ch, fd, inherit, ops, pid, pidset, trpoints;
41 char *tracefile;
42
43 clear = NOTSET;
44 append = ops = pidset = inherit = 0;
45 trpoints = DEF_POINTS;
46 tracefile = DEF_TRACEFILE;
47 while ((ch = getopt(argc,argv,"aCcdf:g:ip:t:")) != EOF)
48 switch((char)ch) {
49 case 'a':
50 append = 1;
51 break;
52 case 'C':
53 clear = CLEARALL;
54 pidset = 1;
55 break;
56 case 'c':
57 clear = CLEAR;
58 break;
59 case 'd':
60 ops |= KTRFLAG_DESCEND;
61 break;
62 case 'f':
63 tracefile = optarg;
64 break;
65 case 'g':
66 pid = -rpid(optarg);
67 pidset = 1;
68 break;
69 case 'i':
70 inherit = 1;
71 break;
72 case 'p':
73 pid = rpid(optarg);
74 pidset = 1;
75 break;
76 case 't':
77 trpoints = getpoints(optarg);
78 if (trpoints < 0) {
79 warnx("unknown facility in %s", optarg);
80 usage();
81 }
82 break;
83 default:
84 usage();
85 }
86 argv += optind;
87 argc -= optind;
88
89 if (pidset && *argv || !pidset && !*argv)
90 usage();
91
92 if (inherit)
93 trpoints |= KTRFAC_INHERIT;
94
95 (void)signal(SIGSYS, no_ktrace);
96 if (clear != NOTSET) {
97 if (clear == CLEARALL) {
98 ops = KTROP_CLEAR | KTRFLAG_DESCEND;
99 trpoints = ALL_POINTS;
100 pid = 1;
101 } else
102 ops |= pid ? KTROP_CLEAR : KTROP_CLEARFILE;
103
104 if (ktrace(tracefile, ops, trpoints, pid) < 0)
105 err(1, tracefile);
106 exit(0);
107 }
108
109 if ((fd = open(tracefile, O_CREAT | O_WRONLY | (append ? 0 : O_TRUNC),
110 DEFFILEMODE)) < 0)
111 err(1, tracefile);
112 (void)close(fd);
113
114 if (*argv) {
115 if (ktrace(tracefile, ops, trpoints, getpid()) < 0)
116 err(1, tracefile);
117 execvp(argv[0], &argv[0]);
118 err(1, "exec of '%s' failed", argv[0]);
119 }
120 else if (ktrace(tracefile, ops, trpoints, pid) < 0)
121 err(1, tracefile);
122 exit(0);
123 }
124
rpid(p)125 rpid(p)
126 char *p;
127 {
128 static int first;
129
130 if (first++) {
131 warnx("only one -g or -p flag is permitted.");
132 usage();
133 }
134 if (!*p) {
135 warnx("illegal process id.");
136 usage();
137 }
138 return(atoi(p));
139 }
140
141 void
usage()142 usage()
143 {
144 (void)fprintf(stderr,
145 "usage:\tktrace [-aCcid] [-f trfile] [-g pgid] [-p pid] [-t [acgn]\n\tktrace [-aCcid] [-f trfile] [-t [acgn] command\n");
146 exit(1);
147 }
148
149 void
no_ktrace(sig)150 no_ktrace(sig)
151 int sig;
152 {
153 (void)fprintf(stderr,
154 "error:\tktrace() system call not supported in the running kernel\n\tre-compile kernel with 'options KTRACE'\n");
155 exit(1);
156 }
157