diff options
-rw-r--r-- | include/my_getopt.h | 2 | ||||
-rw-r--r-- | libmysqld/lib_sql.cc | 9 | ||||
-rw-r--r-- | mysys/default.c | 10 | ||||
-rw-r--r-- | mysys/mf_tempdir.c | 7 | ||||
-rw-r--r-- | mysys/my_getopt.c | 33 | ||||
-rw-r--r-- | sql/mysql_priv.h | 3 | ||||
-rw-r--r-- | sql/mysqld.cc | 163 |
7 files changed, 142 insertions, 85 deletions
diff --git a/include/my_getopt.h b/include/my_getopt.h index 50ebe9190d8..7cbad607aac 100644 --- a/include/my_getopt.h +++ b/include/my_getopt.h @@ -72,7 +72,7 @@ extern void my_cleanup_options(const struct my_option *options); extern void my_print_help(const struct my_option *options); extern void my_print_variables(const struct my_option *options); extern void my_getopt_register_get_addr(uchar ** (*func_addr)(const char *, uint, - const struct my_option *)); + const struct my_option *, int *)); ulonglong getopt_ull_limit_value(ulonglong num, const struct my_option *optp, my_bool *fix); diff --git a/libmysqld/lib_sql.cc b/libmysqld/lib_sql.cc index 6e82812239e..4888ebca533 100644 --- a/libmysqld/lib_sql.cc +++ b/libmysqld/lib_sql.cc @@ -43,6 +43,15 @@ extern char mysql_server_last_error[MYSQL_ERRMSG_SIZE]; static my_bool emb_read_query_result(MYSQL *mysql); +extern "C" void unireg_clear(int exit_code) +{ + DBUG_ENTER("unireg_clear"); + clean_up(!opt_help && (exit_code || !opt_bootstrap)); /* purecov: inspected */ + my_end(opt_endinfo ? MY_CHECK_ERROR | MY_GIVE_INFO : 0); + DBUG_VOID_RETURN; +} + + /* Reads error information from the MYSQL_DATA and puts it into proper MYSQL members diff --git a/mysys/default.c b/mysys/default.c index 6b2b31d43ec..c7e1e513e1e 100644 --- a/mysys/default.c +++ b/mysys/default.c @@ -144,6 +144,7 @@ static char *remove_end_comment(char *ptr); RETURN 0 ok 1 given cinf_file doesn't exist + 2 out of memory The global variable 'my_defaults_group_suffix' is updated with value for --defaults_group_suffix @@ -190,7 +191,7 @@ int my_search_option_files(const char *conf_file, int *argc, char ***argv, if (!(extra_groups= (const char**)alloc_root(ctx->alloc, (2*group->count+1)*sizeof(char*)))) - goto err; + DBUG_RETURN(2); for (i= 0; i < group->count; i++) { @@ -199,7 +200,7 @@ int my_search_option_files(const char *conf_file, int *argc, char ***argv, len= strlen(extra_groups[i]); if (!(ptr= alloc_root(ctx->alloc, len+instance_len+1))) - goto err; + DBUG_RETURN(2); extra_groups[i+group->count]= ptr; @@ -254,12 +255,11 @@ int my_search_option_files(const char *conf_file, int *argc, char ***argv, } } - DBUG_RETURN(error); + DBUG_RETURN(0); err: fprintf(stderr,"Fatal error in defaults handling. Program aborted\n"); - exit(1); - return 0; /* Keep compiler happy */ + DBUG_RETURN(1); } diff --git a/mysys/mf_tempdir.c b/mysys/mf_tempdir.c index b2c18c74347..6ad0f95a342 100644 --- a/mysys/mf_tempdir.c +++ b/mysys/mf_tempdir.c @@ -85,8 +85,11 @@ char *my_tmpdir(MY_TMPDIR *tmpdir) void free_tmpdir(MY_TMPDIR *tmpdir) { uint i; - for (i=0; i<=tmpdir->max; i++) - my_free(tmpdir->list[i], MYF(0)); + if (tmpdir->full_list.elements) + { + for (i=0; i<=tmpdir->max; i++) + my_free(tmpdir->list[i], MYF(0)); + } delete_dynamic(&tmpdir->full_list); pthread_mutex_destroy(&tmpdir->mutex); } diff --git a/mysys/my_getopt.c b/mysys/my_getopt.c index 6a7ee748930..5c7e3ecef34 100644 --- a/mysys/my_getopt.c +++ b/mysys/my_getopt.c @@ -100,10 +100,10 @@ static void default_reporter(enum loglevel level, one. Call function 'get_one_option()' once for each option. */ -static uchar** (*getopt_get_addr)(const char *, uint, const struct my_option *); +static uchar** (*getopt_get_addr)(const char *, uint, const struct my_option *, int *); void my_getopt_register_get_addr(uchar** (*func_addr)(const char *, uint, - const struct my_option *)) + const struct my_option *, int *)) { getopt_get_addr= func_addr; } @@ -362,8 +362,12 @@ int handle_options(int *argc, char ***argv, my_progname, optp->name); return EXIT_NO_ARGUMENT_ALLOWED; } + error= 0; value= optp->var_type & GET_ASK_ADDR ? - (*getopt_get_addr)(key_name, (uint) strlen(key_name), optp) : optp->value; + (*getopt_get_addr)(key_name, (uint) strlen(key_name), optp, &error) : + optp->value; + if (error) + return error; if (optp->arg_type == NO_ARG) { @@ -397,9 +401,10 @@ invalid value '%s'", my_progname, optp->name, optend); continue; } - get_one_option(optp->id, optp, - *((my_bool*) value) ? - (char*) "1" : disabled_my_option); + if (get_one_option(optp->id, optp, + *((my_bool*) value) ? + (char*) "1" : disabled_my_option)) + return EXIT_UNSPECIFIED_ERROR; continue; } argument= optend; @@ -457,7 +462,8 @@ invalid value '%s'", optp->arg_type == NO_ARG) { *((my_bool*) optp->value)= (my_bool) 1; - get_one_option(optp->id, optp, argument); + if (get_one_option(optp->id, optp, argument)) + return EXIT_UNSPECIFIED_ERROR; continue; } else if (optp->arg_type == REQUIRED_ARG || @@ -476,7 +482,8 @@ invalid value '%s'", { if (optp->var_type == GET_BOOL) *((my_bool*) optp->value)= (my_bool) 1; - get_one_option(optp->id, optp, argument); + if (get_one_option(optp->id, optp, argument)) + return EXIT_UNSPECIFIED_ERROR; continue; } /* Check if there are more arguments after this one */ @@ -501,7 +508,8 @@ invalid value '%s'", my_progname, argument, optp->name); return error; } - get_one_option(optp->id, optp, argument); + if (get_one_option(optp->id, optp, argument)) + return EXIT_UNSPECIFIED_ERROR; break; } } @@ -524,7 +532,8 @@ invalid value '%s'", my_progname, argument, optp->name); return error; } - get_one_option(optp->id, optp, argument); + if (get_one_option(optp->id, optp, argument)) + return EXIT_UNSPECIFIED_ERROR; (*argc)--; /* option handled (short or long), decrease argument count */ } @@ -1085,7 +1094,7 @@ static void init_variables(const struct my_option *options, if (options->value) init_one_value(options, options->value, options->def_value); if (options->var_type & GET_ASK_ADDR && - (variable= (*getopt_get_addr)("", 0, options))) + (variable= (*getopt_get_addr)("", 0, options, 0))) init_one_value(options, variable, options->def_value); } DBUG_VOID_RETURN; @@ -1189,7 +1198,7 @@ void my_print_variables(const struct my_option *options) for (optp= options; optp->id; optp++) { uchar* *value= (optp->var_type & GET_ASK_ADDR ? - (*getopt_get_addr)("", 0, optp) : optp->value); + (*getopt_get_addr)("", 0, optp, 0) : optp->value); if (value) { printf("%s ", optp->name); diff --git a/sql/mysql_priv.h b/sql/mysql_priv.h index d11f2838e3a..192da33422e 100644 --- a/sql/mysql_priv.h +++ b/sql/mysql_priv.h @@ -2406,7 +2406,8 @@ extern "C" void unireg_abort(int exit_code) __attribute__((noreturn)); void kill_delayed_threads(void); bool check_stack_overrun(THD *thd, long margin, uchar *dummy); #else -#define unireg_abort(exit_code) DBUG_RETURN(exit_code) +extern "C" void unireg_clear(int exit_code); +#define unireg_abort(exit_code) do { unireg_clear(exit_code); DBUG_RETURN(exit_code); } while(0) inline void kill_delayed_threads(void) {} #define check_stack_overrun(A, B, C) 0 #endif diff --git a/sql/mysqld.cc b/sql/mysqld.cc index 76deffec789..601bdcaeaa5 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -733,13 +733,13 @@ uint connection_count= 0; /* Function declarations */ pthread_handler_t signal_hand(void *arg); -static void mysql_init_variables(void); -static void get_options(int *argc,char **argv); +static int mysql_init_variables(void); +static int get_options(int *argc,char **argv); extern "C" my_bool mysqld_get_one_option(int, const struct my_option *, char *); static void set_server_version(void); static int init_thread_environment(); static char *get_relative_path(const char *path); -static void fix_paths(void); +static int fix_paths(void); pthread_handler_t handle_connections_sockets(void *arg); pthread_handler_t kill_server_thread(void *arg); static void bootstrap(FILE *file); @@ -753,7 +753,7 @@ pthread_handler_t handle_connections_shared_memory(void *arg); pthread_handler_t handle_slave(void *arg); static ulong find_bit_type(const char *x, TYPELIB *bit_lib); static ulong find_bit_type_or_exit(const char *x, TYPELIB *bit_lib, - const char *option); + const char *option, int *error); static void clean_up(bool print_message); static int test_if_case_insensitive(const char *dir_name); @@ -1187,7 +1187,8 @@ extern "C" void unireg_abort(int exit_code) my_end(opt_endinfo ? MY_CHECK_ERROR | MY_GIVE_INFO : 0); exit(exit_code); /* purecov: inspected */ } -#endif + +#endif /*EMBEDDED_LIBRARY*/ void clean_up(bool print_message) @@ -3141,12 +3142,12 @@ static int init_common_variables(const char *conf_file_name, int argc, if (!rpl_filter || !binlog_filter) { sql_perror("Could not allocate replication and binlog filters"); - exit(1); + return 1; } - if (init_thread_environment()) + if (init_thread_environment() || + mysql_init_variables()) return 1; - mysql_init_variables(); #ifdef HAVE_TZNAME { @@ -3222,7 +3223,8 @@ static int init_common_variables(const char *conf_file_name, int argc, load_defaults(conf_file_name, groups, &argc, &argv); defaults_argv=argv; defaults_argc=argc; - get_options(&defaults_argc, defaults_argv); + if (get_options(&defaults_argc, defaults_argv)) + return 1; set_server_version(); DBUG_PRINT("info",("%s Ver %s for %s on %s\n",my_progname, @@ -7347,6 +7349,8 @@ SHOW_VAR status_vars[]= { {NullS, NullS, SHOW_LONG} }; +#ifndef EMBEDDED_LIBRARY + static void print_version(void) { set_server_version(); @@ -7358,7 +7362,6 @@ static void print_version(void) server_version,SYSTEM_TYPE,MACHINE_TYPE, MYSQL_COMPILATION_COMMENT); } -#ifndef EMBEDDED_LIBRARY static void usage(void) { if (!(default_charset_info= get_charset_by_csname(default_character_set_name, @@ -7423,8 +7426,9 @@ To see what values a running MySQL server is using, type\n\ as these are initialized by my_getopt. */ -static void mysql_init_variables(void) +static int mysql_init_variables(void) { + int error; /* Things reset to zero */ opt_skip_slave_start= opt_reckless_slave = 0; mysql_home[0]= pidfile_name[0]= log_error_file[0]= 0; @@ -7481,7 +7485,10 @@ static void mysql_init_variables(void) delay_key_write_options= (uint) DELAY_KEY_WRITE_ON; slave_exec_mode_options= 0; slave_exec_mode_options= (uint) - find_bit_type_or_exit(slave_exec_mode_str, &slave_exec_mode_typelib, NULL); + find_bit_type_or_exit(slave_exec_mode_str, &slave_exec_mode_typelib, NULL, + &error); + if (error) + return 1; opt_specialflag= SPECIAL_ENGLISH; unix_sock= ip_sock= INVALID_SOCKET; mysql_home_ptr= mysql_home; @@ -7504,7 +7511,7 @@ static void mysql_init_variables(void) key_caches.empty(); if (!(dflt_key_cache= get_or_create_key_cache(default_key_cache_base.str, default_key_cache_base.length))) - exit(1); + return 1; /* set key_cache_hash.default_value = dflt_key_cache */ multi_keycache_init(); @@ -7647,6 +7654,7 @@ static void mysql_init_variables(void) tmpenv = DEFAULT_MYSQL_HOME; (void) strmake(mysql_home, tmpenv, sizeof(mysql_home)-1); #endif + return 0; } @@ -7655,6 +7663,8 @@ mysqld_get_one_option(int optid, const struct my_option *opt __attribute__((unused)), char *argument) { + int error; + switch(optid) { case '#': #ifndef DBUG_OFF @@ -7700,7 +7710,9 @@ mysqld_get_one_option(int optid, break; case OPT_SLAVE_EXEC_MODE: slave_exec_mode_options= (uint) - find_bit_type_or_exit(argument, &slave_exec_mode_typelib, ""); + find_bit_type_or_exit(argument, &slave_exec_mode_typelib, "", &error); + if (error) + return 1; break; #endif case OPT_SAFEMALLOC_MEM_LIMIT: @@ -7709,9 +7721,11 @@ mysqld_get_one_option(int optid, #endif break; #include <sslopt-case.h> +#ifndef EMBEDDED_LIBRARY case 'V': print_version(); exit(0); +#endif /*EMBEDDED_LIBRARY*/ case 'W': if (!argument) global_system_variables.log_warnings++; @@ -7763,18 +7777,16 @@ mysqld_get_one_option(int optid, if (!(p= strstr(argument, "->"))) { - fprintf(stderr, - "Bad syntax in replicate-rewrite-db - missing '->'!\n"); - exit(1); + sql_print_error("Bad syntax in replicate-rewrite-db - missing '->'!\n"); + return 1; } val= p--; while (my_isspace(mysqld_charset, *p) && p > argument) *p-- = 0; if (p == argument) { - fprintf(stderr, - "Bad syntax in replicate-rewrite-db - empty FROM db!\n"); - exit(1); + sql_print_error("Bad syntax in replicate-rewrite-db - empty FROM db!\n"); + return 1; } *val= 0; val+= 2; @@ -7782,9 +7794,8 @@ mysqld_get_one_option(int optid, *val++; if (!*val) { - fprintf(stderr, - "Bad syntax in replicate-rewrite-db - empty TO db!\n"); - exit(1); + sql_print_error("Bad syntax in replicate-rewrite-db - empty TO db!\n"); + return 1; } rpl_filter->add_db_rewrite(key, val); @@ -7812,8 +7823,8 @@ mysqld_get_one_option(int optid, { if (rpl_filter->add_do_table(argument)) { - fprintf(stderr, "Could not add do table rule '%s'!\n", argument); - exit(1); + sql_print_error("Could not add do table rule '%s'!\n", argument); + return 1; } break; } @@ -7821,8 +7832,8 @@ mysqld_get_one_option(int optid, { if (rpl_filter->add_wild_do_table(argument)) { - fprintf(stderr, "Could not add do table rule '%s'!\n", argument); - exit(1); + sql_print_error("Could not add do table rule '%s'!\n", argument); + return 1; } break; } @@ -7830,8 +7841,8 @@ mysqld_get_one_option(int optid, { if (rpl_filter->add_wild_ignore_table(argument)) { - fprintf(stderr, "Could not add ignore table rule '%s'!\n", argument); - exit(1); + sql_print_error("Could not add ignore table rule '%s'!\n", argument); + return 1; } break; } @@ -7839,8 +7850,8 @@ mysqld_get_one_option(int optid, { if (rpl_filter->add_ignore_table(argument)) { - fprintf(stderr, "Could not add ignore table rule '%s'!\n", argument); - exit(1); + sql_print_error("Could not add ignore table rule '%s'!\n", argument); + return 1; } break; } @@ -7863,7 +7874,9 @@ mysqld_get_one_option(int optid, { log_output_str= argument; log_output_options= - find_bit_type_or_exit(argument, &log_output_typelib, opt->name); + find_bit_type_or_exit(argument, &log_output_typelib, opt->name, &error); + if (error) + return 1; } break; } @@ -7873,7 +7886,7 @@ mysqld_get_one_option(int optid, sql_perror("Event scheduler is not supported in embedded build."); #else if (Events::set_opt_event_scheduler(argument)) - exit(1); + return 1; #endif break; case (int) OPT_SKIP_NEW: @@ -7912,7 +7925,7 @@ mysqld_get_one_option(int optid, case (int) OPT_SKIP_NETWORKING: #if defined(__NETWARE__) sql_perror("Can't start server: skip-networking option is currently not supported on NetWare"); - exit(1); + return 1; #endif opt_disable_networking=1; mysqld_port=0; @@ -7942,14 +7955,14 @@ mysqld_get_one_option(int optid, if (gethostname(myhostname,sizeof(myhostname)) < 0) { sql_perror("Can't start server: cannot get my own hostname!"); - exit(1); + return 1; } ent=gethostbyname(myhostname); } if (!ent) { sql_perror("Can't start server: cannot resolve hostname!"); - exit(1); + return 1; } my_bind_addr = (ulong) ((in_addr*)ent->h_addr_list[0])->s_addr; } @@ -8083,7 +8096,10 @@ mysqld_get_one_option(int optid, { myisam_recover_options_str=argument; myisam_recover_options= - find_bit_type_or_exit(argument, &myisam_recover_typelib, opt->name); + find_bit_type_or_exit(argument, &myisam_recover_typelib, opt->name, + &error); + if (error) + return 1; } ha_open_options|=HA_OPEN_ABORT_IF_CRASHED; break; @@ -8128,7 +8144,9 @@ mysqld_get_one_option(int optid, { sql_mode_str= argument; global_system_variables.sql_mode= - find_bit_type_or_exit(argument, &sql_mode_typelib, opt->name); + find_bit_type_or_exit(argument, &sql_mode_typelib, opt->name, &error); + if (error) + return 1; global_system_variables.sql_mode= fix_sql_mode(global_system_variables. sql_mode); break; @@ -8147,7 +8165,7 @@ mysqld_get_one_option(int optid, if (ft_boolean_check_syntax_string((uchar*) argument)) { fprintf(stderr, "Invalid ft-boolean-syntax string: %s\n", argument); - exit(1); + return 1; } strmake(ft_boolean_syntax, argument, sizeof(ft_boolean_syntax)-1); break; @@ -8167,13 +8185,17 @@ mysqld_get_one_option(int optid, /** Handle arguments for multiple key caches. */ -extern "C" uchar **mysql_getopt_value(const char *keyname, uint key_length, - const struct my_option *option); +extern "C" int mysql_getopt_value(uchar **value, + const char *keyname, uint key_length, + const struct my_option *option, + int *error); -uchar* * +static uchar* * mysql_getopt_value(const char *keyname, uint key_length, - const struct my_option *option) + const struct my_option *option, int *error) { + if (error) + *error= 0; switch (option->id) { case OPT_KEY_BUFFER_SIZE: case OPT_KEY_CACHE_BLOCK_SIZE: @@ -8182,7 +8204,11 @@ mysql_getopt_value(const char *keyname, uint key_length, { KEY_CACHE *key_cache; if (!(key_cache= get_or_create_key_cache(keyname, key_length))) - exit(1); + { + if (error) + *error= EXIT_OUT_OF_MEMORY; + return 0; + } switch (option->id) { case OPT_KEY_BUFFER_SIZE: return (uchar**) &key_cache->param_buff_size; @@ -8220,7 +8246,7 @@ void option_error_reporter(enum loglevel level, const char *format, ...) @todo - FIXME add EXIT_TOO_MANY_ARGUMENTS to "mysys_err.h" and return that code? */ -static void get_options(int *argc,char **argv) +static int get_options(int *argc,char **argv) { int ho_error; @@ -8234,7 +8260,7 @@ static void get_options(int *argc,char **argv) if ((ho_error= handle_options(argc, &argv, my_long_options, mysqld_get_one_option))) - exit(ho_error); + return ho_error; (*argc)++; /* add back one for the progname handle_options removes */ /* no need to do this for argv as we are discarding it. */ @@ -8273,7 +8299,8 @@ static void get_options(int *argc,char **argv) max_allowed_packet= global_system_variables.max_allowed_packet; net_buffer_length= global_system_variables.net_buffer_length; #endif - fix_paths(); + if (fix_paths()) + return 1; /* Set some global variables from the global_system_variables @@ -8300,7 +8327,7 @@ static void get_options(int *argc,char **argv) &global_system_variables.time_format) || init_global_datetime_format(MYSQL_TIMESTAMP_DATETIME, &global_system_variables.datetime_format)) - exit(1); + return 1; #ifdef EMBEDDED_LIBRARY one_thread_scheduler(&thread_scheduler); @@ -8313,6 +8340,7 @@ static void get_options(int *argc,char **argv) else pool_of_threads_scheduler(&thread_scheduler); /* purecov: tested */ #endif + return 0; } @@ -8376,7 +8404,7 @@ fn_format_relative_to_data_home(char * to, const char *name, } -static void fix_paths(void) +static int fix_paths(void) { char buff[FN_REFLEN],*pos; convert_dirname(mysql_home,mysql_home,NullS); @@ -8423,12 +8451,12 @@ static void fix_paths(void) charsets_dir=mysql_charsets_dir; if (init_tmpdir(&mysql_tmpdir_list, opt_mysql_tmpdir)) - exit(1); + return 1; #ifdef HAVE_REPLICATION if (!slave_load_tmpdir) { if (!(slave_load_tmpdir = (char*) my_strdup(mysql_tmpdir, MYF(MY_FAE)))) - exit(1); + return 1; } #endif /* HAVE_REPLICATION */ /* @@ -8441,30 +8469,37 @@ static void fix_paths(void) my_free(opt_secure_file_priv, MYF(0)); opt_secure_file_priv= my_strdup(buff, MYF(MY_FAE)); } + return 0; } static ulong find_bit_type_or_exit(const char *x, TYPELIB *bit_lib, - const char *option) + const char *option, int *error) { - ulong res; - + ulong result; const char **ptr; - if ((res= find_bit_type(x, bit_lib)) == ~(ulong) 0) + *error= 0; + if ((result= find_bit_type(x, bit_lib)) == ~(ulong) 0) { + char *buff= (char *) my_alloca(2048); + char *cbuf; ptr= bit_lib->type_names; - if (!*x) - fprintf(stderr, "No option given to %s\n", option); - else - fprintf(stderr, "Wrong option to %s. Option(s) given: %s\n", option, x); - fprintf(stderr, "Alternatives are: '%s'", *ptr); + cbuf= buff + ((!*x) ? + my_snprintf(buff, 2048, "No option given to %s\n", option) : + my_snprintf(buff, 2048, "Wrong option to %s. Option(s) given: %s\n", + option, x)); + cbuf+= my_snprintf(cbuf, 2048 - (cbuf-buff), "Alternatives are: '%s'", *ptr); while (*++ptr) - fprintf(stderr, ",'%s'", *ptr); - fprintf(stderr, "\n"); - exit(1); + cbuf+= my_snprintf(cbuf, 2048 - (cbuf-buff), ",'%s'", *ptr); + my_snprintf(cbuf, 2048 - (cbuf-buff), "\n"); + sql_perror(buff); + *error= 1; + my_afree(buff); + return 0; } - return res; + + return result; } |