diff -Nru busybox-1.21.0/coreutils/Config.src src/coreutils/Config.src --- busybox-1.21.0/coreutils/Config.src 2013-09-27 14:21:31.330620871 +0200 +++ src/coreutils/Config.src 2013-09-27 14:14:41.771830750 +0200 @@ -555,6 +555,9 @@ help Allow for fractional numeric parameters. +config SLEEPUNTIL + bool "sleepuntil" + config SORT bool "sort" default y diff -Nru busybox-1.21.0/coreutils/Kbuild.src src/coreutils/Kbuild.src --- busybox-1.21.0/coreutils/Kbuild.src 2013-01-14 05:19:43.000000000 +0100 +++ src/coreutils/Kbuild.src 2013-09-27 14:14:41.771830750 +0200 @@ -64,6 +64,7 @@ lib-$(CONFIG_SHA512SUM) += md5_sha1_sum.o lib-$(CONFIG_SHA3SUM) += md5_sha1_sum.o lib-$(CONFIG_SLEEP) += sleep.o +lib-$(CONFIG_SLEEPUNTIL)+= sleepuntil.o lib-$(CONFIG_SPLIT) += split.o lib-$(CONFIG_SORT) += sort.o lib-$(CONFIG_STAT) += stat.o diff -Nru busybox-1.21.0/coreutils/sleepuntil.c src/coreutils/sleepuntil.c --- busybox-1.21.0/coreutils/sleepuntil.c 1970-01-01 01:00:00.000000000 +0100 +++ src/coreutils/sleepuntil.c 2013-09-27 14:18:32.497403613 +0200 @@ -0,0 +1,135 @@ +/* + * sleepuntil.c for busybox + * Created by on Wed Sep 18 15:41:32 2013 + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include /* for __NR_clock_gettime */ + +#include "libbb.h" + +//usage:#define sleepuntil_trivial_usage +//usage: "sleepuntil -q|" +//usage:#define sleepuntil_full_usage sleepuntil_trivial_usage + +static bool verbose = false; + +/* + * busybox won't link with -lrt, so use syscall(3) to invoke + * clock_gettime(2). + */ +static int my_clock_gettime(int clock, struct timespec *ts) +{ + return syscall(__NR_clock_gettime, clock, ts); +} + +static void usage(void) +{ + printf("usage: sleeptill -q | \n\n"); +} + +/* + * get CLOCK_MONOTONIC and print it to stdout. + */ +static int do_querymode(void) +{ + struct timespec ts; + + if (my_clock_gettime(CLOCK_MONOTONIC, &ts) < 0) { + perror("clock_gettime"); + return -1; + } + + printf("%u\n", (unsigned int)ts.tv_sec); + return 0; +} + +/* + * sleep until CLOCK_MONOTONIC reaches the until value. + */ +static int do_sleepuntil(const char *str_until) +{ + const char *end; + unsigned int until; + int amount; + struct timespec ts; + + until = strtof(str_until, (char**)&end); + if (*end) { + fprintf(stderr, "%s: invalid until value.", str_until); + return -1; + } + + if (my_clock_gettime(CLOCK_MONOTONIC, &ts) < 0) { + perror("clock_gettime"); + return -1; + } + + amount = until - ts.tv_sec; + if (amount <= 0) { + /* can't go back to the future (for now) */ + if (verbose) + printf("%i seconds late!\n", -amount); + return 0; + } + if (verbose) + printf("must sleep %u seconds.\n", amount); + + ts.tv_sec = amount; + ts.tv_nsec = 0; + + /* sleep in a signal friendly way */ + do { + nanosleep(&ts, &ts); + } while (errno == EINTR); + return 0; +} + +extern int sleepuntil_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; +int sleepuntil_main(int argc, char **argv) +{ + bool querymode = false; + + do { + int c = getopt(argc, argv, "qv"); + if (c < 0) + break; + switch (c) { + case 'q': + querymode = true; + break; + case 'v': + verbose = true; + break; + default: + usage(); + return EXIT_FAILURE; + } + } while (1); + + argc -= optind; + argv += optind; + + if (querymode) { + if (do_querymode() < 0) + return EXIT_FAILURE; + return EXIT_SUCCESS; + } else { + if (!argc) { + usage(); + return EXIT_FAILURE; + } + if (do_sleepuntil(argv[0]) < 0) + return EXIT_FAILURE; + return EXIT_SUCCESS; + } +} diff -Nru busybox-1.21.0/include/applets.src.h src/include/applets.src.h --- busybox-1.21.0/include/applets.src.h 2013-01-14 05:19:43.000000000 +0100 +++ src/include/applets.src.h 2013-09-27 14:14:41.775830778 +0200 @@ -335,6 +335,7 @@ IF_SLATTACH(APPLET(slattach, BB_DIR_SBIN, BB_SUID_DROP)) /* Do not make this applet NOFORK. It breaks ^C-ing of pauses in shells: */ IF_SLEEP(APPLET(sleep, BB_DIR_BIN, BB_SUID_DROP)) +IF_SLEEPUNTIL(APPLET(sleepuntil, BB_DIR_BIN, BB_SUID_DROP)) IF_SOFTLIMIT(APPLET_ODDNAME(softlimit, chpst, BB_DIR_USR_BIN, BB_SUID_DROP, softlimit)) IF_SORT(APPLET_NOEXEC(sort, sort, BB_DIR_USR_BIN, BB_SUID_DROP, sort)) IF_SPLIT(APPLET(split, BB_DIR_USR_BIN, BB_SUID_DROP))