Permalink
Browse files

add -a flag for specifying time in seconds from epoch

  • Loading branch information...
1 parent 4e43802 commit 36caa096342a17ce2061dd2523fd6f8508592877 @falconindy falconindy committed Dec 6, 2011
Showing with 50 additions and 11 deletions.
  1. +50 −11 wakeup.c
View
@@ -18,11 +18,13 @@
#define _GNU_SOURCE
#include <ctype.h>
#include <errno.h>
+#include <inttypes.h>
#include <getopt.h>
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
+#include <sys/time.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <time.h>
@@ -40,6 +42,7 @@ struct timespec_t {
extern char *program_invocation_short_name;
static const char *suspend_cmd;
+static long epochtime;
static long
timespec_to_seconds(struct timespec_t *ts)
@@ -51,16 +54,19 @@ static void
help(FILE *stream)
{
fprintf(stream, "usage: %s <timespec>\n\n"
+ " -a, --at SEC specify an absolute time in seconds from epoch\n"
" -c, --command CMD execute CMD instead of default '%s'\n"
" -h, --help display this help and exit\n\n"
"timespec can be any combination of hours, minutes, and seconds\n"
"specified by hH, mM, and sS, respecitively.\n\n"
"Examples:\n"
- " %s 1h 20m 42S # 1 hour, 20 minutes, 42 seconds\n"
- " %s 1h20M 2h # 3 hours, 20 minutes\n",
+ " %s 1h 20m 42S # 1 hour, 20 minutes, 42 seconds\n"
+ " %s 1h20M 2h # 3 hours, 20 minutes\n"
+ " %s -a $(date -d tomorrow +%%s) # 24 hours\n",
program_invocation_short_name,
SUSPEND_COMMAND,
program_invocation_short_name,
+ program_invocation_short_name,
program_invocation_short_name);
exit(stream == stderr ? EXIT_FAILURE : EXIT_SUCCESS);
@@ -100,13 +106,17 @@ parse_options(int argc, char **argv)
{
int opt;
static struct option opts[] = {
+ { "at", no_argument, NULL, 'a' },
{ "command", required_argument, NULL, 'c' },
{ "help", no_argument, NULL, 'h' },
{ 0, 0, 0, 0 }
};
- while((opt = getopt_long(argc, argv, "c:h", opts, NULL)) != -1) {
+ while((opt = getopt_long(argc, argv, "ac:h", opts, NULL)) != -1) {
switch(opt) {
+ case 'a':
+ epochtime = 1;
+ break;
case 'c':
suspend_cmd = optarg;
break;
@@ -163,17 +173,46 @@ parse_timefragment(const char *fragment, struct timespec_t *ts)
static int
parse_timespec(int optind, int argc, char **argv, struct timespec_t *ts)
{
- while(optind < argc) {
- if(parse_timefragment(argv[optind], ts) != 0) {
- fprintf(stderr, "failed to parse time: %s\n", argv[optind]);
+ if(epochtime) {
+ char *endptr;
+ intmax_t epoch, diff;
+ time_t now;
+
+ epoch = strtoimax(argv[optind], &endptr, 10);
+ if(*endptr != '\0') {
+ fprintf(stderr, "failed to parse absolute time: %s\n", argv[optind]);
return 1;
}
- optind++;
- }
- if(timespec_to_seconds(ts) == 0) {
- fprintf(stderr, "error: duration must be non-zero\n");
- return 1;
+ now = time(NULL);
+ if(now == (time_t)-1) {
+ fprintf(stderr, "error: failed to get current time\n");
+ return 1;
+ }
+
+ if(epoch < (intmax_t)now) {
+ fprintf(stderr, "error: cannot specify a time in the past\n");
+ return 1;
+ }
+
+ diff = epoch - (intmax_t)now;
+ ts->hour = diff / 3600;
+ diff %= 3600;
+ ts->min = diff / 60;
+ ts->sec = diff % 60;
+ } else {
+ while(optind < argc) {
+ if(parse_timefragment(argv[optind], ts) != 0) {
+ fprintf(stderr, "error: failed to parse time: %s\n", argv[optind]);
+ return 1;
+ }
+ optind++;
+ }
+
+ if(timespec_to_seconds(ts) == 0) {
+ fprintf(stderr, "error: duration must be non-zero\n");
+ return 1;
+ }
}
return 0;

0 comments on commit 36caa09

Please sign in to comment.