chiark / gitweb /
terminal: remove dead code checking O_WRONLY
[elogind.git] / src / libsystemd-terminal / idev-evdev.c
1 /*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
2
3 /***
4   This file is part of systemd.
5
6   Copyright (C) 2014 David Herrmann <dh.herrmann@gmail.com>
7
8   systemd is free software; you can redistribute it and/or modify it
9   under the terms of the GNU Lesser General Public License as published by
10   the Free Software Foundation; either version 2.1 of the License, or
11   (at your option) any later version.
12
13   systemd is distributed in the hope that it will be useful, but
14   WITHOUT ANY WARRANTY; without even the implied warranty of
15   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16   Lesser General Public License for more details.
17
18   You should have received a copy of the GNU Lesser General Public License
19   along with systemd; If not, see <http://www.gnu.org/licenses/>.
20 ***/
21
22 #include <fcntl.h>
23 #include <inttypes.h>
24 #include <libevdev/libevdev.h>
25 #include <libudev.h>
26 #include <stdbool.h>
27 #include <stdlib.h>
28 #include <systemd/sd-bus.h>
29 #include <systemd/sd-event.h>
30 #include <unistd.h>
31 #include "bus-util.h"
32 #include "hashmap.h"
33 #include "idev.h"
34 #include "idev-internal.h"
35 #include "macro.h"
36 #include "udev-util.h"
37 #include "util.h"
38
39 typedef struct idev_evdev idev_evdev;
40 typedef struct unmanaged_evdev unmanaged_evdev;
41 typedef struct managed_evdev managed_evdev;
42
43 struct idev_evdev {
44         idev_element element;
45         struct libevdev *evdev;
46         int fd;
47         sd_event_source *fd_src;
48         sd_event_source *idle_src;
49
50         bool unsync : 1;                /* not in-sync with kernel */
51         bool resync : 1;                /* re-syncing with kernel */
52 };
53
54 struct unmanaged_evdev {
55         idev_evdev evdev;
56         char *devnode;
57 };
58
59 struct managed_evdev {
60         idev_evdev evdev;
61         dev_t devnum;
62
63         sd_bus_slot *slot_pause_device;
64         sd_bus_slot *slot_resume_device;
65         sd_bus_slot *slot_take_device;
66
67         bool requested : 1;             /* TakeDevice() was sent */
68         bool acquired : 1;              /* TakeDevice() was successful */
69 };
70
71 #define idev_evdev_from_element(_e) container_of((_e), idev_evdev, element)
72 #define unmanaged_evdev_from_element(_e) \
73         container_of(idev_evdev_from_element(_e), unmanaged_evdev, evdev)
74 #define managed_evdev_from_element(_e) \
75         container_of(idev_evdev_from_element(_e), managed_evdev, evdev)
76
77 #define IDEV_EVDEV_INIT(_vtable, _session) ((idev_evdev){ \
78                 .element = IDEV_ELEMENT_INIT((_vtable), (_session)), \
79                 .fd = -1, \
80         })
81
82 #define IDEV_EVDEV_NAME_MAX (8 + DECIMAL_STR_MAX(unsigned) * 2)
83
84 static const idev_element_vtable unmanaged_evdev_vtable;
85 static const idev_element_vtable managed_evdev_vtable;
86
87 static int idev_evdev_resume(idev_evdev *evdev, int dev_fd);
88 static void idev_evdev_pause(idev_evdev *evdev, bool release);
89
90 /*
91  * Virtual Evdev Element
92  * The virtual evdev element is the base class of all other evdev elements. It
93  * uses libevdev to access the kernel evdev API. It supports asynchronous
94  * access revocation, re-syncing if events got dropped and more.
95  * This element cannot be used by itself. There must be a wrapper around it
96  * which opens a file-descriptor and passes it to the virtual evdev element.
97  */
98
99 static void idev_evdev_name(char *out, dev_t devnum) {
100         /* @out must be at least of size IDEV_EVDEV_NAME_MAX */
101         sprintf(out, "evdev/%u:%u", major(devnum), minor(devnum));
102 }
103
104 static int idev_evdev_raise(idev_evdev *evdev, struct input_event *event) {
105         idev_data data = {
106                 .type = IDEV_DATA_EVDEV,
107                 .resync = evdev->resync,
108                 .evdev = {
109                         .event = *event,
110                 },
111         };
112
113         return idev_element_feed(&evdev->element, &data);
114 }
115
116 static void idev_evdev_hup(idev_evdev *evdev) {
117         /*
118          * On HUP, we close the current fd via idev_evdev_pause(). This drops
119          * the event-sources from the main-loop and effectively puts the
120          * element asleep. If the HUP is part of a hotplug-event, a following
121          * udev-notification will destroy the element. Otherwise, the HUP is
122          * either result of access-revokation or a serious error.
123          * For unmanaged devices, we should never receive HUP (except for
124          * unplug-events). But if we do, something went seriously wrong and we
125          * shouldn't try to be clever.
126          * Instead, we simply stay asleep and wait for the device to be
127          * disabled and then re-enabled (or closed and re-opened). This will
128          * re-open the device node and restart the device.
129          * For managed devices, a HUP usually means our device-access was
130          * revoked. In that case, we simply put the device asleep and wait for
131          * logind to notify us once the device is alive again. logind also
132          * passes us a new fd. Hence, we don't have to re-enable the device.
133          *
134          * Long story short: The only thing we have to do here, is close() the
135          * file-descriptor and remove it from the main-loop. Everything else is
136          * handled via additional events we receive.
137          */
138
139         idev_evdev_pause(evdev, true);
140 }
141
142 static int idev_evdev_io(idev_evdev *evdev) {
143         idev_element *e = &evdev->element;
144         struct input_event ev;
145         unsigned int flags;
146         int r, error = 0;
147
148         /*
149          * Read input-events via libevdev until the input-queue is drained. In
150          * case we're disabled, don't do anything. The input-queue might
151          * overflow, but we don't care as we have to resync after wake-up,
152          * anyway.
153          * TODO: libevdev should give us a hint how many events to read. We
154          * really want to avoid starvation, so we shouldn't read forever in
155          * case we cannot keep up with the kernel.
156          * TODO: Make sure libevdev always reports SYN_DROPPED to us, regardless
157          * whether any event was synced afterwards.
158          * TODO: Forward SYN_DROPPED to attached devices.
159          */
160
161         flags = LIBEVDEV_READ_FLAG_NORMAL;
162         while (e->enabled) {
163                 if (evdev->unsync) {
164                         /* immediately resync, even if in sync right now */
165                         evdev->unsync = false;
166                         evdev->resync = false;
167                         flags = LIBEVDEV_READ_FLAG_NORMAL;
168                         r = libevdev_next_event(evdev->evdev, flags | LIBEVDEV_READ_FLAG_FORCE_SYNC, &ev);
169                         if (r < 0 && r != -EAGAIN) {
170                                 r = 0;
171                                 goto error;
172                         } else if (r != LIBEVDEV_READ_STATUS_SYNC) {
173                                 log_debug("idev-evdev: %s/%s: cannot force resync: %d",
174                                           e->session->name, e->name, r);
175                         }
176                 } else {
177                         r = libevdev_next_event(evdev->evdev, flags, &ev);
178                 }
179
180                 if (evdev->resync && r == -EAGAIN) {
181                         /* end of re-sync */
182                         evdev->resync = false;
183                         flags = LIBEVDEV_READ_FLAG_NORMAL;
184                 } else if (r == -EAGAIN) {
185                         /* no data available */
186                         break;
187                 } else if (r < 0) {
188                         /* read error */
189                         goto error;
190                 } else if (r == LIBEVDEV_READ_STATUS_SYNC) {
191                         if (evdev->resync) {
192                                 /* sync-event */
193                                 r = idev_evdev_raise(evdev, &ev);
194                                 if (r != 0) {
195                                         error = r;
196                                         break;
197                                 }
198                         } else {
199                                 /* start of sync */
200                                 evdev->resync = true;
201                                 flags = LIBEVDEV_READ_FLAG_SYNC;
202                         }
203                 } else {
204                         /* normal event */
205                         r = idev_evdev_raise(evdev, &ev);
206                         if (r != 0) {
207                                 error = r;
208                                 break;
209                         }
210                 }
211         }
212
213         if (error < 0)
214                 log_debug("idev-evdev: %s/%s: error on data event: %s",
215                           e->session->name, e->name, strerror(-error));
216         return error;
217
218 error:
219         idev_evdev_hup(evdev);
220         return 0; /* idev_evdev_hup() handles the error so discard it */
221 }
222
223 static int idev_evdev_event_fn(sd_event_source *s, int fd, uint32_t revents, void *userdata) {
224         idev_evdev *evdev = userdata;
225
226         /* fetch data as long as EPOLLIN is signalled */
227         if (revents & EPOLLIN)
228                 return idev_evdev_io(evdev);
229
230         if (revents & (EPOLLHUP | EPOLLERR))
231                 idev_evdev_hup(evdev);
232
233         return 0;
234 }
235
236 static int idev_evdev_idle_fn(sd_event_source *s, void *userdata) {
237         idev_evdev *evdev = userdata;
238
239         /*
240          * The idle-event is raised whenever we have to re-sync the libevdev
241          * state from the kernel. We simply call into idev_evdev_io() which
242          * flushes the state and re-syncs it if @unsync is set.
243          * State has to be synced whenever our view of the kernel device is
244          * out of date. This is the case when we open the device, if the
245          * kernel's receive buffer overflows, or on other exceptional
246          * situations. Events during re-syncs must be forwarded to the upper
247          * layers so they can update their view of the device. However, such
248          * events must only be handled passively, as they might be out-of-order
249          * and/or re-ordered. Therefore, we mark them as 'sync' events.
250          */
251
252         if (!evdev->unsync)
253                 return 0;
254
255         return idev_evdev_io(evdev);
256 }
257
258 static void idev_evdev_destroy(idev_evdev *evdev) {
259         assert(evdev);
260         assert(evdev->fd < 0);
261
262         libevdev_free(evdev->evdev);
263         evdev->evdev = NULL;
264 }
265
266 static void idev_evdev_enable(idev_evdev *evdev) {
267         assert(evdev);
268         assert(evdev->fd_src);
269         assert(evdev->idle_src);
270
271         sd_event_source_set_enabled(evdev->fd_src, SD_EVENT_ON);
272         sd_event_source_set_enabled(evdev->idle_src, SD_EVENT_ONESHOT);
273 }
274
275 static void idev_evdev_disable(idev_evdev *evdev) {
276         assert(evdev);
277         assert(evdev->fd_src);
278         assert(evdev->idle_src);
279
280         sd_event_source_set_enabled(evdev->fd_src, SD_EVENT_OFF);
281         sd_event_source_set_enabled(evdev->idle_src, SD_EVENT_OFF);
282 }
283
284 static int idev_evdev_resume(idev_evdev *evdev, int dev_fd) {
285         idev_element *e = &evdev->element;
286         _cleanup_close_ int fd = dev_fd;
287         int r, flags;
288
289         if (fd < 0 || evdev->fd == fd) {
290                 fd = -1;
291                 if (evdev->fd >= 0 && e->n_open > 0 && e->enabled)
292                         idev_evdev_enable(evdev);
293
294                 return 0;
295         }
296
297         idev_evdev_pause(evdev, true);
298         log_debug("idev-evdev: %s/%s: resume", e->session->name, e->name);
299
300         r = fd_nonblock(fd, true);
301         if (r < 0)
302                 return r;
303
304         r = fd_cloexec(fd, true);
305         if (r < 0)
306                 return r;
307
308         flags = fcntl(fd, F_GETFL, 0);
309         if (flags < 0)
310                 return -errno;
311
312         flags &= O_ACCMODE;
313         if (flags == O_WRONLY)
314                 return -EACCES;
315
316         evdev->element.readable = true;
317         evdev->element.writable = !(flags & O_RDONLY);
318
319         /*
320          * TODO: We *MUST* re-sync the device so we get a delta of the changed
321          * state while we didn't read events from the device. This works just
322          * fine with libevdev_change_fd(), however, libevdev_new_from_fd() (or
323          * libevdev_set_fd()) don't pass us events for the initial device
324          * state. So even if we force a re-sync, we will not get the delta for
325          * the initial device state.
326          * We really need to fix libevdev to support that!
327          */
328         if (evdev->evdev)
329                 r = libevdev_change_fd(evdev->evdev, fd);
330         else
331                 r = libevdev_new_from_fd(fd, &evdev->evdev);
332
333         if (r < 0)
334                 return r;
335
336         r = sd_event_add_io(e->session->context->event,
337                             &evdev->fd_src,
338                             fd,
339                             EPOLLHUP | EPOLLERR | EPOLLIN,
340                             idev_evdev_event_fn,
341                             evdev);
342         if (r < 0)
343                 return r;
344
345         r = sd_event_add_defer(e->session->context->event,
346                                &evdev->idle_src,
347                                idev_evdev_idle_fn,
348                                evdev);
349         if (r < 0) {
350                 evdev->fd_src = sd_event_source_unref(evdev->fd_src);
351                 return r;
352         }
353
354         if (e->n_open < 1 || !e->enabled) {
355                 sd_event_source_set_enabled(evdev->fd_src, SD_EVENT_OFF);
356                 sd_event_source_set_enabled(evdev->idle_src, SD_EVENT_OFF);
357         }
358
359         evdev->unsync = true;
360         evdev->fd = fd;
361
362         fd = -1;
363         return 0;
364 }
365
366 static void idev_evdev_pause(idev_evdev *evdev, bool release) {
367         idev_element *e = &evdev->element;
368
369         if (evdev->fd < 0)
370                 return;
371
372         log_debug("idev-evdev: %s/%s: pause", e->session->name, e->name);
373
374         if (release) {
375                 evdev->idle_src = sd_event_source_unref(evdev->idle_src);
376                 evdev->fd_src = sd_event_source_unref(evdev->fd_src);
377                 evdev->fd = safe_close(evdev->fd);
378         } else {
379                 idev_evdev_disable(evdev);
380         }
381 }
382
383 /*
384  * Unmanaged Evdev Element
385  * The unmanaged evdev element opens the evdev node for a given input device
386  * directly (/dev/input/eventX) and thus needs sufficient privileges. It opens
387  * the device only if we really require it and releases it as soon as we're
388  * disabled or closed.
389  * The unmanaged element can be used in all situations where you have direct
390  * access to input device nodes. Unlike managed evdev elements, it can be used
391  * outside of user sessions and in emergency situations where logind is not
392  * available.
393  */
394
395 static void unmanaged_evdev_resume(idev_element *e) {
396         unmanaged_evdev *eu = unmanaged_evdev_from_element(e);
397         int r, fd;
398
399         /*
400          * Unmanaged devices can be acquired on-demand. Therefore, don't
401          * acquire it unless someone opened the device *and* we're enabled.
402          */
403         if (e->n_open < 1 || !e->enabled)
404                 return;
405
406         fd = eu->evdev.fd;
407         if (fd < 0) {
408                 fd = open(eu->devnode, O_RDWR | O_CLOEXEC | O_NOCTTY | O_NONBLOCK);
409                 if (fd < 0) {
410                         if (errno != EACCES && errno != EPERM) {
411                                 log_debug("idev-evdev: %s/%s: cannot open node %s: %m",
412                                           e->session->name, e->name, eu->devnode);
413                                 return;
414                         }
415
416                         fd = open(eu->devnode, O_RDONLY | O_CLOEXEC | O_NOCTTY | O_NONBLOCK);
417                         if (fd < 0) {
418                                 log_debug("idev-evdev: %s/%s: cannot open node %s: %m",
419                                           e->session->name, e->name, eu->devnode);
420                                 return;
421                         }
422
423                         e->readable = true;
424                         e->writable = false;
425                 } else {
426                         e->readable = true;
427                         e->writable = true;
428                 }
429         }
430
431         r = idev_evdev_resume(&eu->evdev, fd);
432         if (r < 0)
433                 log_debug("idev-evdev: %s/%s: cannot resume: %s",
434                           e->session->name, e->name, strerror(-r));
435 }
436
437 static void unmanaged_evdev_pause(idev_element *e) {
438         unmanaged_evdev *eu = unmanaged_evdev_from_element(e);
439
440         /*
441          * Release the device if the device is disabled or there is no-one who
442          * opened it. This guarantees we stay only available if we're opened
443          * *and* enabled.
444          */
445
446         idev_evdev_pause(&eu->evdev, true);
447 }
448
449 static int unmanaged_evdev_new(idev_element **out, idev_session *s, struct udev_device *ud) {
450         _cleanup_(idev_element_freep) idev_element *e = NULL;
451         char name[IDEV_EVDEV_NAME_MAX];
452         unmanaged_evdev *eu;
453         const char *devnode;
454         dev_t devnum;
455         int r;
456
457         assert_return(s, -EINVAL);
458         assert_return(ud, -EINVAL);
459
460         devnode = udev_device_get_devnode(ud);
461         devnum = udev_device_get_devnum(ud);
462         if (!devnode || devnum == 0)
463                 return -ENODEV;
464
465         idev_evdev_name(name, devnum);
466
467         eu = new0(unmanaged_evdev, 1);
468         if (!eu)
469                 return -ENOMEM;
470
471         e = &eu->evdev.element;
472         eu->evdev = IDEV_EVDEV_INIT(&unmanaged_evdev_vtable, s);
473
474         eu->devnode = strdup(devnode);
475         if (!eu->devnode)
476                 return -ENOMEM;
477
478         r = idev_element_add(e, name);
479         if (r < 0)
480                 return r;
481
482         if (out)
483                 *out = e;
484         e = NULL;
485         return 0;
486 }
487
488 static void unmanaged_evdev_free(idev_element *e) {
489         unmanaged_evdev *eu = unmanaged_evdev_from_element(e);
490
491         idev_evdev_destroy(&eu->evdev);
492         free(eu->devnode);
493         free(eu);
494 }
495
496 static const idev_element_vtable unmanaged_evdev_vtable = {
497         .free                   = unmanaged_evdev_free,
498         .enable                 = unmanaged_evdev_resume,
499         .disable                = unmanaged_evdev_pause,
500         .open                   = unmanaged_evdev_resume,
501         .close                  = unmanaged_evdev_pause,
502 };
503
504 /*
505  * Managed Evdev Element
506  * The managed evdev element uses systemd-logind to acquire evdev devices. This
507  * means, we do not open the device node /dev/input/eventX directly. Instead,
508  * logind passes us a file-descriptor whenever our session is activated. Thus,
509  * we don't need access to the device node directly.
510  * Furthermore, whenever the session is put asleep, logind revokes the
511  * file-descriptor so we loose access to the device.
512  * Managed evdev elements should be preferred over unmanaged elements whenever
513  * you run inside a user session with exclusive device access.
514  */
515
516 static int managed_evdev_take_device_fn(sd_bus *bus,
517                                         sd_bus_message *reply,
518                                         void *userdata,
519                                         sd_bus_error *ret_error) {
520         managed_evdev *em = userdata;
521         idev_element *e = &em->evdev.element;
522         idev_session *s = e->session;
523         int r, paused, fd;
524
525         em->slot_take_device = sd_bus_slot_unref(em->slot_take_device);
526
527         if (sd_bus_message_is_method_error(reply, NULL)) {
528                 const sd_bus_error *error = sd_bus_message_get_error(reply);
529
530                 log_debug("idev-evdev: %s/%s: TakeDevice failed: %s: %s",
531                           s->name, e->name, error->name, error->message);
532                 return 0;
533         }
534
535         em->acquired = true;
536
537         r = sd_bus_message_read(reply, "hb", &fd, &paused);
538         if (r < 0) {
539                 log_debug("idev-evdev: %s/%s: erroneous TakeDevice reply", s->name, e->name);
540                 return 0;
541         }
542
543         /* If the device is paused, ignore it; we will get the next fd via
544          * ResumeDevice signals. */
545         if (paused)
546                 return 0;
547
548         fd = fcntl(fd, F_DUPFD_CLOEXEC, 3);
549         if (fd < 0) {
550                 log_debug("idev-evdev: %s/%s: cannot duplicate evdev fd: %m", s->name, e->name);
551                 return 0;
552         }
553
554         r = idev_evdev_resume(&em->evdev, fd);
555         if (r < 0)
556                 log_debug("idev-evdev: %s/%s: cannot resume: %s",
557                           s->name, e->name, strerror(-r));
558
559         return 0;
560 }
561
562 static void managed_evdev_resume(idev_element *e) {
563         _cleanup_bus_message_unref_ sd_bus_message *m = NULL;
564         managed_evdev *em = managed_evdev_from_element(e);
565         idev_session *s = e->session;
566         idev_context *c = s->context;
567         int r;
568
569         /*
570          * Acquiring managed devices is heavy, so do it only once we're
571          * enabled *and* opened by someone.
572          */
573         if (e->n_open < 1 || !e->enabled)
574                 return;
575
576         /* bail out if already pending */
577         if (em->requested)
578                 return;
579
580         r = sd_bus_message_new_method_call(c->sysbus,
581                                            &m,
582                                            "org.freedesktop.login1",
583                                            s->path,
584                                            "org.freedesktop.login1.Session",
585                                            "TakeDevice");
586         if (r < 0)
587                 goto error;
588
589         r = sd_bus_message_append(m, "uu", major(em->devnum), minor(em->devnum));
590         if (r < 0)
591                 goto error;
592
593         r = sd_bus_call_async(c->sysbus,
594                               &em->slot_take_device,
595                               m,
596                               managed_evdev_take_device_fn,
597                               em,
598                               0);
599         if (r < 0)
600                 goto error;
601
602         em->requested = true;
603         return;
604
605 error:
606         log_debug("idev-evdev: %s/%s: cannot send TakeDevice request: %s",
607                   s->name, e->name, strerror(-r));
608 }
609
610 static void managed_evdev_pause(idev_element *e) {
611         _cleanup_bus_message_unref_ sd_bus_message *m = NULL;
612         managed_evdev *em = managed_evdev_from_element(e);
613         idev_session *s = e->session;
614         idev_context *c = s->context;
615         int r;
616
617         /*
618          * Releasing managed devices is heavy. Once acquired, we get
619          * notifications for sleep/wake-up events, so there's no reason to
620          * release it if disabled but opened. However, if a device is closed,
621          * we release it immediately as we don't care for sleep/wake-up events
622          * then (even if we're actually enabled).
623          */
624
625         idev_evdev_pause(&em->evdev, false);
626
627         if (e->n_open > 0 || !em->requested)
628                 return;
629
630         /*
631          * If TakeDevice() is pending or was successful, make sure to
632          * release the device again. We don't care for return-values,
633          * so send it without waiting or callbacks.
634          * If a failed TakeDevice() is pending, but someone else took
635          * the device on the same bus-connection, we might incorrectly
636          * release their device. This is an unlikely race, though.
637          * Furthermore, you really shouldn't have two users of the
638          * controller-API on the same session, on the same devices, *AND* on
639          * the same bus-connection. So we don't care for that race..
640          */
641
642         idev_evdev_pause(&em->evdev, true);
643         em->requested = false;
644
645         if (!em->acquired && !em->slot_take_device)
646                 return;
647
648         em->slot_take_device = sd_bus_slot_unref(em->slot_take_device);
649         em->acquired = false;
650
651         r = sd_bus_message_new_method_call(c->sysbus,
652                                            &m,
653                                            "org.freedesktop.login1",
654                                            s->path,
655                                            "org.freedesktop.login1.Session",
656                                            "ReleaseDevice");
657         if (r >= 0) {
658                 r = sd_bus_message_append(m, "uu", major(em->devnum), minor(em->devnum));
659                 if (r >= 0)
660                         r = sd_bus_send(c->sysbus, m, NULL);
661         }
662
663         if (r < 0 && r != -ENOTCONN)
664                 log_debug("idev-evdev: %s/%s: cannot send ReleaseDevice: %s",
665                           s->name, e->name, strerror(-r));
666 }
667
668 static int managed_evdev_pause_device_fn(sd_bus *bus,
669                                          sd_bus_message *signal,
670                                          void *userdata,
671                                          sd_bus_error *ret_error) {
672         managed_evdev *em = userdata;
673         idev_element *e = &em->evdev.element;
674         idev_session *s = e->session;
675         idev_context *c = s->context;
676         uint32_t major, minor;
677         const char *mode;
678         int r;
679
680         /*
681          * We get PauseDevice() signals from logind whenever a device we
682          * requested was, or is about to be, paused. Arguments are major/minor
683          * number of the device and the mode of the operation.
684          * In case the event is not about our device, we ignore it. Otherwise,
685          * we treat it as asynchronous access-revocation (as if we got HUP on
686          * the device fd). Note that we might have already treated the HUP
687          * event via EPOLLHUP, whichever comes first.
688          *
689          * @mode can be one of the following:
690          *   "pause": The device is about to be paused. We must react
691          *            immediately and respond with PauseDeviceComplete(). Once
692          *            we replied, logind will pause the device. Note that
693          *            logind might apply any kind of timeout and force pause
694          *            the device if we don't respond in a timely manner. In
695          *            this case, we will receive a second PauseDevice event
696          *            with @mode set to "force" (or similar).
697          *   "force": The device was disabled forecfully by logind. Access is
698          *            already revoked. This is just an asynchronous
699          *            notification so we can put the device asleep (in case
700          *            we didn't already notice the access revocation).
701          *    "gone": This is like "force" but is sent if the device was
702          *            paused due to a device-removal event.
703          *
704          * We always handle PauseDevice signals as "force" as we properly
705          * support asynchronous access revocation, anyway. But in case logind
706          * sent mode "pause", we also call PauseDeviceComplete() to immediately
707          * acknowledge the request.
708          */
709
710         r = sd_bus_message_read(signal, "uus", &major, &minor, &mode);
711         if (r < 0) {
712                 log_debug("idev-evdev: %s/%s: erroneous PauseDevice signal",
713                           s->name, e->name);
714                 return 0;
715         }
716
717         /* not our device? */
718         if (makedev(major, minor) != em->devnum)
719                 return 0;
720
721         idev_evdev_pause(&em->evdev, true);
722
723         if (streq(mode, "pause")) {
724                 _cleanup_bus_message_unref_ sd_bus_message *m = NULL;
725
726                 /*
727                  * Sending PauseDeviceComplete() is racy if logind triggers the
728                  * timeout. That is, if we take too long and logind pauses the
729                  * device by sending a forced PauseDevice, our
730                  * PauseDeviceComplete call will be stray. That's fine, though.
731                  * logind ignores such stray calls. Only if logind also sent a
732                  * further PauseDevice() signal, it might match our call
733                  * incorrectly to the newer PauseDevice(). That's fine, too, as
734                  * we handle that event asynchronously, anyway. Therefore,
735                  * whatever happens, we're fine. Yay!
736                  */
737
738                 r = sd_bus_message_new_method_call(c->sysbus,
739                                                    &m,
740                                                    "org.freedesktop.login1",
741                                                    s->path,
742                                                    "org.freedesktop.login1.Session",
743                                                    "PauseDeviceComplete");
744                 if (r >= 0) {
745                         r = sd_bus_message_append(m, "uu", major, minor);
746                         if (r >= 0)
747                                 r = sd_bus_send(c->sysbus, m, NULL);
748                 }
749
750                 if (r < 0)
751                         log_debug("idev-evdev: %s/%s: cannot send PauseDeviceComplete: %s",
752                                   s->name, e->name, strerror(-r));
753         }
754
755         return 0;
756 }
757
758 static int managed_evdev_resume_device_fn(sd_bus *bus,
759                                           sd_bus_message *signal,
760                                           void *userdata,
761                                           sd_bus_error *ret_error) {
762         managed_evdev *em = userdata;
763         idev_element *e = &em->evdev.element;
764         idev_session *s = e->session;
765         uint32_t major, minor;
766         int r, fd;
767
768         /*
769          * We get ResumeDevice signals whenever logind resumed a previously
770          * paused device. The arguments contain the major/minor number of the
771          * related device and a new file-descriptor for the freshly opened
772          * device-node.
773          * If the signal is not about our device, we simply ignore it.
774          * Otherwise, we take the file-descriptor and immediately resume the
775          * device.
776          */
777
778         r = sd_bus_message_read(signal, "uuh", &major, &minor, &fd);
779         if (r < 0) {
780                 log_debug("idev-evdev: %s/%s: erroneous ResumeDevice signal",
781                           s->name, e->name);
782                 return 0;
783         }
784
785         /* not our device? */
786         if (makedev(major, minor) != em->devnum)
787                 return 0;
788
789         fd = fcntl(fd, F_DUPFD_CLOEXEC, 3);
790         if (fd < 0) {
791                 log_debug("idev-evdev: %s/%s: cannot duplicate evdev fd: %m",
792                           s->name, e->name);
793                 return 0;
794         }
795
796         r = idev_evdev_resume(&em->evdev, fd);
797         if (r < 0)
798                 log_debug("idev-evdev: %s/%s: cannot resume: %s",
799                           s->name, e->name, strerror(-r));
800
801         return 0;
802 }
803
804 static int managed_evdev_setup_bus(managed_evdev *em) {
805         idev_element *e = &em->evdev.element;
806         idev_session *s = e->session;
807         idev_context *c = s->context;
808         _cleanup_free_ char *match = NULL;
809         int r;
810
811         match = strjoin("type='signal',"
812                         "sender='org.freedesktop.login1',"
813                         "interface='org.freedesktop.login1.Session',"
814                         "member='PauseDevice',"
815                         "path='", s->path, "'",
816                         NULL);
817         if (!match)
818                 return -ENOMEM;
819
820         r = sd_bus_add_match(c->sysbus,
821                              &em->slot_pause_device,
822                              match,
823                              managed_evdev_pause_device_fn,
824                              em);
825         if (r < 0)
826                 return r;
827
828         free(match);
829         match = strjoin("type='signal',"
830                         "sender='org.freedesktop.login1',"
831                         "interface='org.freedesktop.login1.Session',"
832                         "member='ResumeDevice',"
833                         "path='", s->path, "'",
834                         NULL);
835         if (!match)
836                 return -ENOMEM;
837
838         r = sd_bus_add_match(c->sysbus,
839                              &em->slot_resume_device,
840                              match,
841                              managed_evdev_resume_device_fn,
842                              em);
843         if (r < 0)
844                 return r;
845
846         return 0;
847 }
848
849 static int managed_evdev_new(idev_element **out, idev_session *s, struct udev_device *ud) {
850         _cleanup_(idev_element_freep) idev_element *e = NULL;
851         char name[IDEV_EVDEV_NAME_MAX];
852         managed_evdev *em;
853         dev_t devnum;
854         int r;
855
856         assert_return(s, -EINVAL);
857         assert_return(s->managed, -EINVAL);
858         assert_return(s->context->sysbus, -EINVAL);
859         assert_return(ud, -EINVAL);
860
861         devnum = udev_device_get_devnum(ud);
862         if (devnum == 0)
863                 return -ENODEV;
864
865         idev_evdev_name(name, devnum);
866
867         em = new0(managed_evdev, 1);
868         if (!em)
869                 return -ENOMEM;
870
871         e = &em->evdev.element;
872         em->evdev = IDEV_EVDEV_INIT(&managed_evdev_vtable, s);
873         em->devnum = devnum;
874
875         r = managed_evdev_setup_bus(em);
876         if (r < 0)
877                 return r;
878
879         r = idev_element_add(e, name);
880         if (r < 0)
881                 return r;
882
883         if (out)
884                 *out = e;
885         e = NULL;
886         return 0;
887 }
888
889 static void managed_evdev_free(idev_element *e) {
890         managed_evdev *em = managed_evdev_from_element(e);
891
892         em->slot_resume_device = sd_bus_slot_unref(em->slot_resume_device);
893         em->slot_pause_device = sd_bus_slot_unref(em->slot_pause_device);
894         idev_evdev_destroy(&em->evdev);
895         free(em);
896 }
897
898 static const idev_element_vtable managed_evdev_vtable = {
899         .free                   = managed_evdev_free,
900         .enable                 = managed_evdev_resume,
901         .disable                = managed_evdev_pause,
902         .open                   = managed_evdev_resume,
903         .close                  = managed_evdev_pause,
904 };
905
906 /*
907  * Generic Constructor
908  * Instead of relying on the caller to choose between managed and unmanaged
909  * evdev devices, the idev_evdev_new() constructor does that for you (by
910  * looking at s->managed).
911  */
912
913 bool idev_is_evdev(idev_element *e) {
914         return e && (e->vtable == &unmanaged_evdev_vtable ||
915                      e->vtable == &managed_evdev_vtable);
916 }
917
918 idev_element *idev_find_evdev(idev_session *s, dev_t devnum) {
919         char name[IDEV_EVDEV_NAME_MAX];
920
921         assert_return(s, NULL);
922         assert_return(devnum != 0, NULL);
923
924         idev_evdev_name(name, devnum);
925         return idev_find_element(s, name);
926 }
927
928 int idev_evdev_new(idev_element **out, idev_session *s, struct udev_device *ud) {
929         assert_return(s, -EINVAL);
930         assert_return(ud, -EINVAL);
931
932         return s->managed ? managed_evdev_new(out, s, ud) : unmanaged_evdev_new(out, s, ud);
933 }