aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--LICENSE4
-rw-r--r--generated/flags.h6
-rw-r--r--generated/globals.h2
-rw-r--r--generated/help.h8
-rw-r--r--generated/newtoys.h2
-rw-r--r--lib/lib.c26
-rw-r--r--lib/lib.h10
-rw-r--r--lib/net.c19
-rw-r--r--lib/xwrap.c2
-rw-r--r--toys/net/ping.c41
-rw-r--r--toys/net/sntp.c49
-rw-r--r--toys/other/mountpoint.c6
-rw-r--r--toys/other/readlink.c4
-rw-r--r--toys/posix/date.c30
-rw-r--r--toys/posix/ps.c37
-rw-r--r--toys/posix/pwd.c2
-rwxr-xr-xwww/news.html2
17 files changed, 135 insertions, 115 deletions
diff --git a/LICENSE b/LICENSE
index 8bb7e5f5..24d959a4 100644
--- a/LICENSE
+++ b/LICENSE
@@ -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))
diff --git a/lib/lib.c b/lib/lib.c
index b074a92b..9d5c5f4b 100644
--- a/lib/lib.c
+++ b/lib/lib.c
@@ -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)
{
diff --git a/lib/lib.h b/lib/lib.h
index ed31ffa9..b36d7a75 100644
--- a/lib/lib.h
+++ b/lib/lib.h
@@ -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);
diff --git a/lib/net.c b/lib/net.c
index 346d17e9..d4373fbe 100644
--- a/lib/net.c
+++ b/lib/net.c
@@ -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