On Thu, 4 Dec 2003, Frank Seesink wrote:
> QUESTION:
>
> If you have a Cygwin application binary which spawns a child process
> using spawnlp() in P_NOWAIT mode, is there a way to install that
> application as an NT service using cygrunsrv such that both the parent
> and child process die cleanly?
>
> DETAILS:
>
> I have Googled and searched the Cygwin mailing lists for insight but
> have failed to yield a solid solution. So here goes:
>
> I have been working with the Jabber/XMPP folks (www.jabber.org) to make
> Jabberd, their IM server, run under Cygwin as it does under *nix. With
> v1.4.3, I believe I have achieved a good measure of success. The only
> Cygwin-specific items in Jabberd now are that
>
> 1. modules (a.k.a., shared libraries) are compiled as .dll and not .so
> 2. due to limitations in Cygwin's support for certain network functions
> (support for inet_ntoa() but lack of inet_ntop()) as well as the
> lack of BIND--the DNS resolver portion of Jabberd was rewritten (by
> someone else awhile ago), and instead of working as a shared library
> as it does under *nix, it now fires off a child process via
> spawnlp() using the _P_NOWAIT mode.
>
> Unfortunately, I am running into an issue when I attempt to setup
> Jabberd to run as an NT service via cygrunsrv.
>
> In a nutshell, if I run Cygwin BASH and fire up Jabberd manually:
>
> $ cd /usr/local/jabber
> $ ./jabberd/jabberd.exe
>
> All works well. I look in Windows Task Manager and see two (2)
> processes: jabberd.exe and jabadns.exe (the resolver). Jabberd is
> running in interactive mode, meaning in the BASH window I can do nothing
> until I kill the process by typing CTRL-C (SIGINT). When I do this,
> both processes die cleanly. Life is good. (NOTE: I do NOT exit BASH.
> I simply hit CTRL-C to send a SIGINT to jabberd.exe, which apparently
> in turn kills jabadns.exe; then I have my command prompt back).
>
> However, when I configure Jabberd as an NT service using cygrunsrv and
> then use
>
> net start jabberd
> net stop jabberd
>
> to start/stop the server, though startup works fine and both processes
> initiate, when I stop Jabberd only jabberd.exe dies. jabadns.exe is
> left behind. The only way to kill it is via kill (if you do a 'ps' to
> find the PID, etc.) or via the Windows Task Manager. Basically, I must
> kill jabadns.exe by hand. If I repeat the above commands to start/stop
> Jabberd repeatedly, I'm left with one jabadns.exe 'zombie' process for
> each invocation.
>
> I have read the relevant portion in
> /usr/share/doc/Cygwin/cygrunsrv.README where it states:
> ____________________________________________________________
> ...
> General Notes:
>
> There's currently one caveat, though. If the application behaves as
> a "normal" unix daemon and exits after forking a child, cygrunsrv
> will immediately stop the service (but the actual daemon keeps running
> in the background). This means that you cannot then STOP the daemon
> using cygrunsrv, but you must explicit kill it via 'kill -9 <daemon_pid>'
>
> If you fail to do this, you will probably see something like this in
> the Windows Application Event Log:
> Cygwin Apache : Win32 Process Id = 0xFE : Cygwin Process Id = 0xFE :
> `Cygwin Apache' service started.
> immediately followed by
> Cygwin Apache : Win32 Process Id = 0xFE : Cygwin Process Id = 0xFE :
> `Cygwin Apache' service stopped.
> but 'ps -eaf | grep httpd' shows that httpd IS still running.
>
> To avoid this problem, you must start the application so that it
> doesn't fork a daemon but stays resident instead. sshd
> for example has to be called with the -D option. squid must be
> called with the -N option.
> ...
> ____________________________________________________________
>
> This makes me believe that cygrunsrv is killing off the server process
> but the signal is not propogating to the spawned child process. I am
> trying to understand why this works from the BASH shell but not via
> cygrunsrv, and more importantly, what I'd like to find out is if there
> is a way to make it work properly as an NT service (that is, have both
> processes die cleanly as they do in BASH).
>
> I'm guessing those running Apache, sshd, etc., aren't running into this
> issue, or I would've found more relevant info. And unless I'm wrong,
> these apps do spawn child processes of their own.
>
> Note that 'cygrunsrv --install' is run with an executable (jabberd.exe),
> not a shell script or anything else. And jabberd.exe is set to run in
> interactive, NOT background (daemon), mode. So I would expect the kill
> signal to propogate as it apparently does at the BASH shell level.
>
> * Is this a limitation in cygrunsrv that is inherent?
> * Is it a bug/limitation in cygrunsrv that is being worked on and,
> hopefully sometime soon, will be fixed?
> * Is there an alternative solution that WILL have the signal propogate
> so the child process dies cleanly?
>
> I have tried my hand at configuring a shell to run a script which runs
> Jabberd, but no luck. Had trouble finding examples via Google, so had
> to wing it. Hopefully I'm just missing something simple, but wanted to
> ask if anyone might be able to help.
Frank,
When you press Ctrl-C in bash, the application gets SIGINT. When you stop
the service installed by cygrunsrv, by default the signal is SIGTERM,
which the application may not handle gracefully. Try the '--termsig INT'
('-s 2') cygrunsrv option.
Igor
--
http://cs.nyu.edu/~pechtcha/
|\ _,,,---,,_ pechtcha@cs.nyu.edu
ZZZzz /,`.-'`' -. ;-;;,_ igor@watson.ibm.com
|,4- ) )-,_. ,\ ( `'-' Igor Pechtchanski, Ph.D.
'---''(_/--' `-'\_) fL a.k.a JaguaR-R-R-r-r-r-.-.-. Meow!
"I have since come to realize that being between your mentor and his route
to the bathroom is a major career booster." -- Patrick Naughton
--
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/