X-Git-Url: https://git.librecmc.org/?a=blobdiff_plain;f=util-linux%2Frtcwake.c;h=66b08e34393090497df3785614bcd77254af435e;hb=baad6d889da960ff3336f16a8e5d25518f832c73;hp=6df7334fec2f6f548e72d07d731d52c035247100;hpb=68404f13d4bf4826e3609703dad5375763db28ab;p=oweals%2Fbusybox.git diff --git a/util-linux/rtcwake.c b/util-linux/rtcwake.c index 6df7334fe..66b08e343 100644 --- a/util-linux/rtcwake.c +++ b/util-linux/rtcwake.c @@ -3,6 +3,8 @@ * * This version was taken from util-linux and scrubbed down for busybox. * + * Licensed under GPLv2, see file LICENSE in this tarball for details. + * * This uses cross-platform Linux interfaces to enter a system sleep state, * and leave it no later than a specified time. It uses any RTC framework * driver that supports standard driver model wakeup flags. @@ -26,11 +28,9 @@ #define SYS_RTC_PATH "/sys/class/rtc/%s/device/power/wakeup" #define SYS_POWER_PATH "/sys/power/state" -#define DEFAULT_MODE "suspend" - -static time_t rtc_time; +#define DEFAULT_MODE "standby" -static int may_wakeup(const char *rtcname) +static NOINLINE bool may_wakeup(const char *rtcname) { ssize_t ret; char buf[128]; @@ -42,15 +42,15 @@ static int may_wakeup(const char *rtcname) snprintf(buf, sizeof(buf), SYS_RTC_PATH, rtcname); ret = open_read_close(buf, buf, sizeof(buf)); if (ret < 0) - return 0; + return false; /* wakeup events could be disabled or not supported */ return strncmp(buf, "enabled\n", 8) == 0; } -static void setup_alarm(int fd, time_t *wakeup) +static NOINLINE void setup_alarm(int fd, time_t *wakeup, time_t rtc_time) { - struct tm *tm; + struct tm *ptm; struct linux_rtc_wkalrm wake; /* The wakeup time is in POSIX time (more or less UTC). @@ -63,14 +63,14 @@ static void setup_alarm(int fd, time_t *wakeup) * Else mode is local so the time given to the RTC * will instead use the local time zone. */ - tm = localtime(wakeup); - - wake.time.tm_sec = tm->tm_sec; - wake.time.tm_min = tm->tm_min; - wake.time.tm_hour = tm->tm_hour; - wake.time.tm_mday = tm->tm_mday; - wake.time.tm_mon = tm->tm_mon; - wake.time.tm_year = tm->tm_year; + ptm = localtime(wakeup); + + wake.time.tm_sec = ptm->tm_sec; + wake.time.tm_min = ptm->tm_min; + wake.time.tm_hour = ptm->tm_hour; + wake.time.tm_mday = ptm->tm_mday; + wake.time.tm_mon = ptm->tm_mon; + wake.time.tm_year = ptm->tm_year; /* wday, yday, and isdst fields are unused by Linux */ wake.time.tm_wday = -1; wake.time.tm_yday = -1; @@ -89,15 +89,6 @@ static void setup_alarm(int fd, time_t *wakeup) } } -static void suspend_system(const char *suspend) -{ - FILE *f = xfopen(SYS_POWER_PATH, "w"); - fprintf(f, "%s\n", suspend); - fflush(f); - /* this executes after wake from suspend */ - fclose(f); -} - #define RTCWAKE_OPT_AUTO 0x01 #define RTCWAKE_OPT_LOCAL 0x02 #define RTCWAKE_OPT_UTC 0x04 @@ -107,8 +98,10 @@ static void suspend_system(const char *suspend) #define RTCWAKE_OPT_TIME 0x40 int rtcwake_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; -int rtcwake_main(int argc ATTRIBUTE_UNUSED, char **argv) +int rtcwake_main(int argc UNUSED_PARAM, char **argv) { + time_t rtc_time; + unsigned opt; const char *rtcname = NULL; const char *suspend; @@ -121,7 +114,7 @@ int rtcwake_main(int argc ATTRIBUTE_UNUSED, char **argv) int utc = -1; int fd; -#if ENABLE_GETOPT_LONG +#if ENABLE_LONG_OPTS static const char rtcwake_longopts[] ALIGN1 = "auto\0" No_argument "a" "local\0" No_argument "l" @@ -148,7 +141,7 @@ int rtcwake_main(int argc ATTRIBUTE_UNUSED, char **argv) seconds = xatoi(opt_seconds); if (opt & RTCWAKE_OPT_TIME) /* alarm time, time_t (absolute, seconds since 1/1 1970 UTC) */ - alarm_time = xatoi(opt_time); + alarm_time = xatol(opt_time); if (!alarm_time && !seconds) bb_error_msg_and_die("must provide wake time"); @@ -166,10 +159,13 @@ int rtcwake_main(int argc ATTRIBUTE_UNUSED, char **argv) bb_error_msg_and_die("%s not enabled for wakeup events", rtcname); /* relative or absolute alarm time, normalized to time_t */ - sys_time = time(0); - if (sys_time == (time_t)-1) - bb_perror_msg_and_die("read system time"); - rtc_time = rtc_read_time(fd, utc); + sys_time = time(NULL); + { + struct tm tm_time; + rtc_read_tm(&tm_time, fd); + rtc_time = rtc_tm2time(&tm_time, utc); + } + if (alarm_time) { if (alarm_time < sys_time) @@ -177,15 +173,15 @@ int rtcwake_main(int argc ATTRIBUTE_UNUSED, char **argv) alarm_time += sys_time - rtc_time; } else alarm_time = rtc_time + seconds + 1; - setup_alarm(fd, &alarm_time); + setup_alarm(fd, &alarm_time, rtc_time); sync(); printf("wakeup from \"%s\" at %s", suspend, ctime(&alarm_time)); - fflush(stdout); + fflush_all(); usleep(10 * 1000); if (strcmp(suspend, "on")) - suspend_system(suspend); + xopen_xwrite_close(SYS_POWER_PATH, suspend); else { /* "fake" suspend ... we'll do the delay ourselves */ unsigned long data;