afb-export: Manage path of libraries 63/15963/1
authorJosé Bollo <jose.bollo@iot.bzh>
Thu, 2 Aug 2018 13:26:59 +0000 (15:26 +0200)
committerJosé Bollo <jose.bollo@iot.bzh>
Thu, 2 Aug 2018 13:49:43 +0000 (15:49 +0200)
This change allows a binding to know its
installation path. This path is retrieved using
the api function 'afb_api_settings'.
The path is returned --if known-- as a string
of key "binding-path".

Change-Id: Ie1a349dc4936d4ccf173f1f77e118099f7f0599a
Signed-off-by: José Bollo <jose.bollo@iot.bzh>
src/afb-api-so-v1.c
src/afb-api-so-v2.c
src/afb-api-so-v2.h
src/afb-api-so-v3.c
src/afb-api-v3.c
src/afb-api-v3.h
src/afb-export.c
src/afb-export.h
src/tests/apiv3/test-apiv3.c

index c7b40e8..b68d064 100644 (file)
@@ -164,7 +164,7 @@ int afb_api_so_v1_add(const char *path, void *handle, struct afb_apiset *declare
        /* allocates the description */
        init = dlsym(handle, afb_api_so_v1_service_init);
        onevent = dlsym(handle, afb_api_so_v1_service_event);
-       export = afb_export_create_v1(declare_set, call_set, path, init, onevent);
+       export = afb_export_create_v1(declare_set, call_set, path, init, onevent, path);
        if (export == NULL) {
                ERROR("binding [%s] creation failure...", path);
                goto error;
index 3910788..deb8783 100644 (file)
@@ -130,7 +130,13 @@ static void do_preinit(int sig, void *closure)
        }
 };
 
-int afb_api_so_v2_add_binding(const struct afb_binding_v2 *binding, void *handle, struct afb_apiset *declare_set, struct afb_apiset * call_set, struct afb_binding_data_v2 *data)
+int afb_api_so_v2_add_binding(
+               const struct afb_binding_v2 *binding,
+               void *handle,
+               struct afb_apiset *declare_set,
+               struct afb_apiset * call_set,
+               struct afb_binding_data_v2 *data,
+               const char *path)
 {
        int rc;
        struct afb_export *export;
@@ -143,7 +149,7 @@ int afb_api_so_v2_add_binding(const struct afb_binding_v2 *binding, void *handle
        assert(data);
 
        /* allocates the description */
-       export = afb_export_create_v2(declare_set, call_set, binding->api, binding, data, binding->init, binding->onevent);
+       export = afb_export_create_v2(declare_set, call_set, binding->api, binding, data, binding->init, binding->onevent, path);
        if (!export) {
                ERROR("out of memory");
                goto error;
@@ -209,7 +215,7 @@ int afb_api_so_v2_add(const char *path, void *handle, struct afb_apiset *declare
                goto error;
        }
 
-       return afb_api_so_v2_add_binding(binding, handle, declare_set, call_set, data);
+       return afb_api_so_v2_add_binding(binding, handle, declare_set, call_set, data, path);
 
  error:
        return -1;
index d53206d..c51ec59 100644 (file)
@@ -25,7 +25,7 @@ struct afb_xreq;
 struct json_object;
 
 extern int afb_api_so_v2_add(const char *path, void *handle, struct afb_apiset *declare_set, struct afb_apiset * call_set);
-extern int afb_api_so_v2_add_binding(const struct afb_binding_v2 *binding, void *handle, struct afb_apiset *declare_set, struct afb_apiset * call_set, struct afb_binding_data_v2 *data);
+extern int afb_api_so_v2_add_binding(const struct afb_binding_v2 *binding, void *handle, struct afb_apiset *declare_set, struct afb_apiset * call_set, struct afb_binding_data_v2 *data, const char *path);
 
 extern void afb_api_so_v2_process_call(const struct afb_binding_v2 *binding, struct afb_xreq *xreq);
 extern struct json_object *afb_api_so_v2_make_description_openAPIv3(const struct afb_binding_v2 *binding, const char *apiname);
index b02f3c8..373386e 100644 (file)
@@ -105,7 +105,7 @@ int afb_api_so_v3_add(const char *path, void *handle, struct afb_apiset *declare
                        goto error;
                }
 
-               api = afb_api_v3_create(declare_set, call_set, a.desc->api, a.desc->info, a.desc->noconcurrency, init, &a, 0);
+               api = afb_api_v3_create(declare_set, call_set, a.desc->api, a.desc->info, a.desc->noconcurrency, init, &a, 0, NULL, path);
                if (api)
                        return 1;
        } else {
@@ -116,8 +116,10 @@ int afb_api_so_v3_add(const char *path, void *handle, struct afb_apiset *declare
                }
 
                export = afb_export_create_none_for_path(declare_set, call_set, path, init, &a);
-               if (export)
+               if (export) {
+                       afb_export_unref(export);
                        return 1;
+               }
        }
 
        ERROR("binding [%s] initialisation failed", path);
index 7f63b6e..660fac1 100644 (file)
@@ -179,16 +179,16 @@ struct json_object *afb_api_v3_make_description_openAPIv3(struct afb_api_v3 *api
        return r;
 }
 
-struct afb_api_v3 *afb_api_v3_create(
-               struct afb_apiset *declare_set,
+struct afb_api_v3 *afb_api_v3_create(struct afb_apiset *declare_set,
                struct afb_apiset *call_set,
                const char *apiname,
                const char *info,
                int noconcurrency,
                int (*preinit)(void*, struct afb_api_x3 *),
                void *closure,
-               int copy_info
-)
+               int copy_info,
+               struct afb_export* creator,
+               const char* path)
 {
        struct afb_api_v3 *api;
 
@@ -206,7 +206,7 @@ struct afb_api_v3 *afb_api_v3_create(
        else
                api->info = info;
 
-       api->export = afb_export_create_v3(declare_set, call_set, apiname, api);
+       api->export = afb_export_create_v3(declare_set, call_set, apiname, api, creator, path);
        if (!api->export)
                goto oom2;
 
@@ -400,6 +400,6 @@ static int init_binding(void *closure, struct afb_api_x3 *api)
 
 struct afb_api_v3 *afb_api_v3_from_binding(const struct afb_binding_v3 *desc, struct afb_apiset *declare_set, struct afb_apiset * call_set)
 {
-       return afb_api_v3_create(declare_set, call_set, desc->api, desc->info, desc->noconcurrency, init_binding, (void*)desc, 0);
+       return afb_api_v3_create(declare_set, call_set, desc->api, desc->info, desc->noconcurrency, init_binding, (void*)desc, 0, NULL, NULL);
 }
 
index 04d9124..2ba17bd 100644 (file)
@@ -30,16 +30,16 @@ struct afb_xreq;
 struct json_object;
 struct afb_export;
 
-extern struct afb_api_v3 *afb_api_v3_create(
-               struct afb_apiset *declare_set,
+extern struct afb_api_v3 *afb_api_v3_create(struct afb_apiset *declare_set,
                struct afb_apiset *call_set,
                const char *apiname,
                const char *info,
                int noconcurrency,
                int (*preinit)(void*, struct afb_api_x3 *),
                void *closure,
-               int copy_info
-);
+               int copy_info,
+               struct afb_export* creator,
+               const char* path);
 
 extern struct afb_api_v3 *afb_api_v3_from_binding(
                const struct afb_binding_v3 *desc,
index c1a716f..3afd8c1 100644 (file)
@@ -140,6 +140,12 @@ struct afb_export
        /* event handler list */
        struct event_handler *event_handlers;
 
+       /* creator if any */
+       struct afb_export *creator;
+
+       /* path indication if any */
+       const char *path;
+
        /* settings */
        struct json_object *settings;
 
@@ -218,19 +224,28 @@ void afb_export_set_config(struct json_object *config)
        json_object_put(save);
 }
 
-static struct json_object *get_settings(const char *name)
+static struct json_object *make_settings(struct afb_export *export)
 {
        struct json_object *result;
        struct json_object *obj;
+       struct afb_export *iter;
 
+       /* clone the globals */
        if (json_object_object_get_ex(configuration, "*", &obj))
                result = wrap_json_clone(obj);
        else
                result = json_object_new_object();
 
-       if (json_object_object_get_ex(configuration, name, &obj))
+       /* add locals */
+       if (json_object_object_get_ex(configuration, export->name, &obj))
                wrap_json_object_add(result, obj);
 
+       /* add library path */
+       for (iter = export ; iter && !iter->path ; iter = iter->creator);
+       if (iter)
+               json_object_object_add(result, "binding-path", json_object_new_string(iter->path));
+
+       export->settings = result;
        return result;
 }
 
@@ -385,7 +400,11 @@ static struct afb_api_x3 *api_new_api_cb(
                void *preinit_closure)
 {
        struct afb_export *export = from_api_x3(closure);
-       struct afb_api_v3 *apiv3 = afb_api_v3_create(export->declare_set, export->call_set, api, info, noconcurrency, preinit, preinit_closure, 1);
+       struct afb_api_v3 *apiv3 = afb_api_v3_create(
+                                       export->declare_set, export->call_set,
+                                       api, info, noconcurrency,
+                                       preinit, preinit_closure, 1,
+                                       export, NULL);
        return apiv3 ? to_api_x3(afb_api_v3_export(apiv3)) : NULL;
 }
 
@@ -910,10 +929,8 @@ static struct json_object *settings_cb(struct afb_api_x3 *api)
 {
        struct afb_export *export = from_api_x3(api);
        struct json_object *result = export->settings;
-       if (!result) {
-               result = get_settings(export->name);
-               export->settings = result;
-       }
+       if (!result)
+               result = make_settings(export);
        return result;
 }
 
@@ -1272,9 +1289,11 @@ static struct afb_export *create(
                                struct afb_apiset *declare_set,
                                struct afb_apiset *call_set,
                                const char *apiname,
+                               const char *path,
                                enum afb_api_version version)
 {
        struct afb_export *export;
+       size_t lenapi;
 
        /* session shared with other exports */
        if (common_session == NULL) {
@@ -1282,13 +1301,18 @@ static struct afb_export *create(
                if (common_session == NULL)
                        return NULL;
        }
-       export = calloc(1, sizeof *export + strlen(apiname));
+       lenapi = strlen(apiname);
+       export = calloc(1, sizeof *export + lenapi + (path == apiname || !path ? 0 : strlen(path)));
        if (!export)
                errno = ENOMEM;
        else {
                export->refcount = 1;
                strcpy(export->name, apiname);
                export->api.apiname = export->name;
+               if (path == apiname)
+                       export->path = export->name;
+               else if (path)
+                       export->path = strcpy(&export->name[lenapi + 1], path);
                export->version = version;
                export->state = Api_State_Pre_Init;
                export->session = afb_session_addref(common_session);
@@ -1325,9 +1349,10 @@ void afb_export_destroy(struct afb_export *export)
                afb_session_unref(export->session);
                afb_apiset_unref(export->declare_set);
                afb_apiset_unref(export->call_set);
+               json_object_put(export->settings);
+               afb_export_unref(export->creator);
                if (export->api.apiname != export->name)
                        free((void*)export->api.apiname);
-               json_object_put(export->settings);
                free(export);
        }
 }
@@ -1339,7 +1364,7 @@ struct afb_export *afb_export_create_none_for_path(
                        int (*creator)(void*, struct afb_api_x3*),
                        void *closure)
 {
-       struct afb_export *export = create(declare_set, call_set, path, Api_Version_None);
+       struct afb_export *export = create(declare_set, call_set, path, path, Api_Version_None);
        if (export) {
                afb_export_logmask_set(export, logmask);
                afb_export_update_hooks(export);
@@ -1352,14 +1377,14 @@ struct afb_export *afb_export_create_none_for_path(
 }
 
 #if defined(WITH_LEGACY_BINDING_V1)
-struct afb_export *afb_export_create_v1(
-                       struct afb_apiset *declare_set,
+struct afb_export *afb_export_create_v1(struct afb_apiset *declare_set,
                        struct afb_apiset *call_set,
                        const char *apiname,
                        int (*init)(struct afb_service_x1),
-                       void (*onevent)(const char*, struct json_object*))
+                       void (*onevent)(const char*, struct json_object*),
+                       const char* path)
 {
-       struct afb_export *export = create(declare_set, call_set, apiname, Api_Version_1);
+       struct afb_export *export = create(declare_set, call_set, apiname, path, Api_Version_1);
        if (export) {
                export->init.v1 = init;
                export->on_any_event_v12 = onevent;
@@ -1372,16 +1397,16 @@ struct afb_export *afb_export_create_v1(
 }
 #endif
 
-struct afb_export *afb_export_create_v2(
-                       struct afb_apiset *declare_set,
+struct afb_export *afb_export_create_v2(struct afb_apiset *declare_set,
                        struct afb_apiset *call_set,
                        const char *apiname,
                        const struct afb_binding_v2 *binding,
                        struct afb_binding_data_v2 *data,
                        int (*init)(),
-                       void (*onevent)(const char*, struct json_object*))
+                       void (*onevent)(const char*, struct json_object*),
+                       const char* path)
 {
-       struct afb_export *export = create(declare_set, call_set, apiname, Api_Version_2);
+       struct afb_export *export = create(declare_set, call_set, apiname, path, Api_Version_2);
        if (export) {
                export->init.v2 = init;
                export->on_any_event_v12 = onevent;
@@ -1398,12 +1423,15 @@ struct afb_export *afb_export_create_v2(
 struct afb_export *afb_export_create_v3(struct afb_apiset *declare_set,
                        struct afb_apiset *call_set,
                        const char *apiname,
-                       struct afb_api_v3 *apiv3)
+                       struct afb_api_v3 *apiv3,
+                       struct afb_export* creator,
+                       const char* path)
 {
-       struct afb_export *export = create(declare_set, call_set, apiname, Api_Version_3);
+       struct afb_export *export = create(declare_set, call_set, apiname, path, Api_Version_3);
        if (export) {
                export->unsealed = 1;
                export->desc.v3 = apiv3;
+               export->creator = afb_export_addref(creator);
                afb_export_logmask_set(export, logmask);
                afb_export_update_hooks(export);
        }
@@ -1794,7 +1822,7 @@ int afb_export_declare(struct afb_export *export,
                        ERROR("can't declare export %s to set %s, ABORTING it!",
                                export->api.apiname,
                                afb_apiset_name(export->declare_set));
-                       afb_export_addref(export);
+                       afb_export_unref(export);
                }
        }
 
index 0bee174..33b9491 100644 (file)
@@ -39,19 +39,21 @@ extern struct afb_export *afb_export_create_none_for_path(
                                int (*creator)(void*, struct afb_api_x3*),
                                void *closure);
 
-extern struct afb_export *afb_export_create_v2(
-                               struct afb_apiset *declare_set,
+extern struct afb_export *afb_export_create_v2(struct afb_apiset *declare_set,
                                struct afb_apiset *call_set,
                                const char *apiname,
                                const struct afb_binding_v2 *binding,
                                struct afb_binding_data_v2 *data,
                                int (*init)(),
-                               void (*onevent)(const char*, struct json_object*));
+                               void (*onevent)(const char*, struct json_object*),
+                               const char* path);
 
 extern struct afb_export *afb_export_create_v3(struct afb_apiset *declare_set,
                                struct afb_apiset *call_set,
                                const char *apiname,
-                               struct afb_api_v3 *api);
+                               struct afb_api_v3 *api,
+                               struct afb_export* creator,
+                               const char* path);
 
 extern struct afb_export *afb_export_addref(struct afb_export *export);
 extern void afb_export_unref(struct afb_export *export);
@@ -118,12 +120,12 @@ extern struct afb_api_x3 *afb_export_to_api_x3(struct afb_export *export);
 struct afb_service_x1;
 struct afb_binding_interface_v1;
 
-extern struct afb_export *afb_export_create_v1(
-                               struct afb_apiset *declare_set,
+extern struct afb_export *afb_export_create_v1(struct afb_apiset *declare_set,
                                struct afb_apiset *call_set,
                                const char *apiname,
                                int (*init)(struct afb_service_x1),
-                               void (*onevent)(const char*, struct json_object*));
+                               void (*onevent)(const char*, struct json_object*),
+                               const char* path);
 
 extern struct afb_binding_v1 *afb_export_register_v1(
                                struct afb_export *export,
index 9a06bcb..1472e70 100644 (file)
@@ -151,16 +151,16 @@ START_TEST (test)
        apiset = afb_apiset_create("test-apiv3", 1);
        ck_assert_ptr_nonnull(apiset);
 
-       out_v3 = afb_api_v3_create(
-               apiset,
+       out_v3 = afb_api_v3_create(apiset,
                apiset,
                out_apiname,
                NULL,
                0,
                out_preinit,
                out_apiname,
-               0
-       );
+               0,
+               NULL,
+               NULL);
        ck_assert_ptr_nonnull(out_v3);
        ck_assert_ptr_nonnull(out_api);