mirror of
https://github.com/MariaDB/server.git
synced 2025-01-26 16:54:15 +01:00
Backport BUG#25192 Using relay-log and relay-log-index without values produces unexpected results.
Options loaded from config files were added before command line arguments, and they were parsed together, which could interprete the following: option-a option-b as --option-a=--option-b if 'option-a' requires a value, and caused confusing. Because all options that requires a value are always given in the form '--option=value', so it's an error if there is no '=value' part for such an option read from config file. This patch added a separator to separate the arguments from config files and that from command line, so that they can be handled differently. And report an error for options loaded from config files that requires a value and is not given in the form '--option=value'.
This commit is contained in:
parent
bb6953d1d8
commit
9739efbfec
6 changed files with 83 additions and 13 deletions
extra
include
mysys
sql-common
storage/ndb/test/run-test
|
@ -192,7 +192,8 @@ int main(int argc, char **argv)
|
|||
}
|
||||
|
||||
for (argument= arguments+1 ; *argument ; argument++)
|
||||
puts(*argument);
|
||||
if (*argument != args_separator) /* skip arguments separator */
|
||||
puts(*argument);
|
||||
my_free((char*) load_default_groups,MYF(0));
|
||||
free_defaults(arguments);
|
||||
|
||||
|
|
|
@ -843,6 +843,7 @@ extern void *memdup_root(MEM_ROOT *root,const void *str, size_t len);
|
|||
extern int get_defaults_options(int argc, char **argv,
|
||||
char **defaults, char **extra_defaults,
|
||||
char **group_suffix);
|
||||
extern const char *args_separator;
|
||||
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,
|
||||
|
|
|
@ -41,6 +41,29 @@
|
|||
#include <winbase.h>
|
||||
#endif
|
||||
|
||||
/**
|
||||
arguments separator
|
||||
|
||||
load_defaults() loads arguments from config file and put them
|
||||
before the arguments from command line, this separator is used to
|
||||
separate the arguments loaded from config file and arguments user
|
||||
provided on command line.
|
||||
|
||||
Options with value loaded from config file are always in the form
|
||||
'--option=value', while for command line options, the value can be
|
||||
given as the next argument. Thus we used a separator so that
|
||||
handle_options() can distinguish them.
|
||||
|
||||
Note: any other places that does not need to distinguish them
|
||||
should skip the separator.
|
||||
|
||||
The content of arguments separator does not matter, one should only
|
||||
check the pointer, use "----args-separator----" here to ease debug
|
||||
if someone misused it.
|
||||
|
||||
See BUG#25192
|
||||
*/
|
||||
const char *args_separator= "----args-separator----";
|
||||
const char *my_defaults_file=0;
|
||||
const char *my_defaults_group_suffix=0;
|
||||
char *my_defaults_extra_file=0;
|
||||
|
@ -454,10 +477,11 @@ int my_load_defaults(const char *conf_file, const char **groups,
|
|||
goto err;
|
||||
res= (char**) (ptr+sizeof(alloc));
|
||||
res[0]= **argv; /* Copy program name */
|
||||
/* set arguments separator */
|
||||
res[1]= args_separator;
|
||||
for (i=2 ; i < (uint) *argc ; i++)
|
||||
res[i-1]=argv[0][i];
|
||||
res[i-1]=0; /* End pointer */
|
||||
(*argc)--;
|
||||
res[i]=argv[0][i];
|
||||
res[i]=0; /* End pointer */
|
||||
*argv=res;
|
||||
*(MEM_ROOT*) ptr= alloc; /* Save alloc root for free */
|
||||
if (default_directories)
|
||||
|
@ -487,7 +511,7 @@ int my_load_defaults(const char *conf_file, const char **groups,
|
|||
or a forced default file
|
||||
*/
|
||||
if (!(ptr=(char*) alloc_root(&alloc,sizeof(alloc)+
|
||||
(args.elements + *argc +1) *sizeof(char*))))
|
||||
(args.elements + *argc + 1 + 1) *sizeof(char*))))
|
||||
goto err;
|
||||
res= (char**) (ptr+sizeof(alloc));
|
||||
|
||||
|
@ -508,12 +532,16 @@ int my_load_defaults(const char *conf_file, const char **groups,
|
|||
--*argc; ++*argv; /* skip argument */
|
||||
}
|
||||
|
||||
if (*argc)
|
||||
memcpy((uchar*) (res+1+args.elements), (char*) ((*argv)+1),
|
||||
(*argc-1)*sizeof(char*));
|
||||
res[args.elements+ *argc]=0; /* last null */
|
||||
/* set arguments separator for arguments from config file and
|
||||
command line */
|
||||
res[args.elements+1]= args_separator;
|
||||
|
||||
(*argc)+=args.elements;
|
||||
if (*argc)
|
||||
memcpy((uchar*) (res+1+args.elements+1), (char*) ((*argv)+1),
|
||||
(*argc-1)*sizeof(char*));
|
||||
res[args.elements+ *argc+1]=0; /* last null */
|
||||
|
||||
(*argc)+=args.elements+1;
|
||||
*argv= (char**) res;
|
||||
*(MEM_ROOT*) ptr= alloc; /* Save alloc root for free */
|
||||
delete_dynamic(&args);
|
||||
|
@ -523,7 +551,8 @@ int my_load_defaults(const char *conf_file, const char **groups,
|
|||
printf("%s would have been started with the following arguments:\n",
|
||||
**argv);
|
||||
for (i=1 ; i < *argc ; i++)
|
||||
printf("%s ", (*argv)[i]);
|
||||
if ((*argv)[i] != args_separator) /* skip arguments separator */
|
||||
printf("%s ", (*argv)[i]);
|
||||
puts("");
|
||||
exit(0);
|
||||
}
|
||||
|
|
|
@ -121,6 +121,7 @@ int handle_options(int *argc, char ***argv,
|
|||
const struct my_option *optp;
|
||||
uchar* *value;
|
||||
int error, i;
|
||||
my_bool is_cmdline_arg= 1;
|
||||
|
||||
LINT_INIT(opt_found);
|
||||
/* handle_options() assumes arg0 (program name) always exists */
|
||||
|
@ -130,10 +131,34 @@ int handle_options(int *argc, char ***argv,
|
|||
(*argv)++; /* --- || ---- */
|
||||
init_variables(longopts, init_one_value);
|
||||
|
||||
/*
|
||||
Search for args_separator, if found, then the first part of the
|
||||
arguments are loaded from configs
|
||||
*/
|
||||
for (pos= *argv, pos_end=pos+ *argc; pos != pos_end ; pos++)
|
||||
{
|
||||
if (*pos == args_separator)
|
||||
{
|
||||
is_cmdline_arg= 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
for (pos= *argv, pos_end=pos+ *argc; pos != pos_end ; pos++)
|
||||
{
|
||||
char **first= pos;
|
||||
char *cur_arg= *pos;
|
||||
if (!is_cmdline_arg && (cur_arg == args_separator))
|
||||
{
|
||||
is_cmdline_arg= 1;
|
||||
|
||||
/* save the separator too if skip unkown options */
|
||||
if (my_getopt_skip_unknown)
|
||||
(*argv)[argvpos++]= cur_arg;
|
||||
else
|
||||
(*argc)--;
|
||||
continue;
|
||||
}
|
||||
if (cur_arg[0] == '-' && cur_arg[1] && !end_of_options) /* must be opt */
|
||||
{
|
||||
char *argument= 0;
|
||||
|
@ -426,8 +451,12 @@ invalid value '%s'",
|
|||
}
|
||||
else if (optp->arg_type == REQUIRED_ARG && !optend)
|
||||
{
|
||||
/* Check if there are more arguments after this one */
|
||||
if (!*++pos)
|
||||
/* Check if there are more arguments after this one,
|
||||
|
||||
Note: options loaded from config file that requires value
|
||||
should always be in the form '--option=value'.
|
||||
*/
|
||||
if (!is_cmdline_arg || !*++pos)
|
||||
{
|
||||
if (my_getopt_print_errors)
|
||||
my_getopt_error_reporter(ERROR_LEVEL,
|
||||
|
|
|
@ -1053,6 +1053,8 @@ void mysql_read_default_options(struct st_mysql_options *options,
|
|||
char **option=argv;
|
||||
while (*++option)
|
||||
{
|
||||
if (option[0] == args_separator) /* skip arguments separator */
|
||||
continue;
|
||||
/* DBUG_PRINT("info",("option: %s",option[0])); */
|
||||
if (option[0][0] == '-' && option[0][1] == '-')
|
||||
{
|
||||
|
|
|
@ -105,6 +105,8 @@ setup_config(atrt_config& config)
|
|||
*/
|
||||
for (j = 0; j<(size_t)argc; j++)
|
||||
{
|
||||
if (tmp[j] == args_separator) /* skip arguments separator */
|
||||
continue;
|
||||
for (k = 0; proc_args[k].name; k++)
|
||||
{
|
||||
if (!strncmp(tmp[j], proc_args[k].name, strlen(proc_args[k].name)))
|
||||
|
@ -369,6 +371,12 @@ load_options(int argc, char** argv, int type, atrt_options& opts)
|
|||
{
|
||||
for (size_t i = 0; i<(size_t)argc; i++)
|
||||
{
|
||||
/**
|
||||
* Skip the separator for arguments from config file and command
|
||||
* line
|
||||
*/
|
||||
if (argv[i] == args_separator)
|
||||
continue;
|
||||
for (size_t j = 0; f_options[j].name; j++)
|
||||
{
|
||||
const char * name = f_options[j].name;
|
||||
|
|
Loading…
Add table
Reference in a new issue