From e90c98587bf076547b6aa060d04501330bd2bfde Mon Sep 17 00:00:00 2001 From: Eliot Horowitz Date: Tue, 25 Aug 2009 17:00:01 -0400 Subject: [PATCH] try jmp signal handler --- shell/dbshell.cpp | 87 +++++++++++++++++++++++++++-------------------- 1 file changed, 51 insertions(+), 36 deletions(-) diff --git a/shell/dbshell.cpp b/shell/dbshell.cpp index 4d43532539f..969f25ef3db 100644 --- a/shell/dbshell.cpp +++ b/shell/dbshell.cpp @@ -5,6 +5,7 @@ #ifdef USE_READLINE #include #include +#include #endif #include "../scripting/engine.h" @@ -15,17 +16,13 @@ extern const char * jsconcatcode; string historyFile; - -class Interrupt : public mongo::DBException { -public: - virtual const char * what() const throw() { - return "Interrupt exception"; - } -}; +bool gotInterrupted = 0; +bool inMultiLine = 0; void shellHistoryInit(){ #ifdef USE_READLINE - + rl_set_signals(); + cout << "yo: " << rl_catch_signals << endl; stringstream ss; char * h = getenv( "HOME" ); if ( h ) @@ -35,6 +32,7 @@ void shellHistoryInit(){ using_history(); read_history( historyFile.c_str() ); + #else cout << "type \"exit\" to exit" << endl; #endif @@ -51,32 +49,51 @@ void shellHistoryAdd( const char * line ){ add_history( line ); #endif } -char * shellReadline( const char * prompt ){ -#ifdef USE_READLINE - return readline( prompt ); -#else - printf( prompt ); - char * buf = new char[1024]; - char * l = fgets( buf , 1024 , stdin ); - int len = strlen( buf ); - buf[len-1] = 0; - return l; -#endif + +jmp_buf jbuf; + +void intr( int sig ){ + longjmp( jbuf , 1 ); } -#if !defined(_WIN32) -#include - - void quitNicely( int sig ){ - if ( sig == SIGINT ) - throw Interrupt(); + if ( sig == SIGINT && inMultiLine ){ + gotInterrupted = 1; + return; + } if ( sig == SIGPIPE ) mongo::rawOut( "mongo got signal SIGPIPE\n" ); shellHistoryDone(); exit(0); } +char * shellReadline( const char * prompt , int handlesigint = 0 ){ +#ifdef USE_READLINE + if ( ! handlesigint ) + return readline( prompt ); + if ( setjmp( jbuf ) ){ + gotInterrupted = 1; + sigrelse(SIGINT); + signal( SIGINT , quitNicely ); + return 0; + } + signal( SIGINT , intr ); + char * ret = readline( prompt ); + signal( SIGINT , quitNicely ); + return ret; +#else + printf( prompt ); + char * buf = new char[1024]; + char * l = fgets( buf , 1024 , stdin ); + int len = strlen( buf ); + buf[len-1] = 0; + return l; +#endif +} + +#if !defined(_WIN32) +#include + void quitAbruptly( int sig ) { ostringstream ossSig; ossSig << "mongo got signal " << sig << " (" << strsignal( sig ) << "), stack trace: " << endl; @@ -166,8 +183,11 @@ public: string finishCode( string code ){ while ( ! isBalanced( code ) ){ + inMultiLine = 1; code += "\n"; - char * line = shellReadline("... " ); + char * line = shellReadline("... " , 1 ); + if ( gotInterrupted ) + return ""; if ( ! line ) return ""; code += line; @@ -356,9 +376,10 @@ int _main(int argc, char* argv[]) { //v8::Handle shellHelper = baseContext_->Global()->Get( v8::String::New( "shellHelper" ) )->ToObject(); while ( 1 ){ - + inMultiLine = 0; + gotInterrupted = 0; char * line = shellReadline( "> " ); - + if ( line ) while ( line[0] == ' ' ) line++; @@ -375,10 +396,8 @@ int _main(int argc, char* argv[]) { if ( code.size() == 0 ) continue; - try { - code = finishCode( code ); - } - catch ( Interrupt& i ){ + code = finishCode( code ); + if ( gotInterrupted ){ cout << endl; continue; } @@ -421,10 +440,6 @@ int main(int argc, char* argv[]) { try { return _main( argc , argv ); } - catch ( Interrupt& i ){ - shellHistoryDone(); - exit(0); - } catch ( mongo::DBException& e ){ cerr << "exception: " << e.what() << endl; }