xref: /csrg-svn/usr.bin/ktrace/ktrace.c (revision 69074)
144584Smarc /*-
262045Sbostic  * Copyright (c) 1988, 1993
362045Sbostic  *	The Regents of the University of California.  All rights reserved.
436426Smarc  *
544584Smarc  * %sccs.include.redist.c%
636426Smarc  */
736426Smarc 
836426Smarc #ifndef lint
962045Sbostic static char copyright[] =
1062045Sbostic "@(#) Copyright (c) 1988, 1993\n\
1162045Sbostic 	The Regents of the University of California.  All rights reserved.\n";
1236426Smarc #endif /* not lint */
1336426Smarc 
1436426Smarc #ifndef lint
15*69074Sbostic static char sccsid[] = "@(#)ktrace.c	8.2 (Berkeley) 04/28/95";
1636426Smarc #endif /* not lint */
1736426Smarc 
1845987Sbostic #include <sys/param.h>
1945987Sbostic #include <sys/stat.h>
2045987Sbostic #include <sys/file.h>
2145987Sbostic #include <sys/time.h>
2245987Sbostic #include <sys/errno.h>
2345987Sbostic #include <sys/uio.h>
2445987Sbostic #include <sys/ktrace.h>
25*69074Sbostic 
26*69074Sbostic #include <err.h>
2745987Sbostic #include <stdio.h>
28*69074Sbostic #include <unistd.h>
29*69074Sbostic 
3036462Smarc #include "ktrace.h"
3136426Smarc 
32*69074Sbostic void no_ktrace __P((int));
33*69074Sbostic void usage __P((void));
34*69074Sbostic 
main(argc,argv)3536426Smarc main(argc, argv)
3645987Sbostic 	int argc;
3745987Sbostic 	char **argv;
3836426Smarc {
3945987Sbostic 	enum { NOTSET, CLEAR, CLEARALL } clear;
4045987Sbostic 	int append, ch, fd, inherit, ops, pid, pidset, trpoints;
4145987Sbostic 	char *tracefile;
4236426Smarc 
4345987Sbostic 	clear = NOTSET;
4453174Smarc 	append = ops = pidset = inherit = 0;
4553171Smarc 	trpoints = DEF_POINTS;
4645987Sbostic 	tracefile = DEF_TRACEFILE;
4745987Sbostic 	while ((ch = getopt(argc,argv,"aCcdf:g:ip:t:")) != EOF)
4836426Smarc 		switch((char)ch) {
4945987Sbostic 		case 'a':
5045987Sbostic 			append = 1;
5145987Sbostic 			break;
5240361Smarc 		case 'C':
5345987Sbostic 			clear = CLEARALL;
5447026Smarc 			pidset = 1;
5540361Smarc 			break;
5640361Smarc 		case 'c':
5745987Sbostic 			clear = CLEAR;
5840361Smarc 			break;
5940361Smarc 		case 'd':
6040361Smarc 			ops |= KTRFLAG_DESCEND;
6140361Smarc 			break;
6245987Sbostic 		case 'f':
6345987Sbostic 			tracefile = optarg;
6440361Smarc 			break;
6540361Smarc 		case 'g':
6645987Sbostic 			pid = -rpid(optarg);
6745987Sbostic 			pidset = 1;
6840361Smarc 			break;
6940361Smarc 		case 'i':
7045987Sbostic 			inherit = 1;
7140361Smarc 			break;
7245987Sbostic 		case 'p':
7345987Sbostic 			pid = rpid(optarg);
7445987Sbostic 			pidset = 1;
7540361Smarc 			break;
7645987Sbostic 		case 't':
7745987Sbostic 			trpoints = getpoints(optarg);
7845987Sbostic 			if (trpoints < 0) {
79*69074Sbostic 				warnx("unknown facility in %s", optarg);
8045987Sbostic 				usage();
8145987Sbostic 			}
8240361Smarc 			break;
8340361Smarc 		default:
8445987Sbostic 			usage();
8536426Smarc 		}
8645987Sbostic 	argv += optind;
8745987Sbostic 	argc -= optind;
8836426Smarc 
8945987Sbostic 	if (pidset && *argv || !pidset && !*argv)
9045987Sbostic 		usage();
9145987Sbostic 
9240361Smarc 	if (inherit)
9344584Smarc 		trpoints |= KTRFAC_INHERIT;
9445987Sbostic 
95*69074Sbostic 	(void)signal(SIGSYS, no_ktrace);
9645987Sbostic 	if (clear != NOTSET) {
9745987Sbostic 		if (clear == CLEARALL) {
9840361Smarc 			ops = KTROP_CLEAR | KTRFLAG_DESCEND;
9953171Smarc 			trpoints = ALL_POINTS;
10040361Smarc 			pid = 1;
10145987Sbostic 		} else
10240361Smarc 			ops |= pid ? KTROP_CLEAR : KTROP_CLEARFILE;
10345987Sbostic 
10445987Sbostic 		if (ktrace(tracefile, ops, trpoints, pid) < 0)
105*69074Sbostic 			err(1, tracefile);
10636426Smarc 		exit(0);
10736426Smarc 	}
10836462Smarc 
10945987Sbostic 	if ((fd = open(tracefile, O_CREAT | O_WRONLY | (append ? 0 : O_TRUNC),
11045987Sbostic 	    DEFFILEMODE)) < 0)
111*69074Sbostic 		err(1, tracefile);
11245987Sbostic 	(void)close(fd);
11345987Sbostic 
11445987Sbostic 	if (*argv) {
11545987Sbostic 		if (ktrace(tracefile, ops, trpoints, getpid()) < 0)
116*69074Sbostic 			err(1, tracefile);
11745987Sbostic 		execvp(argv[0], &argv[0]);
118*69074Sbostic 		err(1, "exec of '%s' failed", argv[0]);
11936462Smarc 	}
12045987Sbostic 	else if (ktrace(tracefile, ops, trpoints, pid) < 0)
121*69074Sbostic 		err(1, tracefile);
12236426Smarc 	exit(0);
12336426Smarc }
12445987Sbostic 
rpid(p)12545987Sbostic rpid(p)
12645987Sbostic 	char *p;
12745987Sbostic {
12845987Sbostic 	static int first;
12945987Sbostic 
13045987Sbostic 	if (first++) {
131*69074Sbostic 		warnx("only one -g or -p flag is permitted.");
13245987Sbostic 		usage();
13345987Sbostic 	}
13445987Sbostic 	if (!*p) {
135*69074Sbostic 		warnx("illegal process id.");
13645987Sbostic 		usage();
13745987Sbostic 	}
13845987Sbostic 	return(atoi(p));
13945987Sbostic }
14045987Sbostic 
141*69074Sbostic void
usage()14245987Sbostic usage()
14345987Sbostic {
14445987Sbostic 	(void)fprintf(stderr,
14545987Sbostic "usage:\tktrace [-aCcid] [-f trfile] [-g pgid] [-p pid] [-t [acgn]\n\tktrace [-aCcid] [-f trfile] [-t [acgn] command\n");
14645987Sbostic 	exit(1);
14745987Sbostic }
148*69074Sbostic 
149*69074Sbostic void
no_ktrace(sig)150*69074Sbostic no_ktrace(sig)
151*69074Sbostic         int sig;
152*69074Sbostic {
153*69074Sbostic         (void)fprintf(stderr,
154*69074Sbostic "error:\tktrace() system call not supported in the running kernel\n\tre-compile kernel with 'options KTRACE'\n");
155*69074Sbostic         exit(1);
156*69074Sbostic }
157