summaryrefslogtreecommitdiff
path: root/client
diff options
context:
space:
mode:
authorTatiana A. Nurnberg <azundris@mysql.com>2008-07-21 11:20:03 +0200
committerTatiana A. Nurnberg <azundris@mysql.com>2008-07-21 11:20:03 +0200
commitbb827398ab403c12a5ed98d26c1460b1055dcf85 (patch)
treec05fbbe74a06ec12c77bb1b59d2bbbaec770742d /client
parent6b584b80da4f7b8764bcfcf07df8adfcc070eebc (diff)
parent5ec6659e1e8bc49dd520ad47317243fbe32d5456 (diff)
downloadmariadb-git-bb827398ab403c12a5ed98d26c1460b1055dcf85.tar.gz
auto-merge + post-merge fixies
Diffstat (limited to 'client')
-rwxr-xr-xclient/CMakeLists.txt8
-rw-r--r--client/Makefile.am12
-rw-r--r--client/mysql.cc11
-rw-r--r--client/mysqltest.c243
4 files changed, 262 insertions, 12 deletions
diff --git a/client/CMakeLists.txt b/client/CMakeLists.txt
index a20db4134c2..cbd4a1f306b 100755
--- a/client/CMakeLists.txt
+++ b/client/CMakeLists.txt
@@ -15,7 +15,7 @@
INCLUDE("${PROJECT_SOURCE_DIR}/win/mysql_manifest.cmake")
# We use the "mysqlclient_notls" library here just as safety, in case
-# any of the clients here would go beond the client API and access the
+# any of the clients here would go beyond the client API and access the
# Thread Local Storage directly.
SET(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -DSAFEMALLOC -DSAFE_MUTEX")
@@ -32,9 +32,9 @@ INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/include
ADD_EXECUTABLE(mysql completion_hash.cc mysql.cc readline.cc sql_string.cc ../mysys/my_conio.c)
TARGET_LINK_LIBRARIES(mysql mysqlclient_notls wsock32)
-ADD_EXECUTABLE(mysqltest mysqltest.c ../mysys/my_getsystime.c
- ../mysys/my_copy.c ../mysys/my_mkdir.c)
-TARGET_LINK_LIBRARIES(mysqltest mysqlclient_notls regex wsock32)
+ADD_EXECUTABLE(mysqltest mysqltest.c)
+SET_SOURCE_FILES_PROPERTIES(mysqltest.c PROPERTIES COMPILE_FLAGS "-DTHREADS")
+TARGET_LINK_LIBRARIES(mysqltest mysqlclient mysys regex wsock32 dbug)
ADD_EXECUTABLE(mysqlcheck mysqlcheck.c)
TARGET_LINK_LIBRARIES(mysqlcheck mysqlclient_notls wsock32)
diff --git a/client/Makefile.am b/client/Makefile.am
index c57a5673367..940766ac66c 100644
--- a/client/Makefile.am
+++ b/client/Makefile.am
@@ -86,11 +86,13 @@ mysqlslap_LDADD = $(CXXLDFLAGS) $(CLIENT_THREAD_LIBS) \
$(LIBMYSQLCLIENT_LA) \
$(top_builddir)/mysys/libmysys.a
-mysqltest_SOURCES= mysqltest.c \
- $(top_srcdir)/mysys/my_getsystime.c \
- $(top_srcdir)/mysys/my_copy.c \
- $(top_srcdir)/mysys/my_mkdir.c
-mysqltest_LDADD = $(top_builddir)/regex/libregex.a $(LDADD)
+mysqltest_SOURCES= mysqltest.c
+mysqltest_CFLAGS= -DTHREAD -UUNDEF_THREADS_HACK
+mysqltest_LDADD = $(CXXLDFLAGS) $(CLIENT_THREAD_LIBS) \
+ @CLIENT_EXTRA_LDFLAGS@ \
+ $(LIBMYSQLCLIENT_LA) \
+ $(top_builddir)/mysys/libmysys.a \
+ $(top_builddir)/regex/libregex.a
mysql_upgrade_SOURCES= mysql_upgrade.c \
$(top_srcdir)/mysys/my_getpagesize.c
diff --git a/client/mysql.cc b/client/mysql.cc
index 234180c3c75..024194d81f6 100644
--- a/client/mysql.cc
+++ b/client/mysql.cc
@@ -1821,7 +1821,7 @@ static int read_and_execute(bool interactive)
the very beginning of a text file when
you save the file using "Unicode UTF-8" format.
*/
- if (!line_number &&
+ if (line && !line_number &&
(uchar) line[0] == 0xEF &&
(uchar) line[1] == 0xBB &&
(uchar) line[2] == 0xBF)
@@ -2176,7 +2176,14 @@ static bool add_line(String &buffer,char *line,char *in_string,
}
else if (!*ml_comment && (!*in_string && (inchar == '#' ||
inchar == '-' && pos[1] == '-' &&
- my_isspace(charset_info,pos[2]))))
+ /*
+ The third byte is either whitespace or is the
+ end of the line -- which would occur only
+ because of the user sending newline -- which is
+ itself whitespace and should also match.
+ */
+ (my_isspace(charset_info,pos[2]) ||
+ !pos[2]))))
{
// Flush previously accepted characters
if (out != line)
diff --git a/client/mysqltest.c b/client/mysqltest.c
index 1ff902481b8..6babc42bcd0 100644
--- a/client/mysqltest.c
+++ b/client/mysqltest.c
@@ -48,7 +48,15 @@
#ifdef __WIN__
#include <direct.h>
#endif
+#include <signal.h>
+#include <my_stacktrace.h>
+#ifdef __WIN__
+#include <crtdbg.h>
+#define SIGNAL_FMT "exception 0x%x"
+#else
+#define SIGNAL_FMT "signal %d"
+#endif
/* Use cygwin for --exec and --system before 5.0 */
#if MYSQL_VERSION_ID < 50000
@@ -216,6 +224,7 @@ struct st_connection
/* Used when creating views and sp, to avoid implicit commit */
MYSQL* util_mysql;
char *name;
+ size_t name_len;
MYSQL_STMT* stmt;
#ifdef EMBEDDED_LIBRARY
@@ -269,7 +278,8 @@ enum enum_commands {
Q_REPLACE_REGEX, Q_REMOVE_FILE, Q_FILE_EXIST,
Q_WRITE_FILE, Q_COPY_FILE, Q_PERL, Q_DIE, Q_EXIT, Q_SKIP,
Q_CHMOD_FILE, Q_APPEND_FILE, Q_CAT_FILE, Q_DIFF_FILES,
- Q_SEND_QUIT, Q_CHANGE_USER, Q_MKDIR, Q_RMDIR,
+ Q_SEND_QUIT, Q_CHANGE_USER, Q_MKDIR, Q_RMDIR, Q_LIST_FILES,
+ Q_LIST_FILES_WRITE_FILE, Q_LIST_FILES_APPEND_FILE,
Q_UNKNOWN, /* Unknown command. */
Q_COMMENT, /* Comments, ignored. */
@@ -361,6 +371,9 @@ const char *command_names[]=
"change_user",
"mkdir",
"rmdir",
+ "list_files",
+ "list_files_write_file",
+ "list_files_append_file",
0
};
@@ -2823,6 +2836,126 @@ void do_rmdir(struct st_command *command)
/*
+ SYNOPSIS
+ get_list_files
+ ds output
+ ds_dirname dir to list
+ ds_wild wild-card file pattern (can be empty)
+
+ DESCRIPTION
+ list all entries in directory (matching ds_wild if given)
+*/
+
+static int get_list_files(DYNAMIC_STRING *ds, const DYNAMIC_STRING *ds_dirname,
+ const DYNAMIC_STRING *ds_wild)
+{
+ uint i;
+ MY_DIR *dir_info;
+ FILEINFO *file;
+ DBUG_ENTER("get_list_files");
+
+ DBUG_PRINT("info", ("listing directory: %s", ds_dirname->str));
+ /* Note that my_dir sorts the list if not given any flags */
+ if (!(dir_info= my_dir(ds_dirname->str, MYF(0))))
+ DBUG_RETURN(1);
+ for (i= 0; i < (uint) dir_info->number_off_files; i++)
+ {
+ file= dir_info->dir_entry + i;
+ if (file->name[0] == '.' &&
+ (file->name[1] == '\0' ||
+ (file->name[1] == '.' && file->name[2] == '\0')))
+ continue; /* . or .. */
+ if (ds_wild && ds_wild->length &&
+ wild_compare(file->name, ds_wild->str, 0))
+ continue;
+ dynstr_append(ds, file->name);
+ dynstr_append(ds, "\n");
+ }
+ my_dirend(dir_info);
+ DBUG_RETURN(0);
+}
+
+
+/*
+ SYNOPSIS
+ do_list_files
+ command called command
+
+ DESCRIPTION
+ list_files <dir_name> [<file_name>]
+ List files and directories in directory <dir_name> (like `ls`)
+ [Matching <file_name>, where wild-cards are allowed]
+*/
+
+static void do_list_files(struct st_command *command)
+{
+ int error;
+ static DYNAMIC_STRING ds_dirname;
+ static DYNAMIC_STRING ds_wild;
+ const struct command_arg list_files_args[] = {
+ {"dirname", ARG_STRING, TRUE, &ds_dirname, "Directory to list"},
+ {"file", ARG_STRING, FALSE, &ds_wild, "Filename (incl. wildcard)"}
+ };
+ DBUG_ENTER("do_list_files");
+
+ check_command_args(command, command->first_argument,
+ list_files_args,
+ sizeof(list_files_args)/sizeof(struct command_arg), ' ');
+
+ error= get_list_files(&ds_res, &ds_dirname, &ds_wild);
+ handle_command_error(command, error);
+ dynstr_free(&ds_dirname);
+ dynstr_free(&ds_wild);
+ DBUG_VOID_RETURN;
+}
+
+
+/*
+ SYNOPSIS
+ do_list_files_write_file_command
+ command called command
+ append append file, or create new
+
+ DESCRIPTION
+ list_files_{write|append}_file <filename> <dir_name> [<match_file>]
+ List files and directories in directory <dir_name> (like `ls`)
+ [Matching <match_file>, where wild-cards are allowed]
+
+ Note: File will be truncated if exists and append is not true.
+*/
+
+static void do_list_files_write_file_command(struct st_command *command,
+ my_bool append)
+{
+ int error;
+ static DYNAMIC_STRING ds_content;
+ static DYNAMIC_STRING ds_filename;
+ static DYNAMIC_STRING ds_dirname;
+ static DYNAMIC_STRING ds_wild;
+ const struct command_arg list_files_args[] = {
+ {"filename", ARG_STRING, TRUE, &ds_filename, "Filename for write"},
+ {"dirname", ARG_STRING, TRUE, &ds_dirname, "Directory to list"},
+ {"file", ARG_STRING, FALSE, &ds_wild, "Filename (incl. wildcard)"}
+ };
+ DBUG_ENTER("do_list_files_write_file");
+
+ check_command_args(command, command->first_argument,
+ list_files_args,
+ sizeof(list_files_args)/sizeof(struct command_arg), ' ');
+
+ init_dynamic_string(&ds_content, "", 1024, 1024);
+ error= get_list_files(&ds_content, &ds_dirname, &ds_wild);
+ handle_command_error(command, error);
+ str_to_file2(ds_filename.str, ds_content.str, ds_content.length, append);
+ dynstr_free(&ds_content);
+ dynstr_free(&ds_filename);
+ dynstr_free(&ds_dirname);
+ dynstr_free(&ds_wild);
+ DBUG_VOID_RETURN;
+}
+
+
+/*
Read characters from line buffer or file. This is needed to allow
my_ungetc() to buffer MAX_DELIMITER_LENGTH characters for a file
@@ -4463,6 +4596,7 @@ void do_connect(struct st_command *command)
ds_connection_name.str));
if (!(con_slot->name= my_strdup(ds_connection_name.str, MYF(MY_WME))))
die("Out of memory");
+ con_slot->name_len= strlen(con_slot->name);
cur_con= con_slot;
if (con_slot == next_con)
@@ -6911,6 +7045,104 @@ void mark_progress(struct st_command* command __attribute__((unused)),
}
+#ifdef HAVE_STACKTRACE
+
+static void dump_backtrace(void)
+{
+ struct st_connection *conn= cur_con;
+
+ my_safe_print_str("read_command_buf", read_command_buf,
+ sizeof(read_command_buf));
+ if (conn)
+ {
+ my_safe_print_str("conn->name", conn->name, conn->name_len);
+#ifdef EMBEDDED_LIBRARY
+ my_safe_print_str("conn->cur_query", conn->cur_query, conn->cur_query_len);
+#endif
+ }
+ fputs("Attempting backtrace...\n", stderr);
+ my_print_stacktrace(NULL, my_thread_stack_size);
+}
+
+#else
+
+static void dump_backtrace(void)
+{
+ fputs("Backtrace not available.\n", stderr);
+}
+
+#endif
+
+static sig_handler signal_handler(int sig)
+{
+ fprintf(stderr, "mysqltest got " SIGNAL_FMT "\n", sig);
+ dump_backtrace();
+}
+
+#ifdef __WIN__
+
+LONG WINAPI exception_filter(EXCEPTION_POINTERS *exp)
+{
+ __try
+ {
+ my_set_exception_pointers(exp);
+ signal_handler(exp->ExceptionRecord->ExceptionCode);
+ }
+ __except(EXCEPTION_EXECUTE_HANDLER)
+ {
+ fputs("Got exception in exception handler!\n", stderr);
+ }
+
+ return EXCEPTION_CONTINUE_SEARCH;
+}
+
+
+static void init_signal_handling(void)
+{
+ UINT mode;
+
+ /* Set output destination of messages to the standard error stream. */
+ _CrtSetReportMode(_CRT_WARN, _CRTDBG_MODE_FILE);
+ _CrtSetReportFile(_CRT_WARN, _CRTDBG_FILE_STDERR);
+ _CrtSetReportMode(_CRT_ERROR, _CRTDBG_MODE_FILE);
+ _CrtSetReportFile(_CRT_ERROR, _CRTDBG_FILE_STDERR);
+ _CrtSetReportMode(_CRT_ASSERT, _CRTDBG_MODE_FILE);
+ _CrtSetReportFile(_CRT_ASSERT, _CRTDBG_FILE_STDERR);
+
+ /* Do not not display the a error message box. */
+ mode= SetErrorMode(0) | SEM_FAILCRITICALERRORS | SEM_NOOPENFILEERRORBOX;
+ SetErrorMode(mode);
+
+ SetUnhandledExceptionFilter(exception_filter);
+}
+
+#else /* __WIN__ */
+
+static void init_signal_handling(void)
+{
+ struct sigaction sa;
+ DBUG_ENTER("init_signal_handling");
+
+#ifdef HAVE_STACKTRACE
+ my_init_stacktrace();
+#endif
+
+ sa.sa_flags = SA_RESETHAND | SA_NODEFER;
+ sigemptyset(&sa.sa_mask);
+ sigprocmask(SIG_SETMASK, &sa.sa_mask, NULL);
+
+ sa.sa_handler= signal_handler;
+
+ sigaction(SIGSEGV, &sa, NULL);
+ sigaction(SIGABRT, &sa, NULL);
+#ifdef SIGBUS
+ sigaction(SIGBUS, &sa, NULL);
+#endif
+ sigaction(SIGILL, &sa, NULL);
+ sigaction(SIGFPE, &sa, NULL);
+}
+
+#endif /* !__WIN__ */
int main(int argc, char **argv)
{
@@ -6924,6 +7156,8 @@ int main(int argc, char **argv)
save_file[0]= 0;
TMPDIR[0]= 0;
+ init_signal_handling();
+
/* Init expected errors */
memset(&saved_expected_errors, 0, sizeof(saved_expected_errors));
@@ -7110,6 +7344,13 @@ int main(int argc, char **argv)
case Q_REMOVE_FILE: do_remove_file(command); break;
case Q_MKDIR: do_mkdir(command); break;
case Q_RMDIR: do_rmdir(command); break;
+ case Q_LIST_FILES: do_list_files(command); break;
+ case Q_LIST_FILES_WRITE_FILE:
+ do_list_files_write_file_command(command, FALSE);
+ break;
+ case Q_LIST_FILES_APPEND_FILE:
+ do_list_files_write_file_command(command, TRUE);
+ break;
case Q_FILE_EXIST: do_file_exist(command); break;
case Q_WRITE_FILE: do_write_file(command); break;
case Q_APPEND_FILE: do_append_file(command); break;