mirror of
https://github.com/systemd/systemd-stable.git
synced 2025-03-06 12:58:22 +03:00
sd-event: add sd_event_add_inotify_fd() call
sd_event_add_inotify_fd() is like sd_event_add_inotify(), but takes an fd to an inode instead of a path, and is hence a ton nicer.
This commit is contained in:
parent
53baf2efa4
commit
e67d738a87
@ -518,7 +518,9 @@ manpages = [
|
||||
''],
|
||||
['sd_event_add_inotify',
|
||||
'3',
|
||||
['sd_event_inotify_handler_t', 'sd_event_source_get_inotify_mask'],
|
||||
['sd_event_add_inotify_fd',
|
||||
'sd_event_inotify_handler_t',
|
||||
'sd_event_source_get_inotify_mask'],
|
||||
''],
|
||||
['sd_event_add_io',
|
||||
'3',
|
||||
|
@ -17,6 +17,7 @@
|
||||
|
||||
<refnamediv>
|
||||
<refname>sd_event_add_inotify</refname>
|
||||
<refname>sd_event_add_inotify_fd</refname>
|
||||
<refname>sd_event_source_get_inotify_mask</refname>
|
||||
<refname>sd_event_inotify_handler_t</refname>
|
||||
|
||||
@ -46,6 +47,16 @@
|
||||
<paramdef>void *<parameter>userdata</parameter></paramdef>
|
||||
</funcprototype>
|
||||
|
||||
<funcprototype>
|
||||
<funcdef>int <function>sd_event_add_inotify_fd</function></funcdef>
|
||||
<paramdef>sd_event *<parameter>event</parameter></paramdef>
|
||||
<paramdef>sd_event_source **<parameter>source</parameter></paramdef>
|
||||
<paramdef>int <parameter>fd</parameter></paramdef>
|
||||
<paramdef>uint32_t <parameter>mask</parameter></paramdef>
|
||||
<paramdef>sd_event_inotify_handler_t <parameter>handler</parameter></paramdef>
|
||||
<paramdef>void *<parameter>userdata</parameter></paramdef>
|
||||
</funcprototype>
|
||||
|
||||
<funcprototype>
|
||||
<funcdef>int <function>sd_event_source_get_inotify_mask</function></funcdef>
|
||||
<paramdef>sd_event_source *<parameter>source</parameter></paramdef>
|
||||
@ -71,6 +82,11 @@
|
||||
<citerefentry project='man-pages'><refentrytitle>inotify</refentrytitle><manvolnum>7</manvolnum></citerefentry> for
|
||||
further information.</para>
|
||||
|
||||
<para><function>sd_event_add_inotify_fd()</function> is identical to
|
||||
<function>sd_event_add_inotify()</function>, except that it takes a file descriptor to an inode (possibly
|
||||
an <constant>O_PATH</constant> one, but any other will do too) instead of a path in the file
|
||||
system.</para>
|
||||
|
||||
<para>If multiple event sources are installed for the same inode the backing inotify watch descriptor is
|
||||
automatically shared. The mask parameter may contain any flag defined by the inotify API, with the exception of
|
||||
<constant>IN_MASK_ADD</constant>.</para>
|
||||
@ -157,6 +173,19 @@
|
||||
<listitem><para>The passed event source is not an inotify process event source.</para></listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term><constant>-EBADF</constant></term>
|
||||
|
||||
<listitem><para>The passed file descriptor is not valid.</para></listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term><constant>-ENOSYS</constant></term>
|
||||
|
||||
<listitem><para><function>sd_event_add_inotify_fd()</function> was called without
|
||||
<filename>/proc/</filename> mounted.</para></listitem>
|
||||
</varlistentry>
|
||||
|
||||
</variablelist>
|
||||
</refsect2>
|
||||
</refsect1>
|
||||
|
@ -766,4 +766,5 @@ global:
|
||||
LIBSYSTEMD_250 {
|
||||
global:
|
||||
sd_device_get_diskseq;
|
||||
sd_event_add_inotify_fd;
|
||||
} LIBSYSTEMD_249;
|
||||
|
@ -1989,24 +1989,25 @@ static int inotify_exit_callback(sd_event_source *s, const struct inotify_event
|
||||
return sd_event_exit(sd_event_source_get_event(s), PTR_TO_INT(userdata));
|
||||
}
|
||||
|
||||
_public_ int sd_event_add_inotify(
|
||||
static int event_add_inotify_fd_internal(
|
||||
sd_event *e,
|
||||
sd_event_source **ret,
|
||||
const char *path,
|
||||
int fd,
|
||||
bool donate,
|
||||
uint32_t mask,
|
||||
sd_event_inotify_handler_t callback,
|
||||
void *userdata) {
|
||||
|
||||
_cleanup_close_ int donated_fd = donate ? fd : -1;
|
||||
_cleanup_(source_freep) sd_event_source *s = NULL;
|
||||
struct inotify_data *inotify_data = NULL;
|
||||
struct inode_data *inode_data = NULL;
|
||||
_cleanup_close_ int fd = -1;
|
||||
_cleanup_(source_freep) sd_event_source *s = NULL;
|
||||
struct stat st;
|
||||
int r;
|
||||
|
||||
assert_return(e, -EINVAL);
|
||||
assert_return(e = event_resolve(e), -ENOPKG);
|
||||
assert_return(path, -EINVAL);
|
||||
assert_return(fd >= 0, -EBADF);
|
||||
assert_return(e->state != SD_EVENT_FINISHED, -ESTALE);
|
||||
assert_return(!event_pid_changed(e), -ECHILD);
|
||||
|
||||
@ -2019,12 +2020,6 @@ _public_ int sd_event_add_inotify(
|
||||
if (mask & IN_MASK_ADD)
|
||||
return -EINVAL;
|
||||
|
||||
fd = open(path, O_PATH|O_CLOEXEC|
|
||||
(mask & IN_ONLYDIR ? O_DIRECTORY : 0)|
|
||||
(mask & IN_DONT_FOLLOW ? O_NOFOLLOW : 0));
|
||||
if (fd < 0)
|
||||
return -errno;
|
||||
|
||||
if (fstat(fd, &st) < 0)
|
||||
return -errno;
|
||||
|
||||
@ -2044,14 +2039,24 @@ _public_ int sd_event_add_inotify(
|
||||
|
||||
r = event_make_inode_data(e, inotify_data, st.st_dev, st.st_ino, &inode_data);
|
||||
if (r < 0) {
|
||||
event_free_inotify_data(e, inotify_data);
|
||||
event_gc_inotify_data(e, inotify_data);
|
||||
return r;
|
||||
}
|
||||
|
||||
/* Keep the O_PATH fd around until the first iteration of the loop, so that we can still change the priority of
|
||||
* the event source, until then, for which we need the original inode. */
|
||||
if (inode_data->fd < 0) {
|
||||
inode_data->fd = TAKE_FD(fd);
|
||||
if (donated_fd >= 0)
|
||||
inode_data->fd = TAKE_FD(donated_fd);
|
||||
else {
|
||||
inode_data->fd = fcntl(fd, F_DUPFD_CLOEXEC, 3);
|
||||
if (inode_data->fd < 0) {
|
||||
r = -errno;
|
||||
event_gc_inode_data(e, inode_data);
|
||||
return r;
|
||||
}
|
||||
}
|
||||
|
||||
LIST_PREPEND(to_close, e->inode_data_to_close, inode_data);
|
||||
}
|
||||
|
||||
@ -2064,8 +2069,6 @@ _public_ int sd_event_add_inotify(
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
(void) sd_event_source_set_description(s, path);
|
||||
|
||||
if (ret)
|
||||
*ret = s;
|
||||
TAKE_PTR(s);
|
||||
@ -2073,6 +2076,48 @@ _public_ int sd_event_add_inotify(
|
||||
return 0;
|
||||
}
|
||||
|
||||
_public_ int sd_event_add_inotify_fd(
|
||||
sd_event *e,
|
||||
sd_event_source **ret,
|
||||
int fd,
|
||||
uint32_t mask,
|
||||
sd_event_inotify_handler_t callback,
|
||||
void *userdata) {
|
||||
|
||||
return event_add_inotify_fd_internal(e, ret, fd, /* donate= */ false, mask, callback, userdata);
|
||||
}
|
||||
|
||||
_public_ int sd_event_add_inotify(
|
||||
sd_event *e,
|
||||
sd_event_source **ret,
|
||||
const char *path,
|
||||
uint32_t mask,
|
||||
sd_event_inotify_handler_t callback,
|
||||
void *userdata) {
|
||||
|
||||
sd_event_source *s;
|
||||
int fd, r;
|
||||
|
||||
assert_return(path, -EINVAL);
|
||||
|
||||
fd = open(path, O_PATH|O_CLOEXEC|
|
||||
(mask & IN_ONLYDIR ? O_DIRECTORY : 0)|
|
||||
(mask & IN_DONT_FOLLOW ? O_NOFOLLOW : 0));
|
||||
if (fd < 0)
|
||||
return -errno;
|
||||
|
||||
r = event_add_inotify_fd_internal(e, &s, fd, /* donate= */ true, mask, callback, userdata);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
(void) sd_event_source_set_description(s, path);
|
||||
|
||||
if (ret)
|
||||
*ret = s;
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
static sd_event_source* event_source_free(sd_event_source *s) {
|
||||
if (!s)
|
||||
return NULL;
|
||||
|
@ -93,6 +93,7 @@ int sd_event_add_signal(sd_event *e, sd_event_source **s, int sig, sd_event_sign
|
||||
int sd_event_add_child(sd_event *e, sd_event_source **s, pid_t pid, int options, sd_event_child_handler_t callback, void *userdata);
|
||||
int sd_event_add_child_pidfd(sd_event *e, sd_event_source **s, int pidfd, int options, sd_event_child_handler_t callback, void *userdata);
|
||||
int sd_event_add_inotify(sd_event *e, sd_event_source **s, const char *path, uint32_t mask, sd_event_inotify_handler_t callback, void *userdata);
|
||||
int sd_event_add_inotify_fd(sd_event *e, sd_event_source **s, int fd, uint32_t mask, sd_event_inotify_handler_t callback, void *userdata);
|
||||
int sd_event_add_defer(sd_event *e, sd_event_source **s, sd_event_handler_t callback, void *userdata);
|
||||
int sd_event_add_post(sd_event *e, sd_event_source **s, sd_event_handler_t callback, void *userdata);
|
||||
int sd_event_add_exit(sd_event *e, sd_event_source **s, sd_event_handler_t callback, void *userdata);
|
||||
|
Loading…
x
Reference in New Issue
Block a user