diff options
Diffstat (limited to 'sbin/devfs/devfs.c')
-rw-r--r-- | sbin/devfs/devfs.c | 91 |
1 files changed, 90 insertions, 1 deletions
diff --git a/sbin/devfs/devfs.c b/sbin/devfs/devfs.c index 4622bb9..8608af3 100644 --- a/sbin/devfs/devfs.c +++ b/sbin/devfs/devfs.c @@ -1,5 +1,5 @@ /*- - * Copyright (c) 2002 Dima Dorfman. + * Copyright (c) 2001, 2002 Dima Dorfman. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -32,7 +32,9 @@ __FBSDID("$FreeBSD$"); #include <sys/param.h> +#include <sys/queue.h> +#include <assert.h> #include <err.h> #include <fcntl.h> #include <paths.h> @@ -131,6 +133,93 @@ eatonum(const char *s) return (num); } +/* + * Read a line from a /FILE/. If the return value isn't 0, it is the + * length of the line, a pointer to which exists in /line/. It is the + * caller's responsibility to free(3) it. If the return value is 0, + * there was an error or we reached EOF, and /line/ is undefined (so, + * obviously, the caller shouldn't try to free(3) it). + */ +size_t +efgetln(FILE *fp, char **line) +{ + size_t rv; + char *cp; + + cp = fgetln(fp, &rv); + if (cp == NULL) { + *line = NULL; + return (rv); + } + if (cp[rv - 1] == '\n') { + cp[rv - 1] = '\0'; + *line = strdup(cp); + if (*line == NULL) + errx(1, "cannot allocate memory"); + --rv; + } else { + *line = malloc(rv + 1); + if (*line == NULL) + errx(1, "cannot allocate memory"); + memcpy(*line, cp, rv); + *line[rv] = '\0'; + } + assert(rv == strlen(*line)); + return (rv); +} + +struct ptrstq { + STAILQ_ENTRY(ptrstq) tq; + void *ptr; +}; + +/* + * Create an argument vector from /line/. The caller must free(3) + * /avp/, and /avp[0]/ when the argument vector is no longer + * needed unless /acp/ is 0, in which case /avp/ is undefined. + * /avp/ is NULL-terminated, so it is actually one longer than /acp/. + */ +void +tokenize(const char *line, int *acp, char ***avp) +{ + static const char *delims = " \t\n"; + struct ptrstq *pt; + STAILQ_HEAD(, ptrstq) plist; + char **ap, *cp, *wline, *xcp; + + line += strspn(line, delims); + wline = strdup(line); + if (wline == NULL) + errx(1, "cannot allocate memory"); + + STAILQ_INIT(&plist); + for (xcp = wline, *acp = 0; + (cp = strsep(&xcp, delims)) != NULL;) + if (*cp != '\0') { + pt = calloc(1, sizeof(*pt)); + if (pt == NULL) + errx(1, "cannot allocate memory"); + pt->ptr = cp; + STAILQ_INSERT_TAIL(&plist, pt, tq); + ++*acp; + } + if (*acp == 0) + return; + assert(STAILQ_FIRST(&plist)->ptr == wline); + *avp = malloc(sizeof(**avp) * (*acp + 1)); + if (*avp == NULL) + errx(1, "cannot allocate memory"); + for (ap = *avp; !STAILQ_EMPTY(&plist);) { + pt = STAILQ_FIRST(&plist); + *ap = pt->ptr; + ++ap; + assert(ap <= *avp + (*acp)); + STAILQ_REMOVE_HEAD(&plist, tq); + free(pt); + } + *ap = NULL; +} + void usage(void) { |