]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
conf: use dynamic sized strings
authorYehuda Sadeh <yehuda@hq.newdream.net>
Fri, 13 Mar 2009 21:05:14 +0000 (14:05 -0700)
committerYehuda Sadeh <yehuda@hq.newdream.net>
Fri, 13 Mar 2009 21:05:56 +0000 (14:05 -0700)
src/Makefile.am
src/common/ConfUtils.cc
src/common/dyn_snprintf.c [new file with mode: 0644]
src/common/dyn_snprintf.h [new file with mode: 0644]
src/config.cc

index d6803c71954d792b8813ab732d02f22a5ecab0ce..543e994eebd03c8a2a73575682e443f10c584b7d 100644 (file)
@@ -206,6 +206,7 @@ libcommon_files = \
        common/sctp_crc32.c\
        common/assert.cc \
        common/debug.cc \
+       common/dyn_snprintf.c \
        common/WorkQueue.cc \
        common/ConfUtils.cc \
        mon/MonMap.cc \
@@ -304,6 +305,7 @@ noinst_HEADERS = \
         common/Clock.h\
         common/common_init.h\
         common/Cond.h\
+        common/dyn_snprintf.h\
         common/ConfUtils.h\
         common/DecayCounter.h\
         common/Finisher.h\
index 7f244387f49497bba9be590d13ccf69dfc6ef96b..935b0cd4e7d231b056f8939c6a5d45fd29a2303d 100644 (file)
@@ -12,6 +12,7 @@
 #include <string>
 
 #include "ConfUtils.h"
+#include "dyn_snprintf.h"
 
 using namespace std;
 
@@ -188,7 +189,7 @@ static char *normalize_name(const char *name)
        return newname;
 }
 
-#define MAX_LINE 2560
+#define MAX_LINE 256
 
 static char *get_next_delim(char *str, const char *delim, int alloc, char **p)
 {
@@ -217,7 +218,8 @@ static int _parse_section(char *str, ConfLine *parsed)
        char *name = NULL;
        char *p;
        int ret = 0;
-       char line[MAX_LINE];
+       char *line;
+       size_t max_line = MAX_LINE;
 
        char *start, *end;
 
@@ -235,6 +237,7 @@ static int _parse_section(char *str, ConfLine *parsed)
        
 
        p = start;
+       line = (char *)malloc(max_line);
        line[0] ='\0';
 
        do {
@@ -244,15 +247,17 @@ static int _parse_section(char *str, ConfLine *parsed)
 
                if (*name) {
                        if (*line)
-                               snprintf(line, MAX_LINE, "%s %s", line, name);
+                               dyn_snprintf(&line, &max_line, 2, "%s %s", line, name);
                        else
-                               snprintf(line, MAX_LINE, "%s", name);
+                               dyn_snprintf(&line, &max_line, 1, "%s", name);
                }
        } while (*name);
        
        if (*line)      
                parsed->set_section(line);
 
+       free(line);
+
        return ret;
 }
 
@@ -446,10 +451,12 @@ void ConfFile::_dump(int fd)
 {
        SectionList::iterator sec_iter, sec_end;
         ConfLine *cl;
-       char line[MAX_LINE];
-       int len = 0;
+       char *line;
+       size_t max_line = MAX_LINE;
+       size_t len;
        char *p;
-       
+
+       line = (char *)malloc(max_line);
 
        sec_end=sections_list.end();
 
@@ -467,12 +474,22 @@ void ConfFile::_dump(int fd)
 
                        if (cl) {
                                line[0] = '\0';
-                               cl->output(line, MAX_LINE);
+                               do {
+                                       if (len >= max_line) {
+                                               max_line *= 2;
+                                               free(line);
+                                               line = (char *)malloc(max_line);
+                                       }
+
+                                       len = cl->output(line, max_line);
+                               } while (len == max_line);
                                ::write(fd, line, strlen(line));
                                ::write(fd, "\n", 1);
                        }
                }
        }
+
+       free(line);
 }
 
 void ConfFile::dump()
@@ -513,10 +530,15 @@ int ConfFile::_parse(char *filename, ConfSection **psection)
 {
        char *buf;
        int len, i, l;
-       char line[MAX_LINE];
+       char *line;
        ConfLine *cl;
        ConfSection *section = *psection;
        int fd;
+       int max_line = MAX_LINE;
+
+       line = (char *)malloc(max_line);
+
+       
 
        fd = open(filename, O_RDWR);
        if (fd < 0)
@@ -553,6 +575,11 @@ int ConfFile::_parse(char *filename, ConfSection **psection)
                                break;
                        default:
                                line[l++] = buf[i];
+
+                               if (l == max_line-1) {
+                                       max_line *= 2;
+                                       line = (char *)realloc(line, max_line);
+                               }
                        }
                }
        } while (len);
@@ -561,6 +588,8 @@ int ConfFile::_parse(char *filename, ConfSection **psection)
 
        *psection = section;
 
+       free(line);
+
        return 1;
 }
 
diff --git a/src/common/dyn_snprintf.c b/src/common/dyn_snprintf.c
new file mode 100644 (file)
index 0000000..e274b79
--- /dev/null
@@ -0,0 +1,54 @@
+#include <stdio.h>
+#include <stdarg.h>
+#include <stdlib.h>
+#include <string.h>
+
+#define  MAXARGS     32
+
+
+#define CALL_SNPRINTF(buf, size, format, args) snprintf(buf, size, format, args[0], args[1], args[2], args[3], \
+                               args[4], args[5], args[6], args[7],     \
+                               args[8], args[9], args[10], args[11],   \
+                               args[12], args[13], args[14], args[15], \
+                               args[16], args[17], args[18], args[19], \
+                               args[20], args[21], args[22], args[23], \
+                               args[24], args[25], args[26], args[27], \
+                               args[28], args[29], args[30], args[31])
+
+int dyn_snprintf(char **pbuf, size_t *pmax_size, int nargs, const char *format, ...)
+{
+       int ret;
+       va_list vl;
+       char *old_buf = *pbuf;
+       char *args[MAXARGS];
+       char *arg;
+       char *tmp_src = NULL;
+       int i;
+
+       if (nargs > MAXARGS)
+               return -1;
+
+       va_start(vl, format);
+       arg = va_arg(vl, char *);
+       for (i = 0; i<nargs; i++) {
+               if (arg == old_buf) {
+                       if (!tmp_src) {
+                               tmp_src = strdup(old_buf);
+                       }
+                       arg = tmp_src;
+               }
+               args[i] = arg;
+               arg = va_arg(vl, char *);
+       }
+       va_end(vl);
+       ret = CALL_SNPRINTF(*pbuf, *pmax_size, format, args);
+
+       if (ret >= *pmax_size) {
+               *pmax_size = ret * 2;
+               *pbuf = (char *)realloc(*pbuf, *pmax_size);
+               ret = CALL_SNPRINTF(*pbuf, *pmax_size, format, args);
+       }
+
+       return ret;
+}
+
diff --git a/src/common/dyn_snprintf.h b/src/common/dyn_snprintf.h
new file mode 100644 (file)
index 0000000..743b1a9
--- /dev/null
@@ -0,0 +1,14 @@
+#ifndef __DYN_SNPRINTF_H
+#define __DYN_SNPRINTF_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+int dyn_snprintf(char **pbuf, size_t *pmax_size, int nargs, const char *format, ...);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
index 0247cf246cc67a65c4f0eec19e10bfffb3f2409b..e285eebbdfb481fa7fb4da697ecee57a8da5c2ad 100644 (file)
@@ -37,6 +37,7 @@ atomic_t buffer_total_alloc;
 #include "osd/osd_types.h"
 
 #include "common/ConfUtils.h"
+#include "common/dyn_snprintf.h"
 
 static bool show_config = false;
 
@@ -769,25 +770,33 @@ static const char *var_val(char *var_name)
        return "";
 }
 
-#define MAX_LINE 2560
+#define MAX_LINE 256
 #define MAX_VAR_LEN 32
 
 char *conf_post_process_val(const char *val)
 {
   char var_name[MAX_VAR_LEN];
-  char buf[MAX_LINE];
+  char *buf;
   int i=0;
-  int out_pos = 0;
+  size_t out_pos = 0;
+  size_t max_line = MAX_LINE;
+
+  buf = (char *)malloc(max_line);
 
-  while (val[i] && (out_pos < MAX_LINE - 1)) {
+  while (val[i]) {
     if (val[i] == '$') {
        if (get_var(val, i+1, var_name, MAX_VAR_LEN, &i)) {
-               out_pos += snprintf(buf+out_pos, MAX_LINE-out_pos, "%s", var_val(var_name));
+               out_pos = dyn_snprintf(&buf, &max_line, 2, "%s%s", buf, var_val(var_name));
        } else {
          ++i;
        }
     } else {
+       if (out_pos == max_line - 1) {
+               max_line *= 2;
+               buf = (char *)realloc(buf, max_line);
+       }
        buf[out_pos] = val[i];
+       buf[out_pos + 1] = '\0';
        ++out_pos;
        ++i;
     }
@@ -795,7 +804,7 @@ char *conf_post_process_val(const char *val)
 
   buf[out_pos] = '\0';
 
-  return strdup(buf);
+  return buf;
 }
 
 #define OPT_READ_TYPE(ret, section, var, type, out, def) \