]> git.saurik.com Git - apple/system_cmds.git/blob - ktrace.tproj/ktrace.c
system_cmds-279.tar.gz
[apple/system_cmds.git] / ktrace.tproj / ktrace.c
1 /*
2 * Copyright (c) 1999, 2000-2001 Apple Computer, Inc. All rights reserved.
3 *
4 * @APPLE_LICENSE_HEADER_START@
5 *
6 * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
7 *
8 * This file contains Original Code and/or Modifications of Original Code
9 * as defined in and that are subject to the Apple Public Source License
10 * Version 2.0 (the 'License'). You may not use this file except in
11 * compliance with the License. Please obtain a copy of the License at
12 * http://www.opensource.apple.com/apsl/ and read it before using this
13 * file.
14 *
15 * The Original Code and all software distributed under the License are
16 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
17 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
18 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
19 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
20 * Please see the License for the specific language governing rights and
21 * limitations under the License.
22 *
23 * @APPLE_LICENSE_HEADER_END@
24 */
25 /*-
26 * Copyright (c) 1988, 1993
27 * The Regents of the University of California. All rights reserved.
28 *
29 * Redistribution and use in source and binary forms, with or without
30 * modification, are permitted provided that the following conditions
31 * are met:
32 * 1. Redistributions of source code must retain the above copyright
33 * notice, this list of conditions and the following disclaimer.
34 * 2. Redistributions in binary form must reproduce the above copyright
35 * notice, this list of conditions and the following disclaimer in the
36 * documentation and/or other materials provided with the distribution.
37 * 3. All advertising materials mentioning features or use of this software
38 * must display the following acknowledgement:
39 * This product includes software developed by the University of
40 * California, Berkeley and its contributors.
41 * 4. Neither the name of the University nor the names of its contributors
42 * may be used to endorse or promote products derived from this software
43 * without specific prior written permission.
44 *
45 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
46 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
47 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
48 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
49 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
50 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
51 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
52 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
53 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
54 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
55 * SUCH DAMAGE.
56 */
57
58 #ifndef lint
59 static char copyright[] =
60 "@(#) Copyright (c) 1988, 1993\n\
61 The Regents of the University of California. All rights reserved.\n";
62 #endif /* not lint */
63
64 #ifndef lint
65 #if 0
66 static char sccsid[] = "@(#)ktrace.c 8.1 (Berkeley) 6/6/93";
67 #endif
68 static const char rcsid[] =
69 "$FreeBSD: src/usr.bin/ktrace/ktrace.c,v 1.12.2.3 2001/07/11 00:29:27 mikeh Exp $";
70 #endif /* not lint */
71
72 #include <sys/param.h>
73 #include <sys/stat.h>
74 #include <sys/file.h>
75 #include <sys/time.h>
76 #include <sys/errno.h>
77 #include <sys/uio.h>
78 #include <sys/ktrace.h>
79
80 #include <err.h>
81 #include <stdio.h>
82 #include <unistd.h>
83
84 #include "ktrace.h"
85
86 void no_ktrace __P((int));
87 void usage __P((void));
88
89 main(argc, argv)
90 int argc;
91 char **argv;
92 {
93 enum { NOTSET, CLEAR, CLEARALL } clear;
94 int append, ch, fd, inherit, ops, pid, pidset, trpoints;
95 char *tracefile;
96 mode_t omask;
97 struct stat sb;
98
99 clear = NOTSET;
100 append = ops = pidset = inherit = 0;
101 trpoints = DEF_POINTS;
102 tracefile = DEF_TRACEFILE;
103 while ((ch = getopt(argc,argv,"aCcdf:g:ip:t:")) != -1)
104 switch((char)ch) {
105 case 'a':
106 append = 1;
107 break;
108 case 'C':
109 clear = CLEARALL;
110 pidset = 1;
111 break;
112 case 'c':
113 clear = CLEAR;
114 break;
115 case 'd':
116 ops |= KTRFLAG_DESCEND;
117 break;
118 case 'f':
119 tracefile = optarg;
120 break;
121 case 'g':
122 pid = -rpid(optarg);
123 pidset = 1;
124 break;
125 case 'i':
126 inherit = 1;
127 break;
128 case 'p':
129 pid = rpid(optarg);
130 pidset = 1;
131 break;
132 case 't':
133 trpoints = getpoints(optarg);
134 if (trpoints < 0) {
135 warnx("unknown facility in %s", optarg);
136 usage();
137 }
138 break;
139 default:
140 usage();
141 }
142 argv += optind;
143 argc -= optind;
144
145 if (pidset && *argv || !pidset && !*argv)
146 usage();
147
148 if (inherit)
149 trpoints |= KTRFAC_INHERIT;
150
151 (void)signal(SIGSYS, no_ktrace);
152 if (clear != NOTSET) {
153 if (clear == CLEARALL) {
154 ops = KTROP_CLEAR | KTRFLAG_DESCEND;
155 trpoints = ALL_POINTS;
156 pid = 1;
157 } else
158 ops |= pidset ? KTROP_CLEAR : KTROP_CLEARFILE;
159
160 if (ktrace(tracefile, ops, trpoints, pid) < 0)
161 err(1, "%s", tracefile);
162 exit(0);
163 }
164
165 omask = umask(S_IRWXG|S_IRWXO);
166 if (append) {
167 if ((fd = open(tracefile, O_CREAT | O_WRONLY, DEFFILEMODE)) < 0)
168 err(1, "%s", tracefile);
169 if (fstat(fd, &sb) != 0 || sb.st_uid != getuid())
170 errx(1, "Refuse to append to %s not owned by you.",
171 tracefile);
172 } else {
173 if (unlink(tracefile) == -1 && errno != ENOENT)
174 err(1, "unlink %s", tracefile);
175 if ((fd = open(tracefile, O_CREAT | O_EXCL | O_WRONLY,
176 DEFFILEMODE)) < 0)
177 err(1, "%s", tracefile);
178 }
179 (void)umask(omask);
180 (void)close(fd);
181
182 if (*argv) {
183 if (ktrace(tracefile, ops, trpoints, getpid()) < 0)
184 err(1, "%s", tracefile);
185 execvp(argv[0], &argv[0]);
186 err(1, "exec of '%s' failed", argv[0]);
187 }
188 else if (ktrace(tracefile, ops, trpoints, pid) < 0)
189 err(1, "%s", tracefile);
190 exit(0);
191 }
192
193 rpid(p)
194 char *p;
195 {
196 static int first;
197
198 if (first++) {
199 warnx("only one -g or -p flag is permitted.");
200 usage();
201 }
202 if (!*p) {
203 warnx("illegal process id.");
204 usage();
205 }
206 return(atoi(p));
207 }
208
209 void
210 usage()
211 {
212 (void)fprintf(stderr, "%s\n%s\n",
213 "usage: ktrace [-aCcdi] [-f trfile] [-g pgrp | -p pid] [-t cnisuw]",
214 " ktrace [-adi] [-f trfile] [-t cnisuw] command");
215 exit(1);
216 }
217
218 void
219 no_ktrace(sig)
220 int sig;
221 {
222 (void)fprintf(stderr,
223 "error:\tktrace() system call not supported in the running kernel\n\tre-compile kernel with 'options KTRACE'\n");
224 exit(1);
225 }