summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLennart Poettering <lennart@poettering.net>2013-04-04 18:31:22 +0200
committerLennart Poettering <lennart@poettering.net>2013-04-04 18:31:22 +0200
commit667c24a6a86a5a26a906b7477ae81dcf4c73e64e (patch)
tree2a47196022087dbf16331ef89609084b705f3848
parent60491a28698205d34a071f5e1a66f5a4e3621445 (diff)
login: add sd_login_monitor_get_timeout() public api call
We don't need this right now, but we should keep our options open, in case we need more than just an fd for waking up.
-rw-r--r--man/sd_login_monitor_new.xml61
-rw-r--r--src/login/libsystemd-login.sym1
-rw-r--r--src/login/sd-login.c18
-rw-r--r--src/login/test-login.c19
-rw-r--r--src/systemd/sd-login.h4
5 files changed, 92 insertions, 11 deletions
diff --git a/man/sd_login_monitor_new.xml b/man/sd_login_monitor_new.xml
index 94428771a8..b187ad0dbe 100644
--- a/man/sd_login_monitor_new.xml
+++ b/man/sd_login_monitor_new.xml
@@ -48,6 +48,7 @@
<refname>sd_login_monitor_flush</refname>
<refname>sd_login_monitor_get_fd</refname>
<refname>sd_login_monitor_get_events</refname>
+ <refname>sd_login_monitor_get_timeout</refname>
<refname>sd_login_monitor</refname>
<refpurpose>Monitor login sessions, seats and users</refpurpose>
</refnamediv>
@@ -82,6 +83,12 @@
<paramdef>sd_login_monitor* <parameter>m</parameter></paramdef>
</funcprototype>
+ <funcprototype>
+ <funcdef>int <function>sd_login_monitor_get_timeout</function></funcdef>
+ <paramdef>sd_login_monitor* <parameter>m</parameter></paramdef>
+ <paramdef>uint64_t* <parameter>timeout_usec</parameter></paramdef>
+ </funcprototype>
+
</funcsynopsis>
</refsynopsisdiv>
@@ -130,7 +137,9 @@
or a similar interface. The application should include
the returned file descriptor as wake-up source for the
events mask returned by
- <function>sd_login_monitor_get_events()</function>. Whenever
+ <function>sd_login_monitor_get_events()</function>. It
+ should pass a timeout value as returned by
+ <function>sd_login_monitor_get_timeout()</function>. Whenever
a wake-up is triggered the file descriptor needs to be
reset via
<function>sd_login_monitor_flush()</function>. An
@@ -146,15 +155,51 @@
and similar to fill into the
<literal>.events</literal> field of <literal>struct
pollfd</literal>.</para>
+
+ <para><function>sd_login_monitor_get_timeout()</function>
+ will return a timeout value for usage in
+ <function>poll()</function>. This returns a value in
+ microseconds since the epoch of CLOCK_MONOTONIC for
+ timing out <function>poll()</function> in
+ <literal>timeout_usec</literal>. See
+ <citerefentry><refentrytitle>clock_gettime</refentrytitle><manvolnum>2</manvolnum></citerefentry>
+ for details about
+ <literal>CLOCK_MONOTONIC</literal>. If there's no
+ timeout to wait for this will fill in
+ <literal>(uint64_t) -1</literal> 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_login_monitor_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 <literal>msec</literal>
+ integer can be passed directly as
+ <function>poll()</function>'s timeout
+ parameter.</para>
</refsect1>
<refsect1>
<title>Return Value</title>
<para>On success
- <function>sd_login_monitor_new()</function> and
- <function>sd_login_monitor_flush()</function> return 0
- or a positive integer. On success
+ <function>sd_login_monitor_new()</function>,
+ <function>sd_login_monitor_flush()</function> and
+ <function>sd_login_monitor_get_timeout()</function>
+ return 0 or a positive integer. On success
<function>sd_login_monitor_get_fd()</function> returns
a Unix file descriptor. On success
<function>sd_login_monitor_get_events()</function>
@@ -173,8 +218,9 @@
<para>The <function>sd_login_monitor_new()</function>,
<function>sd_login_monitor_unref()</function>,
<function>sd_login_monitor_flush()</function>,
- <function>sd_login_monitor_get_fd()</function> and
- <function>sd_login_monitor_get_events()</function>
+ <function>sd_login_monitor_get_fd()</function>,
+ <function>sd_login_monitor_get_events()</function> and
+ <function>sd_login_monitor_get_timeout()</function>
interfaces are available as shared library, which can
be compiled and linked to with the
<literal>libsystemd-login</literal>
@@ -189,7 +235,8 @@
<citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
<citerefentry><refentrytitle>sd-login</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
<citerefentry><refentrytitle>sd_get_seats</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
- <citerefentry><refentrytitle>poll</refentrytitle><manvolnum>2</manvolnum></citerefentry>
+ <citerefentry><refentrytitle>poll</refentrytitle><manvolnum>2</manvolnum></citerefentry>,
+ <citerefentry><refentrytitle>clock_gettime</refentrytitle><manvolnum>2</manvolnum></citerefentry>
</para>
</refsect1>
diff --git a/src/login/libsystemd-login.sym b/src/login/libsystemd-login.sym
index 55a828773b..ce2304a1ba 100644
--- a/src/login/libsystemd-login.sym
+++ b/src/login/libsystemd-login.sym
@@ -62,4 +62,5 @@ global:
LIBSYSTEMD_LOGIN_201 {
global:
sd_login_monitor_get_events;
+ sd_login_monitor_get_timeout;
} LIBSYSTEMD_LOGIN_198;
diff --git a/src/login/sd-login.c b/src/login/sd-login.c
index 861a57166d..7513f76cb3 100644
--- a/src/login/sd-login.c
+++ b/src/login/sd-login.c
@@ -804,5 +804,23 @@ _public_ int sd_login_monitor_get_events(sd_login_monitor *m) {
if (!m)
return -EINVAL;
+ /* For now we will only return POLLIN here, since we don't
+ * need anything else ever for inotify. However, let's have
+ * this API to keep our options open should we later on need
+ * it. */
return POLLIN;
}
+
+_public_ int sd_login_monitor_get_timeout(sd_login_monitor *m, uint64_t *timeout_usec) {
+
+ if (!m)
+ return -EINVAL;
+ if (!timeout_usec)
+ return -EINVAL;
+
+ /* For now we will only return (uint64_t) -1, since we don't
+ * need any timeout. However, let's have this API to keep our
+ * options open should we later on need it. */
+ *timeout_usec = (uint64_t) -1;
+ return 0;
+}
diff --git a/src/login/test-login.c b/src/login/test-login.c
index f639129636..e4d0c93378 100644
--- a/src/login/test-login.c
+++ b/src/login/test-login.c
@@ -183,12 +183,23 @@ int main(int argc, char* argv[]) {
r = sd_login_monitor_new("session", &m);
assert_se(r >= 0);
- zero(pollfd);
- pollfd.fd = sd_login_monitor_get_fd(m);
- pollfd.events = sd_login_monitor_get_events(m);
for (n = 0; n < 5; n++) {
- r = poll(&pollfd, 1, -1);
+ usec_t timeout, nw;
+
+ zero(pollfd);
+ assert_se((pollfd.fd = sd_login_monitor_get_fd(m)) >= 0);
+ assert_se((pollfd.events = sd_login_monitor_get_events(m)) >= 0);
+
+ assert_se(sd_login_monitor_get_timeout(m, &timeout) >= 0);
+
+ nw = now(CLOCK_MONOTONIC);
+
+ r = poll(&pollfd, 1,
+ timeout == (uint64_t) -1 ? -1 :
+ timeout > nw ? (int) ((timeout - nw) / 1000) :
+ 0);
+
assert_se(r >= 0);
sd_login_monitor_flush(m);
diff --git a/src/systemd/sd-login.h b/src/systemd/sd-login.h
index 57255bd4a9..d05424dbf3 100644
--- a/src/systemd/sd-login.h
+++ b/src/systemd/sd-login.h
@@ -23,6 +23,7 @@
***/
#include <sys/types.h>
+#include <inttypes.h>
#ifdef __cplusplus
extern "C" {
@@ -159,6 +160,9 @@ int sd_login_monitor_get_fd(sd_login_monitor *m);
/* Get poll() mask to monitor */
int sd_login_monitor_get_events(sd_login_monitor *m);
+/* Get timeout for poll(), as usec value relative to CLOCK_MONOTONIC's epoch */
+int sd_login_monitor_get_timeout(sd_login_monitor *m, uint64_t *timeout_usec);
+
#ifdef __cplusplus
}
#endif