SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} ${flag}")
ENDFOREACH(flag)
-SET(target_hydra dotnet_hydra_launcher)
+SET(target_hydra dotnet_hydra_loader)
PKG_CHECK_MODULES(${target_hydra} REQUIRED liblaunchpad-hydra)
SET_TARGET_PROPERTIES(${DOTNET_LAUNCHER_UTIL} PROPERTIES COMPILE_FLAGS ${EXTRA_CFLAGS_LIB})
TARGET_LINK_LIBRARIES(${DOTNET_LAUNCHER_UTIL} ${${PROJECT_NAME}_LDFLAGS} "-ldl" boost_filesystem boost_system)
+SET(DOTNET_LAUNCHER_CORE "dotnet_launcher_core")
+SET(${DOTNET_LAUNCHER_CORE}_SOURCE_FILES
+ launcher/lib/injection.cc
+ launcher/lib/dotnet_launcher.cc
+)
+ADD_LIBRARY(${DOTNET_LAUNCHER_CORE} SHARED ${${DOTNET_LAUNCHER_CORE}_SOURCE_FILES})
+SET_TARGET_PROPERTIES(${DOTNET_LAUNCHER_CORE} PROPERTIES COMPILE_FLAGS ${EXTRA_CFLAGS_LIB})
+TARGET_LINK_LIBRARIES(${DOTNET_LAUNCHER_CORE} ${${PROJECT_NAME}_LDFLAGS} "-ldl" boost_filesystem boost_system ${DOTNET_LAUNCHER_UTIL})
+
SET(DOTNET_LAUNCHER "dotnet-launcher")
SET(${DOTNET_LAUNCHER}_SOURCE_FILES
- launcher/main.cc
- launcher/injection.cc
- launcher/launcher.cc
- launcher/dotnet/dotnet_launcher.cc
+ launcher/exec/launcher.cc
)
ADD_EXECUTABLE(${DOTNET_LAUNCHER} ${${DOTNET_LAUNCHER}_SOURCE_FILES})
SET_TARGET_PROPERTIES(${DOTNET_LAUNCHER} PROPERTIES COMPILE_FLAGS ${EXTRA_CFLAGS_EXE})
-TARGET_LINK_LIBRARIES(${DOTNET_LAUNCHER} ${${PROJECT_NAME}_LDFLAGS} "-pie -ldl -lpthread" aul ${DOTNET_LAUNCHER_UTIL})
+TARGET_INCLUDE_DIRECTORIES(${DOTNET_LAUNCHER} PRIVATE "launcher/lib")
+TARGET_LINK_LIBRARIES(${DOTNET_LAUNCHER} ${${PROJECT_NAME}_LDFLAGS} "-pie -ldl -lpthread" aul ${DOTNET_LAUNCHER_UTIL} ${DOTNET_LAUNCHER_CORE})
SET_TARGET_PROPERTIES(${DOTNET_LAUNCHER}
PROPERTIES SKIP_BUILD_RPATH TRUE
) # remove rpath option that is automatically generated by cmake.
-SET(DOTNET_HYDRA_LAUNCHER "dotnet-hydra-launcher")
-SET(${DOTNET_HYDRA_LAUNCHER}_SOURCE_FILES
+SET(DOTNET_LOADER "dotnet-loader")
+SET(${DOTNET_LOADER}_SOURCE_FILES
+ launcher/exec/loader.cc
+)
+ADD_EXECUTABLE(${DOTNET_LOADER} ${${DOTNET_LOADER}_SOURCE_FILES})
+SET_TARGET_PROPERTIES(${DOTNET_LOADER} PROPERTIES COMPILE_FLAGS ${EXTRA_CFLAGS_EXE})
+TARGET_INCLUDE_DIRECTORIES(${DOTNET_LOADER} PRIVATE "launcher/lib")
+TARGET_LINK_LIBRARIES(${DOTNET_LOADER} ${${PROJECT_NAME}_LDFLAGS} "-pie -ldl -lpthread" aul ${DOTNET_LAUNCHER_UTIL} ${DOTNET_LAUNCHER_CORE})
+
+SET_TARGET_PROPERTIES(${DOTNET_LOADER}
+ PROPERTIES SKIP_BUILD_RPATH TRUE
+) # remove rpath option that is automatically generated by cmake.
+
+SET(DOTNET_CORERUN "dotnet")
+SET(${DOTNET_CORERUN}_SOURCE_FILES
+ launcher/exec/corerun.cc
+)
+ADD_EXECUTABLE(${DOTNET_CORERUN} ${${DOTNET_CORERUN}_SOURCE_FILES})
+SET_TARGET_PROPERTIES(${DOTNET_CORERUN} PROPERTIES COMPILE_FLAGS ${EXTRA_CFLAGS_EXE})
+TARGET_INCLUDE_DIRECTORIES(${DOTNET_CORERUN} PRIVATE "launcher/lib")
+TARGET_LINK_LIBRARIES(${DOTNET_CORERUN} ${${PROJECT_NAME}_LDFLAGS} "-pie -ldl -lpthread" aul ${DOTNET_LAUNCHER_UTIL} ${DOTNET_LAUNCHER_CORE})
+
+SET_TARGET_PROPERTIES(${DOTNET_CORERUN}
+ PROPERTIES SKIP_BUILD_RPATH TRUE
+) # remove rpath option that is automatically generated by cmake.
+
+SET(DOTNET_HYDRA_LOADER "dotnet-hydra-loader")
+SET(${DOTNET_HYDRA_LOADER}_SOURCE_FILES
hydra/hydra_main.cc
)
-ADD_EXECUTABLE(${DOTNET_HYDRA_LAUNCHER} ${${DOTNET_HYDRA_LAUNCHER}_SOURCE_FILES})
-TARGET_LINK_LIBRARIES(${DOTNET_HYDRA_LAUNCHER} ${${target_hydra}_LDFLAGS} "-pie -ldl")
-SET_TARGET_PROPERTIES(${DOTNET_HYDRA_LAUNCHER} PROPERTIES COMPILE_FLAGS ${EXTRA_CFLAGS_HYDRA})
-SET_TARGET_PROPERTIES(${DOTNET_HYDRA_LAUNCHER}
+ADD_EXECUTABLE(${DOTNET_HYDRA_LOADER} ${${DOTNET_HYDRA_LOADER}_SOURCE_FILES})
+TARGET_LINK_LIBRARIES(${DOTNET_HYDRA_LOADER} ${${target_hydra}_LDFLAGS} "-pie -ldl")
+SET_TARGET_PROPERTIES(${DOTNET_HYDRA_LOADER} PROPERTIES COMPILE_FLAGS ${EXTRA_CFLAGS_HYDRA})
+SET_TARGET_PROPERTIES(${DOTNET_HYDRA_LOADER}
PROPERTIES SKIP_BUILD_RPATH TRUE
) # remove rpath option that is automatically generated by cmake.
CONFIGURE_FILE(dotnet-launcher.pc.in dotnet-launcher.pc @ONLY)
INSTALL(TARGETS ${DOTNET_LAUNCHER_UTIL} DESTINATION ${LIBDIR})
+INSTALL(TARGETS ${DOTNET_LAUNCHER_CORE} DESTINATION ${LIBDIR})
INSTALL(TARGETS ${DOTNET_LAUNCHER} DESTINATION ${BINDIR})
-INSTALL(TARGETS ${DOTNET_HYDRA_LAUNCHER} DESTINATION ${BINDIR})
+INSTALL(TARGETS ${DOTNET_LOADER} DESTINATION ${BINDIR})
+INSTALL(TARGETS ${DOTNET_CORERUN} DESTINATION ${BINDIR})
+INSTALL(TARGETS ${DOTNET_HYDRA_LOADER} DESTINATION ${BINDIR})
INSTALL(TARGETS ${TAC_COMMON} DESTINATION ${LIBDIR})
INSTALL(TARGETS ${NI_COMMON} DESTINATION ${LIBDIR})
INSTALL(TARGETS ${NITOOL} DESTINATION ${BINDIR})
[LOADER]
-NAME dotnet-launcher
+NAME dotnet-loader
# for candidate mode
-EXE /usr/bin/dotnet-launcher
+EXE /usr/bin/dotnet-loader
# for hydra mode
-#EXE /usr/bin/dotnet-hydra-launcher
+#EXE /usr/bin/dotnet-hydra-loader
APP_TYPE dotnet
DETECTION_METHOD TIMEOUT|DEMAND
TIMEOUT 5000
#include "launcher_env.h"
const char* __coreclr_lib = "/usr/share/dotnet.tizen/netcoreapp/libcoreclr.so";
-const char* __dotnet_launcher = "/usr/bin/dotnet-launcher";
+const char* __dotnet_loader = "/usr/bin/dotnet-loader";
typedef int (*coreclr_preload_assembly_ptr)(const char* assemblyPath);
typedef int (*launcher_real_main_ptr)(int argc, char *argv[], const char* mode);
hydra_callback.fork = [](int argc, char **argv, void* user_data) -> int {
_INFO("hydra : fork");
- void* launcher_h = dlopen(__dotnet_launcher, RTLD_NOW | RTLD_GLOBAL);
+ void* launcher_h = dlopen(__dotnet_loader, RTLD_NOW | RTLD_GLOBAL);
if (launcher_h == nullptr) {
_DBG("dlopen failed to open dotnet-launcher");
return -1;
#ifndef __LOG_H__
#define __LOG_H__
-#ifndef NO_TIZEN
#include <dlog.h>
#define LOGX(fmt, arg...) \
({ do { \
dlog_print(DLOG_INFO, LOG_TAG, fmt, ##arg); \
} while (0); })
-#else
-#include <stdio.h>
-#define LOGE(fmt, args...) printf(fmt, ##args)
-#define LOGD(fmt, args...) printf(fmt, ##args)
-#define LOGI(fmt, args...) printf(fmt, ##args)
-#define LOGX(fmt, args...) printf(fmt, ##args)
-#endif
-
#ifdef LOG_TAG
#undef LOG_TAG
#endif
#define _LOGX(fmt, args...) LOGX(fmt "\n", ##args)
#endif
+#ifndef _SOUT
+#define _SOUT(fmt, args...) fprintf(stdout, fmt "\n", ##args)
+#endif
+
+#ifndef _SERR
+#define _SERR(fmt, args...) fprintf(stderr, fmt "\n", ##args)
+#endif
+
#endif /* __LOG_H__ */
*/
bool removeAll(const bf::path& path);
+/**
+ * @brief change command name of the current process for access via ps command
+ * @param[in] name
+ */
+void setCmdName(const char* name);
+
+/**
+ * @brief get file name from the path
+ * @param[in] file path
+ * @return return file name if exist otherwise null.
+ */
+char* getFileNameFromPath(char* path);
+
#endif /* __UTILS_H__ */
--- /dev/null
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * 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 "dotnet_launcher.h"
+#include "utils.h"
+#include "log.h"
+
+using tizen::runtime::dotnetcore::CoreRuntime;
+
+int main(int argc, char *argv[])
+{
+ _INFO("##### Run in corerun mode #####");
+
+ if (argc < 2) {
+ _SOUT("No parameter");
+ return -1;
+ }
+
+ if (!isManagedAssembly(argv[1]) && !isNativeImage(argv[1])) {
+ _SOUT("first parameter should be assembly file");
+ return -1;
+ }
+
+ // remove executable and assembly path form the arguments and pass that to managed code
+ int vargc = argc - 2;
+ std::vector<char*> vargs;
+ for (int i = 0; i < vargc; i++) {
+ vargs.push_back(argv[2 + i]);
+ }
+
+ // set command name to assembly file
+ char* fileName = getFileNameFromPath(argv[1]);
+ setCmdName(fileName);
+
+ CoreRuntime* runtime = new CoreRuntime("corerun");
+
+ // get absolute path of input dll file
+ std::string absoluteDllPath = absolutePath(argv[1]);
+
+ if (runtime->initialize(LaunchMode::corerun, false, absoluteDllPath.c_str()) != 0) {
+ _SOUT("Failed to initialize");
+ return -1;
+ }
+
+ // launch application
+ if (runtime->launch(fileName, baseName(absoluteDllPath).c_str(), absoluteDllPath.c_str(), vargc, &vargs[0])) {
+ _SOUT("Failed to launch");
+ return -1;
+ }
+
+ return 0;
+}
+
--- /dev/null
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * 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 "dotnet_launcher.h"
+#include "utils.h"
+#include "log.h"
+
+#include <cstdio>
+#include <vector>
+#include <memory>
+
+#include <aul.h>
+#include <sys/types.h>
+#include <unistd.h>
+
+#include <sys/prctl.h>
+
+using tizen::runtime::dotnetcore::CoreRuntime;
+
+// By the specification, application id must be shorter than 50 characters.
+// Current length of argv[0] is 25 with a space. ("/usr/bin/dotnet-launcher ")
+// To be able to change argv[0] when standalone mode padding for executable path is added.
+#define APPID_MAX_LENGTH (25 + 105)
+#define PRC_NAME_LENGTH 16
+
+static std::string StandaloneOption("--standalone");
+static std::string PaddingOption("--PADDING_TO_CHANGE_CMDLINE_PADDING_TO_CHANGE_CMDLINE_PADDING_TO_CHANGE_CMDLINE_PADDING_TO_CHANGE_CMDLINE");
+
+int main(int argc, char *argv[])
+{
+ _INFO("##### Run in standalone mode #####");
+
+ char* standalonePath = nullptr;
+ bool paddingExist = false;
+ const char* appRootPath = NULL;
+ char appId[APPID_MAX_LENGTH] = {0,};
+
+ std::vector<char*> vargs;
+
+ // start index 1 to avoid passing executable name "dotnet-launcher" as a parameter
+ for (int i = 1; i < argc; i++) {
+ if (StandaloneOption.compare(argv[i]) == 0) {
+ if (i > argc - 1) {
+ _ERR("Assembly path must be after \"--standalone\" option");
+ return -1;
+ }
+ i++;
+ standalonePath = argv[i];
+ } else if (PaddingOption.compare(argv[i]) == 0) {
+ paddingExist = true;
+ } else {
+ vargs.push_back(argv[i]);
+ }
+ }
+
+ CoreRuntime* runtime = new CoreRuntime("standalone");
+
+ // get app ID and app root path
+ if (AUL_R_OK == aul_app_get_appid_bypid(getpid(), appId, sizeof(appId))) {
+ _INFO("AUL_APPID : %s", appId);
+ // aul_get_app_root_path returns const char*, so there is no need to free after use.
+ appRootPath = aul_get_app_root_path();
+ if (appRootPath == nullptr) {
+ _ERR("Fail to get application root path");
+ return -1;
+ }
+ } else {
+ _ERR("Fail to get app_id");
+ return -1;
+ }
+
+ // set command name to assembly file
+ setCmdName(getFileNameFromPath(standalonePath));
+
+ // change cmdline from dotnet-launcher to executable path
+ int cmdlineSize = paddingExist ? APPID_MAX_LENGTH : APPID_MAX_LENGTH - PaddingOption.length();
+ memset(argv[0], '\0', cmdlineSize);
+ snprintf(argv[0], cmdlineSize - 1, "%s", standalonePath);
+
+ // initialize CoreRuntime (standalone mode enable, dlog redirection enable, root path NULL)
+ if (runtime->initialize(LaunchMode::launcher, true, appRootPath) != 0) {
+ _ERR("Failed to initialize");
+ return -1;
+ }
+
+ // launch application
+ if (runtime->launch(appId, appRootPath, standalonePath, vargs.size(), &vargs[0])) {
+ _ERR("Failed to launch");
+ return -1;
+ }
+
+ return 0;
+}
+
--- /dev/null
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * 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 "dotnet_launcher.h"
+#include "utils.h"
+#include "log.h"
+
+#include <cstdio>
+#include <vector>
+#include <memory>
+
+#include <Ecore.h>
+#include <sys/types.h>
+#include <unistd.h>
+#include <sys/prctl.h>
+
+#include <launchpad.h>
+#include <aul.h>
+
+using tizen::runtime::dotnetcore::CoreRuntime;
+
+static Ecore_Fd_Handler *__fd_handler;
+static loader_receiver_cb __receiver;
+
+// To precreate window(EFL/DALI), argc and argv should be passed.
+// But, create callback of loader doesnot pass that to parameter.
+// So, store argc and argv and use that to precreation.
+// If window precreation code moves to managed, removed below code.
+static int __argc;
+static char **__argv;
+
+typedef struct AppInfo {
+ std::string root;
+ std::string app_path;
+ std::string appid;
+ std::string pkgid;
+} AppInfo;
+static AppInfo __appInfo;
+
+
+//################## Code for running event loop for loader ####################
+
+static Eina_Bool __process_fd_handler(void *data, Ecore_Fd_Handler *handler)
+{
+ int fd;
+
+ fd = ecore_main_fd_handler_fd_get(handler);
+ if (fd == -1) {
+ _ERR("[candidate] ECORE_FD_GET");
+ exit(-1);
+ }
+
+ if (ecore_main_fd_handler_active_get(handler, ECORE_FD_READ)) {
+ if (__receiver)
+ __receiver(fd);
+ } else if (ecore_main_fd_handler_active_get(handler, ECORE_FD_ERROR)) {
+ _ERR("[candidate] ECORE_FD_ERROR");
+ close(fd);
+ exit(-1);
+ }
+
+ return ECORE_CALLBACK_CANCEL;
+}
+
+static void __adapter_loop_begin(void *user_data)
+{
+ ecore_main_loop_begin();
+}
+
+static void __adapter_loop_quit(void *user_data)
+{
+ ecore_main_loop_quit();
+}
+
+static void __adapter_add_fd(void *user_data, int fd,
+ loader_receiver_cb receiver)
+{
+ __fd_handler = ecore_main_fd_handler_add(fd,
+ static_cast<Ecore_Fd_Handler_Flags>(ECORE_FD_READ | ECORE_FD_ERROR),
+ __process_fd_handler, NULL, NULL, NULL);
+
+ if (__fd_handler == NULL) {
+ _ERR("fd_handler is NULL");
+ close(fd);
+ exit(-1);
+ }
+
+ __receiver = receiver;
+}
+
+static void __adapter_remove_fd(void *user_data, int fd)
+{
+ if (__fd_handler) {
+ ecore_main_fd_handler_del(__fd_handler);
+ __fd_handler = NULL;
+ __receiver = NULL;
+ }
+}
+
+//################## Code for managing loader life-cycle #######################
+
+static void __loader_create_cb(bundle *extra, int type, void *user_data)
+{
+ CoreRuntime* runtime = (CoreRuntime*)user_data;
+
+ {
+ // do native window precreation here
+ }
+
+ // initialize CoreRuntime (launchmode, dlog redirection enable, root path NULL)
+ if (runtime->initialize(LaunchMode::loader, true, NULL) != 0) {
+ _ERR("Failed to initialized");
+ } else {
+ _INFO("Success to initialized");
+ }
+}
+
+static int __loader_launch_cb(int argc, char **argv, const char *app_path,
+ const char *appid, const char *pkgid, const char *pkg_type,
+ void *user_data)
+{
+ const char* root_path = aul_get_app_root_path();
+ if (root_path != NULL) {
+ __appInfo.root = root_path;
+ }
+
+ __appInfo.app_path = app_path;
+ __appInfo.appid = appid;
+ __appInfo.pkgid = pkgid;
+
+ return 0;
+}
+
+static int __loader_terminate_cb(int argc, char **argv, void *user_data)
+{
+ CoreRuntime* runtime = (CoreRuntime*)user_data;
+
+ _INFO("launch request with app path : %s", __appInfo.app_path.c_str());
+
+ // The launchpad pass the name of exe file to the first argument.
+ // For the C# spec, we have to skip this first argument.
+ if (runtime->launch(__appInfo.appid.c_str(), __appInfo.root.c_str(),
+ __appInfo.app_path.c_str(), argc - 1, argv + 1)) {
+ _ERR("Failed to launch");
+ }
+
+ return 0;
+}
+
+//################## Main Code #################################################
+
+extern "C" int realMain(int argc, char *argv[], const char* mode)
+{
+ _INFO("##### Run in candidate mode #####");
+
+ CoreRuntime* runtime = new CoreRuntime(mode);
+
+ // change cmdline from dotnet-hydra-loader to dotnet-loader
+ if (strcmp(argv[0], "/usr/bin/dotnet-hydra-loader") == 0) {
+ memset(argv[0], '\0', strlen("/usr/bin/dotnet-hydra-loader"));
+ snprintf(argv[0], strlen("/usr/bin/dotnet-loader") + 1,
+ "/usr/bin/dotnet-loader");
+ }
+
+ setCmdName("dotnet-loader");
+
+ loader_lifecycle_callback_s callbacks = {
+ .create = __loader_create_cb,
+ .launch = __loader_launch_cb,
+ .terminate = __loader_terminate_cb
+ };
+
+ loader_adapter_s adapter = {
+ .loop_begin = __adapter_loop_begin,
+ .loop_quit = __adapter_loop_quit,
+ .add_fd = __adapter_add_fd,
+ .remove_fd = __adapter_remove_fd
+ };
+
+ return launchpad_loader_main(argc, argv, &callbacks, &adapter, runtime);
+}
+
+int main(int argc, char *argv[])
+{
+ __argc = argc;
+ __argv = argv;
+
+ return realMain(argc, argv, "candidate");
+}
+
+++ /dev/null
-/*
- * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
- *
- * Licensed under the Apache License, Version 2.0 (the License);
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * 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 "launcher.h"
-#include "log.h"
-
-#include <launchpad.h>
-#include <aul.h>
-
-#include <Ecore.h>
-#include <bundle_internal.h>
-
-#include <map>
-#include <vector>
-#include <functional>
-
-#include <unistd.h>
-#include <dlfcn.h>
-
-
-namespace tizen {
-namespace runtime {
-
-struct FdHandler {
- Ecore_Fd_Handler *handler;
- loader_receiver_cb receiver;
-};
-
-static int __argc;
-static char **__argv;
-
-class LaunchpadAdapterImpl : public LaunchpadAdapter
-{
- public:
- LaunchpadAdapterImpl() :
- callbacks(),
- adapter(),
- __isLaunched(false)
- { }
- int loaderMain(int argc, char* argv[]) override;
-
- std::map<int, FdHandler> handlers;
-
- private:
- AppInfo appInfo;
- loader_lifecycle_callback_s callbacks;
- loader_adapter_s adapter;
- bool __isLaunched;
- std::string __launchPath;
-};
-
-LaunchpadAdapterImpl LaunchpadImpl;
-LaunchpadAdapter& Launchpad = LaunchpadImpl;
-
-#define WITH_SELF(data) \
- LaunchpadAdapterImpl* self = static_cast<LaunchpadAdapterImpl*>(data); \
- if (self == nullptr) \
- _ERR("No LaunchpadImplData"); \
- else
-
-static Eina_Bool fdHandler(void *data, Ecore_Fd_Handler* handler)
-{
- WITH_SELF(data) {
- int fd = ecore_main_fd_handler_fd_get(handler);
- if (fd == -1) {
- _ERR("Failed to get the Ecore FD");
- exit(-1);
- }
-
- if (ecore_main_fd_handler_active_get(handler, ECORE_FD_READ)) {
- if (self->handlers.find(fd) != self->handlers.end())
- self->handlers[fd].receiver(fd);
- } else if (ecore_main_fd_handler_active_get(handler, ECORE_FD_ERROR)) {
- _ERR("Ecore FD Handler Have Error");
- close(fd);
- exit(-1);
- }
- }
-
- return ECORE_CALLBACK_CANCEL;
-}
-
-static void fdAdd(void *data, int fd, loader_receiver_cb receiver)
-{
- Ecore_Fd_Handler* handler = ecore_main_fd_handler_add(fd,
- static_cast<Ecore_Fd_Handler_Flags>(ECORE_FD_READ | ECORE_FD_ERROR),
- fdHandler, data, nullptr, nullptr);
- if (handler == nullptr) {
- _ERR("Failed to add a FD handler to ecore main loop");
- close(fd);
- exit(-1);
- } WITH_SELF(data) {
- self->handlers[fd] = {handler, receiver};
- }
-}
-
-static void fdRemove(void *data, int fd)
-{
- WITH_SELF(data) {
- if (self->handlers.find(fd) != self->handlers.end()) {
- Ecore_Fd_Handler* handler = self->handlers[fd].handler;
- ecore_main_fd_handler_del(handler);
- self->handlers.erase(fd);
- }
- }
-}
-
-// To run dotnet-launcher on the headless device, remove build dependency from EFL.
-#define ELEMENTARY_PATH "/usr/lib/libelementary.so.1"
-static void* __win;
-typedef int (*elm_init_ptr)(int argc, char **argv);
-typedef void (*elm_config_accel_preference_set_ptr)(const char *pref);
-typedef void* (*elm_win_add_ptr)(void* parent, const char* name, int type);
-typedef void (*elm_win_precreated_object_set_ptr)(void* win);
-
-static void preCreateWindow()
-{
- struct stat sb;
- if (stat(ELEMENTARY_PATH, &sb) != 0) {
- _ERR("[candidate] libelementary is not exist. skip precreation");
- return;
- }
-
- int elmInitCnt = 0;
- void* handle = nullptr;
- elm_init_ptr elm_init = nullptr;
- elm_config_accel_preference_set_ptr elm_config_accel_preference_set = nullptr;
- elm_win_add_ptr elm_win_add = nullptr;
- elm_win_precreated_object_set_ptr elm_win_precreated_object_set = nullptr;
-
- handle = dlopen(ELEMENTARY_PATH, RTLD_NOW | RTLD_GLOBAL);
- if (handle) {
- elm_init = (elm_init_ptr)dlsym(handle, "elm_init");
- if (elm_init) {
- elmInitCnt = elm_init(__argc, __argv);
-
- if (!elmInitCnt) {
- _ERR("[candidate] elm_init() failed");
- return;
- }
- }
-
- elm_config_accel_preference_set = (elm_config_accel_preference_set_ptr)dlsym(handle, "elm_config_accel_preference_set");
- if (elm_config_accel_preference_set) {
- elm_config_accel_preference_set("hw");
- }
-
- elm_win_add = (elm_win_add_ptr)dlsym(handle, "elm_win_add");
- if (elm_win_add) {
- // enum value of "ELM_WIN_BASIC" is 0
- __win = elm_win_add(NULL, "package_name", 0);
- if (__win == NULL) {
- _ERR("[candidate] elm_win_add() failed");
- return;
- }
- }
-
- elm_win_precreated_object_set = (elm_win_precreated_object_set_ptr)dlsym(handle, "elm_win_precreated_object_set");
- if (elm_win_precreated_object_set) {
- elm_win_precreated_object_set(__win);
- }
- _INFO("elm window precreation is done");
- }
-}
-
-int LaunchpadAdapterImpl::loaderMain(int argc, char* argv[])
-{
- __argc = argc;
- __argv = argv;
- callbacks.create = [](bundle *extra, int type, void *userData) {
- preCreateWindow();
- WITH_SELF(userData) {
- if (self->onCreate != nullptr)
- self->onCreate();
- }
- };
- callbacks.launch = [](int argc, char** argv, const char* appPath,
- const char* appId, const char* pkgId,
- const char* pkgType, void* userData) -> int {
- WITH_SELF(userData) {
- const char* appRootPath = aul_get_app_root_path();
- if (appRootPath != nullptr) {
- self->appInfo.root = std::string(appRootPath);
- }
- self->appInfo.path = appPath;
- self->appInfo.id = appId;
- self->appInfo.pkg = pkgId;
- self->appInfo.type = pkgType;
- if (self->onLaunch != nullptr)
- self->onLaunch(self->appInfo, argc, argv);
- }
-
- return 0;
- };
- callbacks.terminate = [](int argc, char **argv, void* userData) -> int {
- WITH_SELF(userData) {
- if (self->onTerminate != nullptr)
- self->onTerminate(self->appInfo, argc, argv);
- }
- return 0;
- };
-
- adapter.loop_begin = [](void *data) {
- ecore_main_loop_begin();
- };
-
- adapter.loop_quit = [](void *data) {
- ecore_main_loop_quit();
- };
- adapter.add_fd = fdAdd;
- adapter.remove_fd = fdRemove;
-
- _INFO("launchpad_loader_main is start");
- int r = launchpad_loader_main(argc, argv, &(this->callbacks), &(this->adapter), this);
- _INFO("launchpad_loader_main is finished with [%d]", r);
-
- return r;
-}
-
-#undef WITH_SELF
-
-} // namespace runtime
-} // namespace tizen
+++ /dev/null
-/*
- * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
- *
- * Licensed under the Apache License, Version 2.0 (the License);
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * 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.
- */
-
-#ifndef __LAUNCHER_INTERFACE_H__
-#define __LAUNCHER_INTERFACE_H__
-
-#include <string>
-#include <functional>
-
-namespace tizen {
-namespace runtime {
-
-struct AppInfo {
- std::string root;
- std::string path;
- std::string id;
- std::string pkg;
- std::string type;
-};
-
-class LaunchpadAdapter
-{
- public:
- virtual int loaderMain(int argc, char* argv[]) = 0;
- std::function<void()> onCreate = nullptr;
- std::function<void(const AppInfo&, int, char**)> onLaunch = nullptr;
- std::function<void(const AppInfo&, int, char**)> onTerminate = nullptr;
-};
-
-extern LaunchpadAdapter& Launchpad;
-
-} // namespace runtime
-} // namespace tizen
-
-#endif /* __LAUNCHER_INTERFACE_H__ */
#include "injection.h"
#include "utils.h"
#include "log.h"
-#include "launcher.h"
#include "dotnet_launcher.h"
#include "plugin_manager.h"
#include "path_manager.h"
dispose();
}
-int CoreRuntime::initialize(bool standalone, bool useDlog, const char* corerunRoot)
+int CoreRuntime::initialize(LaunchMode launchMode, bool useDlog, const char* rootPath)
{
// checkInjection checks dotnet-launcher run mode
// At the moment, this mechanism is used only when the Memory Profiler is started.
#endif // __arm__
// Disable debug pipes and semaphores creation in case of non-standlone mode
- if (!standalone)
+ if (launchMode == LaunchMode::loader)
putenv(const_cast<char *>("COMPlus_EnableDiagnostics=0"));
// Write Debug.WriteLine to stderr
_INFO("libcoreclr dlopen and dlsym success");
- if (!standalone) {
+ if (launchMode == LaunchMode::loader) {
pluginPreload();
// terminate candidate process if language is changed.
std::string NIprobePath;
std::string nativeLibPath;
- if (corerunRoot) {
- probePath = corerunRoot;
- NIprobePath = corerunRoot;
- nativeLibPath = corerunRoot;
+ if (launchMode == LaunchMode::corerun) {
+ probePath = rootPath;
+ NIprobePath = rootPath;
+ nativeLibPath = rootPath;
} else {
__fd = open("/proc/self", O_DIRECTORY);
if (__fd < 0) {
__initialized = true;
- if (!standalone) {
+ if (launchMode == LaunchMode::loader) {
preloadTypes(); // Preload common managed code
}
#ifndef __DOTNET_LAUNCHER_H__
#define __DOTNET_LAUNCHER_H__
-#include "launcher.h"
+#include <string>
+
#include "coreclr_host.h"
#include "plugin_manager.h"
+enum LaunchMode {
+ corerun = 0,
+ loader,
+ launcher
+};
+
namespace tizen {
namespace runtime {
namespace dotnetcore {
public:
CoreRuntime(const char* mode);
~CoreRuntime();
- int initialize(bool standalone, bool useDlog, const char* corerunRoot);
+ int initialize(LaunchMode mode, bool useDlog, const char* rootPath);
void dispose();
int launch(const char* appId, const char* root, const char* path, int argc, char* argv[]);
private:
-
bool initializeCoreClr(const char* appId, const char* assemblyProbePaths, const char* NIProbePaths, const char* pinvokeProbePaths, const char* tpaList);
void preloadTypes();
coreclr_initialize_ptr initializeClr;
+++ /dev/null
-/*
- * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
- *
- * Licensed under the Apache License, Version 2.0 (the License);
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * 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 "dotnet/dotnet_launcher.h"
-#include "utils.h"
-#include "log.h"
-
-#include <cstdio>
-#include <vector>
-#include <memory>
-
-#include <Eina.h>
-#include <aul.h>
-#include <sys/types.h>
-#include <unistd.h>
-
-// By the specification, application id must be shorter than 50 characters.
-// Current length of argv[0] is 25 with a space. ("/usr/bin/dotnet-launcher ")
-// To be able to change argv[0] when standalone mode padding for executable path is added.
-#define APPID_MAX_LENGTH (25 + 105)
-
-static std::string StandaloneOption("--standalone");
-static std::string PaddingOption("--PADDING_TO_CHANGE_CMDLINE_PADDING_TO_CHANGE_CMDLINE_PADDING_TO_CHANGE_CMDLINE_PADDING_TO_CHANGE_CMDLINE");
-
-extern "C" int realMain(int argc, char *argv[], const char* mode)
-{
- int i;
- bool standaloneMode = false;
- char* standalonePath = nullptr;
- bool corerunMode = false;
- bool paddingExist = false;
-
- std::vector<char*> vargs;
-
- // start index 1 to avoid passing executable name "dotnet-launcher" as a parameter
- for (i = 1; i < argc; i++) {
- if (StandaloneOption.compare(argv[i]) == 0) {
- standaloneMode = true;
-
- if (i > argc - 1) {
- fprintf(stderr, "Assembly path must be after \"--standalone\" option\n");
- return 1;
- }
- i++;
- standalonePath = argv[i];
- } else if (PaddingOption.compare(argv[i]) == 0) {
- paddingExist = true;
- } else {
- vargs.push_back(argv[i]);
- }
- }
-
- if (isManagedAssembly(argv[1]) || isNativeImage(argv[1])) {
- corerunMode = true;
- }
-
- using tizen::runtime::Launchpad;
- using tizen::runtime::AppInfo;
- using tizen::runtime::dotnetcore::CoreRuntime;
-
- std::unique_ptr<CoreRuntime> runtime(new CoreRuntime(mode));
-
- if (corerunMode) {
- _INFO("##### Run in corerun mode #####");
- char appId[APPID_MAX_LENGTH] = {0,};
- std::string appRoot;
- snprintf(appId, 16, "%s", "dotnet-launcher");
- std::string absoluteDllPath = absolutePath(argv[1]);
- appRoot = baseName(absoluteDllPath);
-
- if (runtime->initialize(true, false, appRoot.c_str()) != 0) {
- _ERR("Failed to initialize");
- return 1;
- }
-
- int argsLen = vargs.size() - 1;
- char** args = &vargs[1];
- if (runtime->launch(appId, appRoot.c_str(), absoluteDllPath.c_str(), argsLen, args)) {
- _ERR("Failed to launch");
- return 1;
- }
- } else if (standaloneMode) {
- _INFO("##### Run in standalone mode #####");
- char appId[APPID_MAX_LENGTH] = {0,};
- std::string appRoot;
- if (AUL_R_OK == aul_app_get_appid_bypid(getpid(), appId, sizeof(appId))) {
- const char* appRootPath = aul_get_app_root_path();
- if (appRootPath != nullptr)
- appRoot = std::string(appRootPath);
- } else {
- // If appId is not set, it is executed directly by cmdline.
- // In this case, appRoot is passed as an argument.
- snprintf(appId, 16, "%s", "dotnet-launcher");
- appRoot = baseName(baseName(standalonePath));
- }
- _INFO("AUL_APPID : %s", appId);
-
- if (runtime->initialize(true, true, NULL) != 0) {
- _ERR("Failed to initialize");
- return 1;
- }
-
- // change cmdline from dotnet-launcher to executable path
- int cmdlineSize = paddingExist ? APPID_MAX_LENGTH : APPID_MAX_LENGTH - PaddingOption.length();
- memset(argv[0], '\0', cmdlineSize);
- snprintf(argv[0], cmdlineSize, "%s", standalonePath);
-
- int argsLen = vargs.size();
- char** args = &vargs[0];
- if (runtime->launch(appId, appRoot.c_str(), standalonePath, argsLen, args)) {
- _ERR("Failed to launch");
- return 1;
- }
- } else {
- // change cmdline from dotnet-hydra-launcher to dotnet-launcher
- if (strcmp(argv[0], "/usr/bin/dotnet-hydra-launcher") == 0) {
- memset(argv[0], '\0', strlen("/usr/bin/dotnet-hydra-launcher"));
- snprintf(argv[0], strlen("/usr/bin/dotnet-launcher") + 1, "/usr/bin/dotnet-launcher");
- }
-
- Launchpad.onCreate = [&runtime]() {
- if (runtime->initialize(false, true, NULL) != 0) {
- _ERR("Failed to initialized");
- } else {
- _INFO("Success to initialized");
- }
- };
-
- Launchpad.onTerminate = [&runtime](const AppInfo& appInfo, int argc, char** argv) {
- _INFO("launch request with app path : %s", appInfo.path.c_str());
- _INFO("appId : %s", appInfo.id.c_str());
- _INFO("pkg : %s", appInfo.pkg.c_str());
-
- // aul_get_app_root_path() can return NULL for error case.
- if (appInfo.root.empty()) {
- _ERR("Failed to launch. root path is set to NULL");
- } else {
- // The launchpad pass the name of exe file to the first argument.
- // For the C# spec, we have to skip this first argument.
- if (runtime->launch(appInfo.id.c_str(), appInfo.root.c_str(), appInfo.path.c_str(), argc-1, argv+1))
- _ERR("Failed to launch");
- }
- };
- int ret = Launchpad.loaderMain(argc, argv);
- if (ret < 0) {
- _ERR("fail to start loaderMain. candidate process is not created.");
- return 1;
- }
- }
-
- return 0;
-}
-
-int main(int argc, char *argv[])
-{
- return realMain(argc, argv, "default");
-}
#include <pkgmgr-info.h>
#include <pkgmgr_installer_info.h>
#include <sys/smack.h>
+#include <sys/prctl.h>
#include <cstdlib>
#include <cstring>
}
return true;
}
+
+void setCmdName(const char* name)
+{
+ #define PRC_NAME_LENGTH 16
+
+ char processName[PRC_NAME_LENGTH] = {0, };
+
+ if (name == NULL || *name == '\0') {
+ return;
+ }
+
+ memset(processName, '\0', PRC_NAME_LENGTH);
+ snprintf(processName, PRC_NAME_LENGTH, "%s", name);
+ prctl(PR_SET_NAME, processName);
+}
+
+char* getFileNameFromPath(char* path)
+{
+ char* fileName = strrchr(path, PATH_SEPARATOR);
+ if (fileName != NULL && *fileName != '\0') {
+ return ++fileName;
+ }
+
+ return NULL;
+}
+
</request>
<assign>
<filesystem path="/opt/usr/dotnet" label="System::Shared" type="transmutable" />
+ <filesystem path="/usr/bin/dotnet-loader" label="User" exec_label="User" />
+ <filesystem path="/usr/bin/dotnet" label="System::Tools" exec_label="User" />
</assign>
</manifest>
mkdir -p /opt/etc/skel/.dotnet
chsmack -t -a User::App::Shared /opt/etc/skel/.dotnet
%{_bindir}/dotnettool --ni-dll %{_runtime_dir}/System.Private.CoreLib.dll
+setcap cap_setgid,cap_sys_admin+ei /usr/bin/dotnet-launcher
+setcap cap_setgid,cap_sys_admin+ei /usr/bin/dotnet-loader
+setcap cap_setgid,cap_sys_admin+ei /usr/bin/dotnet
%files
%manifest dotnet-launcher.manifest
%{_install_mdplugin_dir}/libprefer_nuget_cache_plugin.so
%{_install_mdplugin_dir}/libprefer_dotnet_aot_plugin.so
%{_bindir}/dotnet-launcher
-%{_bindir}/dotnet-hydra-launcher
+%{_bindir}/dotnet-loader
+%{_bindir}/dotnet
+%{_bindir}/dotnet-hydra-loader
%{_libdir}/libdotnet_launcher_util.so
+%{_libdir}/libdotnet_launcher_core.so
%{_libdir}/libni_common.so
%{_libdir}/libtac_common.so
/etc/tmpfiles.d/%{name}.conf