diff options
Diffstat (limited to 'src/CModule.cpp')
-rw-r--r-- | src/CModule.cpp | 205 |
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 */ |