Commit be66e43d authored by Alexey Botchkov's avatar Alexey Botchkov

Bug#39289 libmysqld.a calls exit() upon error

Several functions (mostly in mysqld.cc) directly call
exit() function in case of errors, which is not a desired
behaviour expecially in the embedded-server library.

Fixed by making these functions return error sign instead
of exiting.

per-file comments:
  include/my_getopt.h
Bug#39289 libmysqld.a calls exit() upon error 
  added 'error' retvalue for my_getopt_register_get_addr

  libmysqld/lib_sql.cc
Bug#39289 libmysqld.a calls exit() upon error 
  unireg_clear() function implemented

  mysys/default.c
Bug#39289 libmysqld.a calls exit() upon error 
  error returned instead of exit() call

  mysys/mf_tempdir.c
Bug#39289 libmysqld.a calls exit() upon error 
  free_tmpdir() - fixed so it's not produce crash on uninitialized
    tmpdir structure

  mysys/my_getopt.c
Bug#39289 libmysqld.a calls exit() upon error 
  error returned instead of exit() call

  sql/mysql_priv.h
Bug#39289 libmysqld.a calls exit() upon error 
  unireg_abort definition fixed for the embedded server

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