mirror of
https://github.com/rsmarples/dhcpcd.git
synced 2024-12-18 06:13:30 +08:00
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.
This commit is contained in:
parent
9783ceb17a
commit
e1caa8dbad
61
common.c
61
common.c
@ -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;
|
||||
|
||||
while(!feof(fp)) {
|
||||
if (*line == NULL || last != 0) {
|
||||
*len += BUFSIZ;
|
||||
*line = xrealloc(*line, *len);
|
||||
again:
|
||||
if (feof(fp))
|
||||
return NULL;
|
||||
|
||||
#ifdef DEBUG_MEMORY
|
||||
if (!lbuf)
|
||||
atexit(free_lbuf);
|
||||
#endif
|
||||
|
||||
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 */
|
||||
|
2
common.h
2
common.h
@ -86,7 +86,7 @@ int closefrom(int);
|
||||
|
||||
int set_cloexec(int);
|
||||
int set_nonblock(int);
|
||||
ssize_t get_line(char **, size_t *, FILE *);
|
||||
char *get_line(FILE * restrict);
|
||||
extern int clock_monotonic;
|
||||
int get_monotonic(struct timeval *);
|
||||
time_t uptime(void);
|
||||
|
25
duid.c
25
duid.c
@ -47,30 +47,23 @@ get_duid(unsigned char *duid, const struct interface *iface)
|
||||
time_t t;
|
||||
int x = 0;
|
||||
unsigned char *p = duid;
|
||||
size_t len = 0, l = 0;
|
||||
char *buffer = NULL, *line, *option;
|
||||
size_t len = 0;
|
||||
char *line;
|
||||
|
||||
/* If we already have a DUID then use it as it's never supposed
|
||||
* to change once we have one even if the interfaces do */
|
||||
if ((f = fopen(DUID, "r"))) {
|
||||
while ((get_line(&buffer, &len, f))) {
|
||||
line = buffer;
|
||||
while ((option = strsep(&line, " \t")))
|
||||
if (*option != '\0')
|
||||
break;
|
||||
if (!option || *option == '\0' || *option == '#')
|
||||
continue;
|
||||
l = hwaddr_aton(NULL, option);
|
||||
if (l && l <= DUID_LEN) {
|
||||
hwaddr_aton(duid, option);
|
||||
while ((line = get_line(f))) {
|
||||
len = hwaddr_aton(NULL, line);
|
||||
if (len && len <= DUID_LEN) {
|
||||
hwaddr_aton(duid, line);
|
||||
break;
|
||||
}
|
||||
l = 0;
|
||||
len = 0;
|
||||
}
|
||||
fclose(f);
|
||||
free(buffer);
|
||||
if (l)
|
||||
return l;
|
||||
if (len)
|
||||
return len;
|
||||
} else {
|
||||
if (errno != ENOENT)
|
||||
return 0;
|
||||
|
10
if-linux.c
10
if-linux.c
@ -431,18 +431,15 @@ struct interface *
|
||||
discover_interfaces(int argc, char * const *argv)
|
||||
{
|
||||
FILE *f;
|
||||
char *buffer = NULL, *p;
|
||||
size_t len = 0, ln = 0, n;
|
||||
char *p;
|
||||
size_t ln = 0, n;
|
||||
int i;
|
||||
struct interface *ifs = NULL, *ifp, *ifl;
|
||||
|
||||
if ((f = fopen("/proc/net/dev", "r"))) {
|
||||
while (get_line(&buffer, &len, f)) {
|
||||
while (p = get_line(f)) {
|
||||
if (++ln < 2)
|
||||
continue;
|
||||
p = buffer;
|
||||
while (isspace((unsigned int)*p))
|
||||
p++;
|
||||
n = strcspn(p, ": \t");
|
||||
p[n]= '\0';
|
||||
ifl = NULL;
|
||||
@ -479,7 +476,6 @@ discover_interfaces(int argc, char * const *argv)
|
||||
}
|
||||
}
|
||||
fclose(f);
|
||||
free(buffer);
|
||||
}
|
||||
return ifs;
|
||||
}
|
||||
|
18
if-options.c
18
if-options.c
@ -586,8 +586,7 @@ read_config(const char *file, const char *ifname)
|
||||
{
|
||||
struct if_options *ifo;
|
||||
FILE *f;
|
||||
size_t len = 0;
|
||||
char *line, *option, *p, *buffer = NULL;
|
||||
char *line, *option, *p;
|
||||
int skip = 0;
|
||||
|
||||
/* Seed our default options */
|
||||
@ -612,18 +611,8 @@ read_config(const char *file, const char *ifname)
|
||||
if (!f)
|
||||
return ifo;
|
||||
|
||||
while ((get_line(&buffer, &len, f))) {
|
||||
line = buffer;
|
||||
while ((option = strsep(&line, " \t")))
|
||||
if (*option != '\0')
|
||||
break;
|
||||
if (!option || *option == '\0' || *option == '#')
|
||||
continue;
|
||||
/* Trim leading whitespace */
|
||||
if (line) {
|
||||
while (*line != '\0' && (*line == ' ' || *line == '\t'))
|
||||
line++;
|
||||
}
|
||||
while ((line = get_line(f))) {
|
||||
option = strsep(&line, " \t");
|
||||
/* Trim trailing whitespace */
|
||||
if (line && *line) {
|
||||
p = line + strlen(line) - 1;
|
||||
@ -646,7 +635,6 @@ read_config(const char *file, const char *ifname)
|
||||
break;
|
||||
}
|
||||
}
|
||||
free(buffer);
|
||||
fclose(f);
|
||||
|
||||
/* Terminate the encapsulated options */
|
||||
|
Loading…
Reference in New Issue
Block a user