[m-rev.] for review: fix `mmc --make' signal bugs

Simon Taylor stayl at cs.mu.OZ.AU
Thu Nov 21 11:56:00 AEDT 2002


Estimated hours taken: 1.5
Branches: main, release

Fix bugs in the handling of signals with `mmc --make'.

compiler/process_util.m:
	Reset the signal handlers in the child to the defaults
	so that SIGTERM is not ignored.

	Don't infinitely loop if the child ignores SIGTERM.

runtime/mercury_signal.{c,h}:
	Add a function MR_init_signal_action() which initializes a
	MR_signal_action suitable for passing to MR_set_signal_action().

runtime/mercury_std.h:
	Fix a #include in the wrong place which caused MR_is_eintr
	to always fail.

Index: runtime/mercury_signal.c
===================================================================
RCS file: /home/mercury1/repository/mercury/runtime/mercury_signal.c,v
retrieving revision 1.14
diff -u -u -r1.14 mercury_signal.c
--- runtime/mercury_signal.c	12 Mar 2002 16:33:31 -0000	1.14
+++ runtime/mercury_signal.c	20 Nov 2002 16:15:58 -0000
@@ -76,10 +76,17 @@
 		MR_bool restart, const char *error_message)
 {
 	MR_signal_action	act;
+	MR_init_signal_action(&act, handler, need_info, restart);
+	MR_set_signal_action(sig, &act, error_message);
+}
 
+void
+MR_init_signal_action(MR_signal_action *act, MR_Code *handler,
+		MR_bool need_info, MR_bool restart)
+{
 #if	defined(MR_HAVE_SIGACTION)
 
-	act.sa_flags = (restart ? SA_RESTART : 0);
+	act->sa_flags = (restart ? SA_RESTART : 0);
 
 	if (need_info) {
 	/*
@@ -89,23 +96,21 @@
 	** handler will not be of the right type.
 	*/
 #if	!defined(MR_HAVE_SIGCONTEXT_STRUCT)
-		act.sa_flags |= SA_SIGINFO;
+		act->sa_flags |= SA_SIGINFO;
 #endif
 	}
-	if (sigemptyset(&act.sa_mask) != 0) {
+	if (sigemptyset(&(act->sa_mask)) != 0) {
 		MR_perror("cannot set clear signal mask");
 		exit(1);
 	}
 	errno = 0;
 
-	act.MR_SIGACTION_FIELD = handler;
+	act->MR_SIGACTION_FIELD = handler;
 #else /* not MR_HAVE_SIGACTION */
 
 	act = handler;
 
 #endif /* not MR_HAVE_SIGACTION */
-
-	MR_set_signal_action(sig, &act, error_message);
 }
 
 void
Index: runtime/mercury_signal.h
===================================================================
RCS file: /home/mercury1/repository/mercury/runtime/mercury_signal.h,v
retrieving revision 1.11
diff -u -u -r1.11 mercury_signal.h
--- runtime/mercury_signal.h	12 Mar 2002 16:33:31 -0000	1.11
+++ runtime/mercury_signal.h	20 Nov 2002 16:15:45 -0000
@@ -78,6 +78,14 @@
 	MR_bool need_info, const char * error_message);
 
 	/*
+	** As above, but initialize a signal action suitable to be
+	** passed to MR_set_signal_action rather than setting a
+	** signal handler for a signal.
+	*/
+extern void MR_init_signal_action(MR_signal_action* act, MR_Code *handler,
+	MR_bool need_info, MR_bool should_restart_system_call);
+
+	/*
 	** Get the current action for the given signal.
 	** If the action cannot be retrieved, it aborts with the given
 	** error message.
Index: runtime/mercury_std.h
===================================================================
RCS file: /home/mercury1/repository/mercury/runtime/mercury_std.h,v
retrieving revision 1.24
diff -u -u -r1.24 mercury_std.h
--- runtime/mercury_std.h	9 Nov 2002 13:18:39 -0000	1.24
+++ runtime/mercury_std.h	20 Nov 2002 14:43:06 -0000
@@ -14,10 +14,10 @@
 
 #include <stdlib.h>	/* for size_t */
 #include <assert.h>	/* for assert() */
