List:Commits« Previous MessageNext Message »
From:He Zhenxing Date:March 24 2009 9:50am
Subject:bzr commit into mysql-6.0-rpl branch (zhenxing.he:2828) Bug#25129
View as plain text  
#At file:///media/sdb2/hezx/work/mysql/bzrwork/b25192/6.0-rpl/

 2828 He Zhenxing	2009-03-24
      BUG#25129 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'.
modified:
  extra/my_print_defaults.c
  include/my_sys.h
  mysys/default.c
  mysys/my_getopt.c
  sql-common/client.c
  storage/ndb/test/run-test/setup.cpp

=== modified file 'extra/my_print_defaults.c'
--- a/extra/my_print_defaults.c	2007-05-10 09:59:39 +0000
+++ b/extra/my_print_defaults.c	2009-03-24 09:50:09 +0000
@@ -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);
 

=== modified file 'include/my_sys.h'
--- a/include/my_sys.h	2009-02-23 14:53:18 +0000
+++ b/include/my_sys.h	2009-03-24 09:50:09 +0000
@@ -894,6 +894,25 @@ extern void *memdup_root(MEM_ROOT *root,
 extern int get_defaults_options(int argc, char **argv,
                                 char **defaults, char **extra_defaults,
                                 char **group_suffix);
+/**
+   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.
+
+   See BUG#25192
+ */
+extern const char *args_separator;
 extern int load_defaults(const char *conf_file, const char **groups,
 			 int *argc, char ***argv);
 extern int modify_defaults_file(const char *file_location, const char *option,

=== modified file 'mysys/default.c'
--- a/mysys/default.c	2008-07-22 11:38:24 +0000
+++ b/mysys/default.c	2009-03-24 09:50:09 +0000
@@ -41,6 +41,10 @@
 #include <winbase.h>
 #endif
 
+/* 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 */
+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;
@@ -420,10 +424,11 @@ int load_defaults(const char *conf_file,
       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 */
     DBUG_RETURN(0);
@@ -450,7 +455,7 @@ int load_defaults(const char *conf_file,
     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));
 
@@ -471,12 +476,16 @@ int load_defaults(const char *conf_file,
     --*argc; ++*argv;				/* skip argument */
   }
 
+  /* set arguments separator for arguments from config file and
+     command line */
+  res[args.elements+1]= args_separator;
+
   if (*argc)
-    memcpy((uchar*) (res+1+args.elements), (char*) ((*argv)+1),
+    memcpy((uchar*) (res+1+args.elements+1), (char*) ((*argv)+1),
 	   (*argc-1)*sizeof(char*));
-  res[args.elements+ *argc]=0;			/* last null */
+  res[args.elements+ *argc+1]=0;                /* last null */
 
-  (*argc)+=args.elements;
+  (*argc)+=args.elements+1;
   *argv= (char**) res;
   *(MEM_ROOT*) ptr= alloc;			/* Save alloc root for free */
   delete_dynamic(&args);
@@ -486,7 +495,8 @@ int load_defaults(const char *conf_file,
     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][0] != '+')                 /* skip arguments separator */
+        printf("%s ", (*argv)[i]);
     puts("");
     exit(0);
   }

=== modified file 'mysys/my_getopt.c'
--- a/mysys/my_getopt.c	2009-03-18 09:49:57 +0000
+++ b/mysys/my_getopt.c	2009-03-24 09:50:09 +0000
@@ -119,6 +119,7 @@ int handle_options(int *argc, char ***ar
   const struct my_option *optp;
   uchar* *value;
   int error, i;
+  my_bool is_cmdline_arg= 0;
 
   LINT_INIT(opt_found);
   /* handle_options() assumes arg0 (program name) always exists */
@@ -132,6 +133,17 @@ int handle_options(int *argc, char ***ar
   {
     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;
@@ -420,10 +432,11 @@ invalid value '%s'",
 	else if (optp->arg_type == REQUIRED_ARG && !optend)
 	{
 	  /* Check if there are more arguments after this one,
-             arguments started with '-' must be specified with '=', so
-             arguments '--relay-log --relay-log-index' will not be
-             recognized as '--relay-log=--relay-log-index' */
-	  if (!*++pos || *pos[0] == '-')
+
+             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,

=== modified file 'sql-common/client.c'
--- a/sql-common/client.c	2009-02-25 10:03:18 +0000
+++ b/sql-common/client.c	2009-03-24 09:50:09 +0000
@@ -1135,6 +1135,8 @@ void mysql_read_default_options(struct s
     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] == '-')
       {

=== modified file 'storage/ndb/test/run-test/setup.cpp'
--- a/storage/ndb/test/run-test/setup.cpp	2008-12-12 08:04:28 +0000
+++ b/storage/ndb/test/run-test/setup.cpp	2009-03-24 09:50:09 +0000
@@ -112,6 +112,8 @@ setup_config(atrt_config& config, const 
      */
     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)))
@@ -400,6 +402,12 @@ load_options(int argc, char** argv, int 
 {
   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;

Thread
bzr commit into mysql-6.0-rpl branch (zhenxing.he:2828) Bug#25129He Zhenxing24 Mar