Using stdio in getent() results in a minor wallclock speedup but
halves the system time on my test machine.  As a bonus we can reuse
pfp in tcgetnext().

 - todd

Index: lib/libc/gen/getcap.c
===================================================================
RCS file: /cvs/src/lib/libc/gen/getcap.c,v
retrieving revision 1.28
diff -u -r1.28 getcap.c
--- lib/libc/gen/getcap.c       6 Jul 2011 18:51:09 -0000       1.28
+++ lib/libc/gen/getcap.c       6 Jul 2011 21:28:46 -0000
@@ -58,7 +58,7 @@
 static int      gottoprec;     /* Flag indicating retrieval of toprecord */
 
 static int     cdbget(DB *, char **, const char *);
-static int     getent(char **, u_int *, char **, int, const char *, int, char 
*);
+static int     getent(char **, u_int *, char **, FILE *, const char *, int, 
char *);
 static int     nfcmp(const char *, char *);
 
 static int     usedb = 1;
@@ -168,12 +168,12 @@
 {
        u_int dummy;
 
-       return (getent(buf, &dummy, db_array, -1, name, 0, NULL));
+       return (getent(buf, &dummy, db_array, NULL, name, 0, NULL));
 }
 
 /*
- * Getent implements the functions of cgetent.  If fd is non-negative,
- * *db_array has already been opened and fd is the open file descriptor.  We
+ * Getent implements the functions of cgetent.  If fp is non-NULL,
+ * *db_array has already been opened and fp is the open file descriptor.  We
  * do this to save time and avoid using up file descriptors for tc=
  * recursions.
  *
@@ -190,7 +190,7 @@
  *       MAX_RECURSION.
  */
 static int
-getent(char **cap, u_int *len, char **db_array, int fd,
+getent(char **cap, u_int *len, char **db_array, FILE *fp,
        const char *name, int depth, char *nfield)
 {
        DB *capdbp;
@@ -240,8 +240,8 @@
                /*
                 * Open database if not already open.
                 */
-               if (fd >= 0) {
-                       (void)lseek(fd, (off_t)0, SEEK_SET);
+               if (fp != NULL) {
+                       (void)fseek(fp, 0L, SEEK_SET);
                        myfd = 0;
                        opened++;
                } else {
@@ -272,8 +272,8 @@
                                *cap = cbuf;
                                return (retval);
                        } else {
-                               fd = open(*db_p, O_RDONLY, 0);
-                               if (fd < 0) {
+                               fp = fopen(*db_p, "r");
+                               if (fp == NULL) {
                                        /* No error on unfound file. */
                                        continue;
                                }
@@ -308,20 +308,19 @@
                        rp = record;
                        for (;;) {
                                if (bp >= b_end) {
-                                       int n;
+                                       size_t n;
 
-                                       n = read(fd, buf, sizeof(buf));
-                                       if (n <= 0) {
+                                       n = fread(buf, 1, sizeof(buf), fp);
+                                       if (n == 0) {
+                                               eof = feof(fp);
                                                if (myfd)
-                                                       (void)close(fd);
-                                               if (n < 0) {
-                                                       free(record);
-                                                       return (-2);
-                                               } else {
-                                                       fd = -1;
-                                                       eof = 1;
+                                                       (void)fclose(fp);
+                                               if (eof) {
+                                                       fp = NULL;
                                                        break;
                                                }
+                                               free(record);
+                                               return (-2);
                                        }
                                        b_end = buf+n;
                                        bp = buf;
@@ -343,7 +342,7 @@
                                 * some more.
                                 */
                                if (rp >= r_end) {
-                                       u_int pos;
+                                       size_t pos;
                                        size_t newsize;
                                        char *nrecord;
 
@@ -354,7 +353,7 @@
                                                if (record)
                                                        free(record);
                                                if (myfd)
-                                                       (void)close(fd);
+                                                       (void)fclose(fp);
                                                errno = ENOMEM;
                                                return (-2);
                                        }
@@ -440,13 +439,13 @@
                        tclen = s - tcstart;
                        tcend = s;
 
-                       iret = getent(&icap, &ilen, db_p, fd, tc, depth+1,
+                       iret = getent(&icap, &ilen, db_p, fp, tc, depth+1,
                                      NULL);
                        if (iret != 0) {
                                /* an error */
                                if (iret < -1) {
                                        if (myfd)
-                                               (void)close(fd);
+                                               (void)fclose(fp);
                                        free(record);
                                        return (iret);
                                }
@@ -498,7 +497,7 @@
                                        if (record)
                                                free(record);
                                        if (myfd)
-                                               (void)close(fd);
+                                               (void)fclose(fp);
                                        free(ibuf);
                                        errno = ENOMEM;
                                        return (-2);
@@ -532,7 +531,7 @@
         * return capability, length and success.
         */
        if (myfd)
-               (void)close(fd);
+               (void)fclose(fp);
        *len = rp - record - 1; /* don't count NUL */
        if (r_end > rp) {
                char *nrecord;
@@ -660,13 +659,12 @@
 cgetnext(char **cap, char **db_array)
 {
        size_t len;
-       int serrno, status = -1;
-       char nbuf[BSIZE];
-       char *record = NULL, *r_end, *rp;
-       char buf[BUFSIZ];
-       char *b_end, *bp;
-       int c;
+       int c, serrno, status = -1;
+       char buf[BUFSIZ], nbuf[BSIZE];
+       char *b_end, *bp, *r_end, *rp;
+       char *record = NULL;
        u_int dummy;
+       off_t pos;
 
        if (dbp == NULL)
                dbp = db_array;
@@ -747,17 +745,17 @@
                         * some more.
                         */
                        if (rp >= r_end) {
-                               size_t newsize, pos;
+                               size_t newsize, off;
                                char *nrecord;
 
-                               pos = rp - record;
+                               off = rp - record;
                                newsize = r_end - record + BFRAG;
                                nrecord = realloc(record, newsize);
                                if (nrecord == NULL)
                                        goto done;
                                record = nrecord;
                                r_end = record + newsize;
-                               rp = record + pos;
+                               rp = record + off;
                        }
                }
                /* loop invariant lets us do this */
@@ -783,7 +781,10 @@
        nbuf[len] = '\0';
 
        /* return value of getent() is one less than cgetnext() */
-       status = getent(cap, &dummy, db_array, -1, nbuf, 0, NULL) + 1;
+       pos = ftello(pfp);
+       status = getent(cap, &dummy, db_array, pfp, nbuf, 0, NULL) + 1;
+       if (status > 0)
+               fseeko(pfp, pos, SEEK_SET);
 done:
        serrno = errno;
        free(record);

Reply via email to