Radim Blazek wrote:
> >> > Also, currently the global error handler (G_set_error_routine) is
> >> > called before the non-exclusive handlers (G_add_error_handler), so
> >> > those will never be called if the global handler lonjmp()s out. The
> >> > global error handler isn't limited to fatal errors, but is also used
> >> > for messages and warnings.
> >>
> >> G_add_error_handler() is used by GRASS itself?
> >
> > The raster library installs a handler which calls Rast__unopen_all().
> > The vector and DBMI libraries provide interfaces to it, although I
> > don't know how (or if) these are used at present.
>
> It is desired that Rast__unopen_all() is not called before longjmp(),
> I think. I don't want to close all maps successfully opened before.
It can be removed with
G_remove_error_handler(Rast__error_handler, NULL);
But I still think that the global error handler is the wrong place for
a longjmp(). Its original purpose was to allow the standard
notification mechanism (stderr, log file, and/or email) to be replaced
with a custom mechanism.
Can you try the attached patch? The new function should be used like:
if (setjmp(*G_fatal_longjmp(1))) {
// this will be executed on fatal errors
}
--
Glynn Clements <[email protected]>
Index: include/defs/gis.h
===================================================================
--- include/defs/gis.h (revision 60521)
+++ include/defs/gis.h (working copy)
@@ -60,6 +60,7 @@
#include <stdarg.h>
#include <stdio.h>
+#include <setjmp.h>
#include <sys/types.h>
#include <sys/stat.h>
@@ -217,6 +218,7 @@
void G_switch_env(void);
/* error.c */
+jmp_buf *G_fatal_longjmp(int);
int G_info_format(void);
void G_message(const char *, ...) __attribute__ ((format(printf, 1, 2)));
void G_verbose_message(const char *, ...)
Index: lib/gis/error.c
===================================================================
--- lib/gis/error.c (revision 60521)
+++ lib/gis/error.c (working copy)
@@ -14,6 +14,7 @@
#include <stdlib.h>
#include <string.h>
+#include <setjmp.h>
#include <unistd.h>
#include <time.h>
#include <stdarg.h>
@@ -57,6 +58,15 @@
static int write_error(const char *, int, time_t, const char *);
static void log_error(const char *, int);
+static int fatal_longjmp;
+static jmp_buf fatal_jmp_buf;
+
+jmp_buf *G_fatal_longjmp(int enable)
+{
+ fatal_longjmp = enable;
+ return &fatal_jmp_buf;
+}
+
static void vfprint_error(int type, const char *template, va_list ap)
{
char buffer[2000]; /* G_asprintf does not work */
@@ -158,6 +168,11 @@
va_end(ap);
}
+ if (fatal_longjmp) {
+ busy = 0;
+ longjmp(fatal_jmp_buf, 1);
+ }
+
G__call_error_handlers();
/* Raise SIGABRT, useful for debugging only.
_______________________________________________
grass-dev mailing list
[email protected]
http://lists.osgeo.org/mailman/listinfo/grass-dev