From 86e4b1ef653729fa3129ac44ee8771509ee4ba1c Mon Sep 17 00:00:00 2001 From: Michael Natterer Date: Wed, 10 May 2000 21:21:23 +0000 Subject: [PATCH] Another try to get the signal/dead child recovery stuff right. 2000-05-10 Michael Natterer Another try to get the signal/dead child recovery stuff right. Could the brave signal crew (TM) (Austin, Garry, Raphael, Tim) please do bad tests to the new code? I removed all strange constants (SA_NODEFER etc.) and used only glib and POSIX stuff. * app/main.c * libgimp/gimp.c: - Call gimp_signal_private() with no flags to enforce a proper sigaction() behaviour (block signals while handler is active). - Removed the reentrancy guards from the handlers. - Renamed the handlers. - Ignore SIGPIPE in the app and in plugins. - Re-introduced the SIGCHLD handler because it should work now. Also added a SIGCHLD handler to libgimp/gimp.c. * app/errors.c * libgimp/gimp.c: in the signal handler, unblock all signals with sigprocmask() before calling g_on_error_query() because gdb otherwise inherits the blocked signals and does nothing. Wrapped the statements with "if (TRUE) { }" blocks so it's easy to make the stack trace a command line option. * app/plug_in.c * libgimp/gimp.c: listen for G_IO_ERR and G_IO_HUP on the read channels. In the app, pop up an error message and clean up the plugin. In plugins, clean up and exit. * libgimp/gimpwire.c: removed the "plug-in chrashed?" message and print the program's name with all error messages. * plug-ins/helpbrowser/helpbrowser.c: typo. --- ChangeLog | 35 +++++++ app/actions/plug-in-commands.c | 69 +++++++++----- app/errors.c | 17 +++- app/gui/plug-in-commands.c | 69 +++++++++----- app/gui/plug-in-menus.c | 69 +++++++++----- app/main.c | 119 +++++++++++------------ app/menus/plug-in-menus.c | 69 +++++++++----- app/plug-in/gimpplugin-message.c | 69 +++++++++----- app/plug-in/gimpplugin-progress.c | 69 +++++++++----- app/plug-in/gimpplugin.c | 69 +++++++++----- app/plug-in/gimppluginmanager-call.c | 69 +++++++++----- app/plug-in/gimppluginmanager-run.c | 69 +++++++++----- app/plug-in/gimppluginmanager.c | 69 +++++++++----- app/plug-in/gimppluginshm.c | 69 +++++++++----- app/plug-in/plug-in-def.c | 69 +++++++++----- app/plug-in/plug-in-message.c | 69 +++++++++----- app/plug-in/plug-in-params.c | 69 +++++++++----- app/plug-in/plug-in-progress.c | 69 +++++++++----- app/plug-in/plug-in-run.c | 69 +++++++++----- app/plug-in/plug-in-shm.c | 69 +++++++++----- app/plug-in/plug-in.c | 69 +++++++++----- app/plug-in/plug-ins.c | 69 +++++++++----- app/plug_in.c | 69 +++++++++----- libgimp/gimp.c | 135 +++++++++++++++++---------- libgimp/gimpwire.c | 10 +- libgimpbase/gimpwire.c | 10 +- plug-ins/helpbrowser/helpbrowser.c | 2 +- 27 files changed, 1100 insertions(+), 608 deletions(-) diff --git a/ChangeLog b/ChangeLog index 6fc9525062..73d0eff0c3 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,38 @@ +2000-05-10 Michael Natterer + + Another try to get the signal/dead child recovery stuff right. + + Could the brave signal crew (TM) (Austin, Garry, Raphael, Tim) + please do bad tests to the new code? I removed all strange + constants (SA_NODEFER etc.) and used only glib and POSIX stuff. + + * app/main.c + * libgimp/gimp.c: + - Call gimp_signal_private() with no flags to enforce a proper + sigaction() behaviour (block signals while handler is active). + - Removed the reentrancy guards from the handlers. + - Renamed the handlers. + - Ignore SIGPIPE in the app and in plugins. + - Re-introduced the SIGCHLD handler because it should work + now. Also added a SIGCHLD handler to libgimp/gimp.c. + + * app/errors.c + * libgimp/gimp.c: in the signal handler, unblock all signals + with sigprocmask() before calling g_on_error_query() because + gdb otherwise inherits the blocked signals and does nothing. + Wrapped the statements with "if (TRUE) { }" blocks so it's + easy to make the stack trace a command line option. + + * app/plug_in.c + * libgimp/gimp.c: listen for G_IO_ERR and G_IO_HUP on the read + channels. In the app, pop up an error message and clean up the + plugin. In plugins, clean up and exit. + + * libgimp/gimpwire.c: removed the "plug-in chrashed?" message + and print the program's name with all error messages. + + * plug-ins/helpbrowser/helpbrowser.c: typo. + 2000-05-10 Tor Lillqvist * README.win32: Clarifications. diff --git a/app/actions/plug-in-commands.c b/app/actions/plug-in-commands.c index ca5ffee17b..7cd04b9090 100644 --- a/app/actions/plug-in-commands.c +++ b/app/actions/plug-in-commands.c @@ -338,13 +338,11 @@ plug_in_init (void) } /* insert the proc defs */ - tmp = gimprc_proc_defs; - while (tmp) + for (tmp = gimprc_proc_defs; tmp; tmp = g_slist_next (tmp)) { proc_def = g_new (PlugInProcDef, 1); *proc_def = *((PlugInProcDef*) tmp->data); plug_in_proc_def_insert (proc_def, NULL); - tmp = tmp->next; } tmp = plug_in_defs; @@ -408,11 +406,9 @@ plug_in_init (void) g_print ("\n"); /* free up stuff */ - tmp = plug_in_defs; - while (tmp) + for (tmp = plug_in_defs; tmp; tmp = g_slist_next (tmp)) { plug_in_def = tmp->data; - tmp = tmp->next; plug_in_def_free (plug_in_def, FALSE); } @@ -1033,10 +1029,11 @@ plug_in_open (PlugIn *plug_in) if (!plug_in->synchronous) { - plug_in->input_id = g_io_add_watch (plug_in->my_read, - G_IO_IN | G_IO_PRI, - plug_in_recv_message, - plug_in); + plug_in->input_id = + g_io_add_watch (plug_in->my_read, + G_IO_IN | G_IO_PRI | G_IO_ERR | G_IO_HUP, + plug_in_recv_message, + plug_in); open_plug_ins = g_slist_prepend (open_plug_ins, plug_in); } @@ -1176,12 +1173,10 @@ plug_in_close (PlugIn *plug_in, GSList *list; PlugInProcDef *proc_def; - list = plug_in->temp_proc_defs; - while (list) + for (list = plug_in->temp_proc_defs; list; list = g_slist_next (list)) { proc_def = (PlugInProcDef *) list->data; plug_in_proc_def_remove (proc_def); - list = list->next; } g_slist_free (plug_in->temp_proc_defs); @@ -1189,9 +1184,9 @@ plug_in_close (PlugIn *plug_in, } /* Close any dialogs that this plugin might have opened */ - brushes_check_dialogs(); - patterns_check_dialogs(); - gradients_check_dialogs(); + brushes_check_dialogs (); + patterns_check_dialogs (); + gradients_check_dialogs (); open_plug_ins = g_slist_remove (open_plug_ins, plug_in); } @@ -1405,25 +1400,51 @@ plug_in_recv_message (GIOChannel *channel, GIOCondition cond, gpointer data) { - WireMessage msg; + gboolean got_message = FALSE; + + if ((PlugIn *) data != current_plug_in) + plug_in_push ((PlugIn *) data); - plug_in_push ((PlugIn*) data); if (current_readchannel == NULL) return TRUE; - memset (&msg, 0, sizeof (WireMessage)); - if (!wire_read_msg (current_readchannel, &msg)) - plug_in_close (current_plug_in, TRUE); - else + if (cond & (G_IO_IN | G_IO_PRI)) { - plug_in_handle_message (&msg); - wire_destroy (&msg); + WireMessage msg; + + memset (&msg, 0, sizeof (WireMessage)); + + if (!wire_read_msg (current_readchannel, &msg)) + { + plug_in_close (current_plug_in, TRUE); + } + else + { + plug_in_handle_message (&msg); + wire_destroy (&msg); + got_message = TRUE; + } + } + if (cond & (G_IO_ERR | G_IO_HUP)) + { + if (current_plug_in->open) + { + plug_in_close (current_plug_in, TRUE); + } + } + + if (!got_message) + g_message (_("Plug-In crashed: %s\n(%s)"), + g_basename (current_plug_in->args[0]), + current_plug_in->args[0]); + if (!current_plug_in->open) plug_in_destroy (current_plug_in); else plug_in_pop (); + return TRUE; } diff --git a/app/errors.c b/app/errors.c index 5271adfb01..aee6cf4785 100644 --- a/app/errors.c +++ b/app/errors.c @@ -78,7 +78,14 @@ gimp_fatal_error (gchar *fmt, ...) g_print ("%s: fatal error: %s\n", prog_name, g_strdup_vprintf (fmt, args)); va_end (args); - g_on_error_query (prog_name); + if (TRUE) + { + sigset_t sigset; + + sigemptyset (&sigset); + sigprocmask (SIG_SETMASK, &sigset, NULL); + g_on_error_query (prog_name); + } #else /* g_on_error_query doesn't do anything reasonable on Win32. */ va_list args; @@ -106,7 +113,13 @@ gimp_terminate (gchar *fmt, ...) va_end (args); if (use_debug_handler) - g_on_error_query (prog_name); + { + sigset_t sigset; + + sigemptyset (&sigset); + sigprocmask (SIG_SETMASK, &sigset, NULL); + g_on_error_query (prog_name); + } #else /* g_on_error_query doesn't do anything reasonable on Win32. */ va_list args; diff --git a/app/gui/plug-in-commands.c b/app/gui/plug-in-commands.c index ca5ffee17b..7cd04b9090 100644 --- a/app/gui/plug-in-commands.c +++ b/app/gui/plug-in-commands.c @@ -338,13 +338,11 @@ plug_in_init (void) } /* insert the proc defs */ - tmp = gimprc_proc_defs; - while (tmp) + for (tmp = gimprc_proc_defs; tmp; tmp = g_slist_next (tmp)) { proc_def = g_new (PlugInProcDef, 1); *proc_def = *((PlugInProcDef*) tmp->data); plug_in_proc_def_insert (proc_def, NULL); - tmp = tmp->next; } tmp = plug_in_defs; @@ -408,11 +406,9 @@ plug_in_init (void) g_print ("\n"); /* free up stuff */ - tmp = plug_in_defs; - while (tmp) + for (tmp = plug_in_defs; tmp; tmp = g_slist_next (tmp)) { plug_in_def = tmp->data; - tmp = tmp->next; plug_in_def_free (plug_in_def, FALSE); } @@ -1033,10 +1029,11 @@ plug_in_open (PlugIn *plug_in) if (!plug_in->synchronous) { - plug_in->input_id = g_io_add_watch (plug_in->my_read, - G_IO_IN | G_IO_PRI, - plug_in_recv_message, - plug_in); + plug_in->input_id = + g_io_add_watch (plug_in->my_read, + G_IO_IN | G_IO_PRI | G_IO_ERR | G_IO_HUP, + plug_in_recv_message, + plug_in); open_plug_ins = g_slist_prepend (open_plug_ins, plug_in); } @@ -1176,12 +1173,10 @@ plug_in_close (PlugIn *plug_in, GSList *list; PlugInProcDef *proc_def; - list = plug_in->temp_proc_defs; - while (list) + for (list = plug_in->temp_proc_defs; list; list = g_slist_next (list)) { proc_def = (PlugInProcDef *) list->data; plug_in_proc_def_remove (proc_def); - list = list->next; } g_slist_free (plug_in->temp_proc_defs); @@ -1189,9 +1184,9 @@ plug_in_close (PlugIn *plug_in, } /* Close any dialogs that this plugin might have opened */ - brushes_check_dialogs(); - patterns_check_dialogs(); - gradients_check_dialogs(); + brushes_check_dialogs (); + patterns_check_dialogs (); + gradients_check_dialogs (); open_plug_ins = g_slist_remove (open_plug_ins, plug_in); } @@ -1405,25 +1400,51 @@ plug_in_recv_message (GIOChannel *channel, GIOCondition cond, gpointer data) { - WireMessage msg; + gboolean got_message = FALSE; + + if ((PlugIn *) data != current_plug_in) + plug_in_push ((PlugIn *) data); - plug_in_push ((PlugIn*) data); if (current_readchannel == NULL) return TRUE; - memset (&msg, 0, sizeof (WireMessage)); - if (!wire_read_msg (current_readchannel, &msg)) - plug_in_close (current_plug_in, TRUE); - else + if (cond & (G_IO_IN | G_IO_PRI)) { - plug_in_handle_message (&msg); - wire_destroy (&msg); + WireMessage msg; + + memset (&msg, 0, sizeof (WireMessage)); + + if (!wire_read_msg (current_readchannel, &msg)) + { + plug_in_close (current_plug_in, TRUE); + } + else + { + plug_in_handle_message (&msg); + wire_destroy (&msg); + got_message = TRUE; + } + } + if (cond & (G_IO_ERR | G_IO_HUP)) + { + if (current_plug_in->open) + { + plug_in_close (current_plug_in, TRUE); + } + } + + if (!got_message) + g_message (_("Plug-In crashed: %s\n(%s)"), + g_basename (current_plug_in->args[0]), + current_plug_in->args[0]); + if (!current_plug_in->open) plug_in_destroy (current_plug_in); else plug_in_pop (); + return TRUE; } diff --git a/app/gui/plug-in-menus.c b/app/gui/plug-in-menus.c index ca5ffee17b..7cd04b9090 100644 --- a/app/gui/plug-in-menus.c +++ b/app/gui/plug-in-menus.c @@ -338,13 +338,11 @@ plug_in_init (void) } /* insert the proc defs */ - tmp = gimprc_proc_defs; - while (tmp) + for (tmp = gimprc_proc_defs; tmp; tmp = g_slist_next (tmp)) { proc_def = g_new (PlugInProcDef, 1); *proc_def = *((PlugInProcDef*) tmp->data); plug_in_proc_def_insert (proc_def, NULL); - tmp = tmp->next; } tmp = plug_in_defs; @@ -408,11 +406,9 @@ plug_in_init (void) g_print ("\n"); /* free up stuff */ - tmp = plug_in_defs; - while (tmp) + for (tmp = plug_in_defs; tmp; tmp = g_slist_next (tmp)) { plug_in_def = tmp->data; - tmp = tmp->next; plug_in_def_free (plug_in_def, FALSE); } @@ -1033,10 +1029,11 @@ plug_in_open (PlugIn *plug_in) if (!plug_in->synchronous) { - plug_in->input_id = g_io_add_watch (plug_in->my_read, - G_IO_IN | G_IO_PRI, - plug_in_recv_message, - plug_in); + plug_in->input_id = + g_io_add_watch (plug_in->my_read, + G_IO_IN | G_IO_PRI | G_IO_ERR | G_IO_HUP, + plug_in_recv_message, + plug_in); open_plug_ins = g_slist_prepend (open_plug_ins, plug_in); } @@ -1176,12 +1173,10 @@ plug_in_close (PlugIn *plug_in, GSList *list; PlugInProcDef *proc_def; - list = plug_in->temp_proc_defs; - while (list) + for (list = plug_in->temp_proc_defs; list; list = g_slist_next (list)) { proc_def = (PlugInProcDef *) list->data; plug_in_proc_def_remove (proc_def); - list = list->next; } g_slist_free (plug_in->temp_proc_defs); @@ -1189,9 +1184,9 @@ plug_in_close (PlugIn *plug_in, } /* Close any dialogs that this plugin might have opened */ - brushes_check_dialogs(); - patterns_check_dialogs(); - gradients_check_dialogs(); + brushes_check_dialogs (); + patterns_check_dialogs (); + gradients_check_dialogs (); open_plug_ins = g_slist_remove (open_plug_ins, plug_in); } @@ -1405,25 +1400,51 @@ plug_in_recv_message (GIOChannel *channel, GIOCondition cond, gpointer data) { - WireMessage msg; + gboolean got_message = FALSE; + + if ((PlugIn *) data != current_plug_in) + plug_in_push ((PlugIn *) data); - plug_in_push ((PlugIn*) data); if (current_readchannel == NULL) return TRUE; - memset (&msg, 0, sizeof (WireMessage)); - if (!wire_read_msg (current_readchannel, &msg)) - plug_in_close (current_plug_in, TRUE); - else + if (cond & (G_IO_IN | G_IO_PRI)) { - plug_in_handle_message (&msg); - wire_destroy (&msg); + WireMessage msg; + + memset (&msg, 0, sizeof (WireMessage)); + + if (!wire_read_msg (current_readchannel, &msg)) + { + plug_in_close (current_plug_in, TRUE); + } + else + { + plug_in_handle_message (&msg); + wire_destroy (&msg); + got_message = TRUE; + } + } + if (cond & (G_IO_ERR | G_IO_HUP)) + { + if (current_plug_in->open) + { + plug_in_close (current_plug_in, TRUE); + } + } + + if (!got_message) + g_message (_("Plug-In crashed: %s\n(%s)"), + g_basename (current_plug_in->args[0]), + current_plug_in->args[0]); + if (!current_plug_in->open) plug_in_destroy (current_plug_in); else plug_in_pop (); + return TRUE; } diff --git a/app/main.c b/app/main.c index d0db4172e1..bd428bd016 100644 --- a/app/main.c +++ b/app/main.c @@ -54,14 +54,15 @@ #ifdef G_OS_WIN32 #include #else -static void on_signal (gint); +static void gimp_sigfatal_handler (gint sig_num); +static void gimp_sigchld_handler (gint sig_num); #endif -static void init (void); -static void on_error (const gchar *domain, - GLogLevelFlags flags, - const gchar *msg, - gpointer user_data); +static void init (void); +static void gimp_error_handler (const gchar *domain, + GLogLevelFlags flags, + const gchar *msg, + gpointer user_data); /* GLOBAL data */ gboolean no_interface = FALSE; @@ -327,37 +328,36 @@ main (int argc, /* No use catching these on Win32, the user won't get any * stack trace from glib anyhow. It's better to let Windows inform - * about the program error, and offer debugging (if the use + * about the program error, and offer debugging (if the user * has installed MSVC or some other compiler that knows how to * install itself as a handler for program errors). */ - /* Handle some signals */ + /* Handle fatal signals */ - gimp_signal_private (SIGHUP, on_signal, SA_RESETHAND | SA_NODEFER); - gimp_signal_private (SIGINT, on_signal, SA_RESETHAND | SA_NODEFER); - gimp_signal_private (SIGQUIT, on_signal, SA_RESETHAND | SA_NODEFER); - gimp_signal_private (SIGABRT, on_signal, SA_RESETHAND | SA_NODEFER); - gimp_signal_private (SIGBUS, on_signal, SA_RESETHAND | SA_NODEFER); - gimp_signal_private (SIGSEGV, on_signal, SA_RESETHAND | SA_NODEFER); - gimp_signal_private (SIGPIPE, on_signal, SA_RESETHAND | SA_NODEFER); - gimp_signal_private (SIGTERM, on_signal, SA_RESETHAND | SA_NODEFER); - gimp_signal_private (SIGFPE, on_signal, SA_RESETHAND | SA_NODEFER); + gimp_signal_private (SIGHUP, gimp_sigfatal_handler, 0); + gimp_signal_private (SIGINT, gimp_sigfatal_handler, 0); + gimp_signal_private (SIGQUIT, gimp_sigfatal_handler, 0); + gimp_signal_private (SIGABRT, gimp_sigfatal_handler, 0); + gimp_signal_private (SIGBUS, gimp_sigfatal_handler, 0); + gimp_signal_private (SIGSEGV, gimp_sigfatal_handler, 0); + gimp_signal_private (SIGTERM, gimp_sigfatal_handler, 0); + gimp_signal_private (SIGFPE, gimp_sigfatal_handler, 0); -#ifndef __EMX__ /* OS/2 may not support SA_NOCLDSTOP -GRO */ + /* Ignore SIGPIPE because plug_in.c handles broken pipes */ - /* Disable child exit notification. This doesn't just block */ - /* receipt of SIGCHLD, it in fact completely disables the */ - /* generation of the signal by the OS. This behavior is */ - /* mandated by POSIX.1. */ + gimp_signal_private (SIGPIPE, SIG_IGN, 0); - gimp_signal_private (SIGCHLD, NULL, SA_NOCLDSTOP); + /* Collect dead children */ -#endif -#endif + gimp_signal_private (SIGCHLD, gimp_sigchld_handler, SA_RESTART); - g_log_set_handler (NULL, G_LOG_LEVEL_ERROR | G_LOG_FLAG_FATAL, - on_error, NULL); +#endif /* G_OS_WIN32 */ + + g_log_set_handler (NULL, + G_LOG_LEVEL_ERROR | G_LOG_FLAG_FATAL, + gimp_error_handler, + NULL); /* Keep the command line arguments--for use in gimp_init */ gimp_argc = argc - 1; @@ -403,10 +403,10 @@ init (void) static void -on_error (const gchar *domain, - GLogLevelFlags flags, - const gchar *msg, - gpointer user_data) +gimp_error_handler (const gchar *domain, + GLogLevelFlags flags, + const gchar *msg, + gpointer user_data) { gimp_fatal_error ("%s", msg); } @@ -416,57 +416,42 @@ on_error (const gchar *domain, /* gimp core signal handler for fatal signals */ static void -on_signal (gint sig_num) +gimp_sigfatal_handler (gint sig_num) { - static gboolean caught_fatal_sig = FALSE; - - if (caught_fatal_sig) - kill (getpid (), sig_num); - caught_fatal_sig = TRUE; - switch (sig_num) { - case SIGHUP: - gimp_terminate ("sighup caught"); - break; - case SIGINT: - gimp_terminate ("sigint caught"); - break; - case SIGQUIT: - gimp_terminate ("sigquit caught"); - break; - case SIGABRT: - gimp_terminate ("sigabrt caught"); + case SIGTERM: + gimp_terminate (g_strsignal (sig_num)); break; case SIGBUS: - gimp_fatal_error ("sigbus caught"); - break; - case SIGSEGV: - gimp_fatal_error ("sigsegv caught"); - break; - - case SIGPIPE: - gimp_terminate ("sigpipe caught"); - break; - - case SIGTERM: - gimp_terminate ("sigterm caught"); - break; - case SIGFPE: - gimp_fatal_error ("sigfpe caught"); - break; - default: - gimp_fatal_error ("unknown signal"); + gimp_fatal_error (g_strsignal (sig_num)); break; } } +/* gimp core signal handler for death-of-child signals */ + +static void +gimp_sigchld_handler (gint sig_num) +{ + gint pid; + gint status; + + while (TRUE) + { + pid = waitpid (WAIT_ANY, &status, WNOHANG); + + if (pid <= 0) + break; + } +} + #endif /* !G_OS_WIN32 */ diff --git a/app/menus/plug-in-menus.c b/app/menus/plug-in-menus.c index ca5ffee17b..7cd04b9090 100644 --- a/app/menus/plug-in-menus.c +++ b/app/menus/plug-in-menus.c @@ -338,13 +338,11 @@ plug_in_init (void) } /* insert the proc defs */ - tmp = gimprc_proc_defs; - while (tmp) + for (tmp = gimprc_proc_defs; tmp; tmp = g_slist_next (tmp)) { proc_def = g_new (PlugInProcDef, 1); *proc_def = *((PlugInProcDef*) tmp->data); plug_in_proc_def_insert (proc_def, NULL); - tmp = tmp->next; } tmp = plug_in_defs; @@ -408,11 +406,9 @@ plug_in_init (void) g_print ("\n"); /* free up stuff */ - tmp = plug_in_defs; - while (tmp) + for (tmp = plug_in_defs; tmp; tmp = g_slist_next (tmp)) { plug_in_def = tmp->data; - tmp = tmp->next; plug_in_def_free (plug_in_def, FALSE); } @@ -1033,10 +1029,11 @@ plug_in_open (PlugIn *plug_in) if (!plug_in->synchronous) { - plug_in->input_id = g_io_add_watch (plug_in->my_read, - G_IO_IN | G_IO_PRI, - plug_in_recv_message, - plug_in); + plug_in->input_id = + g_io_add_watch (plug_in->my_read, + G_IO_IN | G_IO_PRI | G_IO_ERR | G_IO_HUP, + plug_in_recv_message, + plug_in); open_plug_ins = g_slist_prepend (open_plug_ins, plug_in); } @@ -1176,12 +1173,10 @@ plug_in_close (PlugIn *plug_in, GSList *list; PlugInProcDef *proc_def; - list = plug_in->temp_proc_defs; - while (list) + for (list = plug_in->temp_proc_defs; list; list = g_slist_next (list)) { proc_def = (PlugInProcDef *) list->data; plug_in_proc_def_remove (proc_def); - list = list->next; } g_slist_free (plug_in->temp_proc_defs); @@ -1189,9 +1184,9 @@ plug_in_close (PlugIn *plug_in, } /* Close any dialogs that this plugin might have opened */ - brushes_check_dialogs(); - patterns_check_dialogs(); - gradients_check_dialogs(); + brushes_check_dialogs (); + patterns_check_dialogs (); + gradients_check_dialogs (); open_plug_ins = g_slist_remove (open_plug_ins, plug_in); } @@ -1405,25 +1400,51 @@ plug_in_recv_message (GIOChannel *channel, GIOCondition cond, gpointer data) { - WireMessage msg; + gboolean got_message = FALSE; + + if ((PlugIn *) data != current_plug_in) + plug_in_push ((PlugIn *) data); - plug_in_push ((PlugIn*) data); if (current_readchannel == NULL) return TRUE; - memset (&msg, 0, sizeof (WireMessage)); - if (!wire_read_msg (current_readchannel, &msg)) - plug_in_close (current_plug_in, TRUE); - else + if (cond & (G_IO_IN | G_IO_PRI)) { - plug_in_handle_message (&msg); - wire_destroy (&msg); + WireMessage msg; + + memset (&msg, 0, sizeof (WireMessage)); + + if (!wire_read_msg (current_readchannel, &msg)) + { + plug_in_close (current_plug_in, TRUE); + } + else + { + plug_in_handle_message (&msg); + wire_destroy (&msg); + got_message = TRUE; + } + } + if (cond & (G_IO_ERR | G_IO_HUP)) + { + if (current_plug_in->open) + { + plug_in_close (current_plug_in, TRUE); + } + } + + if (!got_message) + g_message (_("Plug-In crashed: %s\n(%s)"), + g_basename (current_plug_in->args[0]), + current_plug_in->args[0]); + if (!current_plug_in->open) plug_in_destroy (current_plug_in); else plug_in_pop (); + return TRUE; } diff --git a/app/plug-in/gimpplugin-message.c b/app/plug-in/gimpplugin-message.c index ca5ffee17b..7cd04b9090 100644 --- a/app/plug-in/gimpplugin-message.c +++ b/app/plug-in/gimpplugin-message.c @@ -338,13 +338,11 @@ plug_in_init (void) } /* insert the proc defs */ - tmp = gimprc_proc_defs; - while (tmp) + for (tmp = gimprc_proc_defs; tmp; tmp = g_slist_next (tmp)) { proc_def = g_new (PlugInProcDef, 1); *proc_def = *((PlugInProcDef*) tmp->data); plug_in_proc_def_insert (proc_def, NULL); - tmp = tmp->next; } tmp = plug_in_defs; @@ -408,11 +406,9 @@ plug_in_init (void) g_print ("\n"); /* free up stuff */ - tmp = plug_in_defs; - while (tmp) + for (tmp = plug_in_defs; tmp; tmp = g_slist_next (tmp)) { plug_in_def = tmp->data; - tmp = tmp->next; plug_in_def_free (plug_in_def, FALSE); } @@ -1033,10 +1029,11 @@ plug_in_open (PlugIn *plug_in) if (!plug_in->synchronous) { - plug_in->input_id = g_io_add_watch (plug_in->my_read, - G_IO_IN | G_IO_PRI, - plug_in_recv_message, - plug_in); + plug_in->input_id = + g_io_add_watch (plug_in->my_read, + G_IO_IN | G_IO_PRI | G_IO_ERR | G_IO_HUP, + plug_in_recv_message, + plug_in); open_plug_ins = g_slist_prepend (open_plug_ins, plug_in); } @@ -1176,12 +1173,10 @@ plug_in_close (PlugIn *plug_in, GSList *list; PlugInProcDef *proc_def; - list = plug_in->temp_proc_defs; - while (list) + for (list = plug_in->temp_proc_defs; list; list = g_slist_next (list)) { proc_def = (PlugInProcDef *) list->data; plug_in_proc_def_remove (proc_def); - list = list->next; } g_slist_free (plug_in->temp_proc_defs); @@ -1189,9 +1184,9 @@ plug_in_close (PlugIn *plug_in, } /* Close any dialogs that this plugin might have opened */ - brushes_check_dialogs(); - patterns_check_dialogs(); - gradients_check_dialogs(); + brushes_check_dialogs (); + patterns_check_dialogs (); + gradients_check_dialogs (); open_plug_ins = g_slist_remove (open_plug_ins, plug_in); } @@ -1405,25 +1400,51 @@ plug_in_recv_message (GIOChannel *channel, GIOCondition cond, gpointer data) { - WireMessage msg; + gboolean got_message = FALSE; + + if ((PlugIn *) data != current_plug_in) + plug_in_push ((PlugIn *) data); - plug_in_push ((PlugIn*) data); if (current_readchannel == NULL) return TRUE; - memset (&msg, 0, sizeof (WireMessage)); - if (!wire_read_msg (current_readchannel, &msg)) - plug_in_close (current_plug_in, TRUE); - else + if (cond & (G_IO_IN | G_IO_PRI)) { - plug_in_handle_message (&msg); - wire_destroy (&msg); + WireMessage msg; + + memset (&msg, 0, sizeof (WireMessage)); + + if (!wire_read_msg (current_readchannel, &msg)) + { + plug_in_close (current_plug_in, TRUE); + } + else + { + plug_in_handle_message (&msg); + wire_destroy (&msg); + got_message = TRUE; + } + } + if (cond & (G_IO_ERR | G_IO_HUP)) + { + if (current_plug_in->open) + { + plug_in_close (current_plug_in, TRUE); + } + } + + if (!got_message) + g_message (_("Plug-In crashed: %s\n(%s)"), + g_basename (current_plug_in->args[0]), + current_plug_in->args[0]); + if (!current_plug_in->open) plug_in_destroy (current_plug_in); else plug_in_pop (); + return TRUE; } diff --git a/app/plug-in/gimpplugin-progress.c b/app/plug-in/gimpplugin-progress.c index ca5ffee17b..7cd04b9090 100644 --- a/app/plug-in/gimpplugin-progress.c +++ b/app/plug-in/gimpplugin-progress.c @@ -338,13 +338,11 @@ plug_in_init (void) } /* insert the proc defs */ - tmp = gimprc_proc_defs; - while (tmp) + for (tmp = gimprc_proc_defs; tmp; tmp = g_slist_next (tmp)) { proc_def = g_new (PlugInProcDef, 1); *proc_def = *((PlugInProcDef*) tmp->data); plug_in_proc_def_insert (proc_def, NULL); - tmp = tmp->next; } tmp = plug_in_defs; @@ -408,11 +406,9 @@ plug_in_init (void) g_print ("\n"); /* free up stuff */ - tmp = plug_in_defs; - while (tmp) + for (tmp = plug_in_defs; tmp; tmp = g_slist_next (tmp)) { plug_in_def = tmp->data; - tmp = tmp->next; plug_in_def_free (plug_in_def, FALSE); } @@ -1033,10 +1029,11 @@ plug_in_open (PlugIn *plug_in) if (!plug_in->synchronous) { - plug_in->input_id = g_io_add_watch (plug_in->my_read, - G_IO_IN | G_IO_PRI, - plug_in_recv_message, - plug_in); + plug_in->input_id = + g_io_add_watch (plug_in->my_read, + G_IO_IN | G_IO_PRI | G_IO_ERR | G_IO_HUP, + plug_in_recv_message, + plug_in); open_plug_ins = g_slist_prepend (open_plug_ins, plug_in); } @@ -1176,12 +1173,10 @@ plug_in_close (PlugIn *plug_in, GSList *list; PlugInProcDef *proc_def; - list = plug_in->temp_proc_defs; - while (list) + for (list = plug_in->temp_proc_defs; list; list = g_slist_next (list)) { proc_def = (PlugInProcDef *) list->data; plug_in_proc_def_remove (proc_def); - list = list->next; } g_slist_free (plug_in->temp_proc_defs); @@ -1189,9 +1184,9 @@ plug_in_close (PlugIn *plug_in, } /* Close any dialogs that this plugin might have opened */ - brushes_check_dialogs(); - patterns_check_dialogs(); - gradients_check_dialogs(); + brushes_check_dialogs (); + patterns_check_dialogs (); + gradients_check_dialogs (); open_plug_ins = g_slist_remove (open_plug_ins, plug_in); } @@ -1405,25 +1400,51 @@ plug_in_recv_message (GIOChannel *channel, GIOCondition cond, gpointer data) { - WireMessage msg; + gboolean got_message = FALSE; + + if ((PlugIn *) data != current_plug_in) + plug_in_push ((PlugIn *) data); - plug_in_push ((PlugIn*) data); if (current_readchannel == NULL) return TRUE; - memset (&msg, 0, sizeof (WireMessage)); - if (!wire_read_msg (current_readchannel, &msg)) - plug_in_close (current_plug_in, TRUE); - else + if (cond & (G_IO_IN | G_IO_PRI)) { - plug_in_handle_message (&msg); - wire_destroy (&msg); + WireMessage msg; + + memset (&msg, 0, sizeof (WireMessage)); + + if (!wire_read_msg (current_readchannel, &msg)) + { + plug_in_close (current_plug_in, TRUE); + } + else + { + plug_in_handle_message (&msg); + wire_destroy (&msg); + got_message = TRUE; + } + } + if (cond & (G_IO_ERR | G_IO_HUP)) + { + if (current_plug_in->open) + { + plug_in_close (current_plug_in, TRUE); + } + } + + if (!got_message) + g_message (_("Plug-In crashed: %s\n(%s)"), + g_basename (current_plug_in->args[0]), + current_plug_in->args[0]); + if (!current_plug_in->open) plug_in_destroy (current_plug_in); else plug_in_pop (); + return TRUE; } diff --git a/app/plug-in/gimpplugin.c b/app/plug-in/gimpplugin.c index ca5ffee17b..7cd04b9090 100644 --- a/app/plug-in/gimpplugin.c +++ b/app/plug-in/gimpplugin.c @@ -338,13 +338,11 @@ plug_in_init (void) } /* insert the proc defs */ - tmp = gimprc_proc_defs; - while (tmp) + for (tmp = gimprc_proc_defs; tmp; tmp = g_slist_next (tmp)) { proc_def = g_new (PlugInProcDef, 1); *proc_def = *((PlugInProcDef*) tmp->data); plug_in_proc_def_insert (proc_def, NULL); - tmp = tmp->next; } tmp = plug_in_defs; @@ -408,11 +406,9 @@ plug_in_init (void) g_print ("\n"); /* free up stuff */ - tmp = plug_in_defs; - while (tmp) + for (tmp = plug_in_defs; tmp; tmp = g_slist_next (tmp)) { plug_in_def = tmp->data; - tmp = tmp->next; plug_in_def_free (plug_in_def, FALSE); } @@ -1033,10 +1029,11 @@ plug_in_open (PlugIn *plug_in) if (!plug_in->synchronous) { - plug_in->input_id = g_io_add_watch (plug_in->my_read, - G_IO_IN | G_IO_PRI, - plug_in_recv_message, - plug_in); + plug_in->input_id = + g_io_add_watch (plug_in->my_read, + G_IO_IN | G_IO_PRI | G_IO_ERR | G_IO_HUP, + plug_in_recv_message, + plug_in); open_plug_ins = g_slist_prepend (open_plug_ins, plug_in); } @@ -1176,12 +1173,10 @@ plug_in_close (PlugIn *plug_in, GSList *list; PlugInProcDef *proc_def; - list = plug_in->temp_proc_defs; - while (list) + for (list = plug_in->temp_proc_defs; list; list = g_slist_next (list)) { proc_def = (PlugInProcDef *) list->data; plug_in_proc_def_remove (proc_def); - list = list->next; } g_slist_free (plug_in->temp_proc_defs); @@ -1189,9 +1184,9 @@ plug_in_close (PlugIn *plug_in, } /* Close any dialogs that this plugin might have opened */ - brushes_check_dialogs(); - patterns_check_dialogs(); - gradients_check_dialogs(); + brushes_check_dialogs (); + patterns_check_dialogs (); + gradients_check_dialogs (); open_plug_ins = g_slist_remove (open_plug_ins, plug_in); } @@ -1405,25 +1400,51 @@ plug_in_recv_message (GIOChannel *channel, GIOCondition cond, gpointer data) { - WireMessage msg; + gboolean got_message = FALSE; + + if ((PlugIn *) data != current_plug_in) + plug_in_push ((PlugIn *) data); - plug_in_push ((PlugIn*) data); if (current_readchannel == NULL) return TRUE; - memset (&msg, 0, sizeof (WireMessage)); - if (!wire_read_msg (current_readchannel, &msg)) - plug_in_close (current_plug_in, TRUE); - else + if (cond & (G_IO_IN | G_IO_PRI)) { - plug_in_handle_message (&msg); - wire_destroy (&msg); + WireMessage msg; + + memset (&msg, 0, sizeof (WireMessage)); + + if (!wire_read_msg (current_readchannel, &msg)) + { + plug_in_close (current_plug_in, TRUE); + } + else + { + plug_in_handle_message (&msg); + wire_destroy (&msg); + got_message = TRUE; + } + } + if (cond & (G_IO_ERR | G_IO_HUP)) + { + if (current_plug_in->open) + { + plug_in_close (current_plug_in, TRUE); + } + } + + if (!got_message) + g_message (_("Plug-In crashed: %s\n(%s)"), + g_basename (current_plug_in->args[0]), + current_plug_in->args[0]); + if (!current_plug_in->open) plug_in_destroy (current_plug_in); else plug_in_pop (); + return TRUE; } diff --git a/app/plug-in/gimppluginmanager-call.c b/app/plug-in/gimppluginmanager-call.c index ca5ffee17b..7cd04b9090 100644 --- a/app/plug-in/gimppluginmanager-call.c +++ b/app/plug-in/gimppluginmanager-call.c @@ -338,13 +338,11 @@ plug_in_init (void) } /* insert the proc defs */ - tmp = gimprc_proc_defs; - while (tmp) + for (tmp = gimprc_proc_defs; tmp; tmp = g_slist_next (tmp)) { proc_def = g_new (PlugInProcDef, 1); *proc_def = *((PlugInProcDef*) tmp->data); plug_in_proc_def_insert (proc_def, NULL); - tmp = tmp->next; } tmp = plug_in_defs; @@ -408,11 +406,9 @@ plug_in_init (void) g_print ("\n"); /* free up stuff */ - tmp = plug_in_defs; - while (tmp) + for (tmp = plug_in_defs; tmp; tmp = g_slist_next (tmp)) { plug_in_def = tmp->data; - tmp = tmp->next; plug_in_def_free (plug_in_def, FALSE); } @@ -1033,10 +1029,11 @@ plug_in_open (PlugIn *plug_in) if (!plug_in->synchronous) { - plug_in->input_id = g_io_add_watch (plug_in->my_read, - G_IO_IN | G_IO_PRI, - plug_in_recv_message, - plug_in); + plug_in->input_id = + g_io_add_watch (plug_in->my_read, + G_IO_IN | G_IO_PRI | G_IO_ERR | G_IO_HUP, + plug_in_recv_message, + plug_in); open_plug_ins = g_slist_prepend (open_plug_ins, plug_in); } @@ -1176,12 +1173,10 @@ plug_in_close (PlugIn *plug_in, GSList *list; PlugInProcDef *proc_def; - list = plug_in->temp_proc_defs; - while (list) + for (list = plug_in->temp_proc_defs; list; list = g_slist_next (list)) { proc_def = (PlugInProcDef *) list->data; plug_in_proc_def_remove (proc_def); - list = list->next; } g_slist_free (plug_in->temp_proc_defs); @@ -1189,9 +1184,9 @@ plug_in_close (PlugIn *plug_in, } /* Close any dialogs that this plugin might have opened */ - brushes_check_dialogs(); - patterns_check_dialogs(); - gradients_check_dialogs(); + brushes_check_dialogs (); + patterns_check_dialogs (); + gradients_check_dialogs (); open_plug_ins = g_slist_remove (open_plug_ins, plug_in); } @@ -1405,25 +1400,51 @@ plug_in_recv_message (GIOChannel *channel, GIOCondition cond, gpointer data) { - WireMessage msg; + gboolean got_message = FALSE; + + if ((PlugIn *) data != current_plug_in) + plug_in_push ((PlugIn *) data); - plug_in_push ((PlugIn*) data); if (current_readchannel == NULL) return TRUE; - memset (&msg, 0, sizeof (WireMessage)); - if (!wire_read_msg (current_readchannel, &msg)) - plug_in_close (current_plug_in, TRUE); - else + if (cond & (G_IO_IN | G_IO_PRI)) { - plug_in_handle_message (&msg); - wire_destroy (&msg); + WireMessage msg; + + memset (&msg, 0, sizeof (WireMessage)); + + if (!wire_read_msg (current_readchannel, &msg)) + { + plug_in_close (current_plug_in, TRUE); + } + else + { + plug_in_handle_message (&msg); + wire_destroy (&msg); + got_message = TRUE; + } + } + if (cond & (G_IO_ERR | G_IO_HUP)) + { + if (current_plug_in->open) + { + plug_in_close (current_plug_in, TRUE); + } + } + + if (!got_message) + g_message (_("Plug-In crashed: %s\n(%s)"), + g_basename (current_plug_in->args[0]), + current_plug_in->args[0]); + if (!current_plug_in->open) plug_in_destroy (current_plug_in); else plug_in_pop (); + return TRUE; } diff --git a/app/plug-in/gimppluginmanager-run.c b/app/plug-in/gimppluginmanager-run.c index ca5ffee17b..7cd04b9090 100644 --- a/app/plug-in/gimppluginmanager-run.c +++ b/app/plug-in/gimppluginmanager-run.c @@ -338,13 +338,11 @@ plug_in_init (void) } /* insert the proc defs */ - tmp = gimprc_proc_defs; - while (tmp) + for (tmp = gimprc_proc_defs; tmp; tmp = g_slist_next (tmp)) { proc_def = g_new (PlugInProcDef, 1); *proc_def = *((PlugInProcDef*) tmp->data); plug_in_proc_def_insert (proc_def, NULL); - tmp = tmp->next; } tmp = plug_in_defs; @@ -408,11 +406,9 @@ plug_in_init (void) g_print ("\n"); /* free up stuff */ - tmp = plug_in_defs; - while (tmp) + for (tmp = plug_in_defs; tmp; tmp = g_slist_next (tmp)) { plug_in_def = tmp->data; - tmp = tmp->next; plug_in_def_free (plug_in_def, FALSE); } @@ -1033,10 +1029,11 @@ plug_in_open (PlugIn *plug_in) if (!plug_in->synchronous) { - plug_in->input_id = g_io_add_watch (plug_in->my_read, - G_IO_IN | G_IO_PRI, - plug_in_recv_message, - plug_in); + plug_in->input_id = + g_io_add_watch (plug_in->my_read, + G_IO_IN | G_IO_PRI | G_IO_ERR | G_IO_HUP, + plug_in_recv_message, + plug_in); open_plug_ins = g_slist_prepend (open_plug_ins, plug_in); } @@ -1176,12 +1173,10 @@ plug_in_close (PlugIn *plug_in, GSList *list; PlugInProcDef *proc_def; - list = plug_in->temp_proc_defs; - while (list) + for (list = plug_in->temp_proc_defs; list; list = g_slist_next (list)) { proc_def = (PlugInProcDef *) list->data; plug_in_proc_def_remove (proc_def); - list = list->next; } g_slist_free (plug_in->temp_proc_defs); @@ -1189,9 +1184,9 @@ plug_in_close (PlugIn *plug_in, } /* Close any dialogs that this plugin might have opened */ - brushes_check_dialogs(); - patterns_check_dialogs(); - gradients_check_dialogs(); + brushes_check_dialogs (); + patterns_check_dialogs (); + gradients_check_dialogs (); open_plug_ins = g_slist_remove (open_plug_ins, plug_in); } @@ -1405,25 +1400,51 @@ plug_in_recv_message (GIOChannel *channel, GIOCondition cond, gpointer data) { - WireMessage msg; + gboolean got_message = FALSE; + + if ((PlugIn *) data != current_plug_in) + plug_in_push ((PlugIn *) data); - plug_in_push ((PlugIn*) data); if (current_readchannel == NULL) return TRUE; - memset (&msg, 0, sizeof (WireMessage)); - if (!wire_read_msg (current_readchannel, &msg)) - plug_in_close (current_plug_in, TRUE); - else + if (cond & (G_IO_IN | G_IO_PRI)) { - plug_in_handle_message (&msg); - wire_destroy (&msg); + WireMessage msg; + + memset (&msg, 0, sizeof (WireMessage)); + + if (!wire_read_msg (current_readchannel, &msg)) + { + plug_in_close (current_plug_in, TRUE); + } + else + { + plug_in_handle_message (&msg); + wire_destroy (&msg); + got_message = TRUE; + } + } + if (cond & (G_IO_ERR | G_IO_HUP)) + { + if (current_plug_in->open) + { + plug_in_close (current_plug_in, TRUE); + } + } + + if (!got_message) + g_message (_("Plug-In crashed: %s\n(%s)"), + g_basename (current_plug_in->args[0]), + current_plug_in->args[0]); + if (!current_plug_in->open) plug_in_destroy (current_plug_in); else plug_in_pop (); + return TRUE; } diff --git a/app/plug-in/gimppluginmanager.c b/app/plug-in/gimppluginmanager.c index ca5ffee17b..7cd04b9090 100644 --- a/app/plug-in/gimppluginmanager.c +++ b/app/plug-in/gimppluginmanager.c @@ -338,13 +338,11 @@ plug_in_init (void) } /* insert the proc defs */ - tmp = gimprc_proc_defs; - while (tmp) + for (tmp = gimprc_proc_defs; tmp; tmp = g_slist_next (tmp)) { proc_def = g_new (PlugInProcDef, 1); *proc_def = *((PlugInProcDef*) tmp->data); plug_in_proc_def_insert (proc_def, NULL); - tmp = tmp->next; } tmp = plug_in_defs; @@ -408,11 +406,9 @@ plug_in_init (void) g_print ("\n"); /* free up stuff */ - tmp = plug_in_defs; - while (tmp) + for (tmp = plug_in_defs; tmp; tmp = g_slist_next (tmp)) { plug_in_def = tmp->data; - tmp = tmp->next; plug_in_def_free (plug_in_def, FALSE); } @@ -1033,10 +1029,11 @@ plug_in_open (PlugIn *plug_in) if (!plug_in->synchronous) { - plug_in->input_id = g_io_add_watch (plug_in->my_read, - G_IO_IN | G_IO_PRI, - plug_in_recv_message, - plug_in); + plug_in->input_id = + g_io_add_watch (plug_in->my_read, + G_IO_IN | G_IO_PRI | G_IO_ERR | G_IO_HUP, + plug_in_recv_message, + plug_in); open_plug_ins = g_slist_prepend (open_plug_ins, plug_in); } @@ -1176,12 +1173,10 @@ plug_in_close (PlugIn *plug_in, GSList *list; PlugInProcDef *proc_def; - list = plug_in->temp_proc_defs; - while (list) + for (list = plug_in->temp_proc_defs; list; list = g_slist_next (list)) { proc_def = (PlugInProcDef *) list->data; plug_in_proc_def_remove (proc_def); - list = list->next; } g_slist_free (plug_in->temp_proc_defs); @@ -1189,9 +1184,9 @@ plug_in_close (PlugIn *plug_in, } /* Close any dialogs that this plugin might have opened */ - brushes_check_dialogs(); - patterns_check_dialogs(); - gradients_check_dialogs(); + brushes_check_dialogs (); + patterns_check_dialogs (); + gradients_check_dialogs (); open_plug_ins = g_slist_remove (open_plug_ins, plug_in); } @@ -1405,25 +1400,51 @@ plug_in_recv_message (GIOChannel *channel, GIOCondition cond, gpointer data) { - WireMessage msg; + gboolean got_message = FALSE; + + if ((PlugIn *) data != current_plug_in) + plug_in_push ((PlugIn *) data); - plug_in_push ((PlugIn*) data); if (current_readchannel == NULL) return TRUE; - memset (&msg, 0, sizeof (WireMessage)); - if (!wire_read_msg (current_readchannel, &msg)) - plug_in_close (current_plug_in, TRUE); - else + if (cond & (G_IO_IN | G_IO_PRI)) { - plug_in_handle_message (&msg); - wire_destroy (&msg); + WireMessage msg; + + memset (&msg, 0, sizeof (WireMessage)); + + if (!wire_read_msg (current_readchannel, &msg)) + { + plug_in_close (current_plug_in, TRUE); + } + else + { + plug_in_handle_message (&msg); + wire_destroy (&msg); + got_message = TRUE; + } + } + if (cond & (G_IO_ERR | G_IO_HUP)) + { + if (current_plug_in->open) + { + plug_in_close (current_plug_in, TRUE); + } + } + + if (!got_message) + g_message (_("Plug-In crashed: %s\n(%s)"), + g_basename (current_plug_in->args[0]), + current_plug_in->args[0]); + if (!current_plug_in->open) plug_in_destroy (current_plug_in); else plug_in_pop (); + return TRUE; } diff --git a/app/plug-in/gimppluginshm.c b/app/plug-in/gimppluginshm.c index ca5ffee17b..7cd04b9090 100644 --- a/app/plug-in/gimppluginshm.c +++ b/app/plug-in/gimppluginshm.c @@ -338,13 +338,11 @@ plug_in_init (void) } /* insert the proc defs */ - tmp = gimprc_proc_defs; - while (tmp) + for (tmp = gimprc_proc_defs; tmp; tmp = g_slist_next (tmp)) { proc_def = g_new (PlugInProcDef, 1); *proc_def = *((PlugInProcDef*) tmp->data); plug_in_proc_def_insert (proc_def, NULL); - tmp = tmp->next; } tmp = plug_in_defs; @@ -408,11 +406,9 @@ plug_in_init (void) g_print ("\n"); /* free up stuff */ - tmp = plug_in_defs; - while (tmp) + for (tmp = plug_in_defs; tmp; tmp = g_slist_next (tmp)) { plug_in_def = tmp->data; - tmp = tmp->next; plug_in_def_free (plug_in_def, FALSE); } @@ -1033,10 +1029,11 @@ plug_in_open (PlugIn *plug_in) if (!plug_in->synchronous) { - plug_in->input_id = g_io_add_watch (plug_in->my_read, - G_IO_IN | G_IO_PRI, - plug_in_recv_message, - plug_in); + plug_in->input_id = + g_io_add_watch (plug_in->my_read, + G_IO_IN | G_IO_PRI | G_IO_ERR | G_IO_HUP, + plug_in_recv_message, + plug_in); open_plug_ins = g_slist_prepend (open_plug_ins, plug_in); } @@ -1176,12 +1173,10 @@ plug_in_close (PlugIn *plug_in, GSList *list; PlugInProcDef *proc_def; - list = plug_in->temp_proc_defs; - while (list) + for (list = plug_in->temp_proc_defs; list; list = g_slist_next (list)) { proc_def = (PlugInProcDef *) list->data; plug_in_proc_def_remove (proc_def); - list = list->next; } g_slist_free (plug_in->temp_proc_defs); @@ -1189,9 +1184,9 @@ plug_in_close (PlugIn *plug_in, } /* Close any dialogs that this plugin might have opened */ - brushes_check_dialogs(); - patterns_check_dialogs(); - gradients_check_dialogs(); + brushes_check_dialogs (); + patterns_check_dialogs (); + gradients_check_dialogs (); open_plug_ins = g_slist_remove (open_plug_ins, plug_in); } @@ -1405,25 +1400,51 @@ plug_in_recv_message (GIOChannel *channel, GIOCondition cond, gpointer data) { - WireMessage msg; + gboolean got_message = FALSE; + + if ((PlugIn *) data != current_plug_in) + plug_in_push ((PlugIn *) data); - plug_in_push ((PlugIn*) data); if (current_readchannel == NULL) return TRUE; - memset (&msg, 0, sizeof (WireMessage)); - if (!wire_read_msg (current_readchannel, &msg)) - plug_in_close (current_plug_in, TRUE); - else + if (cond & (G_IO_IN | G_IO_PRI)) { - plug_in_handle_message (&msg); - wire_destroy (&msg); + WireMessage msg; + + memset (&msg, 0, sizeof (WireMessage)); + + if (!wire_read_msg (current_readchannel, &msg)) + { + plug_in_close (current_plug_in, TRUE); + } + else + { + plug_in_handle_message (&msg); + wire_destroy (&msg); + got_message = TRUE; + } + } + if (cond & (G_IO_ERR | G_IO_HUP)) + { + if (current_plug_in->open) + { + plug_in_close (current_plug_in, TRUE); + } + } + + if (!got_message) + g_message (_("Plug-In crashed: %s\n(%s)"), + g_basename (current_plug_in->args[0]), + current_plug_in->args[0]); + if (!current_plug_in->open) plug_in_destroy (current_plug_in); else plug_in_pop (); + return TRUE; } diff --git a/app/plug-in/plug-in-def.c b/app/plug-in/plug-in-def.c index ca5ffee17b..7cd04b9090 100644 --- a/app/plug-in/plug-in-def.c +++ b/app/plug-in/plug-in-def.c @@ -338,13 +338,11 @@ plug_in_init (void) } /* insert the proc defs */ - tmp = gimprc_proc_defs; - while (tmp) + for (tmp = gimprc_proc_defs; tmp; tmp = g_slist_next (tmp)) { proc_def = g_new (PlugInProcDef, 1); *proc_def = *((PlugInProcDef*) tmp->data); plug_in_proc_def_insert (proc_def, NULL); - tmp = tmp->next; } tmp = plug_in_defs; @@ -408,11 +406,9 @@ plug_in_init (void) g_print ("\n"); /* free up stuff */ - tmp = plug_in_defs; - while (tmp) + for (tmp = plug_in_defs; tmp; tmp = g_slist_next (tmp)) { plug_in_def = tmp->data; - tmp = tmp->next; plug_in_def_free (plug_in_def, FALSE); } @@ -1033,10 +1029,11 @@ plug_in_open (PlugIn *plug_in) if (!plug_in->synchronous) { - plug_in->input_id = g_io_add_watch (plug_in->my_read, - G_IO_IN | G_IO_PRI, - plug_in_recv_message, - plug_in); + plug_in->input_id = + g_io_add_watch (plug_in->my_read, + G_IO_IN | G_IO_PRI | G_IO_ERR | G_IO_HUP, + plug_in_recv_message, + plug_in); open_plug_ins = g_slist_prepend (open_plug_ins, plug_in); } @@ -1176,12 +1173,10 @@ plug_in_close (PlugIn *plug_in, GSList *list; PlugInProcDef *proc_def; - list = plug_in->temp_proc_defs; - while (list) + for (list = plug_in->temp_proc_defs; list; list = g_slist_next (list)) { proc_def = (PlugInProcDef *) list->data; plug_in_proc_def_remove (proc_def); - list = list->next; } g_slist_free (plug_in->temp_proc_defs); @@ -1189,9 +1184,9 @@ plug_in_close (PlugIn *plug_in, } /* Close any dialogs that this plugin might have opened */ - brushes_check_dialogs(); - patterns_check_dialogs(); - gradients_check_dialogs(); + brushes_check_dialogs (); + patterns_check_dialogs (); + gradients_check_dialogs (); open_plug_ins = g_slist_remove (open_plug_ins, plug_in); } @@ -1405,25 +1400,51 @@ plug_in_recv_message (GIOChannel *channel, GIOCondition cond, gpointer data) { - WireMessage msg; + gboolean got_message = FALSE; + + if ((PlugIn *) data != current_plug_in) + plug_in_push ((PlugIn *) data); - plug_in_push ((PlugIn*) data); if (current_readchannel == NULL) return TRUE; - memset (&msg, 0, sizeof (WireMessage)); - if (!wire_read_msg (current_readchannel, &msg)) - plug_in_close (current_plug_in, TRUE); - else + if (cond & (G_IO_IN | G_IO_PRI)) { - plug_in_handle_message (&msg); - wire_destroy (&msg); + WireMessage msg; + + memset (&msg, 0, sizeof (WireMessage)); + + if (!wire_read_msg (current_readchannel, &msg)) + { + plug_in_close (current_plug_in, TRUE); + } + else + { + plug_in_handle_message (&msg); + wire_destroy (&msg); + got_message = TRUE; + } + } + if (cond & (G_IO_ERR | G_IO_HUP)) + { + if (current_plug_in->open) + { + plug_in_close (current_plug_in, TRUE); + } + } + + if (!got_message) + g_message (_("Plug-In crashed: %s\n(%s)"), + g_basename (current_plug_in->args[0]), + current_plug_in->args[0]); + if (!current_plug_in->open) plug_in_destroy (current_plug_in); else plug_in_pop (); + return TRUE; } diff --git a/app/plug-in/plug-in-message.c b/app/plug-in/plug-in-message.c index ca5ffee17b..7cd04b9090 100644 --- a/app/plug-in/plug-in-message.c +++ b/app/plug-in/plug-in-message.c @@ -338,13 +338,11 @@ plug_in_init (void) } /* insert the proc defs */ - tmp = gimprc_proc_defs; - while (tmp) + for (tmp = gimprc_proc_defs; tmp; tmp = g_slist_next (tmp)) { proc_def = g_new (PlugInProcDef, 1); *proc_def = *((PlugInProcDef*) tmp->data); plug_in_proc_def_insert (proc_def, NULL); - tmp = tmp->next; } tmp = plug_in_defs; @@ -408,11 +406,9 @@ plug_in_init (void) g_print ("\n"); /* free up stuff */ - tmp = plug_in_defs; - while (tmp) + for (tmp = plug_in_defs; tmp; tmp = g_slist_next (tmp)) { plug_in_def = tmp->data; - tmp = tmp->next; plug_in_def_free (plug_in_def, FALSE); } @@ -1033,10 +1029,11 @@ plug_in_open (PlugIn *plug_in) if (!plug_in->synchronous) { - plug_in->input_id = g_io_add_watch (plug_in->my_read, - G_IO_IN | G_IO_PRI, - plug_in_recv_message, - plug_in); + plug_in->input_id = + g_io_add_watch (plug_in->my_read, + G_IO_IN | G_IO_PRI | G_IO_ERR | G_IO_HUP, + plug_in_recv_message, + plug_in); open_plug_ins = g_slist_prepend (open_plug_ins, plug_in); } @@ -1176,12 +1173,10 @@ plug_in_close (PlugIn *plug_in, GSList *list; PlugInProcDef *proc_def; - list = plug_in->temp_proc_defs; - while (list) + for (list = plug_in->temp_proc_defs; list; list = g_slist_next (list)) { proc_def = (PlugInProcDef *) list->data; plug_in_proc_def_remove (proc_def); - list = list->next; } g_slist_free (plug_in->temp_proc_defs); @@ -1189,9 +1184,9 @@ plug_in_close (PlugIn *plug_in, } /* Close any dialogs that this plugin might have opened */ - brushes_check_dialogs(); - patterns_check_dialogs(); - gradients_check_dialogs(); + brushes_check_dialogs (); + patterns_check_dialogs (); + gradients_check_dialogs (); open_plug_ins = g_slist_remove (open_plug_ins, plug_in); } @@ -1405,25 +1400,51 @@ plug_in_recv_message (GIOChannel *channel, GIOCondition cond, gpointer data) { - WireMessage msg; + gboolean got_message = FALSE; + + if ((PlugIn *) data != current_plug_in) + plug_in_push ((PlugIn *) data); - plug_in_push ((PlugIn*) data); if (current_readchannel == NULL) return TRUE; - memset (&msg, 0, sizeof (WireMessage)); - if (!wire_read_msg (current_readchannel, &msg)) - plug_in_close (current_plug_in, TRUE); - else + if (cond & (G_IO_IN | G_IO_PRI)) { - plug_in_handle_message (&msg); - wire_destroy (&msg); + WireMessage msg; + + memset (&msg, 0, sizeof (WireMessage)); + + if (!wire_read_msg (current_readchannel, &msg)) + { + plug_in_close (current_plug_in, TRUE); + } + else + { + plug_in_handle_message (&msg); + wire_destroy (&msg); + got_message = TRUE; + } + } + if (cond & (G_IO_ERR | G_IO_HUP)) + { + if (current_plug_in->open) + { + plug_in_close (current_plug_in, TRUE); + } + } + + if (!got_message) + g_message (_("Plug-In crashed: %s\n(%s)"), + g_basename (current_plug_in->args[0]), + current_plug_in->args[0]); + if (!current_plug_in->open) plug_in_destroy (current_plug_in); else plug_in_pop (); + return TRUE; } diff --git a/app/plug-in/plug-in-params.c b/app/plug-in/plug-in-params.c index ca5ffee17b..7cd04b9090 100644 --- a/app/plug-in/plug-in-params.c +++ b/app/plug-in/plug-in-params.c @@ -338,13 +338,11 @@ plug_in_init (void) } /* insert the proc defs */ - tmp = gimprc_proc_defs; - while (tmp) + for (tmp = gimprc_proc_defs; tmp; tmp = g_slist_next (tmp)) { proc_def = g_new (PlugInProcDef, 1); *proc_def = *((PlugInProcDef*) tmp->data); plug_in_proc_def_insert (proc_def, NULL); - tmp = tmp->next; } tmp = plug_in_defs; @@ -408,11 +406,9 @@ plug_in_init (void) g_print ("\n"); /* free up stuff */ - tmp = plug_in_defs; - while (tmp) + for (tmp = plug_in_defs; tmp; tmp = g_slist_next (tmp)) { plug_in_def = tmp->data; - tmp = tmp->next; plug_in_def_free (plug_in_def, FALSE); } @@ -1033,10 +1029,11 @@ plug_in_open (PlugIn *plug_in) if (!plug_in->synchronous) { - plug_in->input_id = g_io_add_watch (plug_in->my_read, - G_IO_IN | G_IO_PRI, - plug_in_recv_message, - plug_in); + plug_in->input_id = + g_io_add_watch (plug_in->my_read, + G_IO_IN | G_IO_PRI | G_IO_ERR | G_IO_HUP, + plug_in_recv_message, + plug_in); open_plug_ins = g_slist_prepend (open_plug_ins, plug_in); } @@ -1176,12 +1173,10 @@ plug_in_close (PlugIn *plug_in, GSList *list; PlugInProcDef *proc_def; - list = plug_in->temp_proc_defs; - while (list) + for (list = plug_in->temp_proc_defs; list; list = g_slist_next (list)) { proc_def = (PlugInProcDef *) list->data; plug_in_proc_def_remove (proc_def); - list = list->next; } g_slist_free (plug_in->temp_proc_defs); @@ -1189,9 +1184,9 @@ plug_in_close (PlugIn *plug_in, } /* Close any dialogs that this plugin might have opened */ - brushes_check_dialogs(); - patterns_check_dialogs(); - gradients_check_dialogs(); + brushes_check_dialogs (); + patterns_check_dialogs (); + gradients_check_dialogs (); open_plug_ins = g_slist_remove (open_plug_ins, plug_in); } @@ -1405,25 +1400,51 @@ plug_in_recv_message (GIOChannel *channel, GIOCondition cond, gpointer data) { - WireMessage msg; + gboolean got_message = FALSE; + + if ((PlugIn *) data != current_plug_in) + plug_in_push ((PlugIn *) data); - plug_in_push ((PlugIn*) data); if (current_readchannel == NULL) return TRUE; - memset (&msg, 0, sizeof (WireMessage)); - if (!wire_read_msg (current_readchannel, &msg)) - plug_in_close (current_plug_in, TRUE); - else + if (cond & (G_IO_IN | G_IO_PRI)) { - plug_in_handle_message (&msg); - wire_destroy (&msg); + WireMessage msg; + + memset (&msg, 0, sizeof (WireMessage)); + + if (!wire_read_msg (current_readchannel, &msg)) + { + plug_in_close (current_plug_in, TRUE); + } + else + { + plug_in_handle_message (&msg); + wire_destroy (&msg); + got_message = TRUE; + } + } + if (cond & (G_IO_ERR | G_IO_HUP)) + { + if (current_plug_in->open) + { + plug_in_close (current_plug_in, TRUE); + } + } + + if (!got_message) + g_message (_("Plug-In crashed: %s\n(%s)"), + g_basename (current_plug_in->args[0]), + current_plug_in->args[0]); + if (!current_plug_in->open) plug_in_destroy (current_plug_in); else plug_in_pop (); + return TRUE; } diff --git a/app/plug-in/plug-in-progress.c b/app/plug-in/plug-in-progress.c index ca5ffee17b..7cd04b9090 100644 --- a/app/plug-in/plug-in-progress.c +++ b/app/plug-in/plug-in-progress.c @@ -338,13 +338,11 @@ plug_in_init (void) } /* insert the proc defs */ - tmp = gimprc_proc_defs; - while (tmp) + for (tmp = gimprc_proc_defs; tmp; tmp = g_slist_next (tmp)) { proc_def = g_new (PlugInProcDef, 1); *proc_def = *((PlugInProcDef*) tmp->data); plug_in_proc_def_insert (proc_def, NULL); - tmp = tmp->next; } tmp = plug_in_defs; @@ -408,11 +406,9 @@ plug_in_init (void) g_print ("\n"); /* free up stuff */ - tmp = plug_in_defs; - while (tmp) + for (tmp = plug_in_defs; tmp; tmp = g_slist_next (tmp)) { plug_in_def = tmp->data; - tmp = tmp->next; plug_in_def_free (plug_in_def, FALSE); } @@ -1033,10 +1029,11 @@ plug_in_open (PlugIn *plug_in) if (!plug_in->synchronous) { - plug_in->input_id = g_io_add_watch (plug_in->my_read, - G_IO_IN | G_IO_PRI, - plug_in_recv_message, - plug_in); + plug_in->input_id = + g_io_add_watch (plug_in->my_read, + G_IO_IN | G_IO_PRI | G_IO_ERR | G_IO_HUP, + plug_in_recv_message, + plug_in); open_plug_ins = g_slist_prepend (open_plug_ins, plug_in); } @@ -1176,12 +1173,10 @@ plug_in_close (PlugIn *plug_in, GSList *list; PlugInProcDef *proc_def; - list = plug_in->temp_proc_defs; - while (list) + for (list = plug_in->temp_proc_defs; list; list = g_slist_next (list)) { proc_def = (PlugInProcDef *) list->data; plug_in_proc_def_remove (proc_def); - list = list->next; } g_slist_free (plug_in->temp_proc_defs); @@ -1189,9 +1184,9 @@ plug_in_close (PlugIn *plug_in, } /* Close any dialogs that this plugin might have opened */ - brushes_check_dialogs(); - patterns_check_dialogs(); - gradients_check_dialogs(); + brushes_check_dialogs (); + patterns_check_dialogs (); + gradients_check_dialogs (); open_plug_ins = g_slist_remove (open_plug_ins, plug_in); } @@ -1405,25 +1400,51 @@ plug_in_recv_message (GIOChannel *channel, GIOCondition cond, gpointer data) { - WireMessage msg; + gboolean got_message = FALSE; + + if ((PlugIn *) data != current_plug_in) + plug_in_push ((PlugIn *) data); - plug_in_push ((PlugIn*) data); if (current_readchannel == NULL) return TRUE; - memset (&msg, 0, sizeof (WireMessage)); - if (!wire_read_msg (current_readchannel, &msg)) - plug_in_close (current_plug_in, TRUE); - else + if (cond & (G_IO_IN | G_IO_PRI)) { - plug_in_handle_message (&msg); - wire_destroy (&msg); + WireMessage msg; + + memset (&msg, 0, sizeof (WireMessage)); + + if (!wire_read_msg (current_readchannel, &msg)) + { + plug_in_close (current_plug_in, TRUE); + } + else + { + plug_in_handle_message (&msg); + wire_destroy (&msg); + got_message = TRUE; + } + } + if (cond & (G_IO_ERR | G_IO_HUP)) + { + if (current_plug_in->open) + { + plug_in_close (current_plug_in, TRUE); + } + } + + if (!got_message) + g_message (_("Plug-In crashed: %s\n(%s)"), + g_basename (current_plug_in->args[0]), + current_plug_in->args[0]); + if (!current_plug_in->open) plug_in_destroy (current_plug_in); else plug_in_pop (); + return TRUE; } diff --git a/app/plug-in/plug-in-run.c b/app/plug-in/plug-in-run.c index ca5ffee17b..7cd04b9090 100644 --- a/app/plug-in/plug-in-run.c +++ b/app/plug-in/plug-in-run.c @@ -338,13 +338,11 @@ plug_in_init (void) } /* insert the proc defs */ - tmp = gimprc_proc_defs; - while (tmp) + for (tmp = gimprc_proc_defs; tmp; tmp = g_slist_next (tmp)) { proc_def = g_new (PlugInProcDef, 1); *proc_def = *((PlugInProcDef*) tmp->data); plug_in_proc_def_insert (proc_def, NULL); - tmp = tmp->next; } tmp = plug_in_defs; @@ -408,11 +406,9 @@ plug_in_init (void) g_print ("\n"); /* free up stuff */ - tmp = plug_in_defs; - while (tmp) + for (tmp = plug_in_defs; tmp; tmp = g_slist_next (tmp)) { plug_in_def = tmp->data; - tmp = tmp->next; plug_in_def_free (plug_in_def, FALSE); } @@ -1033,10 +1029,11 @@ plug_in_open (PlugIn *plug_in) if (!plug_in->synchronous) { - plug_in->input_id = g_io_add_watch (plug_in->my_read, - G_IO_IN | G_IO_PRI, - plug_in_recv_message, - plug_in); + plug_in->input_id = + g_io_add_watch (plug_in->my_read, + G_IO_IN | G_IO_PRI | G_IO_ERR | G_IO_HUP, + plug_in_recv_message, + plug_in); open_plug_ins = g_slist_prepend (open_plug_ins, plug_in); } @@ -1176,12 +1173,10 @@ plug_in_close (PlugIn *plug_in, GSList *list; PlugInProcDef *proc_def; - list = plug_in->temp_proc_defs; - while (list) + for (list = plug_in->temp_proc_defs; list; list = g_slist_next (list)) { proc_def = (PlugInProcDef *) list->data; plug_in_proc_def_remove (proc_def); - list = list->next; } g_slist_free (plug_in->temp_proc_defs); @@ -1189,9 +1184,9 @@ plug_in_close (PlugIn *plug_in, } /* Close any dialogs that this plugin might have opened */ - brushes_check_dialogs(); - patterns_check_dialogs(); - gradients_check_dialogs(); + brushes_check_dialogs (); + patterns_check_dialogs (); + gradients_check_dialogs (); open_plug_ins = g_slist_remove (open_plug_ins, plug_in); } @@ -1405,25 +1400,51 @@ plug_in_recv_message (GIOChannel *channel, GIOCondition cond, gpointer data) { - WireMessage msg; + gboolean got_message = FALSE; + + if ((PlugIn *) data != current_plug_in) + plug_in_push ((PlugIn *) data); - plug_in_push ((PlugIn*) data); if (current_readchannel == NULL) return TRUE; - memset (&msg, 0, sizeof (WireMessage)); - if (!wire_read_msg (current_readchannel, &msg)) - plug_in_close (current_plug_in, TRUE); - else + if (cond & (G_IO_IN | G_IO_PRI)) { - plug_in_handle_message (&msg); - wire_destroy (&msg); + WireMessage msg; + + memset (&msg, 0, sizeof (WireMessage)); + + if (!wire_read_msg (current_readchannel, &msg)) + { + plug_in_close (current_plug_in, TRUE); + } + else + { + plug_in_handle_message (&msg); + wire_destroy (&msg); + got_message = TRUE; + } + } + if (cond & (G_IO_ERR | G_IO_HUP)) + { + if (current_plug_in->open) + { + plug_in_close (current_plug_in, TRUE); + } + } + + if (!got_message) + g_message (_("Plug-In crashed: %s\n(%s)"), + g_basename (current_plug_in->args[0]), + current_plug_in->args[0]); + if (!current_plug_in->open) plug_in_destroy (current_plug_in); else plug_in_pop (); + return TRUE; } diff --git a/app/plug-in/plug-in-shm.c b/app/plug-in/plug-in-shm.c index ca5ffee17b..7cd04b9090 100644 --- a/app/plug-in/plug-in-shm.c +++ b/app/plug-in/plug-in-shm.c @@ -338,13 +338,11 @@ plug_in_init (void) } /* insert the proc defs */ - tmp = gimprc_proc_defs; - while (tmp) + for (tmp = gimprc_proc_defs; tmp; tmp = g_slist_next (tmp)) { proc_def = g_new (PlugInProcDef, 1); *proc_def = *((PlugInProcDef*) tmp->data); plug_in_proc_def_insert (proc_def, NULL); - tmp = tmp->next; } tmp = plug_in_defs; @@ -408,11 +406,9 @@ plug_in_init (void) g_print ("\n"); /* free up stuff */ - tmp = plug_in_defs; - while (tmp) + for (tmp = plug_in_defs; tmp; tmp = g_slist_next (tmp)) { plug_in_def = tmp->data; - tmp = tmp->next; plug_in_def_free (plug_in_def, FALSE); } @@ -1033,10 +1029,11 @@ plug_in_open (PlugIn *plug_in) if (!plug_in->synchronous) { - plug_in->input_id = g_io_add_watch (plug_in->my_read, - G_IO_IN | G_IO_PRI, - plug_in_recv_message, - plug_in); + plug_in->input_id = + g_io_add_watch (plug_in->my_read, + G_IO_IN | G_IO_PRI | G_IO_ERR | G_IO_HUP, + plug_in_recv_message, + plug_in); open_plug_ins = g_slist_prepend (open_plug_ins, plug_in); } @@ -1176,12 +1173,10 @@ plug_in_close (PlugIn *plug_in, GSList *list; PlugInProcDef *proc_def; - list = plug_in->temp_proc_defs; - while (list) + for (list = plug_in->temp_proc_defs; list; list = g_slist_next (list)) { proc_def = (PlugInProcDef *) list->data; plug_in_proc_def_remove (proc_def); - list = list->next; } g_slist_free (plug_in->temp_proc_defs); @@ -1189,9 +1184,9 @@ plug_in_close (PlugIn *plug_in, } /* Close any dialogs that this plugin might have opened */ - brushes_check_dialogs(); - patterns_check_dialogs(); - gradients_check_dialogs(); + brushes_check_dialogs (); + patterns_check_dialogs (); + gradients_check_dialogs (); open_plug_ins = g_slist_remove (open_plug_ins, plug_in); } @@ -1405,25 +1400,51 @@ plug_in_recv_message (GIOChannel *channel, GIOCondition cond, gpointer data) { - WireMessage msg; + gboolean got_message = FALSE; + + if ((PlugIn *) data != current_plug_in) + plug_in_push ((PlugIn *) data); - plug_in_push ((PlugIn*) data); if (current_readchannel == NULL) return TRUE; - memset (&msg, 0, sizeof (WireMessage)); - if (!wire_read_msg (current_readchannel, &msg)) - plug_in_close (current_plug_in, TRUE); - else + if (cond & (G_IO_IN | G_IO_PRI)) { - plug_in_handle_message (&msg); - wire_destroy (&msg); + WireMessage msg; + + memset (&msg, 0, sizeof (WireMessage)); + + if (!wire_read_msg (current_readchannel, &msg)) + { + plug_in_close (current_plug_in, TRUE); + } + else + { + plug_in_handle_message (&msg); + wire_destroy (&msg); + got_message = TRUE; + } + } + if (cond & (G_IO_ERR | G_IO_HUP)) + { + if (current_plug_in->open) + { + plug_in_close (current_plug_in, TRUE); + } + } + + if (!got_message) + g_message (_("Plug-In crashed: %s\n(%s)"), + g_basename (current_plug_in->args[0]), + current_plug_in->args[0]); + if (!current_plug_in->open) plug_in_destroy (current_plug_in); else plug_in_pop (); + return TRUE; } diff --git a/app/plug-in/plug-in.c b/app/plug-in/plug-in.c index ca5ffee17b..7cd04b9090 100644 --- a/app/plug-in/plug-in.c +++ b/app/plug-in/plug-in.c @@ -338,13 +338,11 @@ plug_in_init (void) } /* insert the proc defs */ - tmp = gimprc_proc_defs; - while (tmp) + for (tmp = gimprc_proc_defs; tmp; tmp = g_slist_next (tmp)) { proc_def = g_new (PlugInProcDef, 1); *proc_def = *((PlugInProcDef*) tmp->data); plug_in_proc_def_insert (proc_def, NULL); - tmp = tmp->next; } tmp = plug_in_defs; @@ -408,11 +406,9 @@ plug_in_init (void) g_print ("\n"); /* free up stuff */ - tmp = plug_in_defs; - while (tmp) + for (tmp = plug_in_defs; tmp; tmp = g_slist_next (tmp)) { plug_in_def = tmp->data; - tmp = tmp->next; plug_in_def_free (plug_in_def, FALSE); } @@ -1033,10 +1029,11 @@ plug_in_open (PlugIn *plug_in) if (!plug_in->synchronous) { - plug_in->input_id = g_io_add_watch (plug_in->my_read, - G_IO_IN | G_IO_PRI, - plug_in_recv_message, - plug_in); + plug_in->input_id = + g_io_add_watch (plug_in->my_read, + G_IO_IN | G_IO_PRI | G_IO_ERR | G_IO_HUP, + plug_in_recv_message, + plug_in); open_plug_ins = g_slist_prepend (open_plug_ins, plug_in); } @@ -1176,12 +1173,10 @@ plug_in_close (PlugIn *plug_in, GSList *list; PlugInProcDef *proc_def; - list = plug_in->temp_proc_defs; - while (list) + for (list = plug_in->temp_proc_defs; list; list = g_slist_next (list)) { proc_def = (PlugInProcDef *) list->data; plug_in_proc_def_remove (proc_def); - list = list->next; } g_slist_free (plug_in->temp_proc_defs); @@ -1189,9 +1184,9 @@ plug_in_close (PlugIn *plug_in, } /* Close any dialogs that this plugin might have opened */ - brushes_check_dialogs(); - patterns_check_dialogs(); - gradients_check_dialogs(); + brushes_check_dialogs (); + patterns_check_dialogs (); + gradients_check_dialogs (); open_plug_ins = g_slist_remove (open_plug_ins, plug_in); } @@ -1405,25 +1400,51 @@ plug_in_recv_message (GIOChannel *channel, GIOCondition cond, gpointer data) { - WireMessage msg; + gboolean got_message = FALSE; + + if ((PlugIn *) data != current_plug_in) + plug_in_push ((PlugIn *) data); - plug_in_push ((PlugIn*) data); if (current_readchannel == NULL) return TRUE; - memset (&msg, 0, sizeof (WireMessage)); - if (!wire_read_msg (current_readchannel, &msg)) - plug_in_close (current_plug_in, TRUE); - else + if (cond & (G_IO_IN | G_IO_PRI)) { - plug_in_handle_message (&msg); - wire_destroy (&msg); + WireMessage msg; + + memset (&msg, 0, sizeof (WireMessage)); + + if (!wire_read_msg (current_readchannel, &msg)) + { + plug_in_close (current_plug_in, TRUE); + } + else + { + plug_in_handle_message (&msg); + wire_destroy (&msg); + got_message = TRUE; + } + } + if (cond & (G_IO_ERR | G_IO_HUP)) + { + if (current_plug_in->open) + { + plug_in_close (current_plug_in, TRUE); + } + } + + if (!got_message) + g_message (_("Plug-In crashed: %s\n(%s)"), + g_basename (current_plug_in->args[0]), + current_plug_in->args[0]); + if (!current_plug_in->open) plug_in_destroy (current_plug_in); else plug_in_pop (); + return TRUE; } diff --git a/app/plug-in/plug-ins.c b/app/plug-in/plug-ins.c index ca5ffee17b..7cd04b9090 100644 --- a/app/plug-in/plug-ins.c +++ b/app/plug-in/plug-ins.c @@ -338,13 +338,11 @@ plug_in_init (void) } /* insert the proc defs */ - tmp = gimprc_proc_defs; - while (tmp) + for (tmp = gimprc_proc_defs; tmp; tmp = g_slist_next (tmp)) { proc_def = g_new (PlugInProcDef, 1); *proc_def = *((PlugInProcDef*) tmp->data); plug_in_proc_def_insert (proc_def, NULL); - tmp = tmp->next; } tmp = plug_in_defs; @@ -408,11 +406,9 @@ plug_in_init (void) g_print ("\n"); /* free up stuff */ - tmp = plug_in_defs; - while (tmp) + for (tmp = plug_in_defs; tmp; tmp = g_slist_next (tmp)) { plug_in_def = tmp->data; - tmp = tmp->next; plug_in_def_free (plug_in_def, FALSE); } @@ -1033,10 +1029,11 @@ plug_in_open (PlugIn *plug_in) if (!plug_in->synchronous) { - plug_in->input_id = g_io_add_watch (plug_in->my_read, - G_IO_IN | G_IO_PRI, - plug_in_recv_message, - plug_in); + plug_in->input_id = + g_io_add_watch (plug_in->my_read, + G_IO_IN | G_IO_PRI | G_IO_ERR | G_IO_HUP, + plug_in_recv_message, + plug_in); open_plug_ins = g_slist_prepend (open_plug_ins, plug_in); } @@ -1176,12 +1173,10 @@ plug_in_close (PlugIn *plug_in, GSList *list; PlugInProcDef *proc_def; - list = plug_in->temp_proc_defs; - while (list) + for (list = plug_in->temp_proc_defs; list; list = g_slist_next (list)) { proc_def = (PlugInProcDef *) list->data; plug_in_proc_def_remove (proc_def); - list = list->next; } g_slist_free (plug_in->temp_proc_defs); @@ -1189,9 +1184,9 @@ plug_in_close (PlugIn *plug_in, } /* Close any dialogs that this plugin might have opened */ - brushes_check_dialogs(); - patterns_check_dialogs(); - gradients_check_dialogs(); + brushes_check_dialogs (); + patterns_check_dialogs (); + gradients_check_dialogs (); open_plug_ins = g_slist_remove (open_plug_ins, plug_in); } @@ -1405,25 +1400,51 @@ plug_in_recv_message (GIOChannel *channel, GIOCondition cond, gpointer data) { - WireMessage msg; + gboolean got_message = FALSE; + + if ((PlugIn *) data != current_plug_in) + plug_in_push ((PlugIn *) data); - plug_in_push ((PlugIn*) data); if (current_readchannel == NULL) return TRUE; - memset (&msg, 0, sizeof (WireMessage)); - if (!wire_read_msg (current_readchannel, &msg)) - plug_in_close (current_plug_in, TRUE); - else + if (cond & (G_IO_IN | G_IO_PRI)) { - plug_in_handle_message (&msg); - wire_destroy (&msg); + WireMessage msg; + + memset (&msg, 0, sizeof (WireMessage)); + + if (!wire_read_msg (current_readchannel, &msg)) + { + plug_in_close (current_plug_in, TRUE); + } + else + { + plug_in_handle_message (&msg); + wire_destroy (&msg); + got_message = TRUE; + } + } + if (cond & (G_IO_ERR | G_IO_HUP)) + { + if (current_plug_in->open) + { + plug_in_close (current_plug_in, TRUE); + } + } + + if (!got_message) + g_message (_("Plug-In crashed: %s\n(%s)"), + g_basename (current_plug_in->args[0]), + current_plug_in->args[0]); + if (!current_plug_in->open) plug_in_destroy (current_plug_in); else plug_in_pop (); + return TRUE; } diff --git a/app/plug_in.c b/app/plug_in.c index ca5ffee17b..7cd04b9090 100644 --- a/app/plug_in.c +++ b/app/plug_in.c @@ -338,13 +338,11 @@ plug_in_init (void) } /* insert the proc defs */ - tmp = gimprc_proc_defs; - while (tmp) + for (tmp = gimprc_proc_defs; tmp; tmp = g_slist_next (tmp)) { proc_def = g_new (PlugInProcDef, 1); *proc_def = *((PlugInProcDef*) tmp->data); plug_in_proc_def_insert (proc_def, NULL); - tmp = tmp->next; } tmp = plug_in_defs; @@ -408,11 +406,9 @@ plug_in_init (void) g_print ("\n"); /* free up stuff */ - tmp = plug_in_defs; - while (tmp) + for (tmp = plug_in_defs; tmp; tmp = g_slist_next (tmp)) { plug_in_def = tmp->data; - tmp = tmp->next; plug_in_def_free (plug_in_def, FALSE); } @@ -1033,10 +1029,11 @@ plug_in_open (PlugIn *plug_in) if (!plug_in->synchronous) { - plug_in->input_id = g_io_add_watch (plug_in->my_read, - G_IO_IN | G_IO_PRI, - plug_in_recv_message, - plug_in); + plug_in->input_id = + g_io_add_watch (plug_in->my_read, + G_IO_IN | G_IO_PRI | G_IO_ERR | G_IO_HUP, + plug_in_recv_message, + plug_in); open_plug_ins = g_slist_prepend (open_plug_ins, plug_in); } @@ -1176,12 +1173,10 @@ plug_in_close (PlugIn *plug_in, GSList *list; PlugInProcDef *proc_def; - list = plug_in->temp_proc_defs; - while (list) + for (list = plug_in->temp_proc_defs; list; list = g_slist_next (list)) { proc_def = (PlugInProcDef *) list->data; plug_in_proc_def_remove (proc_def); - list = list->next; } g_slist_free (plug_in->temp_proc_defs); @@ -1189,9 +1184,9 @@ plug_in_close (PlugIn *plug_in, } /* Close any dialogs that this plugin might have opened */ - brushes_check_dialogs(); - patterns_check_dialogs(); - gradients_check_dialogs(); + brushes_check_dialogs (); + patterns_check_dialogs (); + gradients_check_dialogs (); open_plug_ins = g_slist_remove (open_plug_ins, plug_in); } @@ -1405,25 +1400,51 @@ plug_in_recv_message (GIOChannel *channel, GIOCondition cond, gpointer data) { - WireMessage msg; + gboolean got_message = FALSE; + + if ((PlugIn *) data != current_plug_in) + plug_in_push ((PlugIn *) data); - plug_in_push ((PlugIn*) data); if (current_readchannel == NULL) return TRUE; - memset (&msg, 0, sizeof (WireMessage)); - if (!wire_read_msg (current_readchannel, &msg)) - plug_in_close (current_plug_in, TRUE); - else + if (cond & (G_IO_IN | G_IO_PRI)) { - plug_in_handle_message (&msg); - wire_destroy (&msg); + WireMessage msg; + + memset (&msg, 0, sizeof (WireMessage)); + + if (!wire_read_msg (current_readchannel, &msg)) + { + plug_in_close (current_plug_in, TRUE); + } + else + { + plug_in_handle_message (&msg); + wire_destroy (&msg); + got_message = TRUE; + } + } + if (cond & (G_IO_ERR | G_IO_HUP)) + { + if (current_plug_in->open) + { + plug_in_close (current_plug_in, TRUE); + } + } + + if (!got_message) + g_message (_("Plug-In crashed: %s\n(%s)"), + g_basename (current_plug_in->args[0]), + current_plug_in->args[0]); + if (!current_plug_in->open) plug_in_destroy (current_plug_in); else plug_in_pop (); + return TRUE; } diff --git a/libgimp/gimp.c b/libgimp/gimp.c index 2d0b6e6909..e6ce8e25d5 100644 --- a/libgimp/gimp.c +++ b/libgimp/gimp.c @@ -20,6 +20,7 @@ #include #include +#include #include #include #include @@ -31,6 +32,9 @@ #ifdef HAVE_SYS_PARAM_H #include #endif +#ifdef HAVE_SYS_WAIT_H +#include +#endif #ifdef HAVE_UNISTD_H #include #endif @@ -77,17 +81,24 @@ void gimp_read_expect_msg (WireMessage *msg, gint type); #ifndef G_OS_WIN32 -static void gimp_plugin_signalhandler (gint signum); +static void gimp_plugin_sigfatal_handler (gint sig_num); +static void gimp_plugin_sigchld_handler (gint sig_num); #endif -static int gimp_write (GIOChannel *channel , guint8 *buf, gulong count); -static int gimp_flush (GIOChannel *channel); -static void gimp_loop (void); -static void gimp_config (GPConfig *config); -static void gimp_proc_run (GPProcRun *proc_run); -static void gimp_temp_proc_run (GPProcRun *proc_run); -static void gimp_message_func (gchar *str); -static void gimp_process_message (WireMessage *msg); -static void gimp_close (void); +static gboolean gimp_plugin_io_error_handler (GIOChannel *channel, + GIOCondition cond, + gpointer data); + +static gint gimp_write (GIOChannel *channel, + guint8 *buf, + gulong count); +static gint gimp_flush (GIOChannel *channel); +static void gimp_loop (void); +static void gimp_config (GPConfig *config); +static void gimp_proc_run (GPProcRun *proc_run); +static void gimp_temp_proc_run (GPProcRun *proc_run); +static void gimp_message_func (gchar *str); +static void gimp_process_message (WireMessage *msg); +static void gimp_close (void); GIOChannel *_readchannel = NULL; @@ -192,28 +203,27 @@ gimp_main (int argc, progname = argv[0]; + g_set_prgname (g_basename (progname)); + #ifndef G_OS_WIN32 /* No use catching these on Win32, the user won't get any meaningful * stack trace from glib anyhow. It's better to let Windows inform * about the program error, and offer debugging if the plug-in * has been built with MSVC, and the user has MSVC installed. */ - gimp_signal_private (SIGHUP, gimp_plugin_signalhandler, - SA_RESETHAND | SA_NODEFER); - gimp_signal_private (SIGINT, gimp_plugin_signalhandler, - SA_RESETHAND | SA_NODEFER); - gimp_signal_private (SIGQUIT, gimp_plugin_signalhandler, - SA_RESETHAND | SA_NODEFER); - gimp_signal_private (SIGBUS, gimp_plugin_signalhandler, - SA_RESETHAND | SA_NODEFER); - gimp_signal_private (SIGSEGV, gimp_plugin_signalhandler, - SA_RESETHAND | SA_NODEFER); - gimp_signal_private (SIGPIPE, gimp_plugin_signalhandler, - SA_RESETHAND | SA_NODEFER); - gimp_signal_private (SIGTERM, gimp_plugin_signalhandler, - SA_RESETHAND | SA_NODEFER); - gimp_signal_private (SIGFPE, gimp_plugin_signalhandler, - SA_RESETHAND | SA_NODEFER); + gimp_signal_private (SIGHUP, gimp_plugin_sigfatal_handler, 0); + gimp_signal_private (SIGINT, gimp_plugin_sigfatal_handler, 0); + gimp_signal_private (SIGQUIT, gimp_plugin_sigfatal_handler, 0); + gimp_signal_private (SIGBUS, gimp_plugin_sigfatal_handler, 0); + gimp_signal_private (SIGSEGV, gimp_plugin_sigfatal_handler, 0); + gimp_signal_private (SIGTERM, gimp_plugin_sigfatal_handler, 0); + gimp_signal_private (SIGFPE, gimp_plugin_sigfatal_handler, 0); + + /* Ignore SIGPIPE from crashing Gimp */ + gimp_signal_private (SIGPIPE, SIG_IGN, 0); + + /* Restart syscalls interrupted by SIGCHLD */ + gimp_signal_private (SIGCHLD, gimp_plugin_sigchld_handler, SA_RESTART); #endif #ifndef G_OS_WIN32 @@ -255,6 +265,11 @@ gimp_main (int argc, temp_proc_ht = g_hash_table_new (&g_str_hash, &g_str_equal); + g_io_add_watch (_readchannel, + G_IO_ERR | G_IO_HUP, + gimp_plugin_io_error_handler, + NULL); + gimp_loop (); return 0; } @@ -1153,39 +1168,63 @@ gimp_request_wakeups (void) #ifndef G_OS_WIN32 static void -gimp_plugin_signalhandler (gint signum) +gimp_plugin_sigfatal_handler (gint sig_num) { - static gboolean caught_fatal_sig = FALSE; - - if (caught_fatal_sig) - kill (getpid (), signum); - - caught_fatal_sig = TRUE; - - fprintf (stderr, "\n%s: %s caught\n", progname, g_strsignal (signum)); - - switch (signum) + switch (sig_num) { -#ifdef SIGBUS - case SIGBUS: -#endif -#ifdef SIGSEGV - case SIGSEGV: -#endif -#ifdef SIGFPE - case SIGFPE: -#endif - case 123456: /* Must have some case value... */ - g_on_error_query (progname); + case SIGHUP: + case SIGINT: + case SIGQUIT: + case SIGABRT: + case SIGTERM: + g_print ("%s terminated: %s\n", progname, g_strsignal (sig_num)); break; + + case SIGBUS: + case SIGSEGV: + case SIGFPE: + case SIGPIPE: default: + g_print ("%s: fatal error: %s\n", progname, g_strsignal (sig_num)); + if (TRUE) + { + sigset_t sigset; + + sigemptyset (&sigset); + sigprocmask (SIG_SETMASK, &sigset, NULL); + g_on_error_query (progname); + } break; } gimp_quit (); } + +static void +gimp_plugin_sigchld_handler (gint sig_num) +{ + gint pid; + gint status; + + while (TRUE) + { + pid = waitpid (WAIT_ANY, &status, WNOHANG); + + if (pid <= 0) + break; + } +} #endif +static gboolean +gimp_plugin_io_error_handler (GIOChannel *channel, + GIOCondition cond, + gpointer data) +{ + g_print ("%s: fatal error: GIMP crashed\n", progname); + gimp_quit (); +} + static int gimp_write (GIOChannel *channel, guint8 *buf, diff --git a/libgimp/gimpwire.c b/libgimp/gimpwire.c index 4fa5dc5552..0be4a6162e 100644 --- a/libgimp/gimpwire.c +++ b/libgimp/gimpwire.c @@ -113,7 +113,7 @@ wire_read (GIOChannel *channel, { if (!(* wire_read_func) (channel, buf, count)) { - g_warning ("wire_read: error"); + g_warning ("%s: wire_read: error", g_get_prgname ()); wire_error_val = TRUE; return FALSE; } @@ -132,14 +132,14 @@ wire_read (GIOChannel *channel, if (error != G_IO_ERROR_NONE) { - g_warning ("wire_read: error"); + g_warning ("%s: wire_read: error", g_get_prgname ()); wire_error_val = TRUE; return FALSE; } if (bytes == 0) { - g_warning ("wire_read: unexpected EOF (plug-in crashed?)"); + g_warning ("%s: wire_read: unexpected EOF", g_get_prgname ()); wire_error_val = TRUE; return FALSE; } @@ -161,7 +161,7 @@ wire_write (GIOChannel *channel, { if (!(* wire_write_func) (channel, buf, count)) { - g_warning ("wire_write: error"); + g_warning ("%s: wire_write: error", g_get_prgname ()); wire_error_val = TRUE; return FALSE; } @@ -180,7 +180,7 @@ wire_write (GIOChannel *channel, if (error != G_IO_ERROR_NONE) { - g_warning ("wire_write: error"); + g_warning ("%s: wire_write: error", g_get_prgname ()); wire_error_val = TRUE; return FALSE; } diff --git a/libgimpbase/gimpwire.c b/libgimpbase/gimpwire.c index 4fa5dc5552..0be4a6162e 100644 --- a/libgimpbase/gimpwire.c +++ b/libgimpbase/gimpwire.c @@ -113,7 +113,7 @@ wire_read (GIOChannel *channel, { if (!(* wire_read_func) (channel, buf, count)) { - g_warning ("wire_read: error"); + g_warning ("%s: wire_read: error", g_get_prgname ()); wire_error_val = TRUE; return FALSE; } @@ -132,14 +132,14 @@ wire_read (GIOChannel *channel, if (error != G_IO_ERROR_NONE) { - g_warning ("wire_read: error"); + g_warning ("%s: wire_read: error", g_get_prgname ()); wire_error_val = TRUE; return FALSE; } if (bytes == 0) { - g_warning ("wire_read: unexpected EOF (plug-in crashed?)"); + g_warning ("%s: wire_read: unexpected EOF", g_get_prgname ()); wire_error_val = TRUE; return FALSE; } @@ -161,7 +161,7 @@ wire_write (GIOChannel *channel, { if (!(* wire_write_func) (channel, buf, count)) { - g_warning ("wire_write: error"); + g_warning ("%s: wire_write: error", g_get_prgname ()); wire_error_val = TRUE; return FALSE; } @@ -180,7 +180,7 @@ wire_write (GIOChannel *channel, if (error != G_IO_ERROR_NONE) { - g_warning ("wire_write: error"); + g_warning ("%s: wire_write: error", g_get_prgname ()); wire_error_val = TRUE; return FALSE; } diff --git a/plug-ins/helpbrowser/helpbrowser.c b/plug-ins/helpbrowser/helpbrowser.c index 348e23d21d..508404512b 100644 --- a/plug-ins/helpbrowser/helpbrowser.c +++ b/plug-ins/helpbrowser/helpbrowser.c @@ -716,7 +716,7 @@ open_browser_dialog (gchar *locale, gint success; guint i; - gimp_ui_init ("webbrowser", TRUE); + gimp_ui_init ("helpbrowser", TRUE); root_dir = g_strconcat (gimp_data_directory(), G_DIR_SEPARATOR_S, GIMP_HELP_PREFIX, NULL);