summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLaurent Bercot <ska-skaware@skarnet.org>2016-10-24 02:15:36 +0000
committerLaurent Bercot <ska-skaware@skarnet.org>2016-10-24 02:15:36 +0000
commit9ef3a9f8b2704693496af12120ea3ab40389bf7b (patch)
tree9ed582b049881f1271a6b02978f1ed6d28a4f948
parent422d91b2b0a2b8b3a8af510cc55b1400c60be303 (diff)
downloadskalibs-9ef3a9f8b2704693496af12120ea3ab40389bf7b.tar.xz
Add the alarm library, first draft.
-rwxr-xr-xconfigure29
-rw-r--r--doc/libstddjb/alarm.html94
-rw-r--r--doc/libstddjb/index.html1
-rw-r--r--package/deps.mak7
-rw-r--r--src/include/skalibs/alarm.h13
-rw-r--r--src/include/skalibs/stddjb.h1
-rw-r--r--src/libstddjb/alarm-internal.h14
-rw-r--r--src/libstddjb/alarm_deadline.c47
-rw-r--r--src/libstddjb/alarm_disable.c41
-rw-r--r--src/libstddjb/alarm_milliseconds.c61
-rw-r--r--src/libstddjb/alarm_timeout.c65
-rw-r--r--src/libstddjb/alloc-internal.h4
-rw-r--r--src/sysdeps/tryitimer.c10
-rw-r--r--src/sysdeps/trytimer.c12
14 files changed, 385 insertions, 14 deletions
diff --git a/configure b/configure
index 96699f6..bb100ed 100755
--- a/configure
+++ b/configure
@@ -118,19 +118,24 @@ tryldflag () {
}
choose () {
+ what="$1"
+ name="$2"
+ macro="$3"
echo "Checking whether system has $4..."
+ shift 4
+ libs="$*"
r=true
- case "$1" in
- *c*) $CC_AUTO $CPPFLAGS_AUTO $CFLAGS_AUTO -o try$2.o -c src/sysdeps/try$2.c 2>/dev/null || r=false ;;
+ case "$what" in
+ *c*) $CC_AUTO $CPPFLAGS_AUTO $CFLAGS_AUTO -o try$name.o -c src/sysdeps/try$name.c 2>/dev/null || r=false ;;
esac
if $r ; then
- case "$1" in
- *l*) $CC_AUTO $CFLAGS_AUTO $LDFLAGS_AUTO -o try$2 try$2.o $5 2>/dev/null || r=false ;;
+ case "$what" in
+ *l*) $CC_AUTO $CFLAGS_AUTO $LDFLAGS_AUTO -o try$name try$name.o $libs 2>/dev/null || r=false ;;
esac
fi
if $r ; then
- case "$1" in
- *r*) ./try$2 >/dev/null 2>&1 ; r=$?
+ case "$what" in
+ *r*) ./try$name >/dev/null 2>&1 ; r=$?
case "$r" in
111) echo " ... test crashed, aborting." ; exit 111 ;;
0) r=true ;;
@@ -138,14 +143,14 @@ choose () {
esac
esac
fi
- rm -f try$2.o try$2
+ rm -f try$name.o try$name
if $r ; then
- echo "$2: yes" >> $sysdeps/sysdeps
- echo "#define ${package_macro_name}_HAS$3" >> $sysdeps/sysdeps.h
+ echo "$name: yes" >> $sysdeps/sysdeps
+ echo "#define ${package_macro_name}_HAS$macro" >> $sysdeps/sysdeps.h
echo " ... yes"
else
- echo "$2: no" >> $sysdeps/sysdeps
- echo "#undef ${package_macro_name}_HAS$3" >> $sysdeps/sysdeps.h
+ echo "$name: no" >> $sysdeps/sysdeps
+ echo "#undef ${package_macro_name}_HAS$macro" >> $sysdeps/sysdeps.h
echo " ... no"
fi
}
@@ -490,6 +495,8 @@ EOF
choose cl futimes FUTIMES 'futimes()'
choose cl arc4random ARC4RANDOM 'arc4random()'
choose cl getrandom GETRANDOM 'getrandom()'
+ choose cl timer TIMER 'timer_create()' $sysclock_lib
+ choose cl itimer ITIMER 'setitimer()'
echo '#endif' >> $sysdeps/sysdeps.h
fi
diff --git a/doc/libstddjb/alarm.html b/doc/libstddjb/alarm.html
new file mode 100644
index 0000000..da14267
--- /dev/null
+++ b/doc/libstddjb/alarm.html
@@ -0,0 +1,94 @@
+<html>
+ <head>
+ <meta name="viewport" content="width=device-width, initial-scale=1.0" />
+ <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
+ <meta http-equiv="Content-Language" content="en" />
+ <title>skalibs: the alarm library interface</title>
+ <meta name="Description" content="skalibs: the alarm library interface" />
+ <meta name="Keywords" content="skalibs c unix alarm getitimer setitimer timer_create timer_gettime timer_settime library libstddjb" />
+ <!-- <link rel="stylesheet" type="text/css" href="http://skarnet.org/default.css" /> -->
+ </head>
+<body>
+
+<p>
+<a href="index.html">libstddjb</a><br />
+<a href="../libskarnet.html">libskarnet</a><br />
+<a href="../index.html">skalibs</a><br />
+<a href="http://skarnet.org/software/">Software</a><br />
+<a href="http://skarnet.org/">skarnet.org</a>
+</p>
+
+<h1> The <tt>alarm</tt> library interface </h1>
+
+<p>
+ The following functions are declared in the <tt>skalibs/alarm.h</tt> header,
+and implemented in the <tt>libskarnet.a</tt> or <tt>libskarnet.so</tt> library.
+</p>
+
+<h2> General information </h2>
+
+<p>
+ <tt>alarm</tt> is a set of primitives to provide the same functionality as
+<a href="http://pubs.opengroup.org/onlinepubs/9699919799/functions/alarm.html">alarm()</a>,
+but with sub-second precision.
+</p>
+
+<p>
+ Depending on the functionality the underlying system provides,
+the precision can be 1 nanosecond (implementation via
+<a href="http://pubs.opengroup.org/onlinepubs/9699919799/functions/timer_getoverrun.html">timer_settime()</a>,
+1 microsecond (implementation via
+<a href="http://pubs.opengroup.org/onlinepubs/9699919799/functions/setitimer.html">setitimer()</a>,
+or 1 second (fallback implementation with
+<a href="http://pubs.opengroup.org/onlinepubs/9699919799/functions/alarm.html">alarm()</a>
+when nothing better can be found).
+</p>
+
+<h2> Functions </h2>
+
+<p>
+<code> int alarm_milliseconds (unsigned int n) </code> <br />
+Sets a fuse that will raise a SIGALRM after <em>n</em> milliseconds.
+If <em>n</em> is 0, the SIGALRM will be raised instantly.
+Returns 1 on success and 0 (and sets errno) on failure.
+</p>
+
+<p>
+<code> int alarm_timeout (tain_t const *tto) </code> <br />
+Sets a fuse that will raise a SIGALRM after some amount
+of time has passed. The amount of time is described in
+*<em>tto</em>, which is a relative
+<a href="tai.html">tain_t</a>, i.e. a structure containing
+a relative TAIN64 time.
+Returns 1 on success and 0 (and sets errno) on failure.
+</p>
+
+<p>
+<code> int alarm_deadline (tain_t const *deadline) </code> <br />
+Sets a fuse that will raise a SIGALRM when the clock reaches
+*<em>deadline</em>, which is an absolute time expressed in
+<a href="tai.html">TAI64N</a> format.
+Returns 1 on success and 0 (and sets errno) on failure.
+</p>
+
+<p>
+<code> void alarm_disable (void) </code> <br />
+Cancels a previously set fuse. No SIGALRM will be raised.
+</p>
+
+<h2> Notes </h2>
+
+<ul>
+ <li> Asynchronous programming via signals is bad. The best way
+to handle situations where something happens after some time has
+elapsed is to use an asynchronous loop primitive such as
+<a href="iopause.html">iopause()</a>. The problem is that some
+external libraries only provide synchronous functions (including
+functions talking to the network!) with no obvious way to set a
+timeout. The <tt>alarm_*</tt> set of functions is meant to work
+around that, with hopefully better granularity than the POSIX
+<tt>alarm()</tt> function. </li>
+</ul>
+
+</body>
+</html>
diff --git a/doc/libstddjb/index.html b/doc/libstddjb/index.html
index dfa6f94..6ecfeb2 100644
--- a/doc/libstddjb/index.html
+++ b/doc/libstddjb/index.html
@@ -45,6 +45,7 @@ including them directly. </li>
<h2> Programming </h2>
<ul>
+ <li> <a href="alarm.html">skalibs/alarm.h</a>: sub-second precision <a href="http://pubs.opengroup.org/onlinepubs/9699919799/functions/alarm.html">alarm()</a> </li>
<li> <a href="alloc.html">skalibs/alloc.h</a>: basic heap memory allocation primitives </li>
<li> <a href="allreadwrite.html">skalibs/allreadwrite.h</a>: <a href="safewrappers.html">safe
wrappers</a> around I/O functions, extra I/O functions </li>
diff --git a/package/deps.mak b/package/deps.mak
index 58fd526..d128122 100644
--- a/package/deps.mak
+++ b/package/deps.mak
@@ -2,6 +2,7 @@
# This file has been generated by tools/gen-deps.sh
#
+src/include/skalibs/alarm.h: src/include/skalibs/tai.h
src/include/skalibs/alloc.h: src/include/skalibs/gccattributes.h
src/include/skalibs/allreadwrite.h: src/include/skalibs/functypes.h src/include/skalibs/siovec.h
src/include/skalibs/avlnode.h: src/include/skalibs/functypes.h src/include/skalibs/gccattributes.h
@@ -44,7 +45,7 @@ src/include/skalibs/skalibs.h: src/include/skalibs/biguint.h src/include/skalibs
src/include/skalibs/skamisc.h: src/include/skalibs/buffer.h src/include/skalibs/stralloc.h
src/include/skalibs/socket.h: src/include/skalibs/djbunix.h src/include/skalibs/gccattributes.h src/include/skalibs/tai.h src/include/skalibs/uint16.h src/include/skalibs/uint32.h src/include/skalibs/webipc.h
src/include/skalibs/stdcrypto.h: src/include/skalibs/md5.h src/include/skalibs/rc4.h src/include/skalibs/sha1.h src/include/skalibs/sha256.h src/include/skalibs/sha512.h
-src/include/skalibs/stddjb.h: src/include/skalibs/alloc.h src/include/skalibs/allreadwrite.h src/include/skalibs/bitarray.h src/include/skalibs/bufalloc.h src/include/skalibs/buffer.h src/include/skalibs/bytestr.h src/include/skalibs/cbuffer.h src/include/skalibs/cdb.h src/include/skalibs/cdb_make.h src/include/skalibs/config.h src/include/skalibs/direntry.h src/include/skalibs/diuint.h src/include/skalibs/diuint32.h src/include/skalibs/djbtime.h src/include/skalibs/djbunix.h src/include/skalibs/env.h src/include/skalibs/envalloc.h src/include/skalibs/environ.h src/include/skalibs/error.h src/include/skalibs/fmtscan.h src/include/skalibs/functypes.h src/include/skalibs/gccattributes.h src/include/skalibs/genalloc.h src/include/skalibs/genwrite.h src/include/skalibs/getpeereid.h src/include/skalibs/gidstuff.h src/include/skalibs/iobuffer.h src/include/skalibs/iopause.h src/include/skalibs/ip46.h src/include/skalibs/lolstdio.h src/include/skalibs/mininetstring.h src/include/skalibs/netstring.h src/include/skalibs/nsig.h src/include/skalibs/segfault.h src/include/skalibs/selfpipe.h src/include/skalibs/setgroups.h src/include/skalibs/sgetopt.h src/include/skalibs/sig.h src/include/skalibs/siovec.h src/include/skalibs/skamisc.h src/include/skalibs/socket.h src/include/skalibs/stralloc.h src/include/skalibs/strerr.h src/include/skalibs/strerr2.h src/include/skalibs/tai.h src/include/skalibs/uint.h src/include/skalibs/uint16.h src/include/skalibs/uint32.h src/include/skalibs/uint64.h src/include/skalibs/ulong.h src/include/skalibs/ushort.h src/include/skalibs/webipc.h
+src/include/skalibs/stddjb.h: src/include/skalibs/alarm.h src/include/skalibs/alloc.h src/include/skalibs/allreadwrite.h src/include/skalibs/bitarray.h src/include/skalibs/bufalloc.h src/include/skalibs/buffer.h src/include/skalibs/bytestr.h src/include/skalibs/cbuffer.h src/include/skalibs/cdb.h src/include/skalibs/cdb_make.h src/include/skalibs/config.h src/include/skalibs/direntry.h src/include/skalibs/diuint.h src/include/skalibs/diuint32.h src/include/skalibs/djbtime.h src/include/skalibs/djbunix.h src/include/skalibs/env.h src/include/skalibs/envalloc.h src/include/skalibs/environ.h src/include/skalibs/error.h src/include/skalibs/fmtscan.h src/include/skalibs/functypes.h src/include/skalibs/gccattributes.h src/include/skalibs/genalloc.h src/include/skalibs/genwrite.h src/include/skalibs/getpeereid.h src/include/skalibs/gidstuff.h src/include/skalibs/iobuffer.h src/include/skalibs/iopause.h src/include/skalibs/ip46.h src/include/skalibs/lolstdio.h src/include/skalibs/mininetstring.h src/include/skalibs/netstring.h src/include/skalibs/nsig.h src/include/skalibs/segfault.h src/include/skalibs/selfpipe.h src/include/skalibs/setgroups.h src/include/skalibs/sgetopt.h src/include/skalibs/sig.h src/include/skalibs/siovec.h src/include/skalibs/skamisc.h src/include/skalibs/socket.h src/include/skalibs/stralloc.h src/include/skalibs/strerr.h src/include/skalibs/strerr2.h src/include/skalibs/tai.h src/include/skalibs/uint.h src/include/skalibs/uint16.h src/include/skalibs/uint32.h src/include/skalibs/uint64.h src/include/skalibs/ulong.h src/include/skalibs/ushort.h src/include/skalibs/webipc.h
src/include/skalibs/stralloc.h: src/include/skalibs/bytestr.h src/include/skalibs/siovec.h
src/include/skalibs/strerr.h: src/include/skalibs/gccattributes.h
src/include/skalibs/strerr2.h: src/include/skalibs/strerr.h
@@ -161,6 +162,10 @@ src/libstdcrypto/sha512_transform.o src/libstdcrypto/sha512_transform.lo: src/li
src/libstdcrypto/sha512_update.o src/libstdcrypto/sha512_update.lo: src/libstdcrypto/sha512_update.c src/include/skalibs/bytestr.h src/libstdcrypto/sha512-internal.h src/include/skalibs/sha512.h
src/libstddjb/absolutepath.o src/libstddjb/absolutepath.lo: src/libstddjb/absolutepath.c src/include/skalibs/djbunix.h src/include/skalibs/skamisc.h src/include/skalibs/stralloc.h
src/libstddjb/absolutepath_tmp.o src/libstddjb/absolutepath_tmp.lo: src/libstddjb/absolutepath_tmp.c src/include/skalibs/bytestr.h src/include/skalibs/djbunix.h src/include/skalibs/stralloc.h
+src/libstddjb/alarm_deadline.o src/libstddjb/alarm_deadline.lo: src/libstddjb/alarm_deadline.c src/libstddjb/alarm-internal.h src/include/skalibs/alarm.h src/include/skalibs/sysdeps.h src/include/skalibs/tai.h
+src/libstddjb/alarm_disable.o src/libstddjb/alarm_disable.lo: src/libstddjb/alarm_disable.c src/libstddjb/alarm-internal.h src/include/skalibs/alarm.h src/include/skalibs/sysdeps.h
+src/libstddjb/alarm_milliseconds.o src/libstddjb/alarm_milliseconds.lo: src/libstddjb/alarm_milliseconds.c src/libstddjb/alarm-internal.h src/include/skalibs/alarm.h src/include/skalibs/sysdeps.h
+src/libstddjb/alarm_timeout.o src/libstddjb/alarm_timeout.lo: src/libstddjb/alarm_timeout.c src/libstddjb/alarm-internal.h src/include/skalibs/alarm.h src/include/skalibs/sysdeps.h src/include/skalibs/tai.h
src/libstddjb/alloc.o src/libstddjb/alloc.lo: src/libstddjb/alloc.c src/libstddjb/alloc-internal.h src/include/skalibs/alloc.h src/include/skalibs/sysdeps.h
src/libstddjb/alloc_0.o src/libstddjb/alloc_0.lo: src/libstddjb/alloc_0.c src/libstddjb/alloc-internal.h src/include/skalibs/alloc.h src/include/skalibs/sysdeps.h
src/libstddjb/allread.o src/libstddjb/allread.lo: src/libstddjb/allread.c src/include/skalibs/allreadwrite.h
diff --git a/src/include/skalibs/alarm.h b/src/include/skalibs/alarm.h
new file mode 100644
index 0000000..9c2951a
--- /dev/null
+++ b/src/include/skalibs/alarm.h
@@ -0,0 +1,13 @@
+/* ISC license. */
+
+#ifndef ALARM_H
+#define ALARM_H
+
+#include <skalibs/tai.h>
+
+extern int alarm_milliseconds (unsigned int) ;
+extern int alarm_timeout (tain_t const *) ;
+extern int alarm_deadline (tain_t const *) ;
+extern void alarm_disable (void) ;
+
+#endif
diff --git a/src/include/skalibs/stddjb.h b/src/include/skalibs/stddjb.h
index e265003..3ebd219 100644
--- a/src/include/skalibs/stddjb.h
+++ b/src/include/skalibs/stddjb.h
@@ -15,6 +15,7 @@
#include <skalibs/ip46.h>
#include <skalibs/setgroups.h>
+#include <skalibs/alarm.h>
#include <skalibs/alloc.h>
#include <skalibs/allreadwrite.h>
#include <skalibs/bitarray.h>
diff --git a/src/libstddjb/alarm-internal.h b/src/libstddjb/alarm-internal.h
new file mode 100644
index 0000000..027a0dc
--- /dev/null
+++ b/src/libstddjb/alarm-internal.h
@@ -0,0 +1,14 @@
+/* ISC license. */
+
+#ifndef ALARM_INTERNAL_H
+#define ALARM_INTERNAL_H
+
+#ifdef SKALIBS_HASTIMER
+
+#include <time.h>
+
+extern timer_t timer_here ;
+
+#endif
+
+#endif
diff --git a/src/libstddjb/alarm_deadline.c b/src/libstddjb/alarm_deadline.c
new file mode 100644
index 0000000..768ee5c
--- /dev/null
+++ b/src/libstddjb/alarm_deadline.c
@@ -0,0 +1,47 @@
+/* ISC license. */
+
+#include <skalibs/sysdeps.h>
+#include <skalibs/tai.h>
+#include <skalibs/alarm.h>
+
+#ifdef SKALIBS_HASTIMER
+
+#include <errno.h>
+#include <signal.h>
+#include <time.h>
+#include "alarm-internal.h"
+
+#undef MYCLOCK
+#ifdef SKALIBS_HASCLOCKMON
+# define MYCLOCK CLOCK_MONOTONIC
+#else
+# define MYCLOCK CLOCK_REALTIME
+#endif
+
+int alarm_deadline (tain_t const *deadline)
+{
+ struct itimerspec it = { .it_interval = { .tv_sec = 0, .tv_nsec = 0 } } ;
+ struct sigevent se = { .sigev_notify = SIGEV_SIGNAL, .sigev_signo = SIGALRM, .sigev_value = { .sival_int = 0 }, .sigev_notify_function = 0, .sigev_notify_attributes = 0 } ;
+ if (!timespec_from_tain(&it.it_value, deadline)) return 0 ;
+ if (timer_create(MYCLOCK, &se, &timer_here) < 0) return 0 ;
+ if (timer_settime(timer_here, TIMER_ABSTIME, &it, 0) < 0)
+ {
+ int e = errno ;
+ timer_delete(timer_here) ;
+ errno = e ;
+ return 0 ;
+ }
+ return 1 ;
+}
+
+#else
+
+int alarm_deadline (tain_t const *deadline)
+{
+ tain_t tto ;
+ tain_now(&tto) ;
+ tain_sub(&tto, deadline, &tto) ;
+ return alarm_timeout(&tto) ;
+}
+
+#endif
diff --git a/src/libstddjb/alarm_disable.c b/src/libstddjb/alarm_disable.c
new file mode 100644
index 0000000..a383411
--- /dev/null
+++ b/src/libstddjb/alarm_disable.c
@@ -0,0 +1,41 @@
+/* ISC license. */
+
+#include <skalibs/sysdeps.h>
+#include <skalibs/alarm.h>
+
+#ifdef SKALIBS_HASTIMER
+
+#include <time.h>
+#include "alarm-internal.h"
+
+timer_t timer_here ;
+
+void alarm_disable ()
+{
+ struct itimerspec stopit = { .it_value = { .tv_sec = 0, .tv_nsec = 0 }, .it_interval = { .tv_sec = 0, .tv_nsec = 0 } } ;
+ timer_settime(timer_here, 0, &stopit, 0) ;
+ timer_delete(timer_here) ;
+}
+
+#else
+#ifdef SKALIBS_HASITIMER
+
+#include <sys/time.h>
+
+void alarm_disable ()
+{
+ struct itimerval stopit = { .it_value = { .tv_sec = 0, .tv_usec = 0 }, .it_interval = { .tv_sec = 0, .tv_usec = 0 } } ;
+ setitimer(ITIMER_REAL, &stopit, 0) ;
+}
+
+#else
+
+#include <unistd.h>
+
+void alarm_disable ()
+{
+ alarm(0) ;
+}
+
+#endif
+#endif
diff --git a/src/libstddjb/alarm_milliseconds.c b/src/libstddjb/alarm_milliseconds.c
new file mode 100644
index 0000000..0628518
--- /dev/null
+++ b/src/libstddjb/alarm_milliseconds.c
@@ -0,0 +1,61 @@
+/* ISC license. */
+
+#include <skalibs/sysdeps.h>
+#include <skalibs/alarm.h>
+
+#ifdef SKALIBS_HASTIMER
+
+#include <errno.h>
+#include <signal.h>
+#include <time.h>
+#include "alarm-internal.h"
+
+#undef MYCLOCK
+#ifdef SKALIBS_HASCLOCKMON
+# define MYCLOCK CLOCK_MONOTONIC
+#else
+# define MYCLOCK CLOCK_REALTIME
+#endif
+
+int alarm_milliseconds (unsigned int t)
+{
+ struct itimerspec it = { .it_interval = { .tv_sec = 0, .tv_nsec = 0 }, .it_value = { .tv_sec = t / 1000, .tv_nsec = 1000000 * (t % 1000) } } ;
+ struct sigevent se = { .sigev_notify = SIGEV_SIGNAL, .sigev_signo = SIGALRM, .sigev_value = { .sival_int = 0 }, .sigev_notify_function = 0, .sigev_notify_attributes = 0 } ;
+ if (timer_create(MYCLOCK, &se, &timer_here) < 0) return 0 ;
+ if (timer_settime(timer_here, 0, &it, 0) < 0)
+ {
+ int e = errno ;
+ timer_delete(timer_here) ;
+ errno = e ;
+ return 0 ;
+ }
+ return 1 ;
+}
+
+#else
+#ifdef SKALIBS_HASITIMER
+
+#include <sys/time.h>
+
+int alarm_milliseconds (unsigned int t)
+{
+ struct itimerval it = { .it_interval = { .tv_sec = 0, .tv_usec = 0 }, .it_value = { .tv_sec = t / 1000, .tv_usec = 1000 * (t % 1000) } } ;
+ if (setitimer(ITIMER_REAL, &it, 0) < 0) return 0 ;
+ return 1 ;
+}
+
+#else
+
+#include <unistd.h>
+#include <limits.h>
+
+int alarm_milliseconds (unsigned int t)
+{
+ if (t > UINT_MAX - 999) return 0 ;
+ t = (t + 999) / 1000 ;
+ alarm(t) ;
+ return 1 ;
+}
+
+#endif
+#endif
diff --git a/src/libstddjb/alarm_timeout.c b/src/libstddjb/alarm_timeout.c
new file mode 100644
index 0000000..630b524
--- /dev/null
+++ b/src/libstddjb/alarm_timeout.c
@@ -0,0 +1,65 @@
+/* ISC license. */
+
+#include <skalibs/sysdeps.h>
+#include <skalibs/tai.h>
+#include <skalibs/alarm.h>
+
+#ifdef SKALIBS_HASTIMER
+
+#include <errno.h>
+#include <signal.h>
+#include <time.h>
+#include "alarm-internal.h"
+
+#undef MYCLOCK
+#ifdef SKALIBS_HASCLOCKMON
+# define MYCLOCK CLOCK_MONOTONIC
+#else
+# define MYCLOCK CLOCK_REALTIME
+#endif
+
+int alarm_timeout (tain_t const *tto)
+{
+ struct itimerspec it = { .it_interval = { .tv_sec = 0, .tv_nsec = 0 } } ;
+ struct sigevent se = { .sigev_notify = SIGEV_SIGNAL, .sigev_signo = SIGALRM, .sigev_value = { .sival_int = 0 }, .sigev_notify_function = 0, .sigev_notify_attributes = 0 } ;
+ if (!timespec_from_tain_relative(&it.it_value, tto)) return 0 ;
+ if (timer_create(MYCLOCK, &se, &timer_here) < 0) return 0 ;
+ if (timer_settime(timer_here, 0, &it, 0) < 0)
+ {
+ int e = errno ;
+ timer_delete(timer_here) ;
+ errno = e ;
+ return 0 ;
+ }
+ return 1 ;
+}
+
+#else
+#ifdef SKALIBS_HASITIMER
+
+#include <sys/time.h>
+
+int alarm_timeout (tain_t const *tto)
+{
+ struct itimerval it = { .it_interval = { .tv_sec = 0, .tv_usec = 0 } } ;
+ if (!timeval_from_tain_relative(&it.it_value, tto)) return 0 ;
+ if (setitimer(ITIMER_REAL, &it, 0) < 0) return 0 ;
+ return 1 ;
+}
+
+#else
+
+#include <unistd.h>
+#include <limits.h>
+
+int alarm_timeout (tain_t const *tto)
+{
+ int t = tain_to_millisecs(tto) ;
+ if (t < 0 || t > INT_MAX - 999) return 0 ;
+ t = (t + 999) / 1000 ;
+ alarm(t) ;
+ return 1 ;
+}
+
+#endif
+#endif
diff --git a/src/libstddjb/alloc-internal.h b/src/libstddjb/alloc-internal.h
index 918b5df..6fd312e 100644
--- a/src/libstddjb/alloc-internal.h
+++ b/src/libstddjb/alloc-internal.h
@@ -1,7 +1,7 @@
/* ISC license. */
-#ifndef ALLOC_0_H
-#define ALLOC_0_H
+#ifndef ALLOC_INTERNAL_H
+#define ALLOC_INTERNAL_H
#include <skalibs/sysdeps.h>
#include <skalibs/alloc.h>
diff --git a/src/sysdeps/tryitimer.c b/src/sysdeps/tryitimer.c
new file mode 100644
index 0000000..4fd3454
--- /dev/null
+++ b/src/sysdeps/tryitimer.c
@@ -0,0 +1,10 @@
+/* ISC license. */
+
+#include <sys/time.h>
+
+int main (void)
+{
+ struct itimerval blah ;
+ if (getitimer(ITIMER_REAL, &blah) < 0) return 111 ;
+ return 0 ;
+}
diff --git a/src/sysdeps/trytimer.c b/src/sysdeps/trytimer.c
new file mode 100644
index 0000000..84cea0d
--- /dev/null
+++ b/src/sysdeps/trytimer.c
@@ -0,0 +1,12 @@
+/* ISC license. */
+
+#include <sys/types.h>
+#include <signal.h>
+#include <time.h>
+
+int main (void)
+{
+ timer_t blah ;
+ if (timer_create(CLOCK_REALTIME, 0, &blah) < 0) return 111 ;
+ return 0 ;
+}