Hello,

The SQLite Command Line Shell is documented
(http://www.sqlite.org/sessions/sqlite.html) to support interrupting a
long-running SQL statement by using the interrupt character (Control-C).

On Windows, the shell is terminated immediately by Control-C, rather than
interrupting the SQL statement.

Looking at the code in the "C source code as an amalgamation, version
3.8.8.3" from the current SQLite download page, I see that in shell.c, there
is a handler for SIGINT registered if SIGINT is defined:

#ifdef SIGINT
  signal(SIGINT, interrupt_handler);
#endif

SIGINT is defined in the signal.h header, but that header has been
deliberately excluded from shell.c on Windows:

#if !defined(_WIN32) && !defined(WIN32)
# include <signal.h>
# if !defined(__RTP__) && !defined(_WRS_KERNEL)
#  include <pwd.h>
# endif
# include <unistd.h>
# include <sys/types.h>
#endif

Including signal.h in shell.c causes the signal handler to be registered,
and I do get the interruption without process termination to a long-running
SQL command with Control-C as expected. However, this only works for the
first Control-C; a Control-C during a subsequent long-running SQL command
causes immediate process termination. signal(SIGINT) is also documented as
not being supported on MSDN, so I tried using the Windows-specific
SetConsoleCtrlHandler command to register a handler instead, and this
approach works correctly for subsequent interrupts too.

Incidentally, the handler will execute on a separate thread on Windows,
something to bear in mind if the shell isn't intended to be multi-threaded
(I know the SQLite library itself is documented to be thread-safe).

This is the diff for shell.c for the source version mentioned (first time
posting, I don't know whether attachments are permitted on this list, so
including inline):


757c757
< #ifdef SIGINT
---
> #if defined(SIGINT) || defined(_WIN32) || defined(WIN32)
766a767,782
>
> #if defined(_WIN32) || defined(WIN32)
> /*
> ** Windows event handler
> */
> BOOL WINAPI CtrlHandler(DWORD dwType){
>   switch( dwType ){
>     case CTRL_C_EVENT:
>       interrupt_handler(0);
>       return TRUE;
>
>     default:
>       return FALSE;
>   }
> }
> #endif
4207a4224,4225
> #elif defined(WIN32) || defined(_WIN32)
>   SetConsoleCtrlHandler(CtrlHandler, TRUE);


Kind regards,
David

Reply via email to