summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKaz Kylheku <kaz@kylheku.com>2014-08-01 22:13:11 -0700
committerKaz Kylheku <kaz@kylheku.com>2014-08-01 22:13:11 -0700
commit404e5c4091c607a39d28b651063da9bdc7ebb3bb (patch)
tree0ff839db2e4d40c86918c423538ec617da24560e
parent3c616876604219141ad1088e372c91928508f089 (diff)
downloadtxr-404e5c4091c607a39d28b651063da9bdc7ebb3bb.tar.gz
txr-404e5c4091c607a39d28b651063da9bdc7ebb3bb.tar.bz2
txr-404e5c4091c607a39d28b651063da9bdc7ebb3bb.zip
* configure (have_sys_time): New variable.
Added check for setitimer/getitimer which also checks for <sys/time.h>. * signal.c (sig_init): Register itimer-real, itimer-virtual, itimer-prof variables and getitimer and setitimer functions. (tv_to_usec): New static function. (getitimer_wrap, setitimer_wrap): New functions. * signal.h (getitimer_wrap, setitimer_wrap): Declared. * txr.1: Documented itimers.
-rw-r--r--ChangeLog15
-rwxr-xr-xconfigure28
-rw-r--r--signal.c51
-rw-r--r--signal.h5
-rw-r--r--txr.137
5 files changed, 136 insertions, 0 deletions
diff --git a/ChangeLog b/ChangeLog
index dbcb0a68..f577bad7 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,20 @@
2014-08-01 Kaz Kylheku <kaz@kylheku.com>
+ * configure (have_sys_time): New variable.
+ Added check for setitimer/getitimer which also
+ checks for <sys/time.h>.
+
+ * signal.c (sig_init): Register itimer-real, itimer-virtual,
+ itimer-prof variables and getitimer and setitimer functions.
+ (tv_to_usec): New static function.
+ (getitimer_wrap, setitimer_wrap): New functions.
+
+ * signal.h (getitimer_wrap, setitimer_wrap): Declared.
+
+ * txr.1: Documented itimers.
+
+2014-08-01 Kaz Kylheku <kaz@kylheku.com>
+
* signal.c (set_sig_handler): Don't use SA_ONSTACK
except for signals for which we use alt stack.
diff --git a/configure b/configure
index 6151327b..33c87103 100755
--- a/configure
+++ b/configure
@@ -114,6 +114,7 @@ mpi_version=1.8.6
have_quilt=
have_patch=
have_unistd=
+have_sys_time=
have_timegm=
have_syslog=
have_windows_h=
@@ -1709,6 +1710,29 @@ else
printf "no\n"
fi
+printf "Checking for setitimer/getitimer ... "
+
+cat > conftest.c <<!
+#include <sys/time.h>
+
+int main(void)
+{
+ struct itimerval itv, itv2;
+ int err;
+ err = getitimer(ITIMER_REAL, &itv);
+ err = getitimer(ITIMER_VIRTUAL, &itv);
+ err = setitimer(ITIMER_VIRTUAL, &itv, &itv2);
+ return 0;
+}
+!
+if conftest ; then
+ printf "yes\n"
+ printf "#define HAVE_ITIMER 1\n" >> config.h
+ have_sys_time=y
+else
+ printf "no\n"
+fi
+
printf "Checking for makedev ... "
cat > conftest.c <<!
@@ -1843,6 +1867,10 @@ if [ -n "$have_unistd" ] ; then
printf "#define HAVE_UNISTD_H 1\n" >> config.h
fi
+if [ -n "$have_sys_time" ] ; then
+ printf "#define HAVE_SYS_TIME 1\n" >> config.h
+fi
+
if [ -n "$have_windows_h" ] ; then
printf "#define HAVE_WINDOWS_H 1\n" >> config.h
fi
diff --git a/signal.c b/signal.c
index 305fee89..35e55fa3 100644
--- a/signal.c
+++ b/signal.c
@@ -34,6 +34,9 @@
#include <dirent.h>
#include <signal.h>
#include "config.h"
+#if HAVE_SYS_TIME
+#include <sys/time.h>
+#endif
#include "lib.h"
#include "gc.h"
#include "signal.h"
@@ -156,6 +159,14 @@ void sig_init(void)
reg_var(intern(lit("sig-pwr"), user_package), num_fast(SIGPWR));
#endif
+#if HAVE_ITIMER
+ reg_var(intern(lit("itimer-real"), user_package), num_fast(ITIMER_REAL));
+ reg_var(intern(lit("itimer-virtual"), user_package), num_fast(ITIMER_VIRTUAL));
+ reg_var(intern(lit("itimer-prov"), user_package), num_fast(ITIMER_PROF));
+ reg_fun(intern(lit("getitimer"), user_package), func_n1(getitimer_wrap));
+ reg_fun(intern(lit("setitimer"), user_package), func_n3(setitimer_wrap));
+#endif
+
reg_fun(intern(lit("set-sig-handler"), user_package), func_n2(set_sig_handler));
reg_fun(intern(lit("get-sig-handler"), user_package), func_n1(get_sig_handler));
reg_fun(intern(lit("sig-check"), user_package), func_n0(sig_check));
@@ -332,3 +343,43 @@ int sig_mask(int how, const sigset_t *set, sigset_t *oldset)
*oldset = sig_blocked_cache;
return 0;
}
+
+#if HAVE_ITIMER
+
+static val tv_to_usec(val sec, val usec)
+{
+ const val meg = num_fast(1000000);
+ return plus(mul(sec, meg), usec);
+}
+
+val getitimer_wrap(val which)
+{
+ struct itimerval itv;
+
+ if (getitimer(c_num(which), &itv) < 0)
+ return nil;
+
+ return list(tv_to_usec(num(itv.it_interval.tv_sec), num(itv.it_interval.tv_usec)),
+ tv_to_usec(num(itv.it_value.tv_sec), num(itv.it_value.tv_usec)),
+ nao);
+}
+
+val setitimer_wrap(val which, val interval, val currval)
+{
+ struct itimerval itn, itv;
+ const val meg = num_fast(1000000);
+
+ itn.it_interval.tv_sec = c_num(trunc(interval, meg));
+ itn.it_interval.tv_usec = c_num(mod(interval, meg));
+ itn.it_value.tv_sec = c_num(trunc(currval, meg));
+ itn.it_value.tv_usec = c_num(mod(currval, meg));
+
+ if (setitimer(c_num(which), &itn, &itv) < 0)
+ return nil;
+
+ return list(tv_to_usec(num(itv.it_interval.tv_sec), num(itv.it_interval.tv_usec)),
+ tv_to_usec(num(itv.it_value.tv_sec), num(itv.it_value.tv_usec)),
+ nao);
+}
+
+#endif
diff --git a/signal.h b/signal.h
index 63a9bb8d..4fe9d823 100644
--- a/signal.h
+++ b/signal.h
@@ -124,3 +124,8 @@ val sig_check(void);
#if HAVE_POSIX_SIGS
int sig_mask(int how, const sigset_t *set, sigset_t *oldset);
#endif
+
+#if HAVE_ITIMER
+val getitimer_wrap(val which);
+val setitimer_wrap(val which, val interval, val currval);
+#endif
diff --git a/txr.1 b/txr.1
index 176d665c..2f9efc99 100644
--- a/txr.1
+++ b/txr.1
@@ -14608,6 +14608,43 @@ It is a wrapper for the POSIX kill function.
If the <signal> argument is omitted, it defaults to the same value as sig-term.
+.SH UNIX ITIMERS
+
+Itimers can be used in combination with signal handling to execute asynchronous
+actions. Itimers deliver one-time or periodic signals. For more information,
+consult the POSIX specification.
+
+.SS Variables itimer-real, itimer-virtual and itimer-prof
+
+.TP
+Description:
+
+These variables correspond to the POSIX constants ITIMER_REAL, ITIMER_VIRTUAL
+and ITIMER_PROF. Thir values are suitable as the <timer> argument of
+the getitimer and setitimer functions.
+
+.SS Functions getitimer and setitimer
+
+.TP
+Syntax:
+
+ (getitimer <timer>)
+ (setitimer <timer> <interval> <value>)
+
+.TP
+Description
+
+The getitimer function returns the current value of the specified timer,
+which must be itimer-real, itimer-virtual or itimer-prof.
+
+The current value consists of a list of two integer values, which
+represents microseconds. The first value is the timer interval,
+and the second value is the timer's current value.
+
+The setitimer function also retrieves the specified timer, exactly
+as getitimer. In addition, it stores a new value in the timer,
+which is given by the two arguments, expressed in microseconds.
+
.SH UNIX SYSLOG
On platforms where a Unix-like syslog API is available, TXR exports this