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

77
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 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;
} }
/** /**