diff options
author | Sergei Golubchik <serg@mariadb.org> | 2019-10-12 21:21:50 +0200 |
---|---|---|
committer | Sergei Golubchik <serg@mariadb.org> | 2019-10-14 10:29:30 +0200 |
commit | 3e56972712395d371f82cda564b039dcbda3100a (patch) | |
tree | 3aedc8cec3ee44902a1d68a9456dd7324600b7dc /mysys/my_default.c | |
parent | 3ea51b518bf8c2ec55e125794a14fb152079839c (diff) | |
download | mariadb-git-3e56972712395d371f82cda564b039dcbda3100a.tar.gz |
cleanup: unify --defaults* option handling
process all --defaults* options uniformly,
get rid of special case for --no-defaults and --print-defaults
use realpath instead of blindly concatenating pwd and relative path.
Diffstat (limited to 'mysys/my_default.c')
-rw-r--r-- | mysys/my_default.c | 301 |
1 files changed, 106 insertions, 195 deletions
diff --git a/mysys/my_default.c b/mysys/my_default.c index c1e9e739700..f60a56704b5 100644 --- a/mysys/my_default.c +++ b/mysys/my_default.c @@ -69,26 +69,19 @@ See BUG#25192 */ -static const char *args_separator= "----args-separator----"; -inline static void set_args_separator(char** arg) -{ - DBUG_ASSERT(my_getopt_use_args_separator); - *arg= (char*)args_separator; -} + +static char *args_separator= (char*)"----args-separator----"; my_bool my_getopt_use_args_separator= FALSE; my_bool my_getopt_is_args_separator(const char* arg) { return (arg == args_separator); } + +my_bool my_no_defaults=FALSE, my_print_defaults= FALSE; const char *my_defaults_file=0; const char *my_defaults_group_suffix=0; const char *my_defaults_extra_file=0; -static char my_defaults_file_buffer[FN_REFLEN]; -static char my_defaults_extra_file_buffer[FN_REFLEN]; - -static my_bool defaults_already_read= FALSE; - /* Which directories are searched for options (and in which order) */ #define MAX_DEFAULT_DIRS 7 @@ -110,11 +103,11 @@ struct handle_option_ctx TYPELIB *group; }; -static int search_default_file(struct handle_option_ctx *ctx, - const char *dir, const char *config_file); -static int search_default_file_with_ext(struct handle_option_ctx *ctx, - const char *dir, const char *ext, - const char *config_file, int recursion_level); +static int search_default_file(struct handle_option_ctx *, + const char *, const char *); +static int search_default_file_with_ext(struct handle_option_ctx *, + const char *, const char *, + const char *, int); /** @@ -149,33 +142,6 @@ static char *remove_end_comment(char *ptr); /* - Expand a file name so that the current working directory is added if - the name is relative. - - RETURNS - 0 All OK - 2 Out of memory or path to long - 3 Not able to get working directory - */ - -static int -fn_expand(const char *filename, char *result_buf) -{ - char dir[FN_REFLEN]; - const int flags= MY_UNPACK_FILENAME | MY_SAFE_PATH | MY_RELATIVE_PATH; - DBUG_ENTER("fn_expand"); - DBUG_PRINT("enter", ("filename: %s, result_buf: %p", - filename, result_buf)); - if (my_getwd(dir, sizeof(dir), MYF(0))) - DBUG_RETURN(3); - DBUG_PRINT("debug", ("dir: %s", dir)); - if (fn_format(result_buf, filename, dir, "", flags) == NULL) - DBUG_RETURN(2); - DBUG_PRINT("return", ("result: %s", result_buf)); - DBUG_RETURN(0); -} - -/* Process config files in default directories. SYNOPSIS @@ -184,8 +150,6 @@ fn_expand(const char *filename, char *result_buf) If this is a path, then only this file is read. argc Pointer to argc of original program argv Pointer to argv of original program - args_used Pointer to variable for storing the number of - arguments used. func Pointer to the function to process options func_ctx It's context. Usually it is the structure to store additional options. @@ -209,42 +173,14 @@ fn_expand(const char *filename, char *result_buf) --defaults_group_suffix */ -static int my_search_option_files(const char *conf_file, int *argc, - char ***argv, uint *args_used, +static int my_search_option_files(const char *conf_file, int *argc, char ***argv, struct handle_option_ctx *ctx, const char **default_directories) { - const char **dirs, *forced_default_file, *forced_extra_defaults; + const char **dirs; int error= 0; DBUG_ENTER("my_search_option_files"); - /* Check if we want to force the use a specific default file */ - *args_used+= get_defaults_options(*argc - *args_used, *argv + *args_used, - (char **) &forced_default_file, - (char **) &forced_extra_defaults, - (char **) &my_defaults_group_suffix); - - if (! my_defaults_group_suffix) - my_defaults_group_suffix= getenv("MYSQL_GROUP_SUFFIX"); - - if (forced_extra_defaults && !defaults_already_read) - { - int error= fn_expand(forced_extra_defaults, my_defaults_extra_file_buffer); - if (error) - DBUG_RETURN(error); - my_defaults_extra_file= my_defaults_extra_file_buffer; - } - - if (forced_default_file && !defaults_already_read) - { - int error= fn_expand(forced_default_file, my_defaults_file_buffer); - if (error) - DBUG_RETURN(error); - my_defaults_file= my_defaults_file_buffer; - } - - defaults_already_read= TRUE; - if (my_defaults_group_suffix) { /* Handle --defaults-group-suffix= */ @@ -355,50 +291,73 @@ static int add_option(struct handle_option_ctx *ctx, const char *option) SYNOPSIS get_defaults_options() - argc Pointer to argc of original program argv Pointer to argv of original program - defaults --defaults-file option - extra_defaults --defaults-extra-file option + + DESCRIPTION + Sets my_no_defaults, my_defaults_file, my_defaults_extra_file, + my_defaults_group_suffix, my_print_defaults RETURN # Number of arguments used from *argv - defaults and extra_defaults will be set to option of the appropriate - items of argv array, or to NULL if there are no such options */ -int get_defaults_options(int argc, char **argv, - char **defaults, - char **extra_defaults, - char **group_suffix) +int get_defaults_options(char **argv) { - int org_argc= argc; - *defaults= *extra_defaults= *group_suffix= 0; + static char file_buffer[FN_REFLEN]; + static char extra_file_buffer[FN_REFLEN]; + char **orig_argv= argv; + + argv++; /* Skip program name */ - while (argc >= 2) + my_defaults_file= my_defaults_group_suffix= my_defaults_extra_file= 0; + my_no_defaults= my_print_defaults= FALSE; + + if (*argv && !strcmp(*argv, "--no-defaults")) { - /* Skip program name or previously handled argument */ + my_no_defaults= 1; argv++; - if (!*defaults && is_prefix(*argv,"--defaults-file=")) - { - *defaults= *argv + sizeof("--defaults-file=")-1; - argc--; - continue; - } - if (!*extra_defaults && is_prefix(*argv,"--defaults-extra-file=")) - { - *extra_defaults= *argv + sizeof("--defaults-extra-file=")-1; - argc--; - continue; - } - if (!*group_suffix && is_prefix(*argv, "--defaults-group-suffix=")) + } + else + for(; *argv; argv++) { - *group_suffix= *argv + sizeof("--defaults-group-suffix=")-1; - argc--; - continue; + if (!my_defaults_file && is_prefix(*argv, "--defaults-file=")) + my_defaults_file= *argv + sizeof("--defaults-file=")-1; + else + if (!my_defaults_extra_file && is_prefix(*argv, "--defaults-extra-file=")) + my_defaults_extra_file= *argv + sizeof("--defaults-extra-file=")-1; + else + if (!my_defaults_group_suffix && is_prefix(*argv, "--defaults-group-suffix=")) + my_defaults_group_suffix= *argv + sizeof("--defaults-group-suffix=")-1; + else + break; } - break; + + if (*argv && !strcmp(*argv, "--print-defaults")) + { + my_print_defaults= 1; + argv++; + } + + if (! my_defaults_group_suffix) + my_defaults_group_suffix= getenv("MYSQL_GROUP_SUFFIX"); + + if (my_defaults_extra_file && my_defaults_extra_file != extra_file_buffer) + { + int error= my_realpath(extra_file_buffer, my_defaults_extra_file, MYF(0)); + if (error) + return error; + my_defaults_extra_file= extra_file_buffer; + } + + if (my_defaults_file && my_defaults_file != file_buffer) + { + int error= my_realpath(file_buffer, my_defaults_file, MYF(0)); + if (error) + return error; + my_defaults_file= file_buffer; } - return org_argc - argc; + + return (int)(argv - orig_argv); } /* @@ -469,120 +428,72 @@ int my_load_defaults(const char *conf_file, const char **groups, int *argc, char ***argv, const char ***default_directories) { DYNAMIC_ARRAY args; - TYPELIB group; - my_bool found_print_defaults= 0; - uint args_used= 0; + int args_used= 0; int error= 0; MEM_ROOT alloc; char *ptr,**res; - struct handle_option_ctx ctx; const char **dirs; - uint args_sep= my_getopt_use_args_separator ? 1 : 0; - DBUG_ENTER("load_defaults"); + DBUG_ENTER("my_load_defaults"); init_alloc_root(&alloc, "my_load_defaults", 512, 0, MYF(0)); if ((dirs= init_default_directories(&alloc)) == NULL) goto err; - /* - Check if the user doesn't want any default option processing - --no-defaults is always the first option - */ - if (*argc >= 2 && !strcmp(argv[0][1],"--no-defaults")) - { - /* remove the --no-defaults argument and return only the other arguments */ - uint i, j; - if (!(ptr=(char*) alloc_root(&alloc,sizeof(alloc)+ - (*argc + 1)*sizeof(char*)))) - goto err; - res= (char**) (ptr+sizeof(alloc)); - res[0]= **argv; /* Copy program name */ - j= 1; /* Start from 1 for the reset result args */ - if (my_getopt_use_args_separator) - { - /* set arguments separator */ - set_args_separator(&res[1]); - j++; - } - for (i=2 ; i < (uint) *argc ; i++, j++) - res[j]=argv[0][i]; - res[j]=0; /* End pointer */ - /* - Update the argc, if have not added args separator, then we have - to decrease argc because we have removed the "--no-defaults". - */ - if (!my_getopt_use_args_separator) - (*argc)--; - *argv=res; - *(MEM_ROOT*) ptr= alloc; /* Save alloc root for free */ - if (default_directories) - *default_directories= dirs; - DBUG_RETURN(0); - } - group.count=0; - group.name= "defaults"; - group.type_names= groups; - - for (; *groups ; groups++) - group.count++; + args_used= get_defaults_options(*argv); if (my_init_dynamic_array(&args, sizeof(char*), 128, 64, MYF(0))) goto err; - ctx.alloc= &alloc; - ctx.args= &args; - ctx.group= &group; + insert_dynamic(&args, *argv);/* Name MUST be set, even by embedded library */ + + *argc-= args_used; + *argv+= args_used; - if ((error= my_search_option_files(conf_file, argc, argv, &args_used, &ctx, - dirs))) + if (!my_no_defaults) { - delete_dynamic(&args); - free_root(&alloc,MYF(0)); - DBUG_RETURN(error); + TYPELIB group; // XXX + struct handle_option_ctx ctx; + + group.count=0; + group.name= "defaults"; + group.type_names= groups; + + for (; *groups ; groups++) + group.count++; + + ctx.alloc= &alloc; + ctx.args= &args; + ctx.group= &group; + + if ((error= my_search_option_files(conf_file, argc - args_used, + argv + args_used, &ctx, dirs))) + { + delete_dynamic(&args); + free_root(&alloc,MYF(0)); + DBUG_RETURN(error); + } } - /* - Here error contains <> 0 only if we have a fully specified conf_file - or a forced default file - */ - if (!(ptr=(char*) alloc_root(&alloc,sizeof(alloc)+ - (args.elements + *argc + 1 + args_sep) *sizeof(char*)))) + + if (!(ptr=(char*) alloc_root(&alloc, sizeof(alloc) + + (args.elements + *argc + 3) * sizeof(char*)))) goto err; res= (char**) (ptr+sizeof(alloc)); - /* copy name + found arguments + command line arguments to new array */ - res[0]= argv[0][0]; /* Name MUST be set, even by embedded library */ - memcpy((uchar*) (res+1), args.buffer, args.elements*sizeof(char*)); - /* Skip --defaults-xxx options */ - (*argc)-= args_used; - (*argv)+= args_used; - - /* - Check if we want to see the new argument list - This options must always be the last of the default options - */ - if (*argc >= 2 && !strcmp(argv[0][1],"--print-defaults")) - { - found_print_defaults=1; - --*argc; ++*argv; /* skip argument */ - } + /* found arguments + command line arguments to new array */ + memcpy(res, args.buffer, args.elements * sizeof(char*)); if (my_getopt_use_args_separator) - { - /* set arguments separator for arguments from config file and - command line */ - set_args_separator(&res[args.elements+1]); - } + res[args.elements++]= args_separator; if (*argc) - memcpy((uchar*) (res+1+args.elements+args_sep), (char*) ((*argv)+1), - (*argc-1)*sizeof(char*)); - res[args.elements+ *argc+args_sep]=0; /* last null */ + memcpy(res + args.elements, *argv, *argc * sizeof(char*)); - (*argc)+=args.elements+args_sep; - *argv= (char**) res; + (*argc)+= args.elements; + *argv= res; + (*argv)[*argc]= 0; *(MEM_ROOT*) ptr= alloc; /* Save alloc root for free */ delete_dynamic(&args); - if (found_print_defaults) + if (my_print_defaults) { int i; printf("%s would have been started with the following arguments:\n", @@ -718,7 +629,7 @@ static int search_default_file_with_ext(struct handle_option_ctx *ctx, MY_DIR *search_dir; FILEINFO *search_file; - if ((dir ? strlen(dir) : 0 )+strlen(config_file) >= FN_REFLEN-3) + if (safe_strlen(dir) + strlen(config_file) >= FN_REFLEN-3) return 0; /* Ignore wrong paths */ if (dir) { |