Attachment "control_c.patch" to
ticket [1c67bd6c]
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;