mirror of
https://github.com/fish-shell/fish-shell
synced 2025-01-14 14:03:58 +00:00
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:
parent
72ad4e0d3b
commit
0a4819be27
5 changed files with 106 additions and 25 deletions
2
event.c
2
event.c
|
@ -540,7 +540,7 @@ static void event_fire_delayed()
|
||||||
free( blocked );
|
free( blocked );
|
||||||
blocked = new_blocked;
|
blocked = new_blocked;
|
||||||
}
|
}
|
||||||
|
|
||||||
while( sig_list[active_list].count > 0 )
|
while( sig_list[active_list].count > 0 )
|
||||||
{
|
{
|
||||||
signal_list_t *lst;
|
signal_list_t *lst;
|
||||||
|
|
97
exec.c
97
exec.c
|
@ -676,11 +676,39 @@ void exec( job_t *j )
|
||||||
if( no_exec )
|
if( no_exec )
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
sigemptyset( &chldset );
|
sigemptyset( &chldset );
|
||||||
sigaddset( &chldset, SIGCHLD );
|
sigaddset( &chldset, SIGCHLD );
|
||||||
|
|
||||||
debug( 4, L"Exec job '%ls' with id %d", j->command, j->job_id );
|
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 )
|
if( j->first_process->type==INTERNAL_EXEC )
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
|
@ -705,7 +733,7 @@ void exec( job_t *j )
|
||||||
j->first_process->completed=1;
|
j->first_process->completed=1;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pipe_read.fd=0;
|
pipe_read.fd=0;
|
||||||
|
@ -718,20 +746,14 @@ void exec( job_t *j )
|
||||||
pipe_write.next=0;
|
pipe_write.next=0;
|
||||||
pipe_write.param1.pipe_fd[0]=pipe_write.param1.pipe_fd[1]=-1;
|
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 )
|
//fwprintf( stderr, L"Run command %ls\n", j->command );
|
||||||
{
|
|
||||||
if( j->io )
|
|
||||||
j->io = io_add( io_duplicate( j, block_io), j->io );
|
|
||||||
else
|
|
||||||
j->io=io_duplicate( j, block_io);
|
|
||||||
}
|
|
||||||
|
|
||||||
j->io = io_add( j->io, &pipe_write );
|
j->io = io_add( j->io, &pipe_write );
|
||||||
|
|
||||||
signal_block();
|
signal_block();
|
||||||
|
|
||||||
/*
|
/*
|
||||||
This loop loops over every process_t in the job, starting it as
|
This loop loops over every process_t in the job, starting it as
|
||||||
appropriate. This turns out to be rather complex, since a
|
appropriate. This turns out to be rather complex, since a
|
||||||
|
@ -739,12 +761,12 @@ void exec( job_t *j )
|
||||||
|
|
||||||
The loop also has to handle pipelining between the jobs.
|
The loop also has to handle pipelining between the jobs.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
for( p=j->first_process; p; p = p->next )
|
for( p=j->first_process; p; p = p->next )
|
||||||
{
|
{
|
||||||
mypipe[1]=-1;
|
mypipe[1]=-1;
|
||||||
skip_fork=0;
|
skip_fork=0;
|
||||||
|
|
||||||
pipe_write.fd = p->pipe_fd;
|
pipe_write.fd = p->pipe_fd;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -813,7 +835,7 @@ void exec( job_t *j )
|
||||||
|
|
||||||
if( p->next )
|
if( p->next )
|
||||||
{
|
{
|
||||||
io_buffer = io_buffer_create();
|
io_buffer = io_buffer_create( 0 );
|
||||||
j->io = io_add( j->io, io_buffer );
|
j->io = io_add( j->io, io_buffer );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -829,7 +851,7 @@ void exec( job_t *j )
|
||||||
{
|
{
|
||||||
if( p->next )
|
if( p->next )
|
||||||
{
|
{
|
||||||
io_buffer = io_buffer_create();
|
io_buffer = io_buffer_create( 0 );
|
||||||
j->io = io_add( j->io, io_buffer );
|
j->io = io_add( j->io, io_buffer );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -837,7 +859,7 @@ void exec( job_t *j )
|
||||||
break;
|
break;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
case INTERNAL_BUILTIN:
|
case INTERNAL_BUILTIN:
|
||||||
{
|
{
|
||||||
int builtin_stdin=0;
|
int builtin_stdin=0;
|
||||||
|
@ -947,6 +969,7 @@ void exec( job_t *j )
|
||||||
|
|
||||||
switch( p->type )
|
switch( p->type )
|
||||||
{
|
{
|
||||||
|
|
||||||
case INTERNAL_BLOCK:
|
case INTERNAL_BLOCK:
|
||||||
case INTERNAL_FUNCTION:
|
case INTERNAL_FUNCTION:
|
||||||
{
|
{
|
||||||
|
@ -1027,6 +1050,48 @@ void exec( job_t *j )
|
||||||
break;
|
break;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
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:
|
case INTERNAL_BUILTIN:
|
||||||
{
|
{
|
||||||
|
@ -1224,7 +1289,7 @@ int exec_subshell( const wchar_t *cmd,
|
||||||
}
|
}
|
||||||
|
|
||||||
is_subshell=1;
|
is_subshell=1;
|
||||||
io_buffer= io_buffer_create();
|
io_buffer= io_buffer_create( 0 );
|
||||||
|
|
||||||
prev_status = proc_get_last_status();
|
prev_status = proc_get_last_status();
|
||||||
|
|
||||||
|
|
|
@ -36,7 +36,7 @@ Implementation file for the low level input library
|
||||||
/**
|
/**
|
||||||
Characters that have been read and returned by the sequence matching code
|
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
|
Number of entries in lookahead_arr
|
||||||
|
|
10
io.c
10
io.c
|
@ -101,16 +101,17 @@ 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 ));
|
io_data_t *buffer_redirect = malloc( sizeof( io_data_t ));
|
||||||
|
|
||||||
buffer_redirect->io_mode=IO_BUFFER;
|
buffer_redirect->io_mode=IO_BUFFER;
|
||||||
buffer_redirect->next=0;
|
buffer_redirect->next=0;
|
||||||
buffer_redirect->param2.out_buffer= malloc( sizeof(buffer_t));
|
buffer_redirect->param2.out_buffer= malloc( sizeof(buffer_t));
|
||||||
|
buffer_redirect->param3.is_input = is_input;
|
||||||
b_init( buffer_redirect->param2.out_buffer );
|
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 )
|
if( exec_pipe( buffer_redirect->param1.pipe_fd ) == -1 )
|
||||||
{
|
{
|
||||||
debug( 1, PIPE_ERROR );
|
debug( 1, PIPE_ERROR );
|
||||||
|
@ -229,8 +230,7 @@ void io_print( io_data_t *io )
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
debug( 1, L"IO fd %d, type ",
|
debug( 1, L"IO fd %d, type ", io->fd );
|
||||||
io->fd );
|
|
||||||
switch( io->io_mode )
|
switch( io->io_mode )
|
||||||
{
|
{
|
||||||
case IO_PIPE:
|
case IO_PIPE:
|
||||||
|
|
20
io.h
20
io.h
|
@ -44,6 +44,17 @@ typedef struct io_data
|
||||||
|
|
||||||
} param2
|
} 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 */
|
/** Pointer to the next IO redirection */
|
||||||
struct io_data *next;
|
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
|
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.
|
Close output pipe, and read from input pipe until eof.
|
||||||
|
|
Loading…
Reference in a new issue