⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 trace.c

📁 <B>Digital的Unix操作系统VAX 4.2源码</B>
💻 C
字号:
#ifndef lintstatic char *sccsid = "@(#)trace.c	4.1	ULTRIX	7/17/90";#endif lint/************************************************************************ *									* *			Copyright (c) 1986 by				* *		Digital Equipment Corporation, Maynard, MA		* *			All rights reserved.				* *									* *   This software is furnished under a license and may be used and	* *   copied  only  in accordance with the terms of such license and	* *   with the  inclusion  of  the  above  copyright  notice.   This	* *   software  or  any  other copies thereof may not be provided or	* *   otherwise made available to any other person.  No title to and	* *   ownership of the software is hereby transferred.			* *									* *   This software is  derived  from  software  received  from  the	* *   University    of   California,   Berkeley,   and   from   Bell	* *   Laboratories.  Use, duplication, or disclosure is  subject  to	* *   restrictions  under  license  agreements  with  University  of	* *   California and with AT&T.						* *									* *   The information in this software is subject to change  without	* *   notice  and should not be construed as a commitment by Digital	* *   Equipment Corporation.						* *									* *   Digital assumes no responsibility for the use  or  reliability	* *   of its software on equipment which is not supplied by Digital.	* *									* ************************************************************************//* *	System Call Tracer User Interface Routine - Robert Rodriguez * *	EDIT HISTORY: *	09-Jun-1988  Mark Parenti *		Changed signal handlers to void. * *	15-Jan-1987  Marc Teitelbaum *		Add ability to send trace info to stdout in real time *		by specifying "-" to -f option.  In this mode, trace *		polls the trace buffer rather than waiting for select *		to wake us up - somewhat analagous to doing a "tail -f" *		on a growing file. */#include <stdio.h>#include <strings.h>#include <sys/ioctl.h>#include <sys/param.h>#include <sys/file.h>#include <sys/time.h>#include <sys/systrace.h>int loop_cnt = 0, pid ,bad_read = -1;void onterm(), onintr();char *usage=  "Usage: trace [-f filename ] [-c|-g|-p|-s|-u]#,#,...# cmd args args\n";extern void sleep(),perror(),exit();main(argc,argv)char **argv;{	register int fd,fd_out,i=0;	register char *filename, *cmd;	int pgrp[TR_PGRP],pids[TR_PIDS],uids[TR_UIDS],sysc[TR_SYSC];	int cflag=0,gflag=0,pflag=0,sflag=0,uflag=0,zflag=0;	int poll = 0;  /* poll trace buffer rather than use select */	char buf[MAXBSIZE];	char cmdbuf[BUFSIZ];	int c,errflg=0,cpid,readfds;	extern int optind;	extern char *optarg;	filename = "trace.dump";	/* default output file name */	while (( c=getopt(argc,argv,"c:f:g:p:s:u:z")) != EOF) {		switch (c) {		case 'c':	/* child flag */			cpid = atoi(optarg);			cflag++;			break;		case 'f':	/* file flag */			filename = optarg;			break;		case 'g':	/* pgrp flag */			gflag++;			getcommalist(optarg,pgrp,TR_PGRP);			break;		case 'p':	/* pid flag */			pflag++;			getcommalist(optarg,pids,TR_PIDS);			break;		case 's':	/* syscall flag */			sflag++;			getcommalist(optarg,sysc,TR_SYSC);			break;		case 'u':	/* uid flag */			uflag++;			getcommalist(optarg,uids,TR_UIDS);			break;		case 'z':			zflag++;			break;		case '?':			errflg++;		}	}	if (errflg) {		(void)fprintf(stderr,usage);		exit(1);	}	if (zflag) {		(void)fprintf(stderr,"Logfile = %s\n",filename);	}	if (cflag && zflag) {		(void)fprintf(stderr,"cflag = %d\ncpid %d, ",cflag,cpid);		(void)fprintf(stderr,"pgrp = %d\n",getpgrp(cpid));	}	if (gflag && zflag) {		(void)fprintf(stderr,"gflag = %d\npgrp\t",gflag);		for(i=0;i<TR_PGRP;i++) (void)fprintf(stderr,"%d ",pgrp[i]);		(void)fprintf(stderr,"\n");	}	if (pflag && zflag) {		(void)fprintf(stderr,"pflag = %d\npids\t",pflag);		for(i=0;i<TR_PIDS;i++) (void)fprintf(stderr,"%d ",pids[i]);		(void)fprintf(stderr,"\n");	}	if (sflag && zflag) {		(void)fprintf(stderr,"sflag = %d\nsysc\t",sflag);		for(i=0;i<TR_SYSC;i++) (void)fprintf(stderr,"%d ",sysc[i]);		(void)fprintf(stderr,"\n");	}	if (uflag && zflag) {		(void)fprintf(stderr,"uflag = %d\nuids\t",uflag);		for(i=0;i<TR_UIDS;i++) (void)fprintf(stderr,"%d ",uids[i]);		(void)fprintf(stderr,"\n");	}	/* the rest of the args form the command */	cmd = cmdbuf;	*cmd = '\0';	for (i=optind;i<argc;i++) {		(void) strcat(cmd,argv[i]);		(void) strcat(cmd," ");	}	if (zflag) {		(void)fprintf(stderr,			"argc = %d, optind = %d, cmd = %s\n",argc,optind,cmd);		exit(0);	}	if (strcmp(filename,"-") == 0) {		/* send output to stdout */		fd_out=1;		/* and poll buffer every second rather than wait for select */		poll=1; 	} else {		fd_out = open(filename,O_WRONLY|O_CREAT|O_TRUNC,0666);		if (fd_out < 0) {			(void)fprintf(stderr,"Can't open %s\n",filename);			exit(2);		}	}	pid = getpid();	if ((int)signal(15,onterm) == -1 || (int)signal(2,onintr) == -1) {		(void) perror("signal");		exit(3);	}	fd = open("/dev/trace",0);	if (fd < 0) {		(void)fprintf(stderr,"Can't open /dev/trace\n");		exit(4);	}	if (gflag+pflag+sflag+uflag == 0 && *cmd != '\0') {		/* no flags -- just do the command */		pgrp[0] = dofork(cmd);		for (i=1;i<TR_PGRP;i++) pgrp[i] = 0;		i = ioctl(fd,IOTR_SETPGRP,(char *)pgrp);	}	else {		/* here is where we do each flag option */		if (cflag) {			pgrp[0] = getpgrp(cpid);			for (i=1;i<TR_PGRP;i++) pgrp[i] = 0;			i = ioctl(fd,IOTR_SETPGRP,(char *)pgrp);		}		else if (gflag) {			i = ioctl(fd,IOTR_SETPGRP,(char *)pgrp);		}		else if (pflag) {			i = ioctl(fd,IOTR_SETPIDS,(char *)pids);		}		else if (sflag) {			i = ioctl(fd,IOTR_SETSYSC,(char *)sysc);		}		else if (uflag) {			i = ioctl(fd,IOTR_SETUIDS,(char *)uids);		}		else {			/* can't get here!!! */			(void)fprintf(stderr,"options not yet implemented\n");			exit(5);		}	}	/*	 *	We take a lot of care to be sure we get all the records	 *	of a trace. When the command exits we will get the termination	 *	signal or the user sends us the termination signal or the	 *	interrupt signal. To handle all cases, we want to do 2 reads	 *	to be sure we got all the data back.	 */	while (1) {		if (bad_read == 0) loop_cnt++;		if (loop_cnt > 2) break;	/* after signal and 2 tries */		if (loop_cnt == 0) {			/* once the signal has been received  */			/* this loop is not done */			if (!poll) {  /* normal case */				readfds = 1<<fd;				i = select(32,&readfds,(int *)0,(int *)0,						(struct timeval *) 0);				if (i == -1 && bad_read == -1) {					(void) perror("select");					break;				}			}		}		if (readfds & (1<<fd) || loop_cnt > 0 || poll) {			/* this loop is done only if the select returned */			/* for the /dev/trace fiel descriptor or if the */			/* signal reset bad_read and thus bumped loop_cnt */			/* - or if we are polling buffer		*/			i = read(fd,buf,sizeof(buf));			if (i > 0) {				if (write(fd_out,buf,i) != i) {					(void) perror("write");				}			}			if (i <= bad_read) break;			/* bad_read is -1 to start, 0 after we get a signal */		}		/* sleep a second if polling buffer */		if (loop_cnt == 0 && poll)			sleep(1);	}	i = close(fd);	exit(0);}getcommalist(string,array,size)	/* parse comma separated list of numbers */register char *string;register int *array;register int size;{	register int i;	register char *ptr;	ptr = string;	for(i=0;i<size;i++) {		if (*ptr != NULL) {			array[i] = atoi(ptr);			/* negatives not allowed */			if (array[i] < 0) array[i] = 0;			while(*ptr!=',' && *ptr != NULL) ptr++;			while(*ptr==',') ptr++;		}		else array[i] = 0;	}}voidonterm()  /* when child sends sigterm a zero read is bad */{	(void) signal(15,SIG_IGN);	(void) signal(2,SIG_IGN);	bad_read = 0;}voidonintr()  /* when we receive sigint a zero read is bad */{	(void) signal(2,SIG_IGN);	(void) signal(15,SIG_IGN);	bad_read = 0;}dofork(cmd)register char *cmd;{	register int forkpid;	if ((forkpid = fork())==0) {  /* child */		(void) sleep((unsigned)2);			/* sleep to let parent set up for trace */		forkpid = getpid();		(void) setpgrp(forkpid,forkpid);   /* set pgrp for tracing */		(void) system(cmd);	/* do command */		(void) kill(pid,15);	/* tell parent no more tracing to do */		exit(0);	}	return forkpid;	/* give back pgrp to trace */}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -