Recover instead of quiting when a redirection error occurs for a shellscript function

darcs-hash:20060111144020-ac50b-a5c7449276730c21949324abd8ba49b91b186e8c.gz
This commit is contained in:
axel 2006-01-12 00:40:20 +10:00
parent 72bb5ae06f
commit 67333a23f1

67
exec.c
View file

@ -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
redirection into fd redirection. This makes the redirection chain
suitable for use as block-level io, since the file won't be
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 )
{
@ -459,6 +481,7 @@ static io_data_t *io_transmogrify( io_data_t * in )
out->fd = in->fd;
out->io_mode = IO_FD;
out->param2.close_old = 1;
out->next=0;
switch( in->io_mode )
{
@ -488,7 +511,8 @@ static io_data_t *io_transmogrify( io_data_t * in )
in->param1.filename );
wperror( L"open" );
exit(1);
free( out );
return 0;
}
out->param1.old_fd = fd;
@ -496,31 +520,19 @@ static io_data_t *io_transmogrify( io_data_t * in )
}
}
if( in->next)
{
out->next = io_transmogrify( in->next );
if( !out->next )
{
io_untransmogrify( in, out );
return 0;
}
}
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
passing to eval, call eval, and clean up morphed redirections.
@ -530,15 +542,23 @@ static void io_untransmogrify( io_data_t * in, io_data_t *out )
\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,
io_data_t *io )
{
int res=0;
io_data_t *io_internal = io_transmogrify( io );
int is_block_old=is_block;
is_block=1;
/*
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 );
@ -555,7 +575,6 @@ static int internal_exec_helper( const wchar_t *def,
io_untransmogrify( io, io_internal );
job_reap( 0 );
is_block=is_block_old;
return res;
}
/**