Nonblocking sockets need to select while writing
authorWilfried Goesgens <dothebart@citadel.org>
Sat, 6 Nov 2010 11:18:23 +0000 (12:18 +0100)
committerWilfried Goesgens <dothebart@citadel.org>
Sun, 21 Nov 2010 15:43:46 +0000 (16:43 +0100)
 we changed the SMTP outbound connections to be nonblocking so we could abort on not reacting SMTP-Servers.
 thus we need to select before writing, else the connection will fail.

citadel/clientsocket.c

index 380a4c6254e7f911773b9af408ad495447f17f74..91094aa8a615295006c8d49da6addd7db698b5d1 100644 (file)
@@ -266,12 +266,40 @@ INLINE int sock_read(int *sock, char *buf, int bytes, int keep_reading_until_ful
  */
 int sock_write(int *sock, const char *buf, int nbytes)
 {
+       int nSuccessLess = 0;
        int bytes_written = 0;
        int retval;
-
-       while ((*sock != -1)  && 
-              (bytes_written < nbytes))
+       fd_set rfds;
+        int fdflags;
+       int IsNonBlock;
+       int timeout = 50;
+       struct timeval tv;
+       int selectresolution = 100;
+
+       fdflags = fcntl(*sock, F_GETFL);
+       IsNonBlock = (fdflags & O_NONBLOCK) == O_NONBLOCK;
+
+       while ((nSuccessLess < timeout) && 
+              (*sock != -1) && 
+              (bytes_written < nbytes)) 
        {
+               if (IsNonBlock){
+                       tv.tv_sec = selectresolution;
+                       tv.tv_usec = 0;
+                       
+                       FD_ZERO(&rfds);
+                       FD_SET(*sock, &rfds);
+                       if (select(*sock + 1, NULL, &rfds, NULL, &tv) == -1) {
+///                            *Error = strerror(errno);
+                               close (*sock);
+                               *sock = -1;
+                               return -1;
+                       }
+               }
+               if (IsNonBlock && !  FD_ISSET(*sock, &rfds)) {
+                       nSuccessLess ++;
+                       continue;
+               }
                retval = write(*sock, &buf[bytes_written],
                               nbytes - bytes_written);
                if (retval < 1) {