Esempio n. 1
0
void SIGCHLD_handler(int s)
{
    int old_errno = errno;
    int child_status = 0, child_pid = 0;

    pid_t appmon_pid = getpid();
    SWI_LOG("APPMON", DEBUG, "SIGCHLD_handler: appmon_pid=%d =============>\n", appmon_pid);

    while (1)
    {
        do
        {
            errno = 0;
            //call waitpid trying to avoid suspend-related state changes.(no WUNTRACED or WCONTINUED options to waitpid)
            child_pid = waitpid(WAIT_ANY, &child_status, WNOHANG);
        } while (child_pid <= 0 && errno == EINTR);

        if (child_pid <= 0)
        {
            /* A real failure means there are no more
             stopped or terminated child processes, so return.  */
            errno = old_errno;
            SWI_LOG("APPMON", DEBUG, "SIGCHLD_handler: pid=%d =============< quit\n", appmon_pid);
            fflush(stdout);
            return;
        }

        app_t* app = find_by_pid(child_pid);
        if (NULL != app)
        {
            int exited = WIFEXITED(child_status);
            int exited_code = exited ? WEXITSTATUS(child_status) : -1;
            int signaled = WIFSIGNALED(child_status);

            //update exit status only if process is terminated.
            //if stopped/continued event on process is caught, don't update status
            if (!exited && !signaled)
            {
                SWI_LOG("APPMON", ERROR, "SIGCHLD_handler: status change looks like suspend events (STOP/CONT), ignored\n");
                continue; //go to next waipid call
            }

            //real child termination, update values
            app->last_exit_code = child_status;
            app_exit_status(app);

            SWI_LOG("APPMON", DEBUG, "SIGCHLD_handler: app terminated: id=%d, prog=%s was pid %d, calculated status =%s\n",
                    app->id, app->prog, child_pid, app->last_exit_status);
            if (TO_BE_KILLED == app->status || (STARTED == app->status && exited && !exited_code))
            {
                //put flag to be used it stop_app
                app->status = KILLED;
                SWI_LOG("APPMON", DEBUG, "SIGCHLD_handler: status => KILLED\n");
            }
            else
            {
                if ((exited && exited_code > 0) | signaled)
                {
                    SWI_LOG("APPMON", DEBUG, "SIGCHLD_handler: Child status error %d, application is set to  TO_BE_RESTARTED, %s\n",
                            child_status, app->prog);
                    //error has occur, restart app after delay
                    // app will not be found if it has been stopped voluntarily, so it won't be restarted.
                    app->status = TO_BE_RESTARTED;
                    alarm(RESTART_DELAY);
                }
            }
        }
        else //app == NULL, pid not found in monitored apps
        {
            SWI_LOG("APPMON", DEBUG, "SIGCHLD_handler: unknown dead app, pid=%d\n", child_pid);
        }
    }
}
Esempio n. 2
0
//handler para tratar SIGCHLD
static void sigchld_hand(int signo, siginfo_t *info, void *data) {

    waitpid(info->si_pid, NULL, 0); 
    vector_remove(job_list, find_by_pid(job_list, info->si_pid)); 
}
Esempio n. 3
0
void* remove_by_pid(Vector vector, pid_t pid){
    return vector_remove(vector, find_by_pid(vector, pid));
}