Index: crit.cc =================================================================== RCS file: /home/cvs/cvsroot/src/cygrunsrv/crit.cc,v retrieving revision 1.1.1.1 diff -u -p -r1.1.1.1 crit.cc --- crit.cc 2001/05/18 20:10:32 1.1.1.1 +++ crit.cc 2001/06/15 19:19:43 @@ -69,4 +69,16 @@ set_service_status (DWORD state, DWORD c LeaveCriticalSection (&ssc); } - +void +set_service_controls_accepted (bool accept_shutdown) +{ + EnterCriticalSection (&ssc); + if (ssh) + { + ss.dwControlsAccepted = SERVICE_ACCEPT_STOP; + if (accept_shutdown) + ss.dwControlsAccepted |= SERVICE_ACCEPT_SHUTDOWN; + SetServiceStatus(ssh, &ss); + } + LeaveCriticalSection (&ssc); +} Index: crit.h =================================================================== RCS file: /home/cvs/cvsroot/src/cygrunsrv/crit.h,v retrieving revision 1.1.1.1 diff -u -p -r1.1.1.1 crit.h --- crit.h 2001/05/18 20:10:32 1.1.1.1 +++ crit.h 2001/06/15 19:19:43 @@ -29,5 +29,6 @@ extern void set_service_status (DWORD st DWORD check_point = 0, DWORD wait_hint = 0, DWORD exit_code = NO_ERROR); +extern void set_service_controls_accepted(bool shutdown); #endif /* _CRIT_H */ Index: cygrunsrv.cc =================================================================== RCS file: /home/cvs/cvsroot/src/cygrunsrv/cygrunsrv.cc,v retrieving revision 1.7 diff -u -p -r1.7 cygrunsrv.cc --- cygrunsrv.cc 2001/05/31 16:09:09 1.7 +++ cygrunsrv.cc 2001/06/15 19:19:44 @@ -63,16 +63,18 @@ struct option longopts[] = { { "stdin", required_argument, NULL, '0' }, { "stdout", required_argument, NULL, '1' }, { "stderr", required_argument, NULL, '2' }, + { "shutdown", no_argument, NULL, 'o' }, { "help", no_argument, NULL, 'h' }, { "version", no_argument, NULL, 'v' }, { 0, no_argument, NULL, 0 } }; -char *opts = "I:R:S:E:p:a:c:e:d:u:w:t:s:y:0:1:2:hv"; +char *opts = "I:R:S:E:p:a:c:e:d:ou:w:t:s:y:0:1:2:hv"; char *appname; char *svcname; DWORD termsig; +DWORD shutdown; enum action_t { Undefined, @@ -124,7 +126,7 @@ int install_registry_keys (const char *name, const char *path, char *args, char *dir, env_t *env, DWORD termsig, const char *in_stdin, const char *in_stdout, - const char *in_stderr) + const char *in_stderr, DWORD shutdown) { HKEY srv_key = NULL; HKEY env_key = NULL; @@ -181,6 +183,11 @@ install_registry_keys (const char *name, (const BYTE *) in_stderr, strlen (in_stderr) + 1) != ERROR_SUCCESS) err_out (RegSetValueEx); + if (shutdown) + if (RegSetValueEx (srv_key, PARAM_SHUTDOWN, 0, REG_DWORD, + (const BYTE *) &shutdown, + sizeof(DWORD)) != ERROR_SUCCESS) + err_out (RegSetValueEx); RegFlushKey (srv_key); out: @@ -248,7 +255,8 @@ reeval_io_path (int fd, char *&io_path, int get_reg_entries (const char *name, char *&path, char *&args, char *&dir, env_t *&env, DWORD *termsig_p, - char *&stdin_path, char *&stdout_path, char *&stderr_path) + char *&stdin_path, char *&stdout_path, char *&stderr_path, + DWORD *shutdown_p) { HKEY srv_key = NULL; HKEY env_key = NULL; @@ -283,6 +291,11 @@ get_reg_entries (const char *name, char (BYTE *) termsig_p, (size = sizeof(*termsig_p), &size)) != ERROR_SUCCESS) *termsig_p = SIGTERM; // the default + /* Get (optional) shutdown flag. */ + if (RegQueryValueEx (srv_key, PARAM_SHUTDOWN, 0, &type, + (BYTE *) shutdown_p, + (size = sizeof(*shutdown_p), &size)) != ERROR_SUCCESS) + *shutdown_p = 0; // the default /* Get (optional) stdin/stdout/stderr redirection files. */ if ((ret = get_opt_string_entry (srv_key, PARAM_STDIN, stdin_path))) goto out; @@ -820,6 +833,7 @@ service_handler (DWORD ctrl) switch (ctrl) { case SERVICE_CONTROL_STOP: + case SERVICE_CONTROL_SHUTDOWN: /* Since the service_handler doesn't run in the same thread as the service_main routine, it has to setup exception handling. */ exception_list except_list; @@ -895,13 +909,15 @@ service_main (DWORD argc, LPSTR *argv) char *stdout_path = NULL; char *stderr_path = NULL; if (err = get_reg_entries (svcname, path, args, dir, env, &termsig, - stdin_path, stdout_path, stderr_path)) + stdin_path, stdout_path, stderr_path, + &shutdown)) { syslog_starterr ("get_reg_entries", err); set_service_status (SERVICE_STOPPED, 0, 0, err); return; } + set_service_controls_accepted ( shutdown ); report_service_status (); /* Step 2: Further preparations: @@ -1026,6 +1042,7 @@ main (int argc, char **argv) char *in_stdin = NULL; char *in_stdout = NULL; char *in_stderr = NULL; + int in_shutdown = 0; appname = argv[0]; @@ -1107,6 +1124,13 @@ main (int argc, char **argv) return error (OnlyOneDisp); in_disp = optarg; break; + case 'o': + if (action != Install) + return error (ShutdownNotAllowed); + if (in_shutdown) + return error (OnlyOneShutdown); + in_shutdown = 1; + break; case 's': if (action != Install) return error (SigNotAllowed); @@ -1199,7 +1223,8 @@ main (int argc, char **argv) return ret; if (ret = install_registry_keys (in_name, in_path, in_args, in_dir, in_env, in_termsig, - in_stdin, in_stdout, in_stderr)) + in_stdin, in_stdout, in_stderr, + in_shutdown)) remove_service (in_name); return ret; break; Index: cygrunsrv.h =================================================================== RCS file: /home/cvs/cvsroot/src/cygrunsrv/cygrunsrv.h,v retrieving revision 1.6 diff -u -p -r1.6 cygrunsrv.h --- cygrunsrv.h 2001/05/31 16:09:09 1.6 +++ cygrunsrv.h 2001/06/15 19:19:44 @@ -31,6 +31,7 @@ #define PARAM_STDERR "StdErr" #define PARAM_ENVIRON "Environment" #define PARAM_TERMSIG "TermSig" +#define PARAM_SHUTDOWN "Shutdown" #define DEF_STDIN_PATH "/dev/null" #define DEF_LOG_PATH "/var/log/" Index: utils.cc =================================================================== RCS file: /home/cvs/cvsroot/src/cygrunsrv/utils.cc,v retrieving revision 1.6 diff -u -p -r1.6 utils.cc --- utils.cc 2001/05/31 16:09:09 1.6 +++ utils.cc 2001/06/15 19:19:44 @@ -57,6 +57,8 @@ char *reason_list[] = { "--dep is only allowed with --install", "--std{in,out,err} are only allowed with --install", "Each of --std{in,out,err} is allowed only once", + "--shutdown is only allowed with --install", + "Only one --shutdown is allowed", "Trailing commandline arguments not allowed", "You must specify one of the `-IRSE' options", "Error installing a service", @@ -159,6 +161,7 @@ usage () uprint (" Default is /var/log/.log."); uprint (" -2, --stderr Optional output file used for stderr redirection."); uprint (" Default is /var/log/.log."); + uprint (" -o, --shutdown Stop service application during system shutdown."); uprint ("\nInformative output:"); uprint (" -h, --help print this help, then exit."); uprint (" -v, --version print cygrunsrv program version number, then exit."); Index: utils.h =================================================================== RCS file: /home/cvs/cvsroot/src/cygrunsrv/utils.h,v retrieving revision 1.5 diff -u -p -r1.5 utils.h --- utils.h 2001/05/31 16:09:09 1.5 +++ utils.h 2001/06/15 19:19:44 @@ -48,6 +48,8 @@ enum reason_t { DepNotAllowed, IONotAllowed, OnlyOneIO, + ShutdownNotAllowed, + OnlyOneShutdown, TrailingArgs, StartAsSvcErr, InstallErr,