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();