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