mirror of
https://github.com/MariaDB/server.git
synced 2025-08-08 11:22:35 +03:00
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.
This commit is contained in:
@@ -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);
|
|||||||
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[])
|
|||||||
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[])
|
|||||||
#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)
|
|||||||
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)))
|
|||||||
|
|
||||||
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)))
|
|||||||
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)))
|
|||||||
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)))
|
|||||||
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);
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user