Commit 715ceb41 authored by unknown's avatar unknown

Bug#17926: mysql.exe crashes when ctrl-c is pressed in windows

SIGINT is handled in funny ways on windows, which could lead to problems when
Control-C was pressed in the client during a long-running query.  Now Control-C
during a query aborts that query (by sending KILL to the server on a second
connexion), while Control-C outside of a running query terminates the client.


client/mysql.cc:
  Bug#17926: mysql.exe crashes when ctrl-c is pressed in windows
  
  Rather than tear down the client right away, open a second connexion to server
  on SIGINT and send a KILL for the first connexion.  Only if we receive another
  SIGINT before the KILL goes through (or if no query was running in the first
  place) do we terminate the client.
parent 698bd7c4
...@@ -136,7 +136,8 @@ static my_bool info_flag=0,ignore_errors=0,wait_flag=0,quick=0, ...@@ -136,7 +136,8 @@ static my_bool info_flag=0,ignore_errors=0,wait_flag=0,quick=0,
tty_password= 0, opt_nobeep=0, opt_reconnect=1, tty_password= 0, opt_nobeep=0, opt_reconnect=1,
default_charset_used= 0, opt_secure_auth= 0, default_charset_used= 0, opt_secure_auth= 0,
default_pager_set= 0, opt_sigint_ignore= 0, default_pager_set= 0, opt_sigint_ignore= 0,
show_warnings = 0; show_warnings= 0;
static volatile int executing_query= 0, interrupted_query= 0;
static ulong opt_max_allowed_packet, opt_net_buffer_length; static ulong opt_max_allowed_packet, opt_net_buffer_length;
static uint verbose=0,opt_silent=0,opt_mysql_port=0, opt_local_infile=0; static uint verbose=0,opt_silent=0,opt_mysql_port=0, opt_local_infile=0;
static my_string opt_mysql_unix_port=0; static my_string opt_mysql_unix_port=0;
...@@ -338,6 +339,7 @@ static void end_timer(ulong start_time,char *buff); ...@@ -338,6 +339,7 @@ static void end_timer(ulong start_time,char *buff);
static void mysql_end_timer(ulong start_time,char *buff); static void mysql_end_timer(ulong start_time,char *buff);
static void nice_time(double sec,char *buff,bool part_second); static void nice_time(double sec,char *buff,bool part_second);
static sig_handler mysql_end(int sig); static sig_handler mysql_end(int sig);
static sig_handler mysql_sigint(int sig);
int main(int argc,char *argv[]) int main(int argc,char *argv[])
...@@ -420,7 +422,7 @@ int main(int argc,char *argv[]) ...@@ -420,7 +422,7 @@ int main(int argc,char *argv[])
if (opt_sigint_ignore) if (opt_sigint_ignore)
signal(SIGINT, SIG_IGN); signal(SIGINT, SIG_IGN);
else else
signal(SIGINT, mysql_end); // Catch SIGINT to clean up signal(SIGINT, mysql_sigint); // Catch SIGINT to clean up
signal(SIGQUIT, mysql_end); // Catch SIGQUIT to clean up signal(SIGQUIT, mysql_end); // Catch SIGQUIT to clean up
/* /*
...@@ -488,6 +490,28 @@ int main(int argc,char *argv[]) ...@@ -488,6 +490,28 @@ int main(int argc,char *argv[])
#endif #endif
} }
sig_handler mysql_sigint(int sig)
{
char kill_buffer[40];
MYSQL *kill_mysql= NULL;
signal(SIGINT, mysql_sigint);
/* terminate if no query being executed, or we already tried interrupting */
if (!executing_query || interrupted_query++)
mysql_end(sig);
kill_mysql= mysql_init(kill_mysql);
if (!mysql_real_connect(kill_mysql,current_host, current_user, opt_password,
"", opt_mysql_port, opt_mysql_unix_port,0))
mysql_end(sig);
/* kill_buffer is always big enough because max length of %lu is 15 */
sprintf(kill_buffer, "KILL /*!50000 QUERY */ %lu", mysql_thread_id(&mysql));
mysql_real_query(kill_mysql, kill_buffer, strlen(kill_buffer));
mysql_close(kill_mysql);
tee_fprintf(stdout, "Query aborted by Ctrl+C\n");
}
sig_handler mysql_end(int sig) sig_handler mysql_end(int sig)
{ {
mysql_close(&mysql); mysql_close(&mysql);
...@@ -1008,6 +1032,8 @@ static int read_and_execute(bool interactive) ...@@ -1008,6 +1032,8 @@ static int read_and_execute(bool interactive)
if (opt_outfile && glob_buffer.is_empty()) if (opt_outfile && glob_buffer.is_empty())
fflush(OUTFILE); fflush(OUTFILE);
interrupted_query= 0;
#if defined( __WIN__) || defined(OS2) || defined(__NETWARE__) #if defined( __WIN__) || defined(OS2) || defined(__NETWARE__)
tee_fputs(prompt, stdout); tee_fputs(prompt, stdout);
#if defined(__NETWARE__) #if defined(__NETWARE__)
...@@ -1998,6 +2024,8 @@ com_go(String *buffer,char *line __attribute__((unused))) ...@@ -1998,6 +2024,8 @@ com_go(String *buffer,char *line __attribute__((unused)))
timer=start_timer(); timer=start_timer();
executing_query= 1;
error= mysql_real_query_for_lazy(buffer->ptr(),buffer->length()); error= mysql_real_query_for_lazy(buffer->ptr(),buffer->length());
#ifdef HAVE_READLINE #ifdef HAVE_READLINE
...@@ -2012,6 +2040,7 @@ com_go(String *buffer,char *line __attribute__((unused))) ...@@ -2012,6 +2040,7 @@ com_go(String *buffer,char *line __attribute__((unused)))
if (error) if (error)
{ {
buffer->length(0); // Remove query on error buffer->length(0); // Remove query on error
executing_query= 0;
return error; return error;
} }
error=0; error=0;
...@@ -2022,13 +2051,19 @@ com_go(String *buffer,char *line __attribute__((unused))) ...@@ -2022,13 +2051,19 @@ com_go(String *buffer,char *line __attribute__((unused)))
if (quick) if (quick)
{ {
if (!(result=mysql_use_result(&mysql)) && mysql_field_count(&mysql)) if (!(result=mysql_use_result(&mysql)) && mysql_field_count(&mysql))
{
executing_query= 0;
return put_error(&mysql); return put_error(&mysql);
}
} }
else else
{ {
error= mysql_store_result_for_lazy(&result); error= mysql_store_result_for_lazy(&result);
if (error) if (error)
{
executing_query= 0;
return error; return error;
}
} }
if (verbose >= 3 || !opt_silent) if (verbose >= 3 || !opt_silent)
...@@ -2089,6 +2124,9 @@ com_go(String *buffer,char *line __attribute__((unused))) ...@@ -2089,6 +2124,9 @@ com_go(String *buffer,char *line __attribute__((unused)))
fflush(stdout); fflush(stdout);
mysql_free_result(result); mysql_free_result(result);
} while (!(err= mysql_next_result(&mysql))); } while (!(err= mysql_next_result(&mysql)));
executing_query= 0;
if (err >= 1) if (err >= 1)
error= put_error(&mysql); error= put_error(&mysql);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment