chiark / gitweb /
terminal: sysview: don't return uninitialized error codes
[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         struct 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         struct idev_evdev evdev;
56         char *devnode;
57 };
58
59 struct managed_evdev {
60         struct 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 r;
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 r;
311
312         flags &= O_ACCMODE;
313         if (flags == O_WRONLY)
314                 return -EACCES;
315
316         evdev->element.readable = true;
317         evdev->element.writable = true;
318         if (flags == O_RDONLY)
319                 evdev->element.writable = false;
320         else if (flags == O_WRONLY)
321                 evdev->element.readable = false;
322
323         /*
324          * TODO: We *MUST* re-sync the device so we get a delta of the changed
325          * state while we didn't read events from the device. This works just
326          * fine with libevdev_change_fd(), however, libevdev_new_from_fd() (or
327          * libevdev_set_fd()) don't pass us events for the initial device
328          * state. So even if we force a re-sync, we will not get the delta for
329          * the initial device state.
330          * We really need to fix libevdev to support that!
331          */
332         if (evdev->evdev)
333                 r = libevdev_change_fd(evdev->evdev, fd);
334         else
335                 r = libevdev_new_from_fd(fd, &evdev->evdev);
336
337         if (r < 0)
338                 return r;
339
340         r = sd_event_add_io(e->session->context->event,
341                             &evdev->fd_src,
342                             fd,
343                             EPOLLHUP | EPOLLERR | EPOLLIN,
344                             idev_evdev_event_fn,
345                             evdev);
346         if (r < 0)
347                 return r;
348
349         r = sd_event_add_defer(e->session->context->event,
350                                &evdev->idle_src,
351                                idev_evdev_idle_fn,
352                                evdev);
353         if (r < 0) {
354                 evdev->fd_src = sd_event_source_unref(evdev->fd_src);
355                 return r;
356         }
357
358         if (e->n_open < 1 || !e->enabled) {
359                 sd_event_source_set_enabled(evdev->fd_src, SD_EVENT_OFF);
360                 sd_event_source_set_enabled(evdev->idle_src, SD_EVENT_OFF);
361         }
362
363         evdev->unsync = true;
364         evdev->fd = fd;
365
366         fd = -1;
367         return 0;
368 }
369
370 static void idev_evdev_pause(idev_evdev *evdev, bool release) {
371         idev_element *e = &evdev->element;
372
373         if (evdev->fd < 0)
374                 return;
375
376         log_debug("idev-evdev: %s/%s: pause", e->session->name, e->name);
377
378         if (release) {
379                 evdev->idle_src = sd_event_source_unref(evdev->idle_src);
380                 evdev->fd_src = sd_event_source_unref(evdev->fd_src);
381                 evdev->fd = safe_close(evdev->fd);
382         } else {
383                 idev_evdev_disable(evdev);
384         }
385 }
386
387 /*
388  * Unmanaged Evdev Element
389  * The unmanaged evdev element opens the evdev node for a given input device
390  * directly (/dev/input/eventX) and thus needs sufficient privileges. It opens
391  * the device only if we really require it and releases it as soon as we're
392  * disabled or closed.
393  * The unmanaged element can be used in all situations where you have direct
394  * access to input device nodes. Unlike managed evdev elements, it can be used
395  * outside of user sessions and in emergency situations where logind is not
396  * available.
397  */
398
399 static void unmanaged_evdev_resume(idev_element *e) {
400         unmanaged_evdev *eu = unmanaged_evdev_from_element(e);
401         int r, fd;
402
403         /*
404          * Unmanaged devices can be acquired on-demand. Therefore, don't
405          * acquire it unless someone opened the device *and* we're enabled.
406          */
407         if (e->n_open < 1 || !e->enabled)
408                 return;
409
410         fd = eu->evdev.fd;
411         if (fd < 0) {
412                 fd = open(eu->devnode, O_RDWR | O_CLOEXEC | O_NOCTTY | O_NONBLOCK);
413                 if (fd < 0) {
414                         if (errno != EACCES && errno != EPERM) {
415                                 log_debug("idev-evdev: %s/%s: cannot open node %s: %m",
416                                           e->session->name, e->name, eu->devnode);
417                                 return;
418                         }
419
420                         fd = open(eu->devnode, O_RDONLY | O_CLOEXEC | O_NOCTTY | O_NONBLOCK);
421                         if (fd < 0) {
422                                 log_debug("idev-evdev: %s/%s: cannot open node %s: %m",
423                                           e->session->name, e->name, eu->devnode);
424                                 return;
425                         }
426
427                         e->readable = true;
428                         e->writable = false;
429                 } else {
430                         e->readable = true;
431                         e->writable = true;
432                 }
433         }
434
435         r = idev_evdev_resume(&eu->evdev, fd);
436         if (r < 0)
437                 log_debug("idev-evdev: %s/%s: cannot resume: %s",
438                           e->session->name, e->name, strerror(-r));
439 }
440
441 static void unmanaged_evdev_pause(idev_element *e) {
442         unmanaged_evdev *eu = unmanaged_evdev_from_element(e);
443
444         /*
445          * Release the device if the device is disabled or there is no-one who
446          * opened it. This guarantees we stay only available if we're opened
447          * *and* enabled.
448          */
449
450         idev_evdev_pause(&eu->evdev, true);
451 }
452
453 static int unmanaged_evdev_new(idev_element **out, idev_session *s, struct udev_device *ud) {
454         _cleanup_(idev_element_freep) idev_element *e = NULL;
455         char name[IDEV_EVDEV_NAME_MAX];
456         unmanaged_evdev *eu;
457         const char *devnode;
458         dev_t devnum;
459         int r;
460
461         assert_return(s, -EINVAL);
462         assert_return(ud, -EINVAL);
463
464         devnode = udev_device_get_devnode(ud);
465         devnum = udev_device_get_devnum(ud);
466         if (!devnode || devnum == 0)
467                 return -ENODEV;
468
469         idev_evdev_name(name, devnum);
470
471         eu = new0(unmanaged_evdev, 1);
472         if (!eu)
473                 return -ENOMEM;
474
475         e = &eu->evdev.element;
476         eu->evdev = IDEV_EVDEV_INIT(&unmanaged_evdev_vtable, s);
477
478         eu->devnode = strdup(devnode);
479         if (!eu->devnode)
480                 return -ENOMEM;
481
482         r = idev_element_add(e, name);
483         if (r < 0)
484                 return r;
485
486         if (out)
487                 *out = e;
488         e = NULL;
489         return 0;
490 }
491
492 static void unmanaged_evdev_free(idev_element *e) {
493         unmanaged_evdev *eu = unmanaged_evdev_from_element(e);
494
495         idev_evdev_destroy(&eu->evdev);
496         free(eu->devnode);
497         free(eu);
498 }
499
500 static const idev_element_vtable unmanaged_evdev_vtable = {
501         .free                   = unmanaged_evdev_free,
502         .enable                 = unmanaged_evdev_resume,
503         .disable                = unmanaged_evdev_pause,
504         .open                   = unmanaged_evdev_resume,
505         .close                  = unmanaged_evdev_pause,
506 };
507
508 /*
509  * Managed Evdev Element
510  * The managed evdev element uses systemd-logind to acquire evdev devices. This
511  * means, we do not open the device node /dev/input/eventX directly. Instead,
512  * logind passes us a file-descriptor whenever our session is activated. Thus,
513  * we don't need access to the device node directly.
514  * Furthermore, whenever the session is put asleep, logind revokes the
515  * file-descriptor so we loose access to the device.
516  * Managed evdev elements should be preferred over unmanaged elements whenever
517  * you run inside a user session with exclusive device access.
518  */
519
520 static int managed_evdev_take_device_fn(sd_bus *bus,
521                                         sd_bus_message *reply,
522                                         void *userdata,
523                                         sd_bus_error *ret_error) {
524         managed_evdev *em = userdata;
525         idev_element *e = &em->evdev.element;
526         idev_session *s = e->session;
527         int r, paused, fd;
528
529         em->slot_take_device = sd_bus_slot_unref(em->slot_take_device);
530
531         if (sd_bus_message_is_method_error(reply, NULL)) {
532                 const sd_bus_error *error = sd_bus_message_get_error(reply);
533
534                 log_debug("idev-evdev: %s/%s: TakeDevice failed: %s: %s",
535                           s->name, e->name, error->name, error->message);
536                 return 0;
537         }
538
539         em->acquired = true;
540
541         r = sd_bus_message_read(reply, "hb", &fd, &paused);
542         if (r < 0) {
543                 log_debug("idev-evdev: %s/%s: erroneous TakeDevice reply", s->name, e->name);
544                 return 0;
545         }
546
547         /* If the device is paused, ignore it; we will get the next fd via
548          * ResumeDevice signals. */
549         if (paused)
550                 return 0;
551
552         fd = fcntl(fd, F_DUPFD_CLOEXEC, 3);
553         if (fd < 0) {
554                 log_debug("idev-evdev: %s/%s: cannot duplicate evdev fd: %m", s->name, e->name);
555                 return 0;
556         }
557
558         r = idev_evdev_resume(&em->evdev, fd);
559         if (r < 0)
560                 log_debug("idev-evdev: %s/%s: cannot resume: %s",
561                           s->name, e->name, strerror(-r));
562
563         return 0;
564 }
565
566 static void managed_evdev_resume(idev_element *e) {
567         _cleanup_bus_message_unref_ sd_bus_message *m = NULL;
568         managed_evdev *em = managed_evdev_from_element(e);
569         idev_session *s = e->session;
570         idev_context *c = s->context;
571         int r;
572
573         /*
574          * Acquiring managed devices is heavy, so do it only once we're
575          * enabled *and* opened by someone.
576          */
577         if (e->n_open < 1 || !e->enabled)
578                 return;
579
580         /* bail out if already pending */
581         if (em->requested)
582                 return;
583
584         r = sd_bus_message_new_method_call(c->sysbus,
585                                            &m,
586                                            "org.freedesktop.login1",
587                                            s->path,
588                                            "org.freedesktop.login1.Session",
589                                            "TakeDevice");
590         if (r < 0)
591                 goto error;
592
593         r = sd_bus_message_append(m, "uu", major(em->devnum), minor(em->devnum));
594         if (r < 0)
595                 goto error;
596
597         r = sd_bus_call_async(c->sysbus,
598                               &em->slot_take_device,
599                               m,
600                               managed_evdev_take_device_fn,
601                               em,
602                               0);
603         if (r < 0)
604                 goto error;
605
606         em->requested = true;
607         return;
608
609 error:
610         log_debug("idev-evdev: %s/%s: cannot send TakeDevice request: %s",
611                   s->name, e->name, strerror(-r));
612 }
613
614 static void managed_evdev_pause(idev_element *e) {
615         _cleanup_bus_message_unref_ sd_bus_message *m = NULL;
616         managed_evdev *em = managed_evdev_from_element(e);
617         idev_session *s = e->session;
618         idev_context *c = s->context;
619         int r;
620
621         /*
622          * Releasing managed devices is heavy. Once acquired, we get
623          * notifications for sleep/wake-up events, so there's no reason to
624          * release it if disabled but opened. However, if a device is closed,
625          * we release it immediately as we don't care for sleep/wake-up events
626          * then (even if we're actually enabled).
627          */
628
629         idev_evdev_pause(&em->evdev, false);
630
631         if (e->n_open > 0 || !em->requested)
632                 return;
633
634         /*
635          * If TakeDevice() is pending or was successful, make sure to
636          * release the device again. We don't care for return-values,
637          * so send it without waiting or callbacks.
638          * If a failed TakeDevice() is pending, but someone else took
639          * the device on the same bus-connection, we might incorrectly
640          * release their device. This is an unlikely race, though.
641          * Furthermore, you really shouldn't have two users of the
642          * controller-API on the same session, on the same devices, *AND* on
643          * the same bus-connection. So we don't care for that race..
644          */
645
646         idev_evdev_pause(&em->evdev, true);
647         em->requested = false;
648
649         if (!em->acquired && !em->slot_take_device)
650                 return;
651
652         em->slot_take_device = sd_bus_slot_unref(em->slot_take_device);
653         em->acquired = false;
654
655         r = sd_bus_message_new_method_call(c->sysbus,
656                                            &m,
657                                            "org.freedesktop.login1",
658                                            s->path,
659                                            "org.freedesktop.login1.Session",
660                                            "ReleaseDevice");
661         if (r >= 0) {
662                 r = sd_bus_message_append(m, "uu", major(em->devnum), minor(em->devnum));
663                 if (r >= 0)
664                         r = sd_bus_send(c->sysbus, m, NULL);
665         }
666
667         if (r < 0 && r != -ENOTCONN)
668                 log_debug("idev-evdev: %s/%s: cannot send ReleaseDevice: %s",
669                           s->name, e->name, strerror(-r));
670 }
671
672 static int managed_evdev_pause_device_fn(sd_bus *bus,
673                                          sd_bus_message *signal,
674                                          void *userdata,
675                                          sd_bus_error *ret_error) {
676         managed_evdev *em = userdata;
677         idev_element *e = &em->evdev.element;
678         idev_session *s = e->session;
679         idev_context *c = s->context;
680         uint32_t major, minor;
681         const char *mode;
682         int r;
683
684         /*
685          * We get PauseDevice() signals from logind whenever a device we
686          * requested was, or is about to be, paused. Arguments are major/minor
687          * number of the device and the mode of the operation.
688          * In case the event is not about our device, we ignore it. Otherwise,
689          * we treat it as asynchronous access-revocation (as if we got HUP on
690          * the device fd). Note that we might have already treated the HUP
691          * event via EPOLLHUP, whichever comes first.
692          *
693          * @mode can be one of the following:
694          *   "pause": The device is about to be paused. We must react
695          *            immediately and respond with PauseDeviceComplete(). Once
696          *            we replied, logind will pause the device. Note that
697          *            logind might apply any kind of timeout and force pause
698          *            the device if we don't respond in a timely manner. In
699          *            this case, we will receive a second PauseDevice event
700          *            with @mode set to "force" (or similar).
701          *   "force": The device was disabled forecfully by logind. Access is
702          *            already revoked. This is just an asynchronous
703          *            notification so we can put the device asleep (in case
704          *            we didn't already notice the access revocation).
705          *    "gone": This is like "force" but is sent if the device was
706          *            paused due to a device-removal event.
707          *
708          * We always handle PauseDevice signals as "force" as we properly
709          * support asynchronous access revocation, anyway. But in case logind
710          * sent mode "pause", we also call PauseDeviceComplete() to immediately
711          * acknowledge the request.
712          */
713
714         r = sd_bus_message_read(signal, "uus", &major, &minor, &mode);
715         if (r < 0) {
716                 log_debug("idev-evdev: %s/%s: erroneous PauseDevice signal",
717                           s->name, e->name);
718                 return 0;
719         }
720
721         /* not our device? */
722         if (makedev(major, minor) != em->devnum)
723                 return 0;
724
725         idev_evdev_pause(&em->evdev, true);
726
727         if (streq(mode, "pause")) {
728                 _cleanup_bus_message_unref_ sd_bus_message *m = NULL;
729
730                 /*
731                  * Sending PauseDeviceComplete() is racy if logind triggers the
732                  * timeout. That is, if we take too long and logind pauses the
733                  * device by sending a forced PauseDevice, our
734                  * PauseDeviceComplete call will be stray. That's fine, though.
735                  * logind ignores such stray calls. Only if logind also sent a
736                  * further PauseDevice() signal, it might match our call
737                  * incorrectly to the newer PauseDevice(). That's fine, too, as
738                  * we handle that event asynchronously, anyway. Therefore,
739                  * whatever happens, we're fine. Yay!
740                  */
741
742                 r = sd_bus_message_new_method_call(c->sysbus,
743                                                    &m,
744                                                    "org.freedesktop.login1",
745                                                    s->path,
746                                                    "org.freedesktop.login1.Session",
747                                                    "PauseDeviceComplete");
748                 if (r >= 0) {
749                         r = sd_bus_message_append(m, "uu", major, minor);
750                         if (r >= 0)
751                                 r = sd_bus_send(c->sysbus, m, NULL);
752                 }
753
754                 if (r < 0)
755                         log_debug("idev-evdev: %s/%s: cannot send PauseDeviceComplete: %s",
756                                   s->name, e->name, strerror(-r));
757         }
758
759         return 0;
760 }
761
762 static int managed_evdev_resume_device_fn(sd_bus *bus,
763                                           sd_bus_message *signal,
764                                           void *userdata,
765                                           sd_bus_error *ret_error) {
766         managed_evdev *em = userdata;
767         idev_element *e = &em->evdev.element;
768         idev_session *s = e->session;
769         uint32_t major, minor;
770         int r, fd;
771
772         /*
773          * We get ResumeDevice signals whenever logind resumed a previously
774          * paused device. The arguments contain the major/minor number of the
775          * related device and a new file-descriptor for the freshly opened
776          * device-node.
777          * If the signal is not about our device, we simply ignore it.
778          * Otherwise, we take the file-descriptor and immediately resume the
779          * device.
780          */
781
782         r = sd_bus_message_read(signal, "uuh", &major, &minor, &fd);
783         if (r < 0) {
784                 log_debug("idev-evdev: %s/%s: erroneous ResumeDevice signal",
785                           s->name, e->name);
786                 return 0;
787         }
788
789         /* not our device? */
790         if (makedev(major, minor) != em->devnum)
791                 return 0;
792
793         fd = fcntl(fd, F_DUPFD_CLOEXEC, 3);
794         if (fd < 0) {
795                 log_debug("idev-evdev: %s/%s: cannot duplicate evdev fd: %m",
796                           s->name, e->name);
797                 return 0;
798         }
799
800         r = idev_evdev_resume(&em->evdev, fd);
801         if (r < 0)
802                 log_debug("idev-evdev: %s/%s: cannot resume: %s",
803                           s->name, e->name, strerror(-r));
804
805         return 0;
806 }
807
808 static int managed_evdev_setup_bus(managed_evdev *em) {
809         idev_element *e = &em->evdev.element;
810         idev_session *s = e->session;
811         idev_context *c = s->context;
812         _cleanup_free_ char *match = NULL;
813         int r;
814
815         match = strjoin("type='signal',"
816                         "sender='org.freedesktop.login1',"
817                         "interface='org.freedesktop.login1.Session',"
818                         "member='PauseDevice',"
819                         "path='", s->path, "'",
820                         NULL);
821         if (!match)
822                 return -ENOMEM;
823
824         r = sd_bus_add_match(c->sysbus,
825                              &em->slot_pause_device,
826                              match,
827                              managed_evdev_pause_device_fn,
828                              em);
829         if (r < 0)
830                 return r;
831
832         free(match);
833         match = strjoin("type='signal',"
834                         "sender='org.freedesktop.login1',"
835                         "interface='org.freedesktop.login1.Session',"
836                         "member='ResumeDevice',"
837                         "path='", s->path, "'",
838                         NULL);
839         if (!match)
840                 return -ENOMEM;
841
842         r = sd_bus_add_match(c->sysbus,
843                              &em->slot_resume_device,
844                              match,
845                              managed_evdev_resume_device_fn,
846                              em);
847         if (r < 0)
848                 return r;
849
850         return 0;
851 }
852
853 static int managed_evdev_new(idev_element **out, idev_session *s, struct udev_device *ud) {
854         _cleanup_(idev_element_freep) idev_element *e = NULL;
855         char name[IDEV_EVDEV_NAME_MAX];
856         managed_evdev *em;
857         dev_t devnum;
858         int r;
859
860         assert_return(s, -EINVAL);
861         assert_return(s->context->sysbus, -EINVAL);
862         assert_return(s->managed, -EINVAL);
863         assert_return(s->context->sysbus, -EINVAL);
864         assert_return(ud, -EINVAL);
865
866         devnum = udev_device_get_devnum(ud);
867         if (devnum == 0)
868                 return -ENODEV;
869
870         idev_evdev_name(name, devnum);
871
872         em = new0(managed_evdev, 1);
873         if (!em)
874                 return -ENOMEM;
875
876         e = &em->evdev.element;
877         em->evdev = IDEV_EVDEV_INIT(&managed_evdev_vtable, s);
878         em->devnum = devnum;
879
880         r = managed_evdev_setup_bus(em);
881         if (r < 0)
882                 return r;
883
884         r = idev_element_add(e, name);
885         if (r < 0)
886                 return r;
887
888         if (out)
889                 *out = e;
890         e = NULL;
891         return 0;
892 }
893
894 static void managed_evdev_free(idev_element *e) {
895         managed_evdev *em = managed_evdev_from_element(e);
896
897         em->slot_resume_device = sd_bus_slot_unref(em->slot_resume_device);
898         em->slot_pause_device = sd_bus_slot_unref(em->slot_pause_device);
899         idev_evdev_destroy(&em->evdev);
900         free(em);
901 }
902
903 static const idev_element_vtable managed_evdev_vtable = {
904         .free                   = managed_evdev_free,
905         .enable                 = managed_evdev_resume,
906         .disable                = managed_evdev_pause,
907         .open                   = managed_evdev_resume,
908         .close                  = managed_evdev_pause,
909 };
910
911 /*
912  * Generic Constructor
913  * Instead of relying on the caller to choose between managed and unmanaged
914  * evdev devices, the idev_evdev_new() constructor does that for you (by
915  * looking at s->managed).
916  */
917
918 bool idev_is_evdev(idev_element *e) {
919         return e && (e->vtable == &unmanaged_evdev_vtable ||
920                      e->vtable == &managed_evdev_vtable);
921 }
922
923 idev_element *idev_find_evdev(idev_session *s, dev_t devnum) {
924         char name[IDEV_EVDEV_NAME_MAX];
925
926         assert_return(s, NULL);
927         assert_return(devnum != 0, NULL);
928
929         idev_evdev_name(name, devnum);
930         return idev_find_element(s, name);
931 }
932
933 int idev_evdev_new(idev_element **out, idev_session *s, struct udev_device *ud) {
934         assert_return(s, -EINVAL);
935         assert_return(ud, -EINVAL);
936
937         return s->managed ? managed_evdev_new(out, s, ud) : unmanaged_evdev_new(out, s, ud);
938 }