app/main.c libgimp/Makefile.am libgimp/gimp.c libgimp/gimpsignal.c (New )

2000-04-21 Garry R. Osgood <gosgood@idt.net>
* app/main.c
* libgimp/Makefile.am
* libgimp/gimp.c
* libgimp/gimpsignal.c (New )
* libgimp/gimpsignal.h (New )
Patch by Austin Donnelly <austin@gimp.org> to
address #2742. (I took the liberty of moving it to
libgimp for general consumption, & fixed a typo)
Thanks due to Tim Mooney
<mooney@dogbert.cc.ndsu.nodak.edu> for testing
this on various flavors of OSF/1 boxes where
#2742 seemed especially common.
This commit is contained in:
Garry R. Osgood 2000-04-21 16:42:11 +00:00 committed by Garry R. Osgood
parent 15ec8b9834
commit e079a173fc
8 changed files with 346 additions and 94 deletions

View File

@ -1,8 +1,28 @@
2000-04-21 Garry R. Osgood <gosgood@idt.net>
* app/main.c
* libgimp/Makefile.am
* libgimp/gimp.c
* libgimp/gimpsignal.c (New )
* libgimp/gimpsignal.h (New )
Patch by Austin Donnelly <austin@gimp.org> to address #2742. (I took
the liberty of moving it to libgimp for general consumption, & fixed a
typo) SYS5R4 unix's were failing when signals arrived at processes in
system calls, a behavior in accordance with POSIX specs. Patch
introduces a gimp_signal_private() workalike replacement for
signal(2), layered over sigaction(2) which internally requests the
signal environment to restart system calls instead of failing. This is
POSIX spec 1170 extension behavior, but one that appears to be generally
supported. Thanks due to Tim Mooney <mooney@dogbert.cc.ndsu.nodak.edu>
for testing this on various flavors of OSF/1 boxes where #2742 seemed
especially common.
2000-04-20 Nick Lamb <njl195@zepler.org.uk>
* plug-ins/common/png.c: Revert Sven's changes, I am not that
silly Sven, read the code more carefully and THINK about it.
We do not want to leak Gimp Images.
* plug-ins/common/png.c: Revert Sven's changes, I am
not that silly Sven, read the code more carefully
and THINK about it. We do not want to leak Gimp
Images.
2000-04-20 Sven Neumann <sven@gimp.org>

View File

@ -40,6 +40,10 @@
#include "libgimp/gimpfeatures.h"
#include "libgimp/gimpenv.h"
#ifndef G_OS_WIN32
#include "libgimp/gimpsignal.h"
#endif
#include "appenv.h"
#include "app_procs.h"
#include "errors.h"
@ -50,11 +54,10 @@
#ifdef G_OS_WIN32
#include <windows.h>
#else
static RETSIGTYPE on_signal (gint);
#ifdef SIGCHLD
static RETSIGTYPE on_sig_child (gint);
#endif
void on_signal (gint);
void on_sig_child (gint);
#endif
static void init (void);
static void on_error (const gchar *domain,
GLogLevelFlags flags,
@ -316,6 +319,7 @@ main (int argc,
g_set_message_handler ((GPrintFunc) gimp_message_func);
#ifndef G_OS_WIN32
/* 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
@ -324,38 +328,20 @@ main (int argc,
*/
/* Handle some signals */
#ifdef SIGHUP
signal (SIGHUP, on_signal);
#endif
#ifdef SIGINT
signal (SIGINT, on_signal);
#endif
#ifdef SIGQUIT
signal (SIGQUIT, on_signal);
#endif
#ifdef SIGABRT
signal (SIGABRT, on_signal);
#endif
#ifdef SIGBUS
signal (SIGBUS, on_signal);
#endif
#ifdef SIGSEGV
signal (SIGSEGV, on_signal);
#endif
#ifdef SIGPIPE
signal (SIGPIPE, on_signal);
#endif
#ifdef SIGTERM
signal (SIGTERM, on_signal);
#endif
#ifdef SIGFPE
signal (SIGFPE, on_signal);
#endif
#ifdef SIGCHLD
gimp_signal_syscallrestart (SIGHUP, on_signal);
gimp_signal_syscallrestart (SIGINT, on_signal);
gimp_signal_syscallrestart (SIGQUIT, on_signal);
gimp_signal_syscallrestart (SIGABRT, on_signal);
gimp_signal_syscallrestart (SIGBUS, on_signal);
gimp_signal_syscallrestart (SIGSEGV, on_signal);
gimp_signal_syscallrestart (SIGPIPE, on_signal);
gimp_signal_syscallrestart (SIGTERM, on_signal);
gimp_signal_syscallrestart (SIGFPE, on_signal);
/* Handle child exits */
signal (SIGCHLD, on_sig_child);
#endif
gimp_signal_syscallrestart (SIGCHLD, on_sig_child);
#endif
@ -414,11 +400,13 @@ on_error (const gchar *domain,
gimp_fatal_error ("%s", msg);
}
static gboolean caught_fatal_sig = FALSE;
#ifndef G_OS_WIN32
static RETSIGTYPE
/* gimp core signal handler for fatal signals */
static gboolean caught_fatal_sig = FALSE;
static void
on_signal (gint sig_num)
{
if (caught_fatal_sig)
@ -427,59 +415,52 @@ on_signal (gint sig_num)
switch (sig_num)
{
#ifdef SIGHUP
case SIGHUP:
gimp_terminate ("sighup caught");
break;
#endif
#ifdef SIGINT
case SIGINT:
gimp_terminate ("sigint caught");
break;
#endif
#ifdef SIGQUIT
case SIGQUIT:
gimp_terminate ("sigquit caught");
break;
#endif
#ifdef SIGABRT
case SIGABRT:
gimp_terminate ("sigabrt caught");
break;
#endif
#ifdef SIGBUS
case SIGBUS:
gimp_fatal_error ("sigbus caught");
break;
#endif
#ifdef SIGSEGV
case SIGSEGV:
gimp_fatal_error ("sigsegv caught");
break;
#endif
#ifdef SIGPIPE
case SIGPIPE:
gimp_terminate ("sigpipe caught");
break;
#endif
#ifdef SIGTERM
case SIGTERM:
gimp_terminate ("sigterm caught");
break;
#endif
#ifdef SIGFPE
case SIGFPE:
gimp_fatal_error ("sigfpe caught");
break;
#endif
default:
gimp_fatal_error ("unknown signal");
break;
}
}
#ifdef SIGCHLD
static RETSIGTYPE
/* gimp core signal handler for death-of-child signals */
static void
on_sig_child (gint sig_num)
{
gint pid;
@ -492,6 +473,5 @@ on_sig_child (gint sig_num)
break;
}
}
#endif /* SIGCHLD */
#endif /* !G_OS_WIN32 */

View File

@ -47,6 +47,8 @@ libgimpi_a_SOURCES = \
gimpprotocol.h \
gimpquerybox.c \
gimpquerybox.h \
gimpsignal.c \
gimpsignal.h \
gimpsizeentry.c \
gimpsizeentry.h \
gimpunitmenu.c \

View File

@ -20,9 +20,13 @@
#include <locale.h>
#include <errno.h>
#include <signal.h>
#include <stdarg.h>
#include <stdio.h>
#ifndef G_OS_WIN32
#include "gimpsignal.h"
#else
#include <signal.h>
#endif
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
@ -73,17 +77,17 @@ void gimp_read_expect_msg (WireMessage *msg, gint type);
#ifndef G_OS_WIN32
static RETSIGTYPE gimp_signal (gint signum);
static void gimp_plugin_signalhandler (gint signum);
#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 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);
GIOChannel *_readchannel = NULL;
@ -193,26 +197,14 @@ gimp_main (int argc,
* about the program error, and offer debugging if the plug-in
* has been built with MSVC, and the user has MSVC installed.
*/
#ifdef SIGHUP
signal (SIGHUP, gimp_signal);
#endif
signal (SIGINT, gimp_signal);
#ifdef SIGQUIT
signal (SIGQUIT, gimp_signal);
#endif
#ifdef SIGBUS
signal (SIGBUS, gimp_signal);
#endif
#ifdef SIGSEGV
signal (SIGSEGV, gimp_signal);
#endif
#ifdef SIGPIPE
signal (SIGPIPE, gimp_signal);
#endif
signal (SIGTERM, gimp_signal);
#ifdef SIGFPE
signal (SIGFPE, gimp_signal);
#endif
gimp_signal_syscallrestart (SIGHUP, gimp_plugin_signalhandler);
gimp_signal_syscallrestart (SIGINT, gimp_plugin_signalhandler);
gimp_signal_syscallrestart (SIGQUIT, gimp_plugin_signalhandler);
gimp_signal_syscallrestart (SIGBUS, gimp_plugin_signalhandler);
gimp_signal_syscallrestart (SIGSEGV, gimp_plugin_signalhandler);
gimp_signal_syscallrestart (SIGPIPE, gimp_plugin_signalhandler);
gimp_signal_syscallrestart (SIGTERM, gimp_plugin_signalhandler);
gimp_signal_syscallrestart (SIGFPE, gimp_plugin_signalhandler);
#endif
#ifndef G_OS_WIN32
@ -1145,8 +1137,8 @@ gimp_request_wakeups (void)
}
#ifndef G_OS_WIN32
static RETSIGTYPE
gimp_signal (gint signum)
static void
gimp_plugin_signalhandler (gint signum)
{
static gboolean caught_fatal_sig = FALSE;

72
libgimp/gimpsignal.c Normal file
View File

@ -0,0 +1,72 @@
/* LIBGIMP - The GIMP Library
* Copyright (C) 1995-1997 Peter Mattis and Spencer Kimball
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*
* $Revision$
*/
#include "gimpsignal.h"
/**
* gimp_signal:
* @signum: selects signal to be handled see man 5 signal
* @handler: handler that maps to signum. Invoked by O/S.
* handler gets signal that caused invocation.
* @sa_flags: preferences. OR'ed SA_<xxx>. See signal.h
*
* This function furnishes a workalike for signal(2) but
* which internally invokes sigaction(2) after certain
* sa_flags are set; these primarily to ensure restarting
* of interrupted system calls. See sigaction(2) It is a
* aid to transition and not new development: that effort
* should employ sigaction directly. [<gosgood@idt.net> 18.04.2000]
*
* Cause handler to be run when signum is delivered. We
* use sigaction(2) rather than signal(2) so that we can control the
* signal hander's environment completely via sa_flags: some signal(2)
* implementations differ in their sematics, so we need to nail down
* exactly what we want. [<austin@gimp.org> 06.04.2000]
*
* Returns: RetSigType (a reference to a signal handling function)
*
*/
/* Courtesy of Austin Donnelly 06-04-2000 to address bug #2742 */
RetSigType
gimp_signal_private (gint signum, void (*gimp_sighandler)(int), gint sa_flags)
{
int ret;
struct sigaction sa;
struct sigaction osa;
/* this field is a union of sa_sighandler.sa_sighandler1 and */
/* sa_sigaction1 - don't set both at once... */
sa.sa_handler = gimp_sighandler;
/* Mask all signals while handler runs to avoid re-entrancy
* problems. */
sigfillset (&sa.sa_mask);
sa.sa_flags = sa_flags;
ret = sigaction (signum, &sa, &osa);
if (ret < 0)
gimp_fatal_error ("unable to set handler for signal %d\n", signum);
return osa.sa_handler;
}

57
libgimp/gimpsignal.h Normal file
View File

@ -0,0 +1,57 @@
/* LIBGIMP - The GIMP Library
* Copyright (C) 1995-2000 Peter Mattis and Spencer Kimball
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*
* $Revision$
*/
#ifndef __GIMP_SIGNAL_H__
#define __GIMP_SIGNAL_H__
/* A gimp-level interface to a Posix.1-compliant signal package lives here */
/* For 1.2, this gimp-level interface mostly passes through to posix calls */
/* without modification. Certain calls manipulate struct sigaction in */
/* ways useful to Gimp. */
#include <signal.h>
#include <glib.h>
/* RETSIGTYPE is a reference to a
* (signal handler) function that
* takes a signal ID and returns
* void. signal(2) returns such
* references; so does
* gimp_signal_private.
*/
typedef void (*RetSigType)(gint);
/* Internal implementation that can be */
/* DEFINEd into various flavors of */
/* signal(2) lookalikes. */
RetSigType gimp_signal_private (gint signum, void (*gimp_sighandler)(int), gint sa_flags);
/* the gimp_signal_syscallrestart() */
/* lookalike looks like signal(2) but */
/* quietly requests the restarting of */
/* system calls. Addresses #2742 */
# define gimp_signal_syscallrestart(x, y) gimp_signal_private ((x), (y), SA_RESTART)
#endif /* __GIMP_SIGNAL_H__ */

72
libgimpbase/gimpsignal.c Normal file
View File

@ -0,0 +1,72 @@
/* LIBGIMP - The GIMP Library
* Copyright (C) 1995-1997 Peter Mattis and Spencer Kimball
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*
* $Revision$
*/
#include "gimpsignal.h"
/**
* gimp_signal:
* @signum: selects signal to be handled see man 5 signal
* @handler: handler that maps to signum. Invoked by O/S.
* handler gets signal that caused invocation.
* @sa_flags: preferences. OR'ed SA_<xxx>. See signal.h
*
* This function furnishes a workalike for signal(2) but
* which internally invokes sigaction(2) after certain
* sa_flags are set; these primarily to ensure restarting
* of interrupted system calls. See sigaction(2) It is a
* aid to transition and not new development: that effort
* should employ sigaction directly. [<gosgood@idt.net> 18.04.2000]
*
* Cause handler to be run when signum is delivered. We
* use sigaction(2) rather than signal(2) so that we can control the
* signal hander's environment completely via sa_flags: some signal(2)
* implementations differ in their sematics, so we need to nail down
* exactly what we want. [<austin@gimp.org> 06.04.2000]
*
* Returns: RetSigType (a reference to a signal handling function)
*
*/
/* Courtesy of Austin Donnelly 06-04-2000 to address bug #2742 */
RetSigType
gimp_signal_private (gint signum, void (*gimp_sighandler)(int), gint sa_flags)
{
int ret;
struct sigaction sa;
struct sigaction osa;
/* this field is a union of sa_sighandler.sa_sighandler1 and */
/* sa_sigaction1 - don't set both at once... */
sa.sa_handler = gimp_sighandler;
/* Mask all signals while handler runs to avoid re-entrancy
* problems. */
sigfillset (&sa.sa_mask);
sa.sa_flags = sa_flags;
ret = sigaction (signum, &sa, &osa);
if (ret < 0)
gimp_fatal_error ("unable to set handler for signal %d\n", signum);
return osa.sa_handler;
}

57
libgimpbase/gimpsignal.h Normal file
View File

@ -0,0 +1,57 @@
/* LIBGIMP - The GIMP Library
* Copyright (C) 1995-2000 Peter Mattis and Spencer Kimball
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*
* $Revision$
*/
#ifndef __GIMP_SIGNAL_H__
#define __GIMP_SIGNAL_H__
/* A gimp-level interface to a Posix.1-compliant signal package lives here */
/* For 1.2, this gimp-level interface mostly passes through to posix calls */
/* without modification. Certain calls manipulate struct sigaction in */
/* ways useful to Gimp. */
#include <signal.h>
#include <glib.h>
/* RETSIGTYPE is a reference to a
* (signal handler) function that
* takes a signal ID and returns
* void. signal(2) returns such
* references; so does
* gimp_signal_private.
*/
typedef void (*RetSigType)(gint);
/* Internal implementation that can be */
/* DEFINEd into various flavors of */
/* signal(2) lookalikes. */
RetSigType gimp_signal_private (gint signum, void (*gimp_sighandler)(int), gint sa_flags);
/* the gimp_signal_syscallrestart() */
/* lookalike looks like signal(2) but */
/* quietly requests the restarting of */
/* system calls. Addresses #2742 */
# define gimp_signal_syscallrestart(x, y) gimp_signal_private ((x), (y), SA_RESTART)
#endif /* __GIMP_SIGNAL_H__ */