Make it runnable with dotnet packages
authorpius.lee <pius.lee@samsung.com>
Thu, 28 Jul 2016 04:28:52 +0000 (13:28 +0900)
committerpius.lee <pius.lee@samsung.com>
Thu, 28 Jul 2016 04:28:52 +0000 (13:28 +0900)
add build option for desktop -DNO_TIZEN=1
add config file path build option -DLAUNCHER_PATH=dotnet-launcher.ini
fix bugs in default TPL paths

CMakeLists.txt
packaging/dotnet-launcher.spec
packaging/dotnet.loader
src/launcher.cc
src/launcher.h
src/log.h
src/waiter.cc
src/waiter.h

index b711b0d..8998418 100644 (file)
@@ -1,47 +1,54 @@
 CMAKE_MINIMUM_REQUIRED(VERSION 2.6)
 PROJECT("dotnet-launcher")
 
-INCLUDE(FindPkgConfig)
-PKG_CHECK_MODULES(${PROJECT_NAME} REQUIRED
-       aul
-       dlog
-       ecore
-       bundle
-       dlog
-       launchpad
-       )
+MESSAGE("CMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE}")
+
+IF(DEFINED NO_TIZEN)
+       SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} -DNO_TIZEN")
+ELSE(DEFINED NO_TIZEN)
+       INCLUDE(FindPkgConfig)
+       PKG_CHECK_MODULES(${PROJECT_NAME} REQUIRED aul dlog ecore bundle dlog launchpad)
+ENDIF(DEFINED NO_TIZEN)
 
 FOREACH(flag ${${PROJECT_NAME}_CFLAGS})
        SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} ${flag}")
 ENDFOREACH(flag)
 
+IF(DEFINED LAUNCHER_PATH)
+       SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} -DLAUNCHER_PATH=${LAUNCHER_PATH}")
+ENDIF(DEFINED LAUNCHER_PATH)
+
+
+SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} -std=c++11")
 SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} -Wl,-zdefs" )
 SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} -fvisibility=hidden")
 SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} -fPIE")
 SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} -fdata-sections -ffunction-sections -Wl,--gc-sections")
 SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} -D_FILE_OFFSET_BITS=64")
 
-SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${EXTRA_CFLAGS}")
-SET(CMAKE_C_FLAGS_DEBUG "-O0 -g")
-SET(CMAKE_C_FLAGS_RELEASE "-O2")
+SET(CMAKE_CXX_FLAGS "${CMAKE_C_FLAGS} ${EXTRA_CFLAGS}")
+SET(CMAKE_CXX_FLAGS_DEBUG "-O0 -g")
+SET(CMAKE_CXX_FLAGS_RELEASE "-O2")
 SET(CMAKE_EXE_LINKER_FLAGS "-Wl,--as-needed")
 
 SET(${PROJECT_NAME}_SOURCE_FILES
        src/launcher.cc
        src/waiter.cc
 )
+
 ADD_EXECUTABLE(${PROJECT_NAME} ${${PROJECT_NAME}_SOURCE_FILES})
 
-TARGET_LINK_LIBRARIES(${PROJECT_NAME} aul)
-TARGET_LINK_LIBRARIES(${PROJECT_NAME} ${${PROJECT_NAME}_LDFLAGS} "-pie")
+IF(NOT DEFINED NO_TIZEN)
+       TARGET_LINK_LIBRARIES(${PROJECT_NAME} aul)
+ENDIF(NOT DEFINED NO_TIZEN)
+TARGET_LINK_LIBRARIES(${PROJECT_NAME} ${${PROJECT_NAME}_LDFLAGS} "-pie -ldl")
 
 SET_TARGET_PROPERTIES(${PROJECT_NAME}
        PROPERTIES SKIP_BUILD_RPATH TRUE
        ) # remove rpath option that is automatically generated by cmake.
 
-CONFIGURE_FILE(${PACKAGE_NAME}.xml.in ${PACKAGE_NAME}.xml)
-
-INSTALL(TARGETS ${PROJECT_NAME} DESTINATION bin)
-INSTALL(FILES ${PACKAGE_NAME}.xml DESTINATION ${MANIFESTDIR})
-INSTALL(FILES packaging/dotnet.loader DESTINATION ${LOADERDIR})
-
+IF(NOT DEFINED NO_TIZEN)
+       INSTALL(TARGETS ${PROJECT_NAME} DESTINATION ${BINDIR})
+       INSTALL(FILES packaging/dotnet.loader DESTINATION ${LOADERDIR})
+       INSTALL(FILES packaging/dotnet-launcher.ini DESTINATION ${CONFIGDIR})
+ENDIF(NOT DEFINED NO_TIZEN)
index c9dca6e..2bbc40a 100644 (file)
@@ -1,8 +1,8 @@
 Name:       dotnet-launcher
 Summary:    Launchpad plugin for dotnet apps
