Based on patch from Piergiorgio Sartor <piergiorgio.sartor@xxxxxxxx> 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@xxxxxxxxxx> --- include/pathnames.h | 1 + sys-utils/rtcwake.8 | 4 ++++ sys-utils/rtcwake.c | 24 +++++++++++++++++++++++- 3 files changed, 28 insertions(+), 1 deletions(-) diff --git a/include/pathnames.h b/include/pathnames.h index ead448e..f958a13 100644 --- a/include/pathnames.h +++ b/include/pathnames.h @@ -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" diff --git a/sys-utils/rtcwake.8 b/sys-utils/rtcwake.8 index dad4a24..af0e232 100644 --- a/sys-utils/rtcwake.8 +++ b/sys-utils/rtcwake.8 @@ -92,6 +92,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 diff --git a/sys-utils/rtcwake.c b/sys-utils/rtcwake.c index 4b84373..e56d1c0 100644 --- a/sys-utils/rtcwake.c +++ b/sys-utils/rtcwake.c @@ -36,6 +36,7 @@ #include <linux/rtc.h> #include "nls.h" +#include "pathnames.h" /* constants from legacy PC/AT hardware */ #define RTC_PF 0x40 @@ -295,6 +296,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; @@ -334,6 +336,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; @@ -428,7 +431,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); @@ -450,6 +457,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); @@ -464,6 +472,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; @@ -483,5 +505,5 @@ int main(int argc, char **argv) close(fd); - exit(EXIT_SUCCESS); + return rc; } -- 1.6.2.5 -- To unsubscribe from this list: send the line "unsubscribe util-linux-ng" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html