Author: kib
Date: Mon Mar 12 12:16:08 2012
New Revision: 232862
URL: http://svn.freebsd.org/changeset/base/232862

Log:
  Rtld on diet part 2:
  
  Do not use stdio for libmap.conf read.  Directly map the file and
  parse lines from the mappings.
  
  Reviewed by:  kan
  MFC after:    3 weeks

Modified:
  head/libexec/rtld-elf/libmap.c

Modified: head/libexec/rtld-elf/libmap.c
==============================================================================
--- head/libexec/rtld-elf/libmap.c      Mon Mar 12 12:15:47 2012        
(r232861)
+++ head/libexec/rtld-elf/libmap.c      Mon Mar 12 12:16:08 2012        
(r232862)
@@ -2,11 +2,14 @@
  * $FreeBSD$
  */
 
-#include <stdio.h>
-#include <string.h>
-#include <stdlib.h>
-#include <sys/queue.h>
 #include <sys/param.h>
+#include <sys/fcntl.h>
+#include <sys/mman.h>
+#include <sys/queue.h>
+#include <sys/stat.h>
+#include <errno.h>
+#include <stdlib.h>
+#include <string.h>
 
 #include "debug.h"
 #include "rtld.h"
@@ -25,7 +28,6 @@ TAILQ_HEAD(lm_list, lm);
 struct lm {
        char *f;
        char *t;
-
        TAILQ_ENTRY(lm) lm_link;
 };
 
@@ -37,17 +39,15 @@ struct lmp {
        TAILQ_ENTRY(lmp) lmp_link;
 };
 
-static int     lm_count;
+static int lm_count;
 
-static void            lmc_parse       (FILE *);
-static void            lm_add          (const char *, const char *, const char 
*);
-static void            lm_free         (struct lm_list *);
-static char *          lml_find        (struct lm_list *, const char *);
-static struct lm_list *        lmp_find        (const char *);
-static struct lm_list *        lmp_init        (char *);
-static const char * quickbasename      (const char *);
-static int     readstrfn       (void * cookie, char *buf, int len);
-static int     closestrfn      (void * cookie);
+static void lmc_parse(char *, size_t);
+static void lm_add(const char *, const char *, const char *);
+static void lm_free(struct lm_list *);
+static char *lml_find(struct lm_list *, const char *);
+static struct lm_list *lmp_find(const char *);
+static struct lm_list *lmp_init(char *);
+static const char *quickbasename(const char *);
 
 #define        iseol(c)        (((c) == '#') || ((c) == '\0') || \
                         ((c) == '\n') || ((c) == '\r'))
@@ -59,56 +59,88 @@ static int  closestrfn      (void * cookie);
 #define        rtld_isspace(c) ((c) == ' ' || (c) == '\t')
 
 int
-lm_init (char *libmap_override)
+lm_init(char *libmap_override)
 {
-       FILE    *fp;
-
-       dbg("%s(\"%s\")", __func__, libmap_override);
+       struct stat st;
+       char *lm_map, *p;
+       int fd;
 
+       dbg("lm_init(\"%s\")", libmap_override);
        TAILQ_INIT(&lmp_head);
 
-       fp = fopen(_PATH_LIBMAP_CONF, "r");
-       if (fp) {
-               lmc_parse(fp);
-               fclose(fp);
+       fd = open(_PATH_LIBMAP_CONF, O_RDONLY);
+       if (fd == -1) {
+               dbg("lm_init: open(\"%s\") failed, %s", _PATH_LIBMAP_CONF,
+                   strerror(errno));
+               goto override;
+       }
+       if (fstat(fd, &st) == -1) {
+               close(fd);
+               dbg("lm_init: fstat(\"%s\") failed, %s", _PATH_LIBMAP_CONF,
+                   strerror(errno));
+               goto override;
        }
+       lm_map = mmap(NULL, st.st_size, PROT_READ, MAP_PRIVATE, fd, 0);
+       if (lm_map == (const char *)MAP_FAILED) {
+               close(fd);
+               dbg("lm_init: mmap(\"%s\") failed, %s", _PATH_LIBMAP_CONF,
+                   strerror(errno));
+               goto override;
+       }
+       close(fd);
+       lmc_parse(lm_map, st.st_size);
+       munmap(lm_map, st.st_size);
 
+override:
        if (libmap_override) {
-               char    *p;
-               /* do some character replacement to make $LIBMAP look like a
-                  text file, then "open" it with funopen */
+               /*
+                * Do some character replacement to make $LIBMAP look
+                * like a text file, then parse it.
+                */
                libmap_override = xstrdup(libmap_override);
-
                for (p = libmap_override; *p; p++) {
                        switch (*p) {
-                               case '=':
-                                       *p = ' '; break;
-                               case ',':
-                                       *p = '\n'; break;
+                       case '=':
+                               *p = ' ';
+                               break;
+                       case ',':
+                               *p = '\n';
+                               break;
                        }
                }
-               fp = funopen(libmap_override, readstrfn, NULL, NULL, 
closestrfn);
-               if (fp) {
-                       lmc_parse(fp);
-                       fclose(fp);
-               }
+               lmc_parse(p, strlen(p));
+               free(p);
        }
 
        return (lm_count == 0);
 }
 
 static void
-lmc_parse (FILE *fp)
+lmc_parse(char *lm_p, size_t lm_len)
 {
-       char    *cp;
-       char    *f, *t, *c, *p;
-       char    prog[MAXPATHLEN];
-       char    line[MAXPATHLEN + 2];
-
-       dbg("%s(%p)", __func__, fp);
+       char *cp, *f, *t, *c, *p;
+       char prog[MAXPATHLEN];
+       char line[MAXPATHLEN + 2];
+       size_t cnt;
+       int i;
        
+       cnt = 0;
        p = NULL;
-       while ((cp = fgets(line, MAXPATHLEN + 1, fp)) != NULL) {
+       while (cnt < lm_len) {
+               i = 0;
+               while (lm_p[cnt] != '\n' && cnt < lm_len &&
+                   i < sizeof(line) - 1) {
+                       line[i] = lm_p[cnt];
+                       cnt++;
+                       i++;
+               }
+               line[i] = '\0';
+               while (lm_p[cnt] != '\n' && cnt < lm_len)
+                       cnt++;
+               /* skip over nl */
+               cnt++;
+
+               cp = &line[0];
                t = f = c = NULL;
 
                /* Skip over leading space */
@@ -344,31 +376,3 @@ quickbasename (const char *path)
        }
        return (p);
 }
-
-static int
-readstrfn(void * cookie, char *buf, int len)
-{
-       static char     *current;
-       static int      left;
-       int     copied;
-       
-       copied = 0;
-       if (!current) {
-               current = cookie;
-               left = strlen(cookie);
-       }
-       while (*current && left && len) {
-               *buf++ = *current++;
-               left--;
-               len--;
-               copied++;
-       }
-       return copied;
-}
-
-static int
-closestrfn(void * cookie)
-{
-       free(cookie);
-       return 0;
-}
_______________________________________________
svn-src-head@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-head
To unsubscribe, send any mail to "svn-src-head-unsubscr...@freebsd.org"

Reply via email to