cygrunsrv logging OK; patch to --args handling

Charles S. Wilson
Tue May 22 21:39:00 GMT 2001

Corinna Vinschen wrote:
> On Tue, May 22, 2001 at 02:45:52PM -0400, Charles Wilson wrote:
> > Corinna Vinschen wrote:
> > > Ok, so, Charles, do you actually want to provide some README?
> > > I really would _love_ to wait for that before releasing 0.93 :-)
> >
> > It has to wait until after I get home from work (about 9pm EDT -0400).
> > How about if you wait for that, then release tomorrow morning (.de time)
> Sure! I'm looking forward,

As promised, but somewhat overdue... 8-O

cygrunsrv README file

This file:
  What is cygrunsrv?
  What does it do?
  How do I use it?
    Informative options...
    Removing a service
    Starting a service
    Stopping a service
    Installing a service
  General Notes
  Generic Examples (but very informative)
  Specific Examples (for common cygwin services)

What is cygrunsrv?
  cygrunsrv is an implementation of an NT/W2K service starter, similar 
to Microsoft's INSTSRV and SRVANY programs, or the FireDaemon program.
However, cygrunsrv is a cygwin program itself, so it obviously supports 
Cygwin applications better.

What does it do?
  cygrunsrv can operate in two basic modes.  The first is the 
'service management' or 'commandline' mode.  This allows you 
to install and remove a service from the system registry, or 
to start and stop a previously installed service.  The second 
mode is the 'run a service' or 'daemonize' mode.  This mode is
reached ONLY via a special entry point called by the Windows 
Service Mananger -- you can't put cygrunsrv in that mode from 
the command line.  In the 'daemonize' mode, cygrunsrv sets up 
the environment (according to flags set via the 'commandline' 
mode). It adds '/bin' to the front of the PATH so that the 
target service can find cygwin1.dll easily.  It (optionally)
redirects stdout, stdin, and stderr to log files or to the
NT/W2K Event Log (event log access not yet implemented).
Finally, cygrunsrv starts the target daemon.

How do I use it?
  As stated earlier, there are four basic operations that 
cygrunsrv can do in its 'service management' or 'commandline' 
mode: install a service (-I or --install), remove a service 
(-R or --remove), start a service (-S or --start), or stop
a service (-E or --stop).  In addition, the informative
options return information about cygrunsrv itself.
Each mode is discussed in turn, below:

Informative Options

cygrunsrv -h
cygrunsrv --help
  print comprehensive help/option listing for cygrunsrv

cygrunsrv -v
cygrunsrv --version
  print version information about the cygrunsrv executable

Remove a service:

cygrunsrv -R <svc_name>
cygrunsrv --remove <svc_name>
  removes the service from the registry

Start a service:

cygrunsrv -S <svc_name>
cygrunsrv --start <svc_name>
  attempts to start a previously installed service

Stop a service:

cygrunsrv -E <svc_name>
cygrunsrv --stop <svc_name>
  attempts to stop a previously started service

Install a service:
  At minimum, the following options and arguments MUST be specified 
(of course, the short options -I and -p can be used instead of the
long options --install and --path):

  cygrunsrv --install svc_name --path /cygwin/style/path/to/daemon.exe

Note that the "svc_name" is the name of the key in the registry under
which the information for this service is stored.  More importantly, 
it is the name that appears in the Service Manager control panel 
applet, and is the name that can be used by 'cygrunsrv --start' (or 
'net start') to start the service (* see --disp option).  Note that
the svc_name does not HAVE to be the same as the executable name, 
but by convention they are usually the same.

There are a number of additional, optional arguments that may be 

-a, --args <args>
  Optional string with command line options which shall be passed 
to the target service when it is started.  This option may only be
specified one; to call the target service with two arguments, list 
both arguments surrounded by quotes.  For example,

  cygrunsrv -I foo -p /usr/bin/bar -a "-D -e"

