144584Smarc /*- 236426Smarc * Copyright (c) 1988 The Regents of the University of California. 336426Smarc * All rights reserved. 436426Smarc * 544584Smarc * %sccs.include.redist.c% 636426Smarc */ 736426Smarc 836426Smarc #ifndef lint 936426Smarc char copyright[] = 1036426Smarc "@(#) Copyright (c) 1988 The Regents of the University of California.\n\ 1136426Smarc All rights reserved.\n"; 1236426Smarc #endif /* not lint */ 1336426Smarc 1436426Smarc #ifndef lint 15*45987Sbostic static char sccsid[] = "@(#)ktrace.c 5.1 (Berkeley) 01/17/91"; 1636426Smarc #endif /* not lint */ 1736426Smarc 18*45987Sbostic #include <sys/param.h> 19*45987Sbostic #include <sys/stat.h> 20*45987Sbostic #include <sys/file.h> 21*45987Sbostic #include <sys/time.h> 22*45987Sbostic #include <sys/errno.h> 23*45987Sbostic #include <sys/uio.h> 24*45987Sbostic #include <sys/ktrace.h> 25*45987Sbostic #include <stdio.h> 2636462Smarc #include "ktrace.h" 2736426Smarc 2836426Smarc main(argc, argv) 29*45987Sbostic int argc; 30*45987Sbostic char **argv; 3136426Smarc { 3236426Smarc extern int optind; 3336426Smarc extern char *optarg; 34*45987Sbostic enum { NOTSET, CLEAR, CLEARALL } clear; 35*45987Sbostic int append, ch, fd, inherit, ops, pid, pidset, trpoints; 36*45987Sbostic char *tracefile; 3736426Smarc 38*45987Sbostic clear = NOTSET; 39*45987Sbostic append = ops = pidset = 0; 40*45987Sbostic trpoints = ALL_POINTS; 41*45987Sbostic tracefile = DEF_TRACEFILE; 42*45987Sbostic while ((ch = getopt(argc,argv,"aCcdf:g:ip:t:")) != EOF) 4336426Smarc switch((char)ch) { 44*45987Sbostic case 'a': 45*45987Sbostic append = 1; 46*45987Sbostic break; 4740361Smarc case 'C': 48*45987Sbostic clear = CLEARALL; 4940361Smarc break; 5040361Smarc case 'c': 51*45987Sbostic clear = CLEAR; 5240361Smarc break; 5340361Smarc case 'd': 5440361Smarc ops |= KTRFLAG_DESCEND; 5540361Smarc break; 56*45987Sbostic case 'f': 57*45987Sbostic tracefile = optarg; 5840361Smarc break; 5940361Smarc case 'g': 60*45987Sbostic pid = -rpid(optarg); 61*45987Sbostic pidset = 1; 6240361Smarc break; 6340361Smarc case 'i': 64*45987Sbostic inherit = 1; 6540361Smarc break; 66*45987Sbostic case 'p': 67*45987Sbostic pid = rpid(optarg); 68*45987Sbostic pidset = 1; 6940361Smarc break; 70*45987Sbostic case 't': 71*45987Sbostic trpoints = getpoints(optarg); 72*45987Sbostic if (trpoints < 0) { 73*45987Sbostic (void)fprintf(stderr, 74*45987Sbostic "ktrace: unknown facility in %s\n", optarg); 75*45987Sbostic usage(); 76*45987Sbostic } 7740361Smarc break; 7840361Smarc default: 79*45987Sbostic usage(); 8036426Smarc } 81*45987Sbostic argv += optind; 82*45987Sbostic argc -= optind; 8336426Smarc 84*45987Sbostic if (pidset && *argv || !pidset && !*argv) 85*45987Sbostic usage(); 86*45987Sbostic 8740361Smarc if (inherit) 8844584Smarc trpoints |= KTRFAC_INHERIT; 89*45987Sbostic 90*45987Sbostic if (clear != NOTSET) { 91*45987Sbostic if (clear == CLEARALL) { 9240361Smarc ops = KTROP_CLEAR | KTRFLAG_DESCEND; 9340361Smarc pid = 1; 94*45987Sbostic } else 9540361Smarc ops |= pid ? KTROP_CLEAR : KTROP_CLEARFILE; 96*45987Sbostic 97*45987Sbostic if (ktrace(tracefile, ops, trpoints, pid) < 0) 98*45987Sbostic error(tracefile); 9936426Smarc exit(0); 10036426Smarc } 10136462Smarc 102*45987Sbostic if ((fd = open(tracefile, O_CREAT | O_WRONLY | (append ? 0 : O_TRUNC), 103*45987Sbostic DEFFILEMODE)) < 0) 104*45987Sbostic error(tracefile); 105*45987Sbostic (void)close(fd); 106*45987Sbostic 107*45987Sbostic if (*argv) { 108*45987Sbostic if (ktrace(tracefile, ops, trpoints, getpid()) < 0) 109*45987Sbostic error(); 110*45987Sbostic execvp(argv[0], &argv[0]); 111*45987Sbostic error(argv[0]); 11236462Smarc exit(1); 11336462Smarc } 114*45987Sbostic else if (ktrace(tracefile, ops, trpoints, pid) < 0) 115*45987Sbostic error(tracefile); 11636426Smarc exit(0); 11736426Smarc } 118*45987Sbostic 119*45987Sbostic rpid(p) 120*45987Sbostic char *p; 121*45987Sbostic { 122*45987Sbostic static int first; 123*45987Sbostic 124*45987Sbostic if (first++) { 125*45987Sbostic (void)fprintf(stderr, 126*45987Sbostic "ktrace: only one -g or -p flag is permitted.\n"); 127*45987Sbostic usage(); 128*45987Sbostic } 129*45987Sbostic if (!*p) { 130*45987Sbostic (void)fprintf(stderr, "ktrace: illegal process id.\n"); 131*45987Sbostic usage(); 132*45987Sbostic } 133*45987Sbostic return(atoi(p)); 134*45987Sbostic } 135*45987Sbostic 136*45987Sbostic error(name) 137*45987Sbostic char *name; 138*45987Sbostic { 139*45987Sbostic (void)fprintf(stderr, "ktrace: %s: %s.\n", name, strerror(errno)); 140*45987Sbostic exit(1); 141*45987Sbostic } 142*45987Sbostic 143*45987Sbostic usage() 144*45987Sbostic { 145*45987Sbostic (void)fprintf(stderr, 146*45987Sbostic "usage:\tktrace [-aCcid] [-f trfile] [-g pgid] [-p pid] [-t [acgn]\n\tktrace [-aCcid] [-f trfile] [-t [acgn] command\n"); 147*45987Sbostic exit(1); 148*45987Sbostic } 149