Search
lxdream.org :: lxdream/src/plugin.c :: diff
lxdream 0.9.1
released Jun 29
Download Now
filename src/plugin.c
changeset 1027:4e527bc96109
prev1024:c67f2d61ab97
next1041:5fcc39857c5c
author nkeynes
date Sat Jun 13 07:12:51 2009 +0000 (12 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 +0000
1.2 +++ b/src/plugin.c Sat Jun 13 07:12:51 2009 +0000
1.3 @@ -16,6 +16,7 @@
1.4 * GNU General Public License for more details.
1.5 */
1.6
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 #endif
1.14
1.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.18
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 binary
1.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 platform
1.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.57
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.75
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 +}
.