chiark / gitweb /
5cc6d69aa26386576719cd5411c418bfde696022
[elogind.git] / src / libelogind / sd-login / sd-login.c
1 /*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
2
3 /***
4   This file is part of systemd.
5
6   Copyright 2011 Lennart Poettering
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 <unistd.h>
23 #include <string.h>
24 #include <errno.h>
25 #include <sys/inotify.h>
26 #include <poll.h>
27
28 #include "util.h"
29 #include "cgroup-util.h"
30 #include "macro.h"
31 #include "strv.h"
32 #include "fileio.h"
33 #include "login-shared.h"
34 #include "formats-util.h"
35 #include "sd-login.h"
36
37 _public_ int sd_pid_get_session(pid_t pid, char **session) {
38
39         assert_return(pid >= 0, -EINVAL);
40         assert_return(session, -EINVAL);
41
42         return cg_pid_get_session(pid, session);
43 }
44
45 _public_ int sd_pid_get_unit(pid_t pid, char **unit) {
46
47         assert_return(pid >= 0, -EINVAL);
48         assert_return(unit, -EINVAL);
49
50         return -ESRCH;
51 }
52
53 _public_ int sd_pid_get_user_unit(pid_t pid, char **unit) {
54
55         assert_return(pid >= 0, -EINVAL);
56         assert_return(unit, -EINVAL);
57
58         return -ESRCH;
59 }
60
61 _public_ int sd_pid_get_machine_name(pid_t pid, char **name) {
62
63         assert_return(pid >= 0, -EINVAL);
64         assert_return(name, -EINVAL);
65
66         return -ESRCH;
67 }
68
69 _public_ int sd_pid_get_slice(pid_t pid, char **slice) {
70
71         assert_return(pid >= 0, -EINVAL);
72         assert_return(slice, -EINVAL);
73
74         return -ESRCH;
75 }
76
77 _public_ int sd_pid_get_owner_uid(pid_t pid, uid_t *uid) {
78
79         assert_return(pid >= 0, -EINVAL);
80         assert_return(uid, -EINVAL);
81
82         return -ESRCH;
83 }
84
85 _public_ int sd_peer_get_session(int fd, char **session) {
86         struct ucred ucred = {};
87         int r;
88
89         assert_return(fd >= 0, -EINVAL);
90         assert_return(session, -EINVAL);
91
92         r = getpeercred(fd, &ucred);
93         if (r < 0)
94                 return r;
95
96         return cg_pid_get_session(ucred.pid, session);
97 }
98
99 _public_ int sd_peer_get_owner_uid(int fd, uid_t *uid) {
100         struct ucred ucred;
101         int r;
102
103         assert_return(fd >= 0, -EINVAL);
104         assert_return(uid, -EINVAL);
105
106         r = getpeercred(fd, &ucred);
107         if (r < 0)
108                 return r;
109
110         return -ESRCH;
111 }
112
113 _public_ int sd_peer_get_unit(int fd, char **unit) {
114         struct ucred ucred;
115         int r;
116
117         assert_return(fd >= 0, -EINVAL);
118         assert_return(unit, -EINVAL);
119
120         r = getpeercred(fd, &ucred);
121         if (r < 0)
122                 return r;
123
124         return -ESRCH;
125 }
126
127 _public_ int sd_peer_get_user_unit(int fd, char **unit) {
128         struct ucred ucred;
129         int r;
130
131         assert_return(fd >= 0, -EINVAL);
132         assert_return(unit, -EINVAL);
133
134         r = getpeercred(fd, &ucred);
135         if (r < 0)
136                 return r;
137
138         return -ESRCH;
139 }
140
141 _public_ int sd_peer_get_machine_name(int fd, char **machine) {
142         struct ucred ucred;
143         int r;
144
145         assert_return(fd >= 0, -EINVAL);
146         assert_return(machine, -EINVAL);
147
148         r = getpeercred(fd, &ucred);
149         if (r < 0)
150                 return r;
151
152         return -ESRCH;
153 }
154
155 _public_ int sd_peer_get_slice(int fd, char **slice) {
156         struct ucred ucred;
157         int r;
158
159         assert_return(fd >= 0, -EINVAL);
160         assert_return(slice, -EINVAL);
161
162         r = getpeercred(fd, &ucred);
163         if (r < 0)
164                 return r;
165
166         return -ESRCH;
167 }
168
169 static int file_of_uid(uid_t uid, char **p) {
170         assert(p);
171
172         if (asprintf(p, "/run/systemd/users/" UID_FMT, uid) < 0)
173                 return -ENOMEM;
174
175         return 0;
176 }
177
178 _public_ int sd_uid_get_state(uid_t uid, char**state) {
179         _cleanup_free_ char *p = NULL;
180         char *s = NULL;
181         int r;
182
183         assert_return(state, -EINVAL);
184
185         r = file_of_uid(uid, &p);
186         if (r < 0)
187                 return r;
188
189         r = parse_env_file(p, NEWLINE, "STATE", &s, NULL);
190         if (r == -ENOENT) {
191                 free(s);
192                 s = strdup("offline");
193                 if (!s)
194                         return -ENOMEM;
195
196         } else if (r < 0) {
197                 free(s);
198                 return r;
199         } else if (!s)
200                 return -EIO;
201
202         *state = s;
203         return 0;
204 }
205
206 _public_ int sd_uid_get_display(uid_t uid, char **session) {
207         _cleanup_free_ char *p = NULL, *s = NULL;
208         int r;
209
210         assert_return(session, -EINVAL);
211
212         r = file_of_uid(uid, &p);
213         if (r < 0)
214                 return r;
215
216         r = parse_env_file(p, NEWLINE, "DISPLAY", &s, NULL);
217         if (r < 0)
218                 return r;
219
220         if (isempty(s))
221                 return -ENOENT;
222
223         *session = s;
224         s = NULL;
225
226         return 0;
227 }
228
229 _public_ int sd_uid_is_on_seat(uid_t uid, int require_active, const char *seat) {
230         _cleanup_free_ char *t = NULL, *s = NULL, *p = NULL;
231         size_t l;
232         int r;
233         const char *word, *variable, *state;
234
235         assert_return(seat, -EINVAL);
236
237         variable = require_active ? "ACTIVE_UID" : "UIDS";
238
239         p = strappend("/run/systemd/seats/", seat);
240         if (!p)
241                 return -ENOMEM;
242
243         r = parse_env_file(p, NEWLINE, variable, &s, NULL);
244
245         if (r < 0)
246                 return r;
247
248         if (!s)
249                 return -EIO;
250
251         if (asprintf(&t, UID_FMT, uid) < 0)
252                 return -ENOMEM;
253
254         FOREACH_WORD(word, l, s, state) {
255                 if (strneq(t, word, l))
256                         return 1;
257         }
258
259         return 0;
260 }
261
262 static int uid_get_array(uid_t uid, const char *variable, char ***array) {
263         _cleanup_free_ char *p = NULL, *s = NULL;
264         char **a;
265         int r;
266
267         r = file_of_uid(uid, &p);
268         if (r < 0)
269                 return r;
270
271         r = parse_env_file(p, NEWLINE,
272                            variable, &s,
273                            NULL);
274         if (r < 0) {
275                 if (r == -ENOENT) {
276                         if (array)
277                                 *array = NULL;
278                         return 0;
279                 }
280
281                 return r;
282         }
283
284         if (!s) {
285                 if (array)
286                         *array = NULL;
287                 return 0;
288         }
289
290         a = strv_split(s, " ");
291
292         if (!a)
293                 return -ENOMEM;
294
295         strv_uniq(a);
296         r = strv_length(a);
297
298         if (array)
299                 *array = a;
300         else
301                 strv_free(a);
302
303         return r;
304 }
305
306 _public_ int sd_uid_get_sessions(uid_t uid, int require_active, char ***sessions) {
307         return uid_get_array(
308                         uid,
309                         require_active == 0 ? "ONLINE_SESSIONS" :
310                         require_active > 0  ? "ACTIVE_SESSIONS" :
311                                               "SESSIONS",
312                         sessions);
313 }
314
315 _public_ int sd_uid_get_seats(uid_t uid, int require_active, char ***seats) {
316         return uid_get_array(
317                         uid,
318                         require_active == 0 ? "ONLINE_SEATS" :
319                         require_active > 0  ? "ACTIVE_SEATS" :
320                                               "SEATS",
321                         seats);
322 }
323
324 static int file_of_session(const char *session, char **_p) {
325         char *p;
326         int r;
327
328         assert(_p);
329
330         if (session) {
331                 if (!session_id_valid(session))
332                         return -EINVAL;
333
334                 p = strappend("/run/systemd/sessions/", session);
335         } else {
336                 _cleanup_free_ char *buf = NULL;
337
338                 r = sd_pid_get_session(0, &buf);
339                 if (r < 0)
340                         return r;
341
342                 p = strappend("/run/systemd/sessions/", buf);
343         }
344
345         if (!p)
346                 return -ENOMEM;
347
348         *_p = p;
349         return 0;
350 }
351
352 _public_ int sd_session_is_active(const char *session) {
353         int r;
354         _cleanup_free_ char *p = NULL, *s = NULL;
355
356         r = file_of_session(session, &p);
357         if (r < 0)
358                 return r;
359
360         r = parse_env_file(p, NEWLINE, "ACTIVE", &s, NULL);
361         if (r < 0)
362                 return r;
363
364         if (!s)
365                 return -EIO;
366
367         return parse_boolean(s);
368 }
369
370 _public_ int sd_session_is_remote(const char *session) {
371         int r;
372         _cleanup_free_ char *p = NULL, *s = NULL;
373
374         r = file_of_session(session, &p);
375         if (r < 0)
376                 return r;
377
378         r = parse_env_file(p, NEWLINE, "REMOTE", &s, NULL);
379         if (r < 0)
380                 return r;
381
382         if (!s)
383                 return -EIO;
384
385         return parse_boolean(s);
386 }
387
388 _public_ int sd_session_get_state(const char *session, char **state) {
389         _cleanup_free_ char *p = NULL, *s = NULL;
390         int r;
391
392         assert_return(state, -EINVAL);
393
394         r = file_of_session(session, &p);
395         if (r < 0)
396                 return r;
397
398         r = parse_env_file(p, NEWLINE, "STATE", &s, NULL);
399         if (r < 0)
400                 return r;
401         else if (!s)
402                 return -EIO;
403
404         *state = s;
405         s = NULL;
406
407         return 0;
408 }
409
410 _public_ int sd_session_get_uid(const char *session, uid_t *uid) {
411         int r;
412         _cleanup_free_ char *p = NULL, *s = NULL;
413
414         assert_return(uid, -EINVAL);
415
416         r = file_of_session(session, &p);
417         if (r < 0)
418                 return r;
419
420         r = parse_env_file(p, NEWLINE, "UID", &s, NULL);
421         if (r < 0)
422                 return r;
423
424         if (!s)
425                 return -EIO;
426
427         return parse_uid(s, uid);
428 }
429
430 static int session_get_string(const char *session, const char *field, char **value) {
431         _cleanup_free_ char *p = NULL, *s = NULL;
432         int r;
433
434         assert_return(value, -EINVAL);
435
436         r = file_of_session(session, &p);
437         if (r < 0)
438                 return r;
439
440         r = parse_env_file(p, NEWLINE, field, &s, NULL);
441         if (r < 0)
442                 return r;
443
444         if (isempty(s))
445                 return -ENOENT;
446
447         *value = s;
448         s = NULL;
449         return 0;
450 }
451
452 _public_ int sd_session_get_seat(const char *session, char **seat) {
453         return session_get_string(session, "SEAT", seat);
454 }
455
456 _public_ int sd_session_get_tty(const char *session, char **tty) {
457         return session_get_string(session, "TTY", tty);
458 }
459
460 _public_ int sd_session_get_vt(const char *session, unsigned *vtnr) {
461         _cleanup_free_ char *vtnr_string = NULL;
462         unsigned u;
463         int r;
464
465         r = session_get_string(session, "VTNR", &vtnr_string);
466         if (r < 0)
467                 return r;
468
469         r = safe_atou(vtnr_string, &u);
470         if (r < 0)
471                 return r;
472
473         *vtnr = u;
474         return 0;
475 }
476
477 _public_ int sd_session_get_service(const char *session, char **service) {
478         return session_get_string(session, "SERVICE", service);
479 }
480
481 _public_ int sd_session_get_type(const char *session, char **type) {
482         return session_get_string(session, "TYPE", type);
483 }
484
485 _public_ int sd_session_get_class(const char *session, char **class) {
486         return session_get_string(session, "CLASS", class);
487 }
488
489 _public_ int sd_session_get_desktop(const char *session, char **desktop) {
490         _cleanup_free_ char *escaped = NULL;
491         char *t;
492         int r;
493
494         assert_return(desktop, -EINVAL);
495
496         r = session_get_string(session, "DESKTOP", &escaped);
497         if (r < 0)
498                 return r;
499
500         r = cunescape(escaped, 0, &t);
501         if (r < 0)
502                 return r;
503
504         *desktop = t;
505         return 0;
506 }
507
508 _public_ int sd_session_get_display(const char *session, char **display) {
509         return session_get_string(session, "DISPLAY", display);
510 }
511
512 _public_ int sd_session_get_remote_user(const char *session, char **remote_user) {
513         return session_get_string(session, "REMOTE_USER", remote_user);
514 }
515
516 _public_ int sd_session_get_remote_host(const char *session, char **remote_host) {
517         return session_get_string(session, "REMOTE_HOST", remote_host);
518 }
519
520 static int file_of_seat(const char *seat, char **_p) {
521         char *p;
522         int r;
523
524         assert(_p);
525
526         if (seat)
527                 p = strappend("/run/systemd/seats/", seat);
528         else {
529                 _cleanup_free_ char *buf = NULL;
530
531                 r = sd_session_get_seat(NULL, &buf);
532                 if (r < 0)
533                         return r;
534
535                 p = strappend("/run/systemd/seats/", buf);
536         }
537
538         if (!p)
539                 return -ENOMEM;
540
541         *_p = p;
542         p = NULL;
543         return 0;
544 }
545
546 _public_ int sd_seat_get_active(const char *seat, char **session, uid_t *uid) {
547         _cleanup_free_ char *p = NULL, *s = NULL, *t = NULL;
548         int r;
549
550         assert_return(session || uid, -EINVAL);
551
552         r = file_of_seat(seat, &p);
553         if (r < 0)
554                 return r;
555
556         r = parse_env_file(p, NEWLINE,
557                            "ACTIVE", &s,
558                            "ACTIVE_UID", &t,
559                            NULL);
560         if (r < 0)
561                 return r;
562
563         if (session && !s)
564                 return -ENOENT;
565
566         if (uid && !t)
567                 return -ENOENT;
568
569         if (uid && t) {
570                 r = parse_uid(t, uid);
571                 if (r < 0)
572                         return r;
573         }
574
575         if (session && s) {
576                 *session = s;
577                 s = NULL;
578         }
579
580         return 0;
581 }
582
583 _public_ int sd_seat_get_sessions(const char *seat, char ***sessions, uid_t **uids, unsigned *n_uids) {
584         _cleanup_free_ char *p = NULL, *s = NULL, *t = NULL;
585         _cleanup_strv_free_ char **a = NULL;
586         _cleanup_free_ uid_t *b = NULL;
587         unsigned n = 0;
588         int r;
589
590         r = file_of_seat(seat, &p);
591         if (r < 0)
592                 return r;
593
594         r = parse_env_file(p, NEWLINE,
595                            "SESSIONS", &s,
596                            "ACTIVE_SESSIONS", &t,
597                            NULL);
598
599         if (r < 0)
600                 return r;
601
602         if (s) {
603                 a = strv_split(s, " ");
604                 if (!a)
605                         return -ENOMEM;
606         }
607
608         if (uids && t) {
609                 const char *word, *state;
610                 size_t l;
611
612                 FOREACH_WORD(word, l, t, state)
613                         n++;
614
615                 if (n > 0) {
616                         unsigned i = 0;
617
618                         b = new(uid_t, n);
619                         if (!b)
620                                 return -ENOMEM;
621
622                         FOREACH_WORD(word, l, t, state) {
623                                 _cleanup_free_ char *k = NULL;
624
625                                 k = strndup(word, l);
626                                 if (!k)
627                                         return -ENOMEM;
628
629                                 r = parse_uid(k, b + i);
630
631                                 if (r < 0)
632                                         continue;
633
634                                 i++;
635                         }
636                 }
637         }
638
639         r = strv_length(a);
640
641         if (sessions) {
642                 *sessions = a;
643                 a = NULL;
644         }
645
646         if (uids) {
647                 *uids = b;
648                 b = NULL;
649         }
650
651         if (n_uids)
652                 *n_uids = n;
653
654         return r;
655 }
656
657 static int seat_get_can(const char *seat, const char *variable) {
658         _cleanup_free_ char *p = NULL, *s = NULL;
659         int r;
660
661         assert_return(variable, -EINVAL);
662
663         r = file_of_seat(seat, &p);
664         if (r < 0)
665                 return r;
666
667         r = parse_env_file(p, NEWLINE,
668                            variable, &s,
669                            NULL);
670         if (r < 0)
671                 return r;
672         if (!s)
673                 return 0;
674
675         return parse_boolean(s);
676 }
677
678 _public_ int sd_seat_can_multi_session(const char *seat) {
679         return seat_get_can(seat, "CAN_MULTI_SESSION");
680 }
681
682 _public_ int sd_seat_can_tty(const char *seat) {
683         return seat_get_can(seat, "CAN_TTY");
684 }
685
686 _public_ int sd_seat_can_graphical(const char *seat) {
687         return seat_get_can(seat, "CAN_GRAPHICAL");
688 }
689
690 _public_ int sd_get_seats(char ***seats) {
691         return get_files_in_directory("/run/systemd/seats/", seats);
692 }
693
694 _public_ int sd_get_sessions(char ***sessions) {
695         return get_files_in_directory("/run/systemd/sessions/", sessions);
696 }
697
698 _public_ int sd_get_uids(uid_t **users) {
699         _cleanup_closedir_ DIR *d;
700         int r = 0;
701         unsigned n = 0;
702         _cleanup_free_ uid_t *l = NULL;
703
704         d = opendir("/run/systemd/users/");
705         if (!d)
706                 return -errno;
707
708         for (;;) {
709                 struct dirent *de;
710                 int k;
711                 uid_t uid;
712
713                 errno = 0;
714                 de = readdir(d);
715                 if (!de && errno != 0)
716                         return -errno;
717
718                 if (!de)
719                         break;
720
721                 dirent_ensure_type(d, de);
722
723                 if (!dirent_is_file(de))
724                         continue;
725
726                 k = parse_uid(de->d_name, &uid);
727                 if (k < 0)
728                         continue;
729
730                 if (users) {
731                         if ((unsigned) r >= n) {
732                                 uid_t *t;
733
734                                 n = MAX(16, 2*r);
735                                 t = realloc(l, sizeof(uid_t) * n);
736                                 if (!t)
737                                         return -ENOMEM;
738
739                                 l = t;
740                         }
741
742                         assert((unsigned) r < n);
743                         l[r++] = uid;
744                 } else
745                         r++;
746         }
747
748         if (users) {
749                 *users = l;
750                 l = NULL;
751         }
752
753         return r;
754 }
755
756 _public_ int sd_get_machine_names(char ***machines) {
757         char **l = NULL, **a, **b;
758         int r;
759
760         assert_return(machines, -EINVAL);
761
762         r = get_files_in_directory("/run/systemd/machines/", &l);
763         if (r < 0)
764                 return r;
765
766         if (l) {
767                 r = 0;
768
769                 /* Filter out the unit: symlinks */
770                 for (a = l, b = l; *a; a++) {
771                         if (startswith(*a, "unit:"))
772                                 free(*a);
773                         else {
774                                 *b = *a;
775                                 b++;
776                                 r++;
777                         }
778                 }
779
780                 *b = NULL;
781         }
782
783         *machines = l;
784         return r;
785 }
786
787 _public_ int sd_machine_get_class(const char *machine, char **class) {
788         _cleanup_free_ char *c = NULL;
789         const char *p;
790         int r;
791
792         assert_return(machine_name_is_valid(machine), -EINVAL);
793         assert_return(class, -EINVAL);
794
795         p = strjoina("/run/systemd/machines/", machine);
796         r = parse_env_file(p, NEWLINE, "CLASS", &c, NULL);
797         if (r < 0)
798                 return r;
799         if (!c)
800                 return -EIO;
801
802         *class = c;
803         c = NULL;
804
805         return 0;
806 }
807
808 _public_ int sd_machine_get_ifindices(const char *machine, int **ifindices) {
809         _cleanup_free_ char *netif = NULL;
810         size_t l, allocated = 0, nr = 0;
811         int *ni = NULL;
812         const char *p, *word, *state;
813         int r;
814
815         assert_return(machine_name_is_valid(machine), -EINVAL);
816         assert_return(ifindices, -EINVAL);
817
818         p = strjoina("/run/systemd/machines/", machine);
819         r = parse_env_file(p, NEWLINE, "NETIF", &netif, NULL);
820         if (r < 0)
821                 return r;
822         if (!netif) {
823                 *ifindices = NULL;
824                 return 0;
825         }
826
827         FOREACH_WORD(word, l, netif, state) {
828                 char buf[l+1];
829                 int ifi;
830
831                 *(char*) (mempcpy(buf, word, l)) = 0;
832
833                 if (safe_atoi(buf, &ifi) < 0)
834                         continue;
835                 if (ifi <= 0)
836                         continue;
837
838                 if (!GREEDY_REALLOC(ni, allocated, nr+1)) {
839                         free(ni);
840                         return -ENOMEM;
841                 }
842
843                 ni[nr++] = ifi;
844         }
845
846         *ifindices = ni;
847         return nr;
848 }
849
850 static inline int MONITOR_TO_FD(sd_login_monitor *m) {
851         return (int) (unsigned long) m - 1;
852 }
853
854 static inline sd_login_monitor* FD_TO_MONITOR(int fd) {
855         return (sd_login_monitor*) (unsigned long) (fd + 1);
856 }
857
858 _public_ int sd_login_monitor_new(const char *category, sd_login_monitor **m) {
859         int fd, k;
860         bool good = false;
861
862         assert_return(m, -EINVAL);
863
864         fd = inotify_init1(IN_NONBLOCK|IN_CLOEXEC);
865         if (fd < 0)
866                 return -errno;
867
868         if (!category || streq(category, "seat")) {
869                 k = inotify_add_watch(fd, "/run/systemd/seats/", IN_MOVED_TO|IN_DELETE);
870                 if (k < 0) {
871                         safe_close(fd);
872                         return -errno;
873                 }
874
875                 good = true;
876         }
877
878         if (!category || streq(category, "session")) {
879                 k = inotify_add_watch(fd, "/run/systemd/sessions/", IN_MOVED_TO|IN_DELETE);
880                 if (k < 0) {
881                         safe_close(fd);
882                         return -errno;
883                 }
884
885                 good = true;
886         }
887
888         if (!category || streq(category, "uid")) {
889                 k = inotify_add_watch(fd, "/run/systemd/users/", IN_MOVED_TO|IN_DELETE);
890                 if (k < 0) {
891                         safe_close(fd);
892                         return -errno;
893                 }
894
895                 good = true;
896         }
897
898         if (!category || streq(category, "machine")) {
899                 k = inotify_add_watch(fd, "/run/systemd/machines/", IN_MOVED_TO|IN_DELETE);
900                 if (k < 0) {
901                         safe_close(fd);
902                         return -errno;
903                 }
904
905                 good = true;
906         }
907
908         if (!good) {
909                 close_nointr(fd);
910                 return -EINVAL;
911         }
912
913         *m = FD_TO_MONITOR(fd);
914         return 0;
915 }
916
917 _public_ sd_login_monitor* sd_login_monitor_unref(sd_login_monitor *m) {
918         int fd;
919
920         assert_return(m, NULL);
921
922         fd = MONITOR_TO_FD(m);
923         close_nointr(fd);
924
925         return NULL;
926 }
927
928 _public_ int sd_login_monitor_flush(sd_login_monitor *m) {
929
930         assert_return(m, -EINVAL);
931
932         return flush_fd(MONITOR_TO_FD(m));
933 }
934
935 _public_ int sd_login_monitor_get_fd(sd_login_monitor *m) {
936
937         assert_return(m, -EINVAL);
938
939         return MONITOR_TO_FD(m);
940 }
941
942 _public_ int sd_login_monitor_get_events(sd_login_monitor *m) {
943
944         assert_return(m, -EINVAL);
945
946         /* For now we will only return POLLIN here, since we don't
947          * need anything else ever for inotify.  However, let's have
948          * this API to keep our options open should we later on need
949          * it. */
950         return POLLIN;
951 }
952
953 _public_ int sd_login_monitor_get_timeout(sd_login_monitor *m, uint64_t *timeout_usec) {
954
955         assert_return(m, -EINVAL);
956         assert_return(timeout_usec, -EINVAL);
957
958         /* For now we will only return (uint64_t) -1, since we don't
959          * need any timeout. However, let's have this API to keep our
960          * options open should we later on need it. */
961         *timeout_usec = (uint64_t) -1;
962         return 0;
963 }