SQLite

Artifact [413d1b10]
Login

Artifact 413d1b10a5d94b0bdf1f13df5f6e6142a8d25e5c:

Attachment "control_c.patch" to ticket [1c67bd6c] added by anonymous 2012-12-23 22:00:29. (unpublished)
     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
   100
   101
   102
   103
   104
   105
   106
   107
   108
   109
   110
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;