Mailing-List: contact cygwin-help AT cygwin DOT com; run by ezmlm List-Subscribe: List-Archive: List-Post: List-Help: , Sender: cygwin-owner AT cygwin DOT com Delivered-To: mailing list cygwin AT cygwin DOT com Message-Id: <3.0.5.32.20020126235138.007e0630@pop.ne.mediaone.net> X-Sender: phumblet AT pop DOT ne DOT mediaone DOT net (Unverified) X-Mailer: QUALCOMM Windows Eudora Pro Version 3.0.5 (32) Date: Sat, 26 Jan 2002 23:51:38 -0500 To: Corinna Vinschen From: "Pierre A. Humblet" Subject: Re: socket/fdopen/exec problem Cc: cygwin In-Reply-To: <20020125171021.X11608@cygbert.vinschen.de> References: <3C517C32 DOT BB66DB47 AT ieee DOT org> <3C50520B DOT 3239FAC5 AT ieee DOT org> <20020124220339 DOT K11608 AT cygbert DOT vinschen DOT de> <3C5080F8 DOT 4E4B8945 AT ieee DOT org> <20020125105955 DOT P11608 AT cygbert DOT vinschen DOT de> <3C517C32 DOT BB66DB47 AT ieee DOT org> Mime-Version: 1.0 Content-Type: multipart/mixed; boundary="=====================_1012125098==_" --=====================_1012125098==_ Content-Type: text/plain; charset="us-ascii" At 05:10 PM 1/25/02 +0100, Corinna Vinschen wrote: >On Fri, Jan 25, 2002 at 10:39:30AM -0500, Pierre A. Humblet wrote: >> Any thoughts? > >Not immediately. Two questions: > >- Could you patch Cygwin fhandler_socket.cc, fhandler_socket::close() > and rip out the whole linger stuff so that only the naked closesocket() > call remains and see if that changes the behaviour? > Corinna, No difference (on Win98 and Me. I will try NT on Monday). I can now duplicate exactly what's happening in the application I am porting. A key element is that it disconnects itself from the controlling terminal by closing fd 0, 1 & 2 and forking. Weird things happen afterwards: 1) For every re-exec (triggered by -HUP), ps -W and the Windows task manager show an extra copy of the program. [without the disconnect from the controlling terminal, only one process appears] 2) If a tcp call was received and a child was forked, then after the next re-exec netstat -a shows an extra LISTEN on port 999. It never goes away. This happens even if the -HUP is given long after (I tried up to 5 minutes) the child terminates. Eventually incoming calls are not answered. [without the disconnect from the controlling terminal, an extra LISTEN appears only if the -HUP was given while the child is running, and it disappears when the child exits] I have no idea where to start debugging that. I am attaching the demo program. It is used as shown in the previous message, and also using ps -W. Ntsec good news: I think I have identified and solved the problem of having an incorrect UID, and also of setting the DACL in the token security descriptor. I will test on Monday and let you know. Pierre --=====================_1012125098==_ Content-Type: text/plain; charset="iso-8859-1" Content-Transfer-Encoding: quoted-printable Content-Disposition: attachment; filename="tcpdemo.c" /********************************************** * This demo program exposes a bug where there are to listen on the same tcp port. New connections may or may not be accepted= **********************************************/ #include #include #include #include #include #include #include #include #include enum {FALSE, TRUE}; /************************************************* * SIGHUP Handler = * *************************************************/ static int sighup_seen; static void sighup_handler(int sig) { sig =3D sig; /* Keep picky compilers happy */ sighup_seen =3D TRUE; signal(SIGHUP, sighup_handler); } main(int argc, char * argv[]) { int on =3D 1, sockfd, newsockfd, lcount, peer_size; int status, cpid, pid; struct sockaddr_in addr, peer; fd_set select_listen; FILE *fd; char msg[100]; // struct linger linger; // linger.l_onoff =3D 1; // linger.l_linger =3D 0; #if 1 close(0); close(1); close(2); pid =3D 0; if (getppid() !=3D 1) { /* not a re-exec */ unlink("demo.log"); /* old log */ pid =3D fork(); if (pid > 0) exit(EXIT_SUCCESS); /* in parent process, just exit */ // setsid(); } #endif fd =3D fopen("demo.log", "a"); if (pid < 0) { fprintf(fd, "Fork: %s\n", strerror(errno)); exit(1); } /************************************************ * Open a socket and listen on port 999 ************************************************/ sockfd =3D socket(AF_INET, SOCK_STREAM, 0); if (sockfd < 0) fprintf(fd, "socket: %s\n", strerror(errno)); if (setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)) <= 0) fprintf(fd, "setsockopt: %s\n", strerror(errno)); if (setsockopt(sockfd, SOL_SOCKET, TCP_NODELAY, &on, sizeof(on)) < 0) fprintf(fd, "setsockopt: %s\n", strerror(errno)); // if (setsockopt(sockfd, SOL_SOCKET, SO_LINGER, (const char *)&linger,= sizeof linger) < 0) // fprintf(fd, "setsockopt: %s\n", strerror(errno)); memset(&addr, 0, sizeof(addr)); addr.sin_family =3D AF_INET; addr.sin_port =3D htons(999); addr.sin_addr.s_addr =3D INADDR_ANY; if (bind(sockfd, (struct sockaddr *) &addr, sizeof(addr)) <= 0) fprintf(fd, "bind: %s\n", strerror(errno)); if (listen(sockfd, 10) < 0) fprintf(fd, "listen: %d %s\n", errno, strerror(errno)); sighup_seen =3D FALSE; signal(SIGHUP, sighup_handler); pid =3D getpid(); /************************************************ * Now wait for a call or sighup, causing a re-exec After a re-exec following a call, there are two listen on port 999 (netstat -a) Incoming calls may or may not work. ************************************************/ while(1) { FD_ZERO(&select_listen); FD_SET(sockfd, &select_listen); fprintf(fd, "looping pid %d\n", pid); lcount =3D select(sockfd + 1, &select_listen, NULL, NULL, NULL); if (lcount =3D=3D 1) { peer_size =3D sizeof(peer); newsockfd =3D accept(sockfd, (struct sockaddr *) &peer, &peer_size); if (newsockfd < 0) { fprintf(fd, "accept: %s\n", strerror(errno)); } else { fprintf(fd, "Got a call\n"); fflush(fd); if ((cpid =3D fork()) =3D=3D 0) { signal(SIGHUP, SIG_IGN); close(sockfd); sprintf(msg, "Hello world. Type kill -HUP %d\n", pid); write(newsockfd, msg, strlen(msg)); /* In this demo we sleep, in reality the child is working */ sleep(60); fprintf(fd, "Child exiting\n"); fclose(fd); close(newsockfd); exit(0); } else if (cpid > 0) { fprintf(fd, "Process %d started\n", cpid); close(newsockfd); } else fprintf(fd, "Fork %s\n", strerror(errno)); } } else if (sighup_seen =3D=3D TRUE) { fprintf(fd, "Sighup seen. Execing\n"); fclose(fd); close(sockfd); signal(SIGHUP, SIG_IGN); execv(argv[0], argv); } else fprintf(fd, "Select error %s\n", strerror(errno)); fflush(fd); } } --=====================_1012125098==_ Content-Type: text/plain; charset=us-ascii -- Unsubscribe info: http://cygwin.com/ml/#unsubscribe-simple Bug reporting: http://cygwin.com/bugs.html Documentation: http://cygwin.com/docs.html FAQ: http://cygwin.com/faq/ --=====================_1012125098==_--