Mail Archives: cygwin/2002/01/27/00:01:54
--=====================_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:
<snip, long example>
>> Any thoughts?
>
>Not immediately. Two questions:
>
<snip, already answered>
>- 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 <stdio.h>
#include <errno.h>
#include <string.h>
#include <stdlib.h>
#include <sys/socket.h>
#include <sys/wait.h>
#include <signal.h>
#include <netinet/in.h>
#include <unistd.h>
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==_--
- Raw text -