diff options
author | 2006-01-12 00:40:20 +1000 | |
---|---|---|
committer | 2006-01-12 00:40:20 +1000 | |
commit | 67333a23f1f84bc1de5d7d90185c621264f259b7 (patch) | |
tree | dab595e11049f7c5fefdd3972ff7a357fc8e10fa /exec.c | |
parent | 72bb5ae06f05fc9a8c237a318a34343ade25c1b9 (diff) |
Recover instead of quiting when a redirection error occurs for a shellscript function
darcs-hash:20060111144020-ac50b-a5c7449276730c21949324abd8ba49b91b186e8c.gz
Diffstat (limited to 'exec.c')
-rw-r--r-- | exec.c | 77 |
1 files changed, 48 insertions, 29 deletions
@@ -440,10 +440,32 @@ 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,7 +481,8 @@ 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,32 +520,20 @@ 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; } /** - 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,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 */ -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; - 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 ); - + signal_block(); - + /* io_data_t *buff = io_get( io, 1 ); 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 ); job_reap( 0 ); is_block=is_block_old; - return res; } /** |