openbmc/build/tmp/deploy/sdk/witherspoon-2019-08-08/sysroots/armv6-openbmc-linux-gnueabi/usr/src/debug/util-linux/2.33.2-r0/util-linux-2.33.2/login-utils/su-common.c
static int wait_for_child(struct su_context* su)
{
    pid_t pid = (pid_t)-1;
    ;
    int status = 0;

    if (su->child == (pid_t)-1)
        return su->childstatus;

    if (su->child != (pid_t)-1)
    {
        /*
         * The "su" parent process spends all time here in waitpid(),
         * but "su --pty" uses pty_proxy_master() and waitpid() is only
         * called to pick up child status or to react to SIGSTOP.
         */
        DBG(SIG, ul_debug("waiting for child [%d]...", su->child));
        for (;;)
        {
            pid = waitpid(su->child, &status, WUNTRACED);

            if (pid != (pid_t)-1 && WIFSTOPPED(status))
            {
                DBG(SIG, ul_debug(" child got SIGSTOP -- stop all session"));
                kill(getpid(), SIGSTOP);
                /* once we get here, we must have resumed */
                kill(pid, SIGCONT);
                DBG(SIG, ul_debug(" session resumed -- continue"));
#ifdef USE_PTY
                /* Let's go back to pty_proxy_master() */
                if (su->pty_sigfd != -1)
                {
                    DBG(SIG, ul_debug(" leaving on child SIGSTOP"));
                    return 0;
                }
#endif
            }
            else
                break;
        }
    }
    if (pid != (pid_t)-1)
    {
        if (WIFSIGNALED(status))
        {
            fprintf(stderr, "%s%s\n", strsignal(WTERMSIG(status)),
                    WCOREDUMP(status) ? _(" (core dumped)") : "");
            status = WTERMSIG(status) + 128;
        }
        else
            status = WEXITSTATUS(status);

        DBG(SIG, ul_debug("child %d is dead", su->child));
        su->child = (pid_t)-1; /* Don't use the PID anymore! */
        su->childstatus = status;
    }
    else if (caught_signal)
        status = caught_signal + 128;
    else
        status = 1;

    DBG(SIG, ul_debug("child status=%d", status));
    return status;
}
/*
 * Note, this function has to be possible call more than once. If the child is
 * already dead than it returns saved result from the previous call.
 */
Note, this function has to be possible call more than once. If the child is
already dead than it returns saved result from the previous call.
Note this function has to be possible call more than once . If the child is already dead than it returns saved result from the previous call .
static int wait_for_child(struct su_context* su)
{
    pid_t pid = (pid_t)-1;
    ;
    int status = 0;
    if (su->child == (pid_t)-1)
        return su->childstatus;
    if (su->child != (pid_t)-1)
    {
        DBG(SIG, ul_debug("waiting for child [%d]...", su->child));
        for (;;)
        {
            pid = waitpid(su->child, &status, WUNTRACED);
            if (pid != (pid_t)-1 && WIFSTOPPED(status))
            {
                DBG(SIG, ul_debug(" child got SIGSTOP -- stop all session"));
                kill(getpid(), SIGSTOP);
                kill(pid, SIGCONT);
                DBG(SIG, ul_debug(" session resumed -- continue"));
#ifdef USE_PTY
                if (su->pty_sigfd != -1)
                {
                    DBG(SIG, ul_debug(" leaving on child SIGSTOP"));
                    return 0;
                }
#endif
            }
            else
                break;
        }
    }
    if (pid != (pid_t)-1)
    {
        if (WIFSIGNALED(status))
        {
            fprintf(stderr, "%s%s\n", strsignal(WTERMSIG(status)),
                    WCOREDUMP(status) ? _(" (core dumped)") : "");
            status = WTERMSIG(status) + 128;
        }
        else
            status = WEXITSTATUS(status);
        DBG(SIG, ul_debug("child %d is dead", su->child));
        su->child = (pid_t)-1; 
        su->childstatus = status;
    }
    else if (caught_signal)
        status = caught_signal + 128;
    else
        status = 1;
    DBG(SIG, ul_debug("child status=%d", status));
    return status;
}
static int wait_for_child ( struct su_context * su ) { pid_t pid = ( pid_t ) - 1 ; ; int status = 0 ; if ( su -> child == ( pid_t ) - 1 ) return su -> childstatus ; if ( su -> child != ( pid_t ) - 1 ) { DBG ( SIG , ul_debug ( " " , su -> child ) ) ; for ( ; ; ) { pid = waitpid ( su -> child , & status , WUNTRACED ) ; if ( pid != ( pid_t ) - 1 && WIFSTOPPED ( status ) ) { DBG ( SIG , ul_debug ( " " ) ) ; kill ( getpid ( ) , SIGSTOP ) ; kill ( pid , SIGCONT ) ; DBG ( SIG , ul_debug ( " " ) ) ; #ifdef USE_PTY if ( su -> pty_sigfd != -1 ) { DBG ( SIG , ul_debug ( " " ) ) ; return 0 ; } #endif } else break ; } } if ( pid != ( pid_t ) - 1 ) { if ( WIFSIGNALED ( status ) ) { fprintf ( stderr , " \n " , strsignal ( WTERMSIG ( status ) ) , WCOREDUMP ( status ) ? _ ( " " ) : " " ) ; status = WTERMSIG ( status ) + 128 ; } else status = WEXITSTATUS ( status ) ; DBG ( SIG , ul_debug ( " " , su -> child ) ) ; su -> child = ( pid_t ) - 1 ; su -> childstatus = status ; } else if ( caught_signal ) status = caught_signal + 128 ; else status = 1 ; DBG ( SIG , ul_debug ( " " , status ) ) ; return status ; }
Note, this function has to be possible call more than once.
Note this function has to be possible call more than once .
/*
         * The "su" parent process spends all time here in waitpid(),
         * but "su --pty" uses pty_proxy_master() and waitpid() is only
         * called to pick up child status or to react to SIGSTOP.
         */ /* once we get here, we must have resumed */ /* Let's go back to pty_proxy_master() */ /* Don't use the PID anymore! */