Ejemplo n.º 1
0
/*******************************
 * Wrappers for the SIO routines
 ******************************/
ssize_t Sio_putl(long v)
{
    ssize_t n;
  
    if ((n = sio_putl(v)) < 0)
	sio_error("Sio_putl error");
    return n;
}
Ejemplo n.º 2
0
/* 
 * sigchld_handler - The kernel sends a SIGCHLD to the shell whenever
 *     a child job terminates (becomes a zombie), or stops because it
 *     received a SIGSTOP, SIGTSTP, SIGTTIN or SIGTTOU signal. The 
 *     handler reaps all available zombie children, but doesn't wait 
 *     for any other currently running children to terminate.  
 */
void sigchld_handler(int sig) {

    int status;
    pid_t pid;
    int olderrno = errno; // store errno in handler

    /*
     * Reap child with the pid if the child is stopped or terminated
     * If a child is terminated normally, delete the child from the job list
     * If a child is stopped by a signal, set the job status as stopped
     * If a child is terminated by a signal that was not caught, delete the child from the job list
     */
    while ((pid = waitpid(-1, &status, WNOHANG|WUNTRACED)) > 0) {

        if (WIFEXITED(status)) {

            deletejob(job_list, pid); // the child ternimated normally

        } else if (WIFSTOPPED(status)) {

            /*
             * Avoid printf() in handler, use helper function to write the output to stdout
             */
            sio_puts("Job [");
            sio_putl(pid2jid(pid));
            sio_puts("] (");
            sio_putl(pid);
            sio_puts(") stopped by signal ");
            sio_putl(WSTOPSIG(status));
            sio_puts("\n");

            getjobpid(job_list, pid) -> state = ST; // the child was stopped by a signal 

        } else if (WIFSIGNALED(status)) { // the child was terminated by a signal that was not caught

            /*
             * Avoid printf() in handler, use helper function to write the output to stdout
             */
            sio_puts("Job [");
            sio_putl(pid2jid(pid));
            sio_puts("] (");
            sio_putl(pid);
            sio_puts(") terminated by signal ");
            sio_putl(WTERMSIG(status));
            sio_puts("\n");

			deletejob(job_list, pid);

        }

    }

    errno = olderrno;
    return;
}