for review: SA_RESTART fix.

Tyson Dowd trd at cs.mu.OZ.AU
Thu May 21 17:33:14 AEST 1998


Hi,

Here's the fix for SA_RESTART.

===================================================================


Estimated hours taken: 1

Be more forgiving of a missing SA_RESTART flag for sigaction.

configure.in:
	If using sigaction, don't require SA_RESTART to be available.
	If SA_RESTART is unavailable, warn about it.

runtime/mercury_signal.c:
	Handle a missing SA_RESTART or SA_SIGINFO.


Index: configure.in
===================================================================
RCS file: /home/staff/zs/imp/mercury/configure.in,v
retrieving revision 1.125
diff -u -r1.125 configure.in
--- configure.in	1998/03/30 05:22:15	1.125
+++ configure.in	1998/05/21 05:34:26
@@ -292,7 +292,7 @@
 
 	int main() {
 		struct sigaction act;
-		act.sa_flags = SA_SIGINFO | SA_RESTART;
+		act.sa_flags = SA_SIGINFO;
 		act.sa_sigaction = handler;
 		if (sigemptyset(&act.sa_mask) != 0)
 			exit(1);
@@ -324,6 +324,55 @@
 	fi
 fi
 #
+# see whether SA_RESTART is defined
+# (we use it if possible, if not available warn about it, because
+# it could cause problems with signal handling).
+#
+AC_MSG_CHECKING(for SA_RESTART)
+AC_CACHE_VAL(mercury_cv_sa_restart,
+AC_TRY_RUN([
+
+#include <signal.h>
+#include <stdlib.h>
+
+#define FAULT_ADDRESS ((int *)112)
+
+extern void handler(int signum, siginfo_t *info, void *context);
+
+int main() {
+	struct sigaction act;
+	act.sa_flags = SA_SIGINFO | SA_RESTART;
+	act.sa_sigaction = handler;
+	if (sigemptyset(&act.sa_mask) != 0)
+		exit(1);
+	if (sigaction(SIGSEGV, &act, NULL) != 0)
+		exit(1);
+	/* provoke a SIGSEGV */
+	(*FAULT_ADDRESS)++;
+	exit(1);
+}
+
+void handler(int signum, siginfo_t *info, void *context) {
+	if (signum == SIGSEGV &&
+	    info->si_signo == SIGSEGV &&
+	    info->si_code > 0 &&
+	    (int *)info->si_addr == FAULT_ADDRESS)
+	{
+		exit(0);
+	} else {
+		exit(1);
+	}
+}],
+[mercury_cv_sa_restart=yes],
+[mercury_cv_sa_restart=no],
+[mercury_cv_sa_restart=no]))
+AC_MSG_RESULT($mercury_cv_sa_restart)
+if test $mercury_cv_sa_restart = yes; then
+	AC_DEFINE(HAVE_SIGINFO)
+else
+	AC_MSG_WARN("using sigaction without SA_RESTART")
+fi
+#
 # check the basics of sigcontext_struct
 #
 AC_MSG_CHECKING(for working \`sigcontext_struct')
@@ -436,7 +485,7 @@
 	extern void handler(int signum, siginfo_t *info, void *context);
 	int main() {
 		struct sigaction act;
-		act.sa_flags = SA_SIGINFO | SA_RESTART;
+		act.sa_flags = SA_SIGINFO;
 		act.$mercury_cv_sigaction_field = handler;
 		if (sigemptyset(&act.sa_mask) != 0)
 			exit(1);
@@ -489,7 +538,7 @@
 		extern void handler(int signum, siginfo_t *info, void *context);
 		int main() {
 			struct sigaction act;
-			act.sa_flags = SA_SIGINFO | SA_RESTART;
+			act.sa_flags = SA_SIGINFO;
 			act.$mercury_cv_sigaction_field = handler;
 			if (sigemptyset(&act.sa_mask) != 0)
 				exit(1);
@@ -525,7 +574,7 @@
 		extern void handler(int signum, siginfo_t *info, void *context);
 		int main() {
 			struct sigaction act;
-			act.sa_flags = SA_SIGINFO | SA_RESTART;
+			act.sa_flags = SA_SIGINFO;
 			act.$mercury_cv_sigaction_field = handler;
 			if (sigemptyset(&act.sa_mask) != 0)
 				exit(1);
@@ -559,7 +608,7 @@
 		extern void handler(int signum, siginfo_t *info, void *context);
 		int main() {
 			struct sigaction act;
-			act.sa_flags = SA_SIGINFO | SA_RESTART;
+			act.sa_flags = SA_SIGINFO;
 			act.$mercury_cv_sigaction_field = handler;
 			if (sigemptyset(&act.sa_mask) != 0)
 				exit(1);
Index: runtime/mercury_signal.c
===================================================================
RCS file: /home/staff/zs/imp/mercury/runtime/mercury_signal.c,v
retrieving revision 1.4
diff -u -r1.4 mercury_signal.c
--- mercury_signal.c	1998/05/18 08:41:33	1.4
+++ mercury_signal.c	1998/05/21 05:51:29
@@ -66,6 +66,19 @@
 
 /*---------------------------------------------------------------------------*/
 
+/*
+** If we don't have SA_RESTART or SA_SIGINFO, defined them as 0.
+** It would be nice to have them, but it is still better to use
+** sigaction without SA_RESTART or SA_SIGINFO than to use signal.
+*/
+#if	!defined(SA_RESTART)
+  #define	SA_RESTART 0
+#endif
+
+#if	!defined(SA_SIGINFO)
+  #define	SA_SIGINFO 0
+#endif
+
 void
 MR_setup_signal(int sig, Code *handler, bool need_info, 
 		const char *error_message)
@@ -75,11 +88,7 @@
 	struct sigaction	act;
 
 	if (need_info) {
-  #if 	defined(SA_SIGINFO)
 		act.sa_flags = SA_SIGINFO | SA_RESTART;
-  #else
-		act.sa_flags = SA_RESTART;
-  #endif
 	} else {
 		act.sa_flags = SA_RESTART;
 	}


-- 
       Tyson Dowd           # There isn't any reason why Linux can't be
                            # implemented as an enterprise computing solution.
     trd at cs.mu.oz.au        # Find out what you've been missing while you've
http://www.cs.mu.oz.au/~trd # been rebooting Windows NT. -- InfoWorld, 1998.



More information about the developers mailing list