2005-10-08 21:20:51 +10:00
# ifndef FISH_IO_H
# define FISH_IO_H
2012-03-07 00:54:01 -08:00
# include <vector>
2013-04-09 14:07:19 -07:00
# if __cplusplus > 199711L
// C++11
# include <memory>
using std : : shared_ptr ;
# else
// C++03
# include <tr1/memory>
using std : : tr1 : : shared_ptr ;
# endif
2012-03-04 02:35:30 -08:00
2005-10-08 21:20:51 +10:00
/**
Describes what type of IO operation an io_data_t represents
*/
2013-01-01 01:11:46 +08:00
enum io_mode_t
2005-10-08 21:20:51 +10:00
{
2013-01-15 17:39:20 +08:00
IO_FILE , IO_PIPE , IO_FD , IO_BUFFER , IO_CLOSE
2012-03-04 02:35:30 -08:00
} ;
2005-10-08 21:20:51 +10:00
/** Represents an FD redirection */
2012-03-04 02:35:30 -08:00
class io_data_t
2005-10-08 21:20:51 +10:00
{
2012-03-04 02:35:30 -08:00
private :
2013-01-07 23:04:55 +08:00
/* No assignment or copying allowed */
io_data_t ( const io_data_t & rhs ) ;
2012-08-05 13:24:33 -07:00
void operator = ( const io_data_t & rhs ) ;
2013-01-04 02:03:41 -08:00
2013-01-15 17:39:20 +08:00
protected :
io_data_t ( io_mode_t m , int f ) :
io_mode ( m ) ,
2013-01-16 11:55:57 +08:00
fd ( f )
2013-01-15 17:39:20 +08:00
{
}
2012-03-04 02:35:30 -08:00
public :
2012-11-18 16:30:30 -08:00
/** Type of redirect */
2013-01-17 14:46:02 +08:00
const io_mode_t io_mode ;
2012-11-18 16:30:30 -08:00
/** FD to redirect */
2013-02-04 20:07:16 +08:00
const int fd ;
2012-11-18 16:30:30 -08:00
2013-01-15 17:39:20 +08:00
virtual void print ( ) const = 0 ;
virtual ~ io_data_t ( ) = 0 ;
2012-02-09 18:43:36 -08:00
} ;
2013-01-09 16:02:04 +08:00
class io_close_t : public io_data_t
{
public :
io_close_t ( int f ) :
io_data_t ( IO_CLOSE , f )
{
}
virtual void print ( ) const ;
} ;
2013-01-15 15:37:33 +08:00
class io_fd_t : public io_data_t
{
public :
/** fd to redirect specified fd to */
2013-02-04 20:14:48 +08:00
const int old_fd ;
2013-01-15 15:37:33 +08:00
/** Whether to close old_fd */
2013-02-04 20:14:48 +08:00
const bool close_old ;
2013-01-15 15:37:33 +08:00
virtual void print ( ) const ;
io_fd_t ( int f , int old , bool close = false ) :
io_data_t ( IO_FD , f ) ,
old_fd ( old ) ,
close_old ( close )
{
}
} ;
2013-01-15 16:18:03 +08:00
class io_file_t : public io_data_t
{
public :
/** Filename, malloc'd. This needs to be used after fork, so don't use wcstring here. */
2013-01-19 10:59:43 -08:00
const char * const filename_cstr ;
2013-01-15 16:18:03 +08:00
/** file creation flags to send to open */
2013-02-04 20:15:32 +08:00
const int flags ;
2013-01-21 10:34:18 +08:00
2013-01-15 16:18:03 +08:00
virtual void print ( ) const ;
2013-01-19 10:59:43 -08:00
io_file_t ( int f , const wcstring & fname , int fl = 0 ) :
2013-01-15 16:18:03 +08:00
io_data_t ( IO_FILE , f ) ,
2013-01-19 10:59:43 -08:00
filename_cstr ( wcs2str ( fname ) ) ,
2013-01-15 16:18:03 +08:00
flags ( fl )
{
}
virtual ~ io_file_t ( )
{
free ( ( void * ) filename_cstr ) ;
}
} ;
2005-10-08 21:20:51 +10:00
2013-01-15 17:31:36 +08:00
class io_pipe_t : public io_data_t
{
2013-01-17 14:46:02 +08:00
protected :
io_pipe_t ( io_mode_t m , int f , bool i ) :
io_data_t ( m , f ) ,
is_input ( i )
{
2013-01-30 02:22:38 -08:00
pipe_fd [ 0 ] = pipe_fd [ 1 ] = - 1 ;
2013-01-17 14:46:02 +08:00
}
2013-01-15 17:31:36 +08:00
public :
int pipe_fd [ 2 ] ;
2013-01-30 02:22:38 -08:00
const bool is_input ;
2013-01-15 17:31:36 +08:00
virtual void print ( ) const ;
2013-01-16 11:55:57 +08:00
io_pipe_t ( int f , bool i ) :
2013-01-15 17:31:36 +08:00
io_data_t ( IO_PIPE , f ) ,
2013-01-16 11:55:57 +08:00
is_input ( i )
2013-01-15 17:31:36 +08:00
{
2013-01-30 02:22:38 -08:00
pipe_fd [ 0 ] = pipe_fd [ 1 ] = - 1 ;
2013-01-15 17:31:36 +08:00
}
} ;
class io_buffer_t : public io_pipe_t
2013-01-15 16:44:31 +08:00
{
private :
/** buffer to save output in */
2013-01-19 10:59:43 -08:00
std : : vector < char > out_buffer ;
2013-01-15 16:44:31 +08:00
2013-01-16 11:55:57 +08:00
io_buffer_t ( int f , bool i ) :
2013-01-17 14:46:02 +08:00
io_pipe_t ( IO_BUFFER , f , i ) ,
2013-01-17 15:46:10 +08:00
out_buffer ( )
2013-01-15 16:44:31 +08:00
{
}
2013-01-15 17:07:30 +08:00
public :
virtual void print ( ) const ;
2013-01-16 11:30:18 +08:00
virtual ~ io_buffer_t ( ) ;
2013-01-15 17:02:46 +08:00
2013-01-15 16:44:31 +08:00
/** Function to append to the buffer */
void out_buffer_append ( const char * ptr , size_t count )
{
2013-01-19 10:59:43 -08:00
out_buffer . insert ( out_buffer . end ( ) , ptr , ptr + count ) ;
2013-01-15 16:44:31 +08:00
}
/** Function to get a pointer to the buffer */
char * out_buffer_ptr ( void )
{
2013-01-19 10:59:43 -08:00
return out_buffer . empty ( ) ? NULL : & out_buffer . at ( 0 ) ;
2013-01-15 16:44:31 +08:00
}
const char * out_buffer_ptr ( void ) const
{
2013-01-19 10:59:43 -08:00
return out_buffer . empty ( ) ? NULL : & out_buffer . at ( 0 ) ;
2013-01-15 16:44:31 +08:00
}
/** Function to get the size of the buffer */
size_t out_buffer_size ( void ) const
{
2013-01-19 10:59:43 -08:00
return out_buffer . size ( ) ;
2013-01-15 16:44:31 +08:00
}
2013-01-15 17:07:30 +08:00
2013-01-15 17:10:40 +08:00
/**
Close output pipe , and read from input pipe until eof .
*/
void read ( ) ;
2013-01-15 17:07:30 +08:00
/**
Create a IO_BUFFER type io redirection , complete with a pipe and a
vector < char > for output . The default file descriptor used is 1 for
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 .
2013-02-04 20:07:16 +08:00
\ param fd when - 1 , determined from is_input .
2013-01-15 17:07:30 +08:00
*/
2013-02-04 20:07:16 +08:00
static io_buffer_t * create ( bool is_input , int fd = - 1 ) ;
2013-01-15 16:44:31 +08:00
} ;
2013-01-07 23:04:55 +08:00
class io_chain_t : public std : : vector < shared_ptr < io_data_t > >
2012-11-18 16:30:30 -08:00
{
2012-08-15 00:57:56 -07:00
public :
io_chain_t ( ) ;
2013-01-07 23:04:55 +08:00
io_chain_t ( const shared_ptr < io_data_t > & ) ;
2012-11-18 11:23:22 +01:00
2013-01-07 23:04:55 +08:00
void remove ( const shared_ptr < const io_data_t > & element ) ;
2013-01-30 02:22:38 -08:00
void push_back ( const shared_ptr < io_data_t > & element ) ;
2012-11-18 11:23:22 +01:00
2013-01-07 23:04:55 +08:00
shared_ptr < const io_data_t > get_io_for_fd ( int fd ) const ;
shared_ptr < io_data_t > get_io_for_fd ( int fd ) ;
2012-08-15 00:57:56 -07:00
} ;
2005-10-08 21:20:51 +10:00
/**
Remove the specified io redirection from the chain
*/
2013-01-07 23:04:55 +08:00
void io_remove ( io_chain_t & list , const shared_ptr < const io_data_t > & element ) ;
2005-10-08 21:20:51 +10:00
2012-08-15 00:57:56 -07:00
/** Destroys an io_chain */
void io_chain_destroy ( io_chain_t & chain ) ;
2005-10-08 21:20:51 +10:00
/**
2007-04-17 06:10:53 +10:00
Return the last io redirection in the chain for the specified file descriptor .
2005-10-08 21:20:51 +10:00
*/
2013-01-07 23:04:55 +08:00
shared_ptr < const io_data_t > io_chain_get ( const io_chain_t & src , int fd ) ;
shared_ptr < io_data_t > io_chain_get ( io_chain_t & src , int fd ) ;
2005-10-08 21:20:51 +10:00
2012-08-15 00:57:56 -07:00
/** Print debug information about the specified IO redirection chain to stderr. */
2012-11-18 16:30:30 -08:00
void io_print ( const io_chain_t & chain ) ;
2006-05-15 08:29:05 +10:00
2005-10-08 21:20:51 +10:00
# endif