summaryrefslogtreecommitdiffstats
path: root/imap-2007e-poll.patch
blob: e25f1b68898165c5b3ae1486c39c435e7e4195ff (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
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));