Put jobs in functions and block into their own process group in interactive mode, but do not put the 'fake jobs' associated with functions in a group

darcs-hash:20060116001556-ac50b-b91d6e45fe136874237ad31538de02b5e63a8bac.gz
This commit is contained in:
axel 2006-01-16 10:15:56 +10:00
parent 24ca6ceb47
commit 18bbb5ad01
2 changed files with 55 additions and 16 deletions

14
exec.c
View File

@ -389,11 +389,11 @@ static int handle_child_io( io_data_t *io, int exit_on_error )
\return 1 on sucess, 0 on failiure
*/
static int setup_child_process( job_t *j, int exit_on_error )
static int setup_child_process( job_t *j, process_t *p )
{
int res;
if( is_interactive && !is_subshell && !is_block)
if( is_interactive && p->type==EXTERNAL )
{
pid_t pid;
/*
@ -418,7 +418,7 @@ static int setup_child_process( job_t *j, int exit_on_error )
}
}
res = handle_child_io( j->io, exit_on_error );
res = handle_child_io( j->io, (p==0) );
/* Set the handling for job control signals back to the default. */
if( res )
@ -601,7 +601,7 @@ static void internal_exec_helper( const wchar_t *def,
static int handle_new_child( job_t *j, process_t *p )
{
if(is_interactive && !is_subshell && !is_block)
if( is_interactive && p->type==EXTERNAL )
{
int new_pgid=0;
@ -1020,7 +1020,7 @@ void exec( job_t *j )
This is the child process. Write out the contents of the pipeline.
*/
p->pid = getpid();
setup_child_process( j, 1 );
setup_child_process( j, p );
write( io_buffer->fd,
io_buffer->param2.out_buffer->buff,
io_buffer->param2.out_buffer->used );
@ -1108,7 +1108,7 @@ void exec( job_t *j )
This is the child process.
*/
p->pid = getpid();
setup_child_process( j, 1 );
setup_child_process( j, p );
if( sb_out->used )
fwprintf( stdout, L"%ls", sb_out->buff );
if( sb_err->used )
@ -1150,7 +1150,7 @@ void exec( job_t *j )
This is the child process.
*/
p->pid = getpid();
setup_child_process( j, 1 );
setup_child_process( j, p );
launch_process( p );
/*

55
proc.c
View File

@ -60,10 +60,14 @@ Some of the code in this file is based on code from the Glibc manual.
*/
#define BUFFER_SIZE 4096
/** Status of last process to exit */
/**
Status of last process to exit
*/
static int last_status=0;
/** Signal flag */
/**
Signal flag
*/
static sig_atomic_t got_signal=0;
job_t *first_job=0;
@ -85,6 +89,7 @@ static event_t event;
Stringbuffer used to create arguments when firing events
*/
static string_buffer_t event_pid;
/**
Stringbuffer used to create arguments when firing events
*/
@ -127,8 +132,9 @@ static void free_process( process_t *p )
free( p );
}
/** Remove job from list of jobs */
/**
Remove job from list of jobs
*/
static int job_remove( job_t *j )
{
job_t *prev=0, *curr=first_job;
@ -258,6 +264,8 @@ job_t *job_get_from_pid( int pid )
/*
Return true if all processes in the job have stopped or completed.
\param j the job to test
*/
int job_is_stopped( const job_t *j )
{
@ -276,6 +284,8 @@ int job_is_stopped( const job_t *j )
/*
Return true if all processes in the job have completed.
\param j the job to test
*/
int job_is_completed( const job_t *j )
{
@ -294,6 +304,8 @@ int job_is_completed( const job_t *j )
/**
Return true if all processes in the job have completed.
\param j the job to test
*/
static int job_last_is_completed( const job_t *j )
{
@ -339,7 +351,11 @@ static void mark_process_status( job_t *j,
/**
Handle status update for child \c pid. This function is called by
the signal handler, so it mustn't use malloc or any such nonsense.
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 )
{
@ -475,6 +491,9 @@ void job_handle_signal ( int signal, siginfo_t *info, void *con )
/**
Format information about job status for the user to look at.
\param j the job to test
\param status a string description of the job exit type
*/
static void format_job_info( const job_t *j, const wchar_t *status )
{
@ -733,6 +752,8 @@ void proc_update_jiffies()
Check if there are buffers associated with the job, and select on
them for a while if available.
\param j the job to test
\return 1 if buffers were avaialble, zero otherwise
*/
static int select_try( job_t *j )
@ -772,6 +793,8 @@ static int select_try( job_t *j )
/**
Read from descriptors until they are empty.
\param j the job to test
*/
static void read_try( job_t *j )
{
@ -823,6 +846,23 @@ static void read_try( job_t *j )
}
}
/**
Test if a specified job contains external commands
\param j the job to test
*/
static int job_is_external( job_t *j )
{
process_t *p;
for( p=j->first_process; p; p=p->next )
{
if( p->type == EXTERNAL )
return 1;
}
return 0;
}
void job_continue (job_t *j, int cont)
{
/*
@ -842,7 +882,7 @@ void job_continue (job_t *j, int cont)
if( !job_is_completed( j ) )
{
if( !is_subshell && is_interactive && !is_block)
if( is_interactive && job_is_external( j ) )
{
/* Put the job into the foreground. */
@ -943,7 +983,6 @@ void job_continue (job_t *j, int cont)
}
}
}
}
if( j->fg )
@ -971,7 +1010,7 @@ void job_continue (job_t *j, int cont)
/*
Put the shell back in the foreground.
*/
if( !is_subshell && is_interactive && !is_block)
if( is_interactive && job_is_external( j ) )
{
signal_block();
if( tcsetpgrp (0, getpid()) )