summaryrefslogtreecommitdiff
path: root/src/CModule.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/CModule.cpp')
-rw-r--r--src/CModule.cpp205
1 files changed, 205 insertions, 0 deletions
diff --git a/src/CModule.cpp b/src/CModule.cpp
new file mode 100644
index 0000000..8f8c967
--- /dev/null
+++ b/src/CModule.cpp
@@ -0,0 +1,205 @@
+/*
+ * Copyright 2013 Samsung Electronics Co., Ltd
+ *
+ * Licensed under the Flora License, Version 1.1 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://floralicense.org/license/
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <dlfcn.h>
+
+#include <dlog.h>
+#include <livebox-service.h>
+#include <livebox-errno.h>
+
+#include "debug.h"
+#include "livebox-cpp.h"
+#include "livebox-impl.h"
+#include "CModule.h"
+#include "dlist.h"
+
+const char *CModule::m_sModulePath = "/opt/usr/live/%s/libexec/liblive-%s.so";
+struct dlist *CModule::m_pModuleList = NULL;
+
+CModule *CModule::Load(const char *pkgname)
+{
+ CModule *inst;
+ char *tmp;
+ char *module_path;
+ int ret;
+
+ tmp = strdup(pkgname);
+ if (!tmp) {
+ ErrPrint("Memory: %s\n", strerror(errno));
+ return NULL;
+ }
+
+ try {
+ inst = new CModule(tmp);
+ } catch (...) {
+ ErrPrint("Memory\n");
+ free(tmp);
+ return NULL;
+ }
+
+ module_path = livebox_service_libexec(pkgname);
+ if (!module_path) {
+ delete inst;
+ free(tmp);
+ return NULL;
+ }
+
+ inst->m_pHandle = dlopen(module_path, RTLD_LOCAL | RTLD_NOW | RTLD_DEEPBIND);
+ free(module_path);
+
+ if (!inst->m_pHandle) {
+ ErrPrint("dlopen: %s\n", dlerror());
+ delete inst;
+ free(tmp);
+ return NULL;
+ }
+
+ inst->m_fNew = (void *(*)(void))dlsym(inst->m_pHandle, "livebox_new");
+ if (!inst->m_fNew) {
+ ErrPrint("symbol: livebox_new is not found: %s\n", dlerror());
+ dlclose(inst->m_pHandle);
+ delete inst;
+ free(tmp);
+ return NULL;
+ }
+
+ inst->m_fNeedToCreate = (int (*)(const char *, const char *))dlsym(inst->m_pHandle, "livebox_need_to_create");
+ if (!inst->m_fNeedToCreate) {
+ DbgPrint("%s has no livebox_need_to_create\n", pkgname);
+ }
+
+ inst->m_fInitialize = (int (*)(const char *))dlsym(inst->m_pHandle, "livebox_initialize");
+ if (!inst->m_fInitialize) {
+ DbgPrint("%s has no livebox_initialize\n", pkgname);
+ } else {
+ ret = inst->m_fInitialize(pkgname);
+ if (ret < 0) {
+ ErrPrint("livebox_finalize(%s) returns %d\n", pkgname, ret);
+ dlclose(inst->m_pHandle);
+ delete inst;
+ free(tmp);
+ return NULL;
+ }
+ }
+
+ inst->m_fFinalize = (int (*)(void))dlsym(inst->m_pHandle, "livebox_finalize");
+ if (!inst->m_fFinalize) {
+ DbgPrint("%s has no livebox_finalize\n", pkgname);
+ }
+
+ m_pModuleList = dlist_append(m_pModuleList, inst);
+ return inst;
+}
+
+int CModule::Unload(void)
+{
+ struct dlist *l;
+
+ l = dlist_find_data(m_pModuleList, this);
+ m_pModuleList = dlist_remove(m_pModuleList, l);
+
+ if (m_fFinalize) {
+ int ret;
+ ret = m_fFinalize();
+ DbgPrint("livebox_finalize of %s returns %d\n", m_sPkgname, ret);
+ }
+
+ dlclose(m_pHandle);
+ free(m_sPkgname);
+ delete this;
+ return LB_STATUS_SUCCESS;
+}
+
+int CModule::Create(const char *filename, const char *content, const char *cluster, const char *category)
+{
+ CLiveBoxImpl *inst;
+
+ inst = (CLiveBoxImpl *)m_fNew();
+ if (inst) {
+ int ret;
+ ret = inst->Create(filename, content, cluster, category);
+ if (ret < 0) {
+ delete inst;
+ return ret;
+ }
+
+ m_pList = dlist_append(m_pList, inst);
+ return 0;
+ }
+
+ return LB_STATUS_ERROR_FAULT;
+}
+
+int CModule::Destroy(CLiveBoxImpl *inst)
+{
+ struct dlist *l;
+
+ l = dlist_find_data(m_pList, inst);
+ if (!l) {
+ return LB_STATUS_ERROR_NOT_EXIST;
+ }
+
+ m_pList = dlist_remove(m_pList, l);
+ delete inst;
+ return LB_STATUS_SUCCESS;
+}
+
+CLiveBoxImpl *CModule::FindLiveBox(const char *filename)
+{
+ struct dlist *l;
+ void *item;
+ CLiveBoxImpl *box;
+
+ dlist_foreach(m_pList, l, item) {
+ box = (CLiveBoxImpl *)item;
+ if (!strcmp(filename, box->Filename())) {
+ return box;
+ }
+ }
+
+ return NULL;
+}
+
+int CModule::NeedToCreate(const char *cluster, const char *category)
+{
+ if (!m_fNeedToCreate) {
+ return 0;
+ }
+
+ return m_fNeedToCreate(cluster, category);
+}
+
+CModule *CModule::FindModule(const char *pkgname)
+{
+ struct dlist *l;
+ void *item;
+ CModule *module;
+
+ dlist_foreach(m_pModuleList, l, item) {
+ module = (CModule *)item;
+ if (!strcmp(pkgname, module->PackageName())) {
+ return module;
+ }
+ }
+
+ return NULL;
+}
+
+/* End of a file */