chiark / gitweb /
include <poll.h> instead of <sys/poll.h>
[elogind.git] / man / sd_journal_get_fd.xml
index 3fc9c5f5b5cde594cd21d81465a49bfe07592b5a..3a38f733ab781b62874b00f19cdc20be96824f9e 100644 (file)
@@ -1,6 +1,6 @@
 <?xml version='1.0'?> <!--*-nxml-*-->
 <!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN"
-        "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
+  "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
 
 <!--
   This file is part of systemd.
 
 <refentry id="sd_journal_get_fd">
 
-        <refentryinfo>
-                <title>sd_journal_get_fd</title>
-                <productname>systemd</productname>
-
-                <authorgroup>
-                        <author>
-                                <contrib>Developer</contrib>
-                                <firstname>Lennart</firstname>
-                                <surname>Poettering</surname>
-                                <email>lennart@poettering.net</email>
-                        </author>
-                </authorgroup>
-        </refentryinfo>
-
-        <refmeta>
-                <refentrytitle>sd_journal_get_fd</refentrytitle>
-                <manvolnum>3</manvolnum>
-        </refmeta>
-
-        <refnamediv>
-                <refname>sd_journal_get_fd</refname>
-                <refname>sd_journal_reliable_fd</refname>
-                <refname>sd_journal_process</refname>
-                <refname>sd_journal_wait</refname>
-                <refname>SD_JOURNAL_NOP</refname>
-                <refname>SD_JOURNAL_APPEND</refname>
-                <refname>SD_JOURNAL_INVALIDATE</refname>
-                <refpurpose>Journal change notification
-                interface</refpurpose>
-        </refnamediv>
-
-        <refsynopsisdiv>
-                <funcsynopsis>
-                        <funcsynopsisinfo>#include &lt;systemd/sd-journal.h&gt;</funcsynopsisinfo>
-
-                        <funcprototype>
-                                <funcdef>int <function>sd_journal_get_fd</function></funcdef>
-                                <paramdef>sd_journal* <parameter>j</parameter></paramdef>
-                        </funcprototype>
-
-                        <funcprototype>
-                                <funcdef>int <function>sd_journal_reliable_fd</function></funcdef>
-                                <paramdef>sd_journal* <parameter>j</parameter></paramdef>
-                        </funcprototype>
-
-                        <funcprototype>
-                                <funcdef>int <function>sd_journal_process</function></funcdef>
-                                <paramdef>sd_journal* <parameter>j</parameter></paramdef>
-                        </funcprototype>
-
-                        <funcprototype>
-                                <funcdef>int <function>sd_journal_wait</function></funcdef>
-                                <paramdef>sd_journal* <parameter>j</parameter></paramdef>
-                                <paramdef>uint64_t <parameter>timeout_usec</parameter></paramdef>
-                        </funcprototype>
-
-                </funcsynopsis>
-        </refsynopsisdiv>
-
-        <refsect1>
-                <title>Description</title>
-
-                <para><function>sd_journal_get_fd()</function> returns
-                a file descriptor that may be asynchronously polled in
-                an external event loop and is signaled readable as
-                soon as the journal changes, because new entries or
-                files were added, rotation took place, or files have
-                been deleted, and similar. The file descriptor is
-                suitable for usage in
-                <citerefentry><refentrytitle>poll</refentrytitle><manvolnum>2</manvolnum></citerefentry>
-                where it will yield POLLIN on changes. The call takes
-                one argument: the journal context object. Note that
-                not all file systems are capable of generating the
-                necessary events for wakeups from this file descriptor
-                to be enirely reliable. In particular network files
-                systems do not generate suitable file change events in
-                all cases. In such a case an application should not
-                rely alone on wake-ups from this file descriptor but
-                wake up and recheck the journal in regular time
-                intervals, for example every 2s. To detect
-                cases where this is necessary, use
-                <function>sd_journal_reliable_fd()</function>,
-                below.</para>
-
-                <para><function>sd_journal_reliable_fd()</function>
-                may be used to check whether the wakeup events from
-                the file descriptor returned by
-                <function>sd_journal_get_fd</function> are sufficient
-                to track changes to the journal. If this call returns
-                0, it is necessary to regularly recheck for journal
-                changes (suggestion: every 2s). If this call returns a
-                positive integer this is not necessary, and wakeups
-                from the file descriptor returned by
-                <function>sd_journal_get_fd()</function> are
-                sufficient as only source for wake-ups.</para>
-
-                <para>After each POLLIN wake-up
-                <function>sd_journal_process()</function> needs to be
-                called to process events and reset the readable state
-                of the file descriptor. This call will also indicate
-                what kind of change has been detected (see below; note
-                that spurious wake-ups are possible).</para>
-
-                <para>A synchronous alternative for using
-                <function>sd_journal_get_fd()</function>,
-                <function>sd_journal_reliable_fd()</function> and
-                <function>sd_journal_process()</function> is
-                <function>sd_journal_wait()</function>. It will
-                synchronously wait until the journal gets changed,
-                possibly using a 2s time-out if this is necessary (see
-                above). In either way the maximum time this call
-                sleeps may be controlled with the
-                <parameter>timeout_usec</parameter> parameter. Pass
-                <literal>(uint64_t) -1</literal> to wait
-                indefinitely. Internally this call simply combines
-                <function>sd_journal_get_fd()</function>,
-                <function>sd_journal_reliable_fd()</function>,
-                <function>poll()</function> and
-                <function>sd_journal_process()</function> into
-                one.</para>
-
-        </refsect1>
-
-        <refsect1>
-                <title>Return Value</title>
-
-                <para><function>sd_journal_get_fd()</function> returns a valid file descriptor on success or a negative errno-style error
-                code.</para>
-
-                <para><function>sd_journal_reliable_fd()</function>
-                returns a positive integer if the file descriptor
-                returned by <function>sd_journal_get_fd()</function>
-                is sufficient as sole wake-up source for journal
-                change events. Returns 0 if it is not sufficient and
-                the journal needs to be checked manually in regular
-                time intervals for changes. Returns a negative
-                errno-style error code on failure.</para>
-
-                <para><function>sd_journal_process()</function> and
-                <function>sd_journal_wait()</function> return one of
-                <literal>SD_JOURNAL_NOP</literal>,
-                <literal>SD_JOURNAL_APPEND</literal> or
-                <literal>SD_JOURNAL_INVALIDATE</literal> on success or
-                a negative errno-style error code. If
-                <literal>SD_JOURNAL_NOP</literal> is returned the
-                journal didn't change since the last invocation. If
-                <literal>SD_JOURNAL_APPEND</literal> is returned new
-                entries have been appended to the end of the
-                journal. If <literal>SD_JOURNAL_INVALIDATE</literal>
-                journal files were added or removed (possibly due to
-                rotation). In the latter event live-view UIs should
-                probably refresh their entire display while in the
-                case of <literal>SD_JOURNAL_APPEND</literal> it is
-                sufficient to simply continue reading at the previous
-                end of the journal.</para>
-        </refsect1>
-
-        <refsect1>
-                <title>Notes</title>
-
-                <para>The <function>sd_journal_get_fd()</function>,
-                <function>sd_journal_reliable_fd()</function>,
-                <function>sd_journal_process()</function> and
-                <function>sd_journal_wait()</function> interfaces are
-                available as shared library, which can be compiled and
-                linked to with the
-                <literal>libsystemd-journal</literal>
-                <citerefentry><refentrytitle>pkg-config</refentrytitle><manvolnum>1</manvolnum></citerefentry>
-                file.</para>
-        </refsect1>
-
-        <refsect1>
-                <title>Examples</title>
-
-                <para>Iterating through the journal, in a live view tracking all changes:</para>
-
-                <programlisting>#include &lt;stdio.h&gt;
+  <refentryinfo>
+    <title>sd_journal_get_fd</title>
+    <productname>systemd</productname>
+
+    <authorgroup>
+      <author>
+        <contrib>Developer</contrib>
+        <firstname>Lennart</firstname>
+        <surname>Poettering</surname>
+        <email>lennart@poettering.net</email>
+      </author>
+    </authorgroup>
+  </refentryinfo>
+
+  <refmeta>
+    <refentrytitle>sd_journal_get_fd</refentrytitle>
+    <manvolnum>3</manvolnum>
+  </refmeta>
+
+  <refnamediv>
+    <refname>sd_journal_get_fd</refname>
+    <refname>sd_journal_get_events</refname>
+    <refname>sd_journal_get_timeout</refname>
+    <refname>sd_journal_process</refname>
+    <refname>sd_journal_wait</refname>
+    <refname>sd_journal_reliable_fd</refname>
+    <refname>SD_JOURNAL_NOP</refname>
+    <refname>SD_JOURNAL_APPEND</refname>
+    <refname>SD_JOURNAL_INVALIDATE</refname>
+    <refpurpose>Journal change notification
+    interface</refpurpose>
+  </refnamediv>
+
+  <refsynopsisdiv>
+    <funcsynopsis>
+      <funcsynopsisinfo>#include &lt;systemd/sd-journal.h&gt;</funcsynopsisinfo>
+
+      <funcprototype>
+        <funcdef>int <function>sd_journal_get_fd</function></funcdef>
+        <paramdef>sd_journal *<parameter>j</parameter></paramdef>
+      </funcprototype>
+
+      <funcprototype>
+        <funcdef>int <function>sd_journal_get_events</function></funcdef>
+        <paramdef>sd_journal *<parameter>j</parameter></paramdef>
+      </funcprototype>
+
+      <funcprototype>
+        <funcdef>int <function>sd_journal_get_timeout</function></funcdef>
+        <paramdef>sd_journal *<parameter>j</parameter></paramdef>
+        <paramdef>uint64_t *<parameter>timeout_usec</parameter></paramdef>
+      </funcprototype>
+
+      <funcprototype>
+        <funcdef>int <function>sd_journal_process</function></funcdef>
+        <paramdef>sd_journal *<parameter>j</parameter></paramdef>
+      </funcprototype>
+
+      <funcprototype>
+        <funcdef>int <function>sd_journal_wait</function></funcdef>
+        <paramdef>sd_journal *<parameter>j</parameter></paramdef>
+        <paramdef>uint64_t <parameter>timeout_usec</parameter></paramdef>
+      </funcprototype>
+
+      <funcprototype>
+        <funcdef>int <function>sd_journal_reliable_fd</function></funcdef>
+        <paramdef>sd_journal *<parameter>j</parameter></paramdef>
+      </funcprototype>
+
+    </funcsynopsis>
+  </refsynopsisdiv>
+
+  <refsect1>
+    <title>Description</title>
+
+    <para><function>sd_journal_get_fd()</function> returns a file
+    descriptor that may be asynchronously polled in an external event
+    loop and is signaled as soon as the journal changes, because new
+    entries or files were added, rotation took place, or files have
+    been deleted, and similar. The file descriptor is suitable for
+    usage in
+    <citerefentry><refentrytitle>poll</refentrytitle><manvolnum>2</manvolnum></citerefentry>.
+    Use <function>sd_journal_get_events()</function> for an events
+    mask to watch for. The call takes one argument: the journal
+    context object. Note that not all file systems are capable of
+    generating the necessary events for wakeups from this file
+    descriptor for changes to be noticed immediately. In particular
+    network files systems do not generate suitable file change events
+    in all cases. Cases like this can be detected with
+    <function>sd_journal_reliable_fd()</function>, below.
+    <function>sd_journal_get_timeout()</function> will ensure in these
+    cases that wake-ups happen frequently enough for changes to be
+    noticed, although with a certain latency.</para>
+
+    <para><function>sd_journal_get_events()</function> will return the
+    <function>poll()</function> mask to wait for. This function will
+    return a combination of <constant>POLLIN</constant> and
+    <constant>POLLOUT</constant> and similar to fill into the
+    <literal>.events</literal> field of <varname>struct
+    pollfd</varname>.</para>
+
+    <para><function>sd_journal_get_timeout()</function> will return a
+    timeout value for usage in <function>poll()</function>. This
+    returns a value in microseconds since the epoch of
+    <constant>CLOCK_MONOTONIC</constant> for timing out
+    <function>poll()</function> in <varname>timeout_usec</varname>.
+    See
+    <citerefentry><refentrytitle>clock_gettime</refentrytitle><manvolnum>2</manvolnum></citerefentry>
+    for details about <constant>CLOCK_MONOTONIC</constant>. If there
+    is no timeout to wait for, this will fill in <constant>(uint64_t)
+    -1</constant> instead. Note that <function>poll()</function> takes
+    a relative timeout in milliseconds rather than an absolute timeout
+    in microseconds. To convert the absolute 'us' timeout into
+    relative 'ms', use code like the following:</para>
+
+    <programlisting>uint64_t t;
+int msec;
+sd_journal_get_timeout(m, &amp;t);
+if (t == (uint64_t) -1)
+  msec = -1;
+else {
+  struct timespec ts;
+  uint64_t n;
+  clock_getttime(CLOCK_MONOTONIC, &amp;ts);
+  n = (uint64_t) ts.tv_sec * 1000000 + ts.tv_nsec / 1000;
+  msec = t > n ? (int) ((t - n + 999) / 1000) : 0;
+}</programlisting>
+
+    <para>The code above does not do any error checking for brevity's
+    sake. The calculated <varname>msec</varname> integer can be passed
+    directly as <function>poll()</function>'s timeout
+    parameter.</para>
+
+    <para>After each <function>poll()</function> wake-up
+    <function>sd_journal_process()</function> needs to be called to
+    process events. This call will also indicate what kind of change
+    has been detected (see below; note that spurious wake-ups are
+    possible).</para>
+
+    <para>A synchronous alternative for using
+    <function>sd_journal_get_fd()</function>,
+    <function>sd_journal_get_events()</function>,
+    <function>sd_journal_get_timeout()</function> and
+    <function>sd_journal_process()</function> is
+    <function>sd_journal_wait()</function>. It will synchronously wait
+    until the journal gets changed. The maximum time this call sleeps
+    may be controlled with the <parameter>timeout_usec</parameter>
+    parameter. Pass <constant>(uint64_t) -1</constant> to wait
+    indefinitely. Internally this call simply combines
+    <function>sd_journal_get_fd()</function>,
+    <function>sd_journal_get_events()</function>,
+    <function>sd_journal_get_timeout()</function>,
+    <function>poll()</function> and
+    <function>sd_journal_process()</function> into one.</para>
+
+    <para><function>sd_journal_reliable_fd()</function> may be used to
+    check whether the wakeup events from the file descriptor returned
+    by <function>sd_journal_get_fd()</function> are known to be
+    immediately triggered. On certain file systems where file change
+    events from the OS are not available (such as NFS) changes need to
+    be polled for repeatedly, and hence are detected only with a
+    certain latency. This call will return a positive value if the
+    journal changes are detected immediately and zero when they need
+    to be polled for and hence might be noticed only with a certain
+    latency. Note that there's usually no need to invoke this function
+    directly as <function>sd_journal_get_timeout()</function> on these
+    file systems will ask for timeouts explicitly anyway.</para>
+  </refsect1>
+
+  <refsect1>
+    <title>Return Value</title>
+
+    <para><function>sd_journal_get_fd()</function> returns a valid
+    file descriptor on success or a negative errno-style error
+    code.</para>
+
+    <para><function>sd_journal_get_events()</function> returns a
+    combination of <constant>POLLIN</constant>,
+    <constant>POLLOUT</constant> and suchlike on success or a negative
+    errno-style error code.</para>
+
+    <para><function>sd_journal_reliable_fd()</function> returns a
+    positive integer if the file descriptor returned by
+    <function>sd_journal_get_fd()</function> will generate wake-ups
+    immediately for all journal changes. Returns 0 if there might be a
+    latency involved.</para>
+
+    <para><function>sd_journal_process()</function> and
+    <function>sd_journal_wait()</function> return one of
+    <constant>SD_JOURNAL_NOP</constant>,
+    <constant>SD_JOURNAL_APPEND</constant> or
+    <constant>SD_JOURNAL_INVALIDATE</constant> on success or a
+    negative errno-style error code. If
+    <constant>SD_JOURNAL_NOP</constant> is returned, the journal did
+    not change since the last invocation. If
+    <constant>SD_JOURNAL_APPEND</constant> is returned, new entries
+    have been appended to the end of the journal. If
+    <constant>SD_JOURNAL_INVALIDATE</constant>, journal files were
+    added or removed (possibly due to rotation). In the latter event,
+    live-view UIs should probably refresh their entire display, while
+    in the case of <constant>SD_JOURNAL_APPEND</constant>, it is
+    sufficient to simply continue reading at the previous end of the
+    journal.</para>
+  </refsect1>
+
+  <refsect1>
+    <title>Notes</title>
+
+    <para>The <function>sd_journal_get_fd()</function>,
+    <function>sd_journal_get_events()</function>,
+    <function>sd_journal_reliable_fd()</function>,
+    <function>sd_journal_process()</function> and
+    <function>sd_journal_wait()</function> interfaces are available as
+    a shared library, which can be compiled and linked to with the
+    <constant>libsystemd</constant> <citerefentry project='die-net'><refentrytitle>pkg-config</refentrytitle><manvolnum>1</manvolnum></citerefentry>
+    file.</para>
+  </refsect1>
+
+  <refsect1>
+    <title>Examples</title>
+
+    <para>Iterating through the journal, in a live view tracking all
+    changes:</para>
+
+    <programlisting>#include &lt;stdio.h&gt;
 #include &lt;string.h&gt;
 #include &lt;systemd/sd-journal.h&gt;
 
 int main(int argc, char *argv[]) {
-        int r;
-        sd_journal *j;
-        r = sd_journal_open(&amp;j, SD_JOURNAL_LOCAL_ONLY);
-        if (r &lt; 0) {
-                fprintf(stderr, "Failed to open journal: %s\n", strerror(-r));
-                return 1;
-        }
-        for (;;)  {
-                const void *d;
-                size_t l;
-                r = sd_journal_next(j);
-                if (r &lt; 0) {
-                        fprintf(stderr, "Failed to iterate to next entry: %s\n", strerror(-r));
-                        break;
-                }
-                if (r == 0) {
-                        /* Reached the end, let's wait for changes, and try again */
-                        r = sd_journal_wait(j, (uint64_t) -1);
-                        if (r &lt; 0) {
-                                fprintf(stderr, "Failed to wait for changes: %s\n", strerror(-r));
-                                break;
-                        }
-                        continue;
-                }
-                r = sd_journal_get_data(j, "MESSAGE", &amp;d, &amp;l);
-                if (r &lt; 0) {
-                        fprintf(stderr, "Failed to read message field: %s\n", strerror(-r));
-                        continue;
-                }
-                printf("%.*s\n", (int) l, (const char*) d);
-        }
-        sd_journal_close(j);
-        return 0;
+  int r;
+  sd_journal *j;
+  r = sd_journal_open(&amp;j, SD_JOURNAL_LOCAL_ONLY);
+  if (r &lt; 0) {
+    fprintf(stderr, "Failed to open journal: %s\n", strerror(-r));
+    return 1;
+  }
+  for (;;)  {
+    const void *d;
+    size_t l;
+    r = sd_journal_next(j);
+    if (r &lt; 0) {
+      fprintf(stderr, "Failed to iterate to next entry: %s\n", strerror(-r));
+      break;
+    }
+    if (r == 0) {
+      /* Reached the end, let's wait for changes, and try again */
+      r = sd_journal_wait(j, (uint64_t) -1);
+      if (r &lt; 0) {
+        fprintf(stderr, "Failed to wait for changes: %s\n", strerror(-r));
+        break;
+      }
+      continue;
+    }
+    r = sd_journal_get_data(j, "MESSAGE", &amp;d, &amp;l);
+    if (r &lt; 0) {
+      fprintf(stderr, "Failed to read message field: %s\n", strerror(-r));
+      continue;
+    }
+    printf("%.*s\n", (int) l, (const char*) d);
+  }
+  sd_journal_close(j);
+  return 0;
 }</programlisting>
 
