From 28d852e015b8167e339543e7eac2c61f3324c4b1 Mon Sep 17 00:00:00 2001 From: Jussi Lind Date: Thu, 24 Feb 2011 16:26:13 +0200 Subject: [PATCH] New: Basic implementation of the e-booster. --- debian/applauncherd-launcher.install | 1 + src/CMakeLists.txt | 3 + src/ebooster/CMakeLists.txt | 28 +++++++ src/ebooster/ebooster.cpp | 87 +++++++++++++++++++++ src/ebooster/ebooster.h | 111 +++++++++++++++++++++++++++ src/ebooster/pluginfactory.cpp | 45 +++++++++++ src/invoker/invokelib.h | 3 +- src/invoker/invoker.c | 21 +++-- src/launcherlib/booster.cpp | 16 +++- src/launcherlib/booster.h | 17 +++- src/launcherlib/logger.cpp | 16 ++-- src/mbooster/mbooster.h | 2 +- 12 files changed, 326 insertions(+), 24 deletions(-) create mode 100644 src/ebooster/CMakeLists.txt create mode 100644 src/ebooster/ebooster.cpp create mode 100644 src/ebooster/ebooster.h create mode 100644 src/ebooster/pluginfactory.cpp diff --git a/debian/applauncherd-launcher.install b/debian/applauncherd-launcher.install index cc7e27c..0efa597 100644 --- a/debian/applauncherd-launcher.install +++ b/debian/applauncherd-launcher.install @@ -1,6 +1,7 @@ usr/bin/applauncherd.bin usr/lib/applauncherd/libapplauncherd.so usr/bin/applauncherd +usr/lib/applauncherd/libebooster.so usr/lib/applauncherd/libmbooster.so usr/lib/applauncherd/libqtbooster.so usr/lib/applauncherd/libqdeclarativebooster.so diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index c0cc02c..b228eab 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -7,6 +7,9 @@ add_subdirectory(launcher) # Sub build: launcher library add_subdirectory(launcherlib) +# Sub build: ebooster plugin +add_subdirectory(ebooster) + # Sub build: mbooster plugin add_subdirectory(mbooster) diff --git a/src/ebooster/CMakeLists.txt b/src/ebooster/CMakeLists.txt new file mode 100644 index 0000000..2a38fce --- /dev/null +++ b/src/ebooster/CMakeLists.txt @@ -0,0 +1,28 @@ +# Qt support +include(${QT_USE_FILE}) + +set(LAUNCHER "${CMAKE_HOME_DIRECTORY}/src/launcherlib") +set(COMMON "${CMAKE_HOME_DIRECTORY}/src/common") + +include_directories(${CMAKE_CURRENT_SOURCE_DIR} ${COMMON} ${LAUNCHER}) + +# Hide all symbols except the ones explicitly exported in the code (like main()) +set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fvisibility=hidden") + +# Set sources +set(SRC ebooster.cpp pluginfactory.cpp ${LAUNCHER}/appdata.cpp ${LAUNCHER}/booster.cpp +${LAUNCHER}/connection.cpp ${LAUNCHER}/logger.cpp +${LAUNCHER}/singleinstance.cpp ${LAUNCHER}/socketmanager.cpp +${COMMON}/eventhandler.cpp) + +set(MOC_HDRS ${COMMON}/eventhandler.h) +qt4_wrap_cpp(MOC_SRC ${MOC_HDRS}) + +# Set libraries to be linked. +link_libraries(${MEEGOTOUCH_LIBRARIES} ${LIBDL} ${QT_QTCORE_LIBRARY}) + +# Set executable +add_library(ebooster MODULE ${SRC} ${MOC_SRC}) + +# Add install rule +install(TARGETS ebooster DESTINATION /usr/lib/applauncherd/) diff --git a/src/ebooster/ebooster.cpp b/src/ebooster/ebooster.cpp new file mode 100644 index 0000000..b5893db --- /dev/null +++ b/src/ebooster/ebooster.cpp @@ -0,0 +1,87 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of applauncherd +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "ebooster.h" +#include "logger.h" + +#include + +#ifdef HAVE_MCOMPONENTCACHE +#include +#endif + +const string EBooster::m_socketId = "/tmp/booste"; +const string EBooster::m_temporaryProcessName = "booster-e"; + +const string & EBooster::socketId() const +{ + return m_socketId; +} + +const string & EBooster::socketName() +{ + return m_socketId; +} + +const string & EBooster::temporaryProcessName() +{ + return m_temporaryProcessName; +} + +const string & EBooster::boosterTemporaryProcessName() const +{ + return temporaryProcessName(); +} + +char EBooster::type() +{ + return 'e'; +} + +bool EBooster::preload() +{ + return true; +} + +int EBooster::launchProcess() +{ + Booster::setEnvironmentBeforeLaunch(); + + // Ensure a NULL-terminated argv + char ** dummyArgv = new char * [appData()->argc() + 1]; + const int i2 = appData()->argc(); + for (int i = 0; i < i2; i++) + dummyArgv[i] = strdup(appData()->argv()[i]); + dummyArgv[i2] = NULL; + + // Exec the binary (execv returns only in case of an error). + if (execv(appData()->fileName().c_str(), + dummyArgv)) + { + Logger::logError("EBooster: Couldn't execv '%s': %s", + appData()->fileName().c_str(), + strerror(errno)); + } + + // Delete dummy argv if execv failed + for (int i = 0; i < i2; i++) + delete dummyArgv[i]; + + return EXIT_FAILURE; +} diff --git a/src/ebooster/ebooster.h b/src/ebooster/ebooster.h new file mode 100644 index 0000000..a2bf3d0 --- /dev/null +++ b/src/ebooster/ebooster.h @@ -0,0 +1,111 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of applauncherd +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef EBOOSTER_H +#define EBOOSTER_H + +#include "booster.h" +#include "eventhandler.h" +#include + +using std::tr1::shared_ptr; + +#include + +/*! + \class EBooster + \brief EBooster is a "booster" that only exec()'s the given binary. + + This can be used with e.g. splash screen to launch any application. + */ +class EBooster : public Booster +{ +public: + + //! \brief Constructor + EBooster() {} + + //! \brief Destructor + virtual ~EBooster() {} + + /*! + * \brief Return the socket name common to all EBooster objects. + * \return Path to the socket file. + */ + static const string & socketName(); + + //! Return the process name to be used when booster is not + //! yet transformed into a running application + static const string & temporaryProcessName(); + + //! \reimp + virtual const string & boosterTemporaryProcessName() const; + + //! \reimp + virtual char boosterType() const { return type(); } + + /*! + * \brief Return a unique character ('e') represtenting the type of EBoosters. + * \return Type character. + */ + static char type(); + + //! \reimp + virtual const string & socketId() const; + +protected: + + //! \reimp + virtual int launchProcess(); + + //! \reimp + virtual bool preload(); + +private: + + //! Disable copy-constructor + EBooster(const EBooster & r); + + //! Disable assignment operator + EBooster & operator= (const EBooster & r); + + static const string m_socketId; + + //! Process name to be used when booster is not + //! yet transformed into a running application + static const string m_temporaryProcessName; + + //! wait for socket connection + void accept(); + +private slots: + + //! Qt signal handler for SIGHUP. + void handleSigHup(); + + //! Qt signal handler for theme change + void notifyThemeChange(); + + +#ifdef UNIT_TEST + friend class Ut_EBooster; +#endif +}; + +#endif // EBooster_H diff --git a/src/ebooster/pluginfactory.cpp b/src/ebooster/pluginfactory.cpp new file mode 100644 index 0000000..e3d96fb --- /dev/null +++ b/src/ebooster/pluginfactory.cpp @@ -0,0 +1,45 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of applauncherd +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "ebooster.h" +#include + +extern "C" +{ + // Create a new plugin instance. + Q_DECL_EXPORT void * create() + { + return new EBooster; + } + + Q_DECL_EXPORT char type() + { + return EBooster::type(); + } + + Q_DECL_EXPORT const char * socketName() + { + return EBooster::socketName().c_str(); + } + + Q_DECL_EXPORT const char * temporaryProcessName() + { + return EBooster::temporaryProcessName().c_str(); + } +} diff --git a/src/invoker/invokelib.h b/src/invoker/invokelib.h index 9bbcdb6..7719510 100644 --- a/src/invoker/invokelib.h +++ b/src/invoker/invokelib.h @@ -30,6 +30,7 @@ void invoke_send_str(int fd, char *str); #define INVOKER_M_SOCK "/tmp/boostm" #define INVOKER_QT_SOCK "/tmp/boostq" -#define INVOKER_QDECL_SOCK "/tmp/boostd" +#define INVOKER_QDECL_SOCK "/tmp/boostd" +#define INVOKER_EXEC_SOCK "/tmp/booste" #endif diff --git a/src/invoker/invoker.c b/src/invoker/invoker.c index 440c0a3..15571f3 100644 --- a/src/invoker/invoker.c +++ b/src/invoker/invoker.c @@ -56,11 +56,12 @@ static const unsigned char EXIT_STATUS_APPLICATION_CONNECTION_LOST = 0xfa; static const unsigned char EXIT_STATUS_APPLICATION_NOT_FOUND = 0x7f; // Enumeration of possible application types: -// M_APP : MeeGo Touch application -// QT_APP : Qt/generic application -// QDECL_APP: QDeclarative (QML) application +// M_APP : MeeGo Touch application +// QT_APP : Qt/generic application +// QDECL_APP : QDeclarative (QML) application +// EXEC_APP : Executable generic application (can be used with splash screen) // -enum APP_TYPE { M_APP, QT_APP, QDECL_APP, UNKNOWN_APP }; +enum APP_TYPE { M_APP, QT_APP, QDECL_APP, EXEC_APP, UNKNOWN_APP }; // Environment extern char ** environ; @@ -210,6 +211,10 @@ static int invoker_init(enum APP_TYPE app_type) { strncpy(sun.sun_path, INVOKER_QDECL_SOCK, maxSize); } + else if (app_type == EXEC_APP) + { + strncpy(sun.sun_path, INVOKER_EXEC_SOCK, maxSize); + } else { die(1, "Unknown type of application: %d\n", app_type); @@ -402,8 +407,10 @@ static void usage(int status) "TYPE chooses the type of booster used. Qt-booster may be used to\n" "launch anything. Possible values for TYPE:\n" " m Launch a MeeGo Touch application.\n" - " qt Launch a Qt application.\n" - " d Launch a Qt Declarative (QML) application.\n\n" + " q (or qt) Launch a Qt application.\n" + " d Launch a Qt Declarative (QML) application.\n" + " e Launch any application, even if it's not a library.\n" + " Can be used if only splash screen is wanted.\n\n" "Options:\n" " -c, --creds Print Aegis security credentials (if enabled).\n" " -d, --delay SECS After invoking sleep for SECS seconds\n" @@ -650,6 +657,8 @@ int main(int argc, char *argv[]) app_type = QT_APP; else if (strcmp(optarg, "d") == 0) app_type = QDECL_APP; + else if (strcmp(optarg, "e") == 0) + app_type = EXEC_APP; else { report(report_error, "Unknown application type: %s \n", optarg); diff --git a/src/launcherlib/booster.cpp b/src/launcherlib/booster.cpp index 91b9c82..4050d53 100644 --- a/src/launcherlib/booster.cpp +++ b/src/launcherlib/booster.cpp @@ -298,7 +298,7 @@ void Booster::renameProcess(int parentArgc, char** parentArgv, } } -int Booster::launchProcess() +void Booster::setEnvironmentBeforeLaunch() { // Possibly restore process priority errno = 0; @@ -342,9 +342,6 @@ int Booster::launchProcess() } #endif - // Load the application and find out the address of main() - void* handle = loadMain(); - // Duplicate I/O descriptors for (unsigned int i = 0; i < m_appData->ioDescriptors().size(); i++) { @@ -369,6 +366,17 @@ int Booster::launchProcess() char * launch = const_cast(strstr(m_appData->argv()[0], ".launch")); *launch = '\0'; } +} + +int Booster::launchProcess() +{ + setEnvironmentBeforeLaunch(); + + // Load the application and find out the address of main() + void* handle = loadMain(); + + // Set dumpable flag + prctl(PR_SET_DUMPABLE, 1); // Set dumpable flag prctl(PR_SET_DUMPABLE, 1); diff --git a/src/launcherlib/booster.h b/src/launcherlib/booster.h index 90dc282..0f16437 100644 --- a/src/launcherlib/booster.h +++ b/src/launcherlib/booster.h @@ -81,7 +81,7 @@ public: /*! * \brief Run the application to be invoked. - * This method causes the application binary to be loaded + * By default, this method causes the application binary to be loaded * using dlopen(). Program execution jumps to the address of * "main()" found in the newly loaded library. The Booster process * exits with corresponding exit-code after the execution of @@ -146,6 +146,18 @@ public: protected: + /*! + * Set process environment (UID, GID..) before launch. + * Re-implement if needed. This is automatically called by + * launchProcess(). + */ + virtual void setEnvironmentBeforeLaunch(); + + /*! Load the library and jump to main. + * Re-implement if needed. + */ + virtual int launchProcess(); + /*! * \brief Preload libraries / initialize cache etc. * Called from initialize if not in the boot mode. @@ -190,9 +202,6 @@ private: //! and signal that a new booster can be created. void sendDataToParent(); - //! Load the library and jump to main - int launchProcess(); - //! Helper method: load the library and find out address for "main". void* loadMain(); diff --git a/src/launcherlib/logger.cpp b/src/launcherlib/logger.cpp index 7f1fd24..e89fb95 100644 --- a/src/launcherlib/logger.cpp +++ b/src/launcherlib/logger.cpp @@ -26,7 +26,7 @@ bool Logger::m_isOpened = false; -bool Logger::m_debugMode = false; +bool Logger::m_debugMode = false; void Logger::openLog(const char * progName) { @@ -46,15 +46,15 @@ void Logger::closeLog() void Logger::writeLog(const int priority, const char * format, va_list ap) { - if (Logger::m_isOpened) + // In debug mode everything is printed also to stdout + if (m_debugMode) { - // In debug mode everything is printed also to stdout - if (m_debugMode) - { - vprintf(format, ap); - printf("\n"); - } + vprintf(format, ap); + printf("\n"); + } + if (Logger::m_isOpened) + { // Print to syslog vsyslog(priority, format, ap); } diff --git a/src/mbooster/mbooster.h b/src/mbooster/mbooster.h index af72cee..4fc34f2 100644 --- a/src/mbooster/mbooster.h +++ b/src/mbooster/mbooster.h @@ -64,7 +64,7 @@ public: virtual char boosterType() const { return type(); } /*! - * \brief Return a unique character ('d') represtenting the type of MBoosters. + * \brief Return a unique character ('m') represtenting the type of MBoosters. * \return Type character. */ static char type();