diff options
| author | Cody Schafer <cody@linux.vnet.ibm.com> | 2012-07-13 14:27:12 -0400 |
|---|---|---|
| committer | Michal Marek <mmarek@suse.cz> | 2012-07-13 16:51:30 -0400 |
| commit | 1a7a8c6fd8ca24d3692dacddf8d658c9bb9c14ad (patch) | |
| tree | 4be8c71a267130b2df0309f46a4e7b99395f2ab7 /scripts | |
| parent | 92b72e8bcbb0d21457b53887bf41db3527258253 (diff) | |
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>
Diffstat (limited to 'scripts')
| -rw-r--r-- | scripts/kconfig/confdata.c | 61 |
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) | |||
| 182 | return 0; | 182 | return 0; |
| 183 | } | 183 | } |
| 184 | 184 | ||
| 185 | #define LINE_GROWTH 16 | ||
| 186 | static int add_byte(int c, char **lineptr, size_t slen, size_t *n) | ||
| 187 | { | ||
| 188 | char *nline; | ||
| 189 | size_t new_size = slen + 1; | ||
| 190 | if (new_size > *n) { | ||
| 191 | new_size += LINE_GROWTH - 1; | ||
| 192 | new_size *= 2; | ||
| 193 | nline = realloc(*lineptr, new_size); | ||
| 194 | if (!nline) | ||
| 195 | return -1; | ||
| 196 | |||
| 197 | *lineptr = nline; | ||
| 198 | *n = new_size; | ||
| 199 | } | ||
| 200 | |||
| 201 | (*lineptr)[slen] = c; | ||
| 202 | |||
| 203 | return 0; | ||
| 204 | } | ||
| 205 | |||
| 206 | static ssize_t compat_getline(char **lineptr, size_t *n, FILE *stream) | ||
| 207 | { | ||
| 208 | char *line = *lineptr; | ||
| 209 | size_t slen = 0; | ||
| 210 | |||
| 211 | for (;;) { | ||
| 212 | int c = getc(stream); | ||
| 213 | |||
| 214 | switch (c) { | ||
| 215 | case '\n': | ||
| 216 | if (add_byte(c, &line, slen, n) < 0) | ||
| 217 | goto e_out; | ||
| 218 | slen++; | ||
| 219 | /* fall through */ | ||
| 220 | case EOF: | ||
| 221 | if (add_byte('\0', &line, slen, n) < 0) | ||
| 222 | goto e_out; | ||
| 223 | *lineptr = line; | ||
| 224 | if (slen == 0) | ||
| 225 | return -1; | ||
| 226 | return slen; | ||
| 227 | default: | ||
| 228 | if (add_byte(c, &line, slen, n) < 0) | ||
| 229 | goto e_out; | ||
| 230 | slen++; | ||
| 231 | } | ||
| 232 | } | ||
| 233 | |||
| 234 | e_out: | ||
| 235 | line[slen-1] = '\0'; | ||
| 236 | *lineptr = line; | ||
| 237 | return -1; | ||
| 238 | } | ||
| 239 | |||
| 185 | int conf_read_simple(const char *name, int def) | 240 | int conf_read_simple(const char *name, int def) |
| 186 | { | 241 | { |
| 187 | FILE *in = NULL; | 242 | FILE *in = NULL; |
| 188 | char line[1024]; | 243 | char *line = NULL; |
| 244 | size_t line_asize = 0; | ||
| 189 | char *p, *p2; | 245 | char *p, *p2; |
| 190 | struct symbol *sym; | 246 | struct symbol *sym; |
| 191 | int i, def_flags; | 247 | int i, def_flags; |
| @@ -247,7 +303,7 @@ load: | |||
| 247 | } | 303 | } |
| 248 | } | 304 | } |
| 249 | 305 | ||
| 250 | while (fgets(line, sizeof(line), in)) { | 306 | while (compat_getline(&line, &line_asize, in) != -1) { |
| 251 | conf_lineno++; | 307 | conf_lineno++; |
| 252 | sym = NULL; | 308 | sym = NULL; |
| 253 | if (line[0] == '#') { | 309 | if (line[0] == '#') { |
| @@ -335,6 +391,7 @@ setsym: | |||
| 335 | cs->def[def].tri = EXPR_OR(cs->def[def].tri, sym->def[def].tri); | 391 | cs->def[def].tri = EXPR_OR(cs->def[def].tri, sym->def[def].tri); |
| 336 | } | 392 | } |
| 337 | } | 393 | } |
| 394 | free(line); | ||
| 338 | fclose(in); | 395 | fclose(in); |
| 339 | 396 | ||
| 340 | if (modules_sym) | 397 | if (modules_sym) |
