From 8669e095b82960aabf939b7b64bd75fcc5ca5974 Mon Sep 17 00:00:00 2001
From: Per Cederqvist <ceder@lysator.liu.se>
Date: Fri, 11 Jul 2003 23:33:19 +0000
Subject: [PATCH] (sys_sig_owner): Added static qualifier. (use_sa_restart):
 New static variable. (sys_on_signal): Use SA_RESTART if use_sa_restart is
 true. (oop_sys_use_sa_restart): New function. (sys_on_fd): Require the
 callback to be non-NULL. (sys_on_time): Ditto. (sys_on_signal): Ditto.

Signed-off-by: Magnus Holmgren <magnus@kibibyte.se>
---
 oop.h |  6 ++++++
 sys.c | 11 ++++++++++-
 2 files changed, 16 insertions(+), 1 deletion(-)

diff --git a/oop.h b/oop.h
index d5d82ac..2ab7c67 100644
--- a/oop.h
+++ b/oop.h
@@ -85,6 +85,12 @@ void oop_sys_delete(oop_source_sys *);
 /* Get the event registration interface for a system event source. */
 oop_source *oop_sys_source(oop_source_sys *);
 
+/* Set SA_RESTART in the sa_flags field of struct sigaction, so that
+   syscalls are restarted.  This is a global setting, and the function
+   must be called before the first signal handler is registered.
+   There is no way to undo the setting.  */
+void oop_sys_use_sa_restart(void);
+
 /* ------------------------------------------------------------------------- */
 
 /* Helper for select-style asynchronous interfaces. */
diff --git a/sys.c b/sys.c
index 65e4143..e39aa4f 100644
--- a/sys.c
+++ b/sys.c
@@ -79,7 +79,8 @@ struct oop_source_sys {
 	sys_file *files;
 };
 
-struct oop_source_sys *sys_sig_owner[OOP_NUM_SIGNALS];
+static struct oop_source_sys *sys_sig_owner[OOP_NUM_SIGNALS];
+static int use_sa_restart = 0;
 
 static oop_source_sys *verify_source(oop_source *source) {
 	oop_source_sys *sys = (oop_source_sys *) source;
@@ -221,6 +222,7 @@ static void sys_on_signal(oop_source *source,int sig,
 #ifdef SA_NODEFER /* BSD/OS doesn't have this, for one. */
 		act.sa_flags &= ~SA_NODEFER;
 #endif
+		if (use_sa_restart) act.sa_flags |= SA_RESTART;
 		sigaction(sig,&act,NULL);
 	}
 }
@@ -280,6 +282,13 @@ oop_source_sys *oop_sys_new(void) {
 	return source;
 }
 
+void oop_sys_use_sa_restart(void) {
+	int i;
+	for (i = 0; i < OOP_NUM_SIGNALS; ++i)
+		assert(NULL == sys_sig_owner[i] && "signal handler already registered");
+	use_sa_restart = 1;
+}
+
 static void *sys_time_run(oop_source_sys *sys) {
 	void *ret = OOP_CONTINUE;
 	while (OOP_CONTINUE == ret && NULL != sys->time_run) {
-- 
GitLab