This is the mail archive of the cygwin mailing list for the Cygwin project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: Bash process remains after I close rxvt in certain ways


[nothin' like resurrecting a month-old thread...]

Christopher Faylor wrote:

This is handled in dcrt0.cc:do_exit().  I'm wondering if rxvt is not
dealing with the SIGHUP that cygwin should be sending to it on
CTRL_CLOSE, though.

Well, rxvt *does* respond to SIGHUP:


$ ps -eaf # output snipped
 cwilson    3796       1 con  01:22:47 /usr/bin/rxvt
 cwilson     392    3796   3  01:22:47 /usr/bin/bash

$ kill -HUP 3796

$ ps -eaf # output snipped
 cwilson     392       1   3  01:22:47 /usr/bin/bash

but leaves behind a zombified bash. Further, because rxvt is compiled as a console app, Windows does not send a WM_CLOSE message when you press Alt-F4 or click the 'x' button: for console apps it sends a CTRL_CLOSE_EVENT, which is intercepted by cygwin and translated into SIGHUP -- so my discussion here:
http://cygwin.com/ml/cygwin/2006-11/msg00312.html
is not really germane, unless I recompile rxvt as a GUI app (however, doing that breaks usages with run.exe, so that's no good).



FWIW, rxvt during its initialization does the following:


...
# ifdef HAVE_SETSID
    setsid();
# endif
# if defined(HAVE_SETPGID)
    setpgid(0, 0);
# elif defined(HAVE_SETPGRP)
    setpgrp(0, 0);
# endif
...
followed by a bunch of stuff to set the controlling tty


I verified using strace that indeed, setsid() and setpgid() are called -- but they happen AFTER the fork(), in the child process that eventually execs bash:



/* spin off the command interpreter */ switch (r->h->cmd_pid = fork()) { case -1: rxvt_print_error("can't fork"); return -1; case 0: /* this is the child */ close(cfd); * only keep r->tty_fd and STDERR open */ close(r->Xfd);

[[[[[ rxvt_control_tty() is where setsid and setpgid are called ]]]]]

        if (rxvt_control_tty(r->tty_fd, r->h->ttydev) < 0)
            rxvt_print_error("could not obtain control of tty");
        else {
        /* Reopen stdin/out/err over the tty file descriptor */
            dup2(r->tty_fd, STDIN_FILENO);
            dup2(r->tty_fd, STDOUT_FILENO);
            dup2(r->tty_fd, STDERR_FILENO);
            if (r->tty_fd > 2)
                close(r->tty_fd);
            rxvt_run_child(r, argv);
        }
        exit(EXIT_FAILURE);
        /* NOTREACHED */
    default:
	/* this is the original process */
	...



So rxvt itself isn't the session leader or the group leader for the child cmd processor (bash)...which is why HUP/KILL don't propagate to the child.

Now, I dunno why rxvt works as-is on unix -- maybe bash on linux notices that its terminal is gone and exits. But it seems to me that in this case, on cygwin, rxvt -- and not cygwin1.dll -- needs to forward SIGHUP to its child process.

I'll got a local version that does propagate (some) signals to the child, and it seems to eliminate the bad behavior (no zombies) -- but I'm not sure what other ramifications this change may have.

I've got a test release on sourceware now; I'll announce it in a new thread and call for testing, once it has propagated to the mirrors.

--
Chuck



--
Unsubscribe info:      http://cygwin.com/ml/#unsubscribe-simple
Problem reports:       http://cygwin.com/problems.html
Documentation:         http://cygwin.com/docs.html
FAQ:                   http://cygwin.com/faq/


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]