-Version:    0.1.0
+Version:    0.0.1
 Release:    1
-Group:      Application Framework/Daemons
+Group:      Application Framework/Application State Management
 License:    Apache License, Version 2.0
 Source0:    %{name}-%{version}.tar.gz
 
@@ -21,25 +21,28 @@ Requires(postun): /sbin/ldconfig
 Requires(postun): /usr/bin/systemctl
 Requires(preun): /usr/bin/systemctl
 
-%define _sys_bin %{TZ_SYS_BIN}
-%define _sys_sbin %{TZ_SYS_SBIN}
-%define _sys_share %{TZ_SYS_RO_SHARE}
-%define _manifestdir %{TZ_SYS_RO_PACKAGES}
-%define _loaderdir %{TZ_SYS_RO_SHARE}/aul
+%define _loaderdir %{_prefix}/share/aul
+%define _configdir /etc
 
 %description
-Launchpad for dotnet apps
+Launchpad plugin for launching dotnet apps
 
 %prep
 %setup -q
 
 %build
+%if 0%{?tizen_build_devel_mode}
+%define _buildmode Debug
+%else
+%define _buildmode Release
+%endif
 cmake \
        -DCMAKE_INSTALL_PREFIX=%{_prefix} \
-       -DMANIFESTDIR=%{_manifestdir} \
        -DPACKAGE_NAME=%{name} \
        -DBINDIR=%{_bindir} \
        -DLOADERDIR=%{_loaderdir} \
+       -DCONFIGDIR=%{_configdir} \
+       -DCMAKE_BUILD_TYPE=%{_buildmode} \
        -DVERSION=%{version}
 
 make %{?jobs:-j%jobs}
@@ -48,11 +51,8 @@ make %{?jobs:-j%jobs}
 rm -rf %{buildroot}
 %make_install
 
-%post
-
 %files
-%manifest dotnet-launchpad.manifest
-%{_manifestdir}/%{name}.xml
+%manifest dotnet-launcher.manifest
+%config /etc/dotnet-launcher.ini
 %{_loaderdir}/dotnet.loader
-%attr(0755,root,root) %{_bindir}/dotnet-loader
-%caps(cap_mac_admin,cap_mac_override,cap_setgid=ei) %{_bindir}/dotnet-loader
+%caps(cap_mac_admin,cap_setgid=ei) %{_bindir}/dotnet-launcher
index 43e2d21..67094b9 100644 (file)
@@ -1,6 +1,6 @@
 [LOADER]
-NAME    dotnet-loader
-EXE     /usr/bin/dotnet-loader
+NAME    dotnet-launcher
+EXE     /usr/bin/dotnet-launcher
 APP_TYPE        dotnet
 DETECTION_METHOD        TIMEOUT|DEMAND
 TIMEOUT         5000
index 631f7e5..66bc440 100644 (file)
@@ -1,9 +1,13 @@
+#include <dlfcn.h>
+
 #include <cstdlib>
 #include <cstring>
 #include <vector>
 #include <string>
 #include <set>
 #include <sstream>
+#include <fstream>
+#include <memory>
 
 #include <dirent.h>
 #include <sys/stat.h>
 
 #include "tini.hpp"
 