-                <para>Waiting with <function>poll()</function> (this
-                example lacks all error checking for the sake of
-                simplicity):</para>
+    <para>Waiting with <function>poll()</function> (this
+    example lacks all error checking for the sake of
+    simplicity):</para>
 
-                <programlisting>#include &lt;sys/poll.h&gt;
+    <programlisting>#include &lt;poll.h&gt;
 #include &lt;systemd/sd-journal.h&gt;
 
 int wait_for_changes(sd_journal *j) {
-        struct pollfd pollfd;
-        pollfd.fd = sd_journal_get_fd(j);
-        pollfd.events = POLLIN;
-        poll(&amp;pollfd, 1, sd_journal_reliable_fd(j) &gt; 0 ? -1 : 2000);
-        return sd_journal_process(j);
-}
-                </programlisting>
-        </refsect1>
-
-
-        <refsect1>
-                <title>See Also</title>
-
-                <para>
-                        <citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
-                        <citerefentry><refentrytitle>sd-journal</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
-                        <citerefentry><refentrytitle>sd_journal_open</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
-                        <citerefentry><refentrytitle>sd_journal_next</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
-                        <citerefentry><refentrytitle>poll</refentrytitle><manvolnum>2</manvolnum></citerefentry>
-                </para>
-        </refsect1>
+  struct pollfd pollfd;
+  int msec;
+
+  sd_journal_get_timeout(m, &amp;t);
+  if (t == (uint64_t) -1)
+    msec = -1;
+  else {
+    struct timespec ts;
+    uint64_t n;
+    clock_getttime(CLOCK_MONOTONIC, &amp;ts);
+    n = (uint64_t) ts.tv_sec * 1000000 + ts.tv_nsec / 1000;
+    msec = t > n ? (int) ((t - n + 999) / 1000) : 0;
+  }
+
+  pollfd.fd = sd_journal_get_fd(j);
+  pollfd.events = sd_journal_get_events(j);
+  poll(&amp;pollfd, 1, msec);
+  return sd_journal_process(j);
+}</programlisting>
+  </refsect1>
+
+  <refsect1>
+    <title>See Also</title>
+
+    <para>
+      <citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
+      <citerefentry><refentrytitle>sd-journal</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
+      <citerefentry><refentrytitle>sd_journal_open</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
+      <citerefentry><refentrytitle>sd_journal_next</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
+      <citerefentry><refentrytitle>poll</refentrytitle><manvolnum>2</manvolnum></citerefentry>,
+      <citerefentry><refentrytitle>clock_gettime</refentrytitle><manvolnum>2</manvolnum></citerefentry>
+    </para>
+  </refsect1>
 
 </refentry>