[xiph-cvs] bug in socket library

Brendan Cully brendan at xiph.org
Wed May 28 15:46:55 PDT 2003


Mike (and CVS watchers),

Karl and I stumbled across a bug in the net module today: sock_write
and sock_write_string may produce short writes when the underlying
socket is non-blocking. This is contrary to the comments in the code
and the expectations in libshout. I've attached a patch for your
review, and because I'm not sure what expectations icecast may have
about these functions. As far as I can tell this has been broken for a
long long time.

Comments? Should I commit?

-b
-------------- next part --------------
? sock.c.diff
Index: sock.c
===================================================================
RCS file: /usr/local/cvsroot/net/sock.c,v
retrieving revision 1.21
diff -u -p -r1.21 sock.c
--- sock.c	8 Apr 2003 12:09:57 -0000	1.21
+++ sock.c	28 May 2003 22:40:05 -0000
@@ -1,3 +1,4 @@
+/* -*- c-basic-offset: 4; -*- */
 /* sock.c
  * - General Socket Functions
  *
@@ -297,7 +298,27 @@ int sock_write_bytes(sock_t sock, const 
 */
 int sock_write_string(sock_t sock, const char *buff)
 {
-    return (sock_write_bytes(sock, buff, strlen(buff)) > 0);
+    int len, sent, rc;
+    fd_set wfds;
+
+    len = strlen(buff);
+    sent = rc = sock_write_bytes(sock, buff, len);
+    if ((rc < 0 && errno != EAGAIN) || sent == len)
+	return (sent < len ? -1 : sent);
+
+    FD_ZERO(&wfds);
+    FD_SET(sock, &wfds);
+
+    do {
+	if (select(sock + 1, NULL, &wfds, NULL, NULL) < 0)
+	    break;
+
+	rc = sock_write_bytes(sock, buff + sent, len - sent);
+	if (rc > 0)
+	    sent += rc;
+    } while (sent < len && (rc >= 0 || errno == EAGAIN));
+
+    return (sent < len ? -1 : sent);
 }
 
 /* sock_write
@@ -314,8 +335,8 @@ int sock_write(sock_t sock, const char *
     va_start(ap, fmt);
     vsnprintf(buff, 1024, fmt, ap);
     va_end(ap);
-    
-    return sock_write_bytes(sock, buff, strlen(buff));
+
+    return sock_write_string(sock, buff);
 }
 
 int sock_write_fmt(sock_t sock, char *fmt, va_list ap)



More information about the commits mailing list