summaryrefslogtreecommitdiff
path: root/mysys/default_modify.c
diff options
context:
space:
mode:
authorunknown <petr@mysql.com>2005-06-23 18:13:58 +0400
committerunknown <petr@mysql.com>2005-06-23 18:13:58 +0400
commit6311217a23cd8424ad10a23ee752141257275252 (patch)
tree88e26b77f00f43df3a5633d689880e7ea37dfc6b /mysys/default_modify.c
parentcceab6e62c3496b7ae58e515e3ffc0f76be050de (diff)
downloadmariadb-git-6311217a23cd8424ad10a23ee752141257275252.tar.gz
Fix modify_defaults_file as agreed with monty (correct all occurences of an option in the section)
mysys/default_modify.c: Correct all occurences of an option in the section. To avoid memory problems preallocate reserve of 1K, and realloc it later if needed (almost never).
Diffstat (limited to 'mysys/default_modify.c')
-rw-r--r--mysys/default_modify.c57
1 files changed, 41 insertions, 16 deletions
diff --git a/mysys/default_modify.c b/mysys/default_modify.c
index 00caa7beed6..d40529817cd 100644
--- a/mysys/default_modify.c
+++ b/mysys/default_modify.c
@@ -20,6 +20,8 @@
#include <my_dir.h>
#define BUFF_SIZE 1024
+/* should be big enough to handle at least one line */
+#define RESERVE 1024
#ifdef __WIN__
#define NEWLINE "\r\n"
@@ -66,8 +68,10 @@ int modify_defaults_file(const char *file_location, const char *option,
FILE *cnf_file;
MY_STAT file_stat;
char linebuff[BUFF_SIZE], *src_ptr, *dst_ptr, *file_buffer;
- uint opt_len, optval_len, sect_len, nr_newlines= 0;
+ uint opt_len, optval_len, sect_len, nr_newlines= 0, buffer_size;
my_bool in_section= FALSE, opt_applied= 0;
+ int reserve_occupied= 0, reserve_extended= 1, old_opt_len;
+ int new_opt_len= opt_len + 1 + optval_len + NEWLINE_LEN;
DBUG_ENTER("modify_defaults_file");
if (!(cnf_file= my_fopen(file_location, O_RDWR | O_BINARY, MYF(0))))
@@ -80,23 +84,26 @@ int modify_defaults_file(const char *file_location, const char *option,
opt_len= (uint) strlen(option);
optval_len= (uint) strlen(option_value);
+ /* calculate the size of the buffer we need */
+ buffer_size= sizeof(char) * (file_stat.st_size +
+ /* option name len */
+ opt_len +
+ /* reserve for '=' char */
+ 1 +
+ /* option value len */
+ optval_len +
+ /* reserve space for newline */
+ NEWLINE_LEN +
+ /* The ending zero */
+ 1 +
+ /* reserve some additional space */
+ RESERVE);
+
/*
Reserve space to read the contents of the file and some more
for the option we want to add.
*/
- if (!(file_buffer= (char*) my_malloc(sizeof(char) *
- (file_stat.st_size +
- /* option name len */
- opt_len +
- /* reserve space for newline */
- NEWLINE_LEN +
- /* reserve for '=' char */
- 1 +
- /* option value len */
- optval_len +
- /* The ending zero */
- 1), MYF(MY_WME))))
-
+ if (!(file_buffer= (char*) my_malloc(buffer_size, MYF(MY_WME))))
goto malloc_err;
sect_len= (uint) strlen(section_name);
@@ -115,13 +122,31 @@ int modify_defaults_file(const char *file_location, const char *option,
}
/* correct the option */
- if (!opt_applied && in_section && !strncmp(src_ptr, option, opt_len) &&
+ if (in_section && !strncmp(src_ptr, option, opt_len) &&
(*(src_ptr + opt_len) == '=' ||
my_isspace(&my_charset_latin1, *(src_ptr + opt_len)) ||
*(src_ptr + opt_len) == '\0'))
{
+ /*
+ we should change all options. If opt_applied is set, we are running
+ into reserved memory area. Hence we should check for overruns.
+ */
+ if (opt_applied)
+ {
+ old_opt_len= strlen(linebuff);
+ /* could be negative */
+ reserve_occupied+= new_opt_len - old_opt_len;
+ if (reserve_occupied > RESERVE*reserve_extended)
+ {
+ file_buffer= (char*) my_realloc(file_buffer, buffer_size +
+ RESERVE*reserve_extended,
+ MYF(MY_WME));
+ reserve_extended++;
+ }
+ }
+ else
+ opt_applied= 1;
dst_ptr= add_option(dst_ptr, option_value, option, remove_option);
- opt_applied= 1;
}
else
{