diff options
author | Tatiana A. Nurnberg <azundris@mysql.com> | 2008-07-21 11:20:03 +0200 |
---|---|---|
committer | Tatiana A. Nurnberg <azundris@mysql.com> | 2008-07-21 11:20:03 +0200 |
commit | bb827398ab403c12a5ed98d26c1460b1055dcf85 (patch) | |
tree | c05fbbe74a06ec12c77bb1b59d2bbbaec770742d /client | |
parent | 6b584b80da4f7b8764bcfcf07df8adfcc070eebc (diff) | |
parent | 5ec6659e1e8bc49dd520ad47317243fbe32d5456 (diff) | |
download | mariadb-git-bb827398ab403c12a5ed98d26c1460b1055dcf85.tar.gz |
auto-merge + post-merge fixies
Diffstat (limited to 'client')
-rwxr-xr-x | client/CMakeLists.txt | 8 | ||||
-rw-r--r-- | client/Makefile.am | 12 | ||||
-rw-r--r-- | client/mysql.cc | 11 | ||||
-rw-r--r-- | client/mysqltest.c | 243 |
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; |