xref: /original-bsd/usr.bin/time/time.c (revision b7261a4b)
1 /*
2  * Copyright (c) 1987, 1988 The Regents of the University of California.
3  * All rights reserved.
4  *
5  * %sccs.include.redist.c%
6  */
7 
8 #ifndef lint
9 char copyright[] =
10 "@(#) Copyright (c) 1987, 1988 The Regents of the University of California.\n\
11  All rights reserved.\n";
12 #endif /* not lint */
13 
14 #ifndef lint
15 static char sccsid[] = "@(#)time.c	4.9 (Berkeley) 06/01/90";
16 #endif /* not lint */
17 
18 #include <sys/types.h>
19 #include <sys/time.h>
20 #include <sys/resource.h>
21 #include <sys/signal.h>
22 #include <stdio.h>
23 
24 main(argc, argv)
25 	int argc;
26 	char **argv;
27 {
28 	extern int optind;
29 	register int pid;
30 	int ch, status, lflag;
31 	struct timeval before, after;
32 	struct rusage ru;
33 
34 	lflag = 0;
35 	while ((ch = getopt(argc, argv, "l")) != EOF)
36 		switch((char)ch) {
37 		case 'l':
38 			lflag = 1;
39 			break;
40 		case '?':
41 		default:
42 			fprintf(stderr, "usage: time [-l] command.\n");
43 			exit(1);
44 		}
45 
46 	if (!(argc -= optind))
47 		exit(0);
48 	argv += optind;
49 
50 	gettimeofday(&before, (struct timezone *)NULL);
51 	switch(pid = vfork()) {
52 	case -1:			/* error */
53 		perror("time");
54 		exit(1);
55 		/* NOTREACHED */
56 	case 0:				/* child */
57 		execvp(*argv, argv);
58 		perror(*argv);
59 		_exit(1);
60 		/* NOTREACHED */
61 	}
62 	/* parent */
63 	(void)signal(SIGINT, SIG_IGN);
64 	(void)signal(SIGQUIT, SIG_IGN);
65 	while (wait3(&status, 0, &ru) != pid);		/* XXX use waitpid */
66 	gettimeofday(&after, (struct timezone *)NULL);
67 	if (status&0377)
68 		fprintf(stderr, "Command terminated abnormally.\n");
69 	after.tv_sec -= before.tv_sec;
70 	after.tv_usec -= before.tv_usec;
71 	if (after.tv_usec < 0)
72 		after.tv_sec--, after.tv_usec += 1000000;
73 	fprintf(stderr, "%9ld.%02ld real ", after.tv_sec, after.tv_usec/10000);
74 	fprintf(stderr, "%9ld.%02ld user ",
75 	    ru.ru_utime.tv_sec, ru.ru_utime.tv_usec/10000);
76 	fprintf(stderr, "%9ld.%02ld sys\n",
77 	    ru.ru_stime.tv_sec, ru.ru_stime.tv_usec/10000);
78 	if (lflag) {
79 		int hz = 100;			/* XXX */
80 		long ticks;
81 
82 		ticks = hz * (ru.ru_utime.tv_sec + ru.ru_stime.tv_sec) +
83 		     hz * (ru.ru_utime.tv_usec + ru.ru_stime.tv_usec) / 1000000;
84 		fprintf(stderr, "%10ld  %s\n",
85 			ru.ru_maxrss, "maximum resident set size");
86 		fprintf(stderr, "%10ld  %s\n",
87 			ru.ru_ixrss / ticks, "average shared memory size");
88 		fprintf(stderr, "%10ld  %s\n",
89 			ru.ru_idrss / ticks, "average unshared data size");
90 		fprintf(stderr, "%10ld  %s\n",
91 			ru.ru_isrss / ticks, "average unshared stack size");
92 		fprintf(stderr, "%10ld  %s\n",
93 			ru.ru_minflt, "page reclaims");
94 		fprintf(stderr, "%10ld  %s\n",
95 			ru.ru_majflt, "page faults");
96 		fprintf(stderr, "%10ld  %s\n",
97 			ru.ru_nswap, "swaps");
98 		fprintf(stderr, "%10ld  %s\n",
99 			ru.ru_inblock, "block input operations");
100 		fprintf(stderr, "%10ld  %s\n",
101 			ru.ru_oublock, "block output operations");
102 		fprintf(stderr, "%10ld  %s\n",
103 			ru.ru_msgsnd, "messages sent");
104 		fprintf(stderr, "%10ld  %s\n",
105 			ru.ru_msgrcv, "messages received");
106 		fprintf(stderr, "%10ld  %s\n",
107 			ru.ru_nsignals, "signals received");
108 		fprintf(stderr, "%10ld  %s\n",
109 			ru.ru_nvcsw, "voluntary context switches");
110 		fprintf(stderr, "%10ld  %s\n",
111 			ru.ru_nivcsw, "involuntary context switches");
112 	}
113 	exit (status>>8);
114 }
115