made command line parsing a little more sane with respect to

windows NT services.
This commit is contained in:
crs 2002-06-17 15:44:45 +00:00
parent a81f573666
commit 68740da942
3 changed files with 65 additions and 123 deletions

8
README
View File

@ -169,9 +169,9 @@ recommended that you run it in the foreground until you've sorted
out your configuration. out your configuration.
on the Windows NT family you cannot run a service directly. on the Windows NT family you cannot run a service directly.
instead you install the service then control it via the Services instead you install the service then run or stop it via the
control panel. on the Windows 95 family, you can use the Services control panel. on the Windows 95 family, you can use
`--daemon' command line option to start synergy in the background the `--daemon' command line option to start synergy as a service
or you can install the service and restart your computer. or you can install the service and restart your computer.
in the text below, except where noted, synergy refers to the in the text below, except where noted, synergy refers to the
@ -201,7 +201,7 @@ windows:
directory (e.g. C:\WINNT) and call it "synergy.sgc". the directory (e.g. C:\WINNT) and call it "synergy.sgc". the
server will automatically find this file. however, you can server will automatically find this file. however, you can
also use the --config command line option and specify an also use the --config command line option and specify an
absolute path to the file. remember that this file must be *absolute* path to the file. remember that this file must be
accessible when the system starts up, before network shares accessible when the system starts up, before network shares
are mapped. are mapped.

View File

