Add support for buffering of input to a command, the first step to piping data to fish_pager instead of using the argument list

darcs-hash:20060813013803-ac50b-f8000d4c96162023411f84643f47221860b350b2.gz
This commit is contained in:
axel 2006-08-13 11:38:03 +10:00
parent 72ad4e0d3b
commit 0a4819be27
5 changed files with 106 additions and 25 deletions

87
exec.c
View file

@ -676,11 +676,39 @@ void exec( job_t *j )
if( no_exec )
return;
sigemptyset( &chldset );
sigaddset( &chldset, SIGCHLD );
debug( 4, L"Exec job '%ls' with id %d", j->command, j->job_id );
if( block_io )
{
if( j->io )
j->io = io_add( io_duplicate( j, block_io), j->io );
else
j->io=io_duplicate( j, block_io);
}
io_data_t *input_redirect = io_get( j->io, 0 );
if( input_redirect &&
(input_redirect->io_mode == IO_BUFFER) &&
input_redirect->param3.is_input )
{
/*
Input redirection - create a new gobetween process to take
care of buffering
*/
process_t *fake = halloc( j, sizeof(process_t) );
fake->type = INTERNAL_BUFFER;
fake->pipe_fd = 1;
fake->next = j->first_process;
j->first_process = fake;
}
if( j->first_process->type==INTERNAL_EXEC )
{
/*
@ -718,15 +746,9 @@ void exec( job_t *j )
pipe_write.next=0;
pipe_write.param1.pipe_fd[0]=pipe_write.param1.pipe_fd[1]=-1;
//fwprintf( stderr, L"Run command %ls\n", j->command );
if( block_io )
{
if( j->io )
j->io = io_add( io_duplicate( j, block_io), j->io );
else
j->io=io_duplicate( j, block_io);
}
//fwprintf( stderr, L"Run command %ls\n", j->command );
j->io = io_add( j->io, &pipe_write );
@ -813,7 +835,7 @@ void exec( job_t *j )
if( p->next )
{
io_buffer = io_buffer_create();
io_buffer = io_buffer_create( 0 );
j->io = io_add( j->io, io_buffer );
}
@ -829,7 +851,7 @@ void exec( job_t *j )
{
if( p->next )
{
io_buffer = io_buffer_create();
io_buffer = io_buffer_create( 0 );
j->io = io_add( j->io, io_buffer );
}
@ -947,6 +969,7 @@ void exec( job_t *j )
switch( p->type )
{
case INTERNAL_BLOCK:
case INTERNAL_FUNCTION:
{
@ -1028,6 +1051,48 @@ void exec( job_t *j )
}
case INTERNAL_BUFFER:
{
debug( 0, L"fork internal buffer" );
pid = fork();
if( pid == 0 )
{
/*
This is the child process. Write out the contents of the pipeline.
*/
p->pid = getpid();
setup_child_process( j, p );
write( 1,
input_redirect->param2.out_buffer->buff,
input_redirect->param2.out_buffer->used );
exit( 0 );
}
else if( pid < 0 )
{
/* The fork failed. */
debug( 0, FORK_ERROR );
wperror (L"fork");
exit (1);
}
else
{
/*
This is the parent process. Store away
information on the child, and possibly give
it control over the terminal.
*/
p->pid = pid;
set_child_group( j, p, 0 );
}
break;
}
case INTERNAL_BUILTIN:
{
int skip_fork=0;
@ -1224,7 +1289,7 @@ int exec_subshell( const wchar_t *cmd,
}
is_subshell=1;
io_buffer= io_buffer_create();
io_buffer= io_buffer_create( 0 );
prev_status = proc_get_last_status();

View file

@ -36,7 +36,7 @@ Implementation file for the low level input library
/**
Characters that have been read and returned by the sequence matching code
*/
static wint_t lookahead_arr[32];
static wint_t lookahead_arr[1024];
/**
Number of entries in lookahead_arr

8
io.c
View file

@ -101,15 +101,16 @@ void io_buffer_read( io_data_t *d )
}
io_data_t *io_buffer_create()
io_data_t *io_buffer_create( int is_input )
{
io_data_t *buffer_redirect = malloc( sizeof( io_data_t ));
buffer_redirect->io_mode=IO_BUFFER;
buffer_redirect->next=0;
buffer_redirect->param2.out_buffer= malloc( sizeof(buffer_t));
buffer_redirect->param3.is_input = is_input;
b_init( buffer_redirect->param2.out_buffer );
buffer_redirect->fd=1;
buffer_redirect->fd=is_input?0:1;
if( exec_pipe( buffer_redirect->param1.pipe_fd ) == -1 )
{
@ -229,8 +230,7 @@ void io_print( io_data_t *io )
return;
}
debug( 1, L"IO fd %d, type ",
io->fd );
debug( 1, L"IO fd %d, type ", io->fd );
switch( io->io_mode )
{
case IO_PIPE:

20
io.h
View file

@ -45,6 +45,17 @@ typedef struct io_data
} param2
;
union
{
/**
This will be non-zero if this is a buffer of input, not
output
*/
int is_input;
}
param3;
/** Pointer to the next IO redirection */
struct io_data *next;
}
@ -80,9 +91,14 @@ void io_buffer_destroy( io_data_t *io_buffer );
/**
Create a IO_BUFFER type io redirection, complete with a pipe and a
buffer_t for output.
buffer_t for output. The default file descriptor used is 1 for
output buffering and 0 for input buffering.
\param is_input set this parameter to zero if the buffer should be
used to buffer the output of a command, or non-zero to buffer the
input to a command.
*/
io_data_t *io_buffer_create();
io_data_t *io_buffer_create( int is_input );
/**
Close output pipe, and read from input pipe until eof.