SQLite
Artifact Content
Not logged in

Artifact 413d1b10a5d94b0bdf1f13df5f6e6142a8d25e5c:

Attachment "control_c.patch" to ticket [1c67bd6ce9d7fd36] added by anonymous 2012-12-23 22:00:29.
Index: src/shell.c
===================================================================
--- src/shell.c
+++ src/shell.c
@@ -33,10 +33,11 @@
 #include <stdio.h>
 #include <assert.h>
 #include "sqlite3.h"
 #include <ctype.h>
 #include <stdarg.h>
+#include <setjmp.h>
 
 #if !defined(_WIN32) && !defined(WIN32)
 # include <signal.h>
 # if !defined(__RTP__) && !defined(_WRS_KERNEL)
 #  include <pwd.h>
@@ -56,10 +57,17 @@
 # define readline(p) local_getline(p,stdin,0)
 # define add_history(X)
 # define read_history(X)
 # define write_history(X)
 # define stifle_history(X)
+#endif
+
+#ifdef sigsetjmp
+#undef setjmp
+#define setjmp(x) sigsetjmp(x, 1)
+#define longjmp(x, y) siglongjmp(x, y)
+#define jmp_buf sigjmp_buf
 #endif
 
 #if defined(_WIN32) || defined(WIN32)
 # include <io.h>
 #define isatty(h) _isatty(h)
@@ -230,10 +238,21 @@
 ** by the SIGINT handler to interrupt database processing.
 */
 static sqlite3 *db = 0;
 
 /*
+** True if currently inside a call to readline.  Used by SIGINT
+** handler.
+*/
+static int in_readline = 0;
+
+/*
+** Used to break out of a call to readline
+*/
+static jmp_buf readline_jmp;
+
+/*
 ** True if an interrupt (Control-C) has been received.
 */
 static volatile int seenInterrupt = 0;
 
 /*
@@ -392,11 +411,15 @@
   if( zPrior && zPrior[0] ){
     zPrompt = continuePrompt;
   }else{
     zPrompt = mainPrompt;
   }
+  if (setjmp(readline_jmp))
+    return NULL;
+  in_readline = 1;
   zResult = readline(zPrompt);
+  in_readline = 0;
 #if defined(HAVE_READLINE) && HAVE_READLINE==1
   if( zResult && *zResult ) add_history(zResult);
 #endif
   return zResult;
 }
@@ -661,10 +684,14 @@
 */
 static void interrupt_handler(int NotUsed){
   UNUSED_PARAMETER(NotUsed);
   seenInterrupt = 1;
   if( db ) sqlite3_interrupt(db);
+  if ( in_readline ){
+    in_readline = 0;
+    longjmp(readline_jmp, 1);
+  }
 }
 #endif
 
 /*
 ** This is the callback routine that the shell
@@ -2630,11 +2657,20 @@
     fflush(p->out);
     free(zLine);
     zLine = one_input_line(zSql, in);
     if( zLine==0 ){
       /* End of input */
-      if( stdin_is_interactive ) printf("\n");
+      if( stdin_is_interactive ){
+        printf("\n");
+        if( seenInterrupt ){
+          seenInterrupt = 0;
+          free(zSql);
+          zSql = 0;
+          nSql = 0;
+          continue;
+        }
+      }
       break;
     }
     if( seenInterrupt ){
       if( in!=0 ) break;
       seenInterrupt = 0;