John Levon wrote:
> Actually I've changed my mind, your code (modulo SIGPIPE issue) is
> fine, with one change: we should do the emergencyCleanup *first* so
> if the lyxerr *does* have problems, then we've at least made an
> effort to save the files ASAP.

Makes sense.

> I think it's fine to do such stuff in signal handlers when we're
> trying to recover what we can from a fatal situation.

Let's be careful here. Could you check the attached patch? If you're 
happy, I'll commit it.

-- 
Angus
Index: src/lyx_main.C
===================================================================
RCS file: /usr/local/lyx/cvsroot/lyx-devel/src/lyx_main.C,v
retrieving revision 1.183
diff -u -p -r1.183 lyx_main.C
--- src/lyx_main.C	25 Feb 2004 12:00:48 -0000	1.183
+++ src/lyx_main.C	22 Mar 2004 12:34:20 -0000
@@ -119,7 +119,7 @@ void LyX::exec(int & argc, char * argv[]
 	// Start the real execution loop.
 	singleton_->priv_exec(argc, argv);
 }
- 
+
 
 LyX & LyX::ref()
 {
@@ -258,6 +258,27 @@ extern "C" {
 
 static void error_handler(int err_sig)
 {
+	// Throw away any signals other than the first one received.
+	static sig_atomic_t handling_error = false;
+	if (handling_error)
+		return;
+	handling_error = true;
+
+	// We have received a signal indicating a fatal error, so
+	// try and save the data ASAP.
+	LyX::cref().emergencyCleanup();
+
+	// These lyxerr calls may or may not work:
+
+	// Signals are asynchronous, so the main program may be in a very
+	// fragile state when a signal is processed and thus while a signal
+	// handler function executes.
+	// In general, therefore, we should avoid performing any
+	// I/O operations or calling most library and system functions from
+	// signal handlers.
+
+	// This shouldn't matter here, however, as we've already invoked
+	// emergencyCleanup.
 	switch (err_sig) {
 	case SIGHUP:
 		lyxerr << "\nlyx: SIGHUP signal caught" << endl;
@@ -279,13 +300,6 @@ static void error_handler(int err_sig)
 	case SIGTERM:
 		// no comments
 		break;
-	case SIGPIPE:
-		// This will be received if lyx tries to write to a socket
-		// whose reading end was closed. It can safely be ignored,
-		// as in this case the ::write() system call will return -1
-		// and errno will be set to EPIPE
-		return;
-		//break;
 	}
 
 	// Deinstall the signal handlers
@@ -294,9 +308,6 @@ static void error_handler(int err_sig)
 	signal(SIGFPE, SIG_DFL);
 	signal(SIGSEGV, SIG_DFL);
 	signal(SIGTERM, SIG_DFL);
-	signal(SIGPIPE, SIG_DFL);
-
-	LyX::cref().emergencyCleanup();
 
 	lyxerr << "Bye." << endl;
 	if (err_sig!= SIGHUP &&
@@ -323,7 +334,7 @@ void LyX::init(bool gui)
 	signal(SIGSEGV, error_handler);
 	signal(SIGINT, error_handler);
 	signal(SIGTERM, error_handler);
-	signal(SIGPIPE, error_handler);
+	// SIGPIPE can be safely ignored.
 
 	bool const explicit_userdir = setLyxPaths();
 

Reply via email to