Esempio n. 1
0
void wait_for_job(job_t *j) {
   int status;
   pid_t pid;
   do
     pid = waitpid(WAIT_ANY, &status, WUNTRACED);
   while (!mark_process_status(pid, status)&& !job_is_stopped(j)
          && !job_is_completed(j));
 }
Esempio n. 2
0
/* Check for processes that have status information available,
   without blocking.  */
void update_status (void) {
	int status;
	pid_t pid;

	do
		pid = waitpid (WAIT_ANY, &status, WUNTRACED|WNOHANG);
	while (!mark_process_status (pid, status));
}
Esempio n. 3
0
void wait_for_bgjobs() {
   int status;
   pid_t pid;

   /* loop until all the backgroun jobs completed */
   do {
	pid = waitpid(WAIT_ANY, &status, WNOHANG|WUNTRACED);
	mark_process_status(pid, status);
   } while (!bgjobs_is_completed());
}
Esempio n. 4
0
void wait_for_job(process *p) {
   int status;
   pid_t pid;

   do {
	// printf("wait on process on %d\n", (long)p->pid);
	pid = waitpid(WAIT_ANY, &status, WUNTRACED);
	mark_process_status(pid, status);
   } while (!p->completed && !p->stopped);
	  
}
Esempio n. 5
0
/* Check for processes that have status information available,
 * without blocking. 
 */
void update_status(void) {
   int status;
   pid_t pid;

   do {
	/* specifies that waitpid should return status information about any child process.  */
	pid = waitpid(WAIT_ANY, &status, WUNTRACED|WNOHANG);
        #ifdef DEBUG
	printf("update_status: waitpid return %d\n", pid);
	#endif
   } while(!mark_process_status(pid, status));
}
Esempio n. 6
0
int cmd_wait(tok_t arg[]){
	int status;
	pid_t pid;
	int n_proc = num_active_proc();

	while(n_proc > 0){
		pid = waitpid(-1, &status, WUNTRACED);
		mark_process_status(pid,status);
		n_proc = num_active_proc();
		}
	
	return 0;
}
Esempio n. 7
0
/// Handle status update for child \c pid.
///
/// \param pid the pid of the process whose status changes
/// \param status the status as returned by wait
static void handle_child_status(pid_t pid, int status) {
    bool found_proc = false;
    const job_t *j = NULL;
    process_t *p = NULL;

    job_iterator_t jobs;
    while (!found_proc && (j = jobs.next())) {
        process_t *prev = 0;
        for (p = j->first_process; p; p = p->next) {
            if (pid == p->pid) {
                mark_process_status(p, status);
                if (p->completed && prev && !prev->completed && prev->pid) {
                    kill(prev->pid, SIGPIPE);
                }
                found_proc = true;
                break;
            }
            prev = p;
        }
    }

    // If the child process was not killed by a signal or other than SIGINT or SIGQUIT we're done.
    if (!WIFSIGNALED(status) || (WTERMSIG(status) != SIGINT && WTERMSIG(status) != SIGQUIT)) {
        return;
    }

    if (is_interactive_session) {
        // In an interactive session, tell the principal parser to skip all blocks we're executing
        // so control-C returns control to the user.
        if (p && found_proc) parser_t::skip_all_blocks();
    } else {
        // Deliver the SIGINT or SIGQUIT signal to ourself since we're not interactive.
        struct sigaction act;
        sigemptyset(&act.sa_mask);
        act.sa_flags = 0;
        act.sa_handler = SIG_DFL;
        sigaction(SIGINT, &act, 0);
        sigaction(SIGQUIT, &act, 0);
        kill(getpid(), WTERMSIG(status));
    }

#if 0
    // TODO: Decide whether to eliminate this block or have it emit a warning message.
    // WARNING: See the special short-circuit logic above vis-a-vis signals.
    if (!found_proc) {
        // A child we lost track of? There have been bugs in both subshell handling and in builtin
        // handling that have caused this previously...
    }
#endif
    return;
}
Esempio n. 8
0
/**
   Handle status update for child \c pid. This function is called by
   the signal handler, so it mustn't use malloc or any such hitech
   nonsense.

   \param pid the pid of the process whose status changes
   \param status the status as returned by wait
*/
static void handle_child_status( pid_t pid, int status )
{
	bool found_proc = false;
	const job_t *j=0;
	process_t *p=0;
//	char mess[MESS_SIZE];	
	/*
	  snprintf( mess, 
	  MESS_SIZE,
	  "Process %d\n",
	  (int) pid );
	  write( 2, mess, strlen(mess ));
	*/

    job_iterator_t jobs;
	while (! found_proc && (j = jobs.next()))
	{
		process_t *prev=0;
		for( p=j->first_process; p; p=p->next )
		{
			if( pid == p->pid )
			{
/*				snprintf( mess,
  MESS_SIZE,
  "Process %d is %ls from job %ls\n",
  (int) pid, p->actual_cmd, j->command );
  write( 2, mess, strlen(mess ));
*/		
				
				mark_process_status ( j, p, status);
				if( p->completed && prev != 0  )
				{
					if( !prev->completed && prev->pid)
					{
						/*					snprintf( mess,
						  MESS_SIZE,
						  "Kill previously uncompleted process %ls (%d)\n",
						  prev->actual_cmd, 
						  prev->pid );
						  write( 2, mess, strlen(mess ));
						*/
						kill(prev->pid,SIGPIPE);
					}
				}
				found_proc = true;
				break;
			}
			prev = p;
		}
	}


	if( WIFSIGNALED( status ) && 
		( WTERMSIG(status)==SIGINT  || 
		  WTERMSIG(status)==SIGQUIT ) )
	{
		if( !is_interactive_session )
		{			
			struct sigaction act;
			sigemptyset( & act.sa_mask );
			act.sa_flags=0;	
			act.sa_handler=SIG_DFL;
			sigaction( SIGINT, &act, 0 );
			sigaction( SIGQUIT, &act, 0 );
			kill( getpid(), WTERMSIG(status) );
		}
		else
		{
            /* In an interactive session, tell the principal parser to skip all blocks we're executing so control-C returns control to the user. */
			if( p && found_proc )
			{
                parser_t::skip_all_blocks();
			}			
		}
	}
		
	if( !found_proc )
	{
		/* 
		   A child we lost track of?
		   
		   There have been bugs in both subshell handling and in
		   builtin handling that have caused this previously...
		*/
/*		snprintf( mess, 
  MESS_SIZE,
  "Process %d not found by %d\n",
  (int) pid, (int)getpid() );

  write( 2, mess, strlen(mess ));
*/
	}	
	return;
}
Esempio n. 9
0
/**
   Handle status update for child \c pid.
 
   \param pid the pid of the process whose status changes
   \param status the status as returned by wait
*/
static void handle_child_status(pid_t pid, int status)
{
    bool found_proc = false;
    const job_t *j = NULL;
    process_t *p = NULL;

    job_iterator_t jobs;
    while (! found_proc && (j = jobs.next()))
    {
        process_t *prev=0;
        for (p=j->first_process; p; p=p->next)
        {
            if (pid == p->pid)
            {
                mark_process_status(j, p, status);
                if (p->completed && prev != 0)
                {
                    if (!prev->completed && prev->pid)
                    {
                        kill(prev->pid,SIGPIPE);
                    }
                }
                found_proc = true;
                break;
            }
            prev = p;
        }
    }


    if (WIFSIGNALED(status) &&
            (WTERMSIG(status)==SIGINT  ||
             WTERMSIG(status)==SIGQUIT))
    {
        if (!is_interactive_session)
        {
            struct sigaction act;
            sigemptyset(& act.sa_mask);
            act.sa_flags=0;
            act.sa_handler=SIG_DFL;
            sigaction(SIGINT, &act, 0);
            sigaction(SIGQUIT, &act, 0);
            kill(getpid(), WTERMSIG(status));
        }
        else
        {
            /* In an interactive session, tell the principal parser to skip all blocks we're executing so control-C returns control to the user. */
            if (p && found_proc)
            {
                parser_t::skip_all_blocks();
            }
        }
    }

    if (!found_proc)
    {
        /*
           A child we lost track of?

           There have been bugs in both subshell handling and in
           builtin handling that have caused this previously...
        */
    }
    return;
}