From 77f5744c982cd57b1bf1181f8f37023512236902 Mon Sep 17 00:00:00 2001 From: Karel Zak Date: Tue, 18 Aug 2009 15:48:34 +0200 Subject: [PATCH] rtcwake: add S5 support Based on patch from Piergiorgio Sartor 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 --- include/pathnames.h | 1 + sys-utils/rtcwake.8 | 4 ++++ sys-utils/rtcwake.c | 24 +++++++++++++++++++++++- 3 files changed, 28 insertions(+), 1 deletion(-) diff --git a/include/pathnames.h b/include/pathnames.h index ead448e3..f958a13b 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 f230e205..999b6786 100644 --- a/sys-utils/rtcwake.8 +++ b/sys-utils/rtcwake.8 @@ -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 diff --git a/sys-utils/rtcwake.c b/sys-utils/rtcwake.c index d75a69f3..1efc7209 100644 --- a/sys-utils/rtcwake.c +++ b/sys-utils/rtcwake.c @@ -36,6 +36,7 @@ #include #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; } -- 2.39.5