Cygrunsrv and spawned processes

Frank Seesink frank@mail.wvnet.edu
Thu Dec 4 19:30:00 GMT 2003


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.



--
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/



More information about the Cygwin mailing list