Search
lxdream.org :: lxdream/src/plugin.c
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)
view annotate diff log raw
     1 /**
     2  * $Id$
     3  *
     4  * Plugin loader code
     5  *
     6  * Copyright (c) 2009 Nathan Keynes.
     7  *
     8  * This program is free software; you can redistribute it and/or modify
     9  * it under the terms of the GNU General Public License as published by
    10  * the Free Software Foundation; either version 2 of the License, or
    11  * (at your option) any later version.
    12  *
    13  * This program is distributed in the hope that it will be useful,
    14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
    15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    16  * GNU General Public License for more details.
    17  */
    19 #include <dirent.h>
    20 #include <dlfcn.h>
    21 #include <string.h>
    22 #include <glib/gmem.h>
    23 #include <glib/gstrfuncs.h>
    24 #include "plugin.h"
    27 #ifdef APPLE_BUILD
    28 #define SOEXT ".dylib"
    29 #else
    30 #define SOEXT ".so"
    31 #endif
    33 const char *plugin_type_string[] = { "Undefined", "Audio driver", "Input driver" };
    35 gboolean plugin_load( const gchar *plugin_path )
    36 {
    37     void *so = dlopen(plugin_path, RTLD_NOW|RTLD_LOCAL);
    38     if( so == NULL ) {
    39         WARN("Failed to load plugin '%s': %s", plugin_path, dlerror());
    40         return FALSE;
    41     }
    43     struct plugin_struct *plugin = (struct plugin_struct *)dlsym(so,"lxdream_plugin_entry");
    44     if( plugin == NULL ) {
    45         WARN("Failed to load plugin: '%s': Not an lxdream plugin", plugin_path);
    46         dlclose(so);
    47         return FALSE;
    48     }
    50     if( strcmp(lxdream_short_version, plugin->version) != 0 ) {
    51         WARN("Failed to load plugin: '%s': Incompatible version (%s)", plugin_path, plugin->version);
    52         dlclose(so);
    53         return FALSE;
    54     }
    56     if( plugin->type < PLUGIN_MIN_TYPE || plugin->type > PLUGIN_MAX_TYPE ) {
    57         WARN("Failed to load plugin: '%s': Unrecognized plugin type (%d)", plugin_path, plugin->type );
    58         dlclose(so);
    59         return FALSE;
    60     }
    62     if( plugin->register_plugin() == FALSE ) {
    63         WARN("Failed to load plugin: '%s': Initialization failed", plugin_path);
    64         dlclose(so);
    65         return FALSE;
    66     }
    67     INFO("Loaded %s plugin '%s'", plugin_type_string[plugin->type], plugin->name);
    68     return TRUE;
    69 }
    71 /**
    72  * Scan the plugin dir and load all valid plugins.
    73  */
    74 int plugin_init( const gchar *plugin_dir )
    75 {
    76     int plugin_count;
    77     struct dirent *ent;
    78     DIR *dir = opendir(plugin_dir);
    79     if( dir == NULL ) {
    80         WARN( "Unable to open plugin directory '%s'", plugin_dir );
    81         return 0;
    82     }
    84     while( (ent = readdir(dir)) != NULL ) {
    85         const char *ext = strrchr(ent->d_name, '.');
    86         if( ext != NULL && strcasecmp(SOEXT,ext) == 0 ) {
    87             char *libname = g_strdup_printf( "%s/%s", plugin_dir,ent->d_name );
    88             if( plugin_load( libname ) ) {
    89                 plugin_count++;
    90             }
    91             g_free(libname);
    92         }
    93     }
    94     return plugin_count;
    95 }
.