1 /*****************************************************************************
2 * modules.c : Builtin and plugin modules management functions
3 *****************************************************************************
4 * Copyright (C) 2001-2011 the VideoLAN team
7 * Authors: Sam Hocevar <sam@zoy.org>
8 * Ethan C. Baldridge <BaldridgeE@cadmus.com>
9 * Hans-Peter Jansen <hpj@urpla.net>
10 * Gildas Bazin <gbazin@videolan.org>
11 * RĂ©mi Denis-Courmont
13 * This program is free software; you can redistribute it and/or modify
14 * it under the terms of the GNU General Public License as published by
15 * the Free Software Foundation; either version 2 of the License, or
16 * (at your option) any later version.
18 * This program is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU General Public License for more details.
23 * You should have received a copy of the GNU General Public License
24 * along with this program; if not, write to the Free Software
25 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
26 *****************************************************************************/
32 #include <vlc_common.h>
33 #include <vlc_plugin.h>
34 #include <vlc_memory.h>
35 #include <vlc_modules.h>
38 #include <stdlib.h> /* free(), strtol() */
39 #include <stdio.h> /* sprintf() */
40 #include <string.h> /* strdup() */
43 #include <sys/types.h>
44 #ifdef HAVE_SYS_STAT_H
45 # include <sys/stat.h>
54 #include "config/configuration.h"
57 #include "vlc_arrays.h"
59 #include "modules/modules.h"
66 } modules = { VLC_STATIC_MUTEX, NULL, 0 };
68 int vlc_entry__main( module_t * );
70 /*****************************************************************************
72 *****************************************************************************/
73 #ifdef HAVE_DYNAMIC_PLUGINS
74 typedef enum { CACHE_USE, CACHE_RESET, CACHE_IGNORE } cache_mode_t;
75 typedef struct module_bank module_bank_t;
77 static void AllocateAllPlugins (vlc_object_t *);
78 static void AllocatePluginPath (vlc_object_t *, const char *, cache_mode_t);
79 static void AllocatePluginDir( vlc_object_t *, module_bank_t *, const char *,
80 unsigned, cache_mode_t );
81 static int AllocatePluginFile( vlc_object_t *, module_bank_t *, const char *,
82 const struct stat *, cache_mode_t );
83 static module_t * AllocatePlugin( vlc_object_t *, const char *, bool );
85 static int AllocateBuiltinModule( vlc_object_t *, int ( * ) ( module_t * ) );
86 static void DeleteModule (module_t **, module_t *);
87 #ifdef HAVE_DYNAMIC_PLUGINS
88 static void DupModule ( module_t * );
89 static void UndupModule ( module_t * );
92 #undef module_InitBank
96 * Creates a module bank structure which will be filled later
97 * on with all the modules found.
98 * \param p_this vlc object structure
101 void module_InitBank( vlc_object_t *p_this )
103 vlc_mutex_lock (&modules.lock);
105 if (modules.usage == 0)
107 /* Fills the module bank structure with the main module infos.
108 * This is very useful as it will allow us to consider the main
109 * library just as another module, and for instance the configuration
110 * options of main will be available in the module bank structure just
111 * as for every other module. */
112 AllocateBuiltinModule( p_this, vlc_entry__main );
113 vlc_rwlock_init (&config_lock);
114 config_SortConfig ();
118 /* We do retain the module bank lock until the plugins are loaded as well.
119 * This is ugly, this staged loading approach is needed: LibVLC gets
120 * some configuration parameters relevant to loading the plugins from
121 * the main (builtin) module. The module bank becomes shared read-only data
122 * once it is ready, so we need to fully serialize initialization.
123 * DO NOT UNCOMMENT the following line unless you managed to squeeze
124 * module_LoadPlugins() before you unlock the mutex. */
125 /*vlc_mutex_unlock (&modules.lock);*/
128 #undef module_EndBank
130 * Unloads all unused plugin modules and empties the module
131 * bank in case of success.
132 * \param p_this vlc object structure
135 void module_EndBank( vlc_object_t *p_this, bool b_plugins )
137 module_t *head = NULL;
139 /* If plugins were _not_ loaded, then the caller still has the bank lock
140 * from module_InitBank(). */
142 vlc_mutex_lock (&modules.lock);
144 vlc_assert_locked (&modules.lock); not for static mutexes :( */
146 assert (modules.usage > 0);
147 if (--modules.usage == 0)
149 config_UnsortConfig ();
150 vlc_rwlock_destroy (&config_lock);
154 vlc_mutex_unlock (&modules.lock);
157 DeleteModule (&head, head);
160 #undef module_LoadPlugins
162 * Loads module descriptions for all available plugins.
163 * Fills the module bank structure with the plugin modules.
165 * \param p_this vlc object structure
168 void module_LoadPlugins (vlc_object_t *obj)
170 /*vlc_assert_locked (&modules.lock); not for static mutexes :( */
172 #ifdef HAVE_DYNAMIC_PLUGINS
173 if (modules.usage == 1)
175 msg_Dbg (obj, "searching plug-in modules");
176 AllocateAllPlugins (obj);
177 config_UnsortConfig ();
178 config_SortConfig ();
181 vlc_mutex_unlock (&modules.lock);
185 * Checks whether a module implements a capability.
187 * \param m the module
188 * \param cap the capability to check
189 * \return TRUE if the module have the capability
191 bool module_provides( const module_t *m, const char *cap )
193 if (unlikely(m->psz_capability == NULL))
195 return !strcmp( m->psz_capability, cap );
199 * Get the internal name of a module
201 * \param m the module
202 * \return the module name
204 const char *module_get_object( const module_t *m )
206 return m->psz_object_name;
210 * Get the human-friendly name of a module.
212 * \param m the module
213 * \param long_name TRUE to have the long name of the module
214 * \return the short or long name of the module
216 const char *module_get_name( const module_t *m, bool long_name )
218 if( long_name && ( m->psz_longname != NULL) )
219 return m->psz_longname;
221 return m->psz_shortname ? m->psz_shortname : m->psz_object_name;
225 * Get the help for a module
227 * \param m the module
230 const char *module_get_help( const module_t *m )
236 * Get the capability for a module
238 * \param m the module
239 * return the capability
241 const char *module_get_capability( const module_t *m )
243 return m->psz_capability;
247 * Get the score for a module
249 * \param m the module
250 * return the score for the capability
252 int module_get_score( const module_t *m )
258 * Translate a string using the module's text domain
260 * \param m the module
261 * \param str the American English ASCII string to localize
262 * \return the gettext-translated string
264 const char *module_gettext (const module_t *m, const char *str)
267 const char *domain = m->domain ? m->domain : PACKAGE_NAME;
268 if (unlikely(str == NULL || *str == '\0'))
270 return dgettext (domain, str);
277 module_t *module_hold (module_t *m)
279 vlc_hold (&m->vlc_gc_data);
283 void module_release (module_t *m)
285 vlc_release (&m->vlc_gc_data);
289 int module_start (vlc_object_t *obj, module_t *m)
291 int (*activate) (vlc_object_t *) = m->pf_activate;
293 return (activate != NULL) ? activate (obj) : VLC_SUCCESS;
297 void module_stop (vlc_object_t *obj, module_t *m)
299 void (*deactivate) (vlc_object_t *) = m->pf_deactivate;
301 if (deactivate != NULL)
306 * Frees the flat list of VLC modules.
307 * @param list list obtained by module_list_get()
308 * @param length number of items on the list
311 void module_list_free (module_t **list)
316 for (size_t i = 0; list[i] != NULL; i++)
317 module_release (list[i]);
322 * Gets the flat list of VLC modules.
323 * @param n [OUT] pointer to the number of modules or NULL
324 * @return NULL-terminated table of module pointers
325 * (release with module_list_free()), or NULL in case of error.
327 module_t **module_list_get (size_t *n)
329 /* TODO: this whole module lookup is quite inefficient */
330 /* Remove this and improve module_need */
331 module_t **tab = NULL;
334 for (module_t *mod = modules.head; mod; mod = mod->next)
337 nt = realloc (tab, (i + 2 + mod->submodule_count) * sizeof (*tab));
340 module_list_free (tab);
345 tab[i++] = module_hold (mod);
346 for (module_t *subm = mod->submodule; subm; subm = subm->next)
347 tab[i++] = module_hold (subm);
355 typedef struct module_list_t
362 static int modulecmp (const void *a, const void *b)
364 const module_list_t *la = a, *lb = b;
365 /* Note that qsort() uses _ascending_ order,
366 * so the smallest module is the one with the biggest score. */
367 return lb->i_score - la->i_score;
370 #undef vlc_module_load
372 * Finds and instantiates the best module of a certain type.
373 * All candidates modules having the specified capability and name will be
374 * sorted in decreasing order of priority. Then the probe callback will be
375 * invoked for each module, until it succeeds (returns 0), or all candidate
376 * module failed to initialize.
378 * The probe callback first parameter is the address of the module entry point.
379 * Further parameters are passed as an argument list; it corresponds to the
380 * variable arguments passed to this function. This scheme is meant to
381 * support arbitrary prototypes for the module entry point.
383 * \param p_this VLC object
384 * \param psz_capability capability, i.e. class of module
385 * \param psz_name name name of the module asked, if any
386 * \param b_strict if true, do not fallback to plugin with a different name
387 * but the same capability
388 * \param probe module probe callback
389 * \return the module or NULL in case of a failure
391 module_t *vlc_module_load(vlc_object_t *p_this, const char *psz_capability,
392 const char *psz_name, bool b_strict,
393 vlc_activate_t probe, ...)
395 stats_TimerStart( p_this, "module_need()", STATS_TIMER_MODULE_NEED );
397 module_list_t *p_list;
400 char *psz_shortcuts = NULL, *psz_var = NULL, *psz_alias = NULL;
401 bool b_force_backup = p_this->b_force;
403 /* Deal with variables */
404 if( psz_name && psz_name[0] == '$' )
406 psz_name = psz_var = var_CreateGetString( p_this, psz_name + 1 );
409 /* Count how many different shortcuts were asked for */
410 if( psz_name && *psz_name )
412 char *psz_parser, *psz_last_shortcut;
414 /* If the user wants none, give him none. */
415 if( !strcmp( psz_name, "none" ) )
418 stats_TimerStop( p_this, STATS_TIMER_MODULE_NEED );
419 stats_TimerDump( p_this, STATS_TIMER_MODULE_NEED );
420 stats_TimerClean( p_this, STATS_TIMER_MODULE_NEED );
425 psz_parser = psz_shortcuts = psz_last_shortcut = strdup( psz_name );
427 while( ( psz_parser = strchr( psz_parser, ',' ) ) )
431 psz_last_shortcut = ++psz_parser;
434 /* Check if the user wants to override the "strict" mode */
435 if( psz_last_shortcut )
437 if( !strcmp(psz_last_shortcut, "none") )
442 else if( !strcmp(psz_last_shortcut, "any") )
450 /* Sort the modules and test them */
452 module_t **p_all = module_list_get (&count);
453 p_list = malloc( count * sizeof( module_list_t ) );
455 /* Parse the module list for capabilities and probe each of them */
457 for (size_t i = 0; (p_module = p_all[i]) != NULL; i++)
459 int i_shortcut_bonus = 0;
461 /* Test that this module can do what we need */
462 if( !module_provides( p_module, psz_capability ) )
465 /* If we required a shortcut, check this plugin provides it. */
466 if( i_shortcuts > 0 )
468 const char *name = psz_shortcuts;
470 for( unsigned i_short = i_shortcuts; i_short > 0; i_short-- )
472 for( unsigned i = 0; i < p_module->i_shortcuts; i++ )
475 if( ( c = strchr( name, '@' ) )
476 ? !strncasecmp( name, p_module->pp_shortcuts[i],
478 : !strcasecmp( name, p_module->pp_shortcuts[i] ) )
483 i_shortcut_bonus = i_short * 10000;
488 /* Go to the next shortcut... This is so lame! */
489 name += strlen( name ) + 1;
492 /* If we are in "strict" mode and we couldn't
493 * find the module in the list of provided shortcuts,
494 * then kick the bastard out of here!!! */
499 /* Trash <= 0 scored plugins (they can only be selected by shortcut) */
500 if( p_module->i_score <= 0 )
504 /* Store this new module */
505 p_list[count].p_module = module_hold (p_module);
506 p_list[count].i_score = p_module->i_score + i_shortcut_bonus;
507 p_list[count].b_force = i_shortcut_bonus && b_strict;
511 /* We can release the list, interesting modules are held */
512 module_list_free (p_all);
514 /* Sort candidates by descending score */
515 qsort (p_list, count, sizeof (p_list[0]), modulecmp);
516 msg_Dbg( p_this, "looking for %s module: %zu candidate%s", psz_capability,
517 count, count == 1 ? "" : "s" );
519 /* Parse the linked list and use the first successful module */
522 va_start(args, probe);
525 for (size_t i = 0; (i < count) && (p_module == NULL); i++)
527 module_t *p_cand = p_list[i].p_module;
528 #ifdef HAVE_DYNAMIC_PLUGINS
529 /* Make sure the module is loaded in mem */
530 module_t *p_real = p_cand->parent ? p_cand->parent : p_cand;
532 if( !p_real->b_builtin && !p_real->b_loaded )
534 module_t *p_new_module =
535 AllocatePlugin( p_this, p_real->psz_filename, false );
536 if( p_new_module == NULL )
537 { /* Corrupted module */
538 msg_Err( p_this, "possibly corrupt module cache" );
539 module_release( p_cand );
542 CacheMerge( p_this, p_real, p_new_module );
543 DeleteModule (&modules.head, p_new_module);
546 p_this->b_force = p_list[i].b_force;
550 if (likely(p_cand->pf_activate != NULL))
555 ret = probe(p_cand->pf_activate, ap);
569 /* good module, but aborted */
570 module_release( p_cand );
573 default: /* bad module */
574 module_release( p_cand );
578 /* Release the remaining modules */
580 module_release (p_list[i].p_module);
585 p_this->b_force = b_force_backup;
587 if( p_module != NULL )
589 msg_Dbg( p_this, "using %s module \"%s\"",
590 psz_capability, p_module->psz_object_name );
591 vlc_object_set_name( p_this, psz_alias ? psz_alias
592 : p_module->psz_object_name );
594 else if( count == 0 )
595 msg_Dbg( p_this, "no %s module matched \"%s\"",
596 psz_capability, (psz_name && *psz_name) ? psz_name : "any" );
598 msg_Dbg( p_this, "no %s module matching \"%s\" could be loaded",
599 psz_capability, (psz_name && *psz_name) ? psz_name : "any" );
601 free( psz_shortcuts );
604 stats_TimerStop( p_this, STATS_TIMER_MODULE_NEED );
605 stats_TimerDump( p_this, STATS_TIMER_MODULE_NEED );
606 stats_TimerClean( p_this, STATS_TIMER_MODULE_NEED );
608 /* Don't forget that the module is still locked */
614 * Deinstantiates a module.
615 * \param module the module pointer as returned by vlc_module_load()
616 * \param deinit deactivation callback
618 void vlc_module_unload(module_t *module, vlc_deactivate_t deinit, ...)
620 if (module->pf_deactivate != NULL)
624 va_start(ap, deinit);
625 deinit(module->pf_deactivate, ap);
628 module_release(module);
632 static int generic_start(void *func, va_list ap)
634 vlc_object_t *obj = va_arg(ap, vlc_object_t *);
635 int (*activate)(vlc_object_t *) = func;
637 return activate(obj);
640 static void generic_stop(void *func, va_list ap)
642 vlc_object_t *obj = va_arg(ap, vlc_object_t *);
643 void (*deactivate)(vlc_object_t *) = func;
649 module_t *module_need(vlc_object_t *obj, const char *cap, const char *name,
652 return vlc_module_load(obj, cap, name, strict, generic_start, obj);
656 void module_unneed(vlc_object_t *obj, module_t *module)
658 msg_Dbg(obj, "removing module \"%s\"", module->psz_object_name);
659 vlc_module_unload(module, generic_stop, obj);
663 * Get a pointer to a module_t given it's name.
665 * \param psz_name the name of the module
666 * \return a pointer to the module or NULL in case of a failure
668 module_t *module_find( const char * psz_name )
670 module_t **list, *module;
672 list = module_list_get (NULL);
676 for (size_t i = 0; (module = list[i]) != NULL; i++)
678 const char *psz_module_name = module->psz_object_name;
680 if( psz_module_name && !strcmp( psz_module_name, psz_name ) )
682 module_hold (module);
686 module_list_free (list);
691 * Tell if a module exists and release it in thic case
693 * \param psz_name th name of the module
694 * \return TRUE if the module exists
696 bool module_exists (const char * psz_name)
698 module_t *p_module = module_find (psz_name);
700 module_release (p_module);
701 return p_module != NULL;
705 * Get a pointer to a module_t that matches a shortcut.
706 * This is a temporary hack for SD. Do not re-use (generally multiple modules
707 * can have the same shortcut, so this is *broken* - use module_need()!).
709 * \param psz_shortcut shortcut of the module
710 * \param psz_cap capability of the module
711 * \return a pointer to the module or NULL in case of a failure
713 module_t *module_find_by_shortcut (const char *psz_shortcut)
715 module_t **list, *module;
717 list = module_list_get (NULL);
721 for (size_t i = 0; (module = list[i]) != NULL; i++)
723 for (size_t j = 0; j < module->i_shortcuts; j++)
725 if (!strcmp (module->pp_shortcuts[j], psz_shortcut))
727 module_hold (module);
733 module_list_free (list);
738 * Get the configuration of a module
740 * \param module the module
741 * \param psize the size of the configuration returned
742 * \return the configuration as an array
744 module_config_t *module_config_get( const module_t *module, unsigned *restrict psize )
747 unsigned size = module->confsize;
748 module_config_t *config = malloc( size * sizeof( *config ) );
750 assert( psize != NULL );
756 for( i = 0, j = 0; i < size; i++ )
758 const module_config_t *item = module->p_config + i;
759 if( item->b_internal /* internal option */
760 || item->b_removed /* removed option */ )
763 memcpy( config + j, item, sizeof( *config ) );
772 * Release the configuration
774 * \param the configuration
777 void module_config_free( module_config_t *config )
782 /*****************************************************************************
783 * Following functions are local.
784 *****************************************************************************/
786 char *psz_vlcpath = NULL;
788 #ifdef HAVE_DYNAMIC_PLUGINS
790 /*****************************************************************************
791 * AllocateAllPlugins: load all plugin modules we can find.
792 *****************************************************************************/
793 static void AllocateAllPlugins (vlc_object_t *p_this)
795 const char *vlcpath = psz_vlcpath;
799 if( !var_InheritBool( p_this, "plugins-cache" ) )
801 else if( var_InheritBool( p_this, "reset-plugins-cache" ) )
806 /* Contruct the special search path for system that have a relocatable
807 * executable. Set it to <vlc path>/plugins. */
810 if( asprintf( &paths, "%s" DIR_SEP "plugins", vlcpath ) != -1 )
812 AllocatePluginPath (p_this, paths, mode);
816 /* If the user provided a plugin path, we add it to the list */
817 paths = getenv( "VLC_PLUGIN_PATH" );
821 paths = strdup( paths ); /* don't harm the environment ! :) */
822 if( unlikely(paths == NULL) )
825 for( char *buf, *path = strtok_r( paths, PATH_SEP, &buf );
827 path = strtok_r( NULL, PATH_SEP, &buf ) )
828 AllocatePluginPath (p_this, path, mode);
837 module_cache_t *cache;
840 module_cache_t *loaded_cache;
843 static void AllocatePluginPath (vlc_object_t *p_this, const char *path,
847 module_cache_t *cache = NULL;
853 count = CacheLoad( p_this, path, &cache );
856 CacheDelete( p_this, path );
859 msg_Dbg( p_this, "ignoring plugins cache file" );
862 msg_Dbg( p_this, "recursively browsing `%s'", path );
866 bank.loaded_cache = cache;
867 bank.i_loaded_cache = count;
869 /* Don't go deeper than 5 subdirectories */
870 AllocatePluginDir (p_this, &bank, path, 5, mode);
875 for( size_t i = 0; i < count; i++ )
877 if (cache[i].p_module != NULL)
878 DeleteModule (&modules.head, cache[i].p_module);
879 free (cache[i].path);
883 CacheSave (p_this, path, bank.cache, bank.i_cache);
889 /*****************************************************************************
890 * AllocatePluginDir: recursively parse a directory to look for plugins
891 *****************************************************************************/
892 static void AllocatePluginDir( vlc_object_t *p_this, module_bank_t *p_bank,
893 const char *psz_dir, unsigned i_maxdepth,
896 if( i_maxdepth == 0 )
899 DIR *dh = vlc_opendir (psz_dir);
903 /* Parse the directory and try to load all files it contains. */
906 char *file = vlc_readdir (dh), *path;
913 if (!strcmp (file, ".") || !strcmp (file, ".."))
919 const int pathlen = asprintf (&path, "%s"DIR_SEP"%s", psz_dir, file);
921 if (pathlen == -1 || vlc_stat (path, &st))
924 if (S_ISDIR (st.st_mode))
925 /* Recurse into another directory */
926 AllocatePluginDir (p_this, p_bank, path, i_maxdepth - 1, mode);
928 if (S_ISREG (st.st_mode)
929 && strncmp (path, "lib", 3)
930 && ((size_t)pathlen >= sizeof ("_plugin"LIBEXT))
931 && !strncasecmp (path + pathlen - strlen ("_plugin"LIBEXT),
932 "_plugin"LIBEXT, strlen ("_plugni"LIBEXT)))
933 /* ^^ We only load files matching "lib*_plugin"LIBEXT */
934 AllocatePluginFile (p_this, p_bank, path, &st, mode);
941 /*****************************************************************************
942 * AllocatePluginFile: load a module into memory and initialize it.
943 *****************************************************************************
944 * This function loads a dynamically loadable module and allocates a structure
945 * for its information data. The module can then be handled by module_need
946 * and module_unneed. It can be removed by DeleteModule.
947 *****************************************************************************/
948 static int AllocatePluginFile( vlc_object_t * p_this, module_bank_t *p_bank,
949 const char *path, const struct stat *st,
952 module_t * p_module = NULL;
954 /* msg_Dbg( p_this, "plugin \"%s\", %s",
955 p_module->psz_object_name, p_module->psz_longname ); */
956 /* Check our plugins cache first then load plugin if needed */
957 if( mode == CACHE_USE )
958 p_module = CacheFind (p_bank->loaded_cache, p_bank->i_loaded_cache,
960 if( p_module == NULL )
961 p_module = AllocatePlugin( p_this, path, true );
962 if( p_module == NULL )
965 /* We have not already scanned and inserted this module */
966 assert( p_module->next == NULL );
968 /* Unload plugin until we really need it */
969 assert( !p_module->b_builtin );
970 if( p_module->b_loaded && p_module->b_unloadable )
972 module_Unload( p_module->handle );
973 p_module->b_loaded = false;
976 /* For now we force loading if the module's config contains
977 * callbacks or actions.
978 * Could be optimized by adding an API call.*/
979 for( size_t n = p_module->confsize, i = 0; i < n; i++ )
980 if( p_module->p_config[i].i_action )
982 /* !unloadable not allowed for plugins with callbacks */
983 assert( !p_module->b_loaded );
984 DeleteModule (&modules.head, p_module);
985 p_module = AllocatePlugin( p_this, path, false );
989 p_module->next = modules.head;
990 modules.head = p_module;
992 if( mode == CACHE_IGNORE )
995 /* Add entry to cache */
996 CacheAdd (&p_bank->cache, &p_bank->i_cache, path, st, p_module);
997 /* TODO: deal with errors */
1001 /*****************************************************************************
1002 * AllocatePlugin: load a module into memory and initialize it.
1003 *****************************************************************************
1004 * This function loads a dynamically loadable module and allocates a structure
1005 * for its information data. The module can then be handled by module_need
1006 * and module_unneed. It can be removed by DeleteModule.
1007 *****************************************************************************/
1008 static module_t *AllocatePlugin( vlc_object_t * p_this, const char *psz_file,
1011 module_t * p_module = NULL;
1012 module_handle_t handle;
1014 if( module_Load( p_this, psz_file, &handle, fast ) )
1017 /* Now that we have successfully loaded the module, we can
1018 * allocate a structure for it */
1019 p_module = vlc_module_create();
1020 if( p_module == NULL )
1022 module_Unload( handle );
1026 p_module->psz_filename = strdup( psz_file );
1027 p_module->handle = handle;
1028 p_module->b_loaded = true;
1030 /* Initialize the module: fill p_module, default config */
1031 static const char entry[] = "vlc_entry" MODULE_SUFFIX;
1033 /* Try to resolve the symbol */
1034 int (*pf_symbol)(module_t * p_module)
1035 = (int (*)(module_t *)) module_Lookup( p_module->handle,entry );
1036 if( pf_symbol == NULL )
1038 msg_Warn( p_this, "cannot find symbol \"%s\" in plugin `%s'",
1043 /* We can now try to call the symbol */
1044 if( pf_symbol( p_module ) != 0 )
1046 /* With a well-written module we shouldn't have to print an
1047 * additional error message here, but just make sure. */
1048 msg_Err( p_this, "cannot initialize plugin `%s'", psz_file );
1052 DupModule( p_module );
1053 assert( !p_module->b_builtin );
1056 free( p_module->psz_filename );
1057 module_release( p_module );
1058 module_Unload( handle );
1062 /*****************************************************************************
1063 * DupModule: make a plugin module standalone.
1064 *****************************************************************************
1065 * This function duplicates all strings in the module, so that the dynamic
1066 * object can be unloaded. It acts recursively on submodules.
1067 *****************************************************************************/
1068 static void DupModule( module_t *p_module )
1070 char **pp_shortcuts = p_module->pp_shortcuts;
1071 for( unsigned i = 0; i < p_module->i_shortcuts; i++ )
1072 pp_shortcuts[i] = strdup( p_module->pp_shortcuts[i] );
1074 /* We strdup() these entries so that they are still valid when the
1075 * module is unloaded. */
1076 p_module->psz_capability =
1077 p_module->psz_capability ? strdup( p_module->psz_capability ) : NULL;
1078 p_module->psz_shortname = p_module->psz_shortname ?
1079 strdup( p_module->psz_shortname ) : NULL;
1080 p_module->psz_longname = strdup( p_module->psz_longname );
1081 p_module->psz_help = p_module->psz_help ? strdup( p_module->psz_help )
1083 p_module->domain = p_module->domain ? strdup( p_module->domain ) : NULL;
1085 for (module_t *subm = p_module->submodule; subm; subm = subm->next)
1089 /*****************************************************************************
1090 * UndupModule: free a duplicated module.
1091 *****************************************************************************
1092 * This function frees the allocations done in DupModule().
1093 *****************************************************************************/
1094 static void UndupModule( module_t *p_module )
1096 char **pp_shortcuts = p_module->pp_shortcuts;
1098 for (module_t *subm = p_module->submodule; subm; subm = subm->next)
1101 for( unsigned i = 0; i < p_module->i_shortcuts; i++ )
1102 free( pp_shortcuts[i] );
1104 free( p_module->psz_capability );
1105 FREENULL( p_module->psz_shortname );
1106 free( p_module->psz_longname );
1107 FREENULL( p_module->psz_help );
1108 free( p_module->domain );
1111 #endif /* HAVE_DYNAMIC_PLUGINS */
1113 /*****************************************************************************
1114 * AllocateBuiltinModule: initialize a builtin module.
1115 *****************************************************************************
1116 * This function registers a builtin module and allocates a structure
1117 * for its information data. The module can then be handled by module_need
1118 * and module_unneed. It can be removed by DeleteModule.
1119 *****************************************************************************/
1120 static int AllocateBuiltinModule( vlc_object_t * p_this,
1121 int ( *pf_entry ) ( module_t * ) )
1123 module_t * p_module;
1125 /* Now that we have successfully loaded the module, we can
1126 * allocate a structure for it */
1127 p_module = vlc_module_create();
1128 if( p_module == NULL )
1131 /* Initialize the module : fill p_module->psz_object_name, etc. */
1132 if( pf_entry( p_module ) != 0 )
1134 /* With a well-written module we shouldn't have to print an
1135 * additional error message here, but just make sure. */
1136 msg_Err( p_this, "failed calling entry point in builtin module" );
1137 module_release( p_module );
1141 /* Everything worked fine ! The module is ready to be added to the list. */
1142 p_module->b_builtin = true;
1144 p_module->next = modules.head;
1145 modules.head = p_module;
1148 /* msg_Dbg( p_this, "builtin \"%s\", %s",
1149 p_module->psz_object_name, p_module->psz_longname ); */
1154 /*****************************************************************************
1155 * DeleteModule: delete a module and its structure.
1156 *****************************************************************************
1157 * This function can only be called if the module isn't being used.
1158 *****************************************************************************/
1159 static void DeleteModule (module_t **head, module_t *p_module)
1163 /* Unlist the module (if it is in the list) */
1164 module_t **pp_self = head;
1165 while (*pp_self != NULL && *pp_self != p_module)
1166 pp_self = &((*pp_self)->next);
1168 *pp_self = p_module->next;
1170 /* We free the structures that we strdup()ed in Allocate*Module(). */
1171 #ifdef HAVE_DYNAMIC_PLUGINS
1172 if( !p_module->b_builtin )
1174 if( p_module->b_loaded && p_module->b_unloadable )
1176 module_Unload( p_module->handle );
1178 UndupModule( p_module );
1179 free( p_module->psz_filename );
1183 /* Free and detach the object's children */
1184 while (p_module->submodule)
1186 module_t *submodule = p_module->submodule;
1187 p_module->submodule = submodule->next;
1188 module_release (submodule);
1191 config_Free( p_module );
1192 module_release( p_module );