mirror of
https://github.com/fish-shell/fish-shell
synced 2024-12-26 12:53:13 +00:00
Move io redirection functions to their own library
darcs-hash:20051008112051-ac50b-113caa4cba470a739e4bfbed9f479e2fed357be7.gz
This commit is contained in:
parent
93eed7bc35
commit
9ae7fa5831
9 changed files with 347 additions and 299 deletions
|
@ -52,7 +52,7 @@ COMMON_OBJS := function.o builtin.o common.o complete.o env.o exec.o \
|
|||
expand.o highlight.o history.o kill.o parser.o proc.o reader.o \
|
||||
sanity.o tokenizer.o util.o wildcard.o wgetopt.o wutil.o input.o \
|
||||
output.o intern.o env_universal.o env_universal_common.o \
|
||||
input_common.o event.o signal.o
|
||||
input_common.o event.o signal.o io.o
|
||||
|
||||
# builtin_help.h exists, but builtin_help.c is autogenerated
|
||||
COMMON_OBJS_WITH_HEADER := builtin_help.o
|
||||
|
|
|
@ -58,6 +58,7 @@
|
|||
#include "input.h"
|
||||
#include "intern.h"
|
||||
#include "event.h"
|
||||
#include "signal.h"
|
||||
|
||||
/**
|
||||
The default prompt for the read command
|
||||
|
@ -2500,8 +2501,6 @@ static int builtin_end( wchar_t **argv )
|
|||
|
||||
case FUNCTION_DEF:
|
||||
{
|
||||
int i;
|
||||
|
||||
/**
|
||||
Copy the text from the beginning of the function
|
||||
until the end command and use as the new definition
|
||||
|
|
172
exec.c
172
exec.c
|
@ -34,6 +34,7 @@
|
|||
#include "wildcard.h"
|
||||
#include "sanity.h"
|
||||
#include "expand.h"
|
||||
#include "signal.h"
|
||||
#include "env_universal.h"
|
||||
|
||||
/**
|
||||
|
@ -52,10 +53,6 @@ pid_t getpgid( pid_t pid );
|
|||
file redirection error message
|
||||
*/
|
||||
#define FILE_ERROR L"An error occurred while redirecting file '%ls'"
|
||||
/**
|
||||
pipe redirection error message
|
||||
*/
|
||||
#define PIPE_ERROR L"An error occurred while setting up pipe"
|
||||
/**
|
||||
fork error message
|
||||
*/
|
||||
|
@ -68,11 +65,7 @@ pid_t getpgid( pid_t pid );
|
|||
*/
|
||||
array_list_t *open_fds=0;
|
||||
|
||||
/**
|
||||
Loops over close until thesyscall was run without beeing
|
||||
interrupted. Thenremoves the fd from the open_fds list.
|
||||
*/
|
||||
static void close_loop( int fd )
|
||||
void exec_close( int fd )
|
||||
{
|
||||
int i;
|
||||
|
||||
|
@ -105,13 +98,19 @@ static void close_loop( int fd )
|
|||
|
||||
}
|
||||
|
||||
/**
|
||||
Call pipe(), and add resulting fds to open_fds, the list of opend
|
||||
file descriptors for pipes.
|
||||
*/
|
||||
static int internal_pipe( int fd[2])
|
||||
int exec_pipe( int fd[2])
|
||||
{
|
||||
int res = pipe( fd );
|
||||
int res;
|
||||
|
||||
while( ( res=pipe( fd ) ) )
|
||||
{
|
||||
if( errno != EINTR )
|
||||
{
|
||||
wperror(L"pipe");
|
||||
return res;
|
||||
}
|
||||
}
|
||||
|
||||
if( open_fds == 0 )
|
||||
{
|
||||
open_fds = malloc( sizeof( array_list_t ) );
|
||||
|
@ -172,7 +171,7 @@ static void close_unused_internal_pipes( io_data_t *io )
|
|||
if( !use_fd_in_pipe( n, io) )
|
||||
{
|
||||
debug( 4, L"Close fd %d, used in other context", n );
|
||||
close_loop( n );
|
||||
exec_close( n );
|
||||
i--;
|
||||
}
|
||||
}
|
||||
|
@ -237,7 +236,7 @@ static void handle_child_io( io_data_t *io )
|
|||
close_unused_internal_pipes( io );
|
||||
|
||||
if( env_universal_server.fd >= 0 )
|
||||
close_loop( env_universal_server.fd );
|
||||
exec_close( env_universal_server.fd );
|
||||
|
||||
for( ; io; io=io->next )
|
||||
{
|
||||
|
@ -296,7 +295,7 @@ static void handle_child_io( io_data_t *io )
|
|||
wperror( L"dup2" );
|
||||
exit(1);
|
||||
}
|
||||
close_loop( tmp );
|
||||
exec_close( tmp );
|
||||
}
|
||||
break;
|
||||
case IO_FD:
|
||||
|
@ -337,11 +336,11 @@ static void handle_child_io( io_data_t *io )
|
|||
|
||||
if( fd_to_dup != 0 )
|
||||
{
|
||||
close_loop( io->pipe_fd[0]);
|
||||
close_loop( io->pipe_fd[1]);
|
||||
exec_close( io->pipe_fd[0]);
|
||||
exec_close( io->pipe_fd[1]);
|
||||
}
|
||||
else
|
||||
close_loop( io->pipe_fd[0] );
|
||||
exec_close( io->pipe_fd[0] );
|
||||
|
||||
/*
|
||||
if( close( io[i].pipe_fd[ io->fd ] ) == -1 )
|
||||
|
@ -438,109 +437,6 @@ static int has_fd( io_data_t *d, int fd )
|
|||
}
|
||||
|
||||
|
||||
/**
|
||||
Read from descriptors until they are empty.
|
||||
*/
|
||||
void exec_read_io_buffer( io_data_t *d )
|
||||
{
|
||||
|
||||
close_loop(d->pipe_fd[1] );
|
||||
|
||||
if( d->io_mode == IO_BUFFER )
|
||||
{
|
||||
if( fcntl( d->pipe_fd[0], F_SETFL, 0 ) )
|
||||
{
|
||||
wperror( L"fcntl" );
|
||||
return;
|
||||
}
|
||||
debug( 4, L"exec_read_io_buffer: blocking read on fd %d", d->pipe_fd[0] );
|
||||
|
||||
while(1)
|
||||
{
|
||||
char b[4096];
|
||||
int l;
|
||||
l=read_blocked( d->pipe_fd[0], b, 4096 );
|
||||
if( l==0 )
|
||||
{
|
||||
break;
|
||||
}
|
||||
else if( l<0 )
|
||||
{
|
||||
/*
|
||||
exec_read_io_buffer is only called on jobs that have
|
||||
exited, and will therefore never block. But a broken
|
||||
pipe seems to cause some flags to reset, causing the
|
||||
EOF flag to not be set. Therefore, EAGAIN is ignored
|
||||
and we exit anyway.
|
||||
*/
|
||||
if( errno != EAGAIN )
|
||||
{
|
||||
debug( 1,
|
||||
L"An error occured while reading output from code block on fd %d",
|
||||
d->pipe_fd[0] );
|
||||
wperror( L"exec_read_io_buffer" );
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
b_append( d->out_buffer, b, l );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
io_data_t *exec_make_io_buffer()
|
||||
{
|
||||
io_data_t *buffer_redirect = malloc( sizeof( io_data_t ));
|
||||
|
||||
buffer_redirect->io_mode=IO_BUFFER;
|
||||
buffer_redirect->next=0;
|
||||
buffer_redirect->out_buffer= malloc( sizeof(buffer_t));
|
||||
b_init( buffer_redirect->out_buffer );
|
||||
buffer_redirect->fd=1;
|
||||
|
||||
|
||||
if( internal_pipe( buffer_redirect->pipe_fd ) == -1 )
|
||||
{
|
||||
debug( 1, PIPE_ERROR );
|
||||
wperror (L"pipe");
|
||||
free( buffer_redirect->out_buffer );
|
||||
free( buffer_redirect );
|
||||
return 0;
|
||||
}
|
||||
else if( fcntl( buffer_redirect->pipe_fd[0],
|
||||
F_SETFL,
|
||||
O_NONBLOCK ) )
|
||||
{
|
||||
debug( 1, PIPE_ERROR );
|
||||
wperror( L"fcntl" );
|
||||
free( buffer_redirect->out_buffer );
|
||||
free( buffer_redirect );
|
||||
return 0;
|
||||
}
|
||||
return buffer_redirect;
|
||||
}
|
||||
|
||||
void exec_free_io_buffer( io_data_t *io_buffer )
|
||||
{
|
||||
|
||||
close_loop( io_buffer->pipe_fd[0] );
|
||||
|
||||
/*
|
||||
Dont free fd for writing. This should already be free'd before
|
||||
calling exec_read_io_buffer on the buffer
|
||||
*/
|
||||
|
||||
b_destroy( io_buffer->out_buffer );
|
||||
|
||||
free( io_buffer->out_buffer );
|
||||
free( io_buffer );
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
Make a copy of the specified io redirection chain, but change file redirection into fd redirection.
|
||||
*/
|
||||
|
@ -612,7 +508,7 @@ static void io_untransmogrify( io_data_t * in, io_data_t *out )
|
|||
switch( in->io_mode )
|
||||
{
|
||||
case IO_FILE:
|
||||
close_loop( out->old_fd );
|
||||
exec_close( out->old_fd );
|
||||
break;
|
||||
}
|
||||
free(out);
|
||||
|
@ -846,7 +742,7 @@ void exec( job_t *j )
|
|||
|
||||
if (p->next)
|
||||
{
|
||||
if (internal_pipe( mypipe ) == -1)
|
||||
if (exec_pipe( mypipe ) == -1)
|
||||
{
|
||||
debug( 1, PIPE_ERROR );
|
||||
wperror (L"pipe");
|
||||
|
@ -911,7 +807,7 @@ void exec( job_t *j )
|
|||
if( p->next )
|
||||
{
|
||||
// fwprintf( stderr, L"Function %ls\n", def );
|
||||
io_buffer = exec_make_io_buffer();
|
||||
io_buffer = io_buffer_create();
|
||||
j->io = io_add( j->io, io_buffer );
|
||||
}
|
||||
|
||||
|
@ -928,7 +824,7 @@ void exec( job_t *j )
|
|||
if( p->next )
|
||||
{
|
||||
// fwprintf( stderr, L"Block %ls\n", p->argv[0] );
|
||||
io_buffer = exec_make_io_buffer();
|
||||
io_buffer = io_buffer_create();
|
||||
j->io = io_add( j->io, io_buffer );
|
||||
}
|
||||
|
||||
|
@ -1034,7 +930,7 @@ void exec( job_t *j )
|
|||
if( close_stdin )
|
||||
{
|
||||
// fwprintf( stderr, L"Close builtin_stdin\n" );
|
||||
close_loop( builtin_stdin );
|
||||
exec_close( builtin_stdin );
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
@ -1062,9 +958,7 @@ void exec( job_t *j )
|
|||
|
||||
j->io = io_remove( j->io, io_buffer );
|
||||
|
||||
debug( 3, L"exec_read_io_buffer on block '%ls'", p->argv[0] );
|
||||
|
||||
exec_read_io_buffer( io_buffer );
|
||||
io_buffer_read( io_buffer );
|
||||
|
||||
if( io_buffer->out_buffer->used != 0 )
|
||||
{
|
||||
|
@ -1105,7 +999,7 @@ void exec( job_t *j )
|
|||
|
||||
}
|
||||
|
||||
exec_free_io_buffer( io_buffer );
|
||||
io_buffer_destroy( io_buffer );
|
||||
|
||||
io_buffer=0;
|
||||
break;
|
||||
|
@ -1256,7 +1150,7 @@ void exec( job_t *j )
|
|||
Close the pipe the current process uses to read from the previous process_t
|
||||
*/
|
||||
if( pipe_read.pipe_fd[0] >= 0 )
|
||||
close_loop( pipe_read.pipe_fd[0] );
|
||||
exec_close( pipe_read.pipe_fd[0] );
|
||||
/*
|
||||
Set up the pipe the next process uses to read from the current process_t
|
||||
*/
|
||||
|
@ -1269,7 +1163,7 @@ void exec( job_t *j )
|
|||
*/
|
||||
if( p->next )
|
||||
{
|
||||
close_loop(mypipe[1]);
|
||||
exec_close(mypipe[1]);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1309,14 +1203,14 @@ int exec_subshell( const wchar_t *cmd,
|
|||
}
|
||||
|
||||
is_subshell=1;
|
||||
io_buffer= exec_make_io_buffer();
|
||||
io_buffer= io_buffer_create();
|
||||
|
||||
prev_status = proc_get_last_status();
|
||||
|
||||
eval( cmd, io_buffer, SUBST );
|
||||
|
||||
debug( 4, L"exec_read_io_buffer on cmdsub '%ls'", cmd );
|
||||
exec_read_io_buffer( io_buffer );
|
||||
io_buffer_read( io_buffer );
|
||||
|
||||
status = proc_get_last_status();
|
||||
proc_set_last_status( prev_status );
|
||||
|
@ -1341,7 +1235,7 @@ int exec_subshell( const wchar_t *cmd,
|
|||
if( el )
|
||||
al_push( l, el );
|
||||
}
|
||||
exec_free_io_buffer( io_buffer );
|
||||
io_buffer_destroy( io_buffer );
|
||||
|
||||
return status;
|
||||
|
||||
|
@ -1359,6 +1253,6 @@ int exec_subshell( const wchar_t *cmd,
|
|||
}
|
||||
}
|
||||
|
||||
exec_free_io_buffer( io_buffer );
|
||||
io_buffer_destroy( io_buffer );
|
||||
return status;
|
||||
}
|
||||
|
|
19
exec.h
19
exec.h
|
@ -10,6 +10,11 @@
|
|||
#include "proc.h"
|
||||
#include "util.h"
|
||||
|
||||
/**
|
||||
pipe redirection error message
|
||||
*/
|
||||
#define PIPE_ERROR L"An error occurred while setting up pipe"
|
||||
|
||||
/**
|
||||
Initialize the exec library
|
||||
*/
|
||||
|
@ -57,19 +62,17 @@ void exec( job_t *j );
|
|||
int exec_subshell( const wchar_t *cmd,
|
||||
array_list_t *l );
|
||||
|
||||
/**
|
||||
Free all resources used by a IO_BUFFER type io redirection.
|
||||
*/
|
||||
void exec_free_io_buffer( io_data_t *io_buffer );
|
||||
|
||||
/**
|
||||
Create a IO_BUFFER type io redirection.
|
||||
Loops over close until thesyscall was run without beeing
|
||||
interrupted. Thenremoves the fd from the open_fds list.
|
||||
*/
|
||||
io_data_t *exec_make_io_buffer();
|
||||
void exec_close( int fd );
|
||||
|
||||
/**
|
||||
Close writing end of IO_BUFFER type io redirection, and fully read the reading end.
|
||||
Call pipe(), and add resulting fds to open_fds, the list of opend
|
||||
file descriptors for pipes.
|
||||
*/
|
||||
void exec_read_io_buffer( io_data_t *d );
|
||||
int exec_pipe( int fd[2]);
|
||||
|
||||
#endif
|
||||
|
|
209
io.c
Normal file
209
io.c
Normal file
|
@ -0,0 +1,209 @@
|
|||
/** \file io.c
|
||||
|
||||
Utilities for io redirection.
|
||||
|
||||
*/
|
||||
#include "config.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <wchar.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
|
||||
#if HAVE_NCURSES_H
|
||||
#include <ncurses.h>
|
||||
#else
|
||||
#include <curses.h>
|
||||
#endif
|
||||
|
||||
#if HAVE_TERMIO_H
|
||||
#include <termio.h>
|
||||
#endif
|
||||
|
||||
#include <term.h>
|
||||
|
||||
#include "util.h"
|
||||
#include "wutil.h"
|
||||
#include "exec.h"
|
||||
#include "common.h"
|
||||
#include "io.h"
|
||||
|
||||
|
||||
|
||||
void io_buffer_read( io_data_t *d )
|
||||
{
|
||||
|
||||
exec_close(d->pipe_fd[1] );
|
||||
|
||||
if( d->io_mode == IO_BUFFER )
|
||||
{
|
||||
if( fcntl( d->pipe_fd[0], F_SETFL, 0 ) )
|
||||
{
|
||||
wperror( L"fcntl" );
|
||||
return;
|
||||
}
|
||||
debug( 4, L"exec_read_io_buffer: blocking read on fd %d", d->pipe_fd[0] );
|
||||
|
||||
while(1)
|
||||
{
|
||||
char b[4096];
|
||||
int l;
|
||||
l=read_blocked( d->pipe_fd[0], b, 4096 );
|
||||
if( l==0 )
|
||||
{
|
||||
break;
|
||||
}
|
||||
else if( l<0 )
|
||||
{
|
||||
/*
|
||||
exec_read_io_buffer is only called on jobs that have
|
||||
exited, and will therefore never block. But a broken
|
||||
pipe seems to cause some flags to reset, causing the
|
||||
EOF flag to not be set. Therefore, EAGAIN is ignored
|
||||
and we exit anyway.
|
||||
*/
|
||||
if( errno != EAGAIN )
|
||||
{
|
||||
debug( 1,
|
||||
L"An error occured while reading output from code block on fd %d",
|
||||
d->pipe_fd[0] );
|
||||
wperror( L"exec_read_io_buffer" );
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
b_append( d->out_buffer, b, l );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
io_data_t *io_buffer_create()
|
||||
{
|
||||
io_data_t *buffer_redirect = malloc( sizeof( io_data_t ));
|
||||
|
||||
buffer_redirect->io_mode=IO_BUFFER;
|
||||
buffer_redirect->next=0;
|
||||
buffer_redirect->out_buffer= malloc( sizeof(buffer_t));
|
||||
b_init( buffer_redirect->out_buffer );
|
||||
buffer_redirect->fd=1;
|
||||
|
||||
|
||||
if( exec_pipe( buffer_redirect->pipe_fd ) == -1 )
|
||||
{
|
||||
debug( 1, PIPE_ERROR );
|
||||
wperror (L"pipe");
|
||||
free( buffer_redirect->out_buffer );
|
||||
free( buffer_redirect );
|
||||
return 0;
|
||||
}
|
||||
else if( fcntl( buffer_redirect->pipe_fd[0],
|
||||
F_SETFL,
|
||||
O_NONBLOCK ) )
|
||||
{
|
||||
debug( 1, PIPE_ERROR );
|
||||
wperror( L"fcntl" );
|
||||
free( buffer_redirect->out_buffer );
|
||||
free( buffer_redirect );
|
||||
return 0;
|
||||
}
|
||||
return buffer_redirect;
|
||||
}
|
||||
|
||||
void io_buffer_destroy( io_data_t *io_buffer )
|
||||
{
|
||||
|
||||
exec_close( io_buffer->pipe_fd[0] );
|
||||
|
||||
/*
|
||||
Dont free fd for writing. This should already be free'd before
|
||||
calling exec_read_io_buffer on the buffer
|
||||
*/
|
||||
|
||||
b_destroy( io_buffer->out_buffer );
|
||||
|
||||
free( io_buffer->out_buffer );
|
||||
free( io_buffer );
|
||||
}
|
||||
|
||||
|
||||
|
||||
io_data_t *io_add( io_data_t *list, io_data_t *element )
|
||||
{
|
||||
io_data_t *curr = list;
|
||||
if( curr == 0 )
|
||||
return element;
|
||||
while( curr->next != 0 )
|
||||
curr = curr->next;
|
||||
curr->next = element;
|
||||
return list;
|
||||
}
|
||||
|
||||
io_data_t *io_remove( io_data_t *list, io_data_t *element )
|
||||
{
|
||||
io_data_t *curr, *prev=0;
|
||||
for( curr=list; curr; curr = curr->next )
|
||||
{
|
||||
if( element == curr )
|
||||
{
|
||||
if( prev == 0 )
|
||||
{
|
||||
io_data_t *tmp = element->next;
|
||||
element->next = 0;
|
||||
return tmp;
|
||||
}
|
||||
else
|
||||
{
|
||||
prev->next = element->next;
|
||||
element->next = 0;
|
||||
return list;
|
||||
}
|
||||
}
|
||||
prev = curr;
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
io_data_t *io_duplicate( io_data_t *l )
|
||||
{
|
||||
io_data_t *res;
|
||||
|
||||
if( l == 0 )
|
||||
return 0;
|
||||
|
||||
res = malloc( sizeof( io_data_t) );
|
||||
|
||||
if( !res )
|
||||
{
|
||||
die_mem();
|
||||
|
||||
}
|
||||
|
||||
memcpy( res, l, sizeof(io_data_t ));
|
||||
res->next=io_duplicate( l->next );
|
||||
return res;
|
||||
}
|
||||
|
||||
io_data_t *io_get( io_data_t *io, int fd )
|
||||
{
|
||||
if( io == 0 )
|
||||
return 0;
|
||||
|
||||
io_data_t *res = io_get( io->next, fd );
|
||||
if( res )
|
||||
return res;
|
||||
|
||||
if( io->fd == fd )
|
||||
return io;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
87
io.h
Normal file
87
io.h
Normal file
|
@ -0,0 +1,87 @@
|
|||
#ifndef FISH_IO_H
|
||||
#define FISH_IO_H
|
||||
|
||||
/**
|
||||
Describes what type of IO operation an io_data_t represents
|
||||
*/
|
||||
enum io_mode
|
||||
{
|
||||
IO_FILE, IO_PIPE, IO_FD, IO_BUFFER, IO_CLOSE
|
||||
}
|
||||
;
|
||||
|
||||
/** Represents an FD redirection */
|
||||
typedef struct io_data
|
||||
{
|
||||
/** Type of redirect */
|
||||
int io_mode;
|
||||
/** FD to redirect */
|
||||
int fd;
|
||||
/** parameter for redirection */
|
||||
union
|
||||
{
|
||||
/** Fds for IO_PIPE and for IO_BUFFER */
|
||||
int pipe_fd[2];
|
||||
/** Filename IO_FILE */
|
||||
wchar_t *filename;
|
||||
/** fd to redirect specified fd to, for IO_FD*/
|
||||
int old_fd;
|
||||
}
|
||||
;
|
||||
union
|
||||
{
|
||||
/** file creation flags to send to open for IO_FILE */
|
||||
int flags;
|
||||
/** buffer to save output in for IO_BUFFER */
|
||||
buffer_t *out_buffer;
|
||||
/** Whether to close old_fd for IO_FD */
|
||||
int close_old;
|
||||
|
||||
}
|
||||
;
|
||||
|
||||
/** Pointer to the next IO redirection */
|
||||
struct io_data *next;
|
||||
}
|
||||
io_data_t;
|
||||
|
||||
|
||||
/**
|
||||
Join two chains of io redirections
|
||||
*/
|
||||
io_data_t *io_add( io_data_t *first_chain, io_data_t *decond_chain );
|
||||
|
||||
/**
|
||||
Remove the specified io redirection from the chain
|
||||
*/
|
||||
io_data_t *io_remove( io_data_t *list, io_data_t *element );
|
||||
|
||||
/**
|
||||
Make a copy of the specified chain of redirections
|
||||
*/
|
||||
io_data_t *io_duplicate( io_data_t *l );
|
||||
|
||||
/**
|
||||
Return the last io redirection in ht e chain for the specified file descriptor.
|
||||
*/
|
||||
io_data_t *io_get( io_data_t *io, int fd );
|
||||
|
||||
|
||||
|
||||
/**
|
||||
Free all resources used by a IO_BUFFER type io redirection.
|
||||
*/
|
||||
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.
|
||||
*/
|
||||
io_data_t *io_buffer_create();
|
||||
|
||||
/**
|
||||
Close output pipe, and read from input pipe until eof.
|
||||
*/
|
||||
void io_buffer_read( io_data_t *d );
|
||||
|
||||
#endif
|
81
proc.c
81
proc.c
|
@ -74,77 +74,6 @@ int is_event=0;
|
|||
int proc_had_barrier;
|
||||
pid_t proc_last_bg_pid = 0;
|
||||
|
||||
io_data_t *io_add( io_data_t *list, io_data_t *element )
|
||||
{
|
||||
io_data_t *curr = list;
|
||||
if( curr == 0 )
|
||||
return element;
|
||||
while( curr->next != 0 )
|
||||
curr = curr->next;
|
||||
curr->next = element;
|
||||
return list;
|
||||
}
|
||||
|
||||
io_data_t *io_remove( io_data_t *list, io_data_t *element )
|
||||
{
|
||||
io_data_t *curr, *prev=0;
|
||||
for( curr=list; curr; curr = curr->next )
|
||||
{
|
||||
if( element == curr )
|
||||
{
|
||||
if( prev == 0 )
|
||||
{
|
||||
io_data_t *tmp = element->next;
|
||||
element->next = 0;
|
||||
return tmp;
|
||||
}
|
||||
else
|
||||
{
|
||||
prev->next = element->next;
|
||||
element->next = 0;
|
||||
return list;
|
||||
}
|
||||
}
|
||||
prev = curr;
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
io_data_t *io_duplicate( io_data_t *l )
|
||||
{
|
||||
io_data_t *res;
|
||||
|
||||
if( l == 0 )
|
||||
return 0;
|
||||
|
||||
res = malloc( sizeof( io_data_t) );
|
||||
|
||||
if( !res )
|
||||
{
|
||||
die_mem();
|
||||
|
||||
}
|
||||
|
||||
memcpy( res, l, sizeof(io_data_t ));
|
||||
res->next=io_duplicate( l->next );
|
||||
return res;
|
||||
}
|
||||
|
||||
io_data_t *io_get( io_data_t *io, int fd )
|
||||
{
|
||||
if( io == 0 )
|
||||
return 0;
|
||||
|
||||
io_data_t *res = io_get( io->next, fd );
|
||||
if( res )
|
||||
return res;
|
||||
|
||||
if( io->fd == fd )
|
||||
return io;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
Recursively free a process and those following it
|
||||
|
@ -368,7 +297,6 @@ static void mark_process_status( job_t *j,
|
|||
else
|
||||
{
|
||||
p->completed = 1;
|
||||
// fwprintf( stderr, L"Proc %d (%ls) exited\n", p->pid, p->actual_cmd );
|
||||
|
||||
if (( !WIFEXITED( status ) ) &&
|
||||
(! WIFSIGNALED( status )) )
|
||||
|
@ -743,15 +671,6 @@ static int select_try( job_t *j )
|
|||
int maxfd=-1;
|
||||
io_data_t *d;
|
||||
|
||||
|
||||
|
||||
/* if( j->stop_reading )
|
||||
{
|
||||
sleep(1);
|
||||
return;
|
||||
}
|
||||
*/
|
||||
|
||||
FD_ZERO(&fds);
|
||||
|
||||
for( d = j->io; d; d=d->next )
|
||||
|
|
67
proc.h
67
proc.h
|
@ -16,15 +16,8 @@
|
|||
#include <unistd.h>
|
||||
|
||||
#include "util.h"
|
||||
#include "io.h"
|
||||
|
||||
/**
|
||||
Describes what type of IO operation an io_data_t represents
|
||||
*/
|
||||
enum io_mode
|
||||
{
|
||||
IO_FILE, IO_PIPE, IO_FD, IO_BUFFER, IO_CLOSE
|
||||
}
|
||||
;
|
||||
|
||||
/**
|
||||
Types of internal processes
|
||||
|
@ -40,44 +33,8 @@ enum
|
|||
;
|
||||
|
||||
|
||||
/** Represents an FD redirection */
|
||||
typedef struct io_data
|
||||
{
|
||||
/** Type of redirect */
|
||||
int io_mode;
|
||||
/** FD to redirect */
|
||||
int fd;
|
||||
/** parameter for redirection */
|
||||
union
|
||||
{
|
||||
/** Fds for IO_PIPE and for IO_BUFFER */
|
||||
int pipe_fd[2];
|
||||
/** Filename IO_FILE */
|
||||
wchar_t *filename;
|
||||
/** fd to redirect specified fd to, for IO_FD*/
|
||||
int old_fd;
|
||||
}
|
||||
;
|
||||
union
|
||||
{
|
||||
/** file creation flags to send to open for IO_FILE */
|
||||
int flags;
|
||||
/** buffer to save output in for IO_BUFFER */
|
||||
buffer_t *out_buffer;
|
||||
/** Whether to close old_fd for IO_FD */
|
||||
int close_old;
|
||||
|
||||
}
|
||||
;
|
||||
|
||||
/** Pointer to the next IO redirection */
|
||||
struct io_data *next;
|
||||
}
|
||||
io_data_t;
|
||||
|
||||
|
||||
/**
|
||||
A structore representing a single process. Contains variables for
|
||||
A structure representing a single process. Contains variables for
|
||||
tracking process state and the process argument list.
|
||||
*/
|
||||
typedef struct process{
|
||||
|
@ -177,26 +134,6 @@ extern int proc_had_barrier;
|
|||
|
||||
extern pid_t proc_last_bg_pid;
|
||||
|
||||
/**
|
||||
Join two chains of io redirections
|
||||
*/
|
||||
io_data_t *io_add( io_data_t *first_chain, io_data_t *decond_chain );
|
||||
|
||||
/**
|
||||
Remove the specified io redirection from the chain
|
||||
*/
|
||||
io_data_t *io_remove( io_data_t *list, io_data_t *element );
|
||||
|
||||
/**
|
||||
Make a copy of the specified chain of redirections
|
||||
*/
|
||||
io_data_t *io_duplicate( io_data_t *l );
|
||||
|
||||
/**
|
||||
Return the last io redirection in ht e chain for the specified file descriptor.
|
||||
*/
|
||||
io_data_t *io_get( io_data_t *io, int fd );
|
||||
|
||||
/**
|
||||
Sets the status of the last process to exit
|
||||
*/
|
||||
|
|
6
reader.c
6
reader.c
|
@ -1260,12 +1260,12 @@ static void run_pager( wchar_t *prefix, int is_quoted, array_list_t *comp )
|
|||
|
||||
term_donate();
|
||||
|
||||
io_data_t *out = exec_make_io_buffer();
|
||||
io_data_t *out = io_buffer_create();
|
||||
|
||||
eval( (wchar_t *)cmd.buff, out, TOP);
|
||||
term_steal();
|
||||
|
||||
exec_read_io_buffer( out );
|
||||
io_buffer_read( out );
|
||||
|
||||
sb_destroy( &cmd );
|
||||
|
||||
|
@ -1285,7 +1285,7 @@ static void run_pager( wchar_t *prefix, int is_quoted, array_list_t *comp )
|
|||
free( str );
|
||||
}
|
||||
|
||||
exec_free_io_buffer( out);
|
||||
io_buffer_destroy( out);
|
||||
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue