1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License, Version 1.0 only 6 * (the "License"). You may not use this file except in compliance 7 * with the License. 8 * 9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10 * or http://www.opensolaris.org/os/licensing. 11 * See the License for the specific language governing permissions 12 * and limitations under the License. 13 * 14 * When distributing Covered Code, include this CDDL HEADER in each 15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16 * If applicable, add the following below this CDDL HEADER, with the 17 * fields enclosed by brackets "[]" replaced with your own identifying 18 * information: Portions Copyright [yyyy] [name of copyright owner] 19 * 20 * CDDL HEADER END 21 */ 22 /* 23 * Copyright 2005 Sun Microsystems, Inc. All rights reserved. 24 * Use is subject to license terms. 25 */ 26 27 /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */ 28 /* All Rights Reserved */ 29 30 /* 31 * Time a command 32 */ 33 34 #include <stdio.h> 35 #include <signal.h> 36 #include <errno.h> 37 #include <stdlib.h> 38 #include <unistd.h> 39 #include <libintl.h> 40 #include <locale.h> 41 #include <limits.h> 42 #include <sys/types.h> 43 #include <sys/times.h> 44 #include <sys/wait.h> 45 46 /* 47 * The following use of HZ/10 will work correctly only if HZ is a multiple 48 * of 10. However the only values for HZ now in use are 100 for the 3B 49 * and 60 for other machines. 50 * 51 * The first value was HZ/10. Since HZ should be gotten from sysconf() 52 * it is dynamically initialized at entry to the main program. 53 */ 54 static clock_t quant[] = { 10, 10, 10, 6, 10, 6, 10, 10, 10 }; 55 static char *pad = "000 "; 56 static char *sep = "\0\0.\0:\0:\0\0"; 57 static char *nsep = "\0\0.\0 \0 \0\0"; 58 59 static void usage(void); 60 static void printt(char *, clock_t); 61 62 int 63 main(int argc, char **argv) 64 { 65 struct tms buffer; 66 pid_t p; 67 int status; 68 int pflag = 0; 69 int c; 70 int clock_tick = CLK_TCK; 71 clock_t before, after; 72 73 (void) setlocale(LC_ALL, ""); 74 #if !defined(TEXT_DOMAIN) 75 #define TEXT_DOMAIN "SYS_TEST" 76 #endif 77 (void) textdomain(TEXT_DOMAIN); 78 79 while ((c = getopt(argc, argv, "p")) != EOF) 80 switch (c) { 81 case 'p': 82 pflag++; 83 break; 84 case '?': 85 usage(); 86 } 87 88 argc -= optind; 89 argv += optind; 90 91 /* 92 * time(1) is only accurate to a tenth of a second. We need to 93 * determine the number of clock ticks in a tenth of a second in 94 * order to later divide away what we don't care about. 95 */ 96 quant[0] = clock_tick/10; 97 98 before = times(&buffer); 99 if (argc < 1) 100 usage(); 101 p = fork(); 102 if (p == (pid_t)-1) { 103 perror("time"); 104 exit(2); 105 } 106 if (p == (pid_t)0) { 107 (void) execvp(argv[0], &argv[0]); 108 perror(argv[0]); 109 if (errno == ENOENT) 110 exit(127); 111 else 112 exit(126); 113 } 114 (void) signal(SIGINT, SIG_IGN); 115 (void) signal(SIGQUIT, SIG_IGN); 116 while (wait(&status) != p); 117 if ((status & 0377) != '\0') 118 (void) fprintf(stderr, "time: %s\n", 119 gettext("command terminated abnormally.")); 120 after = times(&buffer); 121 (void) fprintf(stderr, "\n"); 122 if (pflag) 123 (void) fprintf(stderr, "real %.2f\nuser %.2f\nsys %.2f\n", 124 (double)(after-before)/clock_tick, 125 (double)buffer.tms_cutime/clock_tick, 126 (double)buffer.tms_cstime/clock_tick); 127 else { 128 printt("real", (after-before)); 129 printt("user", buffer.tms_cutime); 130 printt("sys ", buffer.tms_cstime); 131 } 132 133 return ((status & 0xff00) 134 ? (status >> 8) 135 : ((status & 0x00ff) ? ((status & ~WCOREFLG) | 0200) : 0)); 136 } 137 138 139 static void 140 printt(char *s, clock_t a) 141 { 142 int i; 143 char digit[9]; 144 char c; 145 int nonzero; 146 147 a /= quant[0]; /* Divide away the accuracy we don't care about */ 148 149 /* 150 * We now have the number of tenths of seconds elapsed in terms of 151 * ticks. Loop through to determine the actual digits. 152 */ 153 for (i = 1; i < 9; i++) { 154 digit[i] = a % quant[i]; 155 a /= quant[i]; 156 } 157 (void) fprintf(stderr, s); 158 nonzero = 0; 159 while (--i > 0) { 160 c = (digit[i] != 0) ? digit[i]+'0' : (nonzero ? '0': pad[i]); 161 if (c != '\0') 162 (void) putc(c, stderr); 163 nonzero |= digit[i]; 164 c = nonzero?sep[i]:nsep[i]; 165 if (c != '\0') 166 (void) putc(c, stderr); 167 } 168 (void) fprintf(stderr, "\n"); 169 } 170 171 static void 172 usage(void) 173 { 174 (void) fprintf(stderr, 175 gettext("usage: time [-p] utility [argument...]\n")); 176 exit(1); 177 } 178