diff options
-rw-r--r-- | LICENSE | 4 | ||||
-rw-r--r-- | generated/flags.h | 6 | ||||
-rw-r--r-- | generated/globals.h | 2 | ||||
-rw-r--r-- | generated/help.h | 8 | ||||
-rw-r--r-- | generated/newtoys.h | 2 | ||||
-rw-r--r-- | lib/lib.c | 26 | ||||
-rw-r--r-- | lib/lib.h | 10 | ||||
-rw-r--r-- | lib/net.c | 19 | ||||
-rw-r--r-- | lib/xwrap.c | 2 | ||||
-rw-r--r-- | toys/net/ping.c | 41 | ||||
-rw-r--r-- | toys/net/sntp.c | 49 | ||||
-rw-r--r-- | toys/other/mountpoint.c | 6 | ||||
-rw-r--r-- | toys/other/readlink.c | 4 | ||||
-rw-r--r-- | toys/posix/date.c | 30 | ||||
-rw-r--r-- | toys/posix/ps.c | 37 | ||||
-rw-r--r-- | toys/posix/pwd.c | 2 | ||||
-rwxr-xr-x | www/news.html | 2 |
17 files changed, 135 insertions, 115 deletions
@@ -1,6 +1,4 @@ -Toybox is released under the Zero Clause BSD license (SPDX: 0BSD) - -Copyright (C) 2006, 2018 by Rob Landley <rob@landley.net> +Copyright (C) 2006, 2019 by Rob Landley <rob@landley.net> Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted. diff --git a/generated/flags.h b/generated/flags.h index f3d84947..0da3aad3 100644 --- a/generated/flags.h +++ b/generated/flags.h @@ -2494,9 +2494,9 @@ #undef FOR_sleep #endif -// sntp m:Sp:asdDqr#<4>17=10[!as] +// sntp M:m:Sp:asdDqr#<4>17=10[!as] #undef OPTSTR_sntp -#define OPTSTR_sntp "m:Sp:asdDqr#<4>17=10[!as]" +#define OPTSTR_sntp "M:m:Sp:asdDqr#<4>17=10[!as]" #ifdef CLEANUP_sntp #undef CLEANUP_sntp #undef FOR_sntp @@ -2509,6 +2509,7 @@ #undef FLAG_p #undef FLAG_S #undef FLAG_m +#undef FLAG_M #endif // sort gS:T:mo:k*t:xVbMcszdfirun gS:T:mo:k*t:xVbMcszdfirun @@ -5415,6 +5416,7 @@ #define FLAG_p (FORCED_FLAG<<6) #define FLAG_S (FORCED_FLAG<<7) #define FLAG_m (FORCED_FLAG<<8) +#define FLAG_M (FORCED_FLAG<<9) #endif #ifdef FOR_sort diff --git a/generated/globals.h b/generated/globals.h index ef478a4a..8521aa21 100644 --- a/generated/globals.h +++ b/generated/globals.h @@ -189,7 +189,7 @@ struct ping_data { struct sntp_data { long r; - char *p, *m; + char *p, *m, *M; }; // toys/net/tunctl.c diff --git a/generated/help.h b/generated/help.h index 6fcfc564..0d25cf5a 100644 --- a/generated/help.h +++ b/generated/help.h @@ -116,7 +116,7 @@ #define HELP_tunctl "usage: tunctl [-dtT] [-u USER] NAME\n\nCreate and delete tun/tap virtual ethernet devices.\n\n-T Use tap (ethernet frames) instead of tun (ip packets)\n-d Delete tun/tap device\n-t Create tun/tap device\n-u Set owner (user who can read/write device without root access)\n\n\n" -#define HELP_sntp "usage: sntp [-saSdDqm] [-r SHIFT] [-m ADDRESS] [-p PORT] [SERVER]\n\nSimple Network Time Protocol client. Query SERVER and display time.\n\n-p Use PORT (default 123)\n-s Set system clock suddenly\n-a Adjust system clock gradually\n-S Serve time instead of querying (bind to SERVER address if specified)\n-m Wait for updates from multicast ADDRESS (RFC 4330 says use 224.0.1.1)\n-d Daemonize (run in background re-querying )\n-D Daemonize but stay in foreground: re-query time every 1000 seconds\n-r Retry shift (every 1<<SHIFT seconds)\n-q Quiet (don't display time)\n\n" +#define HELP_sntp "usage: sntp [-saSdDqm] [-r SHIFT] [-m ADDRESS] [-p PORT] [SERVER]\n\nSimple Network Time Protocol client. Query SERVER and display time.\n\n-p Use PORT (default 123)\n-s Set system clock suddenly\n-a Adjust system clock gradually\n-S Serve time instead of querying (bind to SERVER address if specified)\n-m Wait for updates from multicast ADDRESS (RFC 4330 says use 224.0.1.1)\n-M Multicast server on ADDRESS\n-d Daemonize (run in background re-querying )\n-D Daemonize but stay in foreground: re-query time every 1000 seconds\n-r Retry shift (every 1<<SHIFT seconds)\n-q Quiet (don't display time)\n\n" #define HELP_rfkill "Usage: rfkill COMMAND [DEVICE]\n\nEnable/disable wireless devices.\n\nCommands:\nlist [DEVICE] List current state\nblock DEVICE Disable device\nunblock DEVICE Enable device\n\nDEVICE is an index number, or one of:\nall, wlan(wifi), bluetooth, uwb(ultrawideband), wimax, wwan, gps, fm.\n\n" @@ -190,7 +190,7 @@ #define HELP_realpath "usage: realpath FILE...\n\nDisplay the canonical absolute pathname\n\n" -#define HELP_readlink "usage: readlink FILE\n\nWith no options, show what symlink points to, return error if not symlink.\n\nOptions for producing cannonical paths (all symlinks/./.. resolved):\n\n-e Canonical path to existing entry (fail if missing)\n-f Full path (fail if directory missing)\n-m Ignore missing entries, show where it would be\n-n No trailing newline\n-q Quiet (no output, just error code)\n\n" +#define HELP_readlink "usage: readlink FILE\n\nWith no options, show what symlink points to, return error if not symlink.\n\nOptions for producing canonical paths (all symlinks/./.. resolved):\n\n-e Canonical path to existing entry (fail if missing)\n-f Full path (fail if directory missing)\n-m Ignore missing entries, show where it would be\n-n No trailing newline\n-q Quiet (no output, just error code)\n\n" #define HELP_readahead "usage: readahead FILE...\n\nPreload files into disk cache.\n\n" @@ -212,7 +212,7 @@ #define HELP_nbd_client "usage: nbd-client [-ns] HOST PORT DEVICE\n\n-n Do not fork into background\n-s nbd swap support (lock server into memory)\n\n" -#define HELP_mountpoint "usage: mountpoint [-q] [-d] directory\n mountpoint [-q] [-x] device\n\n-q Be quiet, return zero if directory is a mountpoint\n-d Print major/minor device number of the directory\n-x Print major/minor device number of the block device\n\n" +#define HELP_mountpoint "usage: mountpoint [-qd] DIR\n mountpoint [-qx] DEVICE\n\nCheck whether the directory or device is a mountpoint.\n\n-q Be quiet, return zero if directory is a mountpoint\n-d Print major/minor device number of the directory\n-x Print major/minor device number of the block device\n\n" #define HELP_modinfo "usage: modinfo [-0] [-b basedir] [-k kernrelease] [-F field] [modulename...]\n\nDisplay module fields for all specified modules, looking in\n<basedir>/lib/modules/<kernrelease>/ (kernrelease defaults to uname -r).\n\n" @@ -492,7 +492,7 @@ #define HELP_renice "usage: renice [-gpu] -n increment ID ...\n\n" -#define HELP_pwd "usage: pwd [-L|-P]\n\nPrint working (current) directory.\n\n-L Use shell's path from $PWD (when applicable)\n-P Print cannonical absolute path\n\n" +#define HELP_pwd "usage: pwd [-L|-P]\n\nPrint working (current) directory.\n\n-L Use shell's path from $PWD (when applicable)\n-P Print canonical absolute path\n\n" #define HELP_pkill "usage: pkill [-fnovx] [-SIGNAL|-l SIGNAL] [PATTERN] [-G GID,] [-g PGRP,] [-P PPID,] [-s SID,] [-t TERM,] [-U UID,] [-u EUID,]\n\n-l Send SIGNAL (default SIGTERM)\n-V Verbose\n-f Check full command line for PATTERN\n-G Match real Group ID(s)\n-g Match Process Group(s) (0 is current user)\n-n Newest match only\n-o Oldest match only\n-P Match Parent Process ID(s)\n-s Match Session ID(s) (0 for current)\n-t Match Terminal(s)\n-U Match real User ID(s)\n-u Match effective User ID(s)\n-v Negate the match\n-x Match whole command (not substring)\n\n" diff --git a/generated/newtoys.h b/generated/newtoys.h index 2938e68d..98a75e7f 100644 --- a/generated/newtoys.h +++ b/generated/newtoys.h @@ -226,7 +226,7 @@ USE_SHRED(NEWTOY(shred, "<1zxus#<1n#<1o#<0f", TOYFLAG_USR|TOYFLAG_BIN)) USE_SKELETON(NEWTOY(skeleton, "(walrus)(blubber):;(also):e@d*c#b:a", TOYFLAG_USR|TOYFLAG_BIN)) USE_SKELETON_ALIAS(NEWTOY(skeleton_alias, "b#dq", TOYFLAG_USR|TOYFLAG_BIN)) USE_SLEEP(NEWTOY(sleep, "<1", TOYFLAG_BIN)) -USE_SNTP(NEWTOY(sntp, "m:Sp:asdDqr#<4>17=10[!as]", TOYFLAG_USR|TOYFLAG_BIN)) +USE_SNTP(NEWTOY(sntp, "M:m:Sp:asdDqr#<4>17=10[!as]", TOYFLAG_USR|TOYFLAG_BIN)) USE_SORT(NEWTOY(sort, USE_SORT_FLOAT("g")"S:T:m" "o:k*t:" "xVbMcszdfirun", TOYFLAG_USR|TOYFLAG_BIN)) USE_SPLIT(NEWTOY(split, ">2a#<1=2>9b#<1l#<1[!bl]", TOYFLAG_USR|TOYFLAG_BIN)) USE_START(NEWTOY(start, "", TOYFLAG_USR|TOYFLAG_SBIN)) @@ -248,7 +248,7 @@ struct string_list *find_in_path(char *path, char *filename) cwd = xgetcwd(); for (;;) { - char *next = strchr(path, ':'); + char *res, *next = strchr(path, ':'); int len = next ? next-path : strlen(path); struct string_list *rnext; struct stat st; @@ -257,9 +257,7 @@ struct string_list *find_in_path(char *path, char *filename) + (len ? len : strlen(cwd)) + 2); if (!len) sprintf(rnext->str, "%s/%s", cwd, filename); else { - char *res = rnext->str; - - memcpy(res, path, len); + memcpy(res = rnext->str, path, len); res += len; *(res++) = '/'; strcpy(res, filename); @@ -553,6 +551,26 @@ void msleep(long miliseconds) nanosleep(&ts, &ts); } +// Adjust timespec by nanosecond offset +void nanomove(struct timespec *ts, long long offset) +{ + long long nano = ts->tv_nsec + offset, secs = nano/1000000000; + + ts->tv_sec += secs; + nano %= 1000000000; + if (nano<0) { + ts->tv_sec--; + nano += 1000000000; + } + ts->tv_nsec = nano; +} + +// return difference between two timespecs in nanosecs +long long nanodiff(struct timespec *old, struct timespec *new) +{ + return (new->tv_sec - old->tv_sec)*1000000000LL+(new->tv_nsec - old->tv_nsec); +} + // return 1<<x of highest bit set int highest_bit(unsigned long l) { @@ -205,6 +205,8 @@ struct string_list **splitpath(char *path, struct string_list **list); char *readfileat(int dirfd, char *name, char *buf, off_t *len); char *readfile(char *name, char *buf, off_t len); void msleep(long miliseconds); +void nanomove(struct timespec *ts, long long offset); +long long nanodiff(struct timespec *old, struct timespec *new); int highest_bit(unsigned long l); int64_t peek_le(void *ptr, unsigned size); int64_t peek_be(void *ptr, unsigned size); @@ -301,6 +303,13 @@ void tty_sigreset(int i); void start_redraw(unsigned *width, unsigned *height); // net.c + +union socksaddr { + struct sockaddr s; + struct sockaddr_in in; + struct sockaddr_in6 in6; +}; + int xsocket(int domain, int type, int protocol); void xsetsockopt(int fd, int level, int opt, void *val, socklen_t len); struct addrinfo *xgetaddrinfo(char *host, char *port, int family, int socktype, @@ -311,6 +320,7 @@ int xpoll(struct pollfd *fds, int nfds, int timeout); int pollinate(int in1, int in2, int out1, int out2, int timeout, int shutdown_timeout); char *ntop(struct sockaddr *sa); void xsendto(int sockfd, void *buf, size_t len, struct sockaddr *dest); +int xrecvwait(int fd, char *buf, int len, union socksaddr *sa, int timeout); // password.c int get_salt(char *salt, char * algo); @@ -138,3 +138,22 @@ void xsendto(int sockfd, void *buf, size_t len, struct sockaddr *dest) if (rc != len) perror_exit("sendto"); } + +// xrecvfrom with timeout in milliseconds +int xrecvwait(int fd, char *buf, int len, union socksaddr *sa, int timeout) +{ + socklen_t sl = sizeof(*sa); + + if (timeout >= 0) { + struct pollfd pfd; + + pfd.fd = fd; + pfd.events = POLLIN; + if (!xpoll(&pfd, 1, timeout)) return 0; + } + + len = recvfrom(fd, buf, len, 0, (void *)sa, &sl); + if (len<0) perror_exit("recvfrom"); + + return len; +} diff --git a/lib/xwrap.c b/lib/xwrap.c index 08b814f1..12016a21 100644 --- a/lib/xwrap.c +++ b/lib/xwrap.c @@ -504,7 +504,7 @@ void xstat(char *path, struct stat *st) if(stat(path, st)) perror_exit("Can't stat %s", path); } -// Cannonicalize path, even to file with one or more missing components at end. +// Canonicalize path, even to file with one or more missing components at end. // if exact, require last path component to exist char *xabspath(char *path, int exact) { diff --git a/toys/net/ping.c b/toys/net/ping.c index bc3381d8..81dca99f 100644 --- a/toys/net/ping.c +++ b/toys/net/ping.c @@ -55,6 +55,7 @@ GLOBALS( unsigned long sent, recv, fugit, min, max; ) +// Print a summary. Called as a single handler or at exit. static void summary(int sig) { if (!(toys.optflags&FLAG_q) && TT.sent && TT.sa) { @@ -87,38 +88,32 @@ void ping_main(void) { struct addrinfo *ai, *ai2; struct ifaddrs *ifa, *ifa2 = 0; - union { - struct sockaddr_in in; - struct sockaddr_in6 in6; - } src_addr, src_addr2; - struct sockaddr *sa = (void *)&src_addr, *sa2 = (void *)&src_addr2; - struct pollfd pfd; + struct icmphdr *ih = (void *)toybuf; + union socksaddr srcaddr, srcaddr2; + struct sockaddr *sa = (void *)&srcaddr; int family = 0, len; long long tnext, tW, tnow, tw; unsigned short seq = 0, pkttime; - struct icmphdr *ih = (void *)toybuf; - // Interval + // Set nonstatic default values if (!(toys.optflags&FLAG_i)) TT.i = (toys.optflags&FLAG_f) ? 200 : 1000; else if (TT.i<200 && getuid()) error_exit("need root for -i <200"); if (!(toys.optflags&FLAG_s)) TT.s = 56; // 64-PHDR_LEN if ((toys.optflags&(FLAG_f|FLAG_c)) == FLAG_f) TT.c = 15; // ipv4 or ipv6? (0 = autodetect if -I or arg have only one address type.) - if ((toys.optflags&FLAG_6) || toys.which->name[4] == '6') family = AF_INET6; - else if (toys.optflags&FLAG_4) family = AF_INET; + if (FLAG(6) || strchr(toys.which->name, '6')) family = AF_INET6; + else if (FLAG(4)) family = AF_INET; else family = 0; - sigatexit(summary); - - // If -I src_addr look it up. Allow numeric address of correct type. - memset(&src_addr, 0, sizeof(src_addr)); + // If -I srcaddr look it up. Allow numeric address of correct type. + memset(&srcaddr, 0, sizeof(srcaddr)); if (TT.I) { if (!(toys.optflags&FLAG_6) && inet_pton(AF_INET, TT.I, - (void *)&src_addr.in.sin_addr)) + (void *)&srcaddr.in.sin_addr)) family = AF_INET; else if (!(toys.optflags&FLAG_4) && inet_pton(AF_INET6, TT.I, - (void *)&src_addr.in6.sin6_addr)) + (void *)&srcaddr.in6.sin6_addr)) family = AF_INET6; else if (getifaddrs(&ifa2)) perror_exit("getifaddrs"); } @@ -160,7 +155,7 @@ void ping_main(void) } xexit(); } - if (TT.I && bind(TT.sock, sa, sizeof(src_addr))) perror_exit("bind"); + if (TT.I && bind(TT.sock, sa, sizeof(srcaddr))) perror_exit("bind"); if (toys.optflags&FLAG_m) { int mark = TT.m; @@ -191,6 +186,8 @@ void ping_main(void) tnext = millitime(); if (TT.w) tw = TT.w*1000+tnext; + sigatexit(summary); + // Send/receive packets for (;;) { int waitms = INT_MAX; @@ -236,13 +233,9 @@ void ping_main(void) // wait for next packet or timeout if (waitms<0) waitms = 0; - pfd.fd = TT.sock; - pfd.events = POLLIN; - if (0>(len = poll(&pfd, 1, waitms))) break; - if (!len) continue; + if (!(len = xrecvwait(TT.sock, toybuf, sizeof(toybuf), &srcaddr2, waitms))) + continue; - len = sizeof(src_addr2); - len = recvfrom(TT.sock, toybuf, sizeof(toybuf), 0, sa2, (void *)&len); TT.recv++; TT.fugit += (pkttime = millitime()-*(unsigned *)(ih+1)); @@ -251,7 +244,7 @@ void ping_main(void) if (!(toys.optflags&FLAG_q)) { if (toys.optflags&FLAG_f) xputc('\b'); else { - printf("%d bytes from %s: icmp_seq=%d ttl=%d", len, ntop(sa2), + printf("%d bytes from %s: icmp_seq=%d ttl=%d", len, ntop(&srcaddr2.s), ih->un.echo.sequence, 0); if (len >= sizeof(*ih)+4) printf(" time=%u ms", pkttime); diff --git a/toys/net/sntp.c b/toys/net/sntp.c index edccd209..b1ecb1be 100644 --- a/toys/net/sntp.c +++ b/toys/net/sntp.c @@ -6,7 +6,7 @@ modes: oneshot display, oneshot set, persist, serve, multi -USE_SNTP(NEWTOY(sntp, "m:Sp:asdDqr#<4>17=10[!as]", TOYFLAG_USR|TOYFLAG_BIN)) +USE_SNTP(NEWTOY(sntp, "M:m:Sp:asdDqr#<4>17=10[!as]", TOYFLAG_USR|TOYFLAG_BIN)) config SNTP bool "sntp" @@ -21,6 +21,7 @@ config SNTP -a Adjust system clock gradually -S Serve time instead of querying (bind to SERVER address if specified) -m Wait for updates from multicast ADDRESS (RFC 4330 says use 224.0.1.1) + -M Multicast server on ADDRESS -d Daemonize (run in background re-querying ) -D Daemonize but stay in foreground: re-query time every 1000 seconds -r Retry shift (every 1<<SHIFT seconds) @@ -32,50 +33,12 @@ config SNTP GLOBALS( long r; - char *p, *m; + char *p, *m, *M; ) // Seconds from 1900 to 1970, including appropriate leap days #define SEVENTIES 2208988800L -union socksaddr { - struct sockaddr_in in; - struct sockaddr_in6 in6; -}; - -// timeout in milliseconds -int xrecvwait(int fd, char *buf, int len, union socksaddr *sa, int timeout) -{ - socklen_t sl = sizeof(*sa); - - if (timeout >= 0) { - struct pollfd pfd; - - pfd.fd = fd; - pfd.events = POLLIN; - if (!xpoll(&pfd, 1, timeout)) return 0; - } - - len = recvfrom(fd, buf, len, 0, (void *)sa, &sl); - if (len<0) perror_exit("recvfrom"); - - return len; -} - -// Adjust timespec by nanosecond offset -static void nanomove(struct timespec *ts, long long offset) -{ - long long nano = ts->tv_nsec + offset, secs = nano/1000000000; - - ts->tv_sec += secs; - nano %= 1000000000; - if (nano<0) { - ts->tv_sec--; - nano += 1000000000; - } - ts->tv_nsec = nano; -} - // Get time and return ntptime (saving timespec in pointer if not null) // NTP time is high 32 bits = seconds since 1970 (blame RFC 868), low 32 bits // fraction of a second. @@ -104,12 +67,6 @@ static void doublyso(unsigned long long now, struct timespec *tv) tv->tv_nsec = ((now&0xFFFFFFFF)*1000000000)>>32; } -// return difference between two timespecs in nanosecs -static long long nanodiff(struct timespec *old, struct timespec *new) -{ - return (new->tv_sec - old->tv_sec)*1000000000LL+(new->tv_nsec - old->tv_nsec); -} - void sntp_main(void) { struct timespec tv, tv2; diff --git a/toys/other/mountpoint.c b/toys/other/mountpoint.c index 98e1d309..a97c600a 100644 --- a/toys/other/mountpoint.c +++ b/toys/other/mountpoint.c @@ -8,8 +8,10 @@ config MOUNTPOINT bool "mountpoint" default y help - usage: mountpoint [-q] [-d] directory - mountpoint [-q] [-x] device + usage: mountpoint [-qd] DIR + mountpoint [-qx] DEVICE + + Check whether the directory or device is a mountpoint. -q Be quiet, return zero if directory is a mountpoint -d Print major/minor device number of the directory diff --git a/toys/other/readlink.c b/toys/other/readlink.c index 6a1a7443..beef92b0 100644 --- a/toys/other/readlink.c +++ b/toys/other/readlink.c @@ -12,7 +12,7 @@ config READLINK With no options, show what symlink points to, return error if not symlink. - Options for producing cannonical paths (all symlinks/./.. resolved): + Options for producing canonical paths (all symlinks/./.. resolved): -e Canonical path to existing entry (fail if missing) -f Full path (fail if directory missing) @@ -28,7 +28,7 @@ void readlink_main(void) { char *s; - // Calculating full cannonical path? + // Calculating full canonical path? // Take advantage of flag positions to calculate m = -1, f = 0, e = 1 if (toys.optflags & (FLAG_f|FLAG_e|FLAG_m)) s = xabspath(*toys.optargs, (toys.optflags&(FLAG_f|FLAG_e))-1); diff --git a/toys/posix/date.c b/toys/posix/date.c index 40c1fed2..09a548f5 100644 --- a/toys/posix/date.c +++ b/toys/posix/date.c @@ -56,17 +56,17 @@ GLOBALS( unsigned nano; ) -static const char *formats[] = { - // Formats with years must come first. - "%Y-%m-%d %H:%M:%S", "%Y-%m-%d %H:%M", "%Y-%m-%d", - "%H:%M:%S", "%H:%M", 0 -}; - // Handle default posix date format (mmddhhmm[[cc]yy]) or @UNIX[.FRAC] // returns 0 success, nonzero for error static int parse_default(char *str, struct tm *tm) { + time_t now; int len = 0, i; + char *formats[] = { + // Formats with years must come first. + "%Y-%m-%d %H:%M:%S", "%Y-%m-%d %H:%M", "%Y-%m-%d", + "%H:%M:%S", "%H:%M" + }; // Parse @UNIXTIME[.FRACTION] if (*str == '@') { @@ -87,23 +87,20 @@ static int parse_default(char *str, struct tm *tm) } if (str[len]) return 1; tt = ll; - gmtime_r(&tt, tm); + localtime_r(&tt, tm); return 0; } // Is it one of the fancy formats? - for (i = 0; formats[i]; ++i) { - time_t now = time(NULL); + for (i = 0; i<ARRAY_LEN(formats); i++) { char *p; - if (!strchr(formats[i], 'Y')) { - localtime_r(&now, tm); - tm->tm_hour = tm->tm_min = tm->tm_sec = 0; - } + now = time(0); + localtime_r(&now, tm); + tm->tm_hour = tm->tm_min = tm->tm_sec = 0; if ((p = strptime(str, formats[i], tm)) && !*p) return 0; } - memset(tm, 0, sizeof(struct tm)); // Posix format? sscanf(str, "%2u%2u%2u%2u%n", &tm->tm_mon, &tm->tm_mday, &tm->tm_hour, @@ -141,6 +138,11 @@ static int parse_default(char *str, struct tm *tm) str += len; } else tm->tm_sec = 0; + // Fix up weekday + now = mktime(tm); + localtime_r(&now, tm); + + // shouldn't be any trailing garbage return *str; } diff --git a/toys/posix/ps.c b/toys/posix/ps.c index eff980f3..faddf685 100644 --- a/toys/posix/ps.c +++ b/toys/posix/ps.c @@ -1431,6 +1431,11 @@ static int header_line(int line, int rev) return line-1; } +static void top_cursor_cleanup(void) +{ + tty_esc("?25h"); +} + static void top_common( int (*filter)(long long *oslot, long long *nslot, int milis)) { @@ -1447,8 +1452,12 @@ static void top_common( int i, lines, topoff = 0, done = 0; char stdout_buf[BUFSIZ]; - // Avoid flicker in interactive mode. - if (!FLAG(b)) setbuf(stdout, stdout_buf); + // Avoid flicker and hide the cursor in interactive mode. + if (!FLAG(b)) { + setbuf(stdout, stdout_buf); + tty_esc("?25l"); + sigatexit(top_cursor_cleanup); + } toys.signal = SIGWINCH; TT.bits = get_headers(TT.fields, toybuf, sizeof(toybuf)); @@ -1535,6 +1544,8 @@ static void top_common( // Display "top" header. if (*toys.which->name == 't') { struct ofields field; + char *hr0 = toybuf+sizeof(toybuf)-32, *hr1 = hr0-32, *hr2 = hr1-32, + *hr3 = hr2-32; long long ll, up = 0; long run[6]; int j; @@ -1555,13 +1566,21 @@ static void top_common( "\nBuffers:","\nCached:","\nSwapTotal:","\nSwapFree:"}[i]); run[i] = pos ? atol(pos) : 0; } - sprintf(toybuf, - "Mem:%10ldk total,%9ldk used,%9ldk free,%9ldk buffers", - run[0], run[0]-run[1], run[1], run[2]); + + human_readable(hr0, 1024*run[0], 0); + human_readable(hr1, 1024*(run[0]-run[1]), 0); + human_readable(hr2, 1024*run[1], 0); + human_readable(hr3, 1024*run[2], 0); + sprintf(toybuf, " Mem: %9s total, %9s used, %9s free, %9s buffers", + hr0, hr1, hr2, hr3); lines = header_line(lines, 0); - sprintf(toybuf, - "Swap:%9ldk total,%9ldk used,%9ldk free,%9ldk cached", - run[4], run[4]-run[5], run[5], run[3]); + + human_readable(hr0, 1024*run[4], 0); + human_readable(hr1, 1024*(run[4]-run[5]), 0); + human_readable(hr2, 1024*run[5], 0); + human_readable(hr3, 1024*run[3], 0); + sprintf(toybuf, " Swap: %9s total, %9s used, %9s free, %9s cached", + hr0, hr1, hr2, hr3); lines = header_line(lines, 0); } @@ -1660,7 +1679,7 @@ static void top_common( // Flush unknown escape sequences. if (i==27) while (0<scan_key_getsize(scratch, 0, &TT.width, &TT.height)); - else if (i==' ') { + else if (i=='\r' || i==' ') { timeout = 0; break; } else if (toupper(i)=='R') diff --git a/toys/posix/pwd.c b/toys/posix/pwd.c index 08f39bf6..4c6ae99b 100644 --- a/toys/posix/pwd.c +++ b/toys/posix/pwd.c @@ -15,7 +15,7 @@ config PWD Print working (current) directory. -L Use shell's path from $PWD (when applicable) - -P Print cannonical absolute path + -P Print canonical absolute path */ #define FOR_pwd diff --git a/www/news.html b/www/news.html index 600b298d..d010faa2 100755 --- a/www/news.html +++ b/www/news.html @@ -42,7 +42,7 @@ arguments, <b>cmp</b> accepts --quiet and --silent as synonyms for -s, <b>hostna added -sfd, <b>head</b> added --bytes as a synonym for -c and --lines as a synonym for -n, <b>mktemp</b> added -t and fixed -u, <b>sed</b> added -z and -iEXT to keep backup files, <b>md5sum</b> and sha1sum added --status and --check as synonyms -s and -c, -<b>readlink</b> added --cannonicalize as a synonym for -f, <b>sort</b> grew -V, +<b>readlink</b> added --canonicalize as a synonym for -f, <b>sort</b> grew -V, <b>patch</b> added -s its synonym --quiet, <b>stat</b> added --format as a synonym for -c, <b>xargs</b> added -p -t -r, Eduardas Meile asked |