-#ifndef LAUNCHER_CONFIG
-#define LAUNCHER_CONFIG "/usr/share/dotnet/dotnet-launcher.ini"
+#include "launcher.h"
+
+namespace dotnet {
+namespace runtime {
+
+#ifdef LAUNCHER_PATH
+#define __STR(x) #x
+#define __XSTR(x) __STR(x)
+#define LAUNCHER_CONFIG __XSTR(LAUNCHER_PATH)
+#else
+#define LAUNCHER_CONFIG "/etc/dotnet-launcher.ini"
+#endif
+static const std::string LauncherConfig(LAUNCHER_CONFIG);
+#ifdef LAUNCHER_PATH
+#undef __STR
+#undef __XSTR
+#undef LAUNCHER_CONFIG
+#undef LAUNCHER_PATH
 #endif
 
 static std::string AbsolutePath(const std::string& path)
@@ -23,7 +43,7 @@ static std::string AbsolutePath(const std::string& path)
   std::string absPath;
 
   char realPath[PATH_MAX];
-  if (realpath(path, realPath) != nullptr && realPath[0] != '\0')
+  if (realpath(path.c_str(), realPath) != nullptr && realPath[0] != '\0')
   {
     absPath.assign(realPath);
   }
@@ -52,7 +72,11 @@ static std::string AssembliesInDirectory(const char *directory)
 
   DIR* dir = opendir(directory);
 
-  if (dir == nullptr) return std::string();
+  if (dir == nullptr)
+  {
+    _ERR("can not open directory : %s", directory);
+    return std::string();
+  }
 
   std::map<std::pair<std::string, std::string>, bool> addedAssemblies;
 
@@ -86,13 +110,18 @@ static std::string AssembliesInDirectory(const char *directory)
     std::string filename(entry->d_name);
     int extPos = filename.find_last_of('.');
     if (extPos <= 0) continue;
+    bool notUsedExtension = true;
     for (auto ext : tpaExtensions)
     {
       int extLength = strlen(ext);
-      if (filename.compare(extPos-1, extLength, ext) != 0)
-        continue;
-    }
 
+      if (filename.compare(extPos, extLength, ext) == 0)
+      {
+        notUsedExtension = false;
+        break;
+      }
+    }
+    if (notUsedExtension) continue;
 
     std::string filenameWithoutExt;
     bool isNativeImage = extPos > niExtensionSize ?
@@ -108,7 +137,6 @@ static std::string AssembliesInDirectory(const char *directory)
     std::string ext = filename.substr(extPos);
 
     std::pair<std::string, std::string> key(filenameWithoutExt, ext);
-    std::cout << "  " << filenameWithoutExt << ext << "  " << isNativeImage << std::endl;
     if (addedAssemblies.count(key))
     {
       isNativeImage = isNativeImage || addedAssemblies[key];
@@ -128,6 +156,7 @@ static std::string AssembliesInDirectory(const char *directory)
     }
     tpaList.append(pair.first.second);
     tpaList.append(":");
+    _DBG("TPA : %s/%s%s", directory, pair.first.first.c_str(), pair.first.second.c_str());
   }
 
   closedir(dir);
@@ -144,46 +173,56 @@ Launcher::~Launcher()
 
 void Launcher::Initialize()
 {
-  std::ifstream iniStream(LAUNCHER_CONFIG);
+  std::ifstream iniStream(LauncherConfig);
   std::stringstream iniString;
   iniString << iniStream.rdbuf();
   tini::ini launcherIni(iniString);
 
-  auto &dotnet = ini["dotnet"];
+  _DBG("config file [%s]", LauncherConfig.c_str());
+  _DBG("%s", launcherIni.to_string().c_str());
+
+  auto &dotnet = launcherIni["dotnet"];
   if (dotnet.find("libcoreclr") == dotnet.end())
     dotnet["libcoreclr"] = "libcoreclr.so";
   if (dotnet.find("coreclr_dir") == dotnet.end())
     dotnet["coreclr_dir"] = "/usr/share/dotnet";
   if (dotnet.find("tpa_dir") == dotnet.end())
     dotnet["tpa_dir"] = dotnet["coreclr_dir"] + ":" + "/usr/share/assemblies";
-  if (dontet.find("native_so_search_dirs") == dotnet.end())
+  if (dotnet.find("native_so_search_dirs") == dotnet.end())
     dotnet["native_so_search_dirs"] = dotnet["tpa_dir"];
 
+  _DBG("libcoreclr : %s", dotnet["libcoreclr"].c_str());
+  _DBG("coreclr_dir : %s", dotnet["coreclr_dir"].c_str());
+  _DBG("tpa_dir : %s", dotnet["tpa_dir"].c_str());
+  _DBG("native_so_search_dirs : %s", dotnet["native_so_search_dirs"].c_str());
+
   std::string libcoreclr = dotnet["coreclr_dir"] + "/" + dotnet["libcoreclr"];
   std::string tpaDirs = dotnet["tpa_dirs"];
   std::string nativeSoSearchDirs = dotnet["native_so_search_dirs"];
 
-  void* coreclrLib = dlopen(libcoreclr, RTLD_NOW | RTLD_LOCAL);
+  _DBG("libcoreclr.so : [%s]", libcoreclr.c_str());
+
+  coreclrLib = dlopen(libcoreclr.c_str(), RTLD_NOW | RTLD_LOCAL);
   if (coreclrLib == nullptr)
   {
     char *err = dlerror();
     _ERR("dlopen failed to open libcoreclr.so with error %s", err);
-    goto CoreClrLibClose;
+    return;
   }
 
   initializeCoreCLR = (coreclr_initialize_ptr)dlsym(coreclrLib, "coreclr_initialize");
   executeAssembly = (coreclr_execute_assembly_ptr)dlsym(coreclrLib, "coreclr_execute_assembly");
   shutdownCoreCLR = (coreclr_shutdown_ptr)dlsym(coreclrLib, "coreclr_shutdown");
 
-  if (coreclr_initialize_ptr == nullptr)
+  if (initializeCoreCLR == nullptr)
   {
-    _ERR("coreclr_initialize_ptr not found in the libcoreclr.so");
+    _ERR("coreclr_initialize not found in the libcoreclr.so");
   }
-  else if (coreclr_execute_assembly_ptr == nullptr)
+  else if (executeAssembly == nullptr)
   {
     _ERR("coreclr_execute_assembly_ptr not found in the libcoreclr.so");
   }
-  else if (coreclr_shutdown_ptr == nullptr)
+  else if (shutdownCoreCLR == nullptr)
   {
     _ERR("coreclr_shutdown_ptr not found in the libcoreclr.so");
   }
@@ -193,29 +232,27 @@ void Launcher::Initialize()
     std::string s;
     while (std::getline(f, s, ':'))
     {
-      TrustedPlatformAssemblies += AssembliesInDirectory(s);
+      TrustedPlatformAssemblies += AssembliesInDirectory(s.c_str());
     }
     NativeDllSearchDirectories = nativeSoSearchDirs; 
     AppDomainCompatSwitch = "UseLatestBehaviorWhenTFMNotSpecified";
   }
