* Added open_module_list_etc() that also allows to specify a required name

suffix. You can use this to verify the version of a module_info structure.
* Made module_info::std_ops optional.
* Minor cleanup in module.h.


git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@24873 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Axel Dörfler
2008-04-09 14:36:04 +00:00
parent 4f61b1059c
commit 8b79f1fd68
3 changed files with 65 additions and 27 deletions
+9 -7
View File
@@ -1,8 +1,7 @@
/* Modules Definitions
**
** Distributed under the terms of the OpenBeOS License.
*/
/*
* Copyright 2002-2008, Haiku Inc. All Rights Reserved.
* Distributed under the terms of the MIT License.
*/
#ifndef _MODULE_H
#define _MODULE_H
@@ -46,10 +45,13 @@ extern "C" {
extern status_t get_module(const char *path, module_info **_info);
extern status_t put_module(const char *path);
extern status_t get_next_loaded_module_name(uint32 *cookie, char *buffer, size_t *_bufferSize);
extern status_t get_next_loaded_module_name(uint32 *cookie, char *buffer,
size_t *_bufferSize);
extern void *open_module_list_etc(const char *prefix, const char *suffix);
extern void *open_module_list(const char *prefix);
extern status_t close_module_list(void *cookie);
extern status_t read_next_module_name(void *cookie, char *buffer, size_t *_bufferSize);
extern status_t read_next_module_name(void *cookie, char *buffer,
size_t *_bufferSize);
#ifdef __cplusplus
}
+52 -18
View File
@@ -120,6 +120,8 @@ typedef struct module_iterator {
char *prefix;
size_t prefix_length;
const char *suffix;
size_t suffix_length;
DIR *current_dir;
status_t status;
int32 module_offset;
@@ -570,7 +572,10 @@ init_module(module *module)
// init module
TRACE(("initializing module %s (at %p)... \n", module->name, module->info->std_ops));
status = module->info->std_ops(B_MODULE_INIT);
if (module->info->std_ops != NULL)
status = module->info->std_ops(B_MODULE_INIT);
TRACE(("...done (%s)\n", strerror(status)));
if (status >= B_OK)
@@ -626,17 +631,18 @@ uninit_module(module *module)
case MODULE_READY:
{
status_t status;
status_t status = B_OK;
module->state = MODULE_UNINIT;
TRACE(("uninitializing module %s...\n", module->name));
status = module->info->std_ops(B_MODULE_UNINIT);
if (module->info->std_ops != NULL)
status = module->info->std_ops(B_MODULE_UNINIT);
TRACE(("...done (%s)\n", strerror(status)));
if (status == B_NO_ERROR) {
if (status == B_OK) {
module->state = MODULE_LOADED;
put_dependent_modules(module);
return B_OK;
}
@@ -689,6 +695,21 @@ iterator_push_path_on_stack(module_iterator *iterator, const char *path, uint32
}
static bool
match_iterator_suffix(module_iterator *iterator, const char *name)
{
if (iterator->suffix == NULL || iterator->suffix_length == 0)
return true;
size_t length = strlen(name);
if (length <= iterator->suffix_length)
return false;
return name[length - iterator->suffix_length - 1] == '/'
&& !strcmp(name + length - iterator->suffix_length, iterator->suffix);
}
static status_t
iterator_get_next_module(module_iterator *iterator, char *buffer,
size_t *_bufferSize)
@@ -701,7 +722,8 @@ iterator_get_next_module(module_iterator *iterator, char *buffer,
for (int32 i = iterator->module_offset; sBuiltInModules[i] != NULL; i++) {
// the module name must fit the prefix
if (strncmp(sBuiltInModules[i]->name, iterator->prefix,
iterator->prefix_length))
iterator->prefix_length)
|| !match_iterator_suffix(iterator, sBuiltInModules[i]->name))
continue;
*_bufferSize = strlcpy(buffer, sBuiltInModules[i]->name,
@@ -722,7 +744,8 @@ iterator_get_next_module(module_iterator *iterator, char *buffer,
for (int32 i = 0; module != NULL; i++) {
if (i >= iterator->module_offset) {
if (!strncmp(module->name, iterator->prefix,
iterator->prefix_length)) {
iterator->prefix_length)
&& match_iterator_suffix(iterator, module->name)) {
*_bufferSize = strlcpy(buffer, module->name, *_bufferSize);
iterator->module_offset = i + 1;
@@ -740,7 +763,7 @@ iterator_get_next_module(module_iterator *iterator, char *buffer,
// prevent from falling into modules hash iteration again
iterator->loaded_modules = false;
}
nextPath:
if (iterator->current_dir == NULL) {
// get next directory path from the stack
@@ -849,12 +872,14 @@ nextModuleImage:
while (*iterator->current_header != NULL) {
module_info *info = *iterator->current_header;
// ToDo: we might want to create a module here and cache it in the hash table
// TODO: we might want to create a module here and cache it in the
// hash table
iterator->current_header++;
iterator->module_offset++;
if (strncmp(info->name, iterator->prefix, iterator->prefix_length))
if (strncmp(info->name, iterator->prefix, iterator->prefix_length)
|| !match_iterator_suffix(iterator, info->name))
continue;
*_bufferSize = strlcpy(buffer, info->name, *_bufferSize);
@@ -1092,18 +1117,15 @@ module_init(kernel_args *args)
/*! This returns a pointer to a structure that can be used to
iterate through a list of all modules available under
a given prefix.
a given prefix that adhere to the specified suffix.
All paths will be searched and the returned list will
contain all modules available under the prefix.
The structure is then used by read_next_module_name(), and
must be freed by calling close_module_list().
*/
void *
open_module_list(const char *prefix)
open_module_list_etc(const char *prefix, const char *suffix)
{
module_iterator *iterator;
uint32 i;
TRACE(("open_module_list(prefix = %s)\n", prefix));
if (sModulesHash == NULL) {
@@ -1111,7 +1133,8 @@ open_module_list(const char *prefix)
return NULL;
}
iterator = (module_iterator *)malloc(sizeof(module_iterator));
module_iterator *iterator = (module_iterator *)malloc(
sizeof(module_iterator));
if (!iterator)
return NULL;
@@ -1124,6 +1147,10 @@ open_module_list(const char *prefix)
}
iterator->prefix_length = strlen(iterator->prefix);
iterator->suffix = suffix;
if (suffix != NULL)
iterator->suffix_length = strlen(iterator->suffix);
if (gBootDevice > 0) {
// We do have a boot device to scan
@@ -1132,7 +1159,7 @@ open_module_list(const char *prefix)
iterator->loaded_modules = false;
// put all search paths on the stack
for (i = 0; i < kNumModulePaths; i++) {
for (uint32 i = 0; i < kNumModulePaths; i++) {
if (sDisableUserAddOns && i >= kFirstNonSystemModulePath)
break;
@@ -1183,6 +1210,13 @@ open_module_list(const char *prefix)
}
void *
open_module_list(const char *prefix)
{
return open_module_list_etc(prefix, NULL);
}
/*! Frees the cookie allocated by open_module_list() */
status_t
close_module_list(void *cookie)
+4 -2
View File
@@ -273,7 +273,8 @@ Module::Init()
{
status_t error = (fInfo ? B_OK : B_NO_INIT);
if (error == B_OK && !fInitialized) {
error = fInfo->std_ops(B_MODULE_INIT);
if (fInfo->std_ops != NULL)
error = fInfo->std_ops(B_MODULE_INIT);
if (error == B_OK)
fInitialized = true;
}
@@ -286,7 +287,8 @@ Module::Uninit()
{
status_t error = (fInfo ? B_OK : B_NO_INIT);
if (error == B_OK && fInitialized) {
error = fInfo->std_ops(B_MODULE_UNINIT);
if (fInfo->std_ops != NULL)
error = fInfo->std_ops(B_MODULE_UNINIT);
fInitialized = false;
}
return error;