time.c revision 11873
183553Smurray/*
283553Smurray * Copyright (c) 1987, 1988, 1993
383553Smurray *	The Regents of the University of California.  All rights reserved.
483553Smurray *
583553Smurray * Redistribution and use in source and binary forms, with or without
683553Smurray * modification, are permitted provided that the following conditions
783553Smurray * are met:
883553Smurray * 1. Redistributions of source code must retain the above copyright
983553Smurray *    notice, this list of conditions and the following disclaimer.
1083553Smurray * 2. Redistributions in binary form must reproduce the above copyright
1183553Smurray *    notice, this list of conditions and the following disclaimer in the
1283553Smurray *    documentation and/or other materials provided with the distribution.
1383553Smurray * 3. All advertising materials mentioning features or use of this software
1483553Smurray *    must display the following acknowledgement:
1583553Smurray *	This product includes software developed by the University of
1683553Smurray *	California, Berkeley and its contributors.
1783553Smurray * 4. Neither the name of the University nor the names of its contributors
1883553Smurray *    may be used to endorse or promote products derived from this software
1983553Smurray *    without specific prior written permission.
2083553Smurray *
2183553Smurray * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
2283553Smurray * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
2383553Smurray * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
2483553Smurray * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
2583553Smurray * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
2683553Smurray * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
2783553Smurray * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28153942Sbrueffer * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29203692Sgavin * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
3083553Smurray * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
3183553Smurray * SUCH DAMAGE.
3283553Smurray */
33153942Sbrueffer
3483553Smurray#ifndef lint
3583553Smurraystatic char copyright[] =
3683553Smurray"@(#) Copyright (c) 1987, 1988, 1993\n\
3783553Smurray	The Regents of the University of California.  All rights reserved.\n";
3883553Smurray#endif /* not lint */
39153942Sbrueffer
40153942Sbrueffer#ifndef lint
41153942Sbruefferstatic char sccsid[] = "@(#)time.c	8.1 (Berkeley) 6/6/93";
42153942Sbrueffer#endif /* not lint */
43153942Sbrueffer
44153942Sbrueffer#include <sys/types.h>
4583553Smurray#include <sys/time.h>
4683553Smurray#include <sys/resource.h>
4783553Smurray#include <sys/signal.h>
4883553Smurray#include <stdio.h>
4983553Smurray
5083553Smurraymain(argc, argv)
5183553Smurray	int argc;
5283553Smurray	char **argv;
53153942Sbrueffer{
54306114Savg	extern int optind;
5583553Smurray	register int pid;
5683553Smurray	int ch, status, lflag;
5783553Smurray	struct timeval before, after;
5883553Smurray	struct rusage ru;
5983553Smurray
6083553Smurray	lflag = 0;
6192137Smurray	while ((ch = getopt(argc, argv, "l")) != EOF)
6283553Smurray		switch((char)ch) {
63131530Sru		case 'l':
64131530Sru			lflag = 1;
65131530Sru			break;
6685405Sru		case '?':
6785405Sru		default:
6883553Smurray			fprintf(stderr, "usage: time [-l] command.\n");
6983553Smurray			exit(1);
7083553Smurray		}
71267938Sbapt
7283553Smurray	if (!(argc -= optind))
7383553Smurray		exit(0);
74	argv += optind;
75
76	gettimeofday(&before, (struct timezone *)NULL);
77	switch(pid = vfork()) {
78	case -1:			/* error */
79		perror("time");
80		exit(1);
81		/* NOTREACHED */
82	case 0:				/* child */
83		execvp(*argv, argv);
84		perror(*argv);
85		_exit(1);
86		/* NOTREACHED */
87	}
88	/* parent */
89	(void)signal(SIGINT, SIG_IGN);
90	(void)signal(SIGQUIT, SIG_IGN);
91	while (wait3(&status, 0, &ru) != pid);		/* XXX use waitpid */
92	gettimeofday(&after, (struct timezone *)NULL);
93	if (status&0377)
94		fprintf(stderr, "Command terminated abnormally.\n");
95	after.tv_sec -= before.tv_sec;
96	after.tv_usec -= before.tv_usec;
97	if (after.tv_usec < 0)
98		after.tv_sec--, after.tv_usec += 1000000;
99	fprintf(stderr, "%9ld.%02ld real ", after.tv_sec, after.tv_usec/10000);
100	fprintf(stderr, "%9ld.%02ld user ",
101	    ru.ru_utime.tv_sec, ru.ru_utime.tv_usec/10000);
102	fprintf(stderr, "%9ld.%02ld sys\n",
103	    ru.ru_stime.tv_sec, ru.ru_stime.tv_usec/10000);
104	if (lflag) {
105		int hz = 100;			/* XXX */
106		u_long ticks;
107
108		ticks = hz * (ru.ru_utime.tv_sec + ru.ru_stime.tv_sec) +
109		     hz * (ru.ru_utime.tv_usec + ru.ru_stime.tv_usec) / 1000000;
110
111		/*
112		 * If our round-off on the tick calculation still puts us at 0,
113		 * then always assume at least one tick.
114		 */
115		if (ticks == 0)
116			ticks = 1;
117
118		fprintf(stderr, "%10ld  %s\n",
119			ru.ru_maxrss, "maximum resident set size");
120		fprintf(stderr, "%10ld  %s\n",
121			ru.ru_ixrss / ticks, "average shared memory size");
122		fprintf(stderr, "%10ld  %s\n",
123			ru.ru_idrss / ticks, "average unshared data size");
124		fprintf(stderr, "%10ld  %s\n",
125			ru.ru_isrss / ticks, "average unshared stack size");
126		fprintf(stderr, "%10ld  %s\n",
127			ru.ru_minflt, "page reclaims");
128		fprintf(stderr, "%10ld  %s\n",
129			ru.ru_majflt, "page faults");
130		fprintf(stderr, "%10ld  %s\n",
131			ru.ru_nswap, "swaps");
132		fprintf(stderr, "%10ld  %s\n",
133			ru.ru_inblock, "block input operations");
134		fprintf(stderr, "%10ld  %s\n",
135			ru.ru_oublock, "block output operations");
136		fprintf(stderr, "%10ld  %s\n",
137			ru.ru_msgsnd, "messages sent");
138		fprintf(stderr, "%10ld  %s\n",
139			ru.ru_msgrcv, "messages received");
140		fprintf(stderr, "%10ld  %s\n",
141			ru.ru_nsignals, "signals received");
142		fprintf(stderr, "%10ld  %s\n",
143			ru.ru_nvcsw, "voluntary context switches");
144		fprintf(stderr, "%10ld  %s\n",
145			ru.ru_nivcsw, "involuntary context switches");
146	}
147	exit (status>>8);
148}
149