calls with two arguments, as in "/usr/bin/bar -D -e". If you need
to specify a single argument which contains spaces, you can 
protect it with single (') or double (") quotes:

  (a) cygrunsrv -I foo -p /usr/bin/bar -a "\"foo bar\""
  (b) cygrunsrv -I foo -p /usr/bin/bar -a "'foo bar'"
  (c) cygrunsrv -I foo -p /usr/bin/bar -a '"foo bar"'

each result in

  (a) /usr/bin/bar "foo bar"
  (b) /usr/bin/bar 'foo bar'
  (c) /usr/bin/bar "foo bar"

(symmetry suggests the following, but it doesn't work.  Trust me)
  cygrunsrv -I foo -p /usr/bin/bar -a '\'foo bar\''

-e, --env <VAR=value>
  Optional environment strings which are added to the environment 
when the service is started. You can add up to 255 environment strings 
using multiple `--env' options.  Note that '/bin:' is always appended
to the path to allow started applications to find cygwin1.dll.  You
may also specify PATH=/a/path:/list if you like, but /bin WILL be
appended.  Note also that the "environment variables" AppPath and
AppArgs are reserved for cygrunsrv's use; don't try to specify these
"variables" with the -e option.

  cygrunsrv -I foo -p /usr/bin/bar -e HOME=/e/services -e TMP=/var/tmp

A single level of quoting with either single (') or double (") quotes
is allowed:

  cygrunsrv -I foo -p /usr/bin/bar -e BAR="\"/d/My Documents/services\""

results in an environment where BAR has the value 
"/d/My Documents/services" *including the quotes* (the \-escaping and 
the outer quotes are required to protect the command itself from bash).
If you don't understand this discussion about quoting, don't worry -- 
you probably don't need it.

-d, --disp <display name>
  Optional string which contains the display name of the service. 
The default value is the service name (svc_name). 

  cygrunsrv -I svc_name -p /usr/bin/svc.exe -d baz

results in a service whose parameters are stored under the registry key
'svc_name', executes the daemon svc.exe, but shows up in the Services 
control panel applet with the name 'baz'.  You can start/stop the daemon 
using 'cygrunsrv -S svc_name' or 'net start svc_name' -- but it will 
report 'The baz service is starting' etc.

-t, --type [auto|manual]
  Optional start type of service. Defaults to `auto' (e.g. this service
will be automatically started at system bootup).  'manual' means the
service must be explicitly started using 'cygrunsrv -S svc_name'

-u, --user <user name>
  Optional user name to start service as. Defaults to SYSTEM account
(also known as the 'LocalSystem' account).

-w, --passwd <password>
  Optional password for user. Only needed if a user is given. If a 
user has an empty password, enter `-w ' with no <password>. If a user 
is given but the -w option is not used, then cygrunsrv will ask for a 
password interactively.  Note that the password is stored in encrypted 
form in the registry.

-0, --stdin <file>
  Optional input file used for stdin redirection. Default is /dev/null.

-1, --stdout <file>
  Optional output file used for stdout redirection. Default is 

-2, --stderr <file>
  Optional output file used for stderr redirection. Default is 
/var/log/<svc_name>.log.  (Thus, by default, both stdout and
stderr are redirected to /var/log/<svc_name>.log).

Note, it may soon be possible to redirect thru a pipe to the 
logger program (which is part of the inetutils package) so that 
messages printed by the target service are stored in the NT/W2K 
Event Application Log. For example,

  cygrunsrv -I svc_name -p /usr/bin/foo.exe \
    --stderr "|/usr/bin/logger -p INFO -t svc_name"

-s, --termsig <signal>
  Optional signal to send to service application to stop
the service.  <signal> can be a number or a signal name such as 
HUP, INT, QUIT, etc. Default is TERM, which is appropriate for
most daemons.

-y, --dep <svc_name2>
  Optional name of service that must be started before this 
new service.  The --dep option may be given up to 16 times, listing 
another dependent service each time.  Try to avoid dependency loops:
that is, if svc_A depends on svc_B, but svc_B depends on svc_A...

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.

For example,
  cygrunsrv -I sshd -p /usr/sbin/sshd -a -D
  cygrunsrv -I squid -p /usr/bin/squid -a -N
although other options may be necessary.

Generic Examples

To install the Cygwin application /bin/foo as service "foo" running under
LocalSystem account, no special options:

    cygrunsrv -I foo -p /bin/foo

To install /bin/foo as a service "bar" which requires command line options:

    cygrunsrv -I bar -p /bin/foo -a '--opt1 --opt2 -x'

To install /bin/foo as a service "baz" which requires a command line option
which contains spaces:

    cygrunsrv -I baz -p /bin/foo -a "-x 'this has spaces inside'"
    cygrunsrv -I baz -p /bin/foo -a '-x "this has spaces inside"'

To install /bin/foo as a service "foo bar" which doesn't automatically
startup when the system boots:

    cygrunsrv -I "foo bar" -p /bin/foo -t manual

To install /bin/foo as a service "bongo" which requires settings for the
environment variables "ENV_VAR_1" and "ENV_VAR_2" to run correctly:

    cygrunsrv -I bongo -p /bin/foo -e "ENV_VAR_1=important_1" \
                                 -e "ENV_VAR_2=also_important"

To install sshd as service under user `joey' account:

    cygrunsrv -I "Joey sshd" -p /usr/sbin/sshd -a '-d' -u joey

cygrunsrv asks for `joey's password interactively. If one wants
to give joey's password (say, "privy23") on the command line:

    cygrunsrv -I "Joey sshd" -p /usr/sbin/sshd -a '-D' -u joey -w privy23

To start the service `foo':

    cygrunsrv -S foo

To stop the service `foo':

    cygrunsrv -E foo

To uninstall the service `foo':

    cygrunsrv -R foo

Specific Examples

Please add suggestions for this list...

  cygrunsrv --install postmaster2 \
    --path /usr/bin/postmaster \
    --args "-D /usr/share/postgresql/data -i -d 2 -o '-o /var/log/postgres.log'" \
    --dep ipc-daemon --termsig INT --user postgresql

  cygrunsrv --install sshd \
    --path /usr/sbin/sshd \
    --args -D

Note that at present, ipc-daemon.exe and inetd.exe contain the 
appropriate code to run as Windows services WITHOUT the assistance 
of cygrunsrv.

Contact Information

For support, contact the cygwin mailing list  cygrunsrv was originally created by Corinna Vinschen.

More information about the Cygwin-apps mailing list