From 0a732af73aa7a2378e6981d3a7443e50fd291d2c Mon Sep 17 00:00:00 2001 From: Kiyoshi Aman Date: Wed, 5 Jun 2019 00:10:11 -0500 Subject: usr.bin/time: this was inappropriately pruned at some point --- usr.bin/time/ext.h | 5 -- usr.bin/time/strpct.c | 125 +++++++++++++++++++++++++++++++++++++++++ usr.bin/time/strpct.h | 3 + usr.bin/time/time.c | 150 +++++++++++++++++++++++++++++++++++++++++++++----- usr.bin/time/xtime.c | 9 --- 5 files changed, 263 insertions(+), 29 deletions(-) delete mode 100644 usr.bin/time/ext.h create mode 100644 usr.bin/time/strpct.c create mode 100644 usr.bin/time/strpct.h delete mode 100644 usr.bin/time/xtime.c diff --git a/usr.bin/time/ext.h b/usr.bin/time/ext.h deleted file mode 100644 index 6626a29..0000000 --- a/usr.bin/time/ext.h +++ /dev/null @@ -1,5 +0,0 @@ -/* $NetBSD: ext.h,v 1.3 2017/07/15 14:34:08 christos Exp $ */ - -/* borrowed from ../../bin/csh/extern.h */ -void prusage1(FILE *, const char *fmt, struct rusage *, struct rusage *, - struct timespec *, struct timespec *); diff --git a/usr.bin/time/strpct.c b/usr.bin/time/strpct.c new file mode 100644 index 0000000..135fcb6 --- /dev/null +++ b/usr.bin/time/strpct.c @@ -0,0 +1,125 @@ +/* $NetBSD: strpct.c,v 1.3 2012/01/07 18:40:56 christos Exp $ */ + +/*- + * Copyright (c) 1998 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Erik E. Fair + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +/* + * Calculate a percentage without resorting to floating point + * and return a pointer to a string + * + * "digits" is the number of digits past the decimal place you want + * (zero being the straight percentage with no decimals) + * + * Erik E. Fair , May 8, 1997 + */ + +#include +#include +#include +#include +#include + +#include "strpct.h" + +char * +strspct(char *buf, size_t bufsiz, intmax_t numerator, intmax_t denominator, + size_t digits) +{ + int sign; + + switch (bufsiz) { + case 1: + *buf = '\0'; + /*FALLTHROUGH*/ + case 0: + return buf; + default: + break; + } + + if (denominator < 0) { + denominator = -denominator; + sign = 1; + } else + sign = 0; + + if (numerator < 0) { + numerator = -numerator; + sign++; + } + + sign &= 1; + (void)strpct(buf + sign, bufsiz - sign, (uintmax_t)numerator, + (uintmax_t)denominator, digits); + if (sign) + *buf = '-'; + return buf; +} + +char * +strpct(char *buf, size_t bufsiz, uintmax_t numerator, uintmax_t denominator, + size_t digits) +{ + uintmax_t factor, result; + size_t u; + + factor = 100; + for (u = 0; u < digits; u++) { + /* watch out for overflow! */ + if (factor < (UINTMAX_MAX / 10)) + factor *= 10; + else + break; + } + + /* watch out for overflow! */ + if (numerator < (UINTMAX_MAX / factor)) + numerator *= factor; + else { + /* toss some of the bits of lesser significance */ + denominator /= factor; + } + + if (denominator == 0) + denominator = 1; + + result = numerator / denominator; + + if (digits == 0) + (void)snprintf(buf, bufsiz, "%ju", result); + else { + factor /= 100; /* undo initialization */ + + (void)snprintf(buf, bufsiz, "%ju%s%0*ju", + result / factor, localeconv()->decimal_point, (int)u, + result % factor); + } + + return buf; +} diff --git a/usr.bin/time/strpct.h b/usr.bin/time/strpct.h new file mode 100644 index 0000000..ad41d7a --- /dev/null +++ b/usr.bin/time/strpct.h @@ -0,0 +1,3 @@ + +extern char *strspct(char *, size_t, intmax_t, intmax_t, size_t); +extern char *strpct(char *, size_t, uintmax_t, uintmax_t, size_t); diff --git a/usr.bin/time/time.c b/usr.bin/time/time.c index 263db9a..1d43d9f 100644 --- a/usr.bin/time/time.c +++ b/usr.bin/time/time.c @@ -29,21 +29,9 @@ * SUCH DAMAGE. */ -#include -#ifndef lint -__COPYRIGHT("@(#) Copyright (c) 1987, 1988, 1993\ - The Regents of the University of California. All rights reserved."); -#endif /* not lint */ - -#ifndef lint -#if 0 -static char sccsid[] = "@(#)time.c 8.1 (Berkeley) 6/6/93"; -#endif -__RCSID("$NetBSD: time.c,v 1.23 2017/07/15 14:34:08 christos Exp $"); -#endif /* not lint */ - #include #include +#include #include #include #include @@ -52,16 +40,22 @@ __RCSID("$NetBSD: time.c,v 1.23 2017/07/15 14:34:08 christos Exp $"); #include #include #include +#include #include +#include -#include "ext.h" +#include "strpct.h" -__dead static void usage(void); +static void usage(void); static void prl(long, const char *); static void prts(const char *, const char *, const struct timespec *, const char *); static void prtv(const char *, const char *, const struct timeval *, const char *); +void prusage1(FILE *, const char *fmt, struct rusage *, struct rusage *, + struct timespec *, struct timespec *); +static void pdeltat(FILE *fp, struct timeval *t1, struct timeval *t0); +static void pcsecs(FILE *fp, long l); int main(int argc, char ** volatile argv) @@ -213,3 +207,129 @@ prtv(const char *pre, const char *decpt, const struct timeval *tv, (void)fprintf(stderr, "%s%9lld%s%02ld%s", pre, (long long)tv->tv_sec, decpt, (long)tv->tv_usec / 10000, post); } + +void +prusage1(FILE *fp, const char *cp, struct rusage *r0, struct rusage *r1, + struct timespec *e, struct timespec *b) +{ + long i; + time_t t; + time_t ms; + + ms = (e->tv_sec - b->tv_sec) * 100 + (e->tv_nsec - b->tv_nsec) / 10000000; + t = (r1->ru_utime.tv_sec - r0->ru_utime.tv_sec) * 100 + + (r1->ru_utime.tv_usec - r0->ru_utime.tv_usec) / 10000 + + (r1->ru_stime.tv_sec - r0->ru_stime.tv_sec) * 100 + + (r1->ru_stime.tv_usec - r0->ru_stime.tv_usec) / 10000; + + for (; *cp; cp++) + if (*cp != '%') + (void) fputc(*cp, fp); + else if (cp[1]) + switch (*++cp) { + case 'D': /* (average) unshared data size */ + (void)fprintf(fp, "%ld", t == 0 ? 0L : + (long)((r1->ru_idrss + r1->ru_isrss - + (r0->ru_idrss + r0->ru_isrss)) / t)); + break; + case 'E': /* elapsed (wall-clock) time */ + pcsecs(fp, (long) ms); + break; + case 'F': /* page faults */ + (void)fprintf(fp, "%ld", r1->ru_majflt - r0->ru_majflt); + break; + case 'I': /* FS blocks in */ + (void)fprintf(fp, "%ld", r1->ru_inblock - r0->ru_inblock); + break; + case 'K': /* (average) total data memory used */ + (void)fprintf(fp, "%ld", t == 0 ? 0L : + (long)(((r1->ru_ixrss + r1->ru_isrss + r1->ru_idrss) - + (r0->ru_ixrss + r0->ru_idrss + r0->ru_isrss)) / t)); + break; + case 'M': /* max. Resident Set Size */ + (void)fprintf(fp, "%ld", r1->ru_maxrss / 2L); + break; + case 'O': /* FS blocks out */ + (void)fprintf(fp, "%ld", r1->ru_oublock - r0->ru_oublock); + break; + case 'P': /* percent time spent running */ + /* check if it did not run at all */ + if (ms == 0) { + (void)fputs("0.0%", fp); + } else { + char pb[32]; + (void)fputs(strpct(pb, sizeof(pb), + (uintmax_t)t, (uintmax_t)ms, 1), fp); + (void)fputc('%', fp); + } + break; + case 'R': /* page reclaims */ + (void)fprintf(fp, "%ld", r1->ru_minflt - r0->ru_minflt); + break; + case 'S': /* system CPU time used */ + pdeltat(fp, &r1->ru_stime, &r0->ru_stime); + break; + case 'U': /* user CPU time used */ + pdeltat(fp, &r1->ru_utime, &r0->ru_utime); + break; + case 'W': /* number of swaps */ + i = r1->ru_nswap - r0->ru_nswap; + (void)fprintf(fp, "%ld", i); + break; + case 'X': /* (average) shared text size */ + (void)fprintf(fp, "%ld", t == 0 ? 0L : + (long)((r1->ru_ixrss - r0->ru_ixrss) / t)); + break; + case 'c': /* num. involuntary context switches */ + (void)fprintf(fp, "%ld", r1->ru_nivcsw - r0->ru_nivcsw); + break; + case 'k': /* number of signals received */ + (void)fprintf(fp, "%ld", r1->ru_nsignals-r0->ru_nsignals); + break; + case 'r': /* socket messages received */ + (void)fprintf(fp, "%ld", r1->ru_msgrcv - r0->ru_msgrcv); + break; + case 's': /* socket messages sent */ + (void)fprintf(fp, "%ld", r1->ru_msgsnd - r0->ru_msgsnd); + break; + case 'w': /* num. voluntary context switches (waits) */ + (void)fprintf(fp, "%ld", r1->ru_nvcsw - r0->ru_nvcsw); + break; + } + (void)fputc('\n', fp); +} + +static void +pdeltat(FILE *fp, struct timeval *t1, struct timeval *t0) +{ + struct timeval td; + + timersub(t1, t0, &td); + (void)fprintf(fp, "%ld.%01ld", (long)td.tv_sec, + (long)(td.tv_usec / 100000)); +} + +#define P2DIG(fp, i) (void)fprintf(fp, "%ld%ld", (i) / 10, (i) % 10) + +static void +pcsecs(FILE *fp, long l) /* PWP: print mm:ss.dd, l is in sec*100 */ +{ + long i; + + i = l / 360000; + if (i) { + (void)fprintf(fp, "%ld:", i); + i = (l % 360000) / 100; + P2DIG(fp, i / 60); + goto minsec; + } + i = l / 100; + (void)fprintf(fp, "%ld", i / 60); +minsec: + i %= 60; + (void)fputc(':', fp); + P2DIG(fp, i); + (void)fputc('.', fp); + P2DIG(fp, (l % 100)); +} + diff --git a/usr.bin/time/xtime.c b/usr.bin/time/xtime.c deleted file mode 100644 index b685d2d..0000000 --- a/usr.bin/time/xtime.c +++ /dev/null @@ -1,9 +0,0 @@ -/* $NetBSD: xtime.c,v 1.1 2007/02/24 21:30:27 matt Exp $ */ - - - -#include -#include -#include -#include "ext.h" -#include "csh/time.c" -- cgit v1.2.3-70-g09d2