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.2 (Berkeley) 04/28/95"; 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 26 #include <err.h> 27 #include <stdio.h> 28 #include <unistd.h> 29 30 #include "ktrace.h" 31 32 void no_ktrace __P((int)); 33 void usage __P((void)); 34 35 main(argc, argv) 36 int argc; 37 char **argv; 38 { 39 enum { NOTSET, CLEAR, CLEARALL } clear; 40 int append, ch, fd, inherit, ops, pid, pidset, trpoints; 41 char *tracefile; 42 43 clear = NOTSET; 44 append = ops = pidset = inherit = 0; 45 trpoints = DEF_POINTS; 46 tracefile = DEF_TRACEFILE; 47 while ((ch = getopt(argc,argv,"aCcdf:g:ip:t:")) != EOF) 48 switch((char)ch) { 49 case 'a': 50 append = 1; 51 break; 52 case 'C': 53 clear = CLEARALL; 54 pidset = 1; 55 break; 56 case 'c': 57 clear = CLEAR; 58 break; 59 case 'd': 60 ops |= KTRFLAG_DESCEND; 61 break; 62 case 'f': 63 tracefile = optarg; 64 break; 65 case 'g': 66 pid = -rpid(optarg); 67 pidset = 1; 68 break; 69 case 'i': 70 inherit = 1; 71 break; 72 case 'p': 73 pid = rpid(optarg); 74 pidset = 1; 75 break; 76 case 't': 77 trpoints = getpoints(optarg); 78 if (trpoints < 0) { 79 warnx("unknown facility in %s", optarg); 80 usage(); 81 } 82 break; 83 default: 84 usage(); 85 } 86 argv += optind; 87 argc -= optind; 88 89 if (pidset && *argv || !pidset && !*argv) 90 usage(); 91 92 if (inherit) 93 trpoints |= KTRFAC_INHERIT; 94 95 (void)signal(SIGSYS, no_ktrace); 96 if (clear != NOTSET) { 97 if (clear == CLEARALL) { 98 ops = KTROP_CLEAR | KTRFLAG_DESCEND; 99 trpoints = ALL_POINTS; 100 pid = 1; 101 } else 102 ops |= pid ? KTROP_CLEAR : KTROP_CLEARFILE; 103 104 if (ktrace(tracefile, ops, trpoints, pid) < 0) 105 err(1, tracefile); 106 exit(0); 107 } 108 109 if ((fd = open(tracefile, O_CREAT | O_WRONLY | (append ? 0 : O_TRUNC), 110 DEFFILEMODE)) < 0) 111 err(1, tracefile); 112 (void)close(fd); 113 114 if (*argv) { 115 if (ktrace(tracefile, ops, trpoints, getpid()) < 0) 116 err(1, tracefile); 117 execvp(argv[0], &argv[0]); 118 err(1, "exec of '%s' failed", argv[0]); 119 } 120 else if (ktrace(tracefile, ops, trpoints, pid) < 0) 121 err(1, tracefile); 122 exit(0); 123 } 124 125 rpid(p) 126 char *p; 127 { 128 static int first; 129 130 if (first++) { 131 warnx("only one -g or -p flag is permitted."); 132 usage(); 133 } 134 if (!*p) { 135 warnx("illegal process id."); 136 usage(); 137 } 138 return(atoi(p)); 139 } 140 141 void 142 usage() 143 { 144 (void)fprintf(stderr, 145 "usage:\tktrace [-aCcid] [-f trfile] [-g pgid] [-p pid] [-t [acgn]\n\tktrace [-aCcid] [-f trfile] [-t [acgn] command\n"); 146 exit(1); 147 } 148 149 void 150 no_ktrace(sig) 151 int sig; 152 { 153 (void)fprintf(stderr, 154 "error:\tktrace() system call not supported in the running kernel\n\tre-compile kernel with 'options KTRACE'\n"); 155 exit(1); 156 } 157