LCOV - code coverage report
Current view: top level - libsystemd/sd-event - test-event.c (source / functions) Hit Total Coverage
Test: main_coverage.info Lines: 284 289 98.3 %
Date: 2019-08-22 15:41:25 Functions: 18 18 100.0 %

          Line data    Source code
       1             : /* SPDX-License-Identifier: LGPL-2.1+ */
       2             : 
       3             : #include <sys/wait.h>
       4             : 
       5             : #include "sd-event.h"
       6             : 
       7             : #include "alloc-util.h"
       8             : #include "fd-util.h"
       9             : #include "fs-util.h"
      10             : #include "log.h"
      11             : #include "macro.h"
      12             : #include "parse-util.h"
      13             : #include "path-util.h"
      14             : #include "process-util.h"
      15             : #include "rm-rf.h"
      16             : #include "signal-util.h"
      17             : #include "stdio-util.h"
      18             : #include "string-util.h"
      19             : #include "tests.h"
      20             : #include "tmpfile-util.h"
      21             : #include "util.h"
      22             : 
      23           6 : static int prepare_handler(sd_event_source *s, void *userdata) {
      24           6 :         log_info("preparing %c", PTR_TO_INT(userdata));
      25           6 :         return 1;
      26             : }
      27             : 
      28             : static bool got_a, got_b, got_c, got_unref;
      29             : static unsigned got_d;
      30             : 
      31           1 : static int unref_handler(sd_event_source *s, int fd, uint32_t revents, void *userdata) {
      32           1 :         sd_event_source_unref(s);
      33           1 :         got_unref = true;
      34           1 :         return 0;
      35             : }
      36             : 
      37           4 : static int io_handler(sd_event_source *s, int fd, uint32_t revents, void *userdata) {
      38             : 
      39           4 :         log_info("got IO on %c", PTR_TO_INT(userdata));
      40             : 
      41           4 :         if (userdata == INT_TO_PTR('a')) {
      42           1 :                 assert_se(sd_event_source_set_enabled(s, SD_EVENT_OFF) >= 0);
      43           1 :                 assert_se(!got_a);
      44           1 :                 got_a = true;
      45           3 :         } else if (userdata == INT_TO_PTR('b')) {
      46           1 :                 assert_se(!got_b);
      47           1 :                 got_b = true;
      48           2 :         } else if (userdata == INT_TO_PTR('d')) {
      49           2 :                 got_d++;
      50           2 :                 if (got_d < 2)
      51           1 :                         assert_se(sd_event_source_set_enabled(s, SD_EVENT_ONESHOT) >= 0);
      52             :                 else
      53           1 :                         assert_se(sd_event_source_set_enabled(s, SD_EVENT_OFF) >= 0);
      54             :         } else
      55           0 :                 assert_not_reached("Yuck!");
      56             : 
      57           4 :         return 1;
      58             : }
      59             : 
      60           1 : static int child_handler(sd_event_source *s, const siginfo_t *si, void *userdata) {
      61             : 
      62           1 :         assert_se(s);
      63           1 :         assert_se(si);
      64             : 
      65           1 :         log_info("got child on %c", PTR_TO_INT(userdata));
      66             : 
      67           1 :         assert_se(userdata == INT_TO_PTR('f'));
      68             : 
      69           1 :         assert_se(sd_event_exit(sd_event_source_get_event(s), 0) >= 0);
      70           1 :         sd_event_source_unref(s);
      71             : 
      72           1 :         return 1;
      73             : }
      74             : 
      75           1 : static int signal_handler(sd_event_source *s, const struct signalfd_siginfo *si, void *userdata) {
      76           1 :         sd_event_source *p = NULL;
      77             :         pid_t pid;
      78             : 
      79           1 :         assert_se(s);
      80           1 :         assert_se(si);
      81             : 
      82           1 :         log_info("got signal on %c", PTR_TO_INT(userdata));
      83             : 
      84           1 :         assert_se(userdata == INT_TO_PTR('e'));
      85             : 
      86           1 :         assert_se(sigprocmask_many(SIG_BLOCK, NULL, SIGCHLD, -1) >= 0);
      87             : 
      88           1 :         pid = fork();
      89           1 :         assert_se(pid >= 0);
      90             : 
      91           1 :         if (pid == 0)
      92           0 :                 _exit(EXIT_SUCCESS);
      93             : 
      94           1 :         assert_se(sd_event_add_child(sd_event_source_get_event(s), &p, pid, WEXITED, child_handler, INT_TO_PTR('f')) >= 0);
      95           1 :         assert_se(sd_event_source_set_enabled(p, SD_EVENT_ONESHOT) >= 0);
      96             : 
      97           1 :         sd_event_source_unref(s);
      98             : 
      99           1 :         return 1;
     100             : }
     101             : 
     102           1 : static int defer_handler(sd_event_source *s, void *userdata) {
     103           1 :         sd_event_source *p = NULL;
     104             : 
     105           1 :         assert_se(s);
     106             : 
     107           1 :         log_info("got defer on %c", PTR_TO_INT(userdata));
     108             : 
     109           1 :         assert_se(userdata == INT_TO_PTR('d'));
     110             : 
     111           1 :         assert_se(sigprocmask_many(SIG_BLOCK, NULL, SIGUSR1, -1) >= 0);
     112             : 
     113           1 :         assert_se(sd_event_add_signal(sd_event_source_get_event(s), &p, SIGUSR1, signal_handler, INT_TO_PTR('e')) >= 0);
     114           1 :         assert_se(sd_event_source_set_enabled(p, SD_EVENT_ONESHOT) >= 0);
     115           1 :         raise(SIGUSR1);
     116             : 
     117           1 :         sd_event_source_unref(s);
     118             : 
     119           1 :         return 1;
     120             : }
     121             : 
     122             : static bool do_quit = false;
     123             : 
     124           2 : static int time_handler(sd_event_source *s, uint64_t usec, void *userdata) {
     125           2 :         log_info("got timer on %c", PTR_TO_INT(userdata));
     126             : 
     127           2 :         if (userdata == INT_TO_PTR('c')) {
     128             : 
     129           2 :                 if (do_quit) {
     130             :                         sd_event_source *p;
     131             : 
     132           1 :                         assert_se(sd_event_add_defer(sd_event_source_get_event(s), &p, defer_handler, INT_TO_PTR('d')) >= 0);
     133           1 :                         assert_se(sd_event_source_set_enabled(p, SD_EVENT_ONESHOT) >= 0);
     134             :                 } else {
     135           1 :                         assert_se(!got_c);
     136           1 :                         got_c = true;
     137             :                 }
     138             :         } else
     139           0 :                 assert_not_reached("Huh?");
     140             : 
     141           2 :         return 2;
     142             : }
     143             : 
     144             : static bool got_exit = false;
     145             : 
     146           1 : static int exit_handler(sd_event_source *s, void *userdata) {
     147           1 :         log_info("got quit handler on %c", PTR_TO_INT(userdata));
     148             : 
     149           1 :         got_exit = true;
     150             : 
     151           1 :         return 3;
     152             : }
     153             : 
     154             : static bool got_post = false;
     155             : 
     156           3 : static int post_handler(sd_event_source *s, void *userdata) {
     157           3 :         log_info("got post handler");
     158             : 
     159           3 :         got_post = true;
     160             : 
     161           3 :         return 2;
     162             : }
     163             : 
     164           1 : static void test_basic(void) {
     165           1 :         sd_event *e = NULL;
     166           1 :         sd_event_source *w = NULL, *x = NULL, *y = NULL, *z = NULL, *q = NULL, *t = NULL;
     167             :         static const char ch = 'x';
     168           1 :         int a[2] = { -1, -1 }, b[2] = { -1, -1}, d[2] = { -1, -1}, k[2] = { -1, -1 };
     169             :         uint64_t event_now;
     170             :         int64_t priority;
     171             : 
     172           1 :         assert_se(pipe(a) >= 0);
     173           1 :         assert_se(pipe(b) >= 0);
     174           1 :         assert_se(pipe(d) >= 0);
     175           1 :         assert_se(pipe(k) >= 0);
     176             : 
     177           1 :         assert_se(sd_event_default(&e) >= 0);
     178           1 :         assert_se(sd_event_now(e, CLOCK_MONOTONIC, &event_now) > 0);
     179             : 
     180           1 :         assert_se(sd_event_set_watchdog(e, true) >= 0);
     181             : 
     182             :         /* Test whether we cleanly can destroy an io event source from its own handler */
     183           1 :         got_unref = false;
     184           1 :         assert_se(sd_event_add_io(e, &t, k[0], EPOLLIN, unref_handler, NULL) >= 0);
     185           1 :         assert_se(write(k[1], &ch, 1) == 1);
     186           1 :         assert_se(sd_event_run(e, (uint64_t) -1) >= 1);
     187           1 :         assert_se(got_unref);
     188             : 
     189           1 :         got_a = false, got_b = false, got_c = false, got_d = 0;
     190             : 
     191             :         /* Add a oneshot handler, trigger it, reenable it, and trigger
     192             :          * it again. */
     193           1 :         assert_se(sd_event_add_io(e, &w, d[0], EPOLLIN, io_handler, INT_TO_PTR('d')) >= 0);
     194           1 :         assert_se(sd_event_source_set_enabled(w, SD_EVENT_ONESHOT) >= 0);
     195           1 :         assert_se(write(d[1], &ch, 1) >= 0);
     196           1 :         assert_se(sd_event_run(e, (uint64_t) -1) >= 1);
     197           1 :         assert_se(got_d == 1);
     198           1 :         assert_se(write(d[1], &ch, 1) >= 0);
     199           1 :         assert_se(sd_event_run(e, (uint64_t) -1) >= 1);
     200           1 :         assert_se(got_d == 2);
     201             : 
     202           1 :         assert_se(sd_event_add_io(e, &x, a[0], EPOLLIN, io_handler, INT_TO_PTR('a')) >= 0);
     203           1 :         assert_se(sd_event_add_io(e, &y, b[0], EPOLLIN, io_handler, INT_TO_PTR('b')) >= 0);
     204           1 :         assert_se(sd_event_add_time(e, &z, CLOCK_MONOTONIC, 0, 0, time_handler, INT_TO_PTR('c')) >= 0);
     205           1 :         assert_se(sd_event_add_exit(e, &q, exit_handler, INT_TO_PTR('g')) >= 0);
     206             : 
     207           1 :         assert_se(sd_event_source_set_priority(x, 99) >= 0);
     208           1 :         assert_se(sd_event_source_get_priority(x, &priority) >= 0);
     209           1 :         assert_se(priority == 99);
     210           1 :         assert_se(sd_event_source_set_enabled(y, SD_EVENT_ONESHOT) >= 0);
     211           1 :         assert_se(sd_event_source_set_prepare(x, prepare_handler) >= 0);
     212           1 :         assert_se(sd_event_source_set_priority(z, 50) >= 0);
     213           1 :         assert_se(sd_event_source_set_enabled(z, SD_EVENT_ONESHOT) >= 0);
     214           1 :         assert_se(sd_event_source_set_prepare(z, prepare_handler) >= 0);
     215             : 
     216             :         /* Test for floating event sources */
     217           1 :         assert_se(sigprocmask_many(SIG_BLOCK, NULL, SIGRTMIN+1, -1) >= 0);
     218           1 :         assert_se(sd_event_add_signal(e, NULL, SIGRTMIN+1, NULL, NULL) >= 0);
     219             : 
     220           1 :         assert_se(write(a[1], &ch, 1) >= 0);
     221           1 :         assert_se(write(b[1], &ch, 1) >= 0);
     222             : 
     223           1 :         assert_se(!got_a && !got_b && !got_c);
     224             : 
     225           1 :         assert_se(sd_event_run(e, (uint64_t) -1) >= 1);
     226             : 
     227           1 :         assert_se(!got_a && got_b && !got_c);
     228             : 
     229           1 :         assert_se(sd_event_run(e, (uint64_t) -1) >= 1);
     230             : 
     231           1 :         assert_se(!got_a && got_b && got_c);
     232             : 
     233           1 :         assert_se(sd_event_run(e, (uint64_t) -1) >= 1);
     234             : 
     235           1 :         assert_se(got_a && got_b && got_c);
     236             : 
     237           1 :         sd_event_source_unref(x);
     238           1 :         sd_event_source_unref(y);
     239             : 
     240           1 :         do_quit = true;
     241           1 :         assert_se(sd_event_add_post(e, NULL, post_handler, NULL) >= 0);
     242           1 :         assert_se(sd_event_now(e, CLOCK_MONOTONIC, &event_now) == 0);
     243           1 :         assert_se(sd_event_source_set_time(z, event_now + 200 * USEC_PER_MSEC) >= 0);
     244           1 :         assert_se(sd_event_source_set_enabled(z, SD_EVENT_ONESHOT) >= 0);
     245             : 
     246           1 :         assert_se(sd_event_loop(e) >= 0);
     247           1 :         assert_se(got_post);
     248           1 :         assert_se(got_exit);
     249             : 
     250           1 :         sd_event_source_unref(z);
     251           1 :         sd_event_source_unref(q);
     252             : 
     253           1 :         sd_event_source_unref(w);
     254             : 
     255           1 :         sd_event_unref(e);
     256             : 
     257           1 :         safe_close_pair(a);
     258           1 :         safe_close_pair(b);
     259           1 :         safe_close_pair(d);
     260           1 :         safe_close_pair(k);
     261           1 : }
     262             : 
     263           1 : static void test_sd_event_now(void) {
     264           1 :         _cleanup_(sd_event_unrefp) sd_event *e = NULL;
     265             :         uint64_t event_now;
     266             : 
     267           1 :         assert_se(sd_event_new(&e) >= 0);
     268           1 :         assert_se(sd_event_now(e, CLOCK_MONOTONIC, &event_now) > 0);
     269           1 :         assert_se(sd_event_now(e, CLOCK_REALTIME, &event_now) > 0);
     270           1 :         assert_se(sd_event_now(e, CLOCK_REALTIME_ALARM, &event_now) > 0);
     271           1 :         if (clock_boottime_supported()) {
     272           1 :                 assert_se(sd_event_now(e, CLOCK_BOOTTIME, &event_now) > 0);
     273           1 :                 assert_se(sd_event_now(e, CLOCK_BOOTTIME_ALARM, &event_now) > 0);
     274             :         }
     275           1 :         assert_se(sd_event_now(e, -1, &event_now) == -EOPNOTSUPP);
     276           1 :         assert_se(sd_event_now(e, 900 /* arbitrary big number */, &event_now) == -EOPNOTSUPP);
     277             : 
     278           1 :         assert_se(sd_event_run(e, 0) == 0);
     279             : 
     280           1 :         assert_se(sd_event_now(e, CLOCK_MONOTONIC, &event_now) == 0);
     281           1 :         assert_se(sd_event_now(e, CLOCK_REALTIME, &event_now) == 0);
     282           1 :         assert_se(sd_event_now(e, CLOCK_REALTIME_ALARM, &event_now) == 0);
     283           1 :         if (clock_boottime_supported()) {
     284           1 :                 assert_se(sd_event_now(e, CLOCK_BOOTTIME, &event_now) == 0);
     285           1 :                 assert_se(sd_event_now(e, CLOCK_BOOTTIME_ALARM, &event_now) == 0);
     286             :         }
     287           1 :         assert_se(sd_event_now(e, -1, &event_now) == -EOPNOTSUPP);
     288           1 :         assert_se(sd_event_now(e, 900 /* arbitrary big number */, &event_now) == -EOPNOTSUPP);
     289           1 : }
     290             : 
     291             : static int last_rtqueue_sigval = 0;
     292             : static int n_rtqueue = 0;
     293             : 
     294           4 : static int rtqueue_handler(sd_event_source *s, const struct signalfd_siginfo *si, void *userdata) {
     295           4 :         last_rtqueue_sigval = si->ssi_int;
     296           4 :         n_rtqueue++;
     297           4 :         return 0;
     298             : }
     299             : 
     300           1 : static void test_rtqueue(void) {
     301           1 :         sd_event_source *u = NULL, *v = NULL, *s = NULL;
     302           1 :         sd_event *e = NULL;
     303             : 
     304           1 :         assert_se(sd_event_default(&e) >= 0);
     305             : 
     306           1 :         assert_se(sigprocmask_many(SIG_BLOCK, NULL, SIGRTMIN+2, SIGRTMIN+3, SIGUSR2, -1) >= 0);
     307           1 :         assert_se(sd_event_add_signal(e, &u, SIGRTMIN+2, rtqueue_handler, NULL) >= 0);
     308           1 :         assert_se(sd_event_add_signal(e, &v, SIGRTMIN+3, rtqueue_handler, NULL) >= 0);
     309           1 :         assert_se(sd_event_add_signal(e, &s, SIGUSR2, rtqueue_handler, NULL) >= 0);
     310             : 
     311           1 :         assert_se(sd_event_source_set_priority(v, -10) >= 0);
     312             : 
     313           1 :         assert_se(sigqueue(getpid_cached(), SIGRTMIN+2, (union sigval) { .sival_int = 1 }) >= 0);
     314           1 :         assert_se(sigqueue(getpid_cached(), SIGRTMIN+3, (union sigval) { .sival_int = 2 }) >= 0);
     315           1 :         assert_se(sigqueue(getpid_cached(), SIGUSR2, (union sigval) { .sival_int = 3 }) >= 0);
     316           1 :         assert_se(sigqueue(getpid_cached(), SIGRTMIN+3, (union sigval) { .sival_int = 4 }) >= 0);
     317           1 :         assert_se(sigqueue(getpid_cached(), SIGUSR2, (union sigval) { .sival_int = 5 }) >= 0);
     318             : 
     319           1 :         assert_se(n_rtqueue == 0);
     320           1 :         assert_se(last_rtqueue_sigval == 0);
     321             : 
     322           1 :         assert_se(sd_event_run(e, (uint64_t) -1) >= 1);
     323           1 :         assert_se(n_rtqueue == 1);
     324           1 :         assert_se(last_rtqueue_sigval == 2); /* first SIGRTMIN+3 */
     325             : 
     326           1 :         assert_se(sd_event_run(e, (uint64_t) -1) >= 1);
     327           1 :         assert_se(n_rtqueue == 2);
     328           1 :         assert_se(last_rtqueue_sigval == 4); /* second SIGRTMIN+3 */
     329             : 
     330           1 :         assert_se(sd_event_run(e, (uint64_t) -1) >= 1);
     331           1 :         assert_se(n_rtqueue == 3);
     332           1 :         assert_se(last_rtqueue_sigval == 3); /* first SIGUSR2 */
     333             : 
     334           1 :         assert_se(sd_event_run(e, (uint64_t) -1) >= 1);
     335           1 :         assert_se(n_rtqueue == 4);
     336           1 :         assert_se(last_rtqueue_sigval == 1); /* SIGRTMIN+2 */
     337             : 
     338           1 :         assert_se(sd_event_run(e, 0) == 0); /* the other SIGUSR2 is dropped, because the first one was still queued */
     339           1 :         assert_se(n_rtqueue == 4);
     340           1 :         assert_se(last_rtqueue_sigval == 1);
     341             : 
     342           1 :         sd_event_source_unref(u);
     343           1 :         sd_event_source_unref(v);
     344           1 :         sd_event_source_unref(s);
     345             : 
     346           1 :         sd_event_unref(e);
     347           1 : }
     348             : 
     349             : #define CREATE_EVENTS_MAX (70000U)
     350             : 
     351             : struct inotify_context {
     352             :         bool delete_self_handler_called;
     353             :         unsigned create_called[CREATE_EVENTS_MAX];
     354             :         unsigned create_overflow;
     355             :         unsigned n_create_events;
     356             : };
     357             : 
     358       49462 : static void maybe_exit(sd_event_source *s, struct inotify_context *c) {
     359             :         unsigned n;
     360             : 
     361       49462 :         assert(s);
     362       49462 :         assert(c);
     363             : 
     364       49462 :         if (!c->delete_self_handler_called)
     365       32972 :                 return;
     366             : 
     367       49470 :         for (n = 0; n < 3; n++) {
     368             :                 unsigned i;
     369             : 
     370       49468 :                 if (c->create_overflow & (1U << n))
     371       32773 :                         continue;
     372             : 
     373   134268264 :                 for (i = 0; i < c->n_create_events; i++)
     374   134268057 :                         if (!(c->create_called[i] & (1U << n)))
     375       16488 :                                 return;
     376             :         }
     377             : 
     378           2 :         sd_event_exit(sd_event_source_get_event(s), 0);
     379             : }
     380             : 
     381       49459 : static int inotify_handler(sd_event_source *s, const struct inotify_event *ev, void *userdata) {
     382       49459 :         struct inotify_context *c = userdata;
     383             :         const char *description;
     384             :         unsigned bit, n;
     385             : 
     386       49459 :         assert_se(sd_event_source_get_description(s, &description) >= 0);
     387       49459 :         assert_se(safe_atou(description, &n) >= 0);
     388             : 
     389       49459 :         assert_se(n <= 3);
     390       49459 :         bit = 1U << n;
     391             : 
     392       49459 :         if (ev->mask & IN_Q_OVERFLOW) {
     393           3 :                 log_info("inotify-handler <%s>: overflow", description);
     394           3 :                 c->create_overflow |= bit;
     395       49456 :         } else if (ev->mask & IN_CREATE) {
     396             :                 unsigned i;
     397             : 
     398       49455 :                 log_debug("inotify-handler <%s>: create on %s", description, ev->name);
     399             : 
     400       49455 :                 if (!streq(ev->name, "sub")) {
     401       49449 :                         assert_se(safe_atou(ev->name, &i) >= 0);
     402             : 
     403       49449 :                         assert_se(i < c->n_create_events);
     404       49449 :                         c->create_called[i] |= bit;
     405             :                 }
     406           1 :         } else if (ev->mask & IN_DELETE) {
     407           1 :                 log_info("inotify-handler <%s>: delete of %s", description, ev->name);
     408           1 :                 assert_se(streq(ev->name, "sub"));
     409             :         } else
     410           0 :                 assert_not_reached("unexpected inotify event");
     411             : 
     412       49459 :         maybe_exit(s, c);
     413       49459 :         return 1;
     414             : }
     415             : 
     416           3 : static int delete_self_handler(sd_event_source *s, const struct inotify_event *ev, void *userdata) {
     417           3 :         struct inotify_context *c = userdata;
     418             : 
     419           3 :         if (ev->mask & IN_Q_OVERFLOW) {
     420           1 :                 log_info("delete-self-handler: overflow");
     421           1 :                 c->delete_self_handler_called = true;
     422           2 :         } else if (ev->mask & IN_DELETE_SELF) {
     423           1 :                 log_info("delete-self-handler: delete-self");
     424           1 :                 c->delete_self_handler_called = true;
     425           1 :         } else if (ev->mask & IN_IGNORED) {
     426           1 :                 log_info("delete-self-handler: ignore");
     427             :         } else
     428           0 :                 assert_not_reached("unexpected inotify event (delete-self)");
     429             : 
     430           3 :         maybe_exit(s, c);
     431           3 :         return 1;
     432             : }
     433             : 
     434           2 : static void test_inotify(unsigned n_create_events) {
     435           2 :         _cleanup_(rm_rf_physical_and_freep) char *p = NULL;
     436           2 :         sd_event_source *a = NULL, *b = NULL, *c = NULL, *d = NULL;
     437           2 :         struct inotify_context context = {
     438             :                 .n_create_events = n_create_events,
     439             :         };
     440           2 :         sd_event *e = NULL;
     441             :         const char *q;
     442             :         unsigned i;
     443             : 
     444           2 :         assert_se(sd_event_default(&e) >= 0);
     445             : 
     446           2 :         assert_se(mkdtemp_malloc("/tmp/test-inotify-XXXXXX", &p) >= 0);
     447             : 
     448           2 :         assert_se(sd_event_add_inotify(e, &a, p, IN_CREATE|IN_ONLYDIR, inotify_handler, &context) >= 0);
     449           2 :         assert_se(sd_event_add_inotify(e, &b, p, IN_CREATE|IN_DELETE|IN_DONT_FOLLOW, inotify_handler, &context) >= 0);
     450           2 :         assert_se(sd_event_source_set_priority(b, SD_EVENT_PRIORITY_IDLE) >= 0);
     451           2 :         assert_se(sd_event_source_set_priority(b, SD_EVENT_PRIORITY_NORMAL) >= 0);
     452           2 :         assert_se(sd_event_add_inotify(e, &c, p, IN_CREATE|IN_DELETE|IN_EXCL_UNLINK, inotify_handler, &context) >= 0);
     453           2 :         assert_se(sd_event_source_set_priority(c, SD_EVENT_PRIORITY_IDLE) >= 0);
     454             : 
     455           2 :         assert_se(sd_event_source_set_description(a, "0") >= 0);
     456           2 :         assert_se(sd_event_source_set_description(b, "1") >= 0);
     457           2 :         assert_se(sd_event_source_set_description(c, "2") >= 0);
     458             : 
     459          10 :         q = strjoina(p, "/sub");
     460           2 :         assert_se(touch(q) >= 0);
     461           2 :         assert_se(sd_event_add_inotify(e, &d, q, IN_DELETE_SELF, delete_self_handler, &context) >= 0);
     462             : 
     463       33102 :         for (i = 0; i < n_create_events; i++) {
     464             :                 char buf[DECIMAL_STR_MAX(unsigned)+1];
     465       33100 :                 _cleanup_free_ char *z;
     466             : 
     467       33100 :                 xsprintf(buf, "%u", i);
     468       33100 :                 assert_se(z = path_join(p, buf));
     469             : 
     470       33100 :                 assert_se(touch(z) >= 0);
     471             :         }
     472             : 
     473           2 :         assert_se(unlink(q) >= 0);
     474             : 
     475           2 :         assert_se(sd_event_loop(e) >= 0);
     476             : 
     477           2 :         sd_event_source_unref(a);
     478           2 :         sd_event_source_unref(b);
     479           2 :         sd_event_source_unref(c);
     480           2 :         sd_event_source_unref(d);
     481             : 
     482           2 :         sd_event_unref(e);
     483           2 : }
     484             : 
     485           1 : int main(int argc, char *argv[]) {
     486           1 :         test_setup_logging(LOG_INFO);
     487             : 
     488           1 :         test_basic();
     489           1 :         test_sd_event_now();
     490           1 :         test_rtqueue();
     491             : 
     492           1 :         test_inotify(100); /* should work without overflow */
     493           1 :         test_inotify(33000); /* should trigger a q overflow */
     494             : 
     495           1 :         return 0;
     496             : }

Generated by: LCOV version 1.14