API documentation updates

darcs-hash:20051009114816-ac50b-4a11de60d61dcba7cbb63ae4b71cfd1eb06e1d7a.gz
This commit is contained in:
axel 2005-10-09 21:48:16 +10:00
parent 9ae7fa5831
commit 8093435b7e
4 changed files with 83 additions and 71 deletions

78
exec.c
View file

@ -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 ) static void setup_child_process( job_t *j )
{ {
if( is_interactive && !is_subshell && !is_block) if( is_interactive && !is_subshell && !is_block)
{ {
pid_t pid; pid_t pid;
/* /*
Put the process into the process group and give the process group Put the process into the process group and give the process
the terminal, if appropriate. group the terminal, if appropriate. This has to be done
This has to be done both by the shell and in the individual both by the shell and in the individual child processes
child processes because of potential race conditions. because of potential race conditions.
*/ */
pid = getpid (); pid = getpid ();
if (j->pgid == 0) if (j->pgid == 0)
@ -402,20 +407,16 @@ static void setup_child_process( job_t *j )
handle_child_io( j->io ); handle_child_io( j->io );
} }
/** /**
This function is executed by the child process created by a call to 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 fork(). It should be called after \c setup_child_process. It calls
parameter. If the command requested for this process is not a execve to replace the fish process image with the command specified
builtin, execv is then called with the appropriate parameters. If in \c p. It never returns.
the command is a builtin, the contents of out and err are printed.
*/ */
static void launch_process( process_t *p ) 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 ) ); execve (wcs2str(p->actual_cmd), wcsv2strv( (const wchar_t **) p->argv), env_export_arr( 0 ) );
debug( 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 ) 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 ) 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 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.
\param def the code to evaluate \param def the code to evaluate
\param block_type the type of block to push on evaluation \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; return res;
} }
/* /**
static void io_print( io_data_t *io ) This function should be called by the parent process right after
{ fork() has been called. If job control is enabled, the child is put
if( !io ) in the jobs group.
{
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 );
}
*/ */
static int handle_new_child( job_t *j, process_t *p ) static int handle_new_child( job_t *j, process_t *p )
{ {
@ -1198,7 +1173,9 @@ int exec_subshell( const wchar_t *cmd,
if( !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; return 0;
} }
@ -1209,7 +1186,6 @@ int exec_subshell( const wchar_t *cmd,
eval( cmd, io_buffer, SUBST ); eval( cmd, io_buffer, SUBST );
debug( 4, L"exec_read_io_buffer on cmdsub '%ls'", cmd );
io_buffer_read( io_buffer ); io_buffer_read( io_buffer );
status = proc_get_last_status(); status = proc_get_last_status();

34
io.c
View file

@ -207,3 +207,37 @@ io_data_t *io_get( io_data_t *io, int fd )
return 0; 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 );
}
*/

View file

@ -51,6 +51,8 @@ The fish parser. Contains functions for parsing code.
*/ */
#define MAX_RECURSION_DEPTH 128 #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 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 ) if( !cmd )
{ {
debug( 1, debug( 1,
L"Tried to evaluate null pointer\n" L"Tried to evaluate null pointer\n" BUGREPORT_MSG,
L"If this error can be reproduced, please file a bug report." ); PACKAGE_BUGREPORT );
return 1; return 1;
} }
@ -1851,29 +1855,28 @@ int eval( const wchar_t *cmd, io_data_t *io, int block_type )
(block_type != SUBST)) (block_type != SUBST))
{ {
debug( 1, debug( 1,
L"Tried to evaluate buffer using invalid block scope of type '%ls'\n" L"Tried to evaluate buffer using invalid block scope of type '%ls'\n" BUGREPORT_MSG,
L"If this error can be reproduced, please file a bug report.", parser_get_block_desc( block_type ),
parser_get_block_desc( block_type ) ); PACKAGE_BUGREPORT );
return 1; return 1;
} }
eval_level++; eval_level++;
current_tokenizer = malloc( sizeof(tokenizer)); current_tokenizer = malloc( sizeof(tokenizer));
parser_push_block( block_type ); parser_push_block( block_type );
forbid_count = al_get_count( &forbidden_function ); forbid_count = al_get_count( &forbidden_function );
tok_init( current_tokenizer, cmd, 0 ); tok_init( current_tokenizer, cmd, 0 );
error_code = 0; error_code = 0;
while( tok_has_next( current_tokenizer ) && while( tok_has_next( current_tokenizer ) &&
!error_code && !error_code &&
!sanity_check() && !sanity_check() &&
!exit_status() ) !exit_status() )
eval_job( current_tokenizer ); eval_job( current_tokenizer );
int prev_block_type = current_block->type; int prev_block_type = current_block->type;
parser_pop_block(); parser_pop_block();
@ -1883,8 +1886,9 @@ int eval( const wchar_t *cmd, io_data_t *io, int block_type )
{ {
debug( 0, debug( 0,
L"End of block mismatch\n" L"End of block mismatch\n"
L"Program terminating. If this error can be reproduced,\n" L"Program terminating. "
L"please file a bug report." ); BUGREPORT_MSG,
PACKAGE_BUGREPORT );
exit(1); exit(1);
break; break;
} }

View file

@ -2148,14 +2148,12 @@ void reader_run_command( wchar_t *cmd )
free(ft); free(ft);
reader_write_title(); reader_write_title();
term_donate(); term_donate();
if( eval( cmd, 0, TOP ) == 0 ) eval( cmd, 0, TOP );
{ job_do_notification();
job_do_notification();
}
term_steal(); term_steal();
env_set( L"_", L"fish", ENV_GLOBAL ); env_set( L"_", L"fish", ENV_GLOBAL );