Ignore:
Timestamp:
Nov 6, 2007, 11:01:53 AM (16 years ago)
Author:
Bruno Cornec
Message:
  • Better output for mindi-busybox revision
  • Remove dummy file created on NFS - report from Arnaud Tiger <arnaud.tiger_at_hp.com>
  • strace useful for debug
  • fix new versions for pb (2.0.0 for mindi and 1.7.2 for mindi-busybox)
  • fix build process for mindi-busybox + options used in that version (dd for label-partitions-as-necessary)
  • fix typo in label-partitions-as-necessary which doesn't seem to work
  • Update to busybox 1.7.2
  • perl is now required at restore time to support uuid swap partitions (and will be used for many other thigs

in the future for sure)

  • next mindi version will be 2.0.0 due to all the changes made in it (udev may break working distros)
  • small optimization in mindi on keyboard handling (one single find instead of multiple)
  • better interaction for USB device when launching mindi manually
  • attempt to automatically guess block disk size for ramdisk
  • fix typos in bkphw
  • Fix the remaining problem with UUID support for swap partitions
  • Updates mondoarchive man page for USB support
  • Adds preliminary Hardware support to mindi (Proliant SSSTK)
  • Tries to add udev support also for rhel4
  • Fix UUID support which was still broken.
  • Be conservative in test for the start-nfs script
  • Update config file for mindi-busybox for 1.7.2 migration
  • Try to run around a busybox bug (1.2.2 pb on inexistant links)
  • Add build content for mindi-busybox in pb
  • Remove distributions content for mindi-busybox
  • Fix a warning on inexistant raidtab
  • Solve problem on tmpfs in restore init (Problem of inexistant symlink and busybox)
  • Create MONDO_CACHE and use it everywhere + creation at start
  • Really never try to eject a USB device
  • Fix a issue with &> usage (replaced with 1> and 2>)
  • Adds magic file to depllist in order to have file working + ldd which helps for debugging issues
  • tty modes correct to avoid sh error messages
  • Use ext3 normally and not ext2 instead
  • USB device should be corrected after reading (take 1st part)
  • Adds a mount_USB_here function derived from mount_CDROM_here
  • usb detection place before /dev detection in device name at restore time
  • Fix when restoring from USB: media is asked in interactive mode
  • Adds USB support for mondorestore
  • mount_cdrom => mount_media
  • elilo.efi is now searched throughout /boot/efi and not in a fixed place as there is no standard
  • untar-and-softlink => untar (+ interface change)
  • suppress useless softlinks creation/removal in boot process
  • avoids udevd messages on groups
  • Increase # of disks to 99 as in mindi at restore time (should be a conf file parameter)
  • skip existing big file creation
  • seems to work correctly for USB mindi boot
  • Adds group and tty link to udev conf
  • Always load usb-torage (even 2.6) to initiate USB bus discovery
  • Better printing of messages
  • Attempt to fix a bug in supporting OpenSusE 10.3 kernel for initramfs (mindi may now use multiple regex for kernel initrd detection)
  • Links were not correctly done as non relative for modules in mindi
  • exclusion of modules denied now works
  • Also create modules in their ordinary place, so that classical modprobe works + copy modules.dep
  • Fix bugs for DENY_MODS handling
  • Add device /dev/console for udev
  • ide-generic should now really be excluded
  • Fix a bug in major number for tty
  • If udev then adds modprobe/insmod to rootfs
  • tty0 is also cretaed with udev
  • ide-generic put rather in DENY_MODS
  • udevd remove from deplist s handled in mindi directly
  • better default for mindi when using --usb
  • Handles dynamically linked busybox (in case we want to use it soon ;-)
  • Adds fixed devices to create for udev
  • ide-generic should not be part of the initrd when using libata v2
  • support a dynamically linked udev (case on Ubuntu 7.10 and Mandriva 2008.0 so should be quite generic) This will give incitation to move to dyn. linked binaries in the initrd which will help for other tasks (ia6 4)
  • Improvement in udev support (do not use cl options not available in busybox)
  • Udev in mindi
    • auto creation of the right links at boot time with udev-links.conf(from Mandriva 2008.0)
    • rework startup of udev as current makes kernel crash (from Mandriva 2008.0)
    • add support for 64 bits udev
  • Try to render MyInsmod silent at boot time
  • Adds udev support (mandatory for newest distributions to avoid remapping of devices in a different way as on the original system)
  • We also need vaft format support for USB boot
  • Adds libusual support (Ubuntu 7.10 needs it for USB)
  • Improve Ubuntu/Debian keyboard detection and support
  • pbinit adapted to new pb (0.8.10). Filtering of docs done in it
  • Suppress some mondo warnings and errors on USB again
  • Tries to fix lack of files in deb mindi package
  • Verify should now work for USB devices
  • More log/mesages improvement for USB support
  • - Supress g_erase_tmpdir_and_scratchdir
  • Improve some log messages for USB support
  • Try to improve install in mindi to avoid issues with isolinux.cfg not installed vene if in the pkg :-(
  • Improve mindi-busybox build
  • In conformity with pb 0.8.9
  • Add support for Ubuntu 7.10 in build process
  • Add USB Key button to Menu UI (CD streamer removed)
  • Attempt to fix error messages on tmp/scratch files at the end by removing those dir at the latest possible.
  • Fix a bug linked to the size of the -E param which could be used (Arnaud Tiger/René Ribaud).
  • Integrate ~/.pbrc content into mondorescue.pb (required project-builder >= 0.8.7)
  • Put mondorescue in conformity with new pb filtering rules
  • Add USB support at restore time (no test done yet). New start-usb script PB varibale added where useful
  • Unmounting USB device before removal of temporary scratchdir
  • Stil refining USB copy back to mondo (one command was not executed)
  • No need to have the image subdor in the csratchdir when USB.
  • umount the USB partition before attempting to use it
  • Remove useless copy from mindi to mondo at end of USB handling

(risky merge, we are raising the limits of 2 diverging branches. The status of stable is not completely sure as such. Will need lots of tests, but it's not yet done :-()
(merge -r1692:1769 $SVN_M/branches/2.2.5)

File:
1 edited

Legend:

Unmodified
Added
Removed
  • branches/stable/mindi-busybox/miscutils/time.c

    r821 r1770  
    33   Copyright (C) 1990, 91, 92, 93, 96 Free Software Foundation, Inc.
    44
    5    Licensed under GPLv2 or later, see file LICENSE in this tarball for details.
     5   Licensed under GPL version 2, see file LICENSE in this tarball for details.
    66*/
    77/* Originally written by David Keppel <pardo@cs.washington.edu>.
     
    1010*/
    1111
    12 #include "busybox.h"
    13 #include <stdlib.h>
    14 #include <stdio.h>
    15 #include <signal.h>
    16 #include <errno.h>
    17 #include <getopt.h>
    18 #include <string.h>
    19 #include <limits.h>
    20 #include <unistd.h>
    21 #include <sys/types.h>  /* For pid_t. */
    22 #include <sys/wait.h>
    23 #include <sys/param.h>  /* For getpagesize, maybe.  */
    24 
    25 #define TV_MSEC tv_usec / 1000
    26 #include <sys/resource.h>
     12#include "libbb.h"
    2713
    2814/* Information on the resources used by a child process.  */
     
    3016    int waitstatus;
    3117    struct rusage ru;
    32     struct timeval start, elapsed;  /* Wallclock time of process.  */
     18    unsigned elapsed_ms;    /* Wallclock time of process.  */
    3319} resource_t;
    3420
     
    3622   usec = microseconds = 1/1,000,000 (1*10e-6) second.  */
    3723
    38 #ifndef TICKS_PER_SEC
    39 #define TICKS_PER_SEC 100
    40 #endif
    41 
    42 /* The number of milliseconds in one `tick' used by the `rusage' structure.  */
    43 #define MSEC_PER_TICK (1000 / TICKS_PER_SEC)
    44 
    45 /* Return the number of clock ticks that occur in M milliseconds.  */
    46 #define MSEC_TO_TICKS(m) ((m) / MSEC_PER_TICK)
    47 
    4824#define UL unsigned long
    4925
    50 static const char *const default_format = "real\t%E\nuser\t%u\nsys\t%T";
     26static const char default_format[] ALIGN1 = "real\t%E\nuser\t%u\nsys\t%T";
    5127
    5228/* The output format for the -p option .*/
    53 static const char *const posix_format = "real %e\nuser %U\nsys %S";
     29static const char posix_format[] ALIGN1 = "real %e\nuser %U\nsys %S";
    5430
    5531
    5632/* Format string for printing all statistics verbosely.
    5733   Keep this output to 24 lines so users on terminals can see it all.*/
    58 static const char *const long_format =
     34static const char long_format[] ALIGN1 =
    5935    "\tCommand being timed: \"%C\"\n"
    6036    "\tUser time (seconds): %U\n"
     
    7854    "\tSocket messages received: %r\n"
    7955    "\tSignals delivered: %k\n"
    80     "\tPage size (bytes): %Z\n" "\tExit status: %x";
    81 
    82 
    83   /* Wait for and fill in data on child process PID.
    84      Return 0 on error, 1 if ok.  */
     56    "\tPage size (bytes): %Z\n"
     57    "\tExit status: %x";
     58
     59
     60/* Wait for and fill in data on child process PID.
     61   Return 0 on error, 1 if ok.  */
    8562
    8663/* pid_t is short on BSDI, so don't try to promote it.  */
     
    8865{
    8966    int status;
    90 
    9167    pid_t caught;
    9268
     
    9773            return 0;
    9874    }
    99 
    100     gettimeofday(&resp->elapsed, (struct timezone *) 0);
    101     resp->elapsed.tv_sec -= resp->start.tv_sec;
    102     if (resp->elapsed.tv_usec < resp->start.tv_usec) {
    103         /* Manually carry a one from the seconds field.  */
    104         resp->elapsed.tv_usec += 1000000;
    105         --resp->elapsed.tv_sec;
    106     }
    107     resp->elapsed.tv_usec -= resp->start.tv_usec;
    108 
     75    resp->elapsed_ms = (monotonic_us() / 1000) - resp->elapsed_ms;
    10976    resp->waitstatus = status;
    110 
    11177    return 1;
    11278}
    11379
    114 /* Print ARGV to FP, with each entry in ARGV separated by FILLER.  */
    115 static void fprintargv(FILE * fp, char *const *argv, const char *filler)
    116 {
    117     char *const *av;
    118 
    119     av = argv;
    120     fputs(*av, fp);
    121     while (*++av) {
    122         fputs(filler, fp);
    123         fputs(*av, fp);
    124     }
    125     if (ferror(fp))
    126         bb_error_msg_and_die(bb_msg_write_error);
     80/* Print ARGV, with each entry in ARGV separated by FILLER.  */
     81static void printargv(char *const *argv, const char *filler)
     82{
     83    fputs(*argv, stdout);
     84    while (*++argv) {
     85        fputs(filler, stdout);
     86        fputs(*argv, stdout);
     87    }
    12788}
    12889
     
    13798static unsigned long ptok(unsigned long pages)
    13899{
    139     static unsigned long ps = 0;
     100    static unsigned long ps;
    140101    unsigned long tmp;
    141     static long size = LONG_MAX;
    142102
    143103    /* Initialization.  */
    144104    if (ps == 0)
    145         ps = (long) getpagesize();
     105        ps = getpagesize();
    146106
    147107    /* Conversion.  */
    148108    if (pages > (LONG_MAX / ps)) {  /* Could overflow.  */
    149109        tmp = pages / 1024; /* Smaller first, */
    150         size = tmp * ps;    /* then larger.  */
    151     } else {            /* Could underflow.  */
    152         tmp = pages * ps;   /* Larger first, */
    153         size = tmp / 1024;  /* then smaller.  */
    154     }
    155     return size;
     110        return tmp * ps;    /* then larger.  */
     111    }
     112    /* Could underflow.  */
     113    tmp = pages * ps;   /* Larger first, */
     114    return tmp / 1024;  /* then smaller.  */
    156115}
    157116
    158117/* summarize: Report on the system use of a command.
    159118
    160    Copy the FMT argument to FP except that `%' sequences
     119   Print the FMT argument except that `%' sequences
    161120   have special meaning, and `\n' and `\t' are translated into
    162121   newline and tab, respectively, and `\\' is translated into `\'.
     
    196155   and dividing by elapsed real time.
    197156
    198    FP is the stream to print to.
    199157   FMT is the format string, interpreted as described above.
    200158   COMMAND is the command and args that are being summarized.
    201159   RESP is resource information on the command.  */
    202160
    203 static void summarize(FILE * fp, const char *fmt, char **command,
    204                       resource_t * resp)
    205 {
    206     unsigned long r;    /* Elapsed real milliseconds.  */
    207     unsigned long v;    /* Elapsed virtual (CPU) milliseconds.  */
     161#ifndef TICKS_PER_SEC
     162#define TICKS_PER_SEC 100
     163#endif
     164
     165static void summarize(const char *fmt, char **command, resource_t * resp)
     166{
     167    unsigned vv_ms;     /* Elapsed virtual (CPU) milliseconds */
     168    unsigned cpu_ticks; /* Same, in "CPU ticks" */
    208169
    209170    if (WIFSTOPPED(resp->waitstatus))
    210         fprintf(fp, "Command stopped by signal %d\n",
     171        printf("Command stopped by signal %u\n",
    211172                WSTOPSIG(resp->waitstatus));
    212173    else if (WIFSIGNALED(resp->waitstatus))
    213         fprintf(fp, "Command terminated by signal %d\n",
     174        printf("Command terminated by signal %u\n",
    214175                WTERMSIG(resp->waitstatus));
    215176    else if (WIFEXITED(resp->waitstatus) && WEXITSTATUS(resp->waitstatus))
    216         fprintf(fp, "Command exited with non-zero status %d\n",
     177        printf("Command exited with non-zero status %u\n",
    217178                WEXITSTATUS(resp->waitstatus));
    218179
    219     /* Convert all times to milliseconds.  Occasionally, one of these values
    220        comes out as zero.  Dividing by zero causes problems, so we first
    221        check the time value.  If it is zero, then we take `evasive action'
    222        instead of calculating a value.  */
    223 
    224     r = resp->elapsed.tv_sec * 1000 + resp->elapsed.tv_usec / 1000;
    225 
    226     v = resp->ru.ru_utime.tv_sec * 1000 + resp->ru.ru_utime.TV_MSEC +
    227         resp->ru.ru_stime.tv_sec * 1000 + resp->ru.ru_stime.TV_MSEC;
     180    vv_ms = (resp->ru.ru_utime.tv_sec + resp->ru.ru_stime.tv_sec) * 1000
     181          + (resp->ru.ru_utime.tv_usec + resp->ru.ru_stime.tv_usec) / 1000;
     182
     183#if (1000 / TICKS_PER_SEC) * TICKS_PER_SEC == 1000
     184    /* 1000 is exactly divisible by TICKS_PER_SEC */
     185    cpu_ticks = vv_ms / (1000 / TICKS_PER_SEC);
     186#else
     187    cpu_ticks = vv_ms * (unsigned long long)TICKS_PER_SEC / 1000;
     188#endif
     189    if (!cpu_ticks) cpu_ticks = 1; /* we divide by it, must be nonzero */
     190
     191    /* putchar() != putc(stdout) in glibc! */
    228192
    229193    while (*fmt) {
     194        /* Handle leading literal part */
     195        int n = strcspn(fmt, "%\\");
     196        if (n) {
     197            printf("%.*s", n, fmt);
     198            fmt += n;
     199            continue;
     200        }
     201
    230202        switch (*fmt) {
     203#ifdef NOT_NEEDED
     204        /* Handle literal char */
     205        /* Usually we optimize for size, but there is a limit
     206         * for everything. With this we do a lot of 1-byte writes */
     207        default:
     208            putc(*fmt, stdout);
     209            break;
     210#endif
     211
    231212        case '%':
    232213            switch (*++fmt) {
    233             case '%':   /* Literal '%'.  */
    234                 putc('%', fp);
    235                 break;
     214#ifdef NOT_NEEDED_YET
     215        /* Our format strings do not have these */
     216        /* and we do not take format str from user */
     217            default:
     218                putc('%', stdout);
     219                /*FALLTHROUGH*/
     220            case '%':
     221                if (!*fmt) goto ret;
     222                putc(*fmt, stdout);
     223                break;
     224#endif
    236225            case 'C':   /* The command that got timed.  */
    237                 fprintargv(fp, command, " ");
     226                printargv(command, " ");
    238227                break;
    239228            case 'D':   /* Average unshared data size.  */
    240                 fprintf(fp, "%lu",
    241                         MSEC_TO_TICKS(v) == 0 ? 0 :
    242                         ptok((UL) resp->ru.ru_idrss) / MSEC_TO_TICKS(v) +
    243                         ptok((UL) resp->ru.ru_isrss) / MSEC_TO_TICKS(v));
    244                 break;
    245             case 'E':   /* Elapsed real (wall clock) time.  */
    246                 if (resp->elapsed.tv_sec >= 3600)   /* One hour -> h:m:s.  */
    247                     fprintf(fp, "%ldh %ldm %02lds",
    248                             resp->elapsed.tv_sec / 3600,
    249                             (resp->elapsed.tv_sec % 3600) / 60,
    250                             resp->elapsed.tv_sec % 60);
     229                printf("%lu",
     230                        ptok((UL) resp->ru.ru_idrss) / cpu_ticks +
     231                        ptok((UL) resp->ru.ru_isrss) / cpu_ticks);
     232                break;
     233            case 'E': { /* Elapsed real (wall clock) time.  */
     234                unsigned seconds = resp->elapsed_ms / 1000;
     235                if (seconds >= 3600)    /* One hour -> h:m:s.  */
     236                    printf("%uh %um %02us",
     237                            seconds / 3600,
     238                            (seconds % 3600) / 60,
     239                            seconds % 60);
    251240                else
    252                     fprintf(fp, "%ldm %ld.%02lds",  /* -> m:s.  */
    253                             resp->elapsed.tv_sec / 60,
    254                             resp->elapsed.tv_sec % 60,
    255                             resp->elapsed.tv_usec / 10000);
    256                 break;
     241                    printf("%um %u.%02us",  /* -> m:s.  */
     242                            seconds / 60,
     243                            seconds % 60,
     244                            (unsigned)(resp->elapsed_ms / 10) % 100);
     245                break;
     246            }
    257247            case 'F':   /* Major page faults.  */
    258                 fprintf(fp, "%ld", resp->ru.ru_majflt);
     248                printf("%lu", resp->ru.ru_majflt);
    259249                break;
    260250            case 'I':   /* Inputs.  */
    261                 fprintf(fp, "%ld", resp->ru.ru_inblock);
     251                printf("%lu", resp->ru.ru_inblock);
    262252                break;
    263253            case 'K':   /* Average mem usage == data+stack+text.  */
    264                 fprintf(fp, "%lu",
    265                         MSEC_TO_TICKS(v) == 0 ? 0 :
    266                         ptok((UL) resp->ru.ru_idrss) / MSEC_TO_TICKS(v) +
    267                         ptok((UL) resp->ru.ru_isrss) / MSEC_TO_TICKS(v) +
    268                         ptok((UL) resp->ru.ru_ixrss) / MSEC_TO_TICKS(v));
     254                printf("%lu",
     255                        ptok((UL) resp->ru.ru_idrss) / cpu_ticks +
     256                        ptok((UL) resp->ru.ru_isrss) / cpu_ticks +
     257                        ptok((UL) resp->ru.ru_ixrss) / cpu_ticks);
    269258                break;
    270259            case 'M':   /* Maximum resident set size.  */
    271                 fprintf(fp, "%lu", ptok((UL) resp->ru.ru_maxrss));
     260                printf("%lu", ptok((UL) resp->ru.ru_maxrss));
    272261                break;
    273262            case 'O':   /* Outputs.  */
    274                 fprintf(fp, "%ld", resp->ru.ru_oublock);
     263                printf("%lu", resp->ru.ru_oublock);
    275264                break;
    276265            case 'P':   /* Percent of CPU this job got.  */
    277266                /* % cpu is (total cpu time)/(elapsed time).  */
    278                 if (r > 0)
    279                     fprintf(fp, "%lu%%", (v * 100 / r));
     267                if (resp->elapsed_ms > 0)
     268                    printf("%u%%", (unsigned)(vv_ms * 100 / resp->elapsed_ms));
    280269                else
    281                     fprintf(fp, "?%%");
     270                    printf("?%%");
    282271                break;
    283272            case 'R':   /* Minor page faults (reclaims).  */
    284                 fprintf(fp, "%ld", resp->ru.ru_minflt);
     273                printf("%lu", resp->ru.ru_minflt);
    285274                break;
    286275            case 'S':   /* System time.  */
    287                 fprintf(fp, "%ld.%02ld",
    288                         resp->ru.ru_stime.tv_sec,
    289                         resp->ru.ru_stime.TV_MSEC / 10);
     276                printf("%u.%02u",
     277                        (unsigned)resp->ru.ru_stime.tv_sec,
     278                        (unsigned)(resp->ru.ru_stime.tv_usec / 10000));
    290279                break;
    291280            case 'T':   /* System time.  */
    292281                if (resp->ru.ru_stime.tv_sec >= 3600) /* One hour -> h:m:s.  */
    293                     fprintf(fp, "%ldh %ldm %02lds",
    294                             resp->ru.ru_stime.tv_sec / 3600,
    295                             (resp->ru.ru_stime.tv_sec % 3600) / 60,
    296                             resp->ru.ru_stime.tv_sec % 60);
     282                    printf("%uh %um %02us",
     283                            (unsigned)(resp->ru.ru_stime.tv_sec / 3600),
     284                            (unsigned)(resp->ru.ru_stime.tv_sec % 3600) / 60,
     285                            (unsigned)(resp->ru.ru_stime.tv_sec % 60));
    297286                else
    298                     fprintf(fp, "%ldm %ld.%02lds",  /* -> m:s.  */
    299                             resp->ru.ru_stime.tv_sec / 60,
    300                             resp->ru.ru_stime.tv_sec % 60,
    301                             resp->ru.ru_stime.tv_usec / 10000);
     287                    printf("%um %u.%02us",  /* -> m:s.  */
     288                            (unsigned)(resp->ru.ru_stime.tv_sec / 60),
     289                            (unsigned)(resp->ru.ru_stime.tv_sec % 60),
     290                            (unsigned)(resp->ru.ru_stime.tv_usec / 10000));
    302291                break;
    303292            case 'U':   /* User time.  */
    304                 fprintf(fp, "%ld.%02ld",
    305                         resp->ru.ru_utime.tv_sec,
    306                         resp->ru.ru_utime.TV_MSEC / 10);
     293                printf("%u.%02u",
     294                        (unsigned)resp->ru.ru_utime.tv_sec,
     295                        (unsigned)(resp->ru.ru_utime.tv_usec / 10000));
    307296                break;
    308297            case 'u':   /* User time.  */
    309298                if (resp->ru.ru_utime.tv_sec >= 3600) /* One hour -> h:m:s.  */
    310                     fprintf(fp, "%ldh %ldm %02lds",
    311                             resp->ru.ru_utime.tv_sec / 3600,
    312                             (resp->ru.ru_utime.tv_sec % 3600) / 60,
    313                             resp->ru.ru_utime.tv_sec % 60);
     299                    printf("%uh %um %02us",
     300                            (unsigned)(resp->ru.ru_utime.tv_sec / 3600),
     301                            (unsigned)(resp->ru.ru_utime.tv_sec % 3600) / 60,
     302                            (unsigned)(resp->ru.ru_utime.tv_sec % 60));
    314303                else
    315                     fprintf(fp, "%ldm %ld.%02lds",  /* -> m:s.  */
    316                             resp->ru.ru_utime.tv_sec / 60,
    317                             resp->ru.ru_utime.tv_sec % 60,
    318                             resp->ru.ru_utime.tv_usec / 10000);
     304                    printf("%um %u.%02us",  /* -> m:s.  */
     305                            (unsigned)(resp->ru.ru_utime.tv_sec / 60),
     306                            (unsigned)(resp->ru.ru_utime.tv_sec % 60),
     307                            (unsigned)(resp->ru.ru_utime.tv_usec / 10000));
    319308                break;
    320309            case 'W':   /* Times swapped out.  */
    321                 fprintf(fp, "%ld", resp->ru.ru_nswap);
     310                printf("%lu", resp->ru.ru_nswap);
    322311                break;
    323312            case 'X':   /* Average shared text size.  */
    324                 fprintf(fp, "%lu",
    325                         MSEC_TO_TICKS(v) == 0 ? 0 :
    326                         ptok((UL) resp->ru.ru_ixrss) / MSEC_TO_TICKS(v));
     313                printf("%lu", ptok((UL) resp->ru.ru_ixrss) / cpu_ticks);
    327314                break;
    328315            case 'Z':   /* Page size.  */
    329                 fprintf(fp, "%d", getpagesize());
     316                printf("%u", getpagesize());
    330317                break;
    331318            case 'c':   /* Involuntary context switches.  */
    332                 fprintf(fp, "%ld", resp->ru.ru_nivcsw);
     319                printf("%lu", resp->ru.ru_nivcsw);
    333320                break;
    334321            case 'e':   /* Elapsed real time in seconds.  */
    335                 fprintf(fp, "%ld.%02ld",
    336                         resp->elapsed.tv_sec, resp->elapsed.tv_usec / 10000);
     322                printf("%u.%02u",
     323                        (unsigned)resp->elapsed_ms / 1000,
     324                        (unsigned)(resp->elapsed_ms / 10) % 100);
    337325                break;
    338326            case 'k':   /* Signals delivered.  */
    339                 fprintf(fp, "%ld", resp->ru.ru_nsignals);
     327                printf("%lu", resp->ru.ru_nsignals);
    340328                break;
    341329            case 'p':   /* Average stack segment.  */
    342                 fprintf(fp, "%lu",
    343                         MSEC_TO_TICKS(v) == 0 ? 0 :
    344                         ptok((UL) resp->ru.ru_isrss) / MSEC_TO_TICKS(v));
     330                printf("%lu", ptok((UL) resp->ru.ru_isrss) / cpu_ticks);
    345331                break;
    346332            case 'r':   /* Incoming socket messages received.  */
    347                 fprintf(fp, "%ld", resp->ru.ru_msgrcv);
     333                printf("%lu", resp->ru.ru_msgrcv);
    348334                break;
    349335            case 's':   /* Outgoing socket messages sent.  */
    350                 fprintf(fp, "%ld", resp->ru.ru_msgsnd);
     336                printf("%lu", resp->ru.ru_msgsnd);
    351337                break;
    352338            case 't':   /* Average resident set size.  */
    353                 fprintf(fp, "%lu",
    354                         MSEC_TO_TICKS(v) == 0 ? 0 :
    355                         ptok((UL) resp->ru.ru_idrss) / MSEC_TO_TICKS(v));
     339                printf("%lu", ptok((UL) resp->ru.ru_idrss) / cpu_ticks);
    356340                break;
    357341            case 'w':   /* Voluntary context switches.  */
    358                 fprintf(fp, "%ld", resp->ru.ru_nvcsw);
     342                printf("%lu", resp->ru.ru_nvcsw);
    359343                break;
    360344            case 'x':   /* Exit status.  */
    361                 fprintf(fp, "%d", WEXITSTATUS(resp->waitstatus));
    362                 break;
    363             case '\0':
    364                 putc('?', fp);
    365                 return;
    366             default:
    367                 putc('?', fp);
    368                 putc(*fmt, fp);
     345                printf("%u", WEXITSTATUS(resp->waitstatus));
     346                break;
    369347            }
    370             ++fmt;
    371348            break;
    372349
     350#ifdef NOT_NEEDED_YET
    373351        case '\\':      /* Format escape.  */
    374352            switch (*++fmt) {
     353            default:
     354                putc('\\', stdout);
     355                /*FALLTHROUGH*/
     356            case '\\':
     357                if (!*fmt) goto ret;
     358                putc(*fmt, stdout);
     359                break;
    375360            case 't':
    376                 putc('\t', fp);
     361                putc('\t', stdout);
    377362                break;
    378363            case 'n':
    379                 putc('\n', fp);
    380                 break;
    381             case '\\':
    382                 putc('\\', fp);
    383                 break;
    384             default:
    385                 putc('?', fp);
    386                 putc('\\', fp);
    387                 putc(*fmt, fp);
     364                putc('\n', stdout);
     365                break;
    388366            }
    389             ++fmt;
    390367            break;
    391 
    392         default:
    393             putc(*fmt++, fp);
     368#endif
    394369        }
    395 
    396         if (ferror(fp))
    397             bb_error_msg_and_die(bb_msg_write_error);
    398     }
    399     putc('\n', fp);
    400 
    401     if (ferror(fp))
    402         bb_error_msg_and_die(bb_msg_write_error);
     370        ++fmt;
     371    }
     372 /* ret: */
     373    putc('\n', stdout);
    403374}
    404375
     
    410381    __sighandler_t interrupt_signal, quit_signal;
    411382
    412     gettimeofday(&resp->start, (struct timezone *) 0);
     383    resp->elapsed_ms = monotonic_us() / 1000;
    413384    pid = vfork();      /* Run CMD as child process.  */
    414385    if (pid < 0)
     
    417388        /* Don't cast execvp arguments; that causes errors on some systems,
    418389           versus merely warnings if the cast is left off.  */
    419         execvp(cmd[0], cmd);
     390        BB_EXECVP(cmd[0], cmd);
    420391        bb_error_msg("cannot run %s", cmd[0]);
    421392        _exit(errno == ENOENT ? 127 : 126);
     
    434405}
    435406
     407int time_main(int argc, char **argv);
    436408int time_main(int argc, char **argv)
    437409{
    438     int gotone;
    439410    resource_t res;
    440411    const char *output_format = default_format;
    441 
    442     argc--;
    443     argv++;
     412    char c;
     413
     414    goto next;
    444415    /* Parse any options  -- don't use getopt() here so we don't
    445416     * consume the args of our client application... */
    446     while (argc > 0 && **argv == '-') {
    447         gotone = 0;
    448         while (gotone == 0 && *++(*argv)) {
    449             switch (**argv) {
     417    while (argc > 0 && argv[0][0] == '-') {
     418        while ((c = *++*argv)) {
     419            switch (c) {
    450420            case 'v':
    451421                output_format = long_format;
     
    457427                bb_show_usage();
    458428            }
    459             argc--;
    460             argv++;
    461             gotone = 1;
    462429        }
    463     }
    464 
    465     if (argv == NULL || *argv == NULL)
    466         bb_show_usage();
     430 next:
     431        argv++;
     432        argc--;
     433        if (!argc)
     434            bb_show_usage();
     435    }
    467436
    468437    run_command(argv, &res);
    469     summarize(stderr, output_format, argv, &res);
    470     fflush(stderr);
     438
     439    /* Cheat. printf's are shorter :) */
     440    stdout = stderr;
     441    dup2(2, 1); /* just in case libc does something silly :( */
     442    summarize(output_format, argv, &res);
    471443
    472444    if (WIFSTOPPED(res.waitstatus))
    473         exit(WSTOPSIG(res.waitstatus));
    474     else if (WIFSIGNALED(res.waitstatus))
    475         exit(WTERMSIG(res.waitstatus));
    476     else if (WIFEXITED(res.waitstatus))
    477         exit(WEXITSTATUS(res.waitstatus));
    478     return 0;
    479 }
     445        return WSTOPSIG(res.waitstatus);
     446    if (WIFSIGNALED(res.waitstatus))
     447        return WTERMSIG(res.waitstatus);
     448    if (WIFEXITED(res.waitstatus))
     449        return WEXITSTATUS(res.waitstatus);
     450    fflush_stdout_and_exit(0);
     451}
Note: See TracChangeset for help on using the changeset viewer.