mirror of
https://github.com/fish-shell/fish-shell.git
synced 2025-03-25 04:22:04 +08:00
Use bitset to implement flags for jobs instead of wasting a whole int for every flag
darcs-hash:20061025204759-ac50b-ea07caa30782a1ea02d2cd8aa7cbc94474047a10.gz
This commit is contained in:
parent
cdc52f7bde
commit
3a128e1484
17
builtin.c
17
builtin.c
@ -2216,8 +2216,8 @@ static int builtin_fg( wchar_t **argv )
|
|||||||
*/
|
*/
|
||||||
for( j=first_job; j; j=j->next )
|
for( j=first_job; j; j=j->next )
|
||||||
{
|
{
|
||||||
if( j->constructed && (!job_is_completed(j)) &&
|
if( job_get_flag( j, JOB_CONSTRUCTED ) && (!job_is_completed(j)) &&
|
||||||
( (job_is_stopped(j) || !j->fg) && (j->job_control) ) )
|
( (job_is_stopped(j) || (!job_get_flag(j, JOB_FOREGROUND)) ) && job_get_flag( j, JOB_CONTROL) ) )
|
||||||
{
|
{
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -2288,7 +2288,7 @@ static int builtin_fg( wchar_t **argv )
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
j = job_get_from_pid( pid );
|
j = job_get_from_pid( pid );
|
||||||
if( !j || !j->constructed || job_is_completed( j ))
|
if( !j || !job_get_flag( j, JOB_CONSTRUCTED ) || job_is_completed( j ))
|
||||||
{
|
{
|
||||||
sb_printf( sb_err,
|
sb_printf( sb_err,
|
||||||
_( L"%ls: No suitable job: %d\n" ),
|
_( L"%ls: No suitable job: %d\n" ),
|
||||||
@ -2297,7 +2297,7 @@ static int builtin_fg( wchar_t **argv )
|
|||||||
builtin_print_help( argv[0], sb_err );
|
builtin_print_help( argv[0], sb_err );
|
||||||
j=0;
|
j=0;
|
||||||
}
|
}
|
||||||
else if( !j->job_control )
|
else if( !job_get_flag( j, JOB_CONTROL) )
|
||||||
{
|
{
|
||||||
sb_printf( sb_err,
|
sb_printf( sb_err,
|
||||||
_( L"%ls: Can't put job %d, '%ls' to foreground because it is not under job control\n" ),
|
_( L"%ls: Can't put job %d, '%ls' to foreground because it is not under job control\n" ),
|
||||||
@ -2339,7 +2339,7 @@ static int builtin_fg( wchar_t **argv )
|
|||||||
reader_write_title();
|
reader_write_title();
|
||||||
|
|
||||||
make_first( j );
|
make_first( j );
|
||||||
j->fg=1;
|
job_set_flag( j, JOB_FOREGROUND, 1 );
|
||||||
|
|
||||||
job_continue( j, job_is_stopped(j) );
|
job_continue( j, job_is_stopped(j) );
|
||||||
}
|
}
|
||||||
@ -2360,7 +2360,7 @@ static int send_to_bg( job_t *j, const wchar_t *name )
|
|||||||
builtin_print_help( L"bg", sb_err );
|
builtin_print_help( L"bg", sb_err );
|
||||||
return STATUS_BUILTIN_ERROR;
|
return STATUS_BUILTIN_ERROR;
|
||||||
}
|
}
|
||||||
else if( !j->job_control )
|
else if( !job_get_flag( j, JOB_CONTROL ) )
|
||||||
{
|
{
|
||||||
sb_printf( sb_err,
|
sb_printf( sb_err,
|
||||||
_( L"%ls: Can't put job %d, '%ls' to background because it is not under job control\n" ),
|
_( L"%ls: Can't put job %d, '%ls' to background because it is not under job control\n" ),
|
||||||
@ -2378,7 +2378,7 @@ static int send_to_bg( job_t *j, const wchar_t *name )
|
|||||||
j->command );
|
j->command );
|
||||||
}
|
}
|
||||||
make_first( j );
|
make_first( j );
|
||||||
j->fg=0;
|
job_set_flag( j, JOB_FOREGROUND, 0 );
|
||||||
job_continue( j, job_is_stopped(j) );
|
job_continue( j, job_is_stopped(j) );
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -2396,7 +2396,7 @@ static int builtin_bg( wchar_t **argv )
|
|||||||
job_t *j;
|
job_t *j;
|
||||||
for( j=first_job; j; j=j->next )
|
for( j=first_job; j; j=j->next )
|
||||||
{
|
{
|
||||||
if( job_is_stopped(j) && j->job_control && (!job_is_completed(j)) )
|
if( job_is_stopped(j) && job_get_flag( j, JOB_CONTROL ) && (!job_is_completed(j)) )
|
||||||
{
|
{
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -2519,7 +2519,6 @@ static void builtin_end_add_function_def( function_data_t *d )
|
|||||||
wchar_t *def = wcsndup( parser_get_buffer()+current_block->tok_pos,
|
wchar_t *def = wcsndup( parser_get_buffer()+current_block->tok_pos,
|
||||||
parser_get_job_pos()-current_block->tok_pos );
|
parser_get_job_pos()-current_block->tok_pos );
|
||||||
|
|
||||||
|
|
||||||
function_add( d->name,
|
function_add( d->name,
|
||||||
def,
|
def,
|
||||||
d->description,
|
d->description,
|
||||||
|
@ -276,7 +276,7 @@ static int builtin_jobs( wchar_t **argv )
|
|||||||
*/
|
*/
|
||||||
for( j=first_job; j; j=j->next )
|
for( j=first_job; j; j=j->next )
|
||||||
{
|
{
|
||||||
if( j->constructed && !job_is_completed(j) )
|
if( (j->flags & JOB_CONSTRUCTED) && !job_is_completed(j) )
|
||||||
{
|
{
|
||||||
builtin_jobs_print( j, mode, !found );
|
builtin_jobs_print( j, mode, !found );
|
||||||
return 0;
|
return 0;
|
||||||
@ -330,7 +330,7 @@ static int builtin_jobs( wchar_t **argv )
|
|||||||
/*
|
/*
|
||||||
Ignore unconstructed jobs, i.e. ourself.
|
Ignore unconstructed jobs, i.e. ourself.
|
||||||
*/
|
*/
|
||||||
if( j->constructed && !job_is_completed(j) )
|
if( (j->flags & JOB_CONSTRUCTED) && !job_is_completed(j) )
|
||||||
{
|
{
|
||||||
builtin_jobs_print( j, mode, !found );
|
builtin_jobs_print( j, mode, !found );
|
||||||
found = 1;
|
found = 1;
|
||||||
|
24
exec.c
24
exec.c
@ -609,7 +609,7 @@ static int set_child_group( job_t *j, process_t *p, int print_errors )
|
|||||||
{
|
{
|
||||||
int res = 0;
|
int res = 0;
|
||||||
|
|
||||||
if( j->job_control )
|
if( job_get_flag( j, JOB_CONTROL ) )
|
||||||
{
|
{
|
||||||
if (!j->pgid)
|
if (!j->pgid)
|
||||||
{
|
{
|
||||||
@ -638,7 +638,7 @@ static int set_child_group( job_t *j, process_t *p, int print_errors )
|
|||||||
j->pgid = getpid();
|
j->pgid = getpid();
|
||||||
}
|
}
|
||||||
|
|
||||||
if( j->terminal && j->fg )
|
if( job_get_flag( j, JOB_TERMINAL ) && job_get_flag( j, JOB_FOREGROUND ) )
|
||||||
{
|
{
|
||||||
if( tcsetpgrp (0, j->pgid) && print_errors )
|
if( tcsetpgrp (0, j->pgid) && print_errors )
|
||||||
{
|
{
|
||||||
@ -735,7 +735,7 @@ void exec( job_t *j )
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
j->constructed=1;
|
job_set_flag( j, JOB_CONSTRUCTED, 1 );
|
||||||
j->first_process->completed=1;
|
j->first_process->completed=1;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -767,7 +767,7 @@ void exec( job_t *j )
|
|||||||
inside a pipeline.
|
inside a pipeline.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
if( j->job_control )
|
if( job_get_flag( j, JOB_CONTROL ) )
|
||||||
{
|
{
|
||||||
for( p=j->first_process; p; p = p->next )
|
for( p=j->first_process; p; p = p->next )
|
||||||
{
|
{
|
||||||
@ -991,8 +991,8 @@ void exec( job_t *j )
|
|||||||
|
|
||||||
builtin_out_redirect = has_fd( j->io, 1 );
|
builtin_out_redirect = has_fd( j->io, 1 );
|
||||||
builtin_err_redirect = has_fd( j->io, 2 );
|
builtin_err_redirect = has_fd( j->io, 2 );
|
||||||
fg = j->fg;
|
fg = job_get_flag( j, JOB_FOREGROUND );
|
||||||
j->fg = 0;
|
job_set_flag( j, JOB_FOREGROUND, 0 );
|
||||||
|
|
||||||
signal_unblock();
|
signal_unblock();
|
||||||
|
|
||||||
@ -1005,7 +1005,7 @@ void exec( job_t *j )
|
|||||||
false during builtin execution so as not to confuse
|
false during builtin execution so as not to confuse
|
||||||
some job-handling builtins.
|
some job-handling builtins.
|
||||||
*/
|
*/
|
||||||
j->fg = fg;
|
job_set_flag( j, JOB_FOREGROUND, fg );
|
||||||
}
|
}
|
||||||
|
|
||||||
if( close_stdin )
|
if( close_stdin )
|
||||||
@ -1041,7 +1041,7 @@ void exec( job_t *j )
|
|||||||
*/
|
*/
|
||||||
if( p->next == 0 )
|
if( p->next == 0 )
|
||||||
{
|
{
|
||||||
proc_set_last_status( j->negate?(!status):status);
|
proc_set_last_status( job_get_flag( j, JOB_NEGATE )?(!status):status);
|
||||||
}
|
}
|
||||||
p->completed = 1;
|
p->completed = 1;
|
||||||
break;
|
break;
|
||||||
@ -1091,7 +1091,7 @@ void exec( job_t *j )
|
|||||||
{
|
{
|
||||||
if( p->next == 0 )
|
if( p->next == 0 )
|
||||||
{
|
{
|
||||||
proc_set_last_status( j->negate?(!status):status);
|
proc_set_last_status( job_get_flag( j, JOB_NEGATE )?(!status):status);
|
||||||
}
|
}
|
||||||
p->completed = 1;
|
p->completed = 1;
|
||||||
}
|
}
|
||||||
@ -1182,7 +1182,7 @@ void exec( job_t *j )
|
|||||||
{
|
{
|
||||||
debug( 3, L"Set status of %ls to %d using short circut", j->command, p->status );
|
debug( 3, L"Set status of %ls to %d using short circut", j->command, p->status );
|
||||||
|
|
||||||
proc_set_last_status( j->negate?(!p->status):p->status );
|
proc_set_last_status( job_get_flag( j, JOB_NEGATE )?(!p->status):p->status );
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -1316,9 +1316,9 @@ void exec( job_t *j )
|
|||||||
for( tmp = block_io; tmp; tmp=tmp->next )
|
for( tmp = block_io; tmp; tmp=tmp->next )
|
||||||
j->io = io_remove( j->io, tmp );
|
j->io = io_remove( j->io, tmp );
|
||||||
|
|
||||||
j->constructed = 1;
|
job_set_flag( j, JOB_CONSTRUCTED, 1 );
|
||||||
|
|
||||||
if( !j->fg )
|
if( !job_get_flag( j, JOB_FOREGROUND ) )
|
||||||
{
|
{
|
||||||
proc_last_bg_pid = j->pgid;
|
proc_last_bg_pid = j->pgid;
|
||||||
}
|
}
|
||||||
|
30
parser.c
30
parser.c
@ -1362,7 +1362,7 @@ static void parse_job_main_loop( process_t *p,
|
|||||||
|
|
||||||
case TOK_BACKGROUND:
|
case TOK_BACKGROUND:
|
||||||
{
|
{
|
||||||
j->fg = 0;
|
job_set_flag( j, JOB_FOREGROUND, 0 );
|
||||||
}
|
}
|
||||||
|
|
||||||
case TOK_END:
|
case TOK_END:
|
||||||
@ -1381,7 +1381,7 @@ static void parse_job_main_loop( process_t *p,
|
|||||||
{
|
{
|
||||||
int skip=0;
|
int skip=0;
|
||||||
|
|
||||||
if( j->skip )
|
if( job_get_flag( j, JOB_SKIP ) )
|
||||||
{
|
{
|
||||||
skip = 1;
|
skip = 1;
|
||||||
}
|
}
|
||||||
@ -1622,7 +1622,7 @@ static void parse_job_main_loop( process_t *p,
|
|||||||
{
|
{
|
||||||
if( unmatched_wildcard && !matched_wildcard )
|
if( unmatched_wildcard && !matched_wildcard )
|
||||||
{
|
{
|
||||||
j->wildcard_error = 1;
|
job_set_flag( j, JOB_WILDCARD_ERROR, 1 );
|
||||||
proc_set_last_status( STATUS_UNMATCHED_WILDCARD );
|
proc_set_last_status( STATUS_UNMATCHED_WILDCARD );
|
||||||
if( is_interactive && !is_block )
|
if( is_interactive && !is_block )
|
||||||
{
|
{
|
||||||
@ -1783,7 +1783,7 @@ static int parse_job( process_t *p,
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
j->negate=1-j->negate;
|
job_set_flag( j, JOB_NEGATE, !job_get_flag( j, JOB_NEGATE ) );
|
||||||
consumed=1;
|
consumed=1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1796,7 +1796,7 @@ static int parse_job( process_t *p,
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
j->skip = proc_get_last_status();
|
job_set_flag( j, JOB_SKIP, proc_get_last_status());
|
||||||
consumed=1;
|
consumed=1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1809,7 +1809,7 @@ static int parse_job( process_t *p,
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
j->skip = !proc_get_last_status();
|
job_set_flag( j, JOB_SKIP, !proc_get_last_status());
|
||||||
consumed=1;
|
consumed=1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -2053,7 +2053,8 @@ static int parse_job( process_t *p,
|
|||||||
fwprintf( stderr, L"%ls", parser_current_line() );
|
fwprintf( stderr, L"%ls", parser_current_line() );
|
||||||
|
|
||||||
current_tokenizer_pos=tmp;
|
current_tokenizer_pos=tmp;
|
||||||
j->skip=1;
|
|
||||||
|
job_set_flag( j, JOB_SKIP, 1 );
|
||||||
proc_set_last_status( STATUS_UNKNOWN_COMMAND );
|
proc_set_last_status( STATUS_UNKNOWN_COMMAND );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -2258,9 +2259,10 @@ static void eval_job( tokenizer *tok )
|
|||||||
case TOK_STRING:
|
case TOK_STRING:
|
||||||
{
|
{
|
||||||
j = job_create();
|
j = job_create();
|
||||||
j->fg=1;
|
job_set_flag( j, JOB_FOREGROUND, 1 );
|
||||||
j->terminal = j->job_control && (!is_subshell && !is_event);
|
job_set_flag( j, JOB_TERMINAL, job_get_flag( j, JOB_CONTROL ) );
|
||||||
j->skip_notification = is_subshell || is_block || is_event || (!is_interactive);
|
job_set_flag( j, JOB_TERMINAL, job_get_flag( j, JOB_CONTROL ) && (!is_subshell && !is_event));
|
||||||
|
job_set_flag( j, JOB_SKIP_NOTIFICATION, is_subshell || is_block || is_event || (!is_interactive));
|
||||||
|
|
||||||
current_block->job = j;
|
current_block->job = j;
|
||||||
|
|
||||||
@ -2303,11 +2305,11 @@ static void eval_job( tokenizer *tok )
|
|||||||
p->cmd = wcsdup( j->command );
|
p->cmd = wcsdup( j->command );
|
||||||
p->skipped=current_block->skip;
|
p->skipped=current_block->skip;
|
||||||
}
|
}
|
||||||
|
|
||||||
skip |= current_block->skip;
|
skip |= current_block->skip;
|
||||||
skip |= j->wildcard_error;
|
skip |= job_get_flag( j, JOB_WILDCARD_ERROR );
|
||||||
skip |= j->skip;
|
skip |= job_get_flag( j, JOB_SKIP );
|
||||||
|
|
||||||
if(!skip )
|
if(!skip )
|
||||||
{
|
{
|
||||||
int was_builtin = 0;
|
int was_builtin = 0;
|
||||||
|
59
proc.c
59
proc.c
@ -211,8 +211,10 @@ job_t *job_create()
|
|||||||
res->job_id = free_id;
|
res->job_id = free_id;
|
||||||
first_job = res;
|
first_job = res;
|
||||||
|
|
||||||
res->job_control = (job_control_mode==JOB_CONTROL_ALL) ||
|
job_set_flag( res,
|
||||||
((job_control_mode == JOB_CONTROL_INTERACTIVE) && (is_interactive));
|
JOB_CONTROL,
|
||||||
|
(job_control_mode==JOB_CONTROL_ALL) ||
|
||||||
|
((job_control_mode == JOB_CONTROL_INTERACTIVE) && (is_interactive)) );
|
||||||
|
|
||||||
// if( res->job_id > 2 )
|
// if( res->job_id > 2 )
|
||||||
// fwprintf( stderr, L"Create job %d\n", res->job_id );
|
// fwprintf( stderr, L"Create job %d\n", res->job_id );
|
||||||
@ -287,6 +289,20 @@ int job_is_completed( const job_t *j )
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void job_set_flag( job_t *j, int flag, int set )
|
||||||
|
{
|
||||||
|
if( set )
|
||||||
|
j->flags |= flag;
|
||||||
|
else
|
||||||
|
j->flags = j->flags & (0xffffffff ^ flag);
|
||||||
|
}
|
||||||
|
|
||||||
|
int job_get_flag( job_t *j, int flag )
|
||||||
|
{
|
||||||
|
return j->flags&flag?1:0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Store the status of the process pid that was returned by waitpid.
|
Store the status of the process pid that was returned by waitpid.
|
||||||
Return 0 if all went well, nonzero otherwise.
|
Return 0 if all went well, nonzero otherwise.
|
||||||
@ -521,7 +537,7 @@ int job_reap( int interactive )
|
|||||||
sent to the console, do not consider reaping jobs that need
|
sent to the console, do not consider reaping jobs that need
|
||||||
status messages
|
status messages
|
||||||
*/
|
*/
|
||||||
if( (!j->skip_notification) && (!interactive) && (!j->fg))
|
if( (!job_get_flag( j, JOB_SKIP_NOTIFICATION ) ) && (!interactive) && (!job_get_flag( j, JOB_FOREGROUND )))
|
||||||
{
|
{
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@ -549,8 +565,8 @@ int job_reap( int interactive )
|
|||||||
{
|
{
|
||||||
int proc_is_job = ((p==j->first_process) && (p->next == 0));
|
int proc_is_job = ((p==j->first_process) && (p->next == 0));
|
||||||
if( proc_is_job )
|
if( proc_is_job )
|
||||||
j->notified = 1;
|
job_set_flag( j, JOB_NOTIFIED, 1 );
|
||||||
if( !j->skip_notification )
|
if( !job_get_flag( j, JOB_SKIP_NOTIFICATION ) )
|
||||||
{
|
{
|
||||||
if( proc_is_job )
|
if( proc_is_job )
|
||||||
fwprintf( stdout,
|
fwprintf( stdout,
|
||||||
@ -589,30 +605,27 @@ int job_reap( int interactive )
|
|||||||
*/
|
*/
|
||||||
if( job_is_completed( j ) )
|
if( job_is_completed( j ) )
|
||||||
{
|
{
|
||||||
if( !j->fg && !j->notified )
|
if( !job_get_flag( j, JOB_FOREGROUND) && !job_get_flag( j, JOB_NOTIFIED ) && !job_get_flag( j, JOB_SKIP_NOTIFICATION ) )
|
||||||
{
|
{
|
||||||
if( !j->skip_notification )
|
format_job_info( j, _( L"ended" ) );
|
||||||
{
|
found=1;
|
||||||
format_job_info( j, _( L"ended" ) );
|
|
||||||
found=1;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
proc_fire_event( L"JOB_EXIT", EVENT_EXIT, -j->pgid, 0 );
|
proc_fire_event( L"JOB_EXIT", EVENT_EXIT, -j->pgid, 0 );
|
||||||
proc_fire_event( L"JOB_EXIT", EVENT_JOB_ID, j->job_id, 0 );
|
proc_fire_event( L"JOB_EXIT", EVENT_JOB_ID, j->job_id, 0 );
|
||||||
|
|
||||||
job_free(j);
|
job_free(j);
|
||||||
}
|
}
|
||||||
else if( job_is_stopped( j ) && !j->notified )
|
else if( job_is_stopped( j ) && !job_get_flag( j, JOB_NOTIFIED ) )
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
Notify the user about newly stopped jobs.
|
Notify the user about newly stopped jobs.
|
||||||
*/
|
*/
|
||||||
if( !j->skip_notification )
|
if( !job_get_flag( j, JOB_SKIP_NOTIFICATION ) )
|
||||||
{
|
{
|
||||||
format_job_info( j, _( L"stopped" ) );
|
format_job_info( j, _( L"stopped" ) );
|
||||||
found=1;
|
found=1;
|
||||||
}
|
}
|
||||||
j->notified = 1;
|
job_set_flag( j, JOB_NOTIFIED, 1 );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -843,7 +856,7 @@ void job_continue (job_t *j, int cont)
|
|||||||
job_remove( j );
|
job_remove( j );
|
||||||
j->next = first_job;
|
j->next = first_job;
|
||||||
first_job = j;
|
first_job = j;
|
||||||
j->notified = 0;
|
job_set_flag( j, JOB_NOTIFIED, 0 );
|
||||||
|
|
||||||
debug( 4,
|
debug( 4,
|
||||||
L"Continue job %d (%ls), %ls, %ls",
|
L"Continue job %d (%ls), %ls, %ls",
|
||||||
@ -854,7 +867,7 @@ void job_continue (job_t *j, int cont)
|
|||||||
|
|
||||||
if( !job_is_completed( j ) )
|
if( !job_is_completed( j ) )
|
||||||
{
|
{
|
||||||
if( j->terminal && j->fg )
|
if( job_get_flag( j, JOB_TERMINAL ) && job_get_flag( j, JOB_FOREGROUND ) )
|
||||||
{
|
{
|
||||||
/* Put the job into the foreground. */
|
/* Put the job into the foreground. */
|
||||||
signal_block();
|
signal_block();
|
||||||
@ -893,7 +906,7 @@ void job_continue (job_t *j, int cont)
|
|||||||
for( p=j->first_process; p; p=p->next )
|
for( p=j->first_process; p; p=p->next )
|
||||||
p->stopped=0;
|
p->stopped=0;
|
||||||
|
|
||||||
if( j->job_control )
|
if( job_get_flag( j, JOB_CONTROL ) )
|
||||||
{
|
{
|
||||||
if( killpg( j->pgid, SIGCONT ) )
|
if( killpg( j->pgid, SIGCONT ) )
|
||||||
{
|
{
|
||||||
@ -914,7 +927,7 @@ void job_continue (job_t *j, int cont)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if( j->fg )
|
if( job_get_flag( j, JOB_FOREGROUND ) )
|
||||||
{
|
{
|
||||||
int quit = 0;
|
int quit = 0;
|
||||||
|
|
||||||
@ -968,7 +981,7 @@ void job_continue (job_t *j, int cont)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if( j->fg )
|
if( job_get_flag( j, JOB_FOREGROUND ) )
|
||||||
{
|
{
|
||||||
|
|
||||||
if( job_is_completed( j ))
|
if( job_is_completed( j ))
|
||||||
@ -986,14 +999,14 @@ void job_continue (job_t *j, int cont)
|
|||||||
if( p->pid )
|
if( p->pid )
|
||||||
{
|
{
|
||||||
debug( 3, L"Set status of %ls to %d", j->command, WEXITSTATUS(p->status) );
|
debug( 3, L"Set status of %ls to %d", j->command, WEXITSTATUS(p->status) );
|
||||||
proc_set_last_status( j->negate?(WEXITSTATUS(p->status)?0:1):WEXITSTATUS(p->status) );
|
proc_set_last_status( job_get_flag( j, JOB_NEGATE )?(WEXITSTATUS(p->status)?0:1):WEXITSTATUS(p->status) );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/*
|
/*
|
||||||
Put the shell back in the foreground.
|
Put the shell back in the foreground.
|
||||||
*/
|
*/
|
||||||
if( j->terminal && j->fg )
|
if( job_get_flag( j, JOB_TERMINAL ) && job_get_flag( j, JOB_FOREGROUND ) )
|
||||||
{
|
{
|
||||||
signal_block();
|
signal_block();
|
||||||
if( tcsetpgrp (0, getpid()) )
|
if( tcsetpgrp (0, getpid()) )
|
||||||
@ -1037,7 +1050,7 @@ void proc_sanity_check()
|
|||||||
{
|
{
|
||||||
process_t *p;
|
process_t *p;
|
||||||
|
|
||||||
if( !j->constructed )
|
if( !job_get_flag( j, JOB_CONSTRUCTED ) )
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
|
||||||
@ -1054,7 +1067,7 @@ void proc_sanity_check()
|
|||||||
/*
|
/*
|
||||||
More than one foreground job?
|
More than one foreground job?
|
||||||
*/
|
*/
|
||||||
if( j->fg && !(job_is_stopped(j) || job_is_completed(j) ) )
|
if( job_get_flag( j, JOB_FOREGROUND ) && !(job_is_stopped(j) || job_is_completed(j) ) )
|
||||||
{
|
{
|
||||||
if( fg_job != 0 )
|
if( fg_job != 0 )
|
||||||
{
|
{
|
||||||
|
96
proc.h
96
proc.h
@ -146,6 +146,64 @@ typedef struct process
|
|||||||
}
|
}
|
||||||
process_t;
|
process_t;
|
||||||
|
|
||||||
|
/**
|
||||||
|
Constant for the flag variable in the job struct
|
||||||
|
|
||||||
|
true if user was told about stopped job
|
||||||
|
*/
|
||||||
|
#define JOB_NOTIFIED 1
|
||||||
|
/**
|
||||||
|
Constant for the flag variable in the job struct
|
||||||
|
|
||||||
|
Whether this job is in the foreground
|
||||||
|
*/
|
||||||
|
#define JOB_FOREGROUND 2
|
||||||
|
/**
|
||||||
|
Constant for the flag variable in the job struct
|
||||||
|
|
||||||
|
Whether the specified job is completely constructed,
|
||||||
|
i.e. completely parsed, and every process in the job has been
|
||||||
|
forked, etc.
|
||||||
|
*/
|
||||||
|
#define JOB_CONSTRUCTED 4
|
||||||
|
/**
|
||||||
|
Constant for the flag variable in the job struct
|
||||||
|
|
||||||
|
Whether the specified job is a part of a subshell, event handler or some other form of special job that should not be reported
|
||||||
|
*/
|
||||||
|
#define JOB_SKIP_NOTIFICATION 8
|
||||||
|
/**
|
||||||
|
Constant for the flag variable in the job struct
|
||||||
|
|
||||||
|
Should the exit status be negated? This flag can only be set by the not builtin.
|
||||||
|
*/
|
||||||
|
#define JOB_NEGATE 16
|
||||||
|
/**
|
||||||
|
Constant for the flag variable in the job struct
|
||||||
|
|
||||||
|
This flag is set to one on wildcard expansion errors. It means that the current command should not be executed
|
||||||
|
*/
|
||||||
|
#define JOB_WILDCARD_ERROR 32
|
||||||
|
|
||||||
|
/**
|
||||||
|
Constant for the flag variable in the job struct
|
||||||
|
|
||||||
|
Skip executing this job. This flag is set by the short-circut builtins, i.e. and and or
|
||||||
|
*/
|
||||||
|
#define JOB_SKIP 64
|
||||||
|
|
||||||
|
/**
|
||||||
|
Constant for the flag variable in the job struct
|
||||||
|
|
||||||
|
Whether the job is under job control
|
||||||
|
*/
|
||||||
|
#define JOB_CONTROL 128
|
||||||
|
/**
|
||||||
|
Constant for the flag variable in the job struct
|
||||||
|
|
||||||
|
Whether the job wants to own the terminal when in the foreground
|
||||||
|
*/
|
||||||
|
#define JOB_TERMINAL 256
|
||||||
|
|
||||||
/** A pipeline of one or more processes. */
|
/** A pipeline of one or more processes. */
|
||||||
typedef struct job
|
typedef struct job
|
||||||
@ -156,45 +214,22 @@ typedef struct job
|
|||||||
process_t *first_process;
|
process_t *first_process;
|
||||||
/** process group ID */
|
/** process group ID */
|
||||||
pid_t pgid;
|
pid_t pgid;
|
||||||
/** true if user was told about stopped job */
|
|
||||||
int notified;
|
|
||||||
/** saved terminal modes */
|
/** saved terminal modes */
|
||||||
struct termios tmodes;
|
struct termios tmodes;
|
||||||
/** The job id of the job*/
|
/** The job id of the job*/
|
||||||
int job_id;
|
int job_id;
|
||||||
/** Whether this job is in the foreground */
|
|
||||||
int fg;
|
|
||||||
/**
|
|
||||||
Whether the specified job is completely constructed,
|
|
||||||
i.e. completely parsed, and every process in the job has been
|
|
||||||
forked, etc.
|
|
||||||
*/
|
|
||||||
int constructed;
|
|
||||||
/**
|
|
||||||
Whether the specified job is a part of a subshell, event handler or some other form of special job that should not be reported
|
|
||||||
*/
|
|
||||||
int skip_notification;
|
|
||||||
|
|
||||||
/** List of IO redrections for the job */
|
/** List of IO redrections for the job */
|
||||||
io_data_t *io;
|
io_data_t *io;
|
||||||
|
|
||||||
/** Should the exit status be negated? This flag can only be set by the not builtin. */
|
|
||||||
int negate;
|
|
||||||
|
|
||||||
/** This flag is set to one on wildcard expansion errors. It means that the current command should not be executed */
|
|
||||||
int wildcard_error;
|
|
||||||
|
|
||||||
/** Skip executing this job. This flag is set by the short-circut builtins, i.e. and and or */
|
|
||||||
int skip;
|
|
||||||
|
|
||||||
/** Whether the job is under job control */
|
|
||||||
int job_control;
|
|
||||||
|
|
||||||
/** Whether the job wants to own the terminal when in the foreground */
|
|
||||||
int terminal;
|
|
||||||
|
|
||||||
/** Pointer to the next job */
|
/** Pointer to the next job */
|
||||||
struct job *next;
|
struct job *next;
|
||||||
|
|
||||||
|
/**
|
||||||
|
Bitset containing information about the job. A combination of the JOB_* constants.
|
||||||
|
*/
|
||||||
|
int flags;
|
||||||
|
|
||||||
}
|
}
|
||||||
job_t;
|
job_t;
|
||||||
|
|
||||||
@ -260,6 +295,9 @@ extern int job_control_mode;
|
|||||||
*/
|
*/
|
||||||
extern int no_exec;
|
extern int no_exec;
|
||||||
|
|
||||||
|
void job_set_flag( job_t *j, int flag, int set );
|
||||||
|
|
||||||
|
int job_get_flag( job_t *j, int flag );
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Sets the status of the last process to exit
|
Sets the status of the last process to exit
|
||||||
|
Loading…
x
Reference in New Issue
Block a user