mirror of
https://github.com/fish-shell/fish-shell
synced 2025-01-13 21:44:16 +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 );
|
||||
blocked = new_blocked;
|
||||
}
|
||||
|
||||
|
||||
while( sig_list[active_list].count > 0 )
|
||||
{
|
||||
signal_list_t *lst;
|
||||
|
|
97
exec.c
97
exec.c
|
@ -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 )
|
||||
{
|
||||
/*
|
||||
|
@ -705,7 +733,7 @@ void exec( job_t *j )
|
|||
j->first_process->completed=1;
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
pipe_read.fd=0;
|
||||
|
@ -718,20 +746,14 @@ 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 );
|
||||
|
||||
signal_block();
|
||||
|
||||
|
||||
/*
|
||||
This loop loops over every process_t in the job, starting it as
|
||||
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.
|
||||
*/
|
||||
|
||||
|
||||
for( p=j->first_process; p; p = p->next )
|
||||
{
|
||||
mypipe[1]=-1;
|
||||
skip_fork=0;
|
||||
|
||||
|
||||
pipe_write.fd = p->pipe_fd;
|
||||
|
||||
/*
|
||||
|
@ -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 );
|
||||
}
|
||||
|
||||
|
@ -837,7 +859,7 @@ void exec( job_t *j )
|
|||
break;
|
||||
|
||||
}
|
||||
|
||||
|
||||
case INTERNAL_BUILTIN:
|
||||
{
|
||||
int builtin_stdin=0;
|
||||
|
@ -947,6 +969,7 @@ void exec( job_t *j )
|
|||
|
||||
switch( p->type )
|
||||
{
|
||||
|
||||
case INTERNAL_BLOCK:
|
||||
case INTERNAL_FUNCTION:
|
||||
{
|
||||
|
@ -1027,6 +1050,48 @@ void exec( job_t *j )
|
|||
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:
|
||||
{
|
||||
|
@ -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();
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
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 ));
|
||||
|
||||
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 )
|
||||
{
|
||||
debug( 1, PIPE_ERROR );
|
||||
|
@ -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
20
io.h
|
@ -44,6 +44,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.
|
||||
|
|
Loading…
Reference in a new issue