xref: /original-bsd/usr.bin/ktrace/ktrace.c (revision b21da0a0)
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.1 (Berkeley) 01/17/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 			break;
50 		case 'c':
51 			clear = CLEAR;
52 			break;
53 		case 'd':
54 			ops |= KTRFLAG_DESCEND;
55 			break;
56 		case 'f':
57 			tracefile = optarg;
58 			break;
59 		case 'g':
60 			pid = -rpid(optarg);
61 			pidset = 1;
62 			break;
63 		case 'i':
64 			inherit = 1;
65 			break;
66 		case 'p':
67 			pid = rpid(optarg);
68 			pidset = 1;
69 			break;
70 		case 't':
71 			trpoints = getpoints(optarg);
72 			if (trpoints < 0) {
73 				(void)fprintf(stderr,
74 				    "ktrace: unknown facility in %s\n", optarg);
75 				usage();
76 			}
77 			break;
78 		default:
79 			usage();
80 		}
81 	argv += optind;
82 	argc -= optind;
83 
84 	if (pidset && *argv || !pidset && !*argv)
85 		usage();
86 
87 	if (inherit)
88 		trpoints |= KTRFAC_INHERIT;
89 
90 	if (clear != NOTSET) {
91 		if (clear == CLEARALL) {
92 			ops = KTROP_CLEAR | KTRFLAG_DESCEND;
93 			pid = 1;
94 		} else
95 			ops |= pid ? KTROP_CLEAR : KTROP_CLEARFILE;
96 
97 		if (ktrace(tracefile, ops, trpoints, pid) < 0)
98 			error(tracefile);
99 		exit(0);
100 	}
101 
102 	if ((fd = open(tracefile, O_CREAT | O_WRONLY | (append ? 0 : O_TRUNC),
103 	    DEFFILEMODE)) < 0)
104 		error(tracefile);
105 	(void)close(fd);
106 
107 	if (*argv) {
108 		if (ktrace(tracefile, ops, trpoints, getpid()) < 0)
109 			error();
110 		execvp(argv[0], &argv[0]);
111 		error(argv[0]);
112 		exit(1);
113 	}
114 	else if (ktrace(tracefile, ops, trpoints, pid) < 0)
115 		error(tracefile);
116 	exit(0);
117 }
118 
119 rpid(p)
120 	char *p;
121 {
122 	static int first;
123 
124 	if (first++) {
125 		(void)fprintf(stderr,
126 		    "ktrace: only one -g or -p flag is permitted.\n");
127 		usage();
128 	}
129 	if (!*p) {
130 		(void)fprintf(stderr, "ktrace: illegal process id.\n");
131 		usage();
132 	}
133 	return(atoi(p));
134 }
135 
136 error(name)
137 	char *name;
138 {
139 	(void)fprintf(stderr, "ktrace: %s: %s.\n", name, strerror(errno));
140 	exit(1);
141 }
142 
143 usage()
144 {
145 	(void)fprintf(stderr,
146 "usage:\tktrace [-aCcid] [-f trfile] [-g pgid] [-p pid] [-t [acgn]\n\tktrace [-aCcid] [-f trfile] [-t [acgn] command\n");
147 	exit(1);
148 }
149