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