

![]() | Start a set with this search |
![]() | Include this search in one of my sets |
![]() | Exclude this search from one of my sets |
![]() | Permalink to these results Paste this link in email or IM: |
| Atom feed for tracking future search results Paste this URL into your reader: |
1 message in net.sourceforge.lists.courier-users[courier-users] [PATCH] read/write ti...| From | Sent On | Attachments |
|---|---|---|
| Johnny C. Lam | Oct 23, 2007 3:11 pm |

![]() | Permalink for this message Paste this link in email or IM: |
![]() | Permalink for this thread Paste this link in email or IM: |
| Atom feed for this thread Paste this URL into your reader: |
| Subject: | [courier-users] [PATCH] read/write timeouts for afxiopipestream objects | Actions... |
|---|---|---|
| From: | Johnny C. Lam (jlam...@buildlink.org) | |
| Date: | Oct 23, 2007 3:11:53 pm | |
| List: | net.sourceforge.lists.courier-users | |
The following patch against HEAD allows one to specify timeouts for the reads and writes performed by afxiopipestream objects. I use this to catch long delays when reading or writing data from an afxiopipestream object bound to a socket file descriptor. The default behavior is the current behavior with "infinite" (actually system-specific) timeouts. The changes to afx.h are source-compatible, so existing code that uses afxiopipestream objects does not need to be changed.
As an aside, the afxiopipestream class is very nice to use. It allows binding a stream to a file descriptor and manages the buffering automatically. The only extra thing I needed was a way to time-out the reads and writes to the file descriptor, which the attached patch provides.
Cheers,
-- Johnny C. Lam
diff -ur afx/afx.h /home/jlam/milter/afx/afx.h --- afx/afx.h Mon Jul 30 00:25:53 2007 +++ /home/jlam/milter/afx/afx.h Tue Oct 23 22:02:51 2007 @@ -8,6 +8,9 @@
#include "afx/config.h"
+#if HAVE_SYS_TYPES_H +#include <sys/types.h> +#endif #if HAVE_UNISTD_H #include <unistd.h> #endif @@ -26,12 +29,15 @@ class afxpipestreambuf : public std::streambuf { int fd; char buffer[8192]; + time_t read_timeout; + time_t write_timeout;
public: + enum timeout_value { TIMEOUT_INF = 0 };
std::ios *iosp;
- afxpipestreambuf(int); + afxpipestreambuf(int, time_t = TIMEOUT_INF, time_t = TIMEOUT_INF); ~afxpipestreambuf(); void close(); void seekg(std::streampos); @@ -47,7 +53,9 @@ class afxipipestream : public std::istream { afxpipestreambuf fd_; public: - afxipipestream(int = -1); + enum timeout_value { TIMEOUT_INF = afxpipestreambuf::TIMEOUT_INF }; + + afxipipestream(int = -1, time_t = TIMEOUT_INF); ~afxipipestream();
void close() { fd_.close(); } @@ -61,7 +69,9 @@ class afxopipestream: public std::ostream { afxpipestreambuf fd_; public: - afxopipestream(int = -1); + enum timeout_value { TIMEOUT_INF = afxpipestreambuf::TIMEOUT_INF }; + + afxopipestream(int = -1, time_t = TIMEOUT_INF); ~afxopipestream(); void close() { fd_.close(); } void seekg(std::streampos p) { fd_.seekg(p); } @@ -74,7 +84,9 @@ class afxiopipestream: public std::iostream { afxpipestreambuf fd_; public: - afxiopipestream(int = -1); + enum timeout_value { TIMEOUT_INF = afxpipestreambuf::TIMEOUT_INF }; + + afxiopipestream(int = -1, time_t = TIMEOUT_INF, time_t = TIMEOUT_INF); ~afxiopipestream(); void close() { fd_.close(); } void seekg(std::streampos p) { fd_.seekg(p); } diff -ur afx/afxpipe.C /home/jlam/milter/afx/afxpipe.C --- afx/afxpipe.C Sun Aug 5 20:00:33 2001 +++ /home/jlam/milter/afx/afxpipe.C Tue Oct 23 22:06:57 2007 @@ -4,10 +4,68 @@ */
#include "afx.h" +#include <errno.h> +#if HAVE_SYS_TIME_H +#include <sys/time.h> +#endif +#if HAVE_SYS_SELECT_H +#include <sys/select.h> +#endif
static const char rcsid[]="$Id: afxpipe.C,v 2.1 2001/08/05 20:00:33 mrsam Exp
$";
-afxpipestreambuf::afxpipestreambuf(int f) : fd(f), iosp(0) +static int fd_timeout(int fd, time_t timeout, int read) +{ + fd_set readfds, writefds; + + FD_ZERO(&readfds); + FD_ZERO(&writefds); + if (read) + FD_SET(fd, &readfds); + else + FD_SET(fd, &writefds); + + struct timeval tv, *tvp=0; + + if (timeout != afxpipestreambuf::TIMEOUT_INF) + { + tv.tv_sec=timeout; + tv.tv_usec=0; + tvp=&tv; + } + + for (;;) + { + int rv=select(fd+1, &readfds, &writefds, 0, tvp); + + if (rv > 0) + { + if (read) + { + if (!FD_ISSET(fd, &readfds)) + return (-1); + } + else + { + if (!FD_ISSET(fd, &writefds)) + return (-1); + } + return (0); + } + else if (rv == 0) + return (-1); + else if (rv < 0) + { + if (errno == EINTR) + continue; + else + return (-1); + } + } +} + +afxpipestreambuf::afxpipestreambuf(int f, time_t rto, time_t wto) + : fd(f), read_timeout(rto), write_timeout(wto), iosp(0) { }
@@ -66,6 +124,10 @@
while (p < e) { + if (write_timeout != TIMEOUT_INF && + fd_timeout(fd, write_timeout, 0) < 0) + return (-1); + int n=::write(fd, p, e-p);
if (n <= 0 && iosp) @@ -86,7 +148,9 @@ int n;
if (fd < 0) - return (-1); + return (-1); + if (read_timeout != TIMEOUT_INF && fd_timeout(fd, read_timeout, 1) < 0) + return (-1);
n=read(fd, buffer, sizeof(buffer));
@@ -101,7 +165,8 @@ return (sgetc()); }
-afxipipestream::afxipipestream(int f) : std::istream(&fd_), fd_(f) +afxipipestream::afxipipestream(int f, time_t rto) + : std::istream(&fd_), fd_(f, rto, TIMEOUT_INF) { fd_.iosp=this; } @@ -110,7 +175,8 @@ { }
-afxopipestream::afxopipestream(int f) : std::ostream(&fd_), fd_(f) +afxopipestream::afxopipestream(int f, time_t wto) + : std::ostream(&fd_), fd_(f, TIMEOUT_INF, wto) { fd_.iosp=this; } @@ -120,7 +186,8 @@ }
-afxiopipestream::afxiopipestream(int f) : std::iostream(&fd_), fd_(f) +afxiopipestream::afxiopipestream(int f, time_t rto, time_t wto) + : std::iostream(&fd_), fd_(f, rto, wto) { fd_.iosp=this; } diff -ur afx/configure.in /home/jlam/milter/afx/configure.in --- afx/configure.in Mon Jul 30 00:25:54 2007 +++ /home/jlam/milter/afx/configure.in Tue Oct 23 20:49:44 2007 @@ -27,7 +27,7 @@
dnl Checks for header files. AC_HEADER_STDC -AC_CHECK_HEADERS(unistd.h strings.h) +AC_CHECK_HEADERS(sys/time.h sys/select.h unistd.h strings.h)
dnl Checks for typedefs, structures, and compiler characteristics. AC_C_CONST diff -ur afx/testafxpipe.C /home/jlam/milter/afx/testafxpipe.C --- afx/testafxpipe.C Sun Aug 5 20:00:33 2001 +++ /home/jlam/milter/afx/testafxpipe.C Tue Oct 23 20:54:15 2007 @@ -12,8 +12,8 @@ int fd0=dup(0); int fd1=dup(1);
- afxipipestream i(fd0); - afxopipestream o(fd1); + afxipipestream i(fd0, 10); + afxopipestream o(fd1, 10);
int c;







