]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
test: add test case for self-destroy inotify handler 21270/head
authorLennart Poettering <lennart@poettering.net>
Mon, 8 Nov 2021 23:15:43 +0000 (00:15 +0100)
committerLennart Poettering <lennart@poettering.net>
Tue, 9 Nov 2021 12:13:25 +0000 (13:13 +0100)
src/libsystemd/sd-event/test-event.c

index 406d10d92b43bf0d2db94d7657a3453c6b05e6db..b637639f261a94ee67c16a26f0a5567cc689bb5b 100644 (file)
@@ -713,6 +713,40 @@ static void test_simple_timeout(void) {
         assert_se(t >= usec_add(f, some_time));
 }
 
+static int inotify_self_destroy_handler(sd_event_source *s, const struct inotify_event *ev, void *userdata) {
+        sd_event_source **p = userdata;
+
+        assert_se(ev);
+        assert_se(p);
+        assert_se(*p == s);
+
+        assert_se(FLAGS_SET(ev->mask, IN_ATTRIB));
+
+        assert_se(sd_event_exit(sd_event_source_get_event(s), 0) >= 0);
+
+        *p = sd_event_source_unref(*p); /* here's what we actually intend to test: we destroy the event
+                                         * source from inside the event source handler */
+        return 1;
+}
+
+static void test_inotify_self_destroy(void) {
+        _cleanup_(sd_event_source_unrefp) sd_event_source *s = NULL;
+        _cleanup_(sd_event_unrefp) sd_event *e = NULL;
+        char path[] = "/tmp/inotifyXXXXXX";
+        _cleanup_close_ int fd = -1;
+
+        /* Tests that destroying an inotify event source from its own handler is safe */
+
+        assert_se(sd_event_default(&e) >= 0);
+
+        fd = mkostemp_safe(path);
+        assert_se(fd >= 0);
+        assert_se(sd_event_add_inotify_fd(e, &s, fd, IN_ATTRIB, inotify_self_destroy_handler, &s) >= 0);
+        fd = safe_close(fd);
+        assert_se(unlink(path) >= 0); /* This will trigger IN_ATTRIB because link count goes to zero */
+        assert_se(sd_event_loop(e) >= 0);
+}
+
 int main(int argc, char *argv[]) {
         test_setup_logging(LOG_DEBUG);
 
@@ -731,5 +765,7 @@ int main(int argc, char *argv[]) {
 
         test_ratelimit();
 
+        test_inotify_self_destroy();
+
         return 0;
 }