Date: Sun, 17 Dec 1995 02:52:29 +1100 From: danjo@blitzen.canberra.edu.au To: FreeBSD-gnats-submit@freebsd.org Subject: misc/898: bug? Message-ID: <199512161552.CAA05399@eyerot.canberra.edu.au> Resent-Message-ID: <199512170920.BAA09845@freefall.freebsd.org>
next in thread | raw e-mail | index | archive | help
>Number: 898 >Category: misc >Synopsis: select() not detecting socket close under certain circumstances >Confidential: no >Severity: non-critical >Priority: medium >Responsible: freebsd-bugs >State: open >Class: sw-bug >Submitter-Id: current-users >Arrival-Date: Sun Dec 17 01:20:06 PST 1995 >Last-Modified: >Originator: Danny Gasparovski >Organization: >Release: FreeBSD 2.1-STABLE i386 >Environment: Running 2.1 RELEASE, no idea if other releases are affected >Description: If a process opens a socket, sheds it's controlling terminal, then closes the socket, the other end will not (with select()) detect that the socket has closed. >How-To-Repeat: Here is the source of a test program, t1.c: #include <stdlib.h> #include <stdio.h> #include <sys/types.h> #include <sys/socket.h> #include <netinet/in.h> extern int errno; #undef SPAM main() { struct sockaddr_in addr; int addrlen = sizeof(addr); int s; s = socket(AF_INET, SOCK_STREAM, 0); addr.sin_family = AF_INET; addr.sin_addr.s_addr = INADDR_ANY; addr.sin_port = htons(6666); if (bind(s, (struct sockaddr *)&addr, sizeof(addr)) != 0) { fprintf(stderr, "bind() failed: %s\n", strerror(errno)); exit(1); } listen(s, 1); s = accept(s, (struct sockaddr *)&addr, &addrlen); sleep(5); #ifdef SPAM if (fork()) exit(0); setsid(); if (fork()) { wait(&s); exit(0); } setpgid(0, 0); #endif close(s); /* t2 should exit now */ sleep(5); exit(0); } Here is the source of t2.c: #include <stdlib.h> #include <stdio.h> #include <sys/types.h> #include <sys/socket.h> #include <sys/time.h> #include <unistd.h> #include <netinet/in.h> main() { struct sockaddr_in addr; fd_set r; int s; char *buf[256]; time_t t; time(&t); s = socket(AF_INET, SOCK_STREAM, 0); addr.sin_family = AF_INET; addr.sin_addr.s_addr = inet_addr("127.0.0.1"); addr.sin_port = htons(6666); connect(s, (struct sockaddr *)&addr, sizeof(addr)); while (1) { FD_ZERO(&r); FD_SET(s, &r); select(s+1, &r, (fd_set *)0, (fd_set *)0, (struct timeval *)0); if (FD_ISSET(s, &r)) { if (read(s, buf, 256) == 0) { fprintf(stderr, "Time difference: %d\n", time((time_t *)0) - t); exit(0); } } } } Now, if you undefine SPAM in t1.c and compile/run it, then compile/run t2.c, t2 should exit when t1 does a close() on the socket. However, if you #define SPAM in t1.c, compile/run it, and then run t2, t2 will NOT exit when t1 issues the close() on the socket. With SPAM undefined, t2 will report a 5 second wait, with SPAM defined it will report a 10 second wait. >Fix: I have no idea. >Audit-Trail: >Unformatted:
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?199512161552.CAA05399>