]> git.sur5r.net Git - openldap/commitdiff
ITS#910, ITS#1983 retry partial writes in ber_pvt_sb_do_write
authorHoward Chu <hyc@openldap.org>
Thu, 1 Aug 2002 03:03:52 +0000 (03:03 +0000)
committerHoward Chu <hyc@openldap.org>
Thu, 1 Aug 2002 03:03:52 +0000 (03:03 +0000)
blind fix, needs testing

libraries/liblber/sockbuf.c

index ae5c07c8c1e4c28e1fba4bf370de5b3a203b185f..3d19c3a4f693125aa49fcc68bde948cfcafd6f8e 100644 (file)
@@ -288,7 +288,7 @@ ber_pvt_sb_copy_out( Sockbuf_Buf *sbb, char *buf, ber_len_t len )
 ber_slen_t
 ber_pvt_sb_do_write( Sockbuf_IO_Desc *sbiod, Sockbuf_Buf *buf_out )
 {
-       ber_len_t               to_go;
+       ber_len_t       to_go, done = 0;
        ber_slen_t ret;
 
        assert( sbiod != NULL );
@@ -300,24 +300,32 @@ ber_pvt_sb_do_write( Sockbuf_IO_Desc *sbiod, Sockbuf_Buf *buf_out )
        for(;;) {
                ret = LBER_SBIOD_WRITE_NEXT( sbiod, buf_out->buf_base +
                        buf_out->buf_ptr, to_go );
+               if ( ret < 0 ) {
+                       if (errno==EAGAIN
 #ifdef EINTR
-               if ((ret<0) && (errno==EINTR)) continue;
+                               || errno==EINTR
 #endif
-               break;
-       }
+                               ) continue;
 
-       if ( ret <= 0 ) return ret;
+                       return ret;
+               }
+
+               if ( ret == 0 ) return ret;
    
-       buf_out->buf_ptr += ret;
-       if (buf_out->buf_ptr == buf_out->buf_end) {
-               buf_out->buf_end = buf_out->buf_ptr = 0;
-       }
+               buf_out->buf_ptr += ret;
+               done += ret;
 
-       if ( (ber_len_t)ret < to_go ) {
-               /* not enough data, so pretend no data was sent. */
-               return -1;
+               if (buf_out->buf_ptr == buf_out->buf_end) {
+                       buf_out->buf_end = buf_out->buf_ptr = 0;
+                       ret = done;
+                       break;
+               } else if (buf_out->buf_ptr > buf_out->buf_end) {
+                       /* impossible */
+                       return -1;
+               } else {
+                       to_go -= ret;
+               }
        }
-
        return ret;
 }