mirror of
https://git.proxmox.com/git/systemd
synced 2025-07-23 20:48:09 +00:00
219 lines
16 KiB
HTML
219 lines
16 KiB
HTML
<html><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8"><title>sd_journal_get_fd</title><meta name="generator" content="DocBook XSL Stylesheets V1.78.1"></head><body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF"><style>
|
||
a.headerlink {
|
||
color: #c60f0f;
|
||
font-size: 0.8em;
|
||
padding: 0 4px 0 4px;
|
||
text-decoration: none;
|
||
visibility: hidden;
|
||
}
|
||
|
||
a.headerlink:hover {
|
||
background-color: #c60f0f;
|
||
color: white;
|
||
}
|
||
|
||
h1:hover > a.headerlink, h2:hover > a.headerlink, h3:hover > a.headerlink, dt:hover > a.headerlink {
|
||
visibility: visible;
|
||
}
|
||
</style><a href="index.html">Index </a>·
|
||
<a href="systemd.directives.html">Directives </a>·
|
||
<a href="../python-systemd/index.html">Python </a>·
|
||
<a href="../libudev/index.html">libudev </a>·
|
||
<a href="../libudev/index.html">gudev </a><span style="float:right">systemd 218</span><hr><div class="refentry"><a name="sd_journal_get_fd"></a><div class="titlepage"></div><div class="refnamediv"><h2>Name</h2><p>sd_journal_get_fd, sd_journal_get_events, sd_journal_get_timeout, sd_journal_process, sd_journal_wait, sd_journal_reliable_fd, SD_JOURNAL_NOP, SD_JOURNAL_APPEND, SD_JOURNAL_INVALIDATE — Journal change notification
|
||
interface</p></div><div class="refsynopsisdiv"><h2>Synopsis</h2><div class="funcsynopsis"><pre class="funcsynopsisinfo">#include <systemd/sd-journal.h></pre><table border="0" class="funcprototype-table" summary="Function synopsis" style="cellspacing: 0; cellpadding: 0;"><tr><td><code class="funcdef">int <b class="fsfunc">sd_journal_get_fd</b>(</code></td><td>sd_journal *<var class="pdparam">j</var><code>)</code>;</td></tr></table><div class="funcprototype-spacer"> </div><table border="0" class="funcprototype-table" summary="Function synopsis" style="cellspacing: 0; cellpadding: 0;"><tr><td><code class="funcdef">int <b class="fsfunc">sd_journal_get_events</b>(</code></td><td>sd_journal *<var class="pdparam">j</var><code>)</code>;</td></tr></table><div class="funcprototype-spacer"> </div><table border="0" class="funcprototype-table" summary="Function synopsis" style="cellspacing: 0; cellpadding: 0;"><tr><td><code class="funcdef">int <b class="fsfunc">sd_journal_get_timeout</b>(</code></td><td>sd_journal *<var class="pdparam">j</var>, </td></tr><tr><td> </td><td>uint64_t *<var class="pdparam">timeout_usec</var><code>)</code>;</td></tr></table><div class="funcprototype-spacer"> </div><table border="0" class="funcprototype-table" summary="Function synopsis" style="cellspacing: 0; cellpadding: 0;"><tr><td><code class="funcdef">int <b class="fsfunc">sd_journal_process</b>(</code></td><td>sd_journal *<var class="pdparam">j</var><code>)</code>;</td></tr></table><div class="funcprototype-spacer"> </div><table border="0" class="funcprototype-table" summary="Function synopsis" style="cellspacing: 0; cellpadding: 0;"><tr><td><code class="funcdef">int <b class="fsfunc">sd_journal_wait</b>(</code></td><td>sd_journal *<var class="pdparam">j</var>, </td></tr><tr><td> </td><td>uint64_t <var class="pdparam">timeout_usec</var><code>)</code>;</td></tr></table><div class="funcprototype-spacer"> </div><table border="0" class="funcprototype-table" summary="Function synopsis" style="cellspacing: 0; cellpadding: 0;"><tr><td><code class="funcdef">int <b class="fsfunc">sd_journal_reliable_fd</b>(</code></td><td>sd_journal *<var class="pdparam">j</var><code>)</code>;</td></tr></table><div class="funcprototype-spacer"> </div></div></div><div class="refsect1"><a name="idm139870240160032"></a><h2 id="Description">Description<a class="headerlink" title="Permalink to this headline" href="#Description">¶</a></h2><p><code class="function">sd_journal_get_fd()</code> 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
|
||
<a href="http://man7.org/linux/man-pages/man2/poll.2.html"><span class="citerefentry"><span class="refentrytitle">poll</span>(2)</span></a>. Use
|
||
<code class="function">sd_journal_get_events()</code> 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
|
||
<code class="function">sd_journal_reliable_fd()</code>,
|
||
below. <code class="function">sd_journal_get_timeout()</code>
|
||
will ensure in these cases that wake-ups happen
|
||
frequently enough for changes to be noticed, although
|
||
with a certain latency.</p><p><code class="function">sd_journal_get_events()</code>
|
||
will return the <code class="function">poll()</code> mask to
|
||
wait for. This function will return a combination of
|
||
<code class="constant">POLLIN</code> and
|
||
<code class="constant">POLLOUT</code> and similar to fill into
|
||
the "<code class="literal">.events</code>" field of
|
||
<code class="varname">struct pollfd</code>.</p><p><code class="function">sd_journal_get_timeout()</code>
|
||
will return a timeout value for usage in
|
||
<code class="function">poll()</code>. This returns a value in
|
||
microseconds since the epoch of
|
||
<code class="constant">CLOCK_MONOTONIC</code> for timing out
|
||
<code class="function">poll()</code> in
|
||
<code class="varname">timeout_usec</code>. See
|
||
<a href="http://man7.org/linux/man-pages/man2/clock_gettime.2.html"><span class="citerefentry"><span class="refentrytitle">clock_gettime</span>(2)</span></a>
|
||
for details about
|
||
<code class="constant">CLOCK_MONOTONIC</code>. If there is no
|
||
timeout to wait for, this will fill in
|
||
<code class="constant">(uint64_t) -1</code> instead. Note that
|
||
<code class="function">poll()</code> 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:</p><pre class="programlisting">uint64_t t;
|
||
int msec;
|
||
sd_journal_get_timeout(m, &t);
|
||
if (t == (uint64_t) -1)
|
||
msec = -1;
|
||
else {
|
||
struct timespec ts;
|
||
uint64_t n;
|
||
clock_getttime(CLOCK_MONOTONIC, &ts);
|
||
n = (uint64_t) ts.tv_sec * 1000000 + ts.tv_nsec / 1000;
|
||
msec = t > n ? (int) ((t - n + 999) / 1000) : 0;
|
||
}</pre><p>The code above does not do any error checking
|
||
for brevity's sake. The calculated <code class="varname">msec</code>
|
||
integer can be passed directly as
|
||
<code class="function">poll()</code>'s timeout
|
||
parameter.</p><p>After each <code class="function">poll()</code> wake-up
|
||
<code class="function">sd_journal_process()</code> 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).</p><p>A synchronous alternative for using
|
||
<code class="function">sd_journal_get_fd()</code>,
|
||
<code class="function">sd_journal_get_events()</code>,
|
||
<code class="function">sd_journal_get_timeout()</code> and
|
||
<code class="function">sd_journal_process()</code> is
|
||
<code class="function">sd_journal_wait()</code>. It will
|
||
synchronously wait until the journal gets changed. The
|
||
maximum time this call sleeps may be controlled with
|
||
the <em class="parameter"><code>timeout_usec</code></em>
|
||
parameter. Pass <code class="constant">(uint64_t) -1</code> to
|
||
wait indefinitely. Internally this call simply
|
||
combines <code class="function">sd_journal_get_fd()</code>,
|
||
<code class="function">sd_journal_get_events()</code>,
|
||
<code class="function">sd_journal_get_timeout()</code>,
|
||
<code class="function">poll()</code> and
|
||
<code class="function">sd_journal_process()</code> into
|
||
one.</p><p><code class="function">sd_journal_reliable_fd()</code>
|
||
may be used to check whether the wakeup events from
|
||
the file descriptor returned by
|
||
<code class="function">sd_journal_get_fd()</code> 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
|
||
<code class="function">sd_journal_get_timeout()</code> on these
|
||
file systems will ask for timeouts explicitly
|
||
anyway.</p></div><div class="refsect1"><a name="idm139870240119632"></a><h2 id="Return Value">Return Value<a class="headerlink" title="Permalink to this headline" href="#Return%20Value">¶</a></h2><p><code class="function">sd_journal_get_fd()</code> returns
|
||
a valid file descriptor on success or a negative
|
||
errno-style error code.</p><p><code class="function">sd_journal_get_events()</code>
|
||
returns a combination of <code class="constant">POLLIN</code>,
|
||
<code class="constant">POLLOUT</code> and suchlike on success or
|
||
a negative errno-style error code.</p><p><code class="function">sd_journal_reliable_fd()</code>
|
||
returns a positive integer if the file descriptor
|
||
returned by <code class="function">sd_journal_get_fd()</code>
|
||
will generate wake-ups immediately for all journal
|
||
changes. Returns 0 if there might be a latency
|
||
involved.</p><p><code class="function">sd_journal_process()</code> and
|
||
<code class="function">sd_journal_wait()</code> return one of
|
||
<code class="constant">SD_JOURNAL_NOP</code>,
|
||
<code class="constant">SD_JOURNAL_APPEND</code> or
|
||
<code class="constant">SD_JOURNAL_INVALIDATE</code> on success or
|
||
a negative errno-style error code. If
|
||
<code class="constant">SD_JOURNAL_NOP</code> is returned, the
|
||
journal did not change since the last invocation. If
|
||
<code class="constant">SD_JOURNAL_APPEND</code> is returned, new
|
||
entries have been appended to the end of the
|
||
journal. If <code class="constant">SD_JOURNAL_INVALIDATE</code>,
|
||
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 <code class="constant">SD_JOURNAL_APPEND</code>, it is
|
||
sufficient to simply continue reading at the previous
|
||
end of the journal.</p></div><div class="refsect1"><a name="idm139870235144576"></a><h2 id="Notes">Notes<a class="headerlink" title="Permalink to this headline" href="#Notes">¶</a></h2><p>The <code class="function">sd_journal_get_fd()</code>,
|
||
<code class="function">sd_journal_get_events()</code>,
|
||
<code class="function">sd_journal_reliable_fd()</code>,
|
||
<code class="function">sd_journal_process()</code> and
|
||
<code class="function">sd_journal_wait()</code> interfaces are
|
||
available as a shared library, which can be compiled and
|
||
linked to with the
|
||
<code class="constant">libsystemd</code> <a href="http://linux.die.net/man/1/pkg-config"><span class="citerefentry"><span class="refentrytitle">pkg-config</span>(1)</span></a>
|
||
file.</p></div><div class="refsect1"><a name="idm139870235138752"></a><h2 id="Examples">Examples<a class="headerlink" title="Permalink to this headline" href="#Examples">¶</a></h2><p>Iterating through the journal, in a live view tracking all changes:</p><pre class="programlisting">#include <stdio.h>
|
||
#include <string.h>
|
||
#include <systemd/sd-journal.h>
|
||
|
||
int main(int argc, char *argv[]) {
|
||
int r;
|
||
sd_journal *j;
|
||
r = sd_journal_open(&j, SD_JOURNAL_LOCAL_ONLY);
|
||
if (r < 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 < 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 < 0) {
|
||
fprintf(stderr, "Failed to wait for changes: %s\n", strerror(-r));
|
||
break;
|
||
}
|
||
continue;
|
||
}
|
||
r = sd_journal_get_data(j, "MESSAGE", &d, &l);
|
||
if (r < 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;
|
||
}</pre><p>Waiting with <code class="function">poll()</code> (this
|
||
example lacks all error checking for the sake of
|
||
simplicity):</p><pre class="programlisting">#include <sys/poll.h>
|
||
#include <systemd/sd-journal.h>
|
||
|
||
int wait_for_changes(sd_journal *j) {
|
||
struct pollfd pollfd;
|
||
int msec;
|
||
|
||
sd_journal_get_timeout(m, &t);
|
||
if (t == (uint64_t) -1)
|
||
msec = -1;
|
||
else {
|
||
struct timespec ts;
|
||
uint64_t n;
|
||
clock_getttime(CLOCK_MONOTONIC, &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(&pollfd, 1, msec);
|
||
return sd_journal_process(j);
|
||
}</pre></div><div class="refsect1"><a name="idm139870235132128"></a><h2 id="See Also">See Also<a class="headerlink" title="Permalink to this headline" href="#See%20Also">¶</a></h2><p>
|
||
<a href="systemd.html"><span class="citerefentry"><span class="refentrytitle">systemd</span>(1)</span></a>,
|
||
<a href="sd-journal.html"><span class="citerefentry"><span class="refentrytitle">sd-journal</span>(3)</span></a>,
|
||
<a href="sd_journal_open.html"><span class="citerefentry"><span class="refentrytitle">sd_journal_open</span>(3)</span></a>,
|
||
<a href="sd_journal_next.html"><span class="citerefentry"><span class="refentrytitle">sd_journal_next</span>(3)</span></a>,
|
||
<a href="http://man7.org/linux/man-pages/man2/poll.2.html"><span class="citerefentry"><span class="refentrytitle">poll</span>(2)</span></a>,
|
||
<a href="http://man7.org/linux/man-pages/man2/clock_gettime.2.html"><span class="citerefentry"><span class="refentrytitle">clock_gettime</span>(2)</span></a>
|
||
</p></div></div></body></html>
|