]> err.no Git - util-linux/commitdiff
rtcwake: add S5 support
authorKarel Zak <kzak@redhat.com>
Tue, 18 Aug 2009 13:48:34 +0000 (15:48 +0200)
committerKarel Zak <kzak@redhat.com>
Mon, 7 Sep 2009 10:04:26 +0000 (12:04 +0200)
Based on patch from
   Piergiorgio Sartor <piergiorgio.sartor@nexgo.de>
at
   https://bugzilla.redhat.com/show_bug.cgi?id=449115

Piergiorgio's note about S5:
> According to the ACPI specifications, chapter 4.7.2.4 "Real Time
> Clock Alarm", the wakeup from RTC, when supported, should work from
> *sleep* state S1-S3 and, optionally, from S4.
>
> Note 3 (same chapter) says that S5 is *not* a sleep state and should
> not be supported. Actually it also says that: "The OS will disable
> the RTC_EN bit prior to entering the G2/S5 or G3 states regardless."
>
> Nevertheless, on all PC supporting the RTC wakeup I tested, all were
> able to wake from S5.

Signed-off-by: Karel Zak <kzak@redhat.com>
include/pathnames.h
sys-utils/rtcwake.8
sys-utils/rtcwake.c

index ead448e3777c9c2c3aa485acbef2d67ba79c675f..f958a13bc9ec1c8ef878a966551deca9da1ffe61 100644 (file)
@@ -34,6 +34,7 @@
 #define _PATH_INITTAB          "/etc/inittab"
 #define _PATH_RC               "/etc/rc"
 #define _PATH_REBOOT           "/sbin/reboot"
+#define _PATH_SHUTDOWN         "/sbin/shutdown"
 #define _PATH_SINGLE           "/etc/singleboot"
 #define _PATH_SHUTDOWN_CONF    "/etc/shutdown.conf"
 
index f230e20568b91b016211e0034a13c9a56f0c5d05..999b678632fc6380ce400c3d9ddd162ca1c0a296 100644 (file)
@@ -100,6 +100,10 @@ and can be used even in the absence of low-level platform support for power
 management. This state operates similarly to Suspend-to-RAM, but includes a
 final step of writing memory contents to disk.
 .TP
+.B off
+ACPI state S5 (Poweroff). This is done by calling '/sbin/shutdown'.
+Not officially supported by ACPI, but usually working.
+.TP
 .B no
 Don't suspend. The rtcwake command sets RTC wakeup time only.
 .TP
index d75a69f3caa69153c5b8f5888616977fdd4bde43..1efc720989a5dab6bd98be2743a3bb1dd76482b7 100644 (file)
@@ -36,6 +36,7 @@
 #include <linux/rtc.h>
 
 #include "nls.h"
+#include "pathnames.h"
 #include "usleep.h"
 
 /* constants from legacy PC/AT hardware */
@@ -296,6 +297,7 @@ int main(int argc, char **argv)
        unsigned        seconds = 0;
        char            *suspend = DEFAULT_MODE;
 
+       int             rc = EXIT_SUCCESS;
        int             t;
        int             fd;
        time_t          alarm = 0;
@@ -335,6 +337,7 @@ int main(int argc, char **argv)
                                        || strcmp(optarg, "disk") == 0
                                        || strcmp(optarg, "on") == 0
                                        || strcmp(optarg, "no") == 0
+                                       || strcmp(optarg, "off") == 0
                           ) {
                                suspend = strdup(optarg);
                                break;
@@ -429,7 +432,11 @@ int main(int argc, char **argv)
        }
 
        /* this RTC must exist and (if we'll sleep) be wakeup-enabled */
+#ifdef O_CLOEXEC
+       fd = open(devname, O_RDONLY | O_CLOEXEC);
+#else
        fd = open(devname, O_RDONLY);
+#endif
        if (fd < 0) {
                perror(devname);
                exit(EXIT_FAILURE);
@@ -451,6 +458,7 @@ int main(int argc, char **argv)
                alarm += sys_time - rtc_time;
        } else
                alarm = rtc_time + seconds + 1;
+
        if (setup_alarm(fd, &alarm) < 0)
                exit(EXIT_FAILURE);
 
@@ -465,6 +473,20 @@ int main(int argc, char **argv)
        else if (strcmp(suspend, "on") != 0) {
                sync();
                suspend_system(suspend);
+       } else if (strcmp(suspend, "off") == 0) {
+               char *arg[4];
+               int i = 0;
+
+               arg[i++] = _PATH_SHUTDOWN;
+               arg[i++] = "-P";
+               arg[i++] = "now";
+               arg[i]   = NULL;
+
+               execv(arg[0], arg);
+
+               fprintf(stderr, _("%s: unable to execute %s: %s\n"),
+                               progname, _PATH_SHUTDOWN, strerror(errno));
+               rc = EXIT_FAILURE;
        } else {
                unsigned long data;
 
@@ -484,5 +506,5 @@ int main(int argc, char **argv)
 
        close(fd);
 
-       exit(EXIT_SUCCESS);
+       return rc;
 }