diff options
author | Lennart Poettering <lennart@poettering.net> | 2013-04-04 18:31:22 +0200 |
---|---|---|
committer | Lennart Poettering <lennart@poettering.net> | 2013-04-04 18:31:22 +0200 |
commit | 667c24a6a86a5a26a906b7477ae81dcf4c73e64e (patch) | |
tree | 2a47196022087dbf16331ef89609084b705f3848 | |
parent | 60491a28698205d34a071f5e1a66f5a4e3621445 (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.xml | 61 | ||||
-rw-r--r-- | src/login/libsystemd-login.sym | 1 | ||||
-rw-r--r-- | src/login/sd-login.c | 18 | ||||
-rw-r--r-- | src/login/test-login.c | 19 | ||||
-rw-r--r-- | src/systemd/sd-login.h | 4 |
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, &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; +}</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 |