diff options
author | axel <axel@liljencrantz.se> | 2005-10-08 21:20:51 +1000 |
---|---|---|
committer | axel <axel@liljencrantz.se> | 2005-10-08 21:20:51 +1000 |
commit | 9ae7fa5831cbc0a7d221c566bcd8633e609b9670 (patch) | |
tree | e58edf5437595dc50ff8595c23215f13efb190f9 /io.c | |
parent | 93eed7bc352d7c5f26097c70b3ee324c9f4947ca (diff) |
Move io redirection functions to their own library
darcs-hash:20051008112051-ac50b-113caa4cba470a739e4bfbed9f479e2fed357be7.gz
Diffstat (limited to 'io.c')
-rw-r--r-- | io.c | 209 |
1 files changed, 209 insertions, 0 deletions
@@ -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; +} + |