diff options
| author | Denis Vlasenko <vda.linux@googlemail.com> | 2006-12-22 13:43:19 +0000 |
|---|---|---|
| committer | Denis Vlasenko <vda.linux@googlemail.com> | 2006-12-22 13:43:19 +0000 |
| commit | c5cb38f4d9fa90fdd01ea258390d0059138616b5 (patch) | |
| tree | dad37097bc7e7489664f3bc814235aee5f88a146 /miscutils | |
| parent | f93ab47c4560b2a1a3130ac17d0bfb886f09ece8 (diff) | |
| download | busybox-w32-c5cb38f4d9fa90fdd01ea258390d0059138616b5.tar.gz busybox-w32-c5cb38f4d9fa90fdd01ea258390d0059138616b5.tar.bz2 busybox-w32-c5cb38f4d9fa90fdd01ea258390d0059138616b5.zip | |
time: -200 bytes of text
Diffstat (limited to 'miscutils')
| -rw-r--r-- | miscutils/time.c | 180 |
1 files changed, 96 insertions, 84 deletions
diff --git a/miscutils/time.c b/miscutils/time.c index 7682a2679..df10eeb02 100644 --- a/miscutils/time.c +++ b/miscutils/time.c | |||
| @@ -100,18 +100,14 @@ static int resuse_end(pid_t pid, resource_t * resp) | |||
| 100 | return 1; | 100 | return 1; |
| 101 | } | 101 | } |
| 102 | 102 | ||
| 103 | /* Print ARGV to FP, with each entry in ARGV separated by FILLER. */ | 103 | /* Print ARGV, with each entry in ARGV separated by FILLER. */ |
| 104 | static void fprintargv(FILE * fp, char *const *argv, const char *filler) | 104 | static void printargv(char *const *argv, const char *filler) |
| 105 | { | 105 | { |
| 106 | char *const *av; | 106 | fputs(*argv, stdout); |
| 107 | 107 | while (*++argv) { | |
| 108 | av = argv; | 108 | fputs(filler, stdout); |
| 109 | fputs(*av, fp); | 109 | fputs(*argv, stdout); |
| 110 | while (*++av) { | ||
| 111 | fputs(filler, fp); | ||
| 112 | fputs(*av, fp); | ||
| 113 | } | 110 | } |
| 114 | die_if_ferror(fp, "output"); | ||
| 115 | } | 111 | } |
| 116 | 112 | ||
| 117 | /* Return the number of kilobytes corresponding to a number of pages PAGES. | 113 | /* Return the number of kilobytes corresponding to a number of pages PAGES. |
| @@ -124,28 +120,26 @@ static void fprintargv(FILE * fp, char *const *argv, const char *filler) | |||
| 124 | 120 | ||
| 125 | static unsigned long ptok(unsigned long pages) | 121 | static unsigned long ptok(unsigned long pages) |
| 126 | { | 122 | { |
| 127 | static unsigned long ps = 0; | 123 | static unsigned long ps; |
| 128 | unsigned long tmp; | 124 | unsigned long tmp; |
| 129 | static long size = LONG_MAX; | ||
| 130 | 125 | ||
| 131 | /* Initialization. */ | 126 | /* Initialization. */ |
| 132 | if (ps == 0) | 127 | if (ps == 0) |
| 133 | ps = (long) getpagesize(); | 128 | ps = getpagesize(); |
| 134 | 129 | ||
| 135 | /* Conversion. */ | 130 | /* Conversion. */ |
| 136 | if (pages > (LONG_MAX / ps)) { /* Could overflow. */ | 131 | if (pages > (LONG_MAX / ps)) { /* Could overflow. */ |
| 137 | tmp = pages / 1024; /* Smaller first, */ | 132 | tmp = pages / 1024; /* Smaller first, */ |
| 138 | size = tmp * ps; /* then larger. */ | 133 | return tmp * ps; /* then larger. */ |
| 139 | } else { /* Could underflow. */ | ||
| 140 | tmp = pages * ps; /* Larger first, */ | ||
| 141 | size = tmp / 1024; /* then smaller. */ | ||
| 142 | } | 134 | } |
| 143 | return size; | 135 | /* Could underflow. */ |
| 136 | tmp = pages * ps; /* Larger first, */ | ||
| 137 | return tmp / 1024; /* then smaller. */ | ||
| 144 | } | 138 | } |
| 145 | 139 | ||
| 146 | /* summarize: Report on the system use of a command. | 140 | /* summarize: Report on the system use of a command. |
| 147 | 141 | ||
| 148 | Copy the FMT argument to FP except that `%' sequences | 142 | Print the FMT argument except that `%' sequences |
| 149 | have special meaning, and `\n' and `\t' are translated into | 143 | have special meaning, and `\n' and `\t' are translated into |
| 150 | newline and tab, respectively, and `\\' is translated into `\'. | 144 | newline and tab, respectively, and `\\' is translated into `\'. |
| 151 | 145 | ||
| @@ -183,25 +177,23 @@ static unsigned long ptok(unsigned long pages) | |||
| 183 | to kbytes by multiplying by the page size, dividing by 1024, | 177 | to kbytes by multiplying by the page size, dividing by 1024, |
| 184 | and dividing by elapsed real time. | 178 | and dividing by elapsed real time. |
| 185 | 179 | ||
| 186 | FP is the stream to print to. | ||
| 187 | FMT is the format string, interpreted as described above. | 180 | FMT is the format string, interpreted as described above. |
| 188 | COMMAND is the command and args that are being summarized. | 181 | COMMAND is the command and args that are being summarized. |
| 189 | RESP is resource information on the command. */ | 182 | RESP is resource information on the command. */ |
| 190 | 183 | ||
| 191 | static void summarize(FILE * fp, const char *fmt, char **command, | 184 | static void summarize(const char *fmt, char **command, resource_t * resp) |
| 192 | resource_t * resp) | ||
| 193 | { | 185 | { |
| 194 | unsigned long r; /* Elapsed real milliseconds. */ | 186 | unsigned long r; /* Elapsed real milliseconds. */ |
| 195 | unsigned long v; /* Elapsed virtual (CPU) milliseconds. */ | 187 | unsigned long v; /* Elapsed virtual (CPU) milliseconds. */ |
| 196 | 188 | ||
| 197 | if (WIFSTOPPED(resp->waitstatus)) | 189 | if (WIFSTOPPED(resp->waitstatus)) |
| 198 | fprintf(fp, "Command stopped by signal %d\n", | 190 | printf("Command stopped by signal %d\n", |
| 199 | WSTOPSIG(resp->waitstatus)); | 191 | WSTOPSIG(resp->waitstatus)); |
| 200 | else if (WIFSIGNALED(resp->waitstatus)) | 192 | else if (WIFSIGNALED(resp->waitstatus)) |
| 201 | fprintf(fp, "Command terminated by signal %d\n", | 193 | printf("Command terminated by signal %d\n", |
| 202 | WTERMSIG(resp->waitstatus)); | 194 | WTERMSIG(resp->waitstatus)); |
| 203 | else if (WIFEXITED(resp->waitstatus) && WEXITSTATUS(resp->waitstatus)) | 195 | else if (WIFEXITED(resp->waitstatus) && WEXITSTATUS(resp->waitstatus)) |
| 204 | fprintf(fp, "Command exited with non-zero status %d\n", | 196 | printf("Command exited with non-zero status %d\n", |
| 205 | WEXITSTATUS(resp->waitstatus)); | 197 | WEXITSTATUS(resp->waitstatus)); |
| 206 | 198 | ||
| 207 | /* Convert all times to milliseconds. Occasionally, one of these values | 199 | /* Convert all times to milliseconds. Occasionally, one of these values |
| @@ -214,178 +206,194 @@ static void summarize(FILE * fp, const char *fmt, char **command, | |||
| 214 | v = resp->ru.ru_utime.tv_sec * 1000 + resp->ru.ru_utime.TV_MSEC + | 206 | v = resp->ru.ru_utime.tv_sec * 1000 + resp->ru.ru_utime.TV_MSEC + |
| 215 | resp->ru.ru_stime.tv_sec * 1000 + resp->ru.ru_stime.TV_MSEC; | 207 | resp->ru.ru_stime.tv_sec * 1000 + resp->ru.ru_stime.TV_MSEC; |
| 216 | 208 | ||
| 209 | /* putchar() != putc(stdout) in glibc! */ | ||
| 210 | |||
| 217 | while (*fmt) { | 211 | while (*fmt) { |
| 212 | /* Handle leading literal part */ | ||
| 213 | int n = strcspn(fmt, "%\\"); | ||
| 214 | if (n) { | ||
| 215 | printf("%.*s", n, fmt); | ||
| 216 | fmt += n; | ||
| 217 | continue; | ||
| 218 | } | ||
| 219 | |||
| 218 | switch (*fmt) { | 220 | switch (*fmt) { |
| 221 | #ifdef NOT_NEEDED | ||
| 222 | /* Handle literal char */ | ||
| 223 | /* Usually we optimize for size, but there is a limit | ||
| 224 | * for everything. With this we do a lot of 1-byte writes */ | ||
| 225 | default: | ||
| 226 | putc(*fmt, stdout); | ||
| 227 | break; | ||
| 228 | #endif | ||
| 229 | |||
| 219 | case '%': | 230 | case '%': |
| 220 | switch (*++fmt) { | 231 | switch (*++fmt) { |
| 221 | case '%': /* Literal '%'. */ | 232 | #ifdef NOT_NEEDED_YET |
| 222 | putc('%', fp); | 233 | /* Our format strings do not have these */ |
| 234 | /* and we do not take format str from user */ | ||
| 235 | default: | ||
| 236 | putc('%', stdout); | ||
| 237 | /*FALLTHROUGH*/ | ||
| 238 | case '%': | ||
| 239 | if (!*fmt) goto ret; | ||
| 240 | putc(*fmt, stdout); | ||
| 223 | break; | 241 | break; |
| 242 | #endif | ||
| 224 | case 'C': /* The command that got timed. */ | 243 | case 'C': /* The command that got timed. */ |
| 225 | fprintargv(fp, command, " "); | 244 | printargv(command, " "); |
| 226 | break; | 245 | break; |
| 227 | case 'D': /* Average unshared data size. */ | 246 | case 'D': /* Average unshared data size. */ |
| 228 | fprintf(fp, "%lu", | 247 | printf("%lu", |
| 229 | MSEC_TO_TICKS(v) == 0 ? 0 : | 248 | MSEC_TO_TICKS(v) == 0 ? 0 : |
| 230 | ptok((UL) resp->ru.ru_idrss) / MSEC_TO_TICKS(v) + | 249 | ptok((UL) resp->ru.ru_idrss) / MSEC_TO_TICKS(v) + |
| 231 | ptok((UL) resp->ru.ru_isrss) / MSEC_TO_TICKS(v)); | 250 | ptok((UL) resp->ru.ru_isrss) / MSEC_TO_TICKS(v)); |
| 232 | break; | 251 | break; |
| 233 | case 'E': /* Elapsed real (wall clock) time. */ | 252 | case 'E': /* Elapsed real (wall clock) time. */ |
| 234 | if (resp->elapsed.tv_sec >= 3600) /* One hour -> h:m:s. */ | 253 | if (resp->elapsed.tv_sec >= 3600) /* One hour -> h:m:s. */ |
| 235 | fprintf(fp, "%ldh %ldm %02lds", | 254 | printf("%ldh %ldm %02lds", |
| 236 | resp->elapsed.tv_sec / 3600, | 255 | resp->elapsed.tv_sec / 3600, |
| 237 | (resp->elapsed.tv_sec % 3600) / 60, | 256 | (resp->elapsed.tv_sec % 3600) / 60, |
| 238 | resp->elapsed.tv_sec % 60); | 257 | resp->elapsed.tv_sec % 60); |
| 239 | else | 258 | else |
| 240 | fprintf(fp, "%ldm %ld.%02lds", /* -> m:s. */ | 259 | printf("%ldm %ld.%02lds", /* -> m:s. */ |
| 241 | resp->elapsed.tv_sec / 60, | 260 | resp->elapsed.tv_sec / 60, |
| 242 | resp->elapsed.tv_sec % 60, | 261 | resp->elapsed.tv_sec % 60, |
| 243 | resp->elapsed.tv_usec / 10000); | 262 | resp->elapsed.tv_usec / 10000); |
| 244 | break; | 263 | break; |
| 245 | case 'F': /* Major page faults. */ | 264 | case 'F': /* Major page faults. */ |
| 246 | fprintf(fp, "%ld", resp->ru.ru_majflt); | 265 | printf("%ld", resp->ru.ru_majflt); |
| 247 | break; | 266 | break; |
| 248 | case 'I': /* Inputs. */ | 267 | case 'I': /* Inputs. */ |
| 249 | fprintf(fp, "%ld", resp->ru.ru_inblock); | 268 | printf("%ld", resp->ru.ru_inblock); |
| 250 | break; | 269 | break; |
| 251 | case 'K': /* Average mem usage == data+stack+text. */ | 270 | case 'K': /* Average mem usage == data+stack+text. */ |
| 252 | fprintf(fp, "%lu", | 271 | printf("%lu", |
| 253 | MSEC_TO_TICKS(v) == 0 ? 0 : | 272 | MSEC_TO_TICKS(v) == 0 ? 0 : |
| 254 | ptok((UL) resp->ru.ru_idrss) / MSEC_TO_TICKS(v) + | 273 | ptok((UL) resp->ru.ru_idrss) / MSEC_TO_TICKS(v) + |
| 255 | ptok((UL) resp->ru.ru_isrss) / MSEC_TO_TICKS(v) + | 274 | ptok((UL) resp->ru.ru_isrss) / MSEC_TO_TICKS(v) + |
| 256 | ptok((UL) resp->ru.ru_ixrss) / MSEC_TO_TICKS(v)); | 275 | ptok((UL) resp->ru.ru_ixrss) / MSEC_TO_TICKS(v)); |
| 257 | break; | 276 | break; |
| 258 | case 'M': /* Maximum resident set size. */ | 277 | case 'M': /* Maximum resident set size. */ |
| 259 | fprintf(fp, "%lu", ptok((UL) resp->ru.ru_maxrss)); | 278 | printf("%lu", ptok((UL) resp->ru.ru_maxrss)); |
| 260 | break; | 279 | break; |
| 261 | case 'O': /* Outputs. */ | 280 | case 'O': /* Outputs. */ |
| 262 | fprintf(fp, "%ld", resp->ru.ru_oublock); | 281 | printf("%ld", resp->ru.ru_oublock); |
| 263 | break; | 282 | break; |
| 264 | case 'P': /* Percent of CPU this job got. */ | 283 | case 'P': /* Percent of CPU this job got. */ |
| 265 | /* % cpu is (total cpu time)/(elapsed time). */ | 284 | /* % cpu is (total cpu time)/(elapsed time). */ |
| 266 | if (r > 0) | 285 | if (r > 0) |
| 267 | fprintf(fp, "%lu%%", (v * 100 / r)); | 286 | printf("%lu%%", (v * 100 / r)); |
| 268 | else | 287 | else |
| 269 | fprintf(fp, "?%%"); | 288 | printf("?%%"); |
| 270 | break; | 289 | break; |
| 271 | case 'R': /* Minor page faults (reclaims). */ | 290 | case 'R': /* Minor page faults (reclaims). */ |
| 272 | fprintf(fp, "%ld", resp->ru.ru_minflt); | 291 | printf("%ld", resp->ru.ru_minflt); |
| 273 | break; | 292 | break; |
| 274 | case 'S': /* System time. */ | 293 | case 'S': /* System time. */ |
| 275 | fprintf(fp, "%ld.%02ld", | 294 | printf("%ld.%02ld", |
| 276 | resp->ru.ru_stime.tv_sec, | 295 | resp->ru.ru_stime.tv_sec, |
| 277 | resp->ru.ru_stime.TV_MSEC / 10); | 296 | resp->ru.ru_stime.TV_MSEC / 10); |
| 278 | break; | 297 | break; |
| 279 | case 'T': /* System time. */ | 298 | case 'T': /* System time. */ |
| 280 | if (resp->ru.ru_stime.tv_sec >= 3600) /* One hour -> h:m:s. */ | 299 | if (resp->ru.ru_stime.tv_sec >= 3600) /* One hour -> h:m:s. */ |
| 281 | fprintf(fp, "%ldh %ldm %02lds", | 300 | printf("%ldh %ldm %02lds", |
| 282 | resp->ru.ru_stime.tv_sec / 3600, | 301 | resp->ru.ru_stime.tv_sec / 3600, |
| 283 | (resp->ru.ru_stime.tv_sec % 3600) / 60, | 302 | (resp->ru.ru_stime.tv_sec % 3600) / 60, |
| 284 | resp->ru.ru_stime.tv_sec % 60); | 303 | resp->ru.ru_stime.tv_sec % 60); |
| 285 | else | 304 | else |
| 286 | fprintf(fp, "%ldm %ld.%02lds", /* -> m:s. */ | 305 | printf("%ldm %ld.%02lds", /* -> m:s. */ |
| 287 | resp->ru.ru_stime.tv_sec / 60, | 306 | resp->ru.ru_stime.tv_sec / 60, |
| 288 | resp->ru.ru_stime.tv_sec % 60, | 307 | resp->ru.ru_stime.tv_sec % 60, |
| 289 | resp->ru.ru_stime.tv_usec / 10000); | 308 | resp->ru.ru_stime.tv_usec / 10000); |
| 290 | break; | 309 | break; |
| 291 | case 'U': /* User time. */ | 310 | case 'U': /* User time. */ |
| 292 | fprintf(fp, "%ld.%02ld", | 311 | printf("%ld.%02ld", |
| 293 | resp->ru.ru_utime.tv_sec, | 312 | resp->ru.ru_utime.tv_sec, |
| 294 | resp->ru.ru_utime.TV_MSEC / 10); | 313 | resp->ru.ru_utime.TV_MSEC / 10); |
| 295 | break; | 314 | break; |
| 296 | case 'u': /* User time. */ | 315 | case 'u': /* User time. */ |
| 297 | if (resp->ru.ru_utime.tv_sec >= 3600) /* One hour -> h:m:s. */ | 316 | if (resp->ru.ru_utime.tv_sec >= 3600) /* One hour -> h:m:s. */ |
| 298 | fprintf(fp, "%ldh %ldm %02lds", | 317 | printf("%ldh %ldm %02lds", |
| 299 | resp->ru.ru_utime.tv_sec / 3600, | 318 | resp->ru.ru_utime.tv_sec / 3600, |
| 300 | (resp->ru.ru_utime.tv_sec % 3600) / 60, | 319 | (resp->ru.ru_utime.tv_sec % 3600) / 60, |
| 301 | resp->ru.ru_utime.tv_sec % 60); | 320 | resp->ru.ru_utime.tv_sec % 60); |
| 302 | else | 321 | else |
| 303 | fprintf(fp, "%ldm %ld.%02lds", /* -> m:s. */ | 322 | printf("%ldm %ld.%02lds", /* -> m:s. */ |
| 304 | resp->ru.ru_utime.tv_sec / 60, | 323 | resp->ru.ru_utime.tv_sec / 60, |
| 305 | resp->ru.ru_utime.tv_sec % 60, | 324 | resp->ru.ru_utime.tv_sec % 60, |
| 306 | resp->ru.ru_utime.tv_usec / 10000); | 325 | resp->ru.ru_utime.tv_usec / 10000); |
| 307 | break; | 326 | break; |
| 308 | case 'W': /* Times swapped out. */ | 327 | case 'W': /* Times swapped out. */ |
| 309 | fprintf(fp, "%ld", resp->ru.ru_nswap); | 328 | printf("%ld", resp->ru.ru_nswap); |
| 310 | break; | 329 | break; |
| 311 | case 'X': /* Average shared text size. */ | 330 | case 'X': /* Average shared text size. */ |
| 312 | fprintf(fp, "%lu", | 331 | printf("%lu", |
| 313 | MSEC_TO_TICKS(v) == 0 ? 0 : | 332 | MSEC_TO_TICKS(v) == 0 ? 0 : |
| 314 | ptok((UL) resp->ru.ru_ixrss) / MSEC_TO_TICKS(v)); | 333 | ptok((UL) resp->ru.ru_ixrss) / MSEC_TO_TICKS(v)); |
| 315 | break; | 334 | break; |
| 316 | case 'Z': /* Page size. */ | 335 | case 'Z': /* Page size. */ |
| 317 | fprintf(fp, "%d", getpagesize()); | 336 | printf("%d", getpagesize()); |
| 318 | break; | 337 | break; |
| 319 | case 'c': /* Involuntary context switches. */ | 338 | case 'c': /* Involuntary context switches. */ |
| 320 | fprintf(fp, "%ld", resp->ru.ru_nivcsw); | 339 | printf("%ld", resp->ru.ru_nivcsw); |
| 321 | break; | 340 | break; |
| 322 | case 'e': /* Elapsed real time in seconds. */ | 341 | case 'e': /* Elapsed real time in seconds. */ |
| 323 | fprintf(fp, "%ld.%02ld", | 342 | printf("%ld.%02ld", |
| 324 | resp->elapsed.tv_sec, resp->elapsed.tv_usec / 10000); | 343 | resp->elapsed.tv_sec, resp->elapsed.tv_usec / 10000); |
| 325 | break; | 344 | break; |
| 326 | case 'k': /* Signals delivered. */ | 345 | case 'k': /* Signals delivered. */ |
| 327 | fprintf(fp, "%ld", resp->ru.ru_nsignals); | 346 | printf("%ld", resp->ru.ru_nsignals); |
| 328 | break; | 347 | break; |
| 329 | case 'p': /* Average stack segment. */ | 348 | case 'p': /* Average stack segment. */ |
| 330 | fprintf(fp, "%lu", | 349 | printf("%lu", |
| 331 | MSEC_TO_TICKS(v) == 0 ? 0 : | 350 | MSEC_TO_TICKS(v) == 0 ? 0 : |
| 332 | ptok((UL) resp->ru.ru_isrss) / MSEC_TO_TICKS(v)); | 351 | ptok((UL) resp->ru.ru_isrss) / MSEC_TO_TICKS(v)); |
| 333 | break; | 352 | break; |
| 334 | case 'r': /* Incoming socket messages received. */ | 353 | case 'r': /* Incoming socket messages received. */ |
| 335 | fprintf(fp, "%ld", resp->ru.ru_msgrcv); | 354 | printf("%ld", resp->ru.ru_msgrcv); |
| 336 | break; | 355 | break; |
| 337 | case 's': /* Outgoing socket messages sent. */ | 356 | case 's': /* Outgoing socket messages sent. */ |
| 338 | fprintf(fp, "%ld", resp->ru.ru_msgsnd); | 357 | printf("%ld", resp->ru.ru_msgsnd); |
| 339 | break; | 358 | break; |
| 340 | case 't': /* Average resident set size. */ | 359 | case 't': /* Average resident set size. */ |
| 341 | fprintf(fp, "%lu", | 360 | printf("%lu", |
| 342 | MSEC_TO_TICKS(v) == 0 ? 0 : | 361 | MSEC_TO_TICKS(v) == 0 ? 0 : |
| 343 | ptok((UL) resp->ru.ru_idrss) / MSEC_TO_TICKS(v)); | 362 | ptok((UL) resp->ru.ru_idrss) / MSEC_TO_TICKS(v)); |
| 344 | break; | 363 | break; |
| 345 | case 'w': /* Voluntary context switches. */ | 364 | case 'w': /* Voluntary context switches. */ |
| 346 | fprintf(fp, "%ld", resp->ru.ru_nvcsw); | 365 | printf("%ld", resp->ru.ru_nvcsw); |
| 347 | break; | 366 | break; |
| 348 | case 'x': /* Exit status. */ | 367 | case 'x': /* Exit status. */ |
| 349 | fprintf(fp, "%d", WEXITSTATUS(resp->waitstatus)); | 368 | printf("%d", WEXITSTATUS(resp->waitstatus)); |
| 350 | break; | 369 | break; |
| 351 | case '\0': | ||
| 352 | putc('?', fp); | ||
| 353 | return; | ||
| 354 | default: | ||
| 355 | putc('?', fp); | ||
| 356 | putc(*fmt, fp); | ||
| 357 | } | 370 | } |
| 358 | ++fmt; | ||
| 359 | break; | 371 | break; |
| 360 | 372 | ||
| 373 | #ifdef NOT_NEEDED_YET | ||
| 361 | case '\\': /* Format escape. */ | 374 | case '\\': /* Format escape. */ |
| 362 | switch (*++fmt) { | 375 | switch (*++fmt) { |
| 376 | default: | ||
| 377 | putc('\\', stdout); | ||
| 378 | /*FALLTHROUGH*/ | ||
| 379 | case '\\': | ||
| 380 | if (!*fmt) goto ret; | ||
| 381 | putc(*fmt, stdout); | ||
| 382 | break; | ||
| 363 | case 't': | 383 | case 't': |
| 364 | putc('\t', fp); | 384 | putc('\t', stdout); |
| 365 | break; | 385 | break; |
| 366 | case 'n': | 386 | case 'n': |
| 367 | putc('\n', fp); | 387 | putc('\n', stdout); |
| 368 | break; | ||
| 369 | case '\\': | ||
| 370 | putc('\\', fp); | ||
| 371 | break; | 388 | break; |
| 372 | default: | ||
| 373 | putc('?', fp); | ||
| 374 | putc('\\', fp); | ||
| 375 | putc(*fmt, fp); | ||
| 376 | } | 389 | } |
| 377 | ++fmt; | ||
| 378 | break; | 390 | break; |
| 379 | 391 | #endif | |
| 380 | default: | ||
| 381 | putc(*fmt++, fp); | ||
| 382 | } | 392 | } |
| 383 | 393 | ++fmt; | |
| 384 | die_if_ferror(fp, "output"); | ||
| 385 | } | 394 | } |
| 386 | putc('\n', fp); | 395 | /* ret: */ |
| 387 | 396 | putc('\n', stdout); | |
| 388 | die_if_ferror(fp, "output"); | ||
| 389 | } | 397 | } |
| 390 | 398 | ||
| 391 | /* Run command CMD and return statistics on it. | 399 | /* Run command CMD and return statistics on it. |
| @@ -449,7 +457,11 @@ int time_main(int argc, char **argv) | |||
| 449 | } | 457 | } |
| 450 | 458 | ||
| 451 | run_command(argv, &res); | 459 | run_command(argv, &res); |
| 452 | summarize(stderr, output_format, argv, &res); | 460 | |
| 461 | /* Cheat. printf's are shorter :) */ | ||
| 462 | stdout = stderr; | ||
| 463 | dup2(2, 1); /* just in case libc does something silly :( */ | ||
| 464 | summarize(output_format, argv, &res); | ||
| 453 | 465 | ||
| 454 | if (WIFSTOPPED(res.waitstatus)) | 466 | if (WIFSTOPPED(res.waitstatus)) |
| 455 | return WSTOPSIG(res.waitstatus); | 467 | return WSTOPSIG(res.waitstatus); |
| @@ -457,5 +469,5 @@ int time_main(int argc, char **argv) | |||
| 457 | return WTERMSIG(res.waitstatus); | 469 | return WTERMSIG(res.waitstatus); |
| 458 | if (WIFEXITED(res.waitstatus)) | 470 | if (WIFEXITED(res.waitstatus)) |
| 459 | return WEXITSTATUS(res.waitstatus); | 471 | return WEXITSTATUS(res.waitstatus); |
| 460 | return 0; | 472 | fflush_stdout_and_exit(0); |
| 461 | } | 473 | } |
