aboutsummaryrefslogtreecommitdiffhomepage
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
parent93eed7bc352d7c5f26097c70b3ee324c9f4947ca (diff)
Move io redirection functions to their own library
darcs-hash:20051008112051-ac50b-113caa4cba470a739e4bfbed9f479e2fed357be7.gz
-rw-r--r--Makefile.in2
-rw-r--r--builtin.c3
-rw-r--r--exec.c172
-rw-r--r--exec.h19
-rw-r--r--io.c209
-rw-r--r--io.h87
-rw-r--r--proc.c81
-rw-r--r--proc.h67
-rw-r--r--reader.c6
9 files changed, 347 insertions, 299 deletions
diff --git a/Makefile.in b/Makefile.in
index e3c242cd..3c44c2ec 100644
--- a/Makefile.in
+++ b/Makefile.in
@@ -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
diff --git a/builtin.c b/builtin.c
index aaa3db58..f621611a 100644
--- a/builtin.c
+++ b/builtin.c
@@ -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
diff --git a/exec.c b/exec.c
index ba58fc56..d4025ebb 100644
--- a/exec.c
+++ b/exec.c
@@ -34,6 +34,7 @@
#include "wildcard.h"
#include "sanity.h"
#include "expand.h"
+#include "signal.h"
#include "env_universal.h"
/**
@@ -53,10 +54,6 @@ pid_t getpgid( pid_t pid );
*/
#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
*/
#define FORK_ERROR L"Could not create child process - exiting"
@@ -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 )
@@ -439,109 +438,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;
}
diff --git a/exec.h b/exec.h
index 14802636..21a5bac9 100644
--- a/exec.h
+++ b/exec.h
@@ -11,6 +11,11 @@
#include "util.h"
/**
+ pipe redirection error message
+*/
+#define PIPE_ERROR L"An error occurred while setting up pipe"
+
+/**
Initialize the exec library
*/
void exec_init();
@@ -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
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;
+}
+
diff --git a/io.h b/io.h
new file mode 100644
index 00000000..6cb103be
--- /dev/null
+++ b/io.h
@@ -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
diff --git a/proc.c b/proc.c
index b4cfd27f..0e73f518 100644
--- a/proc.c
+++ b/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 )
diff --git a/proc.h b/proc.h
index 6e67c377..9f8e85d6 100644
--- a/proc.h
+++ b/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{
@@ -178,26 +135,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
*/
void proc_set_last_status( int s );
diff --git a/reader.c b/reader.c
index 89f2bc64..f1ae2e23 100644
--- a/reader.c
+++ b/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);
}