+}
 
-CoreClrLibClose:
+void Launcher::Dispose()
+{
   if (dlclose(coreclrLib) != 0)
   {
     _ERR("libcoreclr.so close failed");
   }
 }
 
-void Launcher::Dispose()
-{
-}
-
 void Launcher::Launch(const string& exe_path, int argc, char *argv[])
 {
-  std::string bin_path = Basename(exe_path);
-  std::string app_home = Basename(app_path);
+  std::string bin_path = Basename(AbsolutePath(exe_path));
+  std::string app_home = Basename(bin_path);
   std::string lib_path = app_home + "/lib";
-  std::string app_path = bin_path + ":" + lib_path
+  std::string app_path = bin_path + ":" + lib_path;
   std::string app_ni_path = app_path;
   std::string nativeDllSearchDirectories = NativeDllSearchDirectories + app_path;
 
@@ -237,51 +274,82 @@ void Launcher::Launch(const string& exe_path, int argc, char *argv[])
     AppDomainCompatSwitch.c_str()
   };
 
+  //_DBG("trusted platform assemblies : %s", propertyValues[0]);
+  _DBG("app_path : %s", propertyValues[1]);
+  _DBG("app_ni_path : %s", propertyValues[2]);
+  _DBG("native dll search path : %s", propertyValues[3]);
+  _DBG("app domain compat switch : %s", propertyValues[4]);
+
   void* hostHandle;
   unsigned int domainId;
 
-  int st = initializeCoreCLR(exe_path,
+  _DBG("before initialize coreclr");
+
+  int st = initializeCoreCLR(exe_path.c_str(),
       "tizen_dotnet_launcher",
       sizeof(propertyKeys) / sizeof(propertyKeys[0]),
       propertyKeys,
       propertyValues,
       &hostHandle,
       &domainId);
+
+  _DBG("after initialize coreclr");
   if (st < 0)
   {
     // initialize coreclr fail
+    _ERR("initialize core clr fail! (0x%08x)", st);
+    _DBG("check your smack label dll and every directories on the way to dlls");
     exit(-1);
   }
 
   unsigned int exitCode;
-  st = executeAssembly(hostHandle, domainId, argc, argv, exe_path, &exitCode);
+  st = executeAssembly(hostHandle, domainId,
+      argc, const_cast<const char**>(argv), exe_path.c_str(), &exitCode);
   if (st < 0)
   {
     // execute coreclr fail
+    _ERR("execute core clr fail! (0x%08x)", st);
     exit(-1);
   }
+  _DBG("after execute coreclr");
 
   st = shutdownCoreCLR(hostHandle, domainId);
   if (st < 0)
   {
     // shutdown fail
+    _ERR("shutdown core clr fail! (0x%08x)", st);
     exit(-1);
   }
 }
 
