summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLars-Dominik Braun <PromyLOPh@lavabit.com>2010-08-04 16:17:14 +0200
committerLars-Dominik Braun <PromyLOPh@lavabit.com>2010-08-04 16:31:38 +0200
commit2269c74007cbae25875f76195fdc8d548da8f0ce (patch)
tree083baf0fdd86cf9ad19ed98c62ea9a56393c4e07
parenta3eabd6f1f78d9697b5bdc070fe87a5d2b4cca6c (diff)
downloadpianobar-2269c74007cbae25875f76195fdc8d548da8f0ce.tar.gz
pianobar-2269c74007cbae25875f76195fdc8d548da8f0ce.tar.bz2
pianobar-2269c74007cbae25875f76195fdc8d548da8f0ce.zip
socksify/tsocks support
-rw-r--r--libwaitress/src/waitress.c23
1 files changed, 20 insertions, 3 deletions
diff --git a/libwaitress/src/waitress.c b/libwaitress/src/waitress.c
index 8746ae0..27f7b3d 100644
--- a/libwaitress/src/waitress.c
+++ b/libwaitress/src/waitress.c
@@ -34,6 +34,7 @@ THE SOFTWARE.
#include <ctype.h>
#include <fcntl.h>
#include <poll.h>
+#include <errno.h>
#include "config.h"
#include "waitress.h"
@@ -225,6 +226,22 @@ WaitressReturn_t WaitressFetchBuf (WaitressHandle_t *waith, char **buf) {
return wRet;
}
+/* poll wrapper that retries after signal interrupts, required for socksify
+ * wrapper
+ */
+static int WaitressPollLoop (struct pollfd *fds, nfds_t nfds, int timeout) {
+ int pollres = -1;
+ int pollerr = 0;
+
+ do {
+ pollres = poll (fds, nfds, timeout);
+ pollerr = errno;
+ errno = 0;
+ } while (pollerr == EINTR || pollerr == EINPROGRESS || pollerr == EAGAIN);
+
+ return pollres;
+}
+
/* write () wrapper with poll () timeout
* @param socket fd
* @param write buffer
@@ -238,7 +255,7 @@ static WaitressReturn_t WaitressPollWrite (int sockfd, const char *buf, size_t c
int pollres = -1;
sockpoll->events = POLLOUT;
- pollres = poll (sockpoll, 1, timeout);
+ pollres = WaitressPollLoop (sockpoll, 1, timeout);
if (pollres == 0) {
return WAITRESS_RET_TIMEOUT;
} else if (pollres == -1) {
@@ -264,7 +281,7 @@ static WaitressReturn_t WaitressPollRead (int sockfd, char *buf, size_t count,
int pollres = -1;
sockpoll->events = POLLIN;
- pollres = poll (sockpoll, 1, timeout);
+ pollres = WaitressPollLoop (sockpoll, 1, timeout);
if (pollres == 0) {
return WAITRESS_RET_TIMEOUT;
} else if (pollres == -1) {
@@ -344,7 +361,7 @@ WaitressReturn_t WaitressFetchCall (WaitressHandle_t *waith) {
connect (sockfd, res->ai_addr, res->ai_addrlen);
sockpoll.events = POLLOUT;
- pollres = poll (&sockpoll, 1, waith->socktimeout);
+ pollres = WaitressPollLoop (&sockpoll, 1, waith->socktimeout);
freeaddrinfo (res);
if (pollres == 0) {
return WAITRESS_RET_TIMEOUT;