From owner-freebsd-hackers Fri Dec 6 16:54:51 1996 Return-Path: Received: (from root@localhost) by freefall.freebsd.org (8.8.4/8.8.4) id QAA21398 for hackers-outgoing; Fri, 6 Dec 1996 16:54:51 -0800 (PST) Received: from hemi.com (hemi.com [204.132.158.10]) by freefall.freebsd.org (8.8.4/8.8.4) with ESMTP id QAA21393 for ; Fri, 6 Dec 1996 16:54:49 -0800 (PST) Received: (from mbarkah@localhost) by hemi.com (8.8.3/8.7.3) id RAA12233 for hackers@freebsd.org; Fri, 6 Dec 1996 17:54:48 -0700 (MST) From: Ade Barkah Message-Id: <199612070054.RAA12233@hemi.com> Subject: bug in 2.2-alpha loopback (?) To: hackers@freebsd.org Date: Fri, 6 Dec 1996 17:54:48 -0700 (MST) X-Mailer: ELM [version 2.4 PL24] Content-Type: text Sender: owner-hackers@freebsd.org X-Loop: FreeBSD.org Precedence: bulk [Sorry if you got this twice, this is a resend, seems that the first one didn't get through] Hi, It seems that read() on a socket via the loopback interface does not return 0 ("EOF") when the socket is broken. Instead, it returns 1, with the data returned being '\004' (ctrl-D). This breaks various code which check return values with: if ((ret = read (....)) <= 0) /* error processing here */ since ret gets set to 1. (In my case, lex gets really confused.) For convenience, sample test code appended. It simply binds to port 2000 and waits for a connection. Telnet to localhost port 2000, hit ctrl-] and quit, and read the result (should return 0). Works fine in 2.1.x, breaks on 2.2-Alpha. Thanks, -Ade ps. sorry I don't know enough to make a bug-fix patch. ------------------------------------------------------------------- Inet: mbarkah@hemi.com - HEMISPHERE ONLINE - ------------------------------------------------------------------- --CUT HERE-- #include #include #include #include #include #include #include int main(void) { int c, s, fd, alen=1, ret, port = 2000, opval = 1; char buf[1024]; struct sockaddr_in sin, cin; bzero(&sin, sizeof(sin)); sin.sin_family = AF_INET; sin.sin_addr.s_addr = INADDR_ANY; sin.sin_port = htons((unsigned short) port); if ((s = socket(PF_INET, SOCK_STREAM, 0)) == -1) { perror("ERROR: Can't get socket"); exit(-1); } if (setsockopt(s, SOL_SOCKET, SO_REUSEADDR, (int *) &opval, sizeof(opval)) == -1) { perror("ERROR: Cannot set SO_REUSEADDR"); exit(-1); } if (setsockopt(s, SOL_SOCKET, SO_KEEPALIVE, (int *) &opval, sizeof(opval)) == -1) { perror("ERROR: Cannot set SO_KEEPALIVE"); exit(-1); } if (bind(s, (struct sockaddr *) & sin, sizeof(sin)) == -1) { perror("ERROR: Failed to bind"); return (-1); } if (listen(s, 3) == -1) { perror("ERROR: Can't listen()"); return (-1); } printf("Waiting for client on port %d\n", port); alen = sizeof(cin); fd = accept (s, (struct sockaddr *)&cin, &alen); ret = read(fd, buf, sizeof(buf)-1); printf("Attention, read() returned %d.\n", ret); if (ret > 10) ret = 10; for (c = 0; c < ret; c++) printf("[%d]", buf[c]); printf("\n"); } --CUT HERE--