Changeset 5427:543c052527b2 in roaraudio for libroar/roardl.c


Ignore:
Timestamp:
03/20/12 03:40:15 (10 years ago)
Author:
phi
Branch:
default
Phase:
public
Message:

support usage of plugin path also outside plugin containers

File:
1 edited

Legend:

Unmodified
Added
Removed
  • libroar/roardl.c

    r5381 r5427  
    3636#include "libroar.h" 
    3737 
     38#ifdef ROAR_HAVE_H_DIRENT 
     39#include <dirent.h> 
     40#endif 
     41 
    3842#if defined(ROAR_HAVE_LIBDL) && !defined(RTLD_NEXT) 
    3943#define RTLD_NEXT ((void *) -1L) 
     
    191195#endif 
    192196 
     197#ifdef ROAR_HAVE_H_DIRENT 
     198// pvn = prefix, host vendor, host name 
     199static struct roar_dl_lhandle * _load_from_path_pvn(const char * name, 
     200                                                    int flags, int ra_init, 
     201                                                    struct roar_dl_librarypara * para, 
     202                                                    const char * prefix, 
     203                                                    const char * hostvendor, 
     204                                                    const char * hostname) { 
     205 struct roar_dl_lhandle * ret = NULL; 
     206 int i, j; 
     207 char path[1024]; 
     208 const char * path_format[] = {"%s/%s/%s", "%s/%s/universal", "%s/universal/universal"}; 
     209 DIR * dir; 
     210 struct dirent * dirent; 
     211 char file[1024]; 
     212 const char * file_format[] = {"%s/%s/%s", "%s/%s/%s" ROAR_SHARED_SUFFIX, "%s/%s/lib%s" ROAR_SHARED_SUFFIX}; 
     213//  cont->handle[idx] = roar_dl_open(name, ROAR_DL_FLAG_DEFAULTS, 1, para); 
     214//#vars: $PREFIX_PLUGINS, $hostvendor, $hostname, $name 
     215//#search order: $PREFIX_PLUGINS/{$hostvendor/{$hostname,universal},universal/universal}/*/{,lib}$name.so 
     216 
     217 for (i = 0; i < 3; i++) { 
     218  snprintf(path, sizeof(path), path_format[i], prefix, hostvendor, hostname); 
     219  dir = opendir(path); 
     220  if ( dir == NULL ) 
     221   continue; 
     222 
     223  while ((dirent = readdir(dir)) != NULL) { 
     224   if ( !strcmp(dirent->d_name, ".") || !strcmp(dirent->d_name, "..") ) 
     225    continue; 
     226 
     227   for (j = 0; j < 3; j++) { 
     228    snprintf(file, sizeof(file), file_format[j], path, dirent->d_name, name); 
     229    ret = roar_dl_open(file, flags, ra_init, para); 
     230    if ( ret != NULL ) { 
     231     closedir(dir); 
     232     return ret; 
     233    } 
     234   } 
     235  } 
     236 
     237  closedir(dir); 
     238 } 
     239 
     240 return NULL; 
     241} 
     242 
     243static struct roar_dl_lhandle * _load_from_path(const char * name, int flags, int ra_init, 
     244                                                struct roar_dl_librarypara * para) { 
     245 struct roar_dl_lhandle * ret = NULL; 
     246 char * host = NULL; 
     247 char * hostvendor_buffer = NULL; 
     248 char * hostvendor = NULL; 
     249 char * hostname = NULL; 
     250 char * c, * d; 
     251 
     252 if ( para != NULL && para->appname != NULL && para->appname[0] != 0 ) { 
     253  host = roar_mm_strdup(para->appname); 
     254 
     255  // if we are out of memory we will likely not pass the rest, so just return in error. 
     256  if ( host == NULL ) 
     257   return NULL; 
     258 
     259  hostname = host; 
     260  c = strstr(host, "<"); 
     261  if ( c != NULL ) { 
     262   while (c[-1] == ' ') c--; 
     263   *c = 0; 
     264   c++; 
     265   while (*c == ' ' || *c == '<') c++; 
     266   if ( *c ) { 
     267    d = strstr(c, ">"); 
     268    if ( d != NULL ) 
     269     *d = 0; 
     270 
     271    d = strstr(c, "/"); 
     272    if ( d != NULL ) { 
     273     *d = '-'; 
     274     hostvendor = c; 
     275    } else { 
     276     hostvendor_buffer = roar_mm_malloc(roar_mm_strlen(c) + 1 /* tailing \0 */ + 6 /* "unreg-" */); 
     277 
     278     // see above 
     279     if ( hostvendor_buffer == NULL ) { 
     280      roar_mm_free(host); 
     281      return NULL; 
     282     } 
     283 
     284     strcpy(hostvendor_buffer, "unreg-"); 
     285     strcat(hostvendor_buffer, c); 
     286     hostvendor = hostvendor_buffer; 
     287    } 
     288   } 
     289  } 
     290 } 
     291 
     292 if ( hostvendor == NULL ) 
     293  hostvendor = "universal"; 
     294 
     295 if ( hostname == NULL ) 
     296  hostname = "universal"; 
     297 
     298 ret = _load_from_path_pvn(name, flags, ra_init, para, ROAR_PREFIX_PLUGINS, hostvendor, hostname); 
     299 
     300 if ( host != NULL ) 
     301  roar_mm_free(host); 
     302 if ( hostvendor_buffer != NULL ) 
     303  roar_mm_free(hostvendor_buffer); 
     304 return ret; 
     305} 
     306#endif 
     307 
     308static struct roar_dl_lhandle * _roar_dl_open_pluginpath(const char * filename, int flags, 
     309                                      int ra_init, struct roar_dl_librarypara * para) { 
     310 flags |= ROAR_DL_FLAG_PLUGINPATH; 
     311 flags -= ROAR_DL_FLAG_PLUGINPATH; 
     312 
     313#ifdef ROAR_HAVE_H_DIRENT 
     314 return _load_from_path(filename, flags, ra_init, para); 
     315#else 
     316 // fall back to system open function. 
     317 return roar_dl_open(filename, flags, ra_init, para); 
     318#endif 
     319} 
     320 
    193321struct roar_dl_lhandle * roar_dl_open(const char * filename, int flags, 
    194322                                      int ra_init, struct roar_dl_librarypara * para) { 
     
    203331 int err; 
    204332 
    205  if ( flags == ROAR_DL_FLAG_DEFAULTS ) 
    206   flags = ROAR_DL_FLAG_NONE; 
     333 switch (flags) { 
     334  case ROAR_DL_FLAG_DEFAULTS: flags = ROAR_DL_FLAG_NONE;       break; 
     335  case ROAR_DL_FLAG_PLUGIN:   flags = ROAR_DL_FLAG_PLUGINPATH; break; 
     336 } 
     337 
     338 if ( flags & ROAR_DL_FLAG_PLUGINPATH ) 
     339  return _roar_dl_open_pluginpath(filename, flags, ra_init, para); 
    207340 
    208341#if defined(ROAR_HAVE_LIBDL) 
Note: See TracChangeset for help on using the changeset viewer.