Date: Wed, 3 Feb 2010 10:34:47 GMT From: Robert Watson <rwatson@FreeBSD.org> To: Perforce Change Reviews <perforce@freebsd.org> Subject: PERFORCE change 174218 for review Message-ID: <201002031034.o13AYlRq032135@repoman.freebsd.org>
next in thread | raw e-mail | index | archive | help
http://p4web.freebsd.org/chv.cgi?CH=174218 Change 174218 by rwatson@rwatson_vimage_client on 2010/02/03 10:34:01 Keep a running count of valid file descriptors in the directory length array, rather than marking unused ones as (-1). This avoids several loops. While here, fix a (+ sizeof(int)) into a (* sizeof(int)) and a few other nits. Affected files ... .. //depot/projects/trustedbsd/capabilities/src/libexec/rtld-elf/rtld.c#38 edit Differences ... ==== //depot/projects/trustedbsd/capabilities/src/libexec/rtld-elf/rtld.c#38 (text+ko) ==== @@ -188,7 +188,9 @@ static char *ld_bind_now; /* Environment variable for immediate binding */ static char *ld_debug; /* Environment variable for debugging */ static int *ld_library_dirs = NULL; /* File descriptors of lib path (end: -1) */ +static int ld_library_dirs_done; /* ld_library_dirs has been initialized */ static int ld_library_dirlen; /* Capacity of ld_library_dirs */ +static int ld_library_dircount; /* Number of entries in ld_library_dirs */ #ifndef IN_RTLD_CAP static char *ld_library_path; /* Environment variable for search path */ static char *ld_preload; /* Environment variable for libraries to @@ -1240,9 +1242,9 @@ { int fd, i; - if (ld_library_dirs == NULL) + if (!ld_library_dirs_done) init_libdirs(); - for (i = 0; (i < ld_library_dirlen) && (ld_library_dirs[i] != -1); i++) { + for (i = 0; i < ld_library_dircount); i++) { fd = openat(ld_library_dirs[i], name, O_RDONLY); if (fd >= 0) return (fd); @@ -2111,35 +2113,39 @@ /* * Add a file descriptor to ld_library_dirs. + * + * XXX: This may be called from either the rtld startup code, or from + * ld_libdirs. We have no way to distinguish them on error, so die() + * unconditionally. Perhaps the latter case should allow graceful failure. + * + * XXX: Synchronization? */ static void add_libdir_fd(int fd) { - int i; - if (ld_library_dirs == NULL) { - /* Initialize the FD list. */ + /* Initialize the FD list. */ + if (!ld_library_dirs_done) { ld_library_dirlen = INITIAL_FDLEN; + ld_library_dircount = 0; ld_library_dirs = xmalloc(ld_library_dirlen * sizeof(int)); - memset(ld_library_dirs, 0xff, ld_library_dirlen * sizeof(int)); + ld_library_dirs_done = 1; } - /* Find the next available FD slot. */ - for (i = 0; (i < ld_library_dirlen) && (ld_library_dirs[i] != -1); i++) - ; - - if (i == ld_library_dirlen) { - /* We need more space. */ - int old_size = ld_library_dirlen + sizeof(int); - + /* Do we need to grow? */ + if (ld_library_dirlen == ld_library_dircount) { ld_library_dirlen *= 2; - ld_library_dirs = realloc(ld_library_dirs, 2 * old_size); - memset(ld_library_dirs + old_size, 0xff, old_size); + ld_library_dirs = realloc(ld_library_dirs, + ld_library_dirlen * sizeof(int)); + if (ld_library_dirs == NULL) { + _rtld_error("add_libdir_fd: realloc failed"); + die(); + } + } - if (ld_library_dirs == NULL) - err(-1, "realloc() failed"); - } - ld_library_dirs[i] = fd; + /* Add the new library directory fd to the end. */ + ld_library_dirs[ld_library_dircount] = fd; + ld_library_dircount++; } /* @@ -2204,12 +2210,6 @@ add_libdir_paths(gethints()); add_libdir_paths(STANDARD_LIBRARY_PATH); #endif - - /* If all else fails, create an empty array */ - if (ld_library_dirlen == 0) { - ld_library_dirs = malloc(sizeof(int)); - ld_library_dirs[0] = -1; - } } /* @@ -2220,7 +2220,6 @@ int ld_libdirs(int *fds, int *fdcount) { - int i = 0; if (fdcount == NULL) return (-1); @@ -2228,16 +2227,14 @@ *fdcount = -1; return (-1); } - if (ld_library_dirs == NULL) + if (!ld_library_dirs_done) init_libdirs(); - for (i = 0; (i < ld_library_dirlen) && (ld_library_dirs[i] != -1); i++) - ; - if (*fdcount < i) { - *fdcount = i; + if (*fdcount < ld_library_dircount) { + *fdcount = ld_library_dircount; return (-1); } - *fdcount = i; - memcpy(fds, ld_library_dirs, i * sizeof(int)); + *fdcount = ld_library_dircount; + memcpy(fds, ld_library_dirs, ld_library_dircount * sizeof(int)); return (0); }
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201002031034.o13AYlRq032135>