]> git.ipfire.org Git - thirdparty/dhcpcd.git/commitdiff
get_line now uses a single buffer, strips leading space and skips comments. This...
authorRoy Marples <roy@marples.name>
Wed, 5 Nov 2008 13:57:54 +0000 (13:57 +0000)
committerRoy Marples <roy@marples.name>
Wed, 5 Nov 2008 13:57:54 +0000 (13:57 +0000)
common.c
common.h
duid.c
if-linux.c
if-options.c

index bfd0b9c7547c5cde24212937d70c8aea361783e1..802b42be6faad55ab25cc192410eeb7b8f0474db 100644 (file)
--- a/common.c
+++ b/common.c
 #  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 */
index 453d6b77031c2c5857da6f1dc0e36a856cc26021..c58794528dbf86ff37fe0783b0d81418d8cebe1b 100644 (file)
--- a/common.h
+++ b/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);
diff --git a/duid.c b/duid.c
index 8b19550a2d8f9154a4ebec37600c0cd65dcec976..dddb3b94491133b34a83c43b587aad2c2eef4ad8 100644 (file)
--- a/duid.c
+++ b/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;
index bbbc549320d8f03ce96fb62c4912f8ea7f015fd7..188a9af59d9e2eba95312acf9eb807434a09ebac 100644 (file)
@@ -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;
 }
index 3965119d145b312f4ebf91c55544033bcca2dc2d..24bf5ad363aa1385d3f0a42d44ee78731aa8a407 100644 (file)
@@ -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 */