Search
lxdream.org :: lxdream/src/plugin.c :: diff
lxdream 0.9.1
released Jun 29
Download Now
filename src/plugin.c
changeset 1024:c67f2d61ab97
next1027:4e527bc96109
author nkeynes
date Sat Jun 13 00:50:48 2009 +0000 (12 years ago)
permissions -rw-r--r--
last change Build drivers with library dependencies as shared objects (ie plugins)
file annotate diff log raw
1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/src/plugin.c Sat Jun 13 00:50:48 2009 +0000
1.3 @@ -0,0 +1,95 @@
1.4 +/**
1.5 + * $Id$
1.6 + *
1.7 + * Plugin loader code
1.8 + *
1.9 + * Copyright (c) 2009 Nathan Keynes.
1.10 + *
1.11 + * This program is free software; you can redistribute it and/or modify
1.12 + * it under the terms of the GNU General Public License as published by
1.13 + * the Free Software Foundation; either version 2 of the License, or
1.14 + * (at your option) any later version.
1.15 + *
1.16 + * This program is distributed in the hope that it will be useful,
1.17 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
1.18 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1.19 + * GNU General Public License for more details.
1.20 + */
1.21 +
1.22 +#include <dirent.h>
1.23 +#include <dlfcn.h>
1.24 +#include <string.h>
1.25 +#include <glib/gmem.h>
1.26 +#include <glib/gstrfuncs.h>
1.27 +#include "plugin.h"
1.28 +
1.29 +
1.30 +#ifdef APPLE_BUILD
1.31 +#define SOEXT ".dylib"
1.32 +#else
1.33 +#define SOEXT ".so"
1.34 +#endif
1.35 +
1.36 +const char *plugin_type_string[] = { "Undefined", "Audio driver", "Input driver" };
1.37 +
1.38 +gboolean plugin_load( const gchar *plugin_path )
1.39 +{
1.40 + void *so = dlopen(plugin_path, RTLD_NOW|RTLD_LOCAL);
1.41 + if( so == NULL ) {
1.42 + WARN("Failed to load plugin '%s': %s", plugin_path, dlerror());
1.43 + return FALSE;
1.44 + }
1.45 +
1.46 + struct plugin_struct *plugin = (struct plugin_struct *)dlsym(so,"lxdream_plugin_entry");
1.47 + if( plugin == NULL ) {
1.48 + WARN("Failed to load plugin: '%s': Not an lxdream plugin", plugin_path);
1.49 + dlclose(so);
1.50 + return FALSE;
1.51 + }
1.52 +
1.53 + if( strcmp(lxdream_short_version, plugin->version) != 0 ) {
1.54 + WARN("Failed to load plugin: '%s': Incompatible version (%s)", plugin_path, plugin->version);
1.55 + dlclose(so);
1.56 + return FALSE;
1.57 + }
1.58 +
1.59 + if( plugin->type < PLUGIN_MIN_TYPE || plugin->type > PLUGIN_MAX_TYPE ) {
1.60 + WARN("Failed to load plugin: '%s': Unrecognized plugin type (%d)", plugin_path, plugin->type );
1.61 + dlclose(so);
1.62 + return FALSE;
1.63 + }
1.64 +
1.65 + if( plugin->register_plugin() == FALSE ) {
1.66 + WARN("Failed to load plugin: '%s': Initialization failed", plugin_path);
1.67 + dlclose(so);
1.68 + return FALSE;
1.69 + }
1.70 + INFO("Loaded %s plugin '%s'", plugin_type_string[plugin->type], plugin->name);
1.71 + return TRUE;
1.72 +}
1.73 +
1.74 +/**
1.75 + * Scan the plugin dir and load all valid plugins.
1.76 + */
1.77 +int plugin_init( const gchar *plugin_dir )
1.78 +{
1.79 + int plugin_count;
1.80 + struct dirent *ent;
1.81 + DIR *dir = opendir(plugin_dir);
1.82 + if( dir == NULL ) {
1.83 + WARN( "Unable to open plugin directory '%s'", plugin_dir );
1.84 + return 0;
1.85 + }
1.86 +
1.87 + while( (ent = readdir(dir)) != NULL ) {
1.88 + const char *ext = strrchr(ent->d_name, '.');
1.89 + if( ext != NULL && strcasecmp(SOEXT,ext) == 0 ) {
1.90 + char *libname = g_strdup_printf( "%s/%s", plugin_dir,ent->d_name );
1.91 + if( plugin_load( libname ) ) {
1.92 + plugin_count++;
1.93 + }
1.94 + g_free(libname);
1.95 + }
1.96 + }
1.97 + return plugin_count;
1.98 +}
.