* 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:
@@ -1,8 +1,7 @@
|
|||||||
/* Modules Definitions
|
/*
|
||||||
**
|
* Copyright 2002-2008, Haiku Inc. All Rights Reserved.
|
||||||
** Distributed under the terms of the OpenBeOS License.
|
* Distributed under the terms of the MIT License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef _MODULE_H
|
#ifndef _MODULE_H
|
||||||
#define _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 get_module(const char *path, module_info **_info);
|
||||||
extern status_t put_module(const char *path);
|
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 void *open_module_list(const char *prefix);
|
||||||
extern status_t close_module_list(void *cookie);
|
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
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -120,6 +120,8 @@ typedef struct module_iterator {
|
|||||||
|
|
||||||
char *prefix;
|
char *prefix;
|
||||||
size_t prefix_length;
|
size_t prefix_length;
|
||||||
|
const char *suffix;
|
||||||
|
size_t suffix_length;
|
||||||
DIR *current_dir;
|
DIR *current_dir;
|
||||||
status_t status;
|
status_t status;
|
||||||
int32 module_offset;
|
int32 module_offset;
|
||||||
@@ -570,7 +572,10 @@ init_module(module *module)
|
|||||||
// init module
|
// init module
|
||||||
|
|
||||||
TRACE(("initializing module %s (at %p)... \n", module->name, module->info->std_ops));
|
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)));
|
TRACE(("...done (%s)\n", strerror(status)));
|
||||||
|
|
||||||
if (status >= B_OK)
|
if (status >= B_OK)
|
||||||
@@ -626,17 +631,18 @@ uninit_module(module *module)
|
|||||||
|
|
||||||
case MODULE_READY:
|
case MODULE_READY:
|
||||||
{
|
{
|
||||||
status_t status;
|
status_t status = B_OK;
|
||||||
|
|
||||||
module->state = MODULE_UNINIT;
|
module->state = MODULE_UNINIT;
|
||||||
|
|
||||||
TRACE(("uninitializing module %s...\n", module->name));
|
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)));
|
TRACE(("...done (%s)\n", strerror(status)));
|
||||||
|
|
||||||
if (status == B_NO_ERROR) {
|
if (status == B_OK) {
|
||||||
module->state = MODULE_LOADED;
|
module->state = MODULE_LOADED;
|
||||||
|
|
||||||
put_dependent_modules(module);
|
put_dependent_modules(module);
|
||||||
return B_OK;
|
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
|
static status_t
|
||||||
iterator_get_next_module(module_iterator *iterator, char *buffer,
|
iterator_get_next_module(module_iterator *iterator, char *buffer,
|
||||||
size_t *_bufferSize)
|
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++) {
|
for (int32 i = iterator->module_offset; sBuiltInModules[i] != NULL; i++) {
|
||||||
// the module name must fit the prefix
|
// the module name must fit the prefix
|
||||||
if (strncmp(sBuiltInModules[i]->name, iterator->prefix,
|
if (strncmp(sBuiltInModules[i]->name, iterator->prefix,
|
||||||
iterator->prefix_length))
|
iterator->prefix_length)
|
||||||
|
|| !match_iterator_suffix(iterator, sBuiltInModules[i]->name))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
*_bufferSize = strlcpy(buffer, sBuiltInModules[i]->name,
|
*_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++) {
|
for (int32 i = 0; module != NULL; i++) {
|
||||||
if (i >= iterator->module_offset) {
|
if (i >= iterator->module_offset) {
|
||||||
if (!strncmp(module->name, iterator->prefix,
|
if (!strncmp(module->name, iterator->prefix,
|
||||||
iterator->prefix_length)) {
|
iterator->prefix_length)
|
||||||
|
&& match_iterator_suffix(iterator, module->name)) {
|
||||||
*_bufferSize = strlcpy(buffer, module->name, *_bufferSize);
|
*_bufferSize = strlcpy(buffer, module->name, *_bufferSize);
|
||||||
iterator->module_offset = i + 1;
|
iterator->module_offset = i + 1;
|
||||||
|
|
||||||
@@ -849,12 +872,14 @@ nextModuleImage:
|
|||||||
while (*iterator->current_header != NULL) {
|
while (*iterator->current_header != NULL) {
|
||||||
module_info *info = *iterator->current_header;
|
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->current_header++;
|
||||||
iterator->module_offset++;
|
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;
|
continue;
|
||||||
|
|
||||||
*_bufferSize = strlcpy(buffer, info->name, *_bufferSize);
|
*_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
|
/*! This returns a pointer to a structure that can be used to
|
||||||
iterate through a list of all modules available under
|
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
|
All paths will be searched and the returned list will
|
||||||
contain all modules available under the prefix.
|
contain all modules available under the prefix.
|
||||||
The structure is then used by read_next_module_name(), and
|
The structure is then used by read_next_module_name(), and
|
||||||
must be freed by calling close_module_list().
|
must be freed by calling close_module_list().
|
||||||
*/
|
*/
|
||||||
void *
|
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));
|
TRACE(("open_module_list(prefix = %s)\n", prefix));
|
||||||
|
|
||||||
if (sModulesHash == NULL) {
|
if (sModulesHash == NULL) {
|
||||||
@@ -1111,7 +1133,8 @@ open_module_list(const char *prefix)
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
iterator = (module_iterator *)malloc(sizeof(module_iterator));
|
module_iterator *iterator = (module_iterator *)malloc(
|
||||||
|
sizeof(module_iterator));
|
||||||
if (!iterator)
|
if (!iterator)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
@@ -1124,6 +1147,10 @@ open_module_list(const char *prefix)
|
|||||||
}
|
}
|
||||||
iterator->prefix_length = strlen(iterator->prefix);
|
iterator->prefix_length = strlen(iterator->prefix);
|
||||||
|
|
||||||
|
iterator->suffix = suffix;
|
||||||
|
if (suffix != NULL)
|
||||||
|
iterator->suffix_length = strlen(iterator->suffix);
|
||||||
|
|
||||||
if (gBootDevice > 0) {
|
if (gBootDevice > 0) {
|
||||||
// We do have a boot device to scan
|
// We do have a boot device to scan
|
||||||
|
|
||||||
@@ -1132,7 +1159,7 @@ open_module_list(const char *prefix)
|
|||||||
iterator->loaded_modules = false;
|
iterator->loaded_modules = false;
|
||||||
|
|
||||||
// put all search paths on the stack
|
// put all search paths on the stack
|
||||||
for (i = 0; i < kNumModulePaths; i++) {
|
for (uint32 i = 0; i < kNumModulePaths; i++) {
|
||||||
if (sDisableUserAddOns && i >= kFirstNonSystemModulePath)
|
if (sDisableUserAddOns && i >= kFirstNonSystemModulePath)
|
||||||
break;
|
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() */
|
/*! Frees the cookie allocated by open_module_list() */
|
||||||
status_t
|
status_t
|
||||||
close_module_list(void *cookie)
|
close_module_list(void *cookie)
|
||||||
|
|||||||
@@ -273,7 +273,8 @@ Module::Init()
|
|||||||
{
|
{
|
||||||
status_t error = (fInfo ? B_OK : B_NO_INIT);
|
status_t error = (fInfo ? B_OK : B_NO_INIT);
|
||||||
if (error == B_OK && !fInitialized) {
|
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)
|
if (error == B_OK)
|
||||||
fInitialized = true;
|
fInitialized = true;
|
||||||
}
|
}
|
||||||
@@ -286,7 +287,8 @@ Module::Uninit()
|
|||||||
{
|
{
|
||||||
status_t error = (fInfo ? B_OK : B_NO_INIT);
|
status_t error = (fInfo ? B_OK : B_NO_INIT);
|
||||||
if (error == B_OK && fInitialized) {
|
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;
|
fInitialized = false;
|
||||||
}
|
}
|
||||||
return error;
|
return error;
|
||||||
|
|||||||
Reference in New Issue
Block a user