Changeset 5423:ecb64035ba72 in roaraudio for libroar


Ignore:
Timestamp:
03/20/12 02:43:23 (12 years ago)
Author:
phi
Branch:
default
Phase:
public
Message:

added support to load plugins from search path

File:
1 edited

Legend:

Unmodified
Added
Removed
  • libroar/plugincontainer.c

    r5389 r5423  
    3535 
    3636#include "libroar.h" 
     37 
     38#ifdef ROAR_HAVE_H_DIRENT 
     39#include <dirent.h> 
     40#endif 
    3741 
    3842#define MAX_PLUGINS 64 
     
    140144 
    141145// plugin loading and unloading: 
     146#ifdef ROAR_HAVE_H_DIRENT 
     147// pvn = prefix, host vendor, host name 
     148static struct roar_dl_lhandle * _load_from_path_pvn(const char * name, 
     149                                                       struct roar_dl_librarypara * para, 
     150                                                       const char * prefix, 
     151                                                       const char * hostvendor, 
     152                                                       const char * hostname) { 
     153 struct roar_dl_lhandle * ret = NULL; 
     154 int i, j; 
     155 char path[1024]; 
     156 const char * path_format[] = {"%s/%s/%s", "%s/%s/universal", "%s/universal/universal"}; 
     157 DIR * dir; 
     158 struct dirent * dirent; 
     159 char file[1024]; 
     160 const char * file_format[] = {"%s/%s/%s", "%s/%s/%s.so", "%s/%s/lib%s.so"}; 
     161//  cont->handle[idx] = roar_dl_open(name, ROAR_DL_FLAG_DEFAULTS, 1, para); 
     162//#vars: $PREFIX_PLUGINS, $hostvendor, $hostname, $name 
     163//#search order: $PREFIX_PLUGINS/{$hostvendor/{$hostname,universal},universal/universal}/*/{,lib}$name.so 
     164 
     165 for (i = 0; i < 3; i++) { 
     166  snprintf(path, sizeof(path), path_format[i], prefix, hostvendor, hostname); 
     167  dir = opendir(path); 
     168  if ( dir == NULL ) 
     169   continue; 
     170 
     171  while ((dirent = readdir(dir)) != NULL) { 
     172   if ( !strcmp(dirent->d_name, ".") || !strcmp(dirent->d_name, "..") ) 
     173    continue; 
     174 
     175   for (j = 0; j < 3; j++) { 
     176    snprintf(file, sizeof(file), file_format[j], path, dirent->d_name, name); 
     177    ret = roar_dl_open(file, ROAR_DL_FLAG_DEFAULTS, 1, para); 
     178    if ( ret != NULL ) { 
     179     closedir(dir); 
     180     return ret; 
     181    } 
     182   } 
     183  } 
     184 
     185  closedir(dir); 
     186 } 
     187 
     188 return NULL; 
     189} 
     190 
     191static struct roar_dl_lhandle * _load_from_path(const char * name, struct roar_dl_librarypara * para) { 
     192 struct roar_dl_lhandle * ret = NULL; 
     193 char * host = NULL; 
     194 char * hostvendor_buffer = NULL; 
     195 char * hostvendor = NULL; 
     196 char * hostname = NULL; 
     197 char * c, * d; 
     198 
     199 if ( para->appname != NULL && para->appname[0] != 0 ) { 
     200  host = roar_mm_strdup(para->appname); 
     201 
     202  // if we are out of memory we will likely not pass the rest, so just return in error. 
     203  if ( host == NULL ) 
     204   return NULL; 
     205 
     206  hostname = host; 
     207  c = strstr(host, "<"); 
     208  if ( c != NULL ) { 
     209   while (c[-1] == ' ') c--; 
     210   *c = 0; 
     211   c++; 
     212   while (*c == ' ' || *c == '<') c++; 
     213   if ( *c ) { 
     214    d = strstr(c, ">"); 
     215    if ( d != NULL ) 
     216     *d = 0; 
     217 
     218    d = strstr(c, "/"); 
     219    if ( d != NULL ) { 
     220     *d = '-'; 
     221     hostvendor = c; 
     222    } else { 
     223     hostvendor_buffer = roar_mm_malloc(roar_mm_strlen(c) + 1 /* tailing \0 */ + 6 /* "unreg-" */); 
     224 
     225     // see above 
     226     if ( hostvendor_buffer == NULL ) { 
     227      roar_mm_free(host); 
     228      return NULL; 
     229     } 
     230 
     231     strcpy(hostvendor_buffer, "unreg-"); 
     232     strcat(hostvendor_buffer, c); 
     233     hostvendor = hostvendor_buffer; 
     234    } 
     235   } 
     236  } 
     237 } 
     238 
     239 if ( hostvendor == NULL ) 
     240  hostvendor = "universal"; 
     241 
     242 if ( hostname == NULL ) 
     243  hostname = "universal"; 
     244 
     245 ret = _load_from_path_pvn(name, para, ROAR_PREFIX_PLUGINS, hostvendor, hostname); 
     246 
     247 if ( host != NULL ) 
     248  roar_mm_free(host); 
     249 if ( hostvendor_buffer != NULL ) 
     250  roar_mm_free(hostvendor_buffer); 
     251 return ret; 
     252} 
     253#endif 
     254 
    142255int roar_plugincontainer_load(struct roar_plugincontainer * cont, const char * name, struct roar_dl_librarypara * para) { 
    143256 ssize_t idx = -1; 
     
    174287 if ( strstr(name, "/") != NULL ) { 
    175288  cont->handle[idx] = roar_dl_open(name, ROAR_DL_FLAG_DEFAULTS, 1, para); 
    176   if ( cont->handle[idx] == NULL ) 
    177    return -1; 
    178  
    179   cont->deprefc[idx] = 0; 
    180   cont->numhandles++; 
    181  
    182   return 0; 
    183289 } else { 
     290#ifdef ROAR_HAVE_H_DIRENT 
     291  cont->handle[idx] = _load_from_path(name, para); 
     292#else 
    184293  roar_err_set(ROAR_ERROR_NOSYS); 
    185294  return -1; 
    186  } 
    187  
    188  roar_err_set(ROAR_ERROR_NOSYS); 
    189  return -1; 
     295#endif 
     296 } 
     297 
     298 if ( cont->handle[idx] == NULL ) 
     299  return -1; 
     300 
     301 cont->deprefc[idx] = 0; 
     302 cont->numhandles++; 
     303 
     304 return 0; 
    190305} 
    191306 
Note: See TracChangeset for help on using the changeset viewer.