| 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 |
| |
| --- 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" |
| --- 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" |
| --- a/src/osdep/unix/tcp_unix.c |
| +++ b/src/osdep/unix/tcp_unix.c |
| @@ -235,12 +235,11 @@ TCPSTREAM *tcp_open (char *host,char *se |
| 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 *ad |
| 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 *ad |
| 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 *ad |
| 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,un |
| 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,un |
| 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,un |
| |
| 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 * |
| |
| 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 *s |
| 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)); |