diff --git a/exec.c b/exec.c index d4025ebb7..90b07393c 100644 --- a/exec.c +++ b/exec.c @@ -364,17 +364,22 @@ static void handle_child_io( io_data_t *io ) } } - +/** + Initialize a new child process. This should be called right away + after forking in the child process. If job control is suitable, the + process is put in the jobs group, all signal handlers are reset, + SIGCHLD is unblocked, and all IO redirections are performed. +*/ static void setup_child_process( job_t *j ) { if( is_interactive && !is_subshell && !is_block) { pid_t pid; /* - Put the process into the process group and give the process group - the terminal, if appropriate. - This has to be done both by the shell and in the individual - child processes because of potential race conditions. + Put the process into the process group and give the process + group the terminal, if appropriate. This has to be done + both by the shell and in the individual child processes + because of potential race conditions. */ pid = getpid (); if (j->pgid == 0) @@ -402,20 +407,16 @@ static void setup_child_process( job_t *j ) handle_child_io( j->io ); } - /** This function is executed by the child process created by a call to - fork(). This function begins by updating FDs as specified by the io - parameter. If the command requested for this process is not a - builtin, execv is then called with the appropriate parameters. If - the command is a builtin, the contents of out and err are printed. + fork(). It should be called after \c setup_child_process. It calls + execve to replace the fish process image with the command specified + in \c p. It never returns. */ static void launch_process( process_t *p ) { - - /* Set the standard input/output channels of the new process. */ execve (wcs2str(p->actual_cmd), wcsv2strv( (const wchar_t **) p->argv), env_export_arr( 0 ) ); debug( 0, @@ -438,7 +439,10 @@ static int has_fd( io_data_t *d, int fd ) /** - Make a copy of the specified io redirection chain, but change file redirection into fd redirection. + 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. */ static io_data_t *io_transmogrify( io_data_t * in ) @@ -498,7 +502,9 @@ static io_data_t *io_transmogrify( io_data_t * in ) } /** - Free a transmogrified io chain. + 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 ) { @@ -518,7 +524,6 @@ static void io_untransmogrify( io_data_t * in, io_data_t *out ) /** Morph an io redirection chain into redirections suitable for passing to eval, call eval, and clean up morphed redirections. - \param def the code to evaluate \param block_type the type of block to push on evaluation @@ -549,41 +554,11 @@ static int internal_exec_helper( const wchar_t *def, return res; } -/* -static void io_print( io_data_t *io ) -{ - if( !io ) - { - fwprintf( stderr, L"\n" ); - return; - } - - - fwprintf( stderr, L"IO fd %d, type ", - io->fd ); - switch( io->io_mode ) - { - case IO_PIPE: - fwprintf(stderr, L"PIPE, data %d\n", io->pipe_fd[io->fd?1:0] ); - break; - - case IO_FD: - fwprintf(stderr, L"FD, copy %d\n", io->old_fd ); - break; - - case IO_BUFFER: - fwprintf( stderr, L"BUFFER\n" ); - break; - - default: - fwprintf( stderr, L"OTHER\n" ); - } - - io_print( io->next ); - -} +/** + This function should be called by the parent process right after + fork() has been called. If job control is enabled, the child is put + in the jobs group. */ - static int handle_new_child( job_t *j, process_t *p ) { @@ -1198,7 +1173,9 @@ int exec_subshell( const wchar_t *cmd, if( !cmd ) { - debug( 1, L"Sent null command to subshell" ); + debug( 1, + L"Sent null command to subshell. This is a fish bug. If it can be reproduced, please send a bug report to %ls", + PACKAGE_BUGREPORT ); return 0; } @@ -1209,7 +1186,6 @@ int exec_subshell( const wchar_t *cmd, eval( cmd, io_buffer, SUBST ); - debug( 4, L"exec_read_io_buffer on cmdsub '%ls'", cmd ); io_buffer_read( io_buffer ); status = proc_get_last_status(); diff --git a/io.c b/io.c index 863979552..0c868d0e7 100644 --- a/io.c +++ b/io.c @@ -207,3 +207,37 @@ io_data_t *io_get( io_data_t *io, int fd ) return 0; } +/* +static void io_print( io_data_t *io ) +{ + if( !io ) + { + fwprintf( stderr, L"\n" ); + return; + } + + + fwprintf( stderr, L"IO fd %d, type ", + io->fd ); + switch( io->io_mode ) + { + case IO_PIPE: + fwprintf(stderr, L"PIPE, data %d\n", io->pipe_fd[io->fd?1:0] ); + break; + + case IO_FD: + fwprintf(stderr, L"FD, copy %d\n", io->old_fd ); + break; + + case IO_BUFFER: + fwprintf( stderr, L"BUFFER\n" ); + break; + + default: + fwprintf( stderr, L"OTHER\n" ); + } + + io_print( io->next ); + +} +*/ diff --git a/parser.c b/parser.c index e4e3f3b8b..9f6771d05 100644 --- a/parser.c +++ b/parser.c @@ -51,6 +51,8 @@ The fish parser. Contains functions for parsing code. */ #define MAX_RECURSION_DEPTH 128 +#define BUGREPORT_MSG L"If this error can be reproduced, please send a bug report to %s." + /** Error message for improper use of the exec builtin */ @@ -1841,8 +1843,10 @@ int eval( const wchar_t *cmd, io_data_t *io, int block_type ) if( !cmd ) { debug( 1, - L"Tried to evaluate null pointer\n" - L"If this error can be reproduced, please file a bug report." ); + L"Tried to evaluate null pointer\n" BUGREPORT_MSG, + PACKAGE_BUGREPORT ); + + return 1; } @@ -1851,29 +1855,28 @@ int eval( const wchar_t *cmd, io_data_t *io, int block_type ) (block_type != SUBST)) { debug( 1, - L"Tried to evaluate buffer using invalid block scope of type '%ls'\n" - L"If this error can be reproduced, please file a bug report.", - parser_get_block_desc( block_type ) ); + L"Tried to evaluate buffer using invalid block scope of type '%ls'\n" BUGREPORT_MSG, + parser_get_block_desc( block_type ), + PACKAGE_BUGREPORT ); return 1; } - - + eval_level++; current_tokenizer = malloc( sizeof(tokenizer)); - + parser_push_block( block_type ); - + forbid_count = al_get_count( &forbidden_function ); - + tok_init( current_tokenizer, cmd, 0 ); error_code = 0; - + while( tok_has_next( current_tokenizer ) && !error_code && !sanity_check() && !exit_status() ) eval_job( current_tokenizer ); - + int prev_block_type = current_block->type; parser_pop_block(); @@ -1883,8 +1886,9 @@ int eval( const wchar_t *cmd, io_data_t *io, int block_type ) { debug( 0, L"End of block mismatch\n" - L"Program terminating. If this error can be reproduced,\n" - L"please file a bug report." ); + L"Program terminating. " + BUGREPORT_MSG, + PACKAGE_BUGREPORT ); exit(1); break; } diff --git a/reader.c b/reader.c index f1ae2e237..3877ae5ac 100644 --- a/reader.c +++ b/reader.c @@ -2148,14 +2148,12 @@ void reader_run_command( wchar_t *cmd ) free(ft); reader_write_title(); - + term_donate(); - if( eval( cmd, 0, TOP ) == 0 ) - { - job_do_notification(); - } - + eval( cmd, 0, TOP ); + job_do_notification(); + term_steal(); env_set( L"_", L"fish", ENV_GLOBAL );