+}  // namespace runtime
+}  // namespace dotnet
+
+using dotnet::runtime::Launcher;
+using dotnet::runtime::Waiter;
+
 int main(int argc, char *argv[])
 {
+  _DBG("launcher started");
+
+  for (int i=0; i<argc; i++)
+  {
+    _DBG("argv[%d](%d) : [%s]", i, strlen(argv[i]), argv[i]);
+  }
+
   std::unique_ptr<Launcher> launcher(new Launcher());
   auto on_prepare = [&launcher]()
   {
-    launcher.Initialize();
+    launcher->Initialize();
   };
   auto on_requested = [&launcher]()
   {
   };
   auto on_executed = [&launcher](const std::string& path, int argc, char *argv[])
   {
-    launcher.launch(path, argc, argv);
-  }
+    _DBG("EXECUTE %s", path.c_str());
+    launcher->Launch(path, argc, argv);
+  };
   std::unique_ptr<Waiter> waiter(new Waiter(on_prepare, on_requested, on_executed));
+  waiter->WaitToLaunching(argc, argv);
 }
index eb53100..946fed4 100644 (file)
@@ -45,6 +45,8 @@ class Launcher
     string TrustedPlatformAssemblies;
     string NativeDllSearchDirectories;
     string AppDomainCompatSwitch;
+
+    void *coreclrLib;
 };
 
 }  // namespace runtime
index c5b6f9d..59f2dc9 100644 (file)
--- a/src/log.h
+++ b/src/log.h
@@ -1,7 +1,14 @@
 #ifndef __LOG_H__
 #define __LOG_H__
 
+#ifndef NO_TIZEN
 #include <dlog.h>
+#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)
+#endif
 
 #ifdef  LOG_TAG
 #undef  LOG_TAG
 #define LOG_TAG "NETCORE_LAUNCHER"
 
 #ifndef _ERR
-#define _ERR(fmt, args...) LOGE(fmt "\n", __func__, __LINE__, ##args)
+#define _ERR(fmt, args...) LOGE(fmt "\n", ##args)
 #endif
 
 #ifndef _DBG
-#define _DBG(fmt, args...) LOGD(fmt "\n", __func__, __LINE__, ##args)
+#define _DBG(fmt, args...) LOGD(fmt "\n", ##args)
 #endif
 
 #ifndef _INFO
-#define _INFO(fmt, args...) LOGI(fmt "\n", __func__, __LINE__, ##args)
+#define _INFO(fmt, args...) LOGI(fmt "\n", ##args)
 #endif
 
 #endif /* __LOG_H__ */
index 0f622be..7f6eeef 100644 (file)
@@ -1,20 +1,27 @@
-#include "waiter.h"
 
 #include <poll.h>
+
+#ifndef NO_TIZEN
 #include <launchpad.h>
+#endif
 
 #include <memory>
 #include <vector>
 #include <map>
 #include <poll.h>
 
