aboutsummaryrefslogtreecommitdiffhomepage
path: root/io.c
diff options
context:
space:
mode:
authorGravatar axel <axel@liljencrantz.se>2005-10-08 21:20:51 +1000
committerGravatar axel <axel@liljencrantz.se>2005-10-08 21:20:51 +1000
commit9ae7fa5831cbc0a7d221c566bcd8633e609b9670 (patch)
treee58edf5437595dc50ff8595c23215f13efb190f9 /io.c
parent93eed7bc352d7c5f26097c70b3ee324c9f4947ca (diff)
Move io redirection functions to their own library
darcs-hash:20051008112051-ac50b-113caa4cba470a739e4bfbed9f479e2fed357be7.gz
Diffstat (limited to 'io.c')
-rw-r--r--io.c209
1 files changed, 209 insertions, 0 deletions
diff --git a/io.c b/io.c
new file mode 100644
index 00000000..86397955
--- /dev/null
+++ b/io.c
@@ -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;
+}
+