Exemplo n.º 1
0
// "normal" invoke through a socket connection
int invoke_remote(int fd, int prog_argc, char **prog_argv, char *prog_name,
                  uint32_t magic_options, bool wait_term, unsigned int respawn_delay)
{
    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_delay(fd, respawn_delay);
    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;
}
Exemplo n.º 2
0
static int wait_for_launched_process_to_exit(int socket_fd, bool wait_term)
{
    int status = 0;

    // Wait for launched process to exit
    if (wait_term)
    {
        // coverity[tainted_string_return_content]
        g_invoked_pid = invoker_recv_pid(socket_fd);
        debug("Booster's pid is %d \n ", g_invoked_pid);

        // Forward UNIX signals to the invoked process
        sigs_init();

        while(1)
        {
            // Setup things for select()
            fd_set readfds;
            int ndfs = 0;

            FD_ZERO(&readfds);

            FD_SET(socket_fd, &readfds);
            ndfs = (socket_fd > ndfs) ? socket_fd : ndfs;

            // sig_forwarder() handles signals.
            // We only have to receive those here.
            FD_SET(g_signal_pipe[0], &readfds);
            ndfs = (g_signal_pipe[0] > ndfs) ? g_signal_pipe[0] : ndfs;

            // Wait for something appearing in the pipes.
            if (select(ndfs + 1, &readfds, NULL, NULL, NULL) > 0)
            {
                // Check if an exit status from the invoked application
                if (FD_ISSET(socket_fd, &readfds))
                {
                    bool res = invoker_recv_exit(socket_fd, &status);

                    if (!res)
                    {
                        // Because we are here, applauncherd.bin must be dead.
                        // Now we check if the invoked process is also dead
                        // and if not, we will kill it.
                        char filename[50];
                        snprintf(filename, sizeof(filename), "/proc/%d/cmdline", g_invoked_pid);

                        // Open filename for reading only
                        int fd = open(filename, O_RDONLY);
                        if (fd != -1)
                        {
                            // Application is still running
                            close(fd);

                            // Send a signal to kill the application too and exit.
                            // Sleep for some time to give
                            // the new applauncherd some time to load its boosters and
                            // the restart of g_invoked_pid succeeds.

                            sleep(10);
                            kill(g_invoked_pid, SIGKILL);
                            raise(SIGKILL);
                        }
                        else
                        {
                            // connection to application was lost
                            status = EXIT_FAILURE; 
                        }
                    }
                    break;
                }
                // Check if we got a UNIX signal.
                else if (FD_ISSET(g_signal_pipe[0], &readfds))
                {
                    // Clean up the pipe
                    char signal_id;
                    read(g_signal_pipe[0], &signal_id, sizeof(signal_id));

                    // Set signals forwarding to the invoked process again
                    // (they were reset by the signal forwarder).
                    sigs_init();
                }
            }
        }

        // Restore default signal handlers
        sigs_restore();
    }

    return status;
}