Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | File List | Namespace Members | Class Members | File Members

fdstreambuf.h

Go to the documentation of this file.
00001 #ifndef DV_FDSTREAMBUF_H 00002 #define DV_FDSTREAMBUF_H 00003 // $Id: fdstreambuf.h,v 1.21 2003/08/18 13:51:35 dvermeir Exp $ 00004 00005 #include <iostream> 00006 #include <string> 00007 #include <sys/types.h> // for size_t, time_t 00008 /** \file 00009 * The Dv::fdstreambuf class provides a streambuf specialization 00010 * that manages a file descriptor (fd) and handles the possibility of 00011 * timeout on input or open by failing an operation if it times out 00012 */ 00013 namespace Dv { 00014 namespace Util { 00015 00016 /** 00017 * A streambuf specialization that manages a file descriptor and handles 00018 * timeouts. 00019 */ 00020 class fdstreambuf: public std::streambuf { 00021 public: 00022 /** 00023 * The constructor simply allocates the buffers and stores the 00024 * delay (in millisecs). 00025 * 00026 * \param fd filedescriptor to be used by this fdstreambuf 00027 * \param inbuf_sz size of input buffer. 00028 * \param outbuf_sz size of output buffer. 00029 * \param delay time, in millisecs, to wait before an open or input 00030 * operation fails, a delay of 0 means ``wait foerver''. 00031 * \param non_blocking whether the underlying filedecriptor is in 00032 * non-blocking (O_NONBLOCK) mode, see fctnl(2). 00033 * Using a non-blocking streambuf prevents some blocking I/O 00034 * operations. E.g. if select(2) indicates that writing is possible 00035 * but the actual number of bytes to write is too large, the write may 00036 * block indefinitely for a blocking Socket. For a non-blocking socket, 00037 * the write(2) will return EAGAIN which will be handled 00038 * appropriately by fdstreambuf. 00039 * \param debug pointer to ostream to write debug info on or 0, see 00040 * fdstreambuf::debug(). 00041 * 00042 * The constructor also calls <code>signal(SIGPIPE,SIG_IGN)</code>, 00043 * causing <code>SIGPIPE</code> signals to be ignored. Instead, 00044 * the system should let the I/O operation fail and set errno to 00045 * <code>EPIPE</code>. 00046 */ 00047 explicit fdstreambuf(int fd=-1,size_t inbuf_sz=1024,size_t outbuf_sz=1024, 00048 time_t delay=0, bool non_blocking = false, 00049 std::ostream* debug = 0); 00050 /** 00051 * This is already virtual in streambuf. 00052 */ 00053 virtual ~fdstreambuf(); 00054 00055 /** \return size of input buffer */ 00056 size_t inbuf_sz() const { return inbuf_sz_; } 00057 /** \return size of output buffer */ 00058 size_t outbuf_sz() const { return outbuf_sz_; } 00059 /** 00060 * Return the number of millsecs to wait before an open or input operation 00061 * fails. A value of 0 means wait forever. 00062 * 00063 * \return The current delay value. 00064 */ 00065 time_t delay() const { return delay_; } 00066 00067 /** 00068 * Set delay (0 means infinite delay). 00069 * 00070 * \param d delay in millisecs, 0 means ``wait forever''. 00071 */ 00072 void delay(time_t d) { delay_ = d; } 00073 00074 /** 00075 * Return the blocking status. 00076 * 00077 * \return true iff the constructor was called with non_blocking or 00078 * set_non_blocking() was called before. 00079 */ 00080 bool non_blocking() const { return non_blocking_; } 00081 00082 /** 00083 * Set non-blocking I/O. 00084 * 00085 * \return 0 upon success, -1 else in which case error() will 00086 * reflect the system errno. 00087 * \see fcntl(2) 00088 */ 00089 int set_non_blocking(); 00090 00091 /** 00092 * Return file descriptor underlying this fdstreambuf object. 00093 * 00094 * \return The current value for the underlying file descriptor. 00095 */ 00096 int fd() const { return fd_; } 00097 00098 /** 00099 * Set the underlying file descriptor. The previous descriptor, if 00100 * valid, is closed. 00101 * 00102 * \param i new file descriptor. 00103 * \param non_blocking whether I/O should be non-blocking. 00104 * \return true iff close() of the previous valid file descriptor 00105 * succeeded 00106 * \see fdstreambuf::close() 00107 */ 00108 bool fd(int i, bool non_blocking = false); 00109 00110 /** 00111 * Close the underlying file descriptor. 00112 * 00113 * \return false iff close() of the underlying valid file descriptor 00114 * failed. 00115 */ 00116 virtual bool close(); 00117 00118 /** 00119 * Return true iff last I/O operation timed out. 00120 * 00121 * \return true iff the last I/O operation timed out or 00122 * timedout(true) was called since the last I/O operation. 00123 */ 00124 bool timedout() const; 00125 00126 /** 00127 * Set timedout() flag. This flag can only be cleared explicitly by 00128 * fdstreambuf::timedout(false) or by fdstreambuf::fd(int). 00129 * 00130 * @param timed_out New value for timedout(). 00131 * @return true iff timedout status actually changed. It will 00132 * return false, e.g. if the argument is false but the 00133 * previous timedout status was not true. 00134 */ 00135 bool timedout(bool timed_out) const; 00136 00137 /** 00138 * Return last relevant ::errno as set by the system. 00139 * 00140 * \return The last relevant errno as aset by the system. 00141 */ 00142 int error() const { return errno_; } 00143 00144 /** 00145 * Return ::strerror(error()), a string representation of error(). 00146 * 00147 * \return A string representation of error(). 00148 */ 00149 std::string strerror() const; 00150 00151 /** 00152 * Set debug stream. If not null, trace info will be written to this 00153 * stream for all I/O operations. 00154 * 00155 * \param os Pointer to ostream or 0. In the latter case, no debug 00156 * information will be written. 00157 */ 00158 void debug(std::ostream* os) { debug_ = os; return; } 00159 00160 /** 00161 * Return pointer to current debug stream. 00162 * The function may return 0, if debugging is ``off''. 00163 * 00164 * \return A pointer to the current debug stream or 0. 00165 * 00166 * Debug output may be generated for the following member functions: 00167 * set_non_blocking(), error(int), read(), write(). 00168 */ 00169 std::ostream* debug() const { return debug_; } 00170 00171 /** 00172 * Check whether input or output on fd would block. 00173 * 00174 * \param fd file descriptor to check, none if -1 00175 * \param delay time (in millisecs) we are prepared to wait. If 00176 * <code>0</code>, <code>fdwait()</code> may block indefinitely. 00177 * \param syserrno will contain system's errno if return -1 00178 * \param output false if fd is checked for input 00179 * \return <code>1</code> if input/output is available; <code>0</code> 00180 * if a timeout occurred (in which case syserrno=ETIMEOUT) 00181 * and a value <code><0</code> if another error occurred, in which case 00182 * syserrno set to errno. 00183 * 00184 */ 00185 static int fdwait(int fd, time_t delay, int& syserrno, bool output=false); 00186 00187 /** 00188 * Override iostream::sync(), i.e. force all pending output to 00189 * be written using fdstreambuf::rwrite(). 00190 * 00191 * \return 0 if ok, -1 else. 00192 */ 00193 virtual int sync(); 00194 protected: 00195 /** 00196 * Override iostream::underflow(), i.e. attempt to fill the input 00197 * buffer using fdstreambuf::rread(). 00198 * 00199 * \return next input char or EOF. 00200 */ 00201 virtual int underflow(); 00202 00203 /** 00204 * Override iostream::overflow(). May call fdstreambuf::sync(). 00205 * 00206 * \return c if the character was succeffuly written or EOF. 00207 */ 00208 virtual int overflow(int c); 00209 00210 /** 00211 * Wait for I/O to become available. Wait for output or input, 00212 * depending on the value of the parameter. Sets error() 00213 * appropriately if return value is not 1. 00214 * 00215 * \param output Wait for output to be available if 00216 * \return 1 if input is available, 0 if a timeout occurred; -1 00217 * indicates an error condition (e.g. underlying fd not set). 00218 * \see fdwait 00219 */ 00220 int fdwait(bool output) const; 00221 00222 /** 00223 * Wait for I/O to become available. Wait for output or input, 00224 * depending on the value of the parameter. 00225 * 00226 * \param output Wait for output to be available if 00227 * \param syserrno System errorno (output variable). 00228 * \return 1 if input is available, 0 if a timeout occurred; -1 00229 * indicates an error condition (e.g. underlying fd not set). 00230 * \see fdwait 00231 */ 00232 int fdwait(bool output, int& syserrno) const; 00233 00234 /** 00235 * Wait for input to become available. Equivalent to fdwait(0). 00236 * 00237 * \return 1 if input is available, 0 if a timeout occurred; -1 00238 * indicates an error condition (e.g. underlying fd not set). 00239 */ 00240 int iwait() const { return fdwait(0); } 00241 00242 /** 00243 * Wait for output to become available. Equivalent to fdwait(0). 00244 * 00245 * \return 1 if input is available, 0 if a timeout occurred; -1 00246 * indicates an error condition (e.g. underlying fd not set). 00247 */ 00248 int owait() const { return fdwait(1); } 00249 00250 /** 00251 * Attempt an input operation. 00252 * 00253 * \param buf Buffer where characters read will be put. 00254 * \param buf_sz Number of characters to read. 00255 * \return number of chars read, 0 on EOF, -1 if timeout, 00256 * -2 if other error. 00257 * 00258 * On timeout, error() is set to ETIMEDOUT. 00259 * Input operations are retried if they were interrupted. 00260 * 00261 * \see error() 00262 */ 00263 virtual int read(char* buf,size_t buf_sz); 00264 00265 /** 00266 * Attempt an output operation. 00267 * \param buf Buffer containing characters to write. 00268 * \param buf_sz Number of characters to write from buf. 00269 * \return number of chars written, 0 on EOF, -1 if timeout, 00270 * -2 if other error. 00271 * On timeout, error() is set to ETIMEDOUT. 00272 * Output operations are retried if they were interrupted. 00273 * 00274 * \see error() 00275 */ 00276 virtual int write(char* buf,size_t buf_sz); 00277 00278 /** 00279 * Low level read function, default is ::read(fd(), buf, len); 00280 * may set error(). 00281 * Derived classes can override this function. 00282 * 00283 * \param buf Buffer where characters read will be put. 00284 * \param len Number of characters to read. 00285 * \return number of chars read, 0 on EOF, -1 on error. 00286 * 00287 * \see error() 00288 */ 00289 virtual int rread(char* buf,size_t len); 00290 00291 /** 00292 * Low level write function, default is ::write(fd(), buf, len); may 00293 * set error(). 00294 * Derived classes can override this function. 00295 * 00296 * \param buf Buffer containing characters to write. 00297 * \param len Number of characters to write from buf. 00298 * \return number of chars read, 0 means no chars were written. 00299 * On error, -1 is returned. 00300 * 00301 * \see error() 00302 */ 00303 virtual int rwrite(char* buf,size_t len); 00304 00305 /** 00306 * Translate ios::openmode flags to open(2) flags like O_RDWR etc. 00307 * 00308 * \param mode Stream open mode. 00309 * \return A combination of O_RDWR, O_CREAT, O_APPEND, O_WRONLY, 00310 * O_TRUNC, O_RDONLY. 00311 * 00312 * Currently, the function understands combinations with 00313 * ios::in, ios::out, ios::app, ios::trunc. 00314 */ 00315 static int flags(std::ios::openmode mode); 00316 00317 /** 00318 * Set error status of fdstreambuf. 00319 * 00320 * \param e new error code. 00321 * 00322 * \see fdstreambuf::error(). 00323 */ 00324 void error(int e) const; 00325 00326 private: 00327 fdstreambuf(const fdstreambuf&); 00328 fdstreambuf& operator=(const fdstreambuf&); 00329 /** 00330 * Underlying file descriptor, <0 if invalid. 00331 */ 00332 int fd_; 00333 /** 00334 * The number of millsecs to wait before an open or input operation 00335 * fails. A value of 0 means wait forever. 00336 */ 00337 time_t delay_; // timeout value, ==0 if infinite 00338 /** 00339 * Whether fd_ is non-blocking. 00340 */ 00341 bool non_blocking_; 00342 /** 00343 * Size of internal input buffer. 00344 */ 00345 size_t inbuf_sz_; 00346 /** 00347 * Size of internal output buffer. 00348 */ 00349 size_t outbuf_sz_; 00350 /** 00351 * Input buffer. 00352 */ 00353 char* inbuf_; 00354 /** 00355 * Output buffer. 00356 */ 00357 char* outbuf_; 00358 /** 00359 * Error status. A value of 0 means ok. Usually, the value of the 00360 * last ::errno as set by the system. 00361 */ 00362 mutable int errno_; 00363 /** 00364 * Error status. A value of 0 means ok. Usually, the value of the 00365 * last ::errno as set by the system. 00366 */ 00367 mutable bool timedout_; 00368 /** 00369 * Pointer to stream to which debug info is to be written. If 0, 00370 * no debug information is generated. 00371 */ 00372 std::ostream* debug_; 00373 00374 /** 00375 * Return string of the form ``fdstreambuf[fd]::function_name'' 00376 * 00377 * \param funname Name to put after ``::''. 00378 * \return A string of the form ``fdstreambuf[fd]::function_name'' 00379 * where fd is value of fd(). 00380 */ 00381 std::string debug_header(const std::string& funname) const; 00382 }; 00383 00384 }} 00385 #endif

dvutil-0.13.15 [30 December, 2004]