Skip to content

AFNI/NIfTI Server

Sections
Personal tools
You are here: Home » AFNI » Documentation

Doxygen Source Code Documentation


Main Page   Alphabetical List   Data Structures   File List   Data Fields   Globals   Search  

dlopen.c File Reference

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <limits.h>
#include "mach-o/dyld.h"
#include "dlfcn.h"

Go to the source code of this file.


Data Structures

struct  dlopen_handle

Defines

#define DEBUG_PRINT(format)   /**/
#define DEBUG_PRINT1(format, arg1)   /**/
#define DEBUG_PRINT2(format, arg1, arg2)   /**/
#define DEBUG_PRINT3(format, arg1, arg2, arg3)   /**/

Functions

enum DYLD_BOOL NSMakePrivateModulePublic (NSModule module)
int _dl_search_paths (const char *filename, char *pathbuf, struct stat *stat_buf)
void * dlopen (const char *path, int mode)
void * dlsym (void *handle, const char *symbol)
const char * dlerror (void)
int dlclose (void *handle)

Variables

dlopen_handledlopen_handles = NULL
const struct dlopen_handle main_program_handle = {NULL}
char * dlerror_pointer = NULL

Define Documentation

#define DEBUG_PRINT format       /**/
 

Definition at line 51 of file dlopen.c.

Referenced by dlclose().

#define DEBUG_PRINT1 format,
arg1       /**/
 

Definition at line 52 of file dlopen.c.

Referenced by dlclose(), dlopen(), and dlsym().

#define DEBUG_PRINT2 format,
arg1,
arg2       /**/
 

Definition at line 53 of file dlopen.c.

Referenced by dlopen(), and dlsym().

#define DEBUG_PRINT3 format,
arg1,
arg2,
arg3       /**/
 

Definition at line 54 of file dlopen.c.


Function Documentation

int _dl_search_paths const char *    filename,
char *    pathbuf,
struct stat *    stat_buf
[static]
 

Definition at line 107 of file dlopen.c.

References getenv(), p, and q.

Referenced by dlopen().

00111 {
00112     const char *pathspec;
00113     const char *element;
00114     const char *p;
00115     char *q;
00116     char *pathbuf_end;
00117     const char *envvars[] = {
00118         "$DYLD_LIBRARY_PATH",
00119         "$LD_LIBRARY_PATH",
00120         "/usr/lib:/lib",
00121         NULL };
00122     int envvar_index;
00123 
00124         pathbuf_end = pathbuf + PATH_MAX - 8;
00125 
00126         for(envvar_index = 0; envvars[envvar_index]; envvar_index++){
00127             if(envvars[envvar_index][0] == '$'){
00128                 pathspec = getenv(envvars[envvar_index]+1);
00129             }
00130             else {
00131                 pathspec = envvars[envvar_index];
00132             }
00133 
00134             if(pathspec != NULL){
00135                 element = pathspec;
00136                 while(*element){
00137                     /* extract path list element */
00138                     p = element;
00139                     q = pathbuf;
00140                     while(*p && *p != ':' && q < pathbuf_end) *q++ = *p++;
00141                     if(q == pathbuf){  /* empty element */
00142                         if(*p){
00143                             element = p+1;
00144                             continue;
00145                         }
00146                         break;
00147                     }
00148                     if (*p){
00149                         element = p+1;
00150                     }
00151                     else{
00152                         element = p;  /* this terminates the loop */
00153                     }
00154 
00155                     /* add slash if neccessary */
00156                     if(*(q-1) != '/' && q < pathbuf_end){
00157                         *q++ = '/';
00158                     }
00159 
00160                     /* append module name */
00161                     p = filename;
00162                     while(*p && q < pathbuf_end) *q++ = *p++;
00163                     *q++ = 0;
00164 
00165                     if(q >= pathbuf_end){
00166                         /* maybe add an error message here */
00167                         break;
00168                     }
00169 
00170                     if(stat(pathbuf, stat_buf) == 0){
00171                         return 0;
00172                     }
00173                 }
00174             }
00175         }
00176 
00177         /* we have searched everywhere, now we give up */
00178         return -1;
00179 }

