xref: /original-bsd/usr.bin/ktrace/ktrace.c (revision 27393bdf)
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 
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 
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
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
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