+#include <errno.h>	/* for EINTR */
 #ifndef IN_GCC
   #include <ctype.h>	/* for isalnum(), etc. */
 #else
-#include <errno.h>
   /*
   ** When building compiler/gcc.m, we #include GCC back-end
   ** header files that include libiberty's "safe-ctype.h",
Index: compiler/process_util.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/process_util.m,v
retrieving revision 1.5
diff -u -u -r1.5 process_util.m
--- compiler/process_util.m	9 Nov 2002 13:18:37 -0000	1.5
+++ compiler/process_util.m	21 Nov 2002 00:46:43 -0000
@@ -193,7 +193,7 @@
 
 	MR_incr_hp_msg(SigintHandler,
 		MR_bytes_to_words(sizeof(MR_signal_action)),
-		MR_PROC_LABEL, ""make.util.signal_action/0"");
+		MR_PROC_LABEL, ""libs.process_util.signal_action/0"");
 
 	/*
 	** mdb sets up a SIGINT handler, so we should restore
@@ -240,6 +240,41 @@
 #endif
 }").
 
+	% Restore all signal handlers to default values in the child
+	% so that the child will be killed by the signals the parent
+	% is catching.
+:- pred setup_child_signal_handlers(io__state::di, io__state::uo) is det.
+
+setup_child_signal_handlers -->
+	( { SIG_DFL = sig_dfl } ->
+		restore_signal_handlers(yes(SIG_DFL))
+	;
+		[]
+	).
+
+:- func sig_dfl = signal_action is semidet.
+
+sig_dfl = SIG_DFL :-
+	( have_signal_handlers(1) ->
+		SIG_DFL = sig_dfl_2
+	;
+		fail
+	).
+
+:- func sig_dfl_2 = signal_action.
+
+sig_dfl_2 = (_::out) :- error("process_util__sig_dfl_2 called").
+
+:- pragma foreign_proc("C", sig_dfl_2 = (Result::out),
+		[will_not_call_mercury, promise_pure],
+"
+	MR_incr_hp_msg(Result,
+		MR_bytes_to_words(sizeof(MR_signal_action)),
+		MR_PROC_LABEL, ""libs.process_util.signal_action/0"");
+	MR_init_signal_action((MR_signal_action *) Result,
+		SIG_DFL, MR_FALSE, MR_TRUE);
+").
+
 :- pred check_for_signal(int::out, int::out,
 		io__state::di, io__state::uo) is det.
 
@@ -329,7 +364,7 @@
 	} else if (child_pid == 0) {	/* child */
 		MR_Integer exit_status;
 
-		MC_call_io_pred(Pred, &exit_status);
+		MC_call_child_process_io_pred(Pred, &exit_status);
 		exit(exit_status);
 	} else {			/* parent */
 		int child_status;
@@ -365,6 +400,7 @@
 				** to be ignored on some systems (e.g. Linux).
 				*/
 				kill(child_pid, SIGTERM);
+				break;
 			    }
 			} else {
 			    /*
@@ -398,12 +434,14 @@
 #endif /* ! MC_CAN_FORK */
 }").
 
-	% call_io_pred(P, ExitStatus).
-:- pred call_io_pred(io_pred::in(io_pred), int::out,
+	% call_child_process_io_pred(P, ExitStatus).
+:- pred call_child_process_io_pred(io_pred::in(io_pred), int::out,
 		io__state::di, io__state::uo) is det.
-:- pragma export(call_io_pred(in(io_pred), out, di, uo), "MC_call_io_pred").
+:- pragma export(call_child_process_io_pred(in(io_pred), out, di, uo),
+		"MC_call_child_process_io_pred").
 
-call_io_pred(P, Status) -->
+call_child_process_io_pred(P, Status) -->
+	setup_child_signal_handlers,
 	P(Success),
 	{ Status = ( Success = yes -> 0 ; 1 ) }.
 
--------------------------------------------------------------------------
mercury-reviews mailing list
post:  mercury-reviews at cs.mu.oz.au
administrative address: owner-mercury-reviews at cs.mu.oz.au
unsubscribe: Address: mercury-reviews-request at cs.mu.oz.au Message: unsubscribe
subscribe:   Address: mercury-reviews-request at cs.mu.oz.au Message: subscribe
--------------------------------------------------------------------------



More information about the reviews mailing list