+#include <iostream>
+
+#include "waiter.h"
+#include "log.h"
+
 namespace dotnet {
 namespace runtime {
 
-struct Waiter::FdHandler;
+struct FdHandler
 {
   pollfd *info;
-  Receiver re;
+  Receiver receiver;
 };
 
 static volatile bool Waiting_;
@@ -25,9 +32,11 @@ static Waiter::AppInfo AppInfo_;
 void Waiter::OnPrepare()
 {
   // preload the libraries.
+  if (prepare_ != nullptr)
+    prepare_();
 }
 
-void Waiter::OnLaunchRequested()
+void Waiter::OnLaunchRequested(const AppInfo& info)
 {
   // do some job on user id is still system
 }
@@ -37,6 +46,7 @@ void Waiter::OnWaiting()
   // Start the loop
   Waiting_ = true;
 
+  _DBG("start polling...");
   while (Waiting_)
   {
     if (poll(Fdlist_.data(), Fdlist_.size(), -1) < 0)
@@ -45,9 +55,10 @@ void Waiter::OnWaiting()
     for (auto &p : Fdlist_)
     {
       if ( (p.revents | POLLIN) != 0 )
-        Handlers_[p.fd].receiver();
+        Handlers_[p.fd].receiver(p.fd);
     }
   }
+  _DBG("end polling...");
 }
 
 void Waiter::Stop()
@@ -62,6 +73,8 @@ void Waiter::RegisterFd(int fd, Receiver receiver)
 {
   // register fd should be caught in event loop
 
+  _DBG("Register fd %d", fd);
+
   pollfd info;
   info.fd = fd;
   info.events = POLLIN;
@@ -96,20 +109,28 @@ Waiter::~Waiter()
 {
 }
 
-void Waiter::WaitToLaunching(int argc, char *argv[])
+int Waiter::WaitToLaunching(int argc, char *argv[])
 {
+#ifndef NO_TIZEN
   auto on_create = [](bundle *extra, int type, void *user_data)
   {
+    _DBG("on_create..."); // XXX
     Waiter* waiter = static_cast<Waiter*>(user_data);
     waiter->OnPrepare();
   };
 
   auto on_launch = [](int argc, char **argv, const char *app_path,
       const char *appid, const char *pkgid,
-      const char *pkg_type, void *user_data)
+      const char *pkg_type, void *user_data) -> int
   {
+    _DBG("on_launch..."); // XXX
     Waiter* waiter = static_cast<Waiter*>(user_data);
 
+    _DBG ("app path : %s", app_path);
+    _DBG ("app id : %s", appid);
+    _DBG ("pkg id : %s", pkgid);
+    _DBG ("pkg type : %s", pkg_type);
+
     AppInfo info = {
       AppPath : app_path,
       AppId : appid,
@@ -118,43 +139,51 @@ void Waiter::WaitToLaunching(int argc, char *argv[])
     };
 
     waiter->OnLaunchRequested(info);
+    return 0;
   };
 
-  auto on_terminate = [](int argc, char **argv, void *user_data)
+  auto on_terminate = [](int argc, char **argv, void *user_data) -> int
   {
+    _DBG("on_terminate..."); // XXX
     Waiter* waiter = static_cast<Waiter*>(user_data);
-    waiter->executor_(argv[LOADER_ARG_PATH], argc, argv);
+    waiter->executor_(argv[0], argc, argv);
+    return 0;
   };
 
   auto on_start_loop = [](void *user_data)
   {
+    _DBG("on_start_loop..."); // XXX
     Waiter* waiter = static_cast<Waiter*>(user_data);
     waiter->OnWaiting();
   };
 
   auto on_quit_loop = [](void *user_data)
   {
+    _DBG("on_quit_loop..."); // XXX
     Waiter* waiter = static_cast<Waiter*>(user_data);
     waiter->Stop();
   };
 
   auto on_add_fd = [](void *user_data, int fd, loader_receiver_cb receiver)
   {
+    _DBG("on_add_fd..."); // XXX
     Waiter* waiter = static_cast<Waiter*>(user_data);
     waiter->RegisterFd(fd, receiver);
   };
 
   auto on_remove_fd = [](void *user_data, int fd)
   {
+    _DBG("on_remove_fd..."); // XXX
     Waiter* waiter = static_cast<Waiter*>(user_data);
     waiter->DeregisterFd(fd);
   };
 
+  _DBG("launcher wait..."); // XXX
   loader_lifecycle_callback_s callbacks = {
     .create = on_create,
     .launch = on_launch,
     .terminate = on_terminate
-  }
+  };
 
        loader_adapter_s adapter = {
                .loop_begin = on_start_loop,
@@ -164,6 +193,18 @@ void Waiter::WaitToLaunching(int argc, char *argv[])
        };
 
   return launchpad_loader_main(argc, argv, &callbacks, &adapter, this);
+#else
+  if (argc < 2) return -1;
+  this->OnPrepare();
+    AppInfo info = {
+      AppPath : argv[1],
+      AppId : "",
+      PkgId : "",
+      PkgType : ""
+    };
+  this->OnLaunchRequested(info);
+  this->executor_(argv[1], argc, argv);
+#endif
 }
 
 }  // namespace runtime
index 4315d0c..5fa9dd3 100644 (file)
@@ -1,10 +1,13 @@
 #include <string>
+#include <functional>
 
 using std::string;
 
 namespace dotnet {
 namespace runtime {
 
+using Receiver = std::function<void(int)>;
+
 class Waiter
 {
   public:
@@ -16,7 +19,6 @@ class Waiter
       string PkgType;
     };
     using Action = std::function<void(void)>;
-    using Receiver = std::function<void(int)>;
     using Executor = std::function<void(const string&, int, char**)>;
 
     Waiter(Action prepare, Action requested, Executor executor);