consider an extra icon_path for only RO package
[platform/core/appfw/pkgmgr-info.git] / src / pkgmgrinfo_client.c
1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <dlfcn.h>
4
5 #include <dbus/dbus.h>
6 #include <dbus/dbus-glib-lowlevel.h>
7
8 #include "pkgmgrinfo_type.h"
9 #include "pkgmgrinfo_debug.h"
10 #include "pkgmgrinfo_private.h"
11
12 API pkgmgrinfo_client *pkgmgrinfo_client_new(pkgmgrinfo_client_type ctype)
13 {
14         char *errmsg;
15         void *pc = NULL;
16         void *handle;
17         pkgmgrinfo_client *(*__pkgmgr_client_new)(pkgmgrinfo_client_type ctype) = NULL;
18
19         handle = dlopen("libpkgmgr-client.so.0", RTLD_LAZY | RTLD_GLOBAL);
20         retvm_if(!handle, NULL, "dlopen() failed. [%s]", dlerror());
21
22         __pkgmgr_client_new = dlsym(handle, "pkgmgr_client_new");
23         errmsg = dlerror();
24         trym_if((errmsg != NULL) || (__pkgmgr_client_new == NULL), "dlsym() failed. [%s]", errmsg);
25
26         pc = __pkgmgr_client_new(ctype);
27         trym_if(pc == NULL, "pkgmgr_client_new failed.");
28
29 catch:
30         dlclose(handle);
31         return (pkgmgrinfo_client *) pc;
32 }
33
34 API int pkgmgrinfo_client_set_status_type(pkgmgrinfo_client *pc, int status_type)
35 {
36         int ret;
37         char *errmsg;
38         void *handle;
39         int (*__pkgmgr_client_set_status_type)(pkgmgrinfo_client *pc, int status_type) = NULL;
40
41         handle = dlopen("libpkgmgr-client.so.0", RTLD_LAZY | RTLD_GLOBAL);
42         retvm_if(!handle, PMINFO_R_ERROR, "dlopen() failed. [%s]", dlerror());
43
44         __pkgmgr_client_set_status_type = dlsym(handle, "pkgmgr_client_set_status_type");
45         errmsg = dlerror();
46         tryvm_if((errmsg != NULL) || (__pkgmgr_client_set_status_type == NULL), ret = PMINFO_R_ERROR, "dlsym() failed. [%s]", errmsg);
47
48         ret = __pkgmgr_client_set_status_type(pc, status_type);
49         tryvm_if(ret < 0, ret = PMINFO_R_ERROR, "pkgmgr_client_new failed.");
50
51 catch:
52         /*
53          * Do not close libpkgmgr-client.so.0 to avoid munmap registered callback
54          *
55          * The lib dependency chain like below
56          * amd --> pkgmgr-info -- dlopen --> libpkgmgr-client --> libpkgmgr-installer-client
57          *
58          * And there is a function in libpkgmgr-installer-client named _on_signal_handle_filter()
59          * which will registered to dbus callback in amd though in fact amd doesn't direct depends
60          * on libpkgmgr-installer-client.
61          *
62          * So when the dlcose happen, then libpkgmgr-installer-client been closed too since no one
63          * link to it then.
64          *
65          * However, when the libdbus call into the callback function, it suddenly fond that the
66          * function address is gone (unmapped), then we receive a SIGSEGV.
67          *
68          * I'm not sure why we're using dlopen/dlclose in this case, I think it's much simple and
69          * robust if we just link to the well-known lib.
70          *
71          * See https://bugs.tizen.org/jira/browse/PTREL-591
72         dlclose(handle);
73          */
74         return ret;
75 }
76
77 API int pkgmgrinfo_client_listen_status(pkgmgrinfo_client *pc, pkgmgrinfo_handler event_cb, void *data)
78 {
79         int ret = 0;
80         char *errmsg = NULL;
81         void *handle = NULL;
82         int (*__pkgmgr_client_listen_status)(pkgmgrinfo_client *pc, pkgmgrinfo_handler event_cb, void *data) = NULL;
83
84         handle = dlopen("libpkgmgr-client.so.0", RTLD_LAZY | RTLD_GLOBAL);
85         retvm_if(!handle, PMINFO_R_ERROR, "dlopen() failed. [%s]", dlerror());
86
87         __pkgmgr_client_listen_status = dlsym(handle, "pkgmgr_client_listen_status");
88         errmsg = dlerror();
89         tryvm_if((errmsg != NULL) || (__pkgmgr_client_listen_status == NULL), ret = PMINFO_R_ERROR, "dlsym() failed. [%s]", errmsg);
90
91         ret = __pkgmgr_client_listen_status(pc, event_cb, data);
92         tryvm_if(ret < 0, ret = PMINFO_R_ERROR, "pkgmgr_client_new failed.");
93
94 catch:
95         /* same as pkgmgrinfo_client_new */
96         return ret;
97 }
98
99 API int pkgmgrinfo_client_free(pkgmgrinfo_client *pc)
100 {
101         int ret = 0;
102         char *errmsg = NULL;
103         void *handle = NULL;
104         int (*__pkgmgr_client_free)(pkgmgrinfo_client *pc) = NULL;
105
106         handle = dlopen("libpkgmgr-client.so.0", RTLD_LAZY | RTLD_GLOBAL);
107         retvm_if(!handle, PMINFO_R_ERROR, "dlopen() failed. [%s]", dlerror());
108
109         __pkgmgr_client_free = dlsym(handle, "pkgmgr_client_free");
110         errmsg = dlerror();
111         tryvm_if((errmsg != NULL) || (__pkgmgr_client_free == NULL), ret = PMINFO_R_ERROR, "dlsym() failed. [%s]", errmsg);
112
113         ret = __pkgmgr_client_free(pc);
114         tryvm_if(ret < 0, ret = PMINFO_R_ERROR, "pkgmgr_client_new failed.");
115
116 catch:
117         /* same as pkgmgrinfo_client_new */
118         return ret;
119 }