|
|
|
|
@ -60,16 +60,16 @@ enum APP_TYPE { M_APP, QT_APP, WRT_APP, UNKNOWN_APP };
|
|
|
|
|
extern char ** environ;
|
|
|
|
|
|
|
|
|
|
// pid of the invoked process
|
|
|
|
|
static pid_t invoked_pid = -1;
|
|
|
|
|
static pid_t g_invoked_pid = -1;
|
|
|
|
|
|
|
|
|
|
static void sigs_restore(void);
|
|
|
|
|
|
|
|
|
|
// Forwards Unix signals from invoker to the invoked process
|
|
|
|
|
static void sig_forwarder(int sig)
|
|
|
|
|
{
|
|
|
|
|
if (invoked_pid >= 0)
|
|
|
|
|
if (g_invoked_pid >= 0)
|
|
|
|
|
{
|
|
|
|
|
if (kill(invoked_pid, sig) != 0)
|
|
|
|
|
if (kill(g_invoked_pid, sig) != 0)
|
|
|
|
|
{
|
|
|
|
|
report(report_error, "Can't send signal to application: %s \n", strerror(errno));
|
|
|
|
|
}
|
|
|
|
|
@ -445,6 +445,88 @@ static unsigned int get_delay(char *delay_arg)
|
|
|
|
|
return delay;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Fallback for invoke if connection to the launcher is broken.
|
|
|
|
|
// Forks a new process if wait term is not used.
|
|
|
|
|
void invoke_fallback(char **prog_argv, char *prog_name, bool wait_term)
|
|
|
|
|
{
|
|
|
|
|
// Connection with launcher is broken,
|
|
|
|
|
// try to launch application via execve
|
|
|
|
|
warning("Connection with launcher process is broken. \n");
|
|
|
|
|
warning("Trying to start application as a binary executable without launcher...\n");
|
|
|
|
|
|
|
|
|
|
// Fork if wait_term not set
|
|
|
|
|
if(!wait_term)
|
|
|
|
|
{
|
|
|
|
|
// Fork a new process
|
|
|
|
|
pid_t newPid = fork();
|
|
|
|
|
|
|
|
|
|
if (newPid == -1)
|
|
|
|
|
{
|
|
|
|
|
report(report_error, "Invoker failed to fork");
|
|
|
|
|
exit(EXIT_FAILURE);
|
|
|
|
|
}
|
|
|
|
|
else if (newPid != 0) /* parent process */
|
|
|
|
|
{
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Exec the process image
|
|
|
|
|
execve(prog_name, prog_argv, environ);
|
|
|
|
|
perror("execve"); /* execve() only returns on error */
|
|
|
|
|
exit(EXIT_FAILURE);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// "normal" invoke through a socket connection
|
|
|
|
|
int invoke_remote(int fd, int prog_argc, char **prog_argv, char *prog_name,
|
|
|
|
|
int magic_options, bool wait_term)
|
|
|
|
|
{
|
|
|
|
|
int status = 0;
|
|
|
|
|
|
|
|
|
|
// Get process priority
|
|
|
|
|
errno = 0;
|
|
|
|
|
int prog_prio = getpriority(PRIO_PROCESS, 0);
|
|
|
|
|
if (errno && prog_prio < 0)
|
|
|
|
|
{
|
|
|
|
|
prog_prio = 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Connection with launcher process is established,
|
|
|
|
|
// send the data.
|
|
|
|
|
invoker_send_magic(fd, magic_options);
|
|
|
|
|
invoker_send_name(fd, prog_argv[0]);
|
|
|
|
|
invoker_send_exec(fd, prog_name);
|
|
|
|
|
invoker_send_args(fd, prog_argc, prog_argv);
|
|
|
|
|
invoker_send_prio(fd, prog_prio);
|
|
|
|
|
invoker_send_ids(fd, getuid(), getgid());
|
|
|
|
|
invoker_send_io(fd);
|
|
|
|
|
invoker_send_env(fd);
|
|
|
|
|
invoker_send_end(fd);
|
|
|
|
|
|
|
|
|
|
if (prog_name)
|
|
|
|
|
{
|
|
|
|
|
free(prog_name);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Wait for launched process to exit
|
|
|
|
|
if (wait_term)
|
|
|
|
|
{
|
|
|
|
|
g_invoked_pid = invoker_recv_pid(fd);
|
|
|
|
|
debug("Booster's pid is %d \n ", g_invoked_pid);
|
|
|
|
|
|
|
|
|
|
// Forward signals to the invoked process
|
|
|
|
|
sigs_init();
|
|
|
|
|
|
|
|
|
|
// Wait for exit status from the invoked application
|
|
|
|
|
status = invoker_recv_exit(fd);
|
|
|
|
|
|
|
|
|
|
// Restore default signal handlers
|
|
|
|
|
sigs_restore();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return status;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Invokes the given application
|
|
|
|
|
static int invoke(int prog_argc, char **prog_argv, char *prog_name,
|
|
|
|
|
enum APP_TYPE app_type, int magic_options, bool wait_term)
|
|
|
|
|
@ -453,79 +535,18 @@ static int invoke(int prog_argc, char **prog_argv, char *prog_name,
|
|
|
|
|
|
|
|
|
|
if (prog_name && prog_argv)
|
|
|
|
|
{
|
|
|
|
|
// Get process priority
|
|
|
|
|
errno = 0;
|
|
|
|
|
int prog_prio = getpriority(PRIO_PROCESS, 0);
|
|
|
|
|
if (errno && prog_prio < 0)
|
|
|
|
|
{
|
|
|
|
|
prog_prio = 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// This is a fallback if connection with the launcher
|
|
|
|
|
// process is broken
|
|
|
|
|
int fd = invoker_init(app_type);
|
|
|
|
|
if (fd == -1)
|
|
|
|
|
{
|
|
|
|
|
// Connection with launcher is broken,
|
|
|
|
|
// try to launch application via execve
|
|
|
|
|
warning("Connection with launcher process is broken. \n");
|
|
|
|
|
warning("Trying to start application as a binary executable without launcher...\n");
|
|
|
|
|
|
|
|
|
|
if(!wait_term)
|
|
|
|
|
{
|
|
|
|
|
// Fork a new process
|
|
|
|
|
pid_t newPid = fork();
|
|
|
|
|
|
|
|
|
|
if (newPid == -1)
|
|
|
|
|
{
|
|
|
|
|
report(report_error, "Invoker failed to fork");
|
|
|
|
|
exit(EXIT_FAILURE);
|
|
|
|
|
}
|
|
|
|
|
if (newPid != 0) /* parent process */
|
|
|
|
|
{
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
execve(prog_name, prog_argv, environ);
|
|
|
|
|
perror("execve"); /* execve() only returns on error */
|
|
|
|
|
exit(EXIT_FAILURE);
|
|
|
|
|
invoke_fallback(prog_argv, prog_name, wait_term);
|
|
|
|
|
}
|
|
|
|
|
// "normal" invoke through a socket connetion
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
// Connection with launcher process is established,
|
|
|
|
|
// send the data.
|
|
|
|
|
invoker_send_magic(fd, magic_options);
|
|
|
|
|
invoker_send_name(fd, prog_argv[0]);
|
|
|
|
|
invoker_send_exec(fd, prog_name);
|
|
|
|
|
invoker_send_args(fd, prog_argc, prog_argv);
|
|
|
|
|
invoker_send_prio(fd, prog_prio);
|
|
|
|
|
invoker_send_ids(fd, getuid(), getgid());
|
|
|
|
|
invoker_send_io(fd);
|
|
|
|
|
invoker_send_env(fd);
|
|
|
|
|
invoker_send_end(fd);
|
|
|
|
|
|
|
|
|
|
if (prog_name)
|
|
|
|
|
{
|
|
|
|
|
free(prog_name);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Wait for launched process to exit
|
|
|
|
|
if (wait_term)
|
|
|
|
|
{
|
|
|
|
|
invoked_pid = invoker_recv_pid(fd);
|
|
|
|
|
debug("Booster's pid is %d \n ", invoked_pid);
|
|
|
|
|
|
|
|
|
|
// Forward signals to the invoked process
|
|
|
|
|
sigs_init();
|
|
|
|
|
|
|
|
|
|
// Wait for exit status from the invoked application
|
|
|
|
|
status = invoker_recv_exit(fd);
|
|
|
|
|
|
|
|
|
|
// Restore default signal handlers
|
|
|
|
|
sigs_restore();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
status = invoke_remote(fd, prog_argc, prog_argv, prog_name,
|
|
|
|
|
magic_options, wait_term);
|
|
|
|
|
close(fd);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
@ -565,6 +586,7 @@ int main(int argc, char *argv[])
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
// Parse options
|
|
|
|
|
// TODO: Move to a function
|
|
|
|
|
int opt;
|
|
|
|
|
while ((opt = getopt_long(argc, argv, "hcwd:t:", longopts, NULL)) != -1)
|
|
|
|
|
{
|
|
|
|
|
|