diff options
| author | Roy Marples <roy@marples.name> | 2008-11-05 13:57:54 +0000 |
|---|---|---|
| committer | Roy Marples <roy@marples.name> | 2008-11-05 13:57:54 +0000 |
| commit | e1caa8dbade9d653dec2172b5c052f1dbeaebb22 (patch) | |
| tree | 841472da5b26b69879e83089635607b5a6b39129 /common.c | |
| parent | 9783ceb17a8513b0ebcf5fc36d5a42cbd24f1c49 (diff) | |
| download | dhcpcd-e1caa8dbade9d653dec2172b5c052f1dbeaebb22.tar.xz | |
get_line now uses a single buffer, strips leading space and skips comments. This reduces malloc usage slightly and gives a cleaner API at the expense of a slight bss increase.
Diffstat (limited to 'common.c')
| -rw-r--r-- | common.c | 61 |
1 files changed, 47 insertions, 14 deletions
@@ -51,31 +51,64 @@ # define _PATH_DEVNULL "/dev/null" #endif -int clock_monotonic = 0; +int clock_monotonic; +static char *lbuf; +static size_t lbuf_len; + +#ifdef DEBUG_MEMORY +static void +free_lbuf(void) +{ + free(lbuf); +} +#endif /* Handy routine to read very long lines in text files. - * This means we read the whole line and avoid any nasty buffer overflows. */ -ssize_t -get_line(char **line, size_t *len, FILE *fp) + * This means we read the whole line and avoid any nasty buffer overflows. + * We strip leading space and avoid comment lines, making the code that calls + * us smaller. + * As we don't use threads, this API is clean too. */ +char * +get_line(FILE * restrict fp) { - char *p; - size_t last = 0; + char *p, *e; + size_t last; + +again: + if (feof(fp)) + return NULL; + +#ifdef DEBUG_MEMORY + if (!lbuf) + atexit(free_lbuf); +#endif - while(!feof(fp)) { - if (*line == NULL || last != 0) { - *len += BUFSIZ; - *line = xrealloc(*line, *len); + last = 0; + do { + if (!lbuf || last != 0) { + lbuf_len += BUFSIZ; + lbuf = xrealloc(lbuf, lbuf_len); } - p = *line + last; + p = lbuf + last; memset(p, 0, BUFSIZ); fgets(p, BUFSIZ, fp); last += strlen(p); - if (last && (*line)[last - 1] == '\n') { - (*line)[last - 1] = '\0'; + if (last && lbuf[last - 1] == '\n') { + lbuf[last - 1] = '\0'; break; } + } while(!feof(fp)); + if (!last) + return NULL; + + e = p + last - 1; + for (p = lbuf; p < e; p++) { + if (*p != ' ' && *p != '\t') + break; } - return last; + if (p == e || *p == '#' || *p == ';') + goto again; + return p; } /* Simple hack to return a random number without arc4random */ |
