(recvline): Rewrite the loop to receive a line from a socket. The new
authorMarkus Armbruster <armbru@pond.sub.org>
Fri, 14 Dec 2007 07:26:30 +0000 (07:26 +0000)
committerMarkus Armbruster <armbru@pond.sub.org>
Fri, 14 Dec 2007 07:26:30 +0000 (07:26 +0000)
version silently truncates long lines.  The old one split them up and
got quite confused.  It got also confused when the line didn't arrive
in one piece.  Icing on the cake: it wrote beyond the end of the
buffer.  The new version is less efficient, but that doesn't matter
here.

src/client/expect.c

index b681668a6fcd43b6ae93bbdad07eb990246ddfee..7e27b515df39e9b4c37ea2eba81055c3e604f941 100644 (file)
@@ -29,6 +29,7 @@
  * 
  *  Known contributors to this file:
  *      Steve McClure, 1998
+ *      Markus Armbruster, 2007
  */
 
 #include <config.h>
@@ -46,8 +47,6 @@
 #include "misc.h"
 
 #ifdef _WIN32
-#define recv(sock, buffer, buf_size, flags) \
-       w32_recv((sock), (buffer), (buf_size), (flags))
 #define read(sock, buffer, buf_size) \
        w32_recv((sock), (buffer), (buf_size), 0)
 #define write(sock, buffer, buf_size) \
 int
 recvline(int s, char *buf)
 {
-    int size;
-    char *p;
-    int n;
-    int newline;
-    char *ptr;
-    int cc;
+    int sz = 1024;
+    char *bp;
+    char ch;
+    ssize_t n;
 
-    size = 1024;
-    ptr = buf;
-    n = recv(s, ptr, size, MSG_PEEK);
-    if (n <= 0) {
-       perror("recv");
-       return 0;
-    }
-    size -= n;
-    buf[n] = '\0';
-    if ((p = strchr(ptr, '\n')) == NULL) {
-       do {
-           cc = read(s, ptr, n);
-           if (cc < 0) {
-               perror("expect: read");
-               return 0;
-           }
-           if (cc != n) {
-               fprintf(stderr, "expect: short read (%d not %d)\n", cc, n);
-               return 0;
-           }
-           ptr += n;
-           if ((n = recv(s, ptr, size, MSG_PEEK)) <= 0) {
-               perror("recv");
-               return 0;
+    bp = buf;
+    for (;;) {
+       n = read(s, &ch, 1);
+       if (n < 0) {
+           if (errno != EINTR) {
+               perror("read");
+               exit(1);
            }
-           size -= n;
-           ptr[n] = '\0';
-       } while ((p = strchr(ptr, '\n')) == 0);
-       newline = 1 + p - buf;
-       *p = 0;
-    } else
-       newline = 1 + p - ptr;
-    cc = read(s, buf, newline);
-    if (cc < 0) {
-       perror("expect: read #2");
-       return 0;
-    }
-    if (cc != newline) {
-       fprintf(stderr, "expect: short read #2 (%d not %d)\n",
-               cc, newline);
-       return 0;
+           continue;
+       }
+       if (n == 0)
+           return -1;
+       if (ch == '\n')
+           break;
+       if (bp < buf + sz - 2)
+           *bp++ = ch;
+       /* else silently truncate */
     }
-    buf[newline] = '\0';
+
+    *bp++ = ch;
+    *bp = 0;
+
     if (!isxdigit(buf[0]) || buf[1] != ' ') {
        fprintf(stderr, "Malformed line %s\n", buf);
        return 0;