mirror of
https://github.com/fish-shell/fish-shell
synced 2024-12-27 05:13:10 +00:00
Recover instead of quiting when a redirection error occurs for a shellscript function
darcs-hash:20060111144020-ac50b-a5c7449276730c21949324abd8ba49b91b186e8c.gz
This commit is contained in:
parent
72bb5ae06f
commit
67333a23f1
1 changed files with 48 additions and 29 deletions
77
exec.c
77
exec.c
|
@ -439,11 +439,33 @@ static int has_fd( io_data_t *d, int fd )
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
Free a transmogrified io chain. Only the chain itself and resources
|
||||||
|
used by a transmogrified IO_FILE redirection are freed, since the
|
||||||
|
original chain may still be needed.
|
||||||
|
*/
|
||||||
|
static void io_untransmogrify( io_data_t * in, io_data_t *out )
|
||||||
|
{
|
||||||
|
if( !out )
|
||||||
|
return;
|
||||||
|
io_untransmogrify( in->next, out->next );
|
||||||
|
switch( in->io_mode )
|
||||||
|
{
|
||||||
|
case IO_FILE:
|
||||||
|
exec_close( out->param1.old_fd );
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
free(out);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Make a copy of the specified io redirection chain, but change file
|
Make a copy of the specified io redirection chain, but change file
|
||||||
redirection into fd redirection. This makes the redirection chain
|
redirection into fd redirection. This makes the redirection chain
|
||||||
suitable for use as block-level io, since the file won't be
|
suitable for use as block-level io, since the file won't be
|
||||||
repeatedly reopened for every command in the block.
|
repeatedly reopened for every command in the block.
|
||||||
|
|
||||||
|
\return the transmogrified chain on sucess, or 0 on failiure
|
||||||
*/
|
*/
|
||||||
static io_data_t *io_transmogrify( io_data_t * in )
|
static io_data_t *io_transmogrify( io_data_t * in )
|
||||||
{
|
{
|
||||||
|
@ -459,7 +481,8 @@ static io_data_t *io_transmogrify( io_data_t * in )
|
||||||
out->fd = in->fd;
|
out->fd = in->fd;
|
||||||
out->io_mode = IO_FD;
|
out->io_mode = IO_FD;
|
||||||
out->param2.close_old = 1;
|
out->param2.close_old = 1;
|
||||||
|
out->next=0;
|
||||||
|
|
||||||
switch( in->io_mode )
|
switch( in->io_mode )
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
|
@ -488,7 +511,8 @@ static io_data_t *io_transmogrify( io_data_t * in )
|
||||||
in->param1.filename );
|
in->param1.filename );
|
||||||
|
|
||||||
wperror( L"open" );
|
wperror( L"open" );
|
||||||
exit(1);
|
free( out );
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
out->param1.old_fd = fd;
|
out->param1.old_fd = fd;
|
||||||
|
@ -496,31 +520,19 @@ static io_data_t *io_transmogrify( io_data_t * in )
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
out->next = io_transmogrify( in->next );
|
if( in->next)
|
||||||
|
{
|
||||||
|
out->next = io_transmogrify( in->next );
|
||||||
|
if( !out->next )
|
||||||
|
{
|
||||||
|
io_untransmogrify( in, out );
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
Free a transmogrified io chain. Only the chain itself and resources
|
|
||||||
used by a transmogrified IO_FILE redirection are freed, since the
|
|
||||||
original chain may still be needed.
|
|
||||||
*/
|
|
||||||
static void io_untransmogrify( io_data_t * in, io_data_t *out )
|
|
||||||
{
|
|
||||||
if( !in )
|
|
||||||
return;
|
|
||||||
io_untransmogrify( in->next, out->next );
|
|
||||||
switch( in->io_mode )
|
|
||||||
{
|
|
||||||
case IO_FILE:
|
|
||||||
exec_close( out->param1.old_fd );
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
free(out);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Morph an io redirection chain into redirections suitable for
|
Morph an io redirection chain into redirections suitable for
|
||||||
passing to eval, call eval, and clean up morphed redirections.
|
passing to eval, call eval, and clean up morphed redirections.
|
||||||
|
@ -530,21 +542,29 @@ static void io_untransmogrify( io_data_t * in, io_data_t *out )
|
||||||
\param io the io redirections to be performed on this block
|
\param io the io redirections to be performed on this block
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static int internal_exec_helper( const wchar_t *def,
|
static void internal_exec_helper( const wchar_t *def,
|
||||||
int block_type,
|
int block_type,
|
||||||
io_data_t *io )
|
io_data_t *io )
|
||||||
{
|
{
|
||||||
int res=0;
|
|
||||||
io_data_t *io_internal = io_transmogrify( io );
|
io_data_t *io_internal = io_transmogrify( io );
|
||||||
int is_block_old=is_block;
|
int is_block_old=is_block;
|
||||||
is_block=1;
|
is_block=1;
|
||||||
|
|
||||||
signal_unblock();
|
/*
|
||||||
|
Did the transmogrification fail - if so, set error status and return
|
||||||
|
*/
|
||||||
|
if( io && !io_internal )
|
||||||
|
{
|
||||||
|
proc_set_last_status( 1 );
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
signal_unblock();
|
||||||
|
|
||||||
eval( def, io_internal, block_type );
|
eval( def, io_internal, block_type );
|
||||||
|
|
||||||
signal_block();
|
signal_block();
|
||||||
|
|
||||||
/*
|
/*
|
||||||
io_data_t *buff = io_get( io, 1 );
|
io_data_t *buff = io_get( io, 1 );
|
||||||
if( buff && buff->io_mode == IO_BUFFER )
|
if( buff && buff->io_mode == IO_BUFFER )
|
||||||
|
@ -555,7 +575,6 @@ static int internal_exec_helper( const wchar_t *def,
|
||||||
io_untransmogrify( io, io_internal );
|
io_untransmogrify( io, io_internal );
|
||||||
job_reap( 0 );
|
job_reap( 0 );
|
||||||
is_block=is_block_old;
|
is_block=is_block_old;
|
||||||
return res;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
Loading…
Reference in a new issue