Skip to content

Commit c74003e

Browse files
author
wonder
committedOct 24, 2007
Fix for ticket #110.
To protect the process from being terminated by GRASS (>= 6.3), we use setjmp/longjmp functions. git-svn-id: http://svn.osgeo.org/qgis/trunk/qgis@7299 c8812cc2-4d05-0410-92ff-de0c093fc19c

File tree

3 files changed

+39
-6
lines changed

3 files changed

+39
-6
lines changed
 

‎src/plugins/grass/qgsgrassselect.cpp

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -394,8 +394,19 @@ QStringList QgsGrassSelect::vectorLayers ( QString gisdbase,
394394
QgsGrass::resetError();
395395
Vect_set_open_level (2);
396396
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+
}
399410

400411
if ( QgsGrass::getError() == QgsGrass::FATAL ) {
401412
std::cerr << "Cannot open GRASS vector: " << QgsGrass::getErrorMessage().toLocal8Bit().data() << std::endl;

‎src/providers/grass/qgsgrass.cpp

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -347,18 +347,26 @@ QString QgsGrass::mMapsetLock;
347347
QString QgsGrass::mGisrc;
348348
QString QgsGrass::mTmp;
349349

350+
jmp_buf QgsGrass::mFatalErrorEnv;
351+
350352
int QgsGrass::error_routine ( char *msg, int fatal) {
351353
return error_routine((const char*) msg, fatal);
352354
}
353355

354356
int QgsGrass::error_routine ( const char *msg, int fatal) {
355357
std::cerr << "error_routine (fatal = " << fatal << "): " << msg << std::endl;
356358

357-
if ( fatal ) error = FATAL;
358-
else error = WARNING;
359-
360359
error_message = msg;
361360

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+
362370
return 1;
363371
}
364372

@@ -374,6 +382,12 @@ QString QgsGrass::getErrorMessage ( void ) {
374382
return error_message;
375383
}
376384

385+
jmp_buf& QgsGrass::fatalErrorEnv()
386+
{
387+
return mFatalErrorEnv;
388+
}
389+
390+
377391
QString QgsGrass::openMapset ( QString gisdbase, QString location, QString mapset )
378392
{
379393
#ifdef QGISDEBUG

‎src/providers/grass/qgsgrass.h

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,8 @@ extern "C" {
2222
#include <grass/form.h>
2323
}
2424

25+
#include <setjmp.h>
26+
2527
/*!
2628
Methods for C library initialization and error handling.
2729
*/
@@ -151,7 +153,10 @@ class QgsGrass {
151153
static int versionMinor();
152154
static int versionRelease();
153155
static QString versionString();
156+
157+
static jmp_buf& fatalErrorEnv();
154158

159+
155160
private:
156161
static int initialized; // Set to 1 after initialization
157162
static bool active; // is active mode
@@ -175,7 +180,10 @@ class QgsGrass {
175180
// Current mapset GISRC file path
176181
static QString mGisrc;
177182
// 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;
179187
};
180188

181189
#endif // QGSGRASS_H

0 commit comments

Comments
 (0)
Please sign in to comment.