int dlclose void *    handle
 

Definition at line 462 of file dlopen.c.

References DEBUG_PRINT, DEBUG_PRINT1, dlerror_pointer, dlopen_handle::dlopen_count, dlopen_handle::dlopen_mode, free, dlopen_handle::module, dlopen_handle::next, dlopen_handle::prev, RTLD_LAZY_UNDEF, and RTLD_NODELETE.

00464 {
00465     struct dlopen_handle *p, *q;
00466     unsigned long options;
00467     NSSymbol NSSymbol;
00468     void (*fini)(void);
00469 
00470         DEBUG_PRINT1("libdl: dlclose(%p) -> ", handle);
00471 
00472         dlerror_pointer = NULL;
00473         q = (struct dlopen_handle *)handle;
00474         p = dlopen_handles;
00475         while(p != NULL){
00476             if(p == q){
00477                 /* if the dlopen() count is not zero we are done */
00478                 p->dlopen_count--;
00479                 if(p->dlopen_count != 0){
00480                     DEBUG_PRINT("OK");
00481                     return(0);
00482                 }
00483 
00484                 /* call the fini function if one exists */
00485                 NSSymbol = NSLookupSymbolInModule(p->module, "__fini");
00486                 if(NSSymbol != NULL){
00487                     fini = NSAddressOfSymbol(NSSymbol);
00488                     fini();
00489                 }
00490 
00491                 /* unlink the module for this handle */
00492                 options = 0;
00493                 if(p->dlopen_mode & RTLD_NODELETE)
00494                     options |= NSUNLINKMODULE_OPTION_KEEP_MEMORY_MAPPED;
00495                 if(p->dlopen_mode & RTLD_LAZY_UNDEF)
00496                     options |= NSUNLINKMODULE_OPTION_RESET_LAZY_REFERENCES;
00497                 if(NSUnLinkModule(p->module, options) == FALSE){
00498                     dlerror_pointer = "NSUnLinkModule() failed for dlclose()";
00499                     DEBUG_PRINT1("ERROR: %s\n", dlerror_pointer);
00500                     return(-1);
00501                 }
00502                 if(p->prev != NULL)
00503                     p->prev->next = p->next;
00504                 if(p->next != NULL)
00505                     p->next->prev = p->prev;
00506                 if(dlopen_handles == p)
00507                     dlopen_handles = p->next;
00508                 free(p);
00509                 DEBUG_PRINT("OK");
00510                 return(0);
00511             }
00512             p = p->next;
00513         }
00514         dlerror_pointer = "invalid handle passed to dlclose()";
00515         DEBUG_PRINT1("ERROR: %s\n", dlerror_pointer);
00516         return(-1);
00517 }

const char* dlerror void   
 

Definition at line 448 of file dlopen.c.

References dlerror_pointer, and p.

00450 {
00451     const char *p;
00452 
00453         p = (const char *)dlerror_pointer;
00454         dlerror_pointer = NULL;
00455         return(p);
00456 }

void* dlopen const char *    path,
int    mode
 

Definition at line 185 of file dlopen.c.

References _dl_search_paths(), DEBUG_PRINT1, DEBUG_PRINT2, dlopen_handle::dev, dlerror_pointer, dlopen_handle::dlopen_count, dlopen_handle::dlopen_mode, dlopen_handle::ino, malloc, dlopen_handle::module, dlopen_handle::next, NSMakePrivateModulePublic(), dlopen_handle::prev, retval(), RTLD_GLOBAL, RTLD_LAZY_UNDEF, RTLD_LOCAL, RTLD_NODELETE, RTLD_NOLOAD, RTLD_NOW, RTLD_UNSHARED, and strerror().

00188 {
00189     const char *module_path;
00190     void *retval;
00191     struct stat stat_buf;
00192     NSObjectFileImage objectFileImage;
00193     NSObjectFileImageReturnCode ofile_result_code;
00194     NSModule module;
00195     struct dlopen_handle *p;
00196     unsigned long options;
00197     NSSymbol NSSymbol;
00198     void (*init)(void);
00199     char pathbuf[PATH_MAX];
00200 
00201         DEBUG_PRINT2("libdl: dlopen(%s,0x%x) -> ", path, (unsigned int)mode);
00202 
00203         dlerror_pointer = NULL;
00204         /*
00205          * A NULL path is to indicate the caller wants a handle for the
00206          * main program.
00207          */
00208         if(path == NULL){
00209             retval = (void *)&main_program_handle;
00210             DEBUG_PRINT1("main / %p\n", retval);
00211             return(retval);
00212         }
00213 
00214         /* see if the path exists and if so get the device and inode number */
00215         if(stat(path, &stat_buf) == -1){
00216             dlerror_pointer = strerror(errno);
00217 
00218             if(path[0] == '/'){
00219                 DEBUG_PRINT1("ERROR (stat): %s\n", dlerror_pointer);
00220                 return(NULL);
00221             }
00222 
00223             /* search for the module in various places */
00224             if(_dl_search_paths(path, pathbuf, &stat_buf)){
00225                 /* dlerror_pointer is unmodified */
00226                 DEBUG_PRINT1("ERROR (stat): %s\n", dlerror_pointer);
00227                 return(NULL);
00228             }
00229             DEBUG_PRINT1("found %s -> ", pathbuf);
00230             module_path = pathbuf;
00231             dlerror_pointer = NULL;
00232         }
00233         else{
00234             module_path = path;
00235         }
00236 
00237         /*
00238          * If we don't want an unshared handle see if we already have a handle
00239          * for this path.
00240          */
00241         if((mode & RTLD_UNSHARED) != RTLD_UNSHARED){
00242             p = dlopen_handles;
00243             while(p != NULL){
00244                 if(p->dev == stat_buf.st_dev && p->ino == stat_buf.st_ino){
00245                     /* skip unshared handles */
00246                     if((p->dlopen_mode & RTLD_UNSHARED) == RTLD_UNSHARED)
00247                         continue;
00248                     /*
00249                      * We have already created a handle for this path.  The
00250                      * caller might be trying to promote an RTLD_LOCAL handle
00251                      * to a RTLD_GLOBAL.  Or just looking it up with
00252                      * RTLD_NOLOAD.
00253                      */
00254                     if((p->dlopen_mode & RTLD_LOCAL) == RTLD_LOCAL &&
00255                        (mode & RTLD_GLOBAL) == RTLD_GLOBAL){
00256                         /* promote the handle */
00257                         if(NSMakePrivateModulePublic(p->module) == TRUE){
00258                             p->dlopen_mode &= ~RTLD_LOCAL;
00259                             p->dlopen_mode |= RTLD_GLOBAL;
00260                             p->dlopen_count++;
00261                             DEBUG_PRINT1("%p\n", p);
00262                             return(p);
00263                         }
00264                         else{
00265                             dlerror_pointer = "can't promote handle from "
00266                                               "RTLD_LOCAL to RTLD_GLOBAL";
00267                             DEBUG_PRINT1("ERROR: %s\n", dlerror_pointer);
00268                             return(NULL);
00269                         }
00270                     }
00271                     p->dlopen_count++;
00272                     DEBUG_PRINT1("%p\n", p);
00273                     return(p);
00274                 }
00275                 p = p->next;
00276             }
00277         }
00278         
00279         /*
00280          * We do not have a handle for this path if we were just trying to
00281          * look it up return NULL to indicate we don't have it.
00282          */
00283         if((mode & RTLD_NOLOAD) == RTLD_NOLOAD){
00284             dlerror_pointer = "no existing handle for path RTLD_NOLOAD test";
00285             DEBUG_PRINT1("ERROR: %s\n", dlerror_pointer);
00286             return(NULL);
00287         }
00288 
00289         /* try to create an object file image from this path */
00290         ofile_result_code = NSCreateObjectFileImageFromFile(module_path,
00291                                                             &objectFileImage);
00292         if(ofile_result_code != NSObjectFileImageSuccess){
00293             switch(ofile_result_code){
00294             case NSObjectFileImageFailure:
00295                 dlerror_pointer = "object file setup failure";
00296                 DEBUG_PRINT1("ERROR: %s\n", dlerror_pointer);
00297                 return(NULL);
00298             case NSObjectFileImageInappropriateFile:
00299                 dlerror_pointer = "not a Mach-O MH_BUNDLE file type";
00300                 DEBUG_PRINT1("ERROR: %s\n", dlerror_pointer);
00301                 return(NULL);
00302             case NSObjectFileImageArch:
00303                 dlerror_pointer = "no object for this architecture";
00304                 DEBUG_PRINT1("ERROR: %s\n", dlerror_pointer);
00305                 return(NULL);
00306             case NSObjectFileImageFormat:
00307                 dlerror_pointer = "bad object file format";
00308                 DEBUG_PRINT1("ERROR: %s\n", dlerror_pointer);
00309                 return(NULL);
00310             case NSObjectFileImageAccess:
00311                 dlerror_pointer = "can't read object file";
00312                 DEBUG_PRINT1("ERROR: %s\n", dlerror_pointer);
00313                 return(NULL);
00314             default:
00315                 dlerror_pointer = "unknown error from "
00316                                   "NSCreateObjectFileImageFromFile()";
00317                 DEBUG_PRINT1("ERROR: %s\n", dlerror_pointer);
00318                 return(NULL);
00319             }
00320         }
00321 
00322         /* try to link in this object file image */
00323         options = NSLINKMODULE_OPTION_PRIVATE;
00324         if((mode & RTLD_NOW) == RTLD_NOW)
00325             options |= NSLINKMODULE_OPTION_BINDNOW;
00326         module = NSLinkModule(objectFileImage, module_path, options);
00327         NSDestroyObjectFileImage(objectFileImage) ;
00328         if(module == NULL){
00329             dlerror_pointer = "NSLinkModule() failed for dlopen()";
00330             DEBUG_PRINT1("ERROR: %s\n", dlerror_pointer);
00331             return(NULL);
00332         }
00333 
00334         /*
00335          * If the handle is to be global promote the handle.  It is done this
00336          * way to avoid multiply defined symbols.
00337          */
00338         if((mode & RTLD_GLOBAL) == RTLD_GLOBAL){
00339             if(NSMakePrivateModulePublic(module) == FALSE){
00340                 dlerror_pointer = "can't promote handle from RTLD_LOCAL to "
00341                                   "RTLD_GLOBAL";
00342                 DEBUG_PRINT1("ERROR: %s\n", dlerror_pointer);
00343                 return(NULL);
00344             }
00345         }
00346 
00347         p = malloc(sizeof(struct dlopen_handle));
00348         if(p == NULL){
00349             dlerror_pointer = "can't allocate memory for the dlopen handle";
00350             DEBUG_PRINT1("ERROR: %s\n", dlerror_pointer);
00351             return(NULL);
00352         }
00353 
00354         /* fill in the handle */
00355         p->dev = stat_buf.st_dev;
00356         p->ino = stat_buf.st_ino;
00357         if(mode & RTLD_GLOBAL)
00358             p->dlopen_mode = RTLD_GLOBAL;
00359         else
00360             p->dlopen_mode = RTLD_LOCAL;
00361         p->dlopen_mode |= (mode & RTLD_UNSHARED) |
00362                           (mode & RTLD_NODELETE) |
00363                           (mode & RTLD_LAZY_UNDEF);
00364         p->dlopen_count = 1;
00365         p->module = module;
00366         p->prev = NULL;
00367         p->next = dlopen_handles;
00368         if(dlopen_handles != NULL)
00369             dlopen_handles->prev = p;
00370         dlopen_handles = p;
00371 
00372         /* call the init function if one exists */
00373         NSSymbol = NSLookupSymbolInModule(p->module, "__init");
00374         if(NSSymbol != NULL){
00375             init = NSAddressOfSymbol(NSSymbol);
00376             init();
00377         }
00378         
00379         DEBUG_PRINT1("%p\n", p);
00380         return(p);
00381 }

void* dlsym void *    handle,
const char *    symbol
 

Definition at line 387 of file dlopen.c.

References DEBUG_PRINT1, DEBUG_PRINT2, dlerror_pointer, dlopen_handle::module, and dlopen_handle::next.

00390 {
00391     struct dlopen_handle *dlopen_handle, *p;
00392     NSSymbol NSSymbol;
00393     void *address;
00394 
00395         DEBUG_PRINT2("libdl: dlsym(%p,%s) -> ", handle, symbol);
00396 
00397         dlopen_handle = (struct dlopen_handle *)handle;
00398 
00399         /*
00400          * If this is the handle for the main program do a global lookup.
00401          */
00402         if(dlopen_handle == (struct dlopen_handle *)&main_program_handle){
00403             if(NSIsSymbolNameDefined(symbol) == TRUE){
00404                 NSSymbol = NSLookupAndBindSymbol(symbol);
00405                 address = NSAddressOfSymbol(NSSymbol);
00406                 dlerror_pointer = NULL;
00407                 DEBUG_PRINT1("%p\n", address);
00408                 return(address);
00409             }
00410             else{
00411                 dlerror_pointer = "symbol not found";
00412                 DEBUG_PRINT1("ERROR: %s\n", dlerror_pointer);
00413                 return(NULL);
00414             }
00415         }
00416 
00417         /*
00418          * Find this handle and do a lookup in just this module.
00419          */
00420         p = dlopen_handles;
00421         while(p != NULL){
00422             if(dlopen_handle == p){
00423                 NSSymbol = NSLookupSymbolInModule(p->module, symbol);
00424                 if(NSSymbol != NULL){
00425                     address = NSAddressOfSymbol(NSSymbol);
00426                     dlerror_pointer = NULL;
00427                     DEBUG_PRINT1("%p\n", address);
00428                     return(address);
00429                 }
00430                 else{
00431                     dlerror_pointer = "symbol not found";
00432                     DEBUG_PRINT1("ERROR: %s\n", dlerror_pointer);
00433                     return(NULL);
00434                 }
00435             }
00436             p = p->next;
00437         }
00438 
00439         dlerror_pointer = "bad handle passed to dlsym()";
00440         DEBUG_PRINT1("ERROR: %s\n", dlerror_pointer);
00441         return(NULL);
00442 }

enum DYLD_BOOL NSMakePrivateModulePublic NSModule    module [static]
 

typedef enum { FALSE = 0, TRUE = 1 } bool; *

Definition at line 84 of file dlopen.c.

References p.

Referenced by dlopen().

00086 {
00087     static enum DYLD_BOOL (*p)(NSModule module) = NULL;
00088 
00089         if(p == NULL)
00090             _dyld_func_lookup("__dyld_NSMakePrivateModulePublic",
00091                               (unsigned long *)&p);
00092         if(p == NULL){
00093 #ifdef DEBUG
00094             printf("_dyld_func_lookup of __dyld_NSMakePrivateModulePublic "
00095                    "failed\n");
00096 #endif
00097             return(FALSE);
00098         }
00099         return(p(module));
00100 }

Variable Documentation

char* dlerror_pointer = NULL [static]
 

Definition at line 72 of file dlopen.c.

Referenced by dlclose(), dlerror(), dlopen(), and dlsym().

struct dlopen_handle* dlopen_handles = NULL [static]
 

Definition at line 70 of file dlopen.c.

const struct dlopen_handle main_program_handle = {NULL} [static]
 

Definition at line 71 of file dlopen.c.

 

Powered by Plone

This site conforms to the following standards: