read_next_module_name() & co now works fine from userland too.

To test, just compile a kernel module against this app, and put
it under ./add-ons/network/...
It support system and home add-ons/network/... too.
These modules kernel functions are now re-implemented for userland:
get_module()
put_module()
open_module_list()
read_next_module_name()
close_module_list()
get_next_loaded_module_name()


git-svn-id: file:///srv/svn/repos/haiku/trunk/current@1725 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Philippe Houdoin 2002-10-28 01:35:59 +00:00
parent a44a6ed6d0
commit a098bed826
1 changed files with 154 additions and 34 deletions

View File

@ -13,6 +13,7 @@
#include <storage/StorageDefs.h>
#include <storage/FindDirectory.h>
#include <storage/Path.h>
#include <storage/Directory.h>
#define ASSERT(condition) if (!(condition)) { debugger("Assertion failed!"); }
@ -47,7 +48,12 @@ typedef struct module_addon {
typedef struct module_list_cookie {
char * prefix;
// TODO
char * search_paths;
char * search_path;
char * next_path_token;
BList * dir_stack;
module_addon * ma; // current module addon looked up
module_info ** mi; // current module addon module info
} module_list_cookie;
#define LOCK_MODULES acquire_sem(g_modules_lock)
@ -178,6 +184,7 @@ status_t get_next_loaded_module_name(uint32 *cookie, char *buf, size_t *bufsize)
void * open_module_list(const char *prefix)
{
module_list_cookie * mlc;
char * addon_path;
if (prefix == NULL)
return NULL;
@ -185,6 +192,13 @@ void * open_module_list(const char *prefix)
mlc = (module_list_cookie *) malloc(sizeof(*mlc));
mlc->prefix = strdup(prefix);
addon_path = getenv("ADDON_PATH");
mlc->search_paths = (addon_path ? strdup(addon_path) : NULL);
mlc->search_path = strtok_r(mlc->search_paths, ":", &mlc->next_path_token);
mlc->dir_stack = new BList();
mlc->ma = NULL;
mlc->mi = NULL;
return mlc;
}
@ -193,10 +207,97 @@ status_t read_next_module_name(void *cookie, char *buf, size_t *bufsize)
{
module_list_cookie * mlc = (module_list_cookie *) cookie;
if (!bufsize)
return B_BAD_VALUE;
if (!mlc)
return B_BAD_VALUE;
// TODO
if (mlc->ma && mlc->mi) {
// we have a module addon loaded, so keep looking at his exported module names
while (*mlc->mi) {
module_info * mi = *mlc->mi;
mlc->mi++;
if(strstr(mi->name, mlc->prefix)) {
if (buf) strncpy(buf, mi->name, *bufsize);
*bufsize = strlen(mi->name);
return B_OK;
};
};
unload_module_addon(mlc->ma);
mlc->ma = NULL;
mlc->mi = NULL;
};
while (mlc->search_path) {
BDirectory * dir;
BEntry entry;
BPath path;
status_t status;
dir = (BDirectory *) mlc->dir_stack->LastItem();
if (!dir) {
if (strncmp(mlc->search_path, "%A/", 3) == 0) {
// compute "%A/..." path
app_info ai;
be_app->GetAppInfo(&ai);
entry.SetTo(&ai.ref);
entry.GetPath(&path);
path.GetParent(&path);
path.Append(mlc->search_path + 3);
} else {
path.SetTo(mlc->search_path);
};
path.Append(mlc->prefix);
printf("Looking module(s) in %s/%s...\n", mlc->search_path, mlc->prefix);
dir = new BDirectory(path.Path());
if (dir)
mlc->dir_stack->AddItem(dir);
};
if (dir) {
while (dir->GetNextEntry(&entry) == B_OK) {
entry.GetPath(&path);
// printf(" %s ?\n", path.Path());
if (entry.IsDirectory()) {
BDirectory * subdir;
// push this directory on dir_stack
subdir = new BDirectory(path.Path());
if (!subdir)
continue;
mlc->dir_stack->AddItem(subdir);
// recursivly search this sub-directory
return read_next_module_name(cookie, buf, bufsize);
};
if (entry.IsFile()) {
mlc->ma = load_module_addon(path.Path());
if (!mlc->ma)
// Oh-oh, not a loadable module addon!?
continue;
mlc->mi = mlc->ma->infos;
return read_next_module_name(cookie, buf, bufsize);
};
};
status = mlc->dir_stack->RemoveItem(dir);
delete dir;
};
if (!mlc->dir_stack->IsEmpty())
continue;
mlc->search_path = strtok_r(NULL, ":", &mlc->next_path_token);
};
// Module(s) list search done, ending...
return B_ERROR;
}
@ -204,17 +305,28 @@ status_t read_next_module_name(void *cookie, char *buf, size_t *bufsize)
status_t close_module_list(void *cookie)
{
module_list_cookie * mlc = (module_list_cookie *) cookie;
BDirectory * dir;
ASSERT(mlc);
ASSERT(mlc->prefix);
if (mlc->ma)
unload_module_addon(mlc->ma);
while((dir = (BDirectory *) mlc->dir_stack->FirstItem())) {
mlc->dir_stack->RemoveItem(dir);
delete dir;
};
delete mlc->dir_stack;
free(mlc->search_paths);
free(mlc->prefix);
free(mlc);
return B_ERROR;
}
// #pragma mark -
// Private routines
@ -227,17 +339,20 @@ static module_addon * load_module_addon(const char * path)
ASSERT(path);
printf("Loading %s addon\n", path);
addon_id = load_add_on(path);
if (addon_id < 0)
if (addon_id < 0) {
printf("Failed to load %s addon: %s.\n", path, strerror(addon_id));
return NULL;
};
// printf("Addon %s loaded.\n", path);
ma = NULL;
status = get_image_symbol(addon_id, "modules", B_SYMBOL_TYPE_DATA, (void **) &mi);
if (status != B_OK) {
// No "modules" symbol found in this addon
printf("No \"modules\" symbol found in %s addon: not a module addon!\n", path);
printf("Symbol \"modules\" not found in %s addon: not a module addon!\n", path);
goto error;
};
@ -324,8 +439,8 @@ error:
free(ma);
};
printf("Unloading %s addon\n", path);
unload_add_on(addon_id);
printf("Addon %s unloaded.\n", path);
return NULL;
}
@ -348,16 +463,15 @@ static status_t unload_module_addon(module_addon * ma)
return B_OK;
if (ma->addon_image < 0)
// built-in addon, it seems...
return B_OK;
status = B_ERROR;
printf("Unloading %s addon\n", ma->path);
status = unload_add_on(ma->addon_image);
if (status != B_OK) {
printf("unload_add_on(%ld -> %s) failed: %ld!\n", ma->addon_image, ma->path, status);
printf("Failed to unload %s addon: %s.\n", ma->path, strerror(status));
return status;
};
// printf("Addon %s unloaded.\n", ma->path);
LOCK_MODULES;
@ -413,36 +527,37 @@ static module * search_module(const char * name)
BPath path;
BPath addons_path;
BEntry entry;
int i;
module * found_module;
directory_which addons_paths[] = {
(directory_which) -2, // APP_ADDONS_DIRECTORY
B_USER_ADDONS_DIRECTORY,
// B_COMMON_ADDONS_DIRECTORY,
B_BEOS_ADDONS_DIRECTORY,
(directory_which) -1
};
char * search_paths;
char * search_path;
char * next_path_token;
printf("search_module(%s):\n", name);
search_paths = getenv("ADDON_PATH");
if (!search_paths)
// Nowhere to search addons!!!
return NULL;
search_paths = strdup(search_paths);
search_path = strtok_r(search_paths, ":", &next_path_token);
found_module = NULL;
for (i = 0; addons_paths[i] != -1 && found_module == NULL; i++) {
if (addons_paths[i] == -2) {
// compute "%A/add-ons" path
while (search_path && found_module == NULL) {
if (strncmp(search_path, "%A/", 3) == 0) {
// compute "%A/..." path
app_info ai;
be_app->GetAppInfo(&ai);
entry.SetTo(&ai.ref);
entry.GetPath(&addons_path);
addons_path.GetParent(&addons_path);
addons_path.Append("add-ons");
addons_path.Append(search_path + 3);
} else {
// try in "net_server" subfolder of officials add-ons repositories
if (find_directory(addons_paths[i], &addons_path, false, NULL) != B_OK)
continue;
addons_path.Append("net_server");
addons_path.SetTo(search_path);
};
printf("Looking into %s\n", addons_path.Path());
printf("Looking into %s\n", search_path);
path.SetTo(addons_path.Path());
path.Append(name);
@ -467,8 +582,12 @@ static module * search_module(const char * name)
// okay, remove the current path leaf and try again...
path.GetParent(&path);
};
search_path = strtok_r(NULL, ":", &next_path_token);
};
free(search_paths);
if (found_module)
printf(" Found it in %s addon module!\n",
found_module->addon ? found_module->addon->path : "BUILTIN");
@ -592,7 +711,7 @@ static module * find_loaded_module_by_id(uint32 id)
#define NET_ETHERNET_MODULE_NAME "network/interfaces/ethernet"
#define NET_IPV4_MODULE_NAME "network/protocols/ipv4/v1"
#define MODULE_LIST_PREFIX "network/protocols"
#define MODULE_LIST_PREFIX "network"
int main(int argc, char **argv)
{
@ -610,12 +729,13 @@ int main(int argc, char **argv)
ml_cookie = open_module_list(MODULE_LIST_PREFIX);
sz = sizeof(module_name);
while(read_next_module_name(ml_cookie, module_name, &sz) == B_OK) {
if (strlen(module_name))
printf(" %s\n", module_name);
sz = sizeof(module_name);
};
close_module_list(ml_cookie);
printf("close_module_list()\n");
// return 0;
core = NULL;
get_module(NET_CORE_MODULE_NAME, (module_info **) &core);