mirror of
https://github.com/morgan9e/systemd
synced 2026-04-15 08:56:15 +09:00
Merge pull request #28767 from poettering/epoll-eperm-journalctl
journalctl epoll/EPERM follow-up
This commit is contained in:
@@ -100,22 +100,21 @@
|
||||
<refsect1>
|
||||
<title>Description</title>
|
||||
|
||||
<para><function>sd_event_add_io()</function> adds a new I/O event
|
||||
source to an event loop. The event loop object is specified in the
|
||||
<parameter>event</parameter> parameter, the event source object is
|
||||
returned in the <parameter>source</parameter> parameter. The
|
||||
<parameter>fd</parameter> parameter takes the UNIX file descriptor
|
||||
to watch, which may refer to a socket, a FIFO, a message queue, a
|
||||
serial connection, a character device, or any other file descriptor
|
||||
compatible with Linux
|
||||
<citerefentry project='man-pages'><refentrytitle>epoll</refentrytitle><manvolnum>7</manvolnum></citerefentry>. The
|
||||
<parameter>events</parameter> parameter takes a bit mask of events
|
||||
to watch for, a combination of the following event flags:
|
||||
<constant>EPOLLIN</constant>, <constant>EPOLLOUT</constant>,
|
||||
<constant>EPOLLRDHUP</constant>, <constant>EPOLLPRI</constant>,
|
||||
and <constant>EPOLLET</constant>, see
|
||||
<citerefentry project='man-pages'><refentrytitle>epoll_ctl</refentrytitle><manvolnum>2</manvolnum></citerefentry>
|
||||
for details.</para>
|
||||
<para><function>sd_event_add_io()</function> adds a new I/O event source to an event loop. The event loop
|
||||
object is specified in the <parameter>event</parameter> parameter, the event source object is returned in
|
||||
the <parameter>source</parameter> parameter. The <parameter>fd</parameter> parameter takes the UNIX file
|
||||
descriptor to watch, which may refer to a socket, a FIFO, a message queue, a serial connection, a
|
||||
character device, or any other file descriptor compatible with Linux <citerefentry
|
||||
project='man-pages'><refentrytitle>epoll</refentrytitle><manvolnum>7</manvolnum></citerefentry>. The
|
||||
<parameter>events</parameter> parameter takes a bit mask of events to watch for, a combination of the
|
||||
following event flags: <constant>EPOLLIN</constant>, <constant>EPOLLOUT</constant>,
|
||||
<constant>EPOLLRDHUP</constant>, <constant>EPOLLPRI</constant>, and <constant>EPOLLET</constant>, see
|
||||
<citerefentry
|
||||
project='man-pages'><refentrytitle>epoll_ctl</refentrytitle><manvolnum>2</manvolnum></citerefentry> for
|
||||
details. Note that not all file descriptors are compatible with epoll, for example regular file or
|
||||
directories are not. If this function is called with a file descriptor that does not support epoll,
|
||||
<constant>-EPERM</constant> is returned (also see below). In most cases such file descriptors may be
|
||||
treated as always-readable or always-writable, so that IO event watching is unnecessary.</para>
|
||||
|
||||
<para>The <parameter>handler</parameter> is a function to call when the event source is triggered or
|
||||
<constant>NULL</constant>. The <parameter>userdata</parameter> pointer will be passed to the handler
|
||||
@@ -278,6 +277,16 @@
|
||||
|
||||
<listitem><para>The passed event source is not an I/O event source.</para></listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term><constant>-EPERM</constant></term>
|
||||
|
||||
<listitem><para>The passed file descriptor does not support the <citerefentry
|
||||
project='man-pages'><refentrytitle>epoll</refentrytitle><manvolnum>7</manvolnum></citerefentry>
|
||||
API, for example because it is a regular file or directory. See <citerefentry
|
||||
project='man-pages'><refentrytitle>epoll_ctl</refentrytitle><manvolnum>2</manvolnum></citerefentry>
|
||||
for details.</para></listitem>
|
||||
</varlistentry>
|
||||
</variablelist>
|
||||
</refsect2>
|
||||
</refsect1>
|
||||
|
||||
@@ -2310,7 +2310,6 @@ static int on_signal(sd_event_source *s, const struct signalfd_siginfo *si, void
|
||||
|
||||
static int setup_event(Context *c, int fd, sd_event **ret) {
|
||||
_cleanup_(sd_event_unrefp) sd_event *e = NULL;
|
||||
struct stat st;
|
||||
int r;
|
||||
|
||||
assert(arg_follow);
|
||||
@@ -2329,15 +2328,15 @@ static int setup_event(Context *c, int fd, sd_event **ret) {
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to add io event source for journal: %m");
|
||||
|
||||
if (fstat(STDOUT_FILENO, &st) < 0)
|
||||
return log_error_errno(errno, "Failed to stat stdout: %m");
|
||||
|
||||
if (IN_SET(st.st_mode & S_IFMT, S_IFCHR, S_IFIFO, S_IFSOCK)) {
|
||||
/* Also keeps an eye on STDOUT, and exits as soon as we see a POLLHUP on that, i.e. when it is closed. */
|
||||
r = sd_event_add_io(e, NULL, STDOUT_FILENO, EPOLLHUP|EPOLLERR, NULL, INT_TO_PTR(-ECANCELED));
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to add io event source for stdout: %m");
|
||||
}
|
||||
/* Also keeps an eye on STDOUT, and exits as soon as we see a POLLHUP on that, i.e. when it is closed. */
|
||||
r = sd_event_add_io(e, NULL, STDOUT_FILENO, EPOLLHUP|EPOLLERR, NULL, INT_TO_PTR(-ECANCELED));
|
||||
if (r == -EPERM)
|
||||
/* Installing an epoll watch on a regular file doesn't work and fails with EPERM. Which is
|
||||
* totally OK, handle it gracefully. epoll_ctl() documents EPERM as the error returned when
|
||||
* the specified fd doesn't support epoll, hence it's safe to check for that. */
|
||||
log_debug_errno(r, "Unable to install EPOLLHUP watch on stderr, not watching for hangups.");
|
||||
else if (r < 0)
|
||||
return log_error_errno(r, "Failed to add io event source for stdout: %m");
|
||||
|
||||
if (arg_lines != 0 || arg_since_set) {
|
||||
r = sd_event_add_defer(e, NULL, on_first_event, c);
|
||||
|
||||
Reference in New Issue
Block a user