mkfs_ext2: fix bad comment. no code changes
[oweals/busybox.git] / util-linux / rtcwake.c
index 6df7334fec2f6f548e72d07d731d52c035247100..66b08e34393090497df3785614bcd77254af435e 100644 (file)
@@ -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.
 
 #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;