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);
}
Exemple #2
0
/* 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);
}