[C++, Linux] Jak przechwycić stdin, stdout i stderr dla programu uruchamianego z poziomu kodu
Ostatnio zmodyfikowano 2015-01-13 17:32
DejaVu Temat założony przez niniejszego użytkownika |
[C++, Linux] Jak przechwycić stdin, stdout i stderr dla programu uruchamianego z poziomu kodu » 2015-01-13 15:15:38 #include <unistd.h> #include <stdio.h> #include <cstdlib>
#define NUM_PIPES 2
#define PARENT_WRITE_PIPE 0 #define PARENT_READ_PIPE 1
int pipes[ NUM_PIPES ][ 2 ];
#define READ_FD 0 #define WRITE_FD 1
#define PARENT_READ_FD ( pipes[PARENT_READ_PIPE][READ_FD] ) #define PARENT_WRITE_FD ( pipes[PARENT_WRITE_PIPE][WRITE_FD] )
#define CHILD_READ_FD ( pipes[PARENT_WRITE_PIPE][READ_FD] ) #define CHILD_WRITE_FD ( pipes[PARENT_READ_PIPE][WRITE_FD] )
int main() { int outfd[ 2 ]; int infd[ 2 ]; pipe( pipes[ PARENT_READ_PIPE ] ); pipe( pipes[ PARENT_WRITE_PIPE ] ); if( !fork() ) { char * argv[] = { "/usr/bin/bc", "-q", 0 }; dup2( CHILD_READ_FD, STDIN_FILENO ); dup2( CHILD_WRITE_FD, STDOUT_FILENO ); close( CHILD_READ_FD ); close( CHILD_WRITE_FD ); close( PARENT_READ_FD ); close( PARENT_WRITE_FD ); execv( argv[ 0 ], argv ); } else { char buffer[ 100 ]; int count; close( CHILD_READ_FD ); close( CHILD_WRITE_FD ); write( PARENT_WRITE_FD, "2^32\n", 5 ); count = read( PARENT_READ_FD, buffer, sizeof( buffer ) - 1 ); if( count >= 0 ) { buffer[ count ] = 0; printf( "%s", buffer ); } else { printf( "IO Error\n" ); } } }
Źródło: https://jineshkj.wordpress.com/2006/12/22/how-to-capture-stdin-stdout-and-stderr-of-child-program/Dodatkowe informacje: http://stackoverflow.com/questions/280571/how-to-control-popen-stdin-stdout-stderr-redirection |
|
akwes |
» 2015-01-13 16:29:40 |
|
DejaVu Temat założony przez niniejszego użytkownika |
» 2015-01-13 17:32:21 #include <unistd.h> #include <cstdio> #include <cstdlib> #include <vector> #include <cstring> #include <errno.h> #include <sys/types.h> #include <sys/time.h> #include <cmath> #include <sys/select.h> #include <termios.h> #include <stropts.h> #include <sys/ioctl.h>
int _kbhit() { static const int STDIN = 0; static bool initialized = false; if( !initialized ) { termios term; tcgetattr( STDIN, & term ); term.c_lflag &= ~ICANON; tcsetattr( STDIN, TCSANOW, & term ); setbuf( stdin, NULL ); initialized = true; } int bytesWaiting; ioctl( STDIN, FIONREAD, & bytesWaiting ); return bytesWaiting; }
class CaptureIO { private: typedef int PipeReadWrite[ 2 ]; PipeReadWrite m_pipeRead; PipeReadWrite m_pipeWrite; static int getDescriptorState( int filedes, float _seconds ) { fd_set waitingList; FD_ZERO( & waitingList ); FD_SET( filedes, & waitingList ); timeval timeout; float reszta = fmod( _seconds, 1.0f ); timeout.tv_sec = static_cast < int >( _seconds ); timeout.tv_usec = static_cast < int >( reszta * 1000000 ); return select( FD_SETSIZE, & waitingList, NULL, NULL, & timeout ); } public: int getChildReadDescriptor() const { return m_pipeWrite[ 0 ]; } int getChildWriteDescriptor() const { return m_pipeRead[ 1 ]; } int getParentReadDescriptor() const { return m_pipeRead[ 0 ]; } int getParentWriteDescriptor() const { return m_pipeWrite[ 1 ]; } void initPipes() { ::pipe( m_pipeRead ); ::pipe( m_pipeWrite ); } void runApplicationAtChild( const char * _sApplication ) { ::dup2( getChildReadDescriptor(), STDIN_FILENO ); ::dup2( getChildWriteDescriptor(), STDOUT_FILENO ); ::close( getChildReadDescriptor() ); ::close( getChildWriteDescriptor() ); ::close( getParentWriteDescriptor() ); ::close( getParentWriteDescriptor() ); ::system( _sApplication ); } void initCommunication() { ::close( getChildReadDescriptor() ); ::close( getChildWriteDescriptor() ); } void write( char _c ) { write( & _c, 1 ); } void write( const char * _sText ) { write( _sText, strlen( _sText ) ); } void write( const char * _sText, size_t _length ) { ::write( getParentWriteDescriptor(), _sText, _length ); } bool isReadingFailed() const { return getDescriptorState( getParentReadDescriptor(), 0.05f ) ==- 1; } bool isWaitingForReading() const { return getDescriptorState( getParentReadDescriptor(), 0.05f ) == 1; } bool read( char * _buffer, size_t _sizeInBytes ) { _buffer[ 0 ] = 0; if( !isWaitingForReading() ) return true; if( _sizeInBytes == 0 ) return true; int count =::read( getParentReadDescriptor(), _buffer, _sizeInBytes - 1 ); if( count > 0 ) { _buffer[ count ] = 0; return true; } else { return false; } } };
int main() { CaptureIO app; app.initPipes(); if( fork() ) { app.initCommunication(); bool bContinue = true; while( bContinue ) { char buffer[ 100 ]; while( bContinue && app.isWaitingForReading() ) { bContinue = app.read( buffer, sizeof( buffer ) ); printf( "%s", buffer ); fflush( stdout ); } if( !app.isWaitingForReading() && _kbhit() > 0 ) { int c = getc( stdin ); app.write( static_cast < char >( c ) ); } } printf( "Closing main application.\n" ); } else { app.runApplicationAtChild( "/usr/bin/bc -q" ); printf( "Application closed!\n" ); } return 0; }
|
|
« 1 » |