* Applied a patch by Siarzhuk Zharski that allows open_module_list() to be
used during early boot. Thanks! * Fixed open_module_list() so that it can deal with a NULL prefix. * Added a note that get_next_loaded_module_name() is implemented incorrectly. * Minor cleanup. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@21315 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2002-2006, Haiku Inc. All rights reserved.
|
* Copyright 2002-2007, Haiku Inc. All rights reserved.
|
||||||
* Distributed under the terms of the MIT License.
|
* Distributed under the terms of the MIT License.
|
||||||
*
|
*
|
||||||
* Copyright 2001, Thomas Kurschel. All rights reserved.
|
* Copyright 2001, Thomas Kurschel. All rights reserved.
|
||||||
@@ -130,6 +130,7 @@ typedef struct module_iterator {
|
|||||||
uint32 path_base_length;
|
uint32 path_base_length;
|
||||||
const char *current_module_path;
|
const char *current_module_path;
|
||||||
bool builtin_modules;
|
bool builtin_modules;
|
||||||
|
bool loaded_modules;
|
||||||
} module_iterator;
|
} module_iterator;
|
||||||
|
|
||||||
|
|
||||||
@@ -693,31 +694,62 @@ iterator_push_path_on_stack(module_iterator *iterator, const char *path, uint32
|
|||||||
|
|
||||||
|
|
||||||
static status_t
|
static status_t
|
||||||
iterator_get_next_module(module_iterator *iterator, char *buffer, size_t *_bufferSize)
|
iterator_get_next_module(module_iterator *iterator, char *buffer,
|
||||||
|
size_t *_bufferSize)
|
||||||
{
|
{
|
||||||
status_t status;
|
status_t status;
|
||||||
|
|
||||||
TRACE(("iterator_get_next_module() -- start\n"));
|
TRACE(("iterator_get_next_module() -- start\n"));
|
||||||
|
|
||||||
if (iterator->builtin_modules) {
|
if (iterator->builtin_modules) {
|
||||||
int32 i;
|
for (int32 i = iterator->module_offset; sBuiltInModules[i] != NULL; i++) {
|
||||||
|
|
||||||
for (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, iterator->prefix_length))
|
if (strncmp(sBuiltInModules[i]->name, iterator->prefix,
|
||||||
|
iterator->prefix_length))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
*_bufferSize = strlcpy(buffer, sBuiltInModules[i]->name, *_bufferSize);
|
*_bufferSize = strlcpy(buffer, sBuiltInModules[i]->name,
|
||||||
|
*_bufferSize);
|
||||||
iterator->module_offset = i + 1;
|
iterator->module_offset = i + 1;
|
||||||
return B_OK;
|
return B_OK;
|
||||||
}
|
}
|
||||||
iterator->builtin_modules = false;
|
iterator->builtin_modules = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (iterator->loaded_modules) {
|
||||||
|
recursive_lock_lock(&sModulesLock);
|
||||||
|
hash_iterator hashIterator;
|
||||||
|
hash_open(sModulesHash, &hashIterator);
|
||||||
|
|
||||||
|
struct module *module = (struct module *)hash_next(sModulesHash,
|
||||||
|
&hashIterator);
|
||||||
|
for (int32 i = 0; module != NULL; i++) {
|
||||||
|
if (i >= iterator->module_offset) {
|
||||||
|
if (!strncmp(module->name, iterator->prefix,
|
||||||
|
iterator->prefix_length)) {
|
||||||
|
*_bufferSize = strlcpy(buffer, module->name, *_bufferSize);
|
||||||
|
iterator->module_offset = i + 1;
|
||||||
|
|
||||||
|
hash_close(sModulesHash, &hashIterator, false);
|
||||||
|
recursive_lock_unlock(&sModulesLock);
|
||||||
|
return B_OK;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
module = (struct module *)hash_next(sModulesHash, &hashIterator);
|
||||||
|
}
|
||||||
|
|
||||||
|
hash_close(sModulesHash, &hashIterator, false);
|
||||||
|
recursive_lock_unlock(&sModulesLock);
|
||||||
|
|
||||||
|
// prevent from falling into modules hash iteration again
|
||||||
|
iterator->loaded_modules = false;
|
||||||
|
}
|
||||||
|
|
||||||
nextPath:
|
nextPath:
|
||||||
if (iterator->current_dir == NULL) {
|
if (iterator->current_dir == NULL) {
|
||||||
// get next directory path from the stack
|
// get next directory path from the stack
|
||||||
const char *path = iterator_pop_path_from_stack(iterator, &iterator->path_base_length);
|
const char *path = iterator_pop_path_from_stack(iterator,
|
||||||
|
&iterator->path_base_length);
|
||||||
if (path == NULL) {
|
if (path == NULL) {
|
||||||
// we are finished, there are no more entries on the stack
|
// we are finished, there are no more entries on the stack
|
||||||
return B_ENTRY_NOT_FOUND;
|
return B_ENTRY_NOT_FOUND;
|
||||||
@@ -755,7 +787,8 @@ nextModuleImage:
|
|||||||
// check if the prefix matches
|
// check if the prefix matches
|
||||||
int32 passedOffset, commonLength;
|
int32 passedOffset, commonLength;
|
||||||
passedOffset = strlen(iterator->current_path) + 1;
|
passedOffset = strlen(iterator->current_path) + 1;
|
||||||
commonLength = iterator->path_base_length + iterator->prefix_length - passedOffset;
|
commonLength = iterator->path_base_length + iterator->prefix_length
|
||||||
|
- passedOffset;
|
||||||
|
|
||||||
if (commonLength > 0) {
|
if (commonLength > 0) {
|
||||||
// the prefix still reaches into the new path part
|
// the prefix still reaches into the new path part
|
||||||
@@ -763,8 +796,8 @@ nextModuleImage:
|
|||||||
if (commonLength > length)
|
if (commonLength > length)
|
||||||
commonLength = length;
|
commonLength = length;
|
||||||
|
|
||||||
if (strncmp(dirent->d_name,
|
if (strncmp(dirent->d_name, iterator->prefix + passedOffset
|
||||||
iterator->prefix + passedOffset - iterator->path_base_length, commonLength))
|
- iterator->path_base_length, commonLength))
|
||||||
goto nextModuleImage;
|
goto nextModuleImage;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -791,8 +824,8 @@ nextModuleImage:
|
|||||||
return B_NO_MEMORY;
|
return B_NO_MEMORY;
|
||||||
|
|
||||||
if (S_ISDIR(st.st_mode)) {
|
if (S_ISDIR(st.st_mode)) {
|
||||||
status = iterator_push_path_on_stack(iterator, iterator->current_module_path,
|
status = iterator_push_path_on_stack(iterator,
|
||||||
iterator->path_base_length);
|
iterator->current_module_path, iterator->path_base_length);
|
||||||
if (status < B_OK)
|
if (status < B_OK)
|
||||||
return status;
|
return status;
|
||||||
|
|
||||||
@@ -1058,12 +1091,6 @@ module_init(kernel_args *args)
|
|||||||
* 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().
|
||||||
*
|
|
||||||
* During early boot, when there is no boot device accessible,
|
|
||||||
* it will only find built-in modules, not those that have
|
|
||||||
* been preloaded - use get_next_loaded_module_name() instead
|
|
||||||
* if you need to have a list of loaded modules.
|
|
||||||
* ToDo: this could be changed
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
void *
|
void *
|
||||||
@@ -1085,36 +1112,45 @@ open_module_list(const char *prefix)
|
|||||||
|
|
||||||
memset(iterator, 0, sizeof(module_iterator));
|
memset(iterator, 0, sizeof(module_iterator));
|
||||||
|
|
||||||
// ToDo: possibly, the prefix don't have to be copied, just referenced
|
iterator->prefix = strdup(prefix != NULL ? prefix : "");
|
||||||
iterator->prefix = strdup(prefix ? prefix : "");
|
|
||||||
if (iterator->prefix == NULL) {
|
if (iterator->prefix == NULL) {
|
||||||
free(iterator);
|
free(iterator);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
iterator->prefix_length = strlen(prefix);
|
iterator->prefix_length = strlen(iterator->prefix);
|
||||||
|
|
||||||
// first, we'll traverse over the built-in modules
|
if (gBootDevice > 0) {
|
||||||
iterator->builtin_modules = true;
|
// We do have a boot device to scan
|
||||||
|
|
||||||
// put all search paths on the stack
|
// first, we'll traverse over the built-in modules
|
||||||
for (i = 0; i < NUM_MODULE_PATHS; i++) {
|
iterator->builtin_modules = true;
|
||||||
if (sDisableUserAddOns && i >= FIRST_USER_MODULE_PATH)
|
iterator->loaded_modules = false;
|
||||||
break;
|
|
||||||
|
|
||||||
// Build path component: base path + '/' + prefix
|
// put all search paths on the stack
|
||||||
size_t length = strlen(sModulePaths[i]);
|
for (i = 0; i < NUM_MODULE_PATHS; i++) {
|
||||||
char *path = (char *)malloc(length + iterator->prefix_length + 2);
|
if (sDisableUserAddOns && i >= FIRST_USER_MODULE_PATH)
|
||||||
if (path == NULL) {
|
break;
|
||||||
// ToDo: should we abort the whole operation here?
|
|
||||||
// if we do, don't forget to empty the stack
|
// Build path component: base path + '/' + prefix
|
||||||
continue;
|
size_t length = strlen(sModulePaths[i]);
|
||||||
|
char *path = (char *)malloc(length + iterator->prefix_length + 2);
|
||||||
|
if (path == NULL) {
|
||||||
|
// ToDo: should we abort the whole operation here?
|
||||||
|
// if we do, don't forget to empty the stack
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
memcpy(path, sModulePaths[i], length);
|
||||||
|
path[length] = '/';
|
||||||
|
memcpy(path + length + 1, iterator->prefix,
|
||||||
|
iterator->prefix_length + 1);
|
||||||
|
|
||||||
|
iterator_push_path_on_stack(iterator, path, length + 1);
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
memcpy(path, sModulePaths[i], length);
|
// include loaded modules in case there is no boot device yet
|
||||||
path[length] = '/';
|
iterator->builtin_modules = false;
|
||||||
memcpy(path + length + 1, prefix, iterator->prefix_length + 1);
|
iterator->loaded_modules = true;
|
||||||
|
|
||||||
iterator_push_path_on_stack(iterator, path, length + 1);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return (void *)iterator;
|
return (void *)iterator;
|
||||||
@@ -1158,7 +1194,7 @@ close_module_list(void *cookie)
|
|||||||
|
|
||||||
|
|
||||||
/** Return the next module name from the available list, using
|
/** Return the next module name from the available list, using
|
||||||
* a structure previously created by a call to open_module_list.
|
* a structure previously created by a call to open_module_list().
|
||||||
* Returns B_OK as long as it found another module, B_ENTRY_NOT_FOUND
|
* Returns B_OK as long as it found another module, B_ENTRY_NOT_FOUND
|
||||||
* when done.
|
* when done.
|
||||||
*/
|
*/
|
||||||
@@ -1222,6 +1258,8 @@ get_next_loaded_module_name(uint32 *_cookie, char *buffer, size_t *_bufferSize)
|
|||||||
|
|
||||||
recursive_lock_lock(&sModulesLock);
|
recursive_lock_lock(&sModulesLock);
|
||||||
|
|
||||||
|
// TODO: this is completely unsafe!!!
|
||||||
|
|
||||||
struct module *module = (struct module *)hash_next(sModulesHash, iterator);
|
struct module *module = (struct module *)hash_next(sModulesHash, iterator);
|
||||||
if (module != NULL) {
|
if (module != NULL) {
|
||||||
*_bufferSize = strlcpy(buffer, module->name, *_bufferSize);
|
*_bufferSize = strlcpy(buffer, module->name, *_bufferSize);
|
||||||
|
|||||||
Reference in New Issue
Block a user