From: Markus Armbruster Date: Fri, 14 Dec 2007 07:26:30 +0000 (+0000) Subject: (recvline): Rewrite the loop to receive a line from a socket. The new X-Git-Tag: v4.3.11~29 X-Git-Url: http://git.pond.sub.org/?p=empserver;a=commitdiff_plain;h=8cdf2532d42de683f41e9b1816484a62e1694867;ds=sidebyside (recvline): Rewrite the loop to receive a line from a socket. The new 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. --- diff --git a/src/client/expect.c b/src/client/expect.c index b681668a6..7e27b515d 100644 --- a/src/client/expect.c +++ b/src/client/expect.c @@ -29,6 +29,7 @@ * * Known contributors to this file: * Steve McClure, 1998 + * Markus Armbruster, 2007 */ #include @@ -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) \ @@ -57,56 +56,33 @@ 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;