mirror of
https://github.com/fish-shell/fish-shell
synced 2024-12-26 12:53:13 +00:00
Change the foregrounf/background code a bit, fixes bug where mulktiple jobs want foreground status. Is this fix enough or are there still corner cases?
darcs-hash:20060118124248-ac50b-cbbddb8c6dad1f44826050395cda647fa9348f0f.gz
This commit is contained in:
parent
e15c7fd7e0
commit
05736978bb
7 changed files with 44 additions and 36 deletions
4
event.c
4
event.c
|
@ -325,7 +325,6 @@ static void event_fire_internal( event_t *event )
|
|||
array_list_t *fire=0;
|
||||
|
||||
int was_subshell = is_subshell;
|
||||
// int was_interactive = is_interactive;
|
||||
|
||||
/*
|
||||
First we free all events that have been removed
|
||||
|
@ -402,7 +401,6 @@ static void event_fire_internal( event_t *event )
|
|||
they are marked as non-interactive and as a subshell
|
||||
*/
|
||||
is_subshell=1;
|
||||
// is_interactive=0;
|
||||
eval( (wchar_t *)b->buff, 0, TOP );
|
||||
|
||||
}
|
||||
|
@ -411,7 +409,6 @@ static void event_fire_internal( event_t *event )
|
|||
Restore interactivity flags
|
||||
*/
|
||||
is_subshell = was_subshell;
|
||||
// is_interactive = was_interactive;
|
||||
|
||||
if( b )
|
||||
{
|
||||
|
@ -531,7 +528,6 @@ void event_fire( event_t *event )
|
|||
sig_list[active_list].signal[sig_list[active_list].count++]=event->param1.signal;
|
||||
else
|
||||
sig_list[active_list].overflow=1;
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
14
exec.c
14
exec.c
|
@ -392,8 +392,8 @@ static int handle_child_io( io_data_t *io, int exit_on_error )
|
|||
static int setup_child_process( job_t *j, process_t *p )
|
||||
{
|
||||
int res;
|
||||
|
||||
if( is_interactive && p->type==EXTERNAL )
|
||||
|
||||
if( j->terminal )
|
||||
{
|
||||
pid_t pid;
|
||||
/*
|
||||
|
@ -442,6 +442,7 @@ static int setup_child_process( job_t *j, process_t *p )
|
|||
*/
|
||||
static void launch_process( process_t *p )
|
||||
{
|
||||
// debug( 1, L"exec '%ls'", p->argv[0] );
|
||||
|
||||
execve (wcs2str(p->actual_cmd), wcsv2strv( (const wchar_t **) p->argv), env_export_arr( 0 ) );
|
||||
debug( 0,
|
||||
|
@ -601,7 +602,7 @@ static void internal_exec_helper( const wchar_t *def,
|
|||
static int handle_new_child( job_t *j, process_t *p )
|
||||
{
|
||||
|
||||
if( is_interactive && p->type==EXTERNAL )
|
||||
if( j->terminal )
|
||||
{
|
||||
int new_pgid=0;
|
||||
|
||||
|
@ -678,7 +679,7 @@ void exec( job_t *j )
|
|||
int exec_error=0;
|
||||
|
||||
|
||||
debug( 4, L"Exec job %ls with id %d", j->command, j->job_id );
|
||||
debug( 4, L"Exec job '%ls' with id %d", j->command, j->job_id );
|
||||
|
||||
if( j->first_process->type==INTERNAL_EXEC )
|
||||
{
|
||||
|
@ -704,8 +705,7 @@ void exec( job_t *j )
|
|||
return;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
pipe_read.fd=0;
|
||||
pipe_write.fd=1;
|
||||
|
@ -1014,6 +1014,7 @@ void exec( job_t *j )
|
|||
if( io_buffer->param2.out_buffer->used != 0 )
|
||||
{
|
||||
pid = fork();
|
||||
|
||||
if( pid == 0 )
|
||||
{
|
||||
/*
|
||||
|
@ -1309,5 +1310,6 @@ int exec_subshell( const wchar_t *cmd,
|
|||
}
|
||||
|
||||
io_buffer_destroy( io_buffer );
|
||||
|
||||
return status;
|
||||
}
|
||||
|
|
20
input.c
20
input.c
|
@ -1292,12 +1292,32 @@ static int interrupt_handler()
|
|||
Fire any pending events
|
||||
*/
|
||||
event_fire( 0 );
|
||||
|
||||
/*
|
||||
Reap stray processes, including printing exit status messages
|
||||
*/
|
||||
if( job_reap( 1 ) )
|
||||
repaint();
|
||||
|
||||
/*
|
||||
Check if we should exit
|
||||
*/
|
||||
if( exit_status() )
|
||||
{
|
||||
return R_EXIT;
|
||||
}
|
||||
|
||||
/*
|
||||
Tell the reader an event occured
|
||||
*/
|
||||
if( reader_interupted() )
|
||||
{
|
||||
/*
|
||||
Return 3, i.e. the character read by a Control-C.
|
||||
*/
|
||||
return 3;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
7
parser.c
7
parser.c
|
@ -1162,6 +1162,7 @@ static void parse_job_main_loop( process_t *p,
|
|||
|
||||
case TOK_BACKGROUND:
|
||||
j->fg = 0;
|
||||
j->terminal=0;
|
||||
case TOK_END:
|
||||
{
|
||||
p->argv = list_to_char_arr( args );
|
||||
|
@ -1981,10 +1982,10 @@ static void eval_job( tokenizer *tok )
|
|||
j->fg=1;
|
||||
j->constructed=0;
|
||||
j->skip_notification = is_subshell || is_block || is_event || (!is_interactive);
|
||||
|
||||
current_block->job = j;
|
||||
|
||||
j->terminal = is_interactive && !is_subshell;
|
||||
|
||||
current_block->job = j;
|
||||
|
||||
if( is_interactive )
|
||||
{
|
||||
if( tcgetattr (0, &j->tmodes) )
|
||||
|
|
26
proc.c
26
proc.c
|
@ -846,22 +846,6 @@ 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)
|
||||
{
|
||||
|
@ -873,7 +857,7 @@ void job_continue (job_t *j, int cont)
|
|||
first_job = j;
|
||||
j->notified = 0;
|
||||
|
||||
debug( 3,
|
||||
debug( 4,
|
||||
L"Continue on job %d (%ls), %ls, %ls",
|
||||
j->job_id,
|
||||
j->command,
|
||||
|
@ -882,7 +866,7 @@ void job_continue (job_t *j, int cont)
|
|||
|
||||
if( !job_is_completed( j ) )
|
||||
{
|
||||
if( is_interactive && job_is_external( j ) )
|
||||
if( j->terminal )
|
||||
{
|
||||
|
||||
/* Put the job into the foreground. */
|
||||
|
@ -937,6 +921,7 @@ void job_continue (job_t *j, int cont)
|
|||
{
|
||||
int quit = 0;
|
||||
|
||||
// debug( 1, L"wait loop" );
|
||||
/*
|
||||
Wait for job to report. Looks a bit ugly because it has to
|
||||
handle the possibility that a signal is dispatched while
|
||||
|
@ -953,7 +938,7 @@ void job_continue (job_t *j, int cont)
|
|||
if( !quit )
|
||||
{
|
||||
|
||||
debug( 3, L"select_try()" );
|
||||
// debug( 1, L"select_try()" );
|
||||
switch( select_try(j) )
|
||||
{
|
||||
case 1:
|
||||
|
@ -973,6 +958,7 @@ void job_continue (job_t *j, int cont)
|
|||
short-lived jobs.
|
||||
*/
|
||||
int status;
|
||||
// debug( 1, L"waitpid" );
|
||||
pid_t pid = waitpid(-1, &status, WUNTRACED );
|
||||
if( pid > 0 )
|
||||
handle_child_status( pid, status );
|
||||
|
@ -1010,7 +996,7 @@ void job_continue (job_t *j, int cont)
|
|||
/*
|
||||
Put the shell back in the foreground.
|
||||
*/
|
||||
if( is_interactive && job_is_external( j ) )
|
||||
if( j->terminal )
|
||||
{
|
||||
signal_block();
|
||||
if( tcsetpgrp (0, getpid()) )
|
||||
|
|
5
proc.h
5
proc.h
|
@ -154,7 +154,10 @@ typedef struct job
|
|||
|
||||
/** Skip executing this job. This flag is set by the short-circut builtins, i.e. and and or */
|
||||
int skip;
|
||||
|
||||
|
||||
/** Whether this job wants to have control of the terminal when it is in the foreground */
|
||||
int terminal;
|
||||
|
||||
/** Pointer to the next job */
|
||||
struct job *next;
|
||||
}
|
||||
|
|
4
reader.c
4
reader.c
|
@ -2525,8 +2525,8 @@ static int read_i()
|
|||
{
|
||||
prev_end_loop=0;
|
||||
}
|
||||
|
||||
error_reset();
|
||||
|
||||
}
|
||||
reader_pop();
|
||||
return 0;
|
||||
|
@ -2829,7 +2829,7 @@ wchar_t *reader_readline()
|
|||
break;
|
||||
}
|
||||
|
||||
/* exit, but only if line is empty or the previous keypress was also an exit call */
|
||||
/* exit, but only if line is empty */
|
||||
case R_EXIT:
|
||||
{
|
||||
if( data->buff_len == 0 )
|
||||
|
|
Loading…
Reference in a new issue