[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