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
This commit is contained in:
wonder 2007-10-24 18:10:18 +00:00
parent fa1a8bc323
commit c74003e8fe
3 changed files with 39 additions and 6 deletions

View File

@ -394,8 +394,19 @@ QStringList QgsGrassSelect::vectorLayers ( QString gisdbase,
QgsGrass::resetError();
Vect_set_open_level (2);
struct Map_info map;
int level = Vect_open_old_head (&map, (char *) mapName.ascii(),
int level;
// Mechanism to recover from fatal errors in GRASS
// Since fatal error routine in GRASS >= 6.3 terminates the process,
// we use setjmp() to set recovery place in case of a fatal error.
// Call to setjmp() returns 0 first time. In case of fatal error,
// our error routine uses longjmp() to come back to this context,
// this time setjmp() will return non-zero value and we can continue...
if (setjmp(QgsGrass::fatalErrorEnv()) == 0)
{
level = Vect_open_old_head (&map, (char *) mapName.ascii(),
(char *) mapset.ascii());
}
if ( QgsGrass::getError() == QgsGrass::FATAL ) {
std::cerr << "Cannot open GRASS vector: " << QgsGrass::getErrorMessage().toLocal8Bit().data() << std::endl;

View File

@ -347,6 +347,8 @@ QString QgsGrass::mMapsetLock;
QString QgsGrass::mGisrc;
QString QgsGrass::mTmp;
jmp_buf QgsGrass::mFatalErrorEnv;
int QgsGrass::error_routine ( char *msg, int fatal) {
return error_routine((const char*) msg, fatal);
}
@ -354,11 +356,17 @@ int QgsGrass::error_routine ( char *msg, int fatal) {
int QgsGrass::error_routine ( const char *msg, int fatal) {
std::cerr << "error_routine (fatal = " << fatal << "): " << msg << std::endl;
if ( fatal ) error = FATAL;
else error = WARNING;
error_message = msg;
if ( fatal )
{
error = FATAL;
// we have to do a long jump here, otherwise GRASS >= 6.3 will kill our process
longjmp(mFatalErrorEnv, 1);
}
else
error = WARNING;
return 1;
}
@ -374,6 +382,12 @@ QString QgsGrass::getErrorMessage ( void ) {
return error_message;
}
jmp_buf& QgsGrass::fatalErrorEnv()
{
return mFatalErrorEnv;
}
QString QgsGrass::openMapset ( QString gisdbase, QString location, QString mapset )
{
#ifdef QGISDEBUG

View File

@ -22,6 +22,8 @@ extern "C" {
#include <grass/form.h>
}
#include <setjmp.h>
/*!
Methods for C library initialization and error handling.
*/
@ -152,6 +154,9 @@ public:
static int versionRelease();
static QString versionString();
static jmp_buf& fatalErrorEnv();
private:
static int initialized; // Set to 1 after initialization
static bool active; // is active mode
@ -176,6 +181,9 @@ private:
static QString mGisrc;
// Temporary directory where GISRC and sockets are stored
static QString mTmp;
// Context saved before a call to routine that can produce a fatal error
static jmp_buf mFatalErrorEnv;
};
#endif // QGSGRASS_H