summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--sysif.c29
-rw-r--r--sysif.h2
-rw-r--r--txr.138
3 files changed, 69 insertions, 0 deletions
diff --git a/sysif.c b/sysif.c
index 141b2908..78327b0c 100644
--- a/sysif.c
+++ b/sysif.c
@@ -98,6 +98,8 @@ val passwd_s, gecos_s, dir_s, shell_s;
val group_s, mem_s;
#endif
+static val at_exit_list;
+
static val errno_wrap(val newval)
{
val oldval = num(errno);
@@ -130,6 +132,27 @@ static val exit_wrap(val status)
return nil;
}
+val at_exit_call(val func)
+{
+ push(func, &at_exit_list);
+ return func;
+}
+
+val at_exit_do_not_call(val func)
+{
+ val old = at_exit_list;
+ at_exit_list = remq(func, old);
+ return tnil(old == at_exit_list);
+}
+
+static void at_exit_handler(void)
+{
+ val iter;
+
+ for (iter = at_exit_list; iter; iter = cdr(iter))
+ funcall(car(iter));
+}
+
static val abort_wrap(void)
{
abort();
@@ -1389,6 +1412,10 @@ static val fnmatch_wrap(val pattern, val string, val flags)
void sysif_init(void)
{
+ prot1(&at_exit_list);
+
+ atexit(at_exit_handler);
+
stat_s = intern(lit("stat"), user_package);
dev_k = intern(lit("dev"), keyword_package);
ino_k = intern(lit("ino"), keyword_package);
@@ -1444,6 +1471,8 @@ void sysif_init(void)
reg_fun(intern(lit("errno"), user_package), func_n1o(errno_wrap, 0));
reg_fun(intern(lit("exit"), user_package), func_n1(exit_wrap));
+ reg_fun(intern(lit("at-exit-call"), user_package), func_n1(at_exit_call));
+ reg_fun(intern(lit("at-exit-do-not-call"), user_package), func_n1(at_exit_do_not_call));
reg_fun(intern(lit("abort"), user_package), func_n0(abort_wrap));
reg_fun(intern(lit("usleep"), user_package), func_n1(usleep_wrap));
#if HAVE_UNISTD_H
diff --git a/sysif.h b/sysif.h
index 62712387..5b22ea5c 100644
--- a/sysif.h
+++ b/sysif.h
@@ -43,6 +43,8 @@ typedef long off_t;
#endif
val getenv_wrap(val name);
+val at_exit_call(val func);
+val at_exit_do_not_call(val func);
#if HAVE_FORK_STUFF
val exec_wrap(val file, val args_opt);
#endif
diff --git a/txr.1 b/txr.1
index 7dd08b90..cb16a7f5 100644
--- a/txr.1
+++ b/txr.1
@@ -36279,6 +36279,44 @@ signal, known in \*(TX as the
variable. Abnormal termination of the process is this signal's
default action.
+.coNP Functions @ at-exit-call and @ at-exit-do-not-call
+.synb
+.mets (at-exit-call << function )
+.mets (at-exit-do-not-call << function )
+.syne
+.desc
+The
+.code at-exit-call
+function registers
+.meta function
+to be called when the process terminates normally.
+Multiple functions can be registered, and the same function
+can be registered more than once. The registered
+functions are called in reverse order of their
+registrations.
+
+The
+.code at-exit-do-not-call
+function removes all previous
+.code at-exit-call
+registrations of
+.metn function .
+
+The
+.code at-exit-call
+function returns
+.metn function .
+
+The
+.code at-exit-do-not-call
+function returns
+.code t
+if it removed anything,
+.code nil
+if no registrations of
+.meta function
+were found.
+
.coNP Function @ usleep
.synb
.mets (usleep << usec )