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>
Sat, 6 Nov 2010 11:18:23 +0000 (12:18 +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 49dee67b222d472886705ec1aa12ad6c1d314111..159ec72125728f1ed8004d7c8712dcbbe3924d88 100644 (file)
@@ -231,10 +231,40 @@ INLINE int sock_read(int *sock, char *buf, int bytes,
  */
 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) {