summaryrefslogtreecommitdiff
path: root/drivers/tty
diff options
context:
space:
mode:
authorNicolas Pitre <nicolas.pitre@linaro.org>2019-01-09 19:17:20 -0500
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2019-01-18 13:48:52 +0100
commit95252f9c04f7158e0ba44ce8efe208760874dfd9 (patch)
treed3211c5d518c11bdf219f1cc383298d4007fbb84 /drivers/tty
parentfad08b205cf134759c28d182905bf27762017192 (diff)
vcs: restore and document initial POLLPRI event
Restore and document the forced initial POLLPRI event reporting when poll() is used for the first time. This used to be the implemented behavior before recent changes. Because of the way poll() is implemented, this prevents losing an event happening between the last read() and the first poll() invocation. Since poll() for /dev/vcs* was not always supported, user space probes for its availability as follows: int fd = open("/dev/vcsa", O_RDONLY); struct pollfd p = { .fd = fd, .events = POLLPRI }; available = (poll(&p, 1, 0) == 1); Semantically, it makes sense to signal the first event as such even if it might be spurious. The screen could be modified, and modified back to its initial state before we get to read it, so users must be prepared for that anyway. Signed-off-by: Nicolas Pitre <nico@linaro.org> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/tty')
-rw-r--r--drivers/tty/vt/vc_screen.c9
1 files changed, 9 insertions, 0 deletions
diff --git a/drivers/tty/vt/vc_screen.c b/drivers/tty/vt/vc_screen.c
index 1d887113ff49..160f46115aaa 100644
--- a/drivers/tty/vt/vc_screen.c
+++ b/drivers/tty/vt/vc_screen.c
@@ -140,6 +140,15 @@ vcs_poll_data_get(struct file *file)
poll->cons_num = console(file_inode(file));
init_waitqueue_head(&poll->waitq);
poll->notifier.notifier_call = vcs_notifier;
+ /*
+ * In order not to lose any update event, we must pretend one might
+ * have occurred before we have a chance to register our notifier.
+ * This is also how user space has come to detect which kernels
+ * support POLLPRI on /dev/vcs* devices i.e. using poll() with
+ * POLLPRI and a zero timeout.
+ */
+ poll->event = VT_UPDATE;
+
if (register_vt_notifier(&poll->notifier) != 0) {
kfree(poll);
return NULL;