Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 6 Dec 1996 17:54:48 -0700 (MST)
From:      Ade Barkah <mbarkah@hemi.com>
To:        hackers@freebsd.org
Subject:   bug in 2.2-alpha loopback (?)
Message-ID:  <199612070054.RAA12233@hemi.com>

next in thread | raw e-mail | index | archive | help
[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 - <http://www.hemi.com/>;
-------------------------------------------------------------------

--CUT HERE--
#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <sys/param.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>

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--



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?199612070054.RAA12233>