]> git.ipfire.org Git - thirdparty/util-linux.git/commitdiff
rtcwake: wait stdin to settle down before entering a system sleep
authorSami Kerola <kerolasa@iki.fi>
Sun, 3 Dec 2017 15:43:25 +0000 (15:43 +0000)
committerKarel Zak <kzak@redhat.com>
Tue, 2 Jan 2018 14:14:37 +0000 (15:14 +0100)
This can delay entering to system sleep up to 0.28 seconds while discarding
input, when stdin is interactive device.

[kzak@redhat.com: - add note to the man page]

Reference: https://github.com/karelzak/util-linux/issues/527
See-also: a85c39013491713ac0d9e24fd0f07b4fabdcfc17
Signed-off-by: Sami Kerola <kerolasa@iki.fi>
Signed-off-by: Karel Zak <kzak@redhat.com>
sys-utils/rtcwake.8.in
sys-utils/rtcwake.c

index b35860113c792e4bdc33dd69448f66c2d218d1e5..72eb0e34f5034d251958b5b3342ce8c1c65335f6 100644 (file)
@@ -48,8 +48,11 @@ an alarm up to 24 hours in the future.
 .PP
 The suspend setup maybe be interrupted by active hardware; for example wireless USB
 input devices that continue to send events for some fraction of a second after the
-return key is pressed. In this case is better to use sleep command before invoking
-suspend by rtcwake.
+return key is pressed.
+.BR rtcwake
+tries to avoid this problem and it waits to terminal to settle down before
+entering a system sleep.
+
 .SH OPTIONS
 .TP
 .BR \-A , " \-\-adjfile " \fIfile
index 20e40a07f63bbe75098b35f2098611131bde3589..b63c646277e411b1f0c0e9e33ab4240d02d22179 100644 (file)
 #include <fcntl.h>
 #include <getopt.h>
 #include <linux/rtc.h>
+#include <poll.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
 #include <sys/ioctl.h>
 #include <sys/time.h>
 #include <sys/types.h>
+#include <termios.h>
 #include <time.h>
 #include <unistd.h>
 
@@ -260,6 +262,22 @@ nothing:
        return NULL;
 }
 
+static void wait_stdin(struct rtcwake_control *ctl)
+{
+       struct pollfd fd[] = {
+               {.fd = STDIN_FILENO, .events = POLLIN}
+       };
+       int tries = 0;
+
+       while (tries < 8 && poll(fd, 1, 10) == 1) {
+               if (ctl->verbose)
+                       warnx(_("discarding stdin"));
+               xusleep(250000);
+               tcflush(STDIN_FILENO, TCIFLUSH);
+               tries++;
+       }
+}
+
 static void suspend_system(struct rtcwake_control *ctl)
 {
        FILE    *f = fopen(SYS_POWER_STATE_PATH, "w");
@@ -270,6 +288,8 @@ static void suspend_system(struct rtcwake_control *ctl)
        }
 
        if (!ctl->dryrun) {
+               if (isatty(STDIN_FILENO))
+                       wait_stdin(ctl);
                fprintf(f, "%s\n", ctl->mode_str);
                fflush(f);
        }