@ -485,24 +485,10 @@ daemonStartup(IPlatform* iplatform, int argc, const char** argv)
} }
static static
bool int
logDiscard(int, const char*) daemonStartup95(IPlatform*, int, const char**)
{ {
return true; return restartableMain();
}
static bool s_die = false;
static
void
checkParse(int e)
{
// anything over 1 means invalid args. 1 means missing args.
// 0 means graceful exit. we plan to exit for anything but
// 1 (missing args); the service control manager may supply
// the missing arguments so we don't exit in that case.
s_die = (e != 1);
throw s_die;
} }
int WINAPI int WINAPI
@ -519,42 +505,26 @@ WinMain(HINSTANCE instance, HINSTANCE, LPSTR, int)
// initialize network library // initialize network library
CNetwork::init(); CNetwork::init();
// parse command line without reporting errors but recording if
// the app would've exited. this is too avoid showing a dialog
// box if we're being started as a service because we shouldn't
// take too long to startup in that case. this mostly works but
// will choke if the service control manager passes --install
// or --uninstall (but that's unlikely).
CLog::setOutputter(&logDiscard);
bye = &checkParse;
try {
parse(__argc, const_cast<const char**>(__argv));
}
catch (...) {
// ignore
}
// send PRINT and FATAL output to a message box // send PRINT and FATAL output to a message box
CLog::setOutputter(&logMessageBox); CLog::setOutputter(&logMessageBox);
// if we're not starting as an NT service then reparse the command // windows NT family starts services using no command line options.
// line normally. // since i'm not sure how to tell the difference between that and
if (s_die || __argc > 1 || s_install || s_uninstall || // a user providing no options we'll assume that if there are no
CWin32Platform::isWindows95Family()) { // arguments and we're on NT then we're being invoked as a service.
// users on NT can use `--daemon' or `--no-daemon' to force us out
// of the service code path.
if (__argc <= 1 && !CWin32Platform::isWindows95Family()) {
int result = platform.daemonize(DAEMON_NAME, &daemonStartup);
if (result == -1) {
log((CLOG_CRIT "failed to start as a service" BYE, pname));
return 16;
}
return result;
}
// exit on bye // parse command line
bye = &exit;
// reparse
parse(__argc, const_cast<const char**>(__argv)); parse(__argc, const_cast<const char**>(__argv));
}
// if no arguments were provided then we're hopefully starting as
// a service. we'll parse the command line passed in when the
// service control manager calls us back.
else {
// do nothing
}
// install/uninstall // install/uninstall
if (s_install) { if (s_install) {
@ -609,24 +579,25 @@ WinMain(HINSTANCE instance, HINSTANCE, LPSTR, int)
// daemonize if requested // daemonize if requested
int result; int result;
if (__argc <= 1) { if (s_daemon) {
// redirect log messages
platform.installDaemonLogger(DAEMON_NAME);
// start as a daemon
if (CWin32Platform::isWindows95Family()) { if (CWin32Platform::isWindows95Family()) {
result = -1; result = platform.daemonize(DAEMON_NAME, &daemonStartup95);
}
else {
result = platform.daemonize(DAEMON_NAME, &daemonStartup);
}
if (result == -1) { if (result == -1) {
log((CLOG_CRIT "failed to start as a service" BYE, pname)); log((CLOG_CRIT "failed to start as a service" BYE, pname));
return 16; return 16;
} }
} }
else { else {
// if a daemon then redirect log // cannot start a service from the command line so just
if (s_daemon) { // run normally (except with log messages redirected).
platform.installDaemonLogger(__argv[0]); result = restartableMain();
} }
}
else {
// run // run
result = restartableMain(); result = restartableMain();
} }

View File

@ -599,24 +599,10 @@ daemonStartup(IPlatform* iplatform, int argc, const char** argv)
} }
static static
bool int
logDiscard(int, const char*) daemonStartup95(IPlatform*, int, const char**)
{ {
return true; return restartableMain();
}
static bool s_die = false;
static
void
checkParse(int e)
{
// anything over 1 means invalid args. 1 means missing args.
// 0 means graceful exit. we plan to exit for anything but
// 1 (missing args); the service control manager may supply
// the missing arguments so we don't exit in that case.
s_die = (e != 1);
throw s_die;
} }
int WINAPI int WINAPI
@ -633,42 +619,26 @@ WinMain(HINSTANCE instance, HINSTANCE, LPSTR, int)
// initialize network library // initialize network library
CNetwork::init(); CNetwork::init();
// parse command line without reporting errors but recording if
// the app would've exited. this is too avoid showing a dialog
// box if we're being started as a service because we shouldn't
// take to long to startup as a service. this mostly works but
// will choke if the service control manager passes --install
// or --uninstall (but that's unlikely).
CLog::setOutputter(&logDiscard);
bye = &checkParse;
try {
parse(__argc, const_cast<const char**>(__argv));
}
catch (...) {
// ignore
}
// send PRINT and FATAL output to a message box // send PRINT and FATAL output to a message box
CLog::setOutputter(&logMessageBox); CLog::setOutputter(&logMessageBox);
// if we're not starting as an NT service then reparse the command // windows NT family starts services using no command line options.
// line normally. // since i'm not sure how to tell the difference between that and
if (s_die || __argc > 1 || s_install || s_uninstall || // a user providing no options we'll assume that if there are no
CWin32Platform::isWindows95Family()) { // arguments and we're on NT then we're being invoked as a service.
// users on NT can use `--daemon' or `--no-daemon' to force us out
// of the service code path.
if (__argc <= 1 && !CWin32Platform::isWindows95Family()) {
int result = platform.daemonize(DAEMON_NAME, &daemonStartup);
if (result == -1) {
log((CLOG_CRIT "failed to start as a service" BYE, pname));
return 16;
}
return result;
}
// exit on bye // parse command line
bye = &exit;
// reparse
parse(__argc, const_cast<const char**>(__argv)); parse(__argc, const_cast<const char**>(__argv));
}
// if no arguments were provided then we're hopefully starting as
// a service. we'll parse the command line passed in when the
// service control manager calls us back.
else {
// do nothing
}
// install/uninstall // install/uninstall
if (s_install) { if (s_install) {
@ -731,23 +701,24 @@ WinMain(HINSTANCE instance, HINSTANCE, LPSTR, int)
// daemonize if requested // daemonize if requested
int result; int result;
if (s_daemon) { if (s_daemon) {
// redirect log messages
platform.installDaemonLogger(DAEMON_NAME);
// start as a daemon
if (CWin32Platform::isWindows95Family()) { if (CWin32Platform::isWindows95Family()) {
result = -1; result = platform.daemonize(DAEMON_NAME, &daemonStartup95);
}
else {
result = platform.daemonize(DAEMON_NAME, &daemonStartup);
}
if (result == -1) { if (result == -1) {
log((CLOG_CRIT "failed to start as a service" BYE, pname)); log((CLOG_CRIT "failed to start as a service" BYE, pname));
return 16; return 16;
} }
} }
else { else {
// if a daemon then redirect log // cannot start a service from the command line so just
if (s_daemon) { // run normally (except with log messages redirected).
platform.installDaemonLogger(__argv[0]); result = restartableMain();
} }
}
else {
// run // run
result = restartableMain(); result = restartableMain();
} }