• Main Page
  • Namespaces
  • Classes
  • Files
  • File List
  • File Members

pipe.h

Go to the documentation of this file.
00001 // -*- C++ -*- (c) 2008 Petr Rockai <me@mornfall.net>
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

Generated on Tue May 10 2011 16:51:50 for wibble by  doxygen 1.7.1