Merge branch 'master' into my-master

pull/1/head
Jussi Lind 15 years ago
commit 9a385e95ea

@ -29,16 +29,43 @@ Using applauncherd
Binaries intended to be run with applauncherd should be compiled with -fPIC option to produce position independent code. In order to produce a position independent executable, -pie option and -rdynamic options can be used in linking. This allows the result to be executed traditionally and with the launcher.
To improve linking and load times of shared object libraries the size of dynamic export table it is encouraged to hide the unnecessary symbols from the resulting binary by using -fvisibility=hidden and -fvisibility-inlines-hidden flags in compilation as well.
To improve linking and load times of shared object libraries the size of dynamic export table it is encouraged to hide the unnecessary symbols from the resulting binary by using -fvisibility=hidden and -fvisibility-inlines-hidden flags in compilation as well.
Manual settings for QMake
Using QMake
-------------------------
If you are using QMake, making your application boostable is just a
matter of installing libmeegotouch-dev package and adding the following
line to your .pro file:
CONFIG += meegotouch-boostable
The meegotouch-boostable configuration option includes the meegotouch
option (so you don't have to specify it explicitly) and ultimately
uses pkg-config to get the correct flags.
Using QMake with pkg-config
-------------------------
If you are using QMake, you can define following variables in .pro file:
If you want to use pkg-config directly for some reason, you can do it
by adding the following lines to your .pro file:
QMAKE_CXXFLAGS += `pkg-config --cflags meegotouch-boostable`
QMAKE_LFLAGS += `pkg-config --libs meegotouch-boostable`
Note that you still have to install the libmeegotouch-dev package.
Manual settings for QMake
-------------------------
As a last resort, you can define following variables in .pro file:
QMAKE_CXXFLAGS += -fPIC -fvisibility=hidden -fvisibility-inlines-hidden
QMAKE_LFLAGS += -pie -rdynamic
Note that you have to update the flags manually if there are any changes in
the required flags.
Manual settings for CMake
-------------------------
@ -55,13 +82,9 @@ To improve linking and load times of shared object libraries the size of dynamic
pkg-config --cflags --libs meegotouch-boostable
And with qmake:
CONFIG += meegotouch-boostable
CMake also has a pkg-config support.
When using these, your application must build-depend on applauncherd-dev.
When using these, your application must build-depend on libmeegotouch-dev.
Symbol visibility
-----------------

@ -4,11 +4,7 @@
</provide>
<request>
<credential name="CAP::setgid"/>
<credential name="CAP::setuid"/>
<credential name="CAP::setfcap"/>
<credential name="CAP::setpcap"/>
<credential name="CAP::sys_nice"/>
<credential match="CAP::*"/>
<credential name="drm"/>
<credential name="Cellular"/>
<credential name="ReadUserData"/>

@ -1,4 +1,5 @@
usr/bin/fala_ft_hello
usr/bin/fala_status.launch
usr/bin/fala_ft_hello1
usr/bin/fala_ft_hello2
usr/bin/fala_ft_hello.launch

20
debian/changelog vendored

@ -1,3 +1,19 @@
applauncherd (0.10.3) stable; urgency=low
* Changes: pass and set gid and uid from invoker process to launcher
-- Nimika Keshri <nimika.1.keshri@nokia.com> Fri, 20 Aug 2010 11:16:01 +0300
applauncherd (0.10.2) stable; urgency=low
* Changes: close connection with invoker if --wait-term param is not used
* Changes: Replaced references to Matti with TDriver
* Changes: sending application exit status to invoker stubs, code refactoring
* Changes: return application's exit status to invoker
* Changes: Changed the order of provide and request in applauncherd-launcher.aegis
-- Nimika Keshri <nimika.1.keshri@nokia.com> Tue, 17 Aug 2010 15:41:40 +0300
applauncherd (0.10.1) stable; urgency=low
* Fixes: NB#184761 - Application launched with applauncher does not generate core dumps
@ -35,7 +51,7 @@ applauncherd (0.8.0) stable; urgency=low
applauncherd (0.7.0-2) stable; urgency=low
* Fixes: NB#176326 - Conndlgs launched using Applauncherd respawns until respawn limit
-- Antti Kervinen <antti.kervinen@nokia.com> Tue, 07 Jul 2010 12:21:29 +0300
applauncherd (0.7.0-1) stable; urgency=low
@ -44,7 +60,7 @@ applauncherd (0.7.0-1) stable; urgency=low
* Dbg packages added: applauncherd-dbg, applauncherd-invoker-dbg, applauncherd-launcher-dbg and applauncherd-testapps-dbg
* Fixes: NB#177439, invoker starts reloading cache too soon
* Implemented: SWP#DUI-3384
-- Antti Kervinen <antti.kervinen@nokia.com> Tue, 07 Jul 2010 10:10:29 +0300
applauncherd (0.6.0-1) stable; urgency=low

@ -33,6 +33,7 @@ const uint32_t INVOKER_MSG_EXEC = 0xe8ec0000;
const uint32_t INVOKER_MSG_ARGS = 0xa4650000;
const uint32_t INVOKER_MSG_ENV = 0xe5710000;
const uint32_t INVOKER_MSG_PRIO = 0xa1ce0000;
const uint32_t INVOKER_MSG_IDS = 0xb2df4000;
const uint32_t INVOKER_MSG_IO = 0x10fd0000;
const uint32_t INVOKER_MSG_END = 0xdead0000;
const uint32_t INVOKER_MSG_PID = 0x1d1d0000;

@ -231,8 +231,14 @@ static uint32_t invoker_recv_exit(int fd)
invoke_recv_msg(fd, &action);
if (action != INVOKER_MSG_EXIT)
die(1, "receiving bad exit status (%08x)\n", action);
{
// probably boosted application process was killed somehow
// let's get applauncherd process some time to cope with this situation
sleep(1);
// if nothing happend, just exit with error message
die(1, "receiving bad exit status (%08x)\n", action);
}
/* Receive pid. */
invoke_recv_msg(fd, &status);
return status;
@ -296,6 +302,18 @@ static bool invoker_send_prio(int fd, int prio)
return true;
}
static bool invoker_send_ids(int fd, int uid, int gid)
{
// Send action.
invoke_send_msg(fd, INVOKER_MSG_IDS);
invoke_send_msg(fd, uid);
invoke_send_msg(fd, gid);
invoke_recv_ack(fd);
return true;
}
static bool invoker_send_env(int fd)
{
int i, n_vars;
@ -418,6 +436,9 @@ static int invoke(int prog_argc, char **prog_argv, char *prog_name,
prog_prio = 0;
}
int uid = getuid();
int gid = getgid();
int fd = invoker_init(app_type);
invoker_send_magic(fd, magic_options);
@ -425,6 +446,7 @@ static int invoke(int prog_argc, char **prog_argv, char *prog_name,
invoker_send_exec(fd, prog_name);
invoker_send_args(fd, prog_argc, prog_argv);
invoker_send_prio(fd, prog_prio);
invoker_send_ids(fd, uid, gid);
invoker_send_io(fd);
invoker_send_env(fd);
invoker_send_end(fd);

@ -27,7 +27,9 @@ AppData::AppData() :
m_fileName(""),
m_prio(0),
m_entry(NULL),
m_ioDescriptors()
m_ioDescriptors(),
m_gid(0),
m_uid(0)
{}
void AppData::setOptions(int newOptions)
@ -110,6 +112,22 @@ void AppData::setIODescriptors(const vector<int> & newIODescriptors)
m_ioDescriptors = newIODescriptors;
}
void AppData::setIDs(uid_t userId, gid_t groupId)
{
m_uid = userId;
m_gid = groupId;
}
uid_t AppData::userId() const
{
return m_uid;
}
gid_t AppData::groupId() const
{
return m_gid;
}
void AppData::deleteArgv()
{
if (m_argv)

@ -89,6 +89,15 @@ public:
//! Set I/O descriptors
void setIODescriptors(const vector<int> & ioDescriptors);
//! Set user ID and group ID of calling process
void setIDs(uid_t userId, gid_t groupId);
//! Get user ID of calling process
uid_t userId() const;
//! Get group ID of calling process
gid_t groupId() const;
//! Frees the memory reserved for argv
void deleteArgv();
@ -105,6 +114,9 @@ private:
int m_prio;
entry_t m_entry;
vector<int> m_ioDescriptors;
gid_t m_gid;
uid_t m_uid;
};
#endif // APPDATA_H

@ -82,6 +82,12 @@ void Booster::run()
{
if (!m_app.fileName().empty())
{
//check if can close sockets here
if (!m_conn->isReportAppExitStatusNeeded())
{
Connection::closeAllSockets();
}
Logger::logInfo("invoking '%s' ", m_app.fileName().c_str());
int ret_val = launchProcess();
@ -168,6 +174,17 @@ int Booster::launchProcess()
if (!errno && cur_prio < m_app.priority())
setpriority(PRIO_PROCESS, 0, m_app.priority());
// Possible set user ID and group ID of calling process
uid_t uid = getuid();
gid_t gid = getgid();
if (uid != m_app.userId())
setuid(m_app.userId());
if (gid != m_app.groupId())
setgid(m_app.groupId());
// Load the application and find out the address of main()
void* handle = loadMain();
@ -246,3 +263,15 @@ bool Booster::popPriority()
return false;
}
pid_t Booster::invokersPid()
{
if (m_conn->isReportAppExitStatusNeeded())
{
return m_conn->peersPid();
}
else
{
return 0;
}
}

@ -104,6 +104,9 @@ public:
//! Restore the old priority stored by the previous successful setPriority().
bool popPriority();
//! Get invoker's pid
pid_t invokersPid();
protected:
/*!

@ -21,7 +21,8 @@
#include "logger.h"
#include <sys/socket.h>
#include <sys/stat.h> // For chmod
#include <sys/un.h> /* for getsockopt */
#include <sys/stat.h> /* for chmod */
#include <cstring>
#include <cstdlib>
#include <cerrno>
@ -48,7 +49,7 @@ Connection::Connection(const string socketId) :
if (m_curSocket == -1)
{
Logger::logErrorAndDie(EXIT_FAILURE, "socket isn't initialized\n");
Logger::logErrorAndDie(EXIT_FAILURE, "Connection: socket isn't initialized\n");
}
#if defined (HAVE_CREDS) && ! defined (DISABLE_VERIFICATION)
@ -57,7 +58,7 @@ Connection::Connection(const string socketId) :
if (m_credsType == CREDS_BAD)
{
Logger::logError("credentials %s conversion failed \n", m_credsStr);
Logger::logError("Connection: credentials %s conversion failed \n", m_credsStr);
}
#endif
@ -95,7 +96,7 @@ void Connection::initSocket(const string socketId)
int sockfd = socket(PF_UNIX, SOCK_STREAM, 0);
if (sockfd < 0)
Logger::logErrorAndDie(EXIT_FAILURE, "opening invoker socket\n");
Logger::logErrorAndDie(EXIT_FAILURE, "Connection: opening invoker socket\n");
unlink(socketId.c_str());
@ -106,10 +107,10 @@ void Connection::initSocket(const string socketId)
sun.sa_data[maxLen] = '\0';
if (bind(sockfd, &sun, sizeof(sun)) < 0)
Logger::logErrorAndDie(EXIT_FAILURE, "binding to invoker socket\n");
Logger::logErrorAndDie(EXIT_FAILURE, "Connection: binding to invoker socket\n");
if (listen(sockfd, 10) < 0)
Logger::logErrorAndDie(EXIT_FAILURE, "listening to invoker socket\n");
Logger::logErrorAndDie(EXIT_FAILURE, "Connection: listening to invoker socket\n");
chmod(socketId.c_str(), S_IRUSR | S_IWUSR | S_IXUSR |
S_IRGRP | S_IWGRP | S_IXGRP |
@ -125,7 +126,7 @@ bool Connection::acceptConn()
if (m_fd < 0)
{
Logger::logError("accepting connections (%s)\n", strerror(errno));
Logger::logError("Connection: accepting connections (%s)\n", strerror(errno));
return false;
}
@ -139,7 +140,7 @@ bool Connection::acceptConn()
if (!allow)
{
Logger::logError("invoker doesn't have enough credentials to call launcher \n");
Logger::logError("Connection: invoker doesn't have enough credentials to call launcher \n");
sendMsg(INVOKER_MSG_BAD_CREDS);
closeConn();
@ -172,7 +173,7 @@ bool Connection::recvMsg(uint32_t *msg)
int len = sizeof(buf);
ssize_t ret = read(m_fd, &buf, len);
if (ret < len) {
Logger::logError("can't read data from connecton in %s", __FUNCTION__);
Logger::logError("Connection: can't read data from connecton in %s", __FUNCTION__);
*msg = 0;
} else {
Logger::logInfo("%s: %08x", __FUNCTION__, *msg);
@ -202,14 +203,14 @@ const char * Connection::recvStr()
bool res = recvMsg(&size);
if (!res || size == 0 || size > STR_LEN_MAX)
{
Logger::logError("string receiving failed in %s, string length is %d", __FUNCTION__, size);
Logger::logError("Connection: string receiving failed in %s, string length is %d", __FUNCTION__, size);
return NULL;
}
char * str = new char[size];
if (!str)
{
Logger::logError("mallocing in %s", __FUNCTION__);
Logger::logError("Connection: mallocing in %s", __FUNCTION__);
return NULL;
}
@ -217,7 +218,7 @@ const char * Connection::recvStr()
uint32_t ret = read(m_fd, str, size);
if (ret < size)
{
Logger::logError("getting string, got %u of %u bytes", ret, size);
Logger::logError("Connection: getting string, got %u of %u bytes", ret, size);
delete [] str;
return NULL;
}
@ -255,7 +256,7 @@ int Connection::receiveMagic()
sendMsg(INVOKER_MSG_ACK);
else
{
Logger::logError("receiving bad magic version (%08x)\n", magic);
Logger::logError("Connection: receiving bad magic version (%08x)\n", magic);
return -1;
}
}
@ -272,14 +273,14 @@ string Connection::receiveAppName()
recvMsg(&msg);
if (msg != INVOKER_MSG_NAME)
{
Logger::logError("receiving invalid action (%08x)", msg);
Logger::logError("Connection: receiving invalid action (%08x)", msg);
return string();
}
const char* name = recvStr();
if (!name)
{
Logger::logError("receiving application name");
Logger::logError("Connection: receiving application name");
return string();
}
sendMsg(INVOKER_MSG_ACK);
@ -310,6 +311,16 @@ bool Connection::receivePriority()
return true;
}
bool Connection::receiveIDs()
{
recvMsg(&m_uid);
recvMsg(&m_gid);
sendMsg(INVOKER_MSG_ACK);
return true;
}
bool Connection::receiveArgs()
{
// Get argc
@ -321,7 +332,7 @@ bool Connection::receiveArgs()
m_argv = new const char * [m_argc];
if (!m_argv)
{
Logger::logError("reserving memory for argv");
Logger::logError("Connection: reserving memory for argv");
return false;
}
@ -331,14 +342,14 @@ bool Connection::receiveArgs()
m_argv[i] = recvStr();
if (!m_argv[i])
{
Logger::logError("receiving argv[%i]", i);
Logger::logError("Connection: receiving argv[%i]", i);
return false;
}
}
}
else
{
Logger::logError("invalid number of parameters %d", m_argc);
Logger::logError("Connection: invalid number of parameters %d", m_argc);
return false;
}
@ -375,7 +386,7 @@ bool Connection::receiveEnv()
const char * var = recvStr();
if (var == NULL)
{
Logger::logError("receiving environ[%i]", i);
Logger::logError("Connection: receiving environ[%i]", i);
return false;
}
@ -394,13 +405,13 @@ bool Connection::receiveEnv()
{
delete [] var;
var = NULL;
Logger::logWarning("invalid environment data");
Logger::logWarning("Connection: invalid environment data");
}
}
}
else
{
Logger::logError("invalid environment variable count %d", n_vars);
Logger::logError("Connection: invalid environment variable count %d", n_vars);
return false;
}
@ -434,13 +445,13 @@ bool Connection::receiveIO()
if (recvmsg(m_fd, &msg, 0) < 0)
{
Logger::logWarning("recvmsg failed in invoked_get_io: %s", strerror(errno));
Logger::logWarning("Connection: recvmsg failed in invoked_get_io: %s", strerror(errno));
return false;
}
if (msg.msg_flags)
{
Logger::logWarning("unexpected msg flags in invoked_get_io");
Logger::logWarning("Connection: unexpected msg flags in invoked_get_io");
return false;
}
@ -448,7 +459,7 @@ bool Connection::receiveIO()
if (cmsg == NULL || cmsg->cmsg_len != CMSG_LEN(sizeof(m_io)) ||
cmsg->cmsg_level != SOL_SOCKET || cmsg->cmsg_type != SCM_RIGHTS)
{
Logger::logWarning("invalid cmsg in invoked_get_io");
Logger::logWarning("Connection: invalid cmsg in invoked_get_io");
return false;
}
@ -485,6 +496,9 @@ bool Connection::receiveActions()
case INVOKER_MSG_IO:
receiveIO();
break;
case INVOKER_MSG_IDS:
receiveIDs();
break;
case INVOKER_MSG_END:
sendMsg(INVOKER_MSG_ACK);
@ -493,7 +507,7 @@ bool Connection::receiveActions()
return true;
default:
Logger::logError("receiving invalid action (%08x)\n", action);
Logger::logError("Connection: receiving invalid action (%08x)\n", action);
return false;
}
}
@ -519,6 +533,7 @@ bool Connection::receiveApplicationData(AppData & rApp)
rApp.setArgc(m_argc);
rApp.setArgv(m_argv);
rApp.setIODescriptors(vector<int>(m_io, m_io + IO_DESCRIPTOR_COUNT));
rApp.setIDs(m_uid, m_gid);
}
else
{
@ -533,3 +548,17 @@ bool Connection::isReportAppExitStatusNeeded()
return m_sendPid;
}
pid_t Connection::peersPid()
{
struct ucred cr;
socklen_t len = sizeof(struct ucred);
if (getsockopt(m_fd, SOL_SOCKET, SO_PEERCRED, &cr, &len) < 0)
{
Logger::logError("Connection: can't get peer's pid: %s\n", strerror(errno));
return 0;
}
return cr.pid;
}

@ -75,7 +75,6 @@ public:
//! \brief Receive application data to rApp.
bool receiveApplicationData(AppData & rApp);
//! \brief Return true if invoker wait for process exit status
bool isReportAppExitStatusNeeded();
@ -90,6 +89,10 @@ public:
//! \brief Close all open sockets.
static void closeAllSockets();
//! \brief Get pid of the process on the other end of socket connection
pid_t peersPid();
private:
/*! \brief Receive actions.
@ -132,6 +135,9 @@ private:
//! Receive I/O descriptors
bool receiveIO();
//! Receive userId and GroupId
bool receiveIDs();
//! Receive priority
bool receivePriority();
@ -161,6 +167,8 @@ private:
int m_io[IO_DESCRIPTOR_COUNT];
uint32_t m_priority;
bool m_sendPid;
gid_t m_gid;
uid_t m_uid;
#if defined (HAVE_CREDS) && ! defined (DISABLE_VERIFICATION)
static const char * m_credsStr;

@ -52,7 +52,7 @@ Daemon::Daemon(int & argc, char * argv[]) :
}
else
{
Logger::logErrorAndDie(EXIT_FAILURE, "Daemon already created!\n");
Logger::logErrorAndDie(EXIT_FAILURE, "Daemon: Daemon already created!\n");
}
// Parse arguments
@ -68,7 +68,7 @@ Daemon::Daemon(int & argc, char * argv[]) :
if (pipe(m_pipefd) == -1)
{
Logger::logErrorAndDie(EXIT_FAILURE, "Creating a pipe failed!!!\n");
Logger::logErrorAndDie(EXIT_FAILURE, "Daemon: Creating a pipe failed!!!\n");
}
// Daemonize if desired
@ -85,11 +85,11 @@ void Daemon::consoleQuiet()
close(2);
if (open("/dev/null", O_RDONLY) < 0)
Logger::logErrorAndDie(EXIT_FAILURE, "opening /dev/null readonly");
Logger::logErrorAndDie(EXIT_FAILURE, "Daemon: opening /dev/null readonly");
int fd = open("/dev/null", O_WRONLY);
if ((fd == -1) || (dup(fd) < 0))
Logger::logErrorAndDie(EXIT_FAILURE, "opening /dev/null writeonly");
Logger::logErrorAndDie(EXIT_FAILURE, "Daemon: opening /dev/null writeonly");
}
Daemon * Daemon::instance()
@ -147,6 +147,20 @@ void Daemon::run()
ssize_t count = read(m_pipefd[0], reinterpret_cast<void *>(&msg), 1);
if (count)
{
// read pid of peer invoker
pid_t invoker_pid;
count = read(m_pipefd[0], reinterpret_cast<void *>(&invoker_pid), sizeof(pid_t));
if (count < sizeof(pid_t))
{
Logger::logErrorAndDie(EXIT_FAILURE, "Daemon: pipe connection with booster failed");
}
else
{
Logger::logError("Daemon: invokers pid: \n", invoker_pid);
}
// Fork a new booster of the given type
// 2nd param guarantees some time for the just launched application
@ -157,7 +171,7 @@ void Daemon::run()
}
else
{
Logger::logWarning("Nothing read from the pipe\n");
Logger::logWarning("Daemon: Nothing read from the pipe\n");
}
}
}
@ -168,7 +182,7 @@ bool Daemon::forkBooster(char type, int sleepTime)
pid_t newPid = fork();
if (newPid == -1)
Logger::logErrorAndDie(EXIT_FAILURE, "Forking while invoking");
Logger::logErrorAndDie(EXIT_FAILURE, "Daemon: Forking while invoking");
if (newPid == 0) /* Child process */
{
@ -186,7 +200,7 @@ bool Daemon::forkBooster(char type, int sleepTime)
if (setsid() < 0)
{
Logger::logError("Setting session id\n");
Logger::logError("Daemon: Setting session id\n");
}
// Guarantee some time for the just launched application to
@ -194,7 +208,7 @@ bool Daemon::forkBooster(char type, int sleepTime)
if (sleepTime)
sleep(sleepTime);
Logger::logNotice("Running a new Booster of %c type...", type);
Logger::logNotice("Daemon: Running a new Booster of %c type...", type);
// Create a new booster and initialize it
Booster * booster = NULL;
@ -208,7 +222,7 @@ bool Daemon::forkBooster(char type, int sleepTime)
}
else
{
Logger::logErrorAndDie(EXIT_FAILURE, "Unknown booster type \n");
Logger::logErrorAndDie(EXIT_FAILURE, "Daemon: Unknown booster type \n");
}
// Drop priority (nice = 10)
@ -227,7 +241,7 @@ bool Daemon::forkBooster(char type, int sleepTime)
booster->popPriority();
// Wait and read commands from the invoker
Logger::logNotice("Wait for message from invoker");
Logger::logNotice("Daemon: Wait for message from invoker");
booster->readCommand();
// Give to the process an application specific name
@ -238,12 +252,18 @@ bool Daemon::forkBooster(char type, int sleepTime)
const char msg = booster->boosterType();
ssize_t ret = write(m_pipefd[1], reinterpret_cast<const void *>(&msg), 1);
if (ret == -1) {
Logger::logError("Can't send signal to launcher process' \n");
Logger::logError("Daemon: Can't send signal to launcher process' \n");
}
// close sockets and pipe
// Send to the parent process pid of invoker for tracking
pid_t pid = booster->invokersPid();
ret = write(m_pipefd[1], reinterpret_cast<const void *>(&pid), sizeof(pid_t));
if (ret == -1) {
Logger::logError("Daemon: Can't send invoker's pid to launcher process' \n");
}
// close pipe
close(m_pipefd[1]);
Connection::closeAllSockets();
// Don't care about fate of parent applauncherd process any more
prctl(PR_SET_PDEATHSIG, 0);
@ -280,10 +300,18 @@ void Daemon::reapZombies()
PidVect::iterator i(m_children.begin());
while (i != m_children.end())
{
pid_t pid = waitpid(*i, NULL, WNOHANG);
int status;
pid_t pid = waitpid(*i, &status, WNOHANG);
if (pid)
{
i = m_children.erase(i);
Logger::logError("Daemon: terminated process pid is %d", pid);
if (WIFSIGNALED(status))
{
// todo: send signal to corresponding invoker form here
Logger::logError("Daemon: booster (pid=%d) terminated due to signal=%d\n", pid, WTERMSIG(status));
}
// Check if pid belongs to boosters, restart dead booster if needed
if (pid == MBooster::ProcessId())
@ -311,7 +339,7 @@ void Daemon::daemonize()
pid = fork();
if (pid < 0)
{
Logger::logError("Unable to fork daemon, code %d (%s)", errno, strerror(errno));
Logger::logError("Daemon: Unable to fork daemon, code %d (%s)", errno, strerror(errno));
exit(EXIT_FAILURE);
}
@ -325,7 +353,7 @@ void Daemon::daemonize()
pid = fork();
if (pid < 0)
{
Logger::logError("Unable to fork daemon, code %d (%s)", errno, strerror(errno));
Logger::logError("Daemon: Unable to fork daemon, code %d (%s)", errno, strerror(errno));
exit(EXIT_FAILURE);
}
@ -344,14 +372,14 @@ void Daemon::daemonize()
sid = setsid();
if (sid < 0)
{
Logger::logError("Unable to create a new session, code %d (%s)", errno, strerror(errno));
Logger::logError("Daemon: Unable to create a new session, code %d (%s)", errno, strerror(errno));
exit(EXIT_FAILURE);
}
// Change the current working directory
if ((chdir("/")) < 0)
{
Logger::logError("Unable to change directory to %s, code %d (%s)", "/", errno, strerror(errno));
Logger::logError("Daemon: Unable to change directory to %s, code %d (%s)", "/", errno, strerror(errno));
exit(EXIT_FAILURE);
}

@ -43,3 +43,6 @@ add_subdirectory(TestApps/testapp)
# Sub build: TestApps
add_subdirectory(TestApps/themetest)
# Sub build: TestApps
add_subdirectory(TestApps/fala_status)

@ -0,0 +1,32 @@
# Set sources
set(SRC fala_status.cpp)
link_libraries(${MEEGOTOUCH_LIBRARIES})
include(${QT_USE_FILE})
# Use the compiler and linker flags given in meegotouch-boostable.pc
# in the source tree.
execute_process(COMMAND "env"
"PKG_CONFIG_PATH=${CMAKE_SOURCE_DIR}/data/pkgconfig"
"/usr/bin/pkg-config"
"--cflags"
"meegotouch-boostable"
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
OUTPUT_VARIABLE booster_cflags
OUTPUT_STRIP_TRAILING_WHITESPACE)
execute_process(COMMAND "env"
"PKG_CONFIG_PATH=${CMAKE_SOURCE_DIR}/data/pkgconfig"
"/usr/bin/pkg-config" "--libs"
"meegotouch-boostable"
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
OUTPUT_VARIABLE booster_libs
OUTPUT_STRIP_TRAILING_WHITESPACE)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${booster_cflags}")
set(CMAKE_EXE_LINKER_FLAGS ${booster_libs})
add_executable(fala_status ${SRC})
# Install
install(PROGRAMS fala_status DESTINATION /usr/bin RENAME fala_status.launch)

@ -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 <MApplication>
#include <MApplicationPage>
#include <MApplicationWindow>
#include <MExport>
#include <QTimer>
#include <iostream>
#ifdef HAVE_MCOMPONENTCACHE
#include <mcomponentcache.h>
#endif
M_EXPORT int main(int argc, char ** argv)
{
#ifdef HAVE_MCOMPONENTCACHE
MApplication *app = MComponentCache::mApplication(argc, argv);
#endif
QTimer::singleShot(5, app, SLOT(quit()));
int usr_id = getuid();
int grp_id = getgid();
std::cerr << "uid=" << usr_id <<"\n";
std::cerr << "gid=" << grp_id <<"\n";
app->exec();
return 29;
}

@ -631,6 +631,78 @@ class launcher_tests (unittest.TestCase):
self.assert_(mpid_new != None, "No booster process running")
self.assert_(mpid_new != mpid, "booster process was not killed")
def test_017_invoker_exit_status(self):
"""
To test that invoker returns the same exit status as the application
"""
#Run application without invoker and get the exit status
st, op = commands.getstatusoutput('/usr/bin/fala_status.launch')
app_st_wo_inv = os.WEXITSTATUS(st)
#Run application with invoker and get the exit status
st, op = commands.getstatusoutput('invoker --type=m --wait-term /usr/bin/fala_status.launch')
app_st_w_inv = os.WEXITSTATUS(st)
self.assert_(app_st_wo_inv == app_st_w_inv, "The invoker returns a wrong exit status")
def test_018_invoker_gid_uid(self):
"""
To Test that the set gid and uid is passed from invoker process to launcher
"""
#get the id in user mode
print ("In User Mode \n")
st, op = commands.getstatusoutput('su user -c ' "id")
usr_id1 = op.split(' ')[0].split('(')[0]
grp_id1 = op.split(' ')[1].split('(')[0]
print("System %s \nSyetem %s" %(usr_id1, grp_id1))
#get id by running the application using invoker in user mode
app = "invoker --type=m /usr/bin/fala_status.launch"
st, op = commands.getstatusoutput('su user -c "%s"' %app );
usr_id = op.split('\n')[1]
grp_id = op.split('\n')[2]
print("Invoker %s \nInvoker %s" %(usr_id, grp_id))
#get id by running the application without invoker in user mode
app = "/usr/bin/fala_status.launch"
st, op = commands.getstatusoutput('su user -c "%s"' %app );
usr_id2 = op.split('\n')[3]
grp_id2 = op.split('\n')[4]
print("Application %s \nApplication %s" %(usr_id2, grp_id2))
self.assert_(usr_id == usr_id1, "The correct UID is not passed by invoker")
self.assert_(grp_id == grp_id1, "The correct GID is not passed by invoker")
self.assert_(usr_id == usr_id2, "The correct UID is not passed by invoker")
self.assert_(grp_id == grp_id2, "The correct GID is not passed by invoker")
#get the id in root mode
print ("In Root Mode \n")
st, op = commands.getstatusoutput("id")
usr_id1 = op.split(' ')[0].split('(')[0]
grp_id1 = op.split(' ')[1].split('(')[0]
print("System %s \nSyetem %s" %(usr_id1, grp_id1))
#get id by running the application using invoker in root mode
app = "invoker --type=m /usr/bin/fala_status.launch"
st, op = commands.getstatusoutput("%s" %app );
usr_id = op.split('\n')[1]
grp_id = op.split('\n')[2]
print("Invoker %s \nInvoker %s" %(usr_id, grp_id))
#get id by running the application without invoker in root mode
app = "/usr/bin/fala_status.launch"
st, op = commands.getstatusoutput("%s" %app );
usr_id2 = op.split('\n')[3]
grp_id2 = op.split('\n')[4]
print("Application %s \nApplication %s" %(usr_id2, grp_id2))
self.assert_(usr_id == usr_id1, "The correct UID is not passed by invoker")
self.assert_(grp_id == grp_id1, "The correct GID is not passed by invoker")
self.assert_(usr_id == usr_id2, "The correct UID is not passed by invoker")
self.assert_(grp_id == grp_id2, "The correct GID is not passed by invoker")
# main
if __name__ == '__main__':

@ -65,6 +65,15 @@
<step expected_result="0">source /tmp/session_bus_address.user; DISPLAY=:0 `pyversions -d` /usr/share/applauncherd-testscripts/test-func-launcher.py test_010</step>
</case>
<case name="invoker-status" type="Functional" description="To test that invoker returns the same exit status as the application" timeout="120" level="System" insignificant="true">
<step expected_result="0">source /tmp/session_bus_address.user; DISPLAY=:0 `pyversions -d` /usr/share/applauncherd-testscripts/test-func-launcher.py test_017_invoker_exit_status</step>
</case>
<case name="gid-uid" type="Functional" description="To Test that the set gid and uid is passed from invoker process to launcher" timeout="120" level="System" insignificant="true">
<step expected_result="0">source /tmp/session_bus_address.user; DISPLAY=:0 `pyversions -d` /usr/share/applauncherd-testscripts/test-func-launcher.py test_018_invoker_gid_uid</step>
</case>
<environments>
<scratchbox>true</scratchbox>
<hardware>true</hardware>

Loading…
Cancel
Save