2005-10-08 19:20:51 +08:00
# ifndef FISH_IO_H
# define FISH_IO_H
2012-03-07 16:54:01 +08:00
# include <vector>
2012-03-04 18:35:30 +08:00
# include <tr1/memory>
using std : : tr1 : : shared_ptr ;
2005-10-08 19:20:51 +08:00
/**
Describes what type of IO operation an io_data_t represents
*/
enum io_mode
{
IO_FILE , IO_PIPE , IO_FD , IO_BUFFER , IO_CLOSE
2012-03-04 18:35:30 +08:00
} ;
2005-10-08 19:20:51 +08:00
/** Represents an FD redirection */
2012-03-04 18:35:30 +08:00
class io_data_t
2005-10-08 19:20:51 +08:00
{
2012-03-04 18:35:30 +08:00
private :
2012-03-10 03:28:24 +08:00
/** buffer to save output in for IO_BUFFER. Note that in the original fish, the buffer was a pointer to a buffer_t stored in the param2 union down below, and when an io_data_t was duplicated the pointer was copied so that two io_data_ts referenced the same buffer. It's not clear to me how this was ever cleaned up correctly. But it's important that they share the same buffer for reasons I don't yet understand either. We can get correct sharing and cleanup with shared_ptr. */
2012-03-04 18:35:30 +08:00
shared_ptr < std : : vector < char > > out_buffer ;
/* No assignment allowed */
void operator = ( const io_data_t & rhs ) { assert ( 0 ) ; }
public :
2005-10-08 19:20:51 +08:00
/** Type of redirect */
int io_mode ;
/** FD to redirect */
int fd ;
2012-03-04 18:35:30 +08:00
2011-12-27 11:18:46 +08:00
/**
Type - specific parameter for redirection
2005-10-24 23:26:25 +08:00
*/
2005-10-08 19:20:51 +08:00
union
{
/** Fds for IO_PIPE and for IO_BUFFER */
int pipe_fd [ 2 ] ;
2012-03-10 03:28:24 +08:00
/** fd to redirect specified fd to, for IO_FD */
2005-10-08 19:20:51 +08:00
int old_fd ;
2012-02-22 11:33:11 +08:00
} param1 ;
2012-03-04 18:35:30 +08:00
/** Second type-specific paramter for redirection */
2005-10-08 19:20:51 +08:00
union
{
/** file creation flags to send to open for IO_FILE */
int flags ;
/** Whether to close old_fd for IO_FD */
int close_old ;
2012-02-10 10:43:36 +08:00
} param2 ;
2012-03-04 15:56:35 +08:00
2012-03-09 15:21:07 +08:00
/** Filename IO_FILE. malloc'd. This needs to be used after fork, so don't use wcstring here. */
const char * filename_cstr ;
/** Convenience to set filename_cstr via wcstring */
void set_filename ( const wcstring & str ) {
free ( ( void * ) filename_cstr ) ;
filename_cstr = wcs2str ( str . c_str ( ) ) ;
}
2012-03-04 18:35:30 +08:00
/** Function to create the output buffer */
void out_buffer_create ( ) {
out_buffer . reset ( new std : : vector < char > ) ;
}
/** Function to append to the buffer */
void out_buffer_append ( const char * ptr , size_t count ) {
assert ( out_buffer . get ( ) ! = NULL ) ;
out_buffer - > insert ( out_buffer - > end ( ) , ptr , ptr + count ) ;
}
/** Function to get a pointer to the buffer */
char * out_buffer_ptr ( void ) {
assert ( out_buffer . get ( ) ! = NULL ) ;
2012-03-16 03:00:27 +08:00
return ( out_buffer - > size ( ) = = 0 ) ? NULL : & out_buffer - > at ( 0 ) ;
2012-03-04 18:35:30 +08:00
}
/** Function to get the size of the buffer */
size_t out_buffer_size ( void ) const {
assert ( out_buffer . get ( ) ! = NULL ) ;
return out_buffer - > size ( ) ;
}
2006-08-13 09:38:03 +08:00
2012-03-04 15:56:35 +08:00
/** Set to true if this is an input io redirection */
2006-11-12 20:16:13 +08:00
int is_input ;
2011-12-27 11:18:46 +08:00
2005-10-08 19:20:51 +08:00
/** Pointer to the next IO redirection */
2012-02-10 10:43:36 +08:00
io_data_t * next ;
2012-03-09 15:21:07 +08:00
io_data_t ( ) : filename_cstr ( NULL ) , next ( NULL )
{
}
io_data_t ( const io_data_t & rhs ) :
out_buffer ( rhs . out_buffer ) ,
io_mode ( rhs . io_mode ) ,
fd ( rhs . fd ) ,
param1 ( rhs . param1 ) ,
param2 ( rhs . param2 ) ,
filename_cstr ( rhs . filename_cstr ? strdup ( rhs . filename_cstr ) : NULL ) ,
is_input ( rhs . is_input ) ,
next ( rhs . next )
2012-03-04 18:35:30 +08:00
{
2012-03-09 15:21:07 +08:00
2012-03-04 18:35:30 +08:00
}
2012-03-09 15:21:07 +08:00
~ io_data_t ( ) {
free ( ( void * ) filename_cstr ) ;
}
2012-02-10 10:43:36 +08:00
} ;
2005-10-08 19:20:51 +08:00
2011-12-27 11:18:46 +08:00
2005-10-08 19:20:51 +08:00
/**
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 ) ;
/**
2012-02-10 10:43:36 +08:00
Make a copy of the specified chain of redirections . Uses operator new .
2005-10-08 19:20:51 +08:00
*/
2012-02-10 10:43:36 +08:00
io_data_t * io_duplicate ( io_data_t * l ) ;
2005-10-08 19:20:51 +08:00
/**
2007-04-17 04:10:53 +08:00
Return the last io redirection in the chain for the specified file descriptor .
2005-10-08 19:20:51 +08:00
*/
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
2012-03-09 15:21:07 +08:00
vector < char > for output . The default file descriptor used is 1 for
2006-08-13 09:38:03 +08:00
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 .
2005-10-08 19:20:51 +08:00
*/
2006-08-13 09:38:03 +08:00
io_data_t * io_buffer_create ( int is_input ) ;
2005-10-08 19:20:51 +08:00
/**
Close output pipe , and read from input pipe until eof .
*/
void io_buffer_read ( io_data_t * d ) ;
2006-06-20 08:50:10 +08:00
/**
Print debug information about the specified IO redirection chain to stderr .
*/
2006-05-15 06:29:05 +08:00
void io_print ( io_data_t * io ) ;
2005-10-08 19:20:51 +08:00
# endif