]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
sd-event: introduce sd_event_source_get_inotify_path() 32349/head
authorYu Watanabe <watanabe.yu+github@gmail.com>
Fri, 19 Apr 2024 04:55:35 +0000 (13:55 +0900)
committerYu Watanabe <watanabe.yu+github@gmail.com>
Fri, 19 Apr 2024 05:23:11 +0000 (14:23 +0900)
This may be useful when there are multiple inotify event sources exist.
Without this, users need to manage the event sources and paths.

man/sd_event_add_inotify.xml
src/libsystemd/libsystemd.sym
src/libsystemd/sd-event/sd-event.c
src/libsystemd/sd-event/test-event.c
src/systemd/sd-event.h

index 2e2f5f25e48225c071ea9b51f414c9c87e02125a..636f37b0012fc2004a362bb6e6e1fad81b17c1aa 100644 (file)
@@ -19,6 +19,7 @@
     <refname>sd_event_add_inotify</refname>
     <refname>sd_event_add_inotify_fd</refname>
     <refname>sd_event_source_get_inotify_mask</refname>
+    <refname>sd_event_source_get_inotify_path</refname>
     <refname>sd_event_inotify_handler_t</refname>
 
     <refpurpose>Add an "inotify" file system inode event source to an event loop</refpurpose>
         <paramdef>uint32_t *<parameter>ret</parameter></paramdef>
       </funcprototype>
 
+      <funcprototype>
+        <funcdef>int <function>sd_event_source_get_inotify_path</function></funcdef>
+        <paramdef>sd_event_source *<parameter>source</parameter></paramdef>
+        <paramdef>char **<parameter>ret</parameter></paramdef>
+      </funcprototype>
+
     </funcsynopsis>
   </refsynopsisdiv>
 
     event source created previously with <function>sd_event_add_inotify()</function>. It takes the event source object
     as the <parameter>source</parameter> parameter and a pointer to a <type>uint32_t</type> variable to return the mask
     in.</para>
+
+    <para><function>sd_event_source_get_inotify_path()</function> retrieves the target path of the configured
+    inotify watch of an event source created previously with <function>sd_event_add_inotify()</function>. It
+    takes the event source object as the <parameter>source</parameter> parameter and a pointer to a
+    <type>char **</type> variable to return the path in. The caller needs to free the returned path.</para>
   </refsect1>
 
   <refsect1>
         <varlistentry>
           <term><constant>-ESTALE</constant></term>
 
-          <listitem><para>The event loop is already terminated.</para></listitem>
+          <listitem>
+            <para>Returned by <function>sd_event_source_add_inotify()</function> or
+            <function>sd_event_source_add_inotify_fd()</function> when the event loop is already terminated.
+            Returned by <function>sd_event_source_get_inotify_path()</function> when no active inode data is
+            assigned to the event source, e.g. when the event source is disabled.</para>
+          </listitem>
 
         </varlistentry>
 
     <function>sd_event_add_inotify()</function>, and
     <function>sd_event_source_get_inotify_mask()</function> were added in version 239.</para>
     <para><function>sd_event_add_inotify_fd()</function> was added in version 250.</para>
+    <para><function>sd_event_source_get_inotify_path()</function> was added in version 256.</para>
   </refsect1>
 
   <refsect1>
index d23da4c1515c84cd4e54fea36a117c3478d1f9ad..89de4b37cab9050c4eabc028838dab8d0e29da11 100644 (file)
@@ -840,4 +840,5 @@ global:
         sd_bus_creds_get_pidfd_dup;
         sd_bus_creds_new_from_pidfd;
         sd_journal_stream_fd_with_namespace;
+        sd_event_source_get_inotify_path;
 } LIBSYSTEMD_255;
index c4de4721064b57e8c130e56e6d00076a36955668..ea35293ec464952bf188eb88cf4d89dee1ac4e68 100644 (file)
@@ -3292,6 +3292,18 @@ _public_ int sd_event_source_get_inotify_mask(sd_event_source *s, uint32_t *ret)
         return 0;
 }
 
+_public_ int sd_event_source_get_inotify_path(sd_event_source *s, char **ret) {
+        assert_return(s, -EINVAL);
+        assert_return(ret, -EINVAL);
+        assert_return(s->type == SOURCE_INOTIFY, -EDOM);
+        assert_return(!event_origin_changed(s->event), -ECHILD);
+
+        if (!s->inotify.inode_data || s->inotify.inode_data->fd < 0)
+                return -ESTALE;
+
+        return fd_get_path(s->inotify.inode_data->fd, ret);
+}
+
 _public_ int sd_event_source_set_prepare(sd_event_source *s, sd_event_handler_t callback) {
         int r;
 
index e02de097baa44180489def6a1e23e90ce5349b6c..87f704ecb190fb9e150a4f1c79abca71c6890f2b 100644 (file)
@@ -475,6 +475,7 @@ static int delete_self_handler(sd_event_source *s, const struct inotify_event *e
 
 static void test_inotify_one(unsigned n_create_events) {
         _cleanup_(rm_rf_physical_and_freep) char *p = NULL;
+        _cleanup_free_ char *pp = NULL;
         sd_event_source *a = NULL, *b = NULL, *c = NULL, *d = NULL;
         struct inotify_context context = {
                 .n_create_events = n_create_events,
@@ -500,6 +501,16 @@ static void test_inotify_one(unsigned n_create_events) {
         assert_se(sd_event_source_set_description(b, "1") >= 0);
         assert_se(sd_event_source_set_description(c, "2") >= 0);
 
+        assert_se(sd_event_source_get_inotify_path(a, &pp) >= 0);
+        assert_se(path_equal_or_inode_same(pp, p, 0));
+        pp = mfree(pp);
+        assert_se(sd_event_source_get_inotify_path(b, &pp) >= 0);
+        assert_se(path_equal_or_inode_same(pp, p, 0));
+        pp = mfree(pp);
+        assert_se(sd_event_source_get_inotify_path(b, &pp) >= 0);
+        assert_se(path_equal_or_inode_same(pp, p, 0));
+        pp = mfree(pp);
+
         q = strjoina(p, "/sub");
         assert_se(touch(q) >= 0);
         assert_se(sd_event_add_inotify(e, &d, q, IN_DELETE_SELF, delete_self_handler, &context) >= 0);
index 49d69759674c7780be7b3f62b092935bcecb2afa..e306c891cb13f50cf307a636a831a63ef1872f04 100644 (file)
@@ -161,6 +161,7 @@ int sd_event_source_send_child_signal(sd_event_source *s, int sig, const siginfo
 int sd_event_source_send_child_signal(sd_event_source *s, int sig, const void *si, unsigned flags);
 #endif
 int sd_event_source_get_inotify_mask(sd_event_source *s, uint32_t *ret);
+int sd_event_source_get_inotify_path(sd_event_source *s, char **ret);
 int sd_event_source_set_memory_pressure_type(sd_event_source *e, const char *ty);
 int sd_event_source_set_memory_pressure_period(sd_event_source *s, uint64_t threshold_usec, uint64_t window_usec);
 int sd_event_source_set_destroy_callback(sd_event_source *s, sd_event_destroy_t callback);