void ast_optional_api_unuse(const char *symname, ast_optional_fn *optional_ref, const char *module) { struct optional_api *api; size_t i; api = get_api(symname); if (!api) { ast_log(LOG_ERROR, "%s: Could not find api\n", symname); ast_do_crash(); return; } for (i = 0; i < api->users_len; ++i) { struct optional_api_user *user = api->users[i]; if (user->optional_ref == optional_ref) { if (*user->optional_ref != user->stub) { *user->optional_ref = user->stub; } /* Remove from the list */ api->users[i] = api->users[--api->users_len]; optional_api_user_destroy(user); return; } } ast_log(LOG_ERROR, "%s: Could not find user %s\n", symname, module); }
/* Allocate a library table entry and load the library information from it. If * library is NULL, try to load the current executable instead. */ static int load_library(DrewLoader *ldr, const char *library, const char *path, library_t **libp) { int err = 0; library_t *p, *lib; p = g_realloc(ldr->lib, sizeof(*p) * (ldr->nlibs + 1)); if (!p) return -ENOMEM; if (p != ldr->lib) { // Fix up the lib pointers in the plugins. for (int i = 0; i < ldr->nplugins; i++) ldr->plugin[i].lib = p + (ldr->plugin[i].lib - ldr->lib); } ldr->lib = p; lib = &ldr->lib[ldr->nlibs]; memset(lib, 0, sizeof(*lib)); ldr->nlibs++; if (!library) { err = -DREW_ERR_RESOLUTION; if (!(lib->handle = open_library(NULL))) goto out; lib->name = g_strdup("<internal>"); lib->path = NULL; } else { err = -ENOMEM; if (!(lib->path = g_strdup_printf("%s/%s", path, library))) goto out; // TODO: query this from the library. lib->name = g_strdup(library); err = -DREW_ERR_RESOLUTION; if (!(lib->handle = open_library(lib->path))) goto out; } err = -DREW_ERR_ENUMERATION; if (!(lib->api = get_api(lib->handle))) goto out; err = 0; *libp = lib; out: if (err) { if (lib->handle) close_library(lib->handle); g_free(lib->name); g_free(lib->path); lib->path = NULL; ldr->nlibs--; } return err; }
void ast_optional_api_unprovide(const char *symname, ast_optional_fn impl) { struct optional_api *api; api = get_api(symname); if (!api) { ast_log(LOG_ERROR, "%s: Could not find api\n", symname); ast_do_crash(); return; } optional_api_set_impl(api, 0); }
void ast_optional_api_provide(const char *symname, ast_optional_fn impl) { struct optional_api *api; api = get_api(symname); if (!api) { ast_log(LOG_ERROR, "%s: Allocation failed\n", symname); ast_do_crash(); return; } optional_api_set_impl(api, impl); }
void ast_optional_api_use(const char *symname, ast_optional_fn *optional_ref, ast_optional_fn stub, const char *module) { struct optional_api_user *user; struct optional_api *api; api = get_api(symname); if (!api) { ast_log(LOG_ERROR, "%s: Allocation failed\n", symname); ast_do_crash(); return; } user = optional_api_user_create(optional_ref, stub, module); if (!user) { ast_log(LOG_ERROR, "%s: Allocation failed\n", symname); ast_do_crash(); return; } /* Add user to the API */ if (api->users_len + 1 > api->users_maxlen) { size_t new_maxlen = api->users_maxlen ? 2 * api->users_maxlen : 1; struct optional_api_user **new_list; new_list = ast_std_realloc(api->users, new_maxlen * sizeof(*new_list)); if (!new_list) { optional_api_user_destroy(user); ast_log(LOG_ERROR, "Failed to allocate api list\n"); ast_do_crash(); return; } api->users_maxlen = new_maxlen; api->users = new_list; } api->users[api->users_len++] = user; optional_api_user_relink(user, api); }