summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCody Schafer <cody@linux.vnet.ibm.com>2012-07-13 22:27:12 +0400
committerMichal Marek <mmarek@suse.cz>2012-07-14 00:51:30 +0400
commit1a7a8c6fd8ca24d3692dacddf8d658c9bb9c14ad (patch)
tree4be8c71a267130b2df0309f46a4e7b99395f2ab7
parent92b72e8bcbb0d21457b53887bf41db3527258253 (diff)
downloadlinux-1a7a8c6fd8ca24d3692dacddf8d658c9bb9c14ad.tar.xz
kconfig: allow long lines in config file
For some config options (CONFIG_EXTRA_FIRMWARE, for example), the length of a config file line can exceed the 1024 byte buffer. Switch from fgets to compat_getline to fix. compat_getline is an internally implimented getline work-alike for portability purposes. Signed-off-by: Cody Schafer <cody@linux.vnet.ibm.com> Signed-off-by: Michal Marek <mmarek@suse.cz>
-rw-r--r--scripts/kconfig/confdata.c61
1 files changed, 59 insertions, 2 deletions
diff --git a/scripts/kconfig/confdata.c b/scripts/kconfig/confdata.c
index 52577f052bc1..13ddf1126c2a 100644
--- a/scripts/kconfig/confdata.c
+++ b/scripts/kconfig/confdata.c
@@ -182,10 +182,66 @@ static int conf_set_sym_val(struct symbol *sym, int def, int def_flags, char *p)
return 0;
}
+#define LINE_GROWTH 16
+static int add_byte(int c, char **lineptr, size_t slen, size_t *n)
+{
+ char *nline;
+ size_t new_size = slen + 1;
+ if (new_size > *n) {
+ new_size += LINE_GROWTH - 1;
+ new_size *= 2;
+ nline = realloc(*lineptr, new_size);
+ if (!nline)
+ return -1;
+
+ *lineptr = nline;
+ *n = new_size;
+ }
+
+ (*lineptr)[slen] = c;
+
+ return 0;
+}
+
+static ssize_t compat_getline(char **lineptr, size_t *n, FILE *stream)
+{
+ char *line = *lineptr;
+ size_t slen = 0;
+
+ for (;;) {
+ int c = getc(stream);
+
+ switch (c) {
+ case '\n':
+ if (add_byte(c, &line, slen, n) < 0)
+ goto e_out;
+ slen++;
+ /* fall through */
+ case EOF:
+ if (add_byte('\0', &line, slen, n) < 0)
+ goto e_out;
+ *lineptr = line;
+ if (slen == 0)
+ return -1;
+ return slen;
+ default:
+ if (add_byte(c, &line, slen, n) < 0)
+ goto e_out;
+ slen++;
+ }
+ }
+
+e_out:
+ line[slen-1] = '\0';
+ *lineptr = line;
+ return -1;
+}
+
int conf_read_simple(const char *name, int def)
{
FILE *in = NULL;
- char line[1024];
+ char *line = NULL;
+ size_t line_asize = 0;
char *p, *p2;
struct symbol *sym;
int i, def_flags;
@@ -247,7 +303,7 @@ load:
}
}
- while (fgets(line, sizeof(line), in)) {
+ while (compat_getline(&line, &line_asize, in) != -1) {
conf_lineno++;
sym = NULL;
if (line[0] == '#') {
@@ -335,6 +391,7 @@ setsym:
cs->def[def].tri = EXPR_OR(cs->def[def].tri, sym->def[def].tri);
}
}
+ free(line);
fclose(in);
if (modules_sym)