filename | src/plugin.c |
changeset | 1027:4e527bc96109 |
prev | 1024:c67f2d61ab97 |
next | 1041:5fcc39857c5c |
author | nkeynes |
date | Sat Jun 13 07:12:51 2009 +0000 (13 years ago) |
permissions | -rw-r--r-- |
last change | Load plugins from the directory containing the executable first if they're there - simplifies development testing. Add dummy plugin for easy identification of the plugin directory |
file | annotate | diff | log | raw |
1.1 --- a/src/plugin.c Sat Jun 13 00:50:48 2009 +00001.2 +++ b/src/plugin.c Sat Jun 13 07:12:51 2009 +00001.3 @@ -16,6 +16,7 @@1.4 * GNU General Public License for more details.1.5 */1.7 +#include <sys/stat.h>1.8 #include <dirent.h>1.9 #include <dlfcn.h>1.10 #include <string.h>1.11 @@ -30,9 +31,40 @@1.12 #define SOEXT ".so"1.13 #endif1.15 -const char *plugin_type_string[] = { "Undefined", "Audio driver", "Input driver" };1.16 +/** Dummy plugin used as a plugin directory marker */1.17 +#define DUMMY_PLUGIN ("lxdream_dummy" SOEXT)1.19 -gboolean plugin_load( const gchar *plugin_path )1.20 +const char *plugin_type_string[] = { "undefined", "audio driver", "input driver" };1.21 +1.22 +int main(int argc, char *argv[]);1.23 +static const char *exec_path = NULL;1.24 +1.25 +/**1.26 + * Return the full path to the main binary1.27 + */1.28 +static const char *get_exec_path()1.29 +{1.30 + if( exec_path == NULL ) {1.31 + Dl_info dli;1.32 +1.33 + /* Use dladdr for this, since it should be available for any platform1.34 + * that we can support plugins on at all.1.35 + */1.36 + if( dladdr( main, &dli) ) {1.37 + gchar *path = g_strdup( dli.dli_fname );1.38 + char *i = strrchr( path, '/' );1.39 + if( i > path ) {1.40 + *i = '\0';1.41 + exec_path = path;1.42 + } else {1.43 + g_free(path);1.44 + }1.45 + }1.46 + }1.47 + return exec_path;1.48 +}1.49 +1.50 +static gboolean plugin_load( const gchar *plugin_path )1.51 {1.52 void *so = dlopen(plugin_path, RTLD_NOW|RTLD_LOCAL);1.53 if( so == NULL ) {1.54 @@ -53,6 +85,12 @@1.55 return FALSE;1.56 }1.58 + if( plugin->type == PLUGIN_NONE ) {1.59 + /* 'dummy' plugin - we don't actually want to load it */1.60 + dlclose(so);1.61 + return FALSE;1.62 + }1.63 +1.64 if( plugin->type < PLUGIN_MIN_TYPE || plugin->type > PLUGIN_MAX_TYPE ) {1.65 WARN("Failed to load plugin: '%s': Unrecognized plugin type (%d)", plugin_path, plugin->type );1.66 dlclose(so);1.67 @@ -64,17 +102,30 @@1.68 dlclose(so);1.69 return FALSE;1.70 }1.71 - INFO("Loaded %s plugin '%s'", plugin_type_string[plugin->type], plugin->name);1.72 + INFO("Loaded %s '%s'", plugin_type_string[plugin->type], plugin->name);1.73 return TRUE;1.74 }1.76 +static gboolean has_plugins( const gchar *path )1.77 +{1.78 + struct stat st;1.79 +1.80 + gchar *dummy_name = g_strdup_printf( "%s/%s", path, DUMMY_PLUGIN );1.81 + if( stat( dummy_name, &st ) == 0 ) {1.82 + return TRUE;1.83 + } else {1.84 + return FALSE;1.85 + }1.86 +}1.87 +1.88 /**1.89 * Scan the plugin dir and load all valid plugins.1.90 */1.91 -int plugin_init( const gchar *plugin_dir )1.92 +static int plugin_load_all( const gchar *plugin_dir )1.93 {1.94 int plugin_count;1.95 struct dirent *ent;1.96 +1.97 DIR *dir = opendir(plugin_dir);1.98 if( dir == NULL ) {1.99 WARN( "Unable to open plugin directory '%s'", plugin_dir );1.100 @@ -93,3 +144,14 @@1.101 }1.102 return plugin_count;1.103 }1.104 +1.105 +int plugin_init()1.106 +{1.107 + const char *path = get_exec_path();1.108 + if( path == NULL || !has_plugins(path) ) {1.109 + path = get_plugin_path();1.110 + }1.111 +1.112 + INFO( "Plugin directory: %s", path );1.113 + return plugin_load_all( path );1.114 +}
.