summaryrefslogtreecommitdiffstats
path: root/imap-2007e-poll.patch
diff options
context:
space:
mode:
Diffstat (limited to 'imap-2007e-poll.patch')
-rw-r--r--imap-2007e-poll.patch192
1 files changed, 192 insertions, 0 deletions
diff --git a/imap-2007e-poll.patch b/imap-2007e-poll.patch
new file mode 100644
index 0000000..e25f1b6
--- /dev/null
+++ b/imap-2007e-poll.patch
@@ -0,0 +1,192 @@
+http://anonscm.debian.org/cgit/collab-maint/uw-imap.git/plain/debian/patches/1005_poll.patch
+
+Description: Use poll(2) instead of select(2) to support more than 1024 file descriptors
+Author: Ben Smithurst <ben.smithurst@gradwell.com>
+Bug-Debian: https://bugs.debian.org/478193
+
+diff --git a/src/osdep/unix/os_lnx.c b/src/osdep/unix/os_lnx.c
+index 03fd17d..671bbd6 100644
+--- a/src/osdep/unix/os_lnx.c
++++ b/src/osdep/unix/os_lnx.c
+@@ -41,6 +41,7 @@
+ extern int errno; /* just in case */
+ #include <pwd.h>
+ #include "misc.h"
++#include <poll.h>
+
+
+ #include "fs_unix.c"
+diff --git a/src/osdep/unix/os_slx.c b/src/osdep/unix/os_slx.c
+index c94d632..f6bf27d 100644
+--- a/src/osdep/unix/os_slx.c
++++ b/src/osdep/unix/os_slx.c
+@@ -42,6 +42,7 @@ extern int errno; /* just in case */
+ #include <pwd.h>
+ #include <shadow.h>
+ #include "misc.h"
++#include <poll.h>
+
+
+ #include "fs_unix.c"
+diff --git a/src/osdep/unix/tcp_unix.c b/src/osdep/unix/tcp_unix.c
+index 795fb4f..c69eaec 100644
+--- a/src/osdep/unix/tcp_unix.c
++++ b/src/osdep/unix/tcp_unix.c
+@@ -235,12 +235,11 @@ TCPSTREAM *tcp_open (char *host,char *service,unsigned long port)
+ int tcp_socket_open (int family,void *adr,size_t adrlen,unsigned short port,
+ char *tmp,int *ctr,char *hst)
+ {
+- int i,ti,sock,flgs;
++ int i,ti,sock,flgs,tmo;
++ struct pollfd pfd;
+ size_t len;
+ time_t now;
+ struct protoent *pt = getprotobyname ("tcp");
+- fd_set rfds,wfds,efds;
+- struct timeval tmo;
+ struct sockaddr *sadr = ip_sockaddr (family,adr,adrlen,port,&len);
+ blocknotify_t bn = (blocknotify_t) mail_parameters (NIL,GET_BLOCKNOTIFY,NIL);
+ /* fetid Solaris */
+@@ -252,14 +251,6 @@ int tcp_socket_open (int family,void *adr,size_t adrlen,unsigned short port,
+ sprintf (tmp,"Unable to create TCP socket: %s",strerror (errno));
+ (*bn) (BLOCK_NONSENSITIVE,data);
+ }
+- else if (sock >= FD_SETSIZE) {/* unselectable sockets are useless */
+- sprintf (tmp,"Unable to create selectable TCP socket (%d >= %d)",
+- sock,FD_SETSIZE);
+- (*bn) (BLOCK_NONSENSITIVE,data);
+- close (sock);
+- sock = -1;
+- errno = EMFILE;
+- }
+
+ else { /* get current socket flags */
+ flgs = fcntl (sock,F_GETFL,0);
+@@ -284,16 +275,11 @@ int tcp_socket_open (int family,void *adr,size_t adrlen,unsigned short port,
+ if ((sock >= 0) && ctr) { /* want open timeout? */
+ now = time (0); /* open timeout */
+ ti = ttmo_open ? now + ttmo_open : 0;
+- tmo.tv_usec = 0;
+- FD_ZERO (&rfds); /* initialize selection vector */
+- FD_ZERO (&wfds); /* initialize selection vector */
+- FD_ZERO (&efds); /* handle errors too */
+- FD_SET (sock,&rfds); /* block for error or readable or writable */
+- FD_SET (sock,&wfds);
+- FD_SET (sock,&efds);
++ pfd.fd = sock;
++ pfd.events = POLLIN | POLLOUT;
+ do { /* block under timeout */
+- tmo.tv_sec = ti ? ti - now : 0;
+- i = select (sock+1,&rfds,&wfds,&efds,ti ? &tmo : NIL);
++ tmo = ti ? ti - now : 0;
++ i = poll (&pfd, 1, ti ? tmo * 1000 : -1);
+ now = time (0); /* fake timeout if interrupt & time expired */
+ if ((i < 0) && (errno == EINTR) && ti && (ti <= now)) i = 0;
+ } while ((i < 0) && (errno == EINTR));
+@@ -302,7 +288,7 @@ int tcp_socket_open (int family,void *adr,size_t adrlen,unsigned short port,
+ fcntl (sock,F_SETFL,flgs);
+ /* This used to be a zero-byte read(), but that crashes Solaris */
+ /* get socket status */
+- if(FD_ISSET(sock, &rfds)) while (((i = *ctr = read (sock,tmp,1)) < 0) && (errno == EINTR));
++ if(pfd.revents & POLLIN) while (((i = *ctr = read (sock,tmp,1)) < 0) && (errno == EINTR));
+ }
+ if (i <= 0) { /* timeout or error? */
+ i = i ? errno : ETIMEDOUT;/* determine error code */
+@@ -545,9 +531,8 @@ long tcp_getbuffer (TCPSTREAM *stream,unsigned long size,char *s)
+ stream->ictr -=n;
+ }
+ if (size) {
+- int i;
+- fd_set fds,efds;
+- struct timeval tmo;
++ int i, tmo;
++ struct pollfd pfd;
+ time_t t = time (0);
+ blocknotify_t bn=(blocknotify_t) mail_parameters (NIL,GET_BLOCKNOTIFY,NIL);
+ (*bn) (BLOCK_TCPREAD,NIL);
+@@ -556,16 +541,13 @@ long tcp_getbuffer (TCPSTREAM *stream,unsigned long size,char *s)
+ time_t now = tl;
+ time_t ti = ttmo_read ? now + ttmo_read : 0;
+ if (tcpdebug) mm_log ("Reading TCP buffer",TCPDEBUG);
+- tmo.tv_usec = 0;
+- FD_ZERO (&fds); /* initialize selection vector */
+- FD_ZERO (&efds); /* handle errors too */
+- /* set bit in selection vectors */
+- FD_SET (stream->tcpsi,&fds);
+- FD_SET (stream->tcpsi,&efds);
++
++ pfd.events = POLLIN;
++ pfd.fd = stream->tcpsi;
+ errno = NIL; /* initially no error */
+ do { /* block under timeout */
+- tmo.tv_sec = ti ? ti - now : 0;
+- i = select (stream->tcpsi+1,&fds,NIL,&efds,ti ? &tmo : NIL);
++ tmo = ti ? ti - now : 0;
++ i = poll (&pfd, 1, ti ? tmo * 1000 : -1);
+ now = time (0); /* fake timeout if interrupt & time expired */
+ if ((i < 0) && (errno == EINTR) && ti && (ti <= now)) i = 0;
+ } while ((i < 0) && (errno == EINTR));
+@@ -605,9 +587,8 @@ long tcp_getbuffer (TCPSTREAM *stream,unsigned long size,char *s)
+
+ long tcp_getdata (TCPSTREAM *stream)
+ {
+- int i;
+- fd_set fds,efds;
+- struct timeval tmo;
++ int i, tmo;
++ struct pollfd pfd;
+ time_t t = time (0);
+ blocknotify_t bn = (blocknotify_t) mail_parameters (NIL,GET_BLOCKNOTIFY,NIL);
+ if (stream->tcpsi < 0) return NIL;
+@@ -617,15 +598,12 @@ long tcp_getdata (TCPSTREAM *stream)
+ time_t now = tl;
+ time_t ti = ttmo_read ? now + ttmo_read : 0;
+ if (tcpdebug) mm_log ("Reading TCP data",TCPDEBUG);
+- tmo.tv_usec = 0;
+- FD_ZERO (&fds); /* initialize selection vector */
+- FD_ZERO (&efds); /* handle errors too */
+- FD_SET (stream->tcpsi,&fds);/* set bit in selection vectors */
+- FD_SET (stream->tcpsi,&efds);
++ pfd.fd = stream->tcpsi;
++ pfd.events = POLLIN;
+ errno = NIL; /* initially no error */
+ do { /* block under timeout */
+- tmo.tv_sec = ti ? ti - now : 0;
+- i = select (stream->tcpsi+1,&fds,NIL,&efds,ti ? &tmo : NIL);
++ tmo = ti ? ti - now : 0;
++ i = poll (&pfd, 1, ti ? tmo * 1000 : -1);
+ now = time (0); /* fake timeout if interrupt & time expired */
+ if ((i < 0) && (errno == EINTR) && ti && (ti <= now)) i = 0;
+ } while ((i < 0) && (errno == EINTR));
+@@ -677,9 +655,8 @@ long tcp_soutr (TCPSTREAM *stream,char *string)
+
+ long tcp_sout (TCPSTREAM *stream,char *string,unsigned long size)
+ {
+- int i;
+- fd_set fds,efds;
+- struct timeval tmo;
++ int i, tmo;
++ struct pollfd pfd;
+ time_t t = time (0);
+ blocknotify_t bn = (blocknotify_t) mail_parameters (NIL,GET_BLOCKNOTIFY,NIL);
+ if (stream->tcpso < 0) return NIL;
+@@ -689,15 +666,12 @@ long tcp_sout (TCPSTREAM *stream,char *string,unsigned long size)
+ time_t now = tl;
+ time_t ti = ttmo_write ? now + ttmo_write : 0;
+ if (tcpdebug) mm_log ("Writing to TCP",TCPDEBUG);
+- tmo.tv_usec = 0;
+- FD_ZERO (&fds); /* initialize selection vector */
+- FD_ZERO (&efds); /* handle errors too */
+- FD_SET (stream->tcpso,&fds);/* set bit in selection vector */
+- FD_SET(stream->tcpso,&efds);/* set bit in error selection vector */
++ pfd.fd = stream->tcpso;
++ pfd.events = POLLOUT;
+ errno = NIL; /* block and write */
+ do { /* block under timeout */
+- tmo.tv_sec = ti ? ti - now : 0;
+- i = select (stream->tcpso+1,NIL,&fds,&efds,ti ? &tmo : NIL);
++ tmo = ti ? ti - now : 0;
++ i = poll (&pfd, 1, ti ? tmo * 1000 : -1);
+ now = time (0); /* fake timeout if interrupt & time expired */
+ if ((i < 0) && (errno == EINTR) && ti && (ti <= now)) i = 0;
+ } while ((i < 0) && (errno == EINTR));