File tree Expand file tree Collapse file tree 3 files changed +39
-6
lines changed Expand file tree Collapse file tree 3 files changed +39
-6
lines changed Original file line number Diff line number Diff line change @@ -394,8 +394,19 @@ QStringList QgsGrassSelect::vectorLayers ( QString gisdbase,
394
394
QgsGrass::resetError ();
395
395
Vect_set_open_level (2 );
396
396
struct Map_info map;
397
- int level = Vect_open_old_head (&map, (char *) mapName.ascii (),
398
- (char *) mapset.ascii ());
397
+ int level;
398
+
399
+ // Mechanism to recover from fatal errors in GRASS
400
+ // Since fatal error routine in GRASS >= 6.3 terminates the process,
401
+ // we use setjmp() to set recovery place in case of a fatal error.
402
+ // Call to setjmp() returns 0 first time. In case of fatal error,
403
+ // our error routine uses longjmp() to come back to this context,
404
+ // this time setjmp() will return non-zero value and we can continue...
405
+ if (setjmp (QgsGrass::fatalErrorEnv ()) == 0 )
406
+ {
407
+ level = Vect_open_old_head (&map, (char *) mapName.ascii (),
408
+ (char *) mapset.ascii ());
409
+ }
399
410
400
411
if ( QgsGrass::getError () == QgsGrass::FATAL ) {
401
412
std::cerr << " Cannot open GRASS vector: " << QgsGrass::getErrorMessage ().toLocal8Bit ().data () << std::endl;
Original file line number Diff line number Diff line change @@ -347,18 +347,26 @@ QString QgsGrass::mMapsetLock;
347
347
QString QgsGrass::mGisrc ;
348
348
QString QgsGrass::mTmp ;
349
349
350
+ jmp_buf QgsGrass::mFatalErrorEnv ;
351
+
350
352
int QgsGrass::error_routine ( char *msg, int fatal) {
351
353
return error_routine ((const char *) msg, fatal);
352
354
}
353
355
354
356
int QgsGrass::error_routine ( const char *msg, int fatal) {
355
357
std::cerr << " error_routine (fatal = " << fatal << " ): " << msg << std::endl;
356
358
357
- if ( fatal ) error = FATAL;
358
- else error = WARNING;
359
-
360
359
error_message = msg;
361
360
361
+ if ( fatal )
362
+ {
363
+ error = FATAL;
364
+ // we have to do a long jump here, otherwise GRASS >= 6.3 will kill our process
365
+ longjmp (mFatalErrorEnv , 1 );
366
+ }
367
+ else
368
+ error = WARNING;
369
+
362
370
return 1 ;
363
371
}
364
372
@@ -374,6 +382,12 @@ QString QgsGrass::getErrorMessage ( void ) {
374
382
return error_message;
375
383
}
376
384
385
+ jmp_buf & QgsGrass::fatalErrorEnv ()
386
+ {
387
+ return mFatalErrorEnv ;
388
+ }
389
+
390
+
377
391
QString QgsGrass::openMapset ( QString gisdbase, QString location, QString mapset )
378
392
{
379
393
#ifdef QGISDEBUG
Original file line number Diff line number Diff line change @@ -22,6 +22,8 @@ extern "C" {
22
22
#include < grass/form.h>
23
23
}
24
24
25
+ #include < setjmp.h>
26
+
25
27
/* !
26
28
Methods for C library initialization and error handling.
27
29
*/
@@ -151,7 +153,10 @@ class QgsGrass {
151
153
static int versionMinor ();
152
154
static int versionRelease ();
153
155
static QString versionString ();
156
+
157
+ static jmp_buf & fatalErrorEnv ();
154
158
159
+
155
160
private:
156
161
static int initialized; // Set to 1 after initialization
157
162
static bool active; // is active mode
@@ -175,7 +180,10 @@ class QgsGrass {
175
180
// Current mapset GISRC file path
176
181
static QString mGisrc ;
177
182
// Temporary directory where GISRC and sockets are stored
178
- static QString mTmp ;
183
+ static QString mTmp ;
184
+
185
+ // Context saved before a call to routine that can produce a fatal error
186
+ static jmp_buf mFatalErrorEnv ;
179
187
};
180
188
181
189
#endif // QGSGRASS_H
You can’t perform that action at this time.
0 commit comments