Package: uw-imap / 8:2007f~dfsg-7

1005_poll.patch Patch series | download
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
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
Description: Use poll(2) instead of select(2) to support more than 1024 file descriptors
Author: Ben Smithurst <ben.smithurst@gradwell.com>
Author: David Duncan Ross Palmer <david.palmer@gradwell.com>
Bug-Debian: https://bugs.debian.org/478193
Bug-Debian: https://bugs.debian.org/770022

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));
--- uw-imap.orig/src/osdep/unix/ssl_unix.c	2014-06-04 15:34:16.000000000 +0100
+++ uw-imap/src/osdep/unix/ssl_unix.c	2014-06-04 15:34:21.000000000 +0100
@@ -472,16 +472,14 @@
 
 long ssl_getdata (SSLSTREAM *stream)
 {
-  int i,sock;
-  fd_set fds,efds;
-  struct timeval tmo;
+  int i,sock,tmo;
+  struct pollfd pfd;
   tcptimeout_t tmoh = (tcptimeout_t) mail_parameters (NIL,GET_TIMEOUT,NIL);
   long ttmo_read = (long) mail_parameters (NIL,GET_READTIMEOUT,NIL);
   time_t t = time (0);
   blocknotify_t bn = (blocknotify_t) mail_parameters (NIL,GET_BLOCKNOTIFY,NIL);
   if (!stream->con || ((sock = SSL_get_fd (stream->con)) < 0)) return NIL;
 				/* tcp_unix should have prevented this */
-  if (sock >= FD_SETSIZE) fatal ("unselectable socket in ssl_getdata()");
   (*bn) (BLOCK_TCPREAD,NIL);
   while (stream->ictr < 1) {	/* if nothing in the buffer */
     time_t tl = time (0);	/* start of request */
@@ -490,15 +488,12 @@
     if (SSL_pending (stream->con)) i = 1;
     else {
       if (tcpdebug) mm_log ("Reading SSL data",TCPDEBUG);
-      tmo.tv_usec = 0;
-      FD_ZERO (&fds);		/* initialize selection vector */
-      FD_ZERO (&efds);		/* handle errors too */
-      FD_SET (sock,&fds);	/* set bit in selection vector */
-      FD_SET (sock,&efds);	/* set bit in error selection vector */
+      pfd.fd = sock;
+      pfd.events = POLLIN;
       errno = NIL;		/* block and read */
       do {			/* block under timeout */
-	tmo.tv_sec = ti ? ti - now : 0;
-	i = select (sock+1,&fds,0,&efds,ti ? &tmo : 0);
+	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));