make dlopen() use hints database, not just paths; from etheisen@TECLink.Net; netbsd...
authorderaadt <deraadt@openbsd.org>
Mon, 20 Nov 1995 07:19:40 +0000 (07:19 +0000)
committerderaadt <deraadt@openbsd.org>
Mon, 20 Nov 1995 07:19:40 +0000 (07:19 +0000)
gnu/usr.bin/ld/rtld/rtld.c
share/man/man3/dlfcn.3

index 72194af..33b5cd7 100644 (file)
@@ -1331,6 +1331,103 @@ static struct so_map dlmap = {
 };
 static int dlerrno;
 
+/*
+ * Populate sod struct for dlopen's call to map_obj
+ */
+void
+build_sod(name, sodp)
+       char            *name;
+       struct  sod     *sodp;
+{
+       unsigned int    number;
+       unsigned int    tuplet;
+       unsigned int    strange = 0;
+       int             major, minor;
+       char            *realname, *tok, *tok1;
+
+       /* default is an absolute or relative path */
+       sodp->sod_name = (long)strdup(name);    /* strtok is destructive */
+       sodp->sod_library = 0;
+       sodp->sod_major = sodp->sod_minor = 0;
+       /* asking for lookup? */
+       if (strncmp((char *)sodp->sod_name, "lib", 3) == NULL) {
+               /* skip over 'lib' */
+               tok = (char *)sodp->sod_name + 3;
+               /* dot guardian */
+               if((strchr(tok, '.') != NULL) && (*(tok+strlen(tok)-1)!='.')) {
+                       tok = strtok(tok, ".");
+                       /* default */
+                       major = minor = -1;
+                       /* removed 'lib' and extensions from name */
+                       realname = tok;
+                       /* loop through name - parse skipping name */
+                       for(tuplet=1;((tok=strtok(NULL,"."))!=NULL);tuplet++) {
+                               switch (tuplet) {
+                                       /* 'so' extension */
+                                       case 1:
+                                               if(strcmp(tok, "so") != NULL)
+                                                       strange = 1;
+                                               break;
+                                       /* major ver extension */
+                                       case 2:
+                                               for(tok1=tok;
+                                                   (*tok1 != '\0');
+                                                   tok1++) {
+                                                       if(isdigit(*tok1))
+                                                               number = 1;
+                                                       else {
+                                                               number = 0;
+                                                               break;
+                                                       }
+                                               }
+                                               if(number)
+                                                       major = atoi(tok);
+                                               else {
+                                                       major = 0;
+                                                       strange = 1;
+                                               }
+                                               break;
+                                       /* minor ver extension */
+                                       case 3:
+                                               for(tok1=tok;
+                                                   (*tok1 != '\0');
+                                                   tok1++) {
+                                                       if(isdigit(*tok1))
+                                                               number = 1;
+                                                       else {
+                                                               number = 0;
+                                                               break;
+                                                       }
+                                               }
+                                               if(number)
+                                                       minor = atoi(tok);
+                                               else {
+                                                       minor = 0;
+                                                       strange = 1;
+                                               }
+                                               break;
+                                       /* if we get here, it must be weird */
+                                       default:
+                                               strange = 1;
+                               } /* end switch */
+                       } /* end for */
+                       /* normal */
+                       if(!strange) {
+                               free((char *)sodp->sod_name);
+                               sodp->sod_name = (long)strdup(realname);
+                               sodp->sod_library = 1;
+                               sodp->sod_major = major;
+                               sodp->sod_minor = minor;
+                       }
+                       /* strange */
+                       else {
+                               free((char *)sodp->sod_name);
+                               sodp->sod_name = (long)strdup(name);
+                       }
+               } /* end if dots */
+       }  /* end if lookup */
+}
+
 static void *
 __dlopen(name, mode)
        char    *name;
@@ -1352,11 +1449,9 @@ __dlopen(name, mode)
                return NULL;
        }
 
-       sodp->sod_name = (long)strdup(name);
-       sodp->sod_library = 0;
-       sodp->sod_major = sodp->sod_minor = 0;
+       build_sod(name, sodp);
 
-       if ((smp = map_object(name, sodp, 0)) == NULL) {
+       if ((smp = map_object((char *)sodp->sod_name, sodp, 0)) == NULL) {
 #ifdef DEBUG
 xprintf("%s: %s\n", name, strerror(errno));
 #endif
index 3c36a96..39047b9 100644 (file)
@@ -41,7 +41,7 @@
 .Sh SYNOPSIS
 .Fd #include <dlfcn.h>
 .Ft "void *"
-.Fn dlopen "char *path" "int mode"
+.Fn dlopen "char *name" "int mode"
 .Ft "int"
 .Fn dlclose "void *handle"
 .Ft "void *"
@@ -57,10 +57,11 @@ They allow new shared objects to be loaded into the process' address space
 under program control.
 The
 .Fn dlopen
-function takes a pathname of a shared object as the first argument. The
-shared object is mapped into the address space, relocated and its external
-references are resolved in the same way as is done with the implicitly loaded
-shared libraries at program startup.
+function takes a filename of the forms 'libname.so', 'libname.so.xx.xx' where
+xx are the major and minor revisions, or 'pathname/filename' of a shared object
+as the first argument. The shared object is mapped into the address space,
+relocated and its external references are resolved in the same way as is done
+with the implicitly loaded shared libraries at program startup.
 The second argument has currently no effect, but should be set to
 .Dv DL_LAZY
 for future compatibility.