summaryrefslogtreecommitdiffstats
path: root/sys-utils/rtcwake.c
diff options
context:
space:
mode:
authorKarel Zak2009-08-18 15:48:34 +0200
committerKarel Zak2009-09-07 12:04:26 +0200
commit77f5744c982cd57b1bf1181f8f37023512236902 (patch)
tree391e615804c7696d868180e4b3df0b1474e95459 /sys-utils/rtcwake.c
parentmkswap: fix memory leaks, cleanup check_blocks() (diff)
downloadkernel-qcow2-util-linux-77f5744c982cd57b1bf1181f8f37023512236902.tar.gz
kernel-qcow2-util-linux-77f5744c982cd57b1bf1181f8f37023512236902.tar.xz
kernel-qcow2-util-linux-77f5744c982cd57b1bf1181f8f37023512236902.zip
rtcwake: add S5 support
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>
Diffstat (limited to 'sys-utils/rtcwake.c')
-rw-r--r--sys-utils/rtcwake.c24
1 files changed, 23 insertions, 1 deletions
diff --git a/sys-utils/rtcwake.c b/sys-utils/rtcwake.c
index d75a69f3c..1efc72098 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"
#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;
}