chiark / gitweb /
man: add sd_event_add_child(3)
[elogind.git] / man / sd_journal_get_fd.xml
index e3b5eaa13d13a11f37121dec1aee4a2fccb25abf..3aa79ce100874a130913ec864d8ad5cce666abd6 100644 (file)
 
         <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>
 
                         <funcprototype>
                                 <funcdef>int <function>sd_journal_get_fd</function></funcdef>
-                                <paramdef>sd_journal* <parameter>j</parameter></paramdef>
+                                <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>
+                                <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>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>
 
 
                 <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, for example because new
-                entries were added. The file descriptor is suitable
+                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>
-                where it will yield POLLIN on all changes. The call
-                takes one argument: the journal context object.</para>
+                <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>
 
-                <para>After each POLLIN wake-up
+                <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 and reset the readable state
-                of the file descriptor. This call will also indicate
+                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> and
+                <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 up
-                to a certain time-out as specified in its second
-                argument. Pass <literal>(uint64_t) -1</literal> to
+                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_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
-                <literal>SD_JOURNAL_NOP</literal>,
-                <literal>SD_JOURNAL_APPEND</literal> or
-                <literal>SD_JOURNAL_INVALIDATE</literal> on success or
+                <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
-                <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
+                <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 <literal>SD_JOURNAL_INVALIDATE</literal>
+                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 <literal>SD_JOURNAL_APPEND</literal> it is
+                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>
                 <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 shared library, which can be compiled and
+                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>
+                <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;
+}</programlisting>
+
+                <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;
+#include &lt;systemd/sd-journal.h&gt;
+
+int wait_for_changes(sd_journal *j) {
+        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>
 
                         <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>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>