Go to the documentation of this file.00001
00002
00003 #include <wibble/sys/macros.h>
00004
00005 #ifdef POSIX
00006 #include <fcntl.h>
00007 #include <sys/select.h>
00008
00009 #include <deque>
00010 #include <cerrno>
00011
00012 #include <wibble/exception.h>
00013
00014 #ifndef WIBBLE_SYS_PIPE_H
00015 #define WIBBLE_SYS_PIPE_H
00016
00017 namespace wibble {
00018 namespace sys {
00019
00020 namespace wexcept = wibble::exception;
00021
00022 struct Pipe {
00023 typedef std::deque< char > Buffer;
00024 Buffer buffer;
00025 int fd;
00026 bool _eof;
00027
00028 Pipe( int p ) : fd( p ), _eof( false )
00029 {
00030 if ( p == -1 )
00031 return;
00032 if ( fcntl( fd, F_SETFL, O_NONBLOCK ) == -1 )
00033 throw wexcept::System( "fcntl on a pipe" );
00034 }
00035 Pipe() : fd( -1 ), _eof( false ) {}
00036
00037 void write( std::string what ) {
00038 ::write( fd, what.c_str(), what.length() );
00039 }
00040
00041 void close() {
00042 ::close( fd );
00043 }
00044
00045 bool active() {
00046 return fd != -1 && !_eof;
00047 }
00048
00049 bool eof() {
00050 return _eof;
00051 }
00052
00053 int readMore() {
00054 char _buffer[1024];
00055 int r = ::read( fd, _buffer, 1023 );
00056 if ( r == -1 && errno != EAGAIN )
00057 throw wexcept::System( "reading from pipe" );
00058 else if ( r == -1 )
00059 return 0;
00060 if ( r == 0 )
00061 _eof = true;
00062 else
00063 std::copy( _buffer, _buffer + r, std::back_inserter( buffer ) );
00064 return r;
00065 }
00066
00067 std::string nextLine() {
00068 Buffer::iterator nl =
00069 std::find( buffer.begin(), buffer.end(), '\n' );
00070 while ( nl == buffer.end() && readMore() );
00071 nl = std::find( buffer.begin(), buffer.end(), '\n' );
00072 if ( nl == buffer.end() )
00073 return "";
00074
00075 std::string line( buffer.begin(), nl );
00076 ++ nl;
00077 buffer.erase( buffer.begin(), nl );
00078 return line;
00079 }
00080
00081 std::string nextLineBlocking() {
00082 fd_set fds;
00083 FD_ZERO( &fds );
00084 std::string l;
00085 while ( !eof() ) {
00086 l = nextLine();
00087 if ( !l.empty() )
00088 return l;
00089 FD_SET( fd, &fds );
00090 select( fd + 1, &fds, 0, 0, 0 );
00091 }
00092 return l;
00093 }
00094
00095 };
00096
00097 }
00098 }
00099 #endif
00100 #endif