PERFORCE change 174095 for review
Jonathan Anderson
jona at FreeBSD.org
Mon Feb 1 15:45:26 UTC 2010
http://p4web.freebsd.org/chv.cgi?CH=174095
Change 174095 by jona at jona-belle-freebsd8 on 2010/02/01 15:45:08
Implementation of ld_libdirs()
Affected files ...
.. //depot/projects/trustedbsd/capabilities/src/libexec/rtld-elf/Symbol.map#4 edit
.. //depot/projects/trustedbsd/capabilities/src/libexec/rtld-elf/rtld.c#32 edit
Differences ...
==== //depot/projects/trustedbsd/capabilities/src/libexec/rtld-elf/Symbol.map#4 (text+ko) ====
@@ -18,6 +18,10 @@
__tls_get_addr;
};
+FBSD_1.2 {
+ ld_libdirs;
+};
+
FBSDprivate_1.0 {
_rtld_thread_init;
_rtld_allocate_tls;
==== //depot/projects/trustedbsd/capabilities/src/libexec/rtld-elf/rtld.c#32 (text+ko) ====
@@ -78,6 +78,8 @@
#endif
#endif
+#define INITIAL_FDLEN 16
+
/* Types. */
typedef void (*func_ptr_type)();
typedef void * (*path_enum_proc) (const char *path, size_t len, void *arg);
@@ -167,6 +169,8 @@
static int object_match_name(const Obj_Entry *, const char *);
static void ld_utrace_log(int, void *, void *, size_t, int, const char *);
+int ld_libdirs(int *, int *);
+
void r_debug_state(struct r_debug *, struct link_map *);
/*
@@ -183,6 +187,8 @@
used to affect the libraries loaded */
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_dirlen; /* Capacity of 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
@@ -249,6 +255,8 @@
(func_ptr_type) &ld_libcache_lookup,
(func_ptr_type) &ld_insandbox,
#endif
+ (func_ptr_type) &ld_libdirs,
+
NULL
};
@@ -2020,6 +2028,7 @@
return (NULL);
}
+#endif
struct try_library_args {
const char *name;
@@ -2055,6 +2064,7 @@
return (NULL);
}
+#ifndef IN_RTLD_CAP
static char *
search_library_path(const char *name, const char *path)
{
@@ -2077,6 +2087,124 @@
}
#endif
+/*
+ * Add a file descriptor to ld_library_dirs.
+ */
+static void
+add_libdir_fd(int fd) {
+
+ if (ld_library_dirs == NULL) {
+ /* Initialize the FD list. */
+
+ ld_library_dirlen = INITIAL_FDLEN;
+ ld_library_dirs = xmalloc(ld_library_dirlen * sizeof(int));
+ memset(ld_library_dirs, 0xff, ld_library_dirlen * sizeof(int));
+ }
+
+ /* Find the next available FD slot. */
+ int i;
+ 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);
+
+ ld_library_dirlen *= 2;
+ ld_library_dirs = realloc(ld_library_dirs, 2 * old_size);
+ memset(ld_library_dirs + old_size, 0xff, old_size);
+
+ if (ld_library_dirs == NULL)
+ err(-1, "realloc() failed");
+ }
+
+ ld_library_dirs[i] = fd;
+}
+
+/*
+ * Add file descriptors for a path list (e.g. '/lib:/usr/lib') to ld_library_dirs.
+ */
+static void
+add_libdir_paths(const char *path) {
+
+ char *pathcopy, *dirname, *tokcontext;
+ int pathlen = strnlen(path, PATH_MAX);
+
+ pathcopy = malloc(pathlen + 1);
+ strncpy(pathcopy, path, pathlen + 1);
+
+ for (dirname = strtok_r(pathcopy, ":", &tokcontext); dirname;
+ dirname = strtok_r(NULL, ":", &tokcontext)) {
+
+ int fd;
+
+ struct try_library_args arg;
+ arg.name = "";
+ arg.namelen = 0;
+ arg.buffer = xmalloc(PATH_MAX);
+ arg.buflen = PATH_MAX;
+
+ if (try_library_path(dirname, strnlen(dirname, PATH_MAX), &arg))
+ fd = open(dirname, O_RDONLY);
+
+ else {
+ /* 'dirname' is not a directory path; perhaps it's a descriptor? */
+ fd = (int) strtol(dirname, NULL, 0);
+ if ((fd == 0) && (errno == 0))
+ continue;
+ }
+
+ if (fd >= 0)
+ add_libdir_fd(fd);
+ }
+
+ free(pathcopy);
+}
+
+/*
+ * Return an array of file descriptors for the library search paths.
+ */
+int
+ld_libdirs(int *fds, int *fdcount) {
+
+ if (fdcount == NULL)
+ return (-1);
+
+ else if (fds == NULL) {
+ *fdcount = -1;
+ return (-1);
+ }
+
+ if (ld_library_dirs == NULL) {
+#ifdef IN_RTLD_CAP
+
+ char *envvar = getenv(LD_ "LIBRARY_DIRS");
+ if (envvar == NULL)
+ err(-1, "No %s set in capability mode", LD_ "LIBRARY_DIRS");
+
+ add_libdir_paths(envvar);
+
+#else /* !IN_RTLD_CAP */
+
+ /* Look for directories a la find_library (TODO: refactor!). */
+ add_libdir_paths(ld_library_path);
+ add_libdir_paths(gethints());
+ add_libdir_paths(STANDARD_LIBRARY_PATH);
+#endif
+ }
+
+ int i = 0;
+ for (i = 0; (i < ld_library_dirlen) && (ld_library_dirs[i] != -1); i++) ;
+
+ if (*fdcount < i) {
+ *fdcount = i;
+ return (-1);
+ }
+
+ *fdcount = i;
+ memcpy(fds, ld_library_dirs, i * sizeof(int));
+ return 0;
+}
+
int
dlclose(void *handle)
{
More information about the p4-projects
mailing list