xref: /original-bsd/usr.bin/ktrace/ktrace.c (revision cef711d2)
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.1 (Berkeley) 06/06/93";
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 = inherit = 0;
40 	trpoints = DEF_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 			trpoints = ALL_POINTS;
95 			pid = 1;
96 		} else
97 			ops |= pid ? KTROP_CLEAR : KTROP_CLEARFILE;
98 
99 		if (ktrace(tracefile, ops, trpoints, pid) < 0)
100 			error(tracefile);
101 		exit(0);
102 	}
103 
104 	if ((fd = open(tracefile, O_CREAT | O_WRONLY | (append ? 0 : O_TRUNC),
105 	    DEFFILEMODE)) < 0)
106 		error(tracefile);
107 	(void)close(fd);
108 
109 	if (*argv) {
110 		if (ktrace(tracefile, ops, trpoints, getpid()) < 0)
111 			error();
112 		execvp(argv[0], &argv[0]);
113 		error(argv[0]);
114 		exit(1);
115 	}
116 	else if (ktrace(tracefile, ops, trpoints, pid) < 0)
117 		error(tracefile);
118 	exit(0);
119 }
120 
121 rpid(p)
122 	char *p;
123 {
124 	static int first;
125 
126 	if (first++) {
127 		(void)fprintf(stderr,
128 		    "ktrace: only one -g or -p flag is permitted.\n");
129 		usage();
130 	}
131 	if (!*p) {
132 		(void)fprintf(stderr, "ktrace: illegal process id.\n");
133 		usage();
134 	}
135 	return(atoi(p));
136 }
137 
138 error(name)
139 	char *name;
140 {
141 	(void)fprintf(stderr, "ktrace: %s: %s.\n", name, strerror(errno));
142 	exit(1);
143 }
144 
145 usage()
146 {
147 	(void)fprintf(stderr,
148 "usage:\tktrace [-aCcid] [-f trfile] [-g pgid] [-p pid] [-t [acgn]\n\tktrace [-aCcid] [-f trfile] [-t [acgn] command\n");
149 	exit(1);
150 }
151