Commit 3e569727 authored by Sergei Golubchik's avatar Sergei Golubchik

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.
parent 3ea51b51
......@@ -146,16 +146,14 @@ int main(int argc, char **argv)
int count, error, args_used;
char **load_default_groups= 0, *tmp_arguments[6];
char **argument, **arguments, **org_argv;
char *defaults, *extra_defaults, *group_suffix;
int nargs, i= 0;
MY_INIT(argv[0]);
org_argv= argv;
args_used= get_defaults_options(argc, argv, &defaults, &extra_defaults,
&group_suffix);
args_used= get_defaults_options(argv);
/* Copy defaults-xxx arguments & program name */
count=args_used+1;
count=args_used;
arguments= tmp_arguments;
memcpy((char*) arguments, (char*) org_argv, count * sizeof(*org_argv));
arguments[count]= 0;
......
......@@ -26,9 +26,7 @@ extern const char *my_defaults_file;
extern my_bool my_getopt_use_args_separator;
extern my_bool my_getopt_is_args_separator(const char* arg);
extern int get_defaults_options(int argc, char **argv,
char **defaults, char **extra_defaults,
char **group_suffix);
extern int get_defaults_options(char **argv);
extern int my_load_defaults(const char *conf_file, const char **groups,
int *argc, char ***argv, const char ***);
extern int load_defaults(const char *conf_file, const char **groups,
......
......@@ -2,11 +2,11 @@ Could not open required defaults file: /path/with/no/extension
Fatal error in defaults handling. Program aborted
Could not open required defaults file: /path/with.ext
Fatal error in defaults handling. Program aborted
Could not open required defaults file: MYSQL_TEST_DIR/relative/path/with.ext
Could not open required defaults file: relative/path/with.ext
Fatal error in defaults handling. Program aborted
Could not open required defaults file: MYSQL_TEST_DIR/relative/path/without/extension
Could not open required defaults file: relative/path/without/extension
Fatal error in defaults handling. Program aborted
Could not open required defaults file: MYSQL_TEST_DIR/with.ext
Could not open required defaults file: with.ext
Fatal error in defaults handling. Program aborted
Could not open required defaults file: MYSQL_TEST_DIR/no_extension
Could not open required defaults file: no_extension
Fatal error in defaults handling. Program aborted
......@@ -13,19 +13,15 @@ exec $MYSQLD --defaults-file=/path/with/no/extension --print-defaults 2>&1;
--error 1
exec $MYSQLD --defaults-file=/path/with.ext --print-defaults 2>&1;
--replace_result $MYSQL_TEST_DIR MYSQL_TEST_DIR
--error 1
exec $MYSQLD --defaults-file=relative/path/with.ext --print-defaults 2>&1;
--replace_result $MYSQL_TEST_DIR MYSQL_TEST_DIR
--error 1
exec $MYSQLD --defaults-file=relative/path/without/extension --print-defaults 2>&1;
--replace_result $MYSQL_TEST_DIR MYSQL_TEST_DIR
--error 1
exec $MYSQLD --defaults-file=with.ext --print-defaults 2>&1;
--replace_result $MYSQL_TEST_DIR MYSQL_TEST_DIR
--error 1
exec $MYSQLD --defaults-file=no_extension --print-defaults 2>&1;
......@@ -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);
/**
......@@ -148,33 +141,6 @@ static const char **init_default_directories(MEM_ROOT *alloc);
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.
......@@ -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;
while (argc >= 2)
argv++; /* Skip program name */
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="))
}
else
for(; *argv; argv++)
{
*defaults= *argv + sizeof("--defaults-file=")-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;
}
if (!*extra_defaults && is_prefix(*argv,"--defaults-extra-file="))
if (*argv && !strcmp(*argv, "--print-defaults"))
{
*extra_defaults= *argv + sizeof("--defaults-extra-file=")-1;
argc--;
continue;
my_print_defaults= 1;
argv++;
}
if (!*group_suffix && is_prefix(*argv, "--defaults-group-suffix="))
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)
{
*group_suffix= *argv + sizeof("--defaults-group-suffix=")-1;
argc--;
continue;
int error= my_realpath(extra_file_buffer, my_defaults_extra_file, MYF(0));
if (error)
return error;
my_defaults_extra_file= extra_file_buffer;
}
break;
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,55 +428,31 @@ 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*))))
args_used= get_defaults_options(*argv);
if (my_init_dynamic_array(&args, sizeof(char*), 128, 64, MYF(0)))
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)
insert_dynamic(&args, *argv);/* Name MUST be set, even by embedded library */
*argc-= args_used;
*argv+= args_used;
if (!my_no_defaults)
{
/* 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);
}
TYPELIB group; // XXX
struct handle_option_ctx ctx;
group.count=0;
group.name= "defaults";
......@@ -526,63 +461,39 @@ int my_load_defaults(const char *conf_file, const char **groups, int *argc,
for (; *groups ; groups++)
group.count++;
if (my_init_dynamic_array(&args, sizeof(char*), 128, 64, MYF(0)))
goto err;
ctx.alloc= &alloc;
ctx.args= &args;
ctx.group= &group;
if ((error= my_search_option_files(conf_file, argc, argv, &args_used, &ctx,
dirs)))
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)
{
......
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