removed restart function from platform. no longer trying to
restart if the X server connection was lost; since synergy is likely to be started by xdm or the user's xsession, it's better for synergy to simply terminate when the connection is lost. synergy will still restart due to other errors. also fixed numerous other minor bugs and cleaned some stuff up (like app error codes are now consistent and enumerated in Version.h, for lack of a better place). and boosted version and protocol numbers.
This commit is contained in:
parent
d9ec880291
commit
c6ecc79c0d
|
@ -127,7 +127,6 @@ CClient::open()
|
||||||
}
|
}
|
||||||
catch (XScreenOpenFailure&) {
|
catch (XScreenOpenFailure&) {
|
||||||
// can't open screen yet. wait a few seconds to retry.
|
// can't open screen yet. wait a few seconds to retry.
|
||||||
CThread::sleep(3.0);
|
|
||||||
log((CLOG_INFO "failed to open screen"));
|
log((CLOG_INFO "failed to open screen"));
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -360,7 +359,15 @@ CClient::openSecondaryScreen()
|
||||||
m_screen = new CXWindowsSecondaryScreen(this);
|
m_screen = new CXWindowsSecondaryScreen(this);
|
||||||
#endif
|
#endif
|
||||||
log((CLOG_DEBUG1 "opening secondary screen"));
|
log((CLOG_DEBUG1 "opening secondary screen"));
|
||||||
m_screen->open();
|
try {
|
||||||
|
m_screen->open();
|
||||||
|
}
|
||||||
|
catch (...) {
|
||||||
|
log((CLOG_DEBUG1 "destroying secondary screen"));
|
||||||
|
delete m_screen;
|
||||||
|
m_screen = NULL;
|
||||||
|
throw;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -472,7 +479,9 @@ CClient::runServer()
|
||||||
log((CLOG_INFO "connected to server"));
|
log((CLOG_INFO "connected to server"));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
catch (XSocketConnect&) {
|
catch (XSocketConnect& e) {
|
||||||
|
log((CLOG_DEBUG1 "failed to connect to server: %s", e.getErrstr()));
|
||||||
|
|
||||||
// failed to connect. if not camping then rethrow.
|
// failed to connect. if not camping then rethrow.
|
||||||
if (!m_camp) {
|
if (!m_camp) {
|
||||||
throw;
|
throw;
|
||||||
|
|
|
@ -67,95 +67,99 @@ static
|
||||||
int
|
int
|
||||||
realMain(CMutex* mutex)
|
realMain(CMutex* mutex)
|
||||||
{
|
{
|
||||||
try {
|
// caller should have mutex locked on entry
|
||||||
// initialize threading library
|
|
||||||
CThread::init();
|
|
||||||
|
|
||||||
// make logging thread safe
|
int result = kExitSuccess;
|
||||||
CMutex logMutex;
|
do {
|
||||||
s_logMutex = &logMutex;
|
|
||||||
CLog::setLock(&logLock);
|
|
||||||
|
|
||||||
bool locked = true;
|
|
||||||
try {
|
try {
|
||||||
// create client
|
// initialize threading library
|
||||||
s_client = new CClient(s_name);
|
CThread::init();
|
||||||
s_client->camp(s_camp);
|
|
||||||
s_client->setAddress(s_serverAddress);
|
// make logging thread safe
|
||||||
if (!s_client->open()) {
|
CMutex logMutex;
|
||||||
|
s_logMutex = &logMutex;
|
||||||
|
CLog::setLock(&logLock);
|
||||||
|
|
||||||
|
bool opened = false;
|
||||||
|
bool locked = true;
|
||||||
|
try {
|
||||||
|
// create client
|
||||||
|
s_client = new CClient(s_name);
|
||||||
|
s_client->camp(s_camp);
|
||||||
|
s_client->setAddress(s_serverAddress);
|
||||||
|
if (s_client->open()) {
|
||||||
|
opened = true;
|
||||||
|
|
||||||
|
// run client
|
||||||
|
if (mutex != NULL) {
|
||||||
|
mutex->unlock();
|
||||||
|
}
|
||||||
|
locked = false;
|
||||||
|
s_client->run();
|
||||||
|
locked = true;
|
||||||
|
if (mutex != NULL) {
|
||||||
|
mutex->lock();
|
||||||
|
}
|
||||||
|
|
||||||
|
// get client status
|
||||||
|
if (s_client->wasRejected()) {
|
||||||
|
// wait a while before retrying. we don't want
|
||||||
|
// to bother the server very often if it doesn't
|
||||||
|
// want us.
|
||||||
|
if (s_restartable) {
|
||||||
|
CThread::sleep(60.0);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
result = kExitFailed;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// clean up
|
||||||
|
s_client->close();
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
// wait a few seconds before retrying
|
||||||
|
if (s_restartable) {
|
||||||
|
CThread::sleep(3.0);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
result = kExitFailed;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// clean up
|
||||||
delete s_client;
|
delete s_client;
|
||||||
s_client = NULL;
|
s_client = NULL;
|
||||||
return 16;
|
CLog::setLock(NULL);
|
||||||
|
s_logMutex = NULL;
|
||||||
}
|
}
|
||||||
|
catch (...) {
|
||||||
// run client
|
// clean up
|
||||||
if (mutex != NULL) {
|
if (!locked && mutex != NULL) {
|
||||||
mutex->unlock();
|
mutex->lock();
|
||||||
|
}
|
||||||
|
if (s_client != NULL) {
|
||||||
|
if (opened) {
|
||||||
|
s_client->close();
|
||||||
|
}
|
||||||
|
delete s_client;
|
||||||
|
s_client = NULL;
|
||||||
|
}
|
||||||
|
CLog::setLock(NULL);
|
||||||
|
s_logMutex = NULL;
|
||||||
|
throw;
|
||||||
}
|
}
|
||||||
locked = false;
|
|
||||||
s_client->run();
|
|
||||||
locked = true;
|
|
||||||
if (mutex != NULL) {
|
|
||||||
mutex->lock();
|
|
||||||
}
|
|
||||||
|
|
||||||
// get client status
|
|
||||||
bool success = !s_client->wasRejected();
|
|
||||||
|
|
||||||
// clean up
|
|
||||||
s_client->close();
|
|
||||||
delete s_client;
|
|
||||||
s_client = NULL;
|
|
||||||
CLog::setLock(NULL);
|
|
||||||
s_logMutex = NULL;
|
|
||||||
|
|
||||||
return success ? 16 : 0;
|
|
||||||
}
|
}
|
||||||
catch (...) {
|
catch (XBase& e) {
|
||||||
// clean up
|
log((CLOG_CRIT "failed: %s", e.what()));
|
||||||
if (!locked && mutex != NULL) {
|
|
||||||
mutex->lock();
|
|
||||||
}
|
|
||||||
if (s_client != NULL) {
|
|
||||||
s_client->close();
|
|
||||||
delete s_client;
|
|
||||||
s_client = NULL;
|
|
||||||
}
|
|
||||||
CLog::setLock(NULL);
|
|
||||||
s_logMutex = NULL;
|
|
||||||
throw;
|
|
||||||
}
|
}
|
||||||
}
|
catch (XThread&) {
|
||||||
catch (XBase& e) {
|
// terminated
|
||||||
log((CLOG_CRIT "failed: %s", e.what()));
|
return kExitTerminated;
|
||||||
return 16;
|
}
|
||||||
}
|
} while (s_restartable);
|
||||||
catch (XThread&) {
|
|
||||||
// terminated
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static
|
return result;
|
||||||
int
|
|
||||||
restartMain()
|
|
||||||
{
|
|
||||||
return realMain(NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
// invoke realMain and wait for it. if s_restartable then keep
|
|
||||||
// restarting realMain until it returns a terminate code.
|
|
||||||
static
|
|
||||||
int
|
|
||||||
restartableMain()
|
|
||||||
{
|
|
||||||
if (s_restartable) {
|
|
||||||
CPlatform platform;
|
|
||||||
return platform.restart(restartMain, 16);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
return realMain(NULL);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -229,10 +233,7 @@ PLATFORM_ARGS
|
||||||
" ourself to the server.\n"
|
" ourself to the server.\n"
|
||||||
" -1, --no-restart do not try to restart the client if it fails for\n"
|
" -1, --no-restart do not try to restart the client if it fails for\n"
|
||||||
" some reason.\n"
|
" some reason.\n"
|
||||||
"* --restart restart the client automatically if it fails for\n"
|
"* --restart restart the client automatically if it fails.\n"
|
||||||
" some unexpected reason, including the server\n"
|
|
||||||
" disconnecting but not including failing to\n"
|
|
||||||
" connect to the server.\n"
|
|
||||||
PLATFORM_DESC
|
PLATFORM_DESC
|
||||||
" -h, --help display this help and exit.\n"
|
" -h, --help display this help and exit.\n"
|
||||||
" --version display version information and exit.\n"
|
" --version display version information and exit.\n"
|
||||||
|
@ -261,7 +262,7 @@ isArg(int argi, int argc, const char** argv,
|
||||||
if (argi + minRequiredParameters >= argc) {
|
if (argi + minRequiredParameters >= argc) {
|
||||||
log((CLOG_PRINT "%s: missing arguments for `%s'" BYE,
|
log((CLOG_PRINT "%s: missing arguments for `%s'" BYE,
|
||||||
pname, argv[argi], pname));
|
pname, argv[argi], pname));
|
||||||
bye(2);
|
bye(kExitArgs);
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -329,12 +330,12 @@ parse(int argc, const char** argv)
|
||||||
|
|
||||||
else if (isArg(i, argc, argv, "-h", "--help")) {
|
else if (isArg(i, argc, argv, "-h", "--help")) {
|
||||||
help();
|
help();
|
||||||
bye(0);
|
bye(kExitSuccess);
|
||||||
}
|
}
|
||||||
|
|
||||||
else if (isArg(i, argc, argv, NULL, "--version")) {
|
else if (isArg(i, argc, argv, NULL, "--version")) {
|
||||||
version();
|
version();
|
||||||
bye(0);
|
bye(kExitSuccess);
|
||||||
}
|
}
|
||||||
|
|
||||||
#if WINDOWS_LIKE
|
#if WINDOWS_LIKE
|
||||||
|
@ -344,7 +345,7 @@ parse(int argc, const char** argv)
|
||||||
log((CLOG_PRINT "%s: `--install' and `--uninstall'"
|
log((CLOG_PRINT "%s: `--install' and `--uninstall'"
|
||||||
" are mutually exclusive" BYE,
|
" are mutually exclusive" BYE,
|
||||||
pname, argv[i], pname));
|
pname, argv[i], pname));
|
||||||
bye(2);
|
bye(kExitArgs);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@ -356,7 +357,7 @@ parse(int argc, const char** argv)
|
||||||
log((CLOG_PRINT "%s: `--install' and `--uninstall'"
|
log((CLOG_PRINT "%s: `--install' and `--uninstall'"
|
||||||
" are mutually exclusive" BYE,
|
" are mutually exclusive" BYE,
|
||||||
pname, argv[i], pname));
|
pname, argv[i], pname));
|
||||||
bye(2);
|
bye(kExitArgs);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@ -370,7 +371,7 @@ parse(int argc, const char** argv)
|
||||||
else if (argv[i][0] == '-') {
|
else if (argv[i][0] == '-') {
|
||||||
log((CLOG_PRINT "%s: unrecognized option `%s'" BYE,
|
log((CLOG_PRINT "%s: unrecognized option `%s'" BYE,
|
||||||
pname, argv[i], pname));
|
pname, argv[i], pname));
|
||||||
bye(2);
|
bye(kExitArgs);
|
||||||
}
|
}
|
||||||
|
|
||||||
else {
|
else {
|
||||||
|
@ -386,19 +387,19 @@ parse(int argc, const char** argv)
|
||||||
log((CLOG_PRINT "%s: unrecognized option `%s' to `%s'" BYE,
|
log((CLOG_PRINT "%s: unrecognized option `%s' to `%s'" BYE,
|
||||||
pname, argv[i], pname,
|
pname, argv[i], pname,
|
||||||
s_install ? "--install" : "--uninstall"));
|
s_install ? "--install" : "--uninstall"));
|
||||||
bye(2);
|
bye(kExitArgs);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if (i == argc) {
|
if (i == argc) {
|
||||||
log((CLOG_PRINT "%s: a server address or name is required" BYE,
|
log((CLOG_PRINT "%s: a server address or name is required" BYE,
|
||||||
pname, pname));
|
pname, pname));
|
||||||
bye(1);
|
bye(kExitArgs);
|
||||||
}
|
}
|
||||||
if (i + 1 != argc) {
|
if (i + 1 != argc) {
|
||||||
log((CLOG_PRINT "%s: unrecognized option `%s'" BYE,
|
log((CLOG_PRINT "%s: unrecognized option `%s'" BYE,
|
||||||
pname, argv[i], pname));
|
pname, argv[i], pname));
|
||||||
bye(2);
|
bye(kExitArgs);
|
||||||
}
|
}
|
||||||
|
|
||||||
// save server address
|
// save server address
|
||||||
|
@ -408,7 +409,7 @@ parse(int argc, const char** argv)
|
||||||
catch (XSocketAddress&) {
|
catch (XSocketAddress&) {
|
||||||
log((CLOG_PRINT "%s: invalid server address" BYE,
|
log((CLOG_PRINT "%s: invalid server address" BYE,
|
||||||
pname, pname));
|
pname, pname));
|
||||||
bye(2);
|
bye(kExitArgs);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -432,7 +433,7 @@ parse(int argc, const char** argv)
|
||||||
if (!CLog::setFilter(s_logFilter)) {
|
if (!CLog::setFilter(s_logFilter)) {
|
||||||
log((CLOG_PRINT "%s: unrecognized log level `%s'" BYE,
|
log((CLOG_PRINT "%s: unrecognized log level `%s'" BYE,
|
||||||
pname, s_logFilter, pname));
|
pname, s_logFilter, pname));
|
||||||
bye(2);
|
bye(kExitArgs);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -488,7 +489,7 @@ daemonStartup(IPlatform* iplatform, int argc, const char** argv)
|
||||||
parse(argc, argv);
|
parse(argc, argv);
|
||||||
if (s_install || s_uninstall) {
|
if (s_install || s_uninstall) {
|
||||||
// not allowed to install/uninstall from service
|
// not allowed to install/uninstall from service
|
||||||
throw CWin32Platform::CDaemonFailed(1);
|
throw CWin32Platform::CDaemonFailed(kExitArgs);
|
||||||
}
|
}
|
||||||
|
|
||||||
// run as a service
|
// run as a service
|
||||||
|
@ -499,7 +500,7 @@ static
|
||||||
int
|
int
|
||||||
daemonStartup95(IPlatform*, int, const char**)
|
daemonStartup95(IPlatform*, int, const char**)
|
||||||
{
|
{
|
||||||
return restartableMain();
|
return realMain(NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
int WINAPI
|
int WINAPI
|
||||||
|
@ -529,7 +530,7 @@ WinMain(HINSTANCE instance, HINSTANCE, LPSTR, int)
|
||||||
int result = platform.daemonize(DAEMON_NAME, &daemonStartup);
|
int 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 kExitFailed;
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
@ -544,7 +545,7 @@ WinMain(HINSTANCE instance, HINSTANCE, LPSTR, int)
|
||||||
if (GetModuleFileName(NULL, path,
|
if (GetModuleFileName(NULL, path,
|
||||||
sizeof(path) / sizeof(path[0])) == 0) {
|
sizeof(path) / sizeof(path[0])) == 0) {
|
||||||
log((CLOG_CRIT "cannot determine absolute path to program"));
|
log((CLOG_CRIT "cannot determine absolute path to program"));
|
||||||
return 16;
|
return kExitFailed;
|
||||||
}
|
}
|
||||||
|
|
||||||
// construct the command line to start the service with
|
// construct the command line to start the service with
|
||||||
|
@ -567,24 +568,24 @@ WinMain(HINSTANCE instance, HINSTANCE, LPSTR, int)
|
||||||
"Shares this system's mouse and keyboard with others.",
|
"Shares this system's mouse and keyboard with others.",
|
||||||
path, commandLine.c_str())) {
|
path, commandLine.c_str())) {
|
||||||
log((CLOG_CRIT "failed to install service"));
|
log((CLOG_CRIT "failed to install service"));
|
||||||
return 16;
|
return kExitFailed;
|
||||||
}
|
}
|
||||||
log((CLOG_PRINT "installed successfully"));
|
log((CLOG_PRINT "installed successfully"));
|
||||||
return 0;
|
return kExitSuccess;
|
||||||
}
|
}
|
||||||
else if (s_uninstall) {
|
else if (s_uninstall) {
|
||||||
switch (platform.uninstallDaemon(DAEMON_NAME)) {
|
switch (platform.uninstallDaemon(DAEMON_NAME)) {
|
||||||
case IPlatform::kSuccess:
|
case IPlatform::kSuccess:
|
||||||
log((CLOG_PRINT "uninstalled successfully"));
|
log((CLOG_PRINT "uninstalled successfully"));
|
||||||
return 0;
|
return kExitSuccess;
|
||||||
|
|
||||||
case IPlatform::kFailed:
|
case IPlatform::kFailed:
|
||||||
log((CLOG_CRIT "failed to uninstall service"));
|
log((CLOG_CRIT "failed to uninstall service"));
|
||||||
return 16;
|
return kExitFailed;
|
||||||
|
|
||||||
case IPlatform::kAlready:
|
case IPlatform::kAlready:
|
||||||
log((CLOG_CRIT "service isn't installed"));
|
log((CLOG_CRIT "service isn't installed"));
|
||||||
return 16;
|
return kExitFailed;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -599,18 +600,18 @@ WinMain(HINSTANCE instance, HINSTANCE, LPSTR, int)
|
||||||
result = platform.daemonize(DAEMON_NAME, &daemonStartup95);
|
result = platform.daemonize(DAEMON_NAME, &daemonStartup95);
|
||||||
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 kExitFailed;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
// cannot start a service from the command line so just
|
// cannot start a service from the command line so just
|
||||||
// run normally (except with log messages redirected).
|
// run normally (except with log messages redirected).
|
||||||
result = restartableMain();
|
result = realMain(NULL);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
// run
|
// run
|
||||||
result = restartableMain();
|
result = realMain(NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
CNetwork::cleanup();
|
CNetwork::cleanup();
|
||||||
|
@ -624,7 +625,7 @@ static
|
||||||
int
|
int
|
||||||
daemonStartup(IPlatform*, int, const char**)
|
daemonStartup(IPlatform*, int, const char**)
|
||||||
{
|
{
|
||||||
return restartableMain();
|
return realMain(NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
|
@ -647,11 +648,11 @@ main(int argc, char** argv)
|
||||||
result = platform.daemonize(DAEMON_NAME, &daemonStartup);
|
result = platform.daemonize(DAEMON_NAME, &daemonStartup);
|
||||||
if (result == -1) {
|
if (result == -1) {
|
||||||
log((CLOG_CRIT "failed to daemonize"));
|
log((CLOG_CRIT "failed to daemonize"));
|
||||||
return 16;
|
return kExitFailed;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
result = restartableMain();
|
result = realMain(NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
CNetwork::cleanup();
|
CNetwork::cleanup();
|
||||||
|
|
|
@ -115,8 +115,9 @@ CTCPSocket::connect(const CNetworkAddress& addr)
|
||||||
addr.getAddressLength()) == CNetwork::Error) {
|
addr.getAddressLength()) == CNetwork::Error) {
|
||||||
// check for failure
|
// check for failure
|
||||||
if (CNetwork::getsockerror() != CNetwork::kECONNECTING) {
|
if (CNetwork::getsockerror() != CNetwork::kECONNECTING) {
|
||||||
|
XSocketConnect e;
|
||||||
CNetwork::setblocking(m_fd, true);
|
CNetwork::setblocking(m_fd, true);
|
||||||
throw XSocketConnect();
|
throw e;
|
||||||
}
|
}
|
||||||
|
|
||||||
// wait for connection or failure
|
// wait for connection or failure
|
||||||
|
@ -130,8 +131,12 @@ CTCPSocket::connect(const CNetworkAddress& addr)
|
||||||
if ((pfds[0].revents & (CNetwork::kPOLLERR |
|
if ((pfds[0].revents & (CNetwork::kPOLLERR |
|
||||||
CNetwork::kPOLLNVAL)) != 0) {
|
CNetwork::kPOLLNVAL)) != 0) {
|
||||||
// connection failed
|
// connection failed
|
||||||
|
int error = 0;
|
||||||
|
CNetwork::AddressLength size = sizeof(error);
|
||||||
CNetwork::setblocking(m_fd, true);
|
CNetwork::setblocking(m_fd, true);
|
||||||
throw XSocketConnect();
|
CNetwork::getsockopt(m_fd, SOL_SOCKET, SO_ERROR,
|
||||||
|
reinterpret_cast<char*>(&error), &size);
|
||||||
|
throw XSocketConnect(error);
|
||||||
}
|
}
|
||||||
if ((pfds[0].revents & CNetwork::kPOLLOUT) != 0) {
|
if ((pfds[0].revents & CNetwork::kPOLLOUT) != 0) {
|
||||||
int error;
|
int error;
|
||||||
|
@ -142,7 +147,7 @@ CTCPSocket::connect(const CNetworkAddress& addr)
|
||||||
error != 0) {
|
error != 0) {
|
||||||
// connection failed
|
// connection failed
|
||||||
CNetwork::setblocking(m_fd, true);
|
CNetwork::setblocking(m_fd, true);
|
||||||
throw XSocketConnect();
|
throw XSocketConnect(error);
|
||||||
}
|
}
|
||||||
|
|
||||||
// connected!
|
// connected!
|
||||||
|
|
|
@ -36,20 +36,36 @@ public:
|
||||||
};
|
};
|
||||||
|
|
||||||
class XSocketBind : public XSocketErrno {
|
class XSocketBind : public XSocketErrno {
|
||||||
|
public:
|
||||||
|
XSocketBind() { }
|
||||||
|
XSocketBind(int e) : XSocketErrno(e) { }
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
// XBase overrides
|
// XBase overrides
|
||||||
virtual CString getWhat() const throw();
|
virtual CString getWhat() const throw();
|
||||||
};
|
};
|
||||||
|
|
||||||
class XSocketAddressInUse : public XSocketBind { };
|
class XSocketAddressInUse : public XSocketBind {
|
||||||
|
public:
|
||||||
|
XSocketAddressInUse() { }
|
||||||
|
XSocketAddressInUse(int e) : XSocketBind(e) { }
|
||||||
|
};
|
||||||
|
|
||||||
class XSocketConnect : public XSocketErrno {
|
class XSocketConnect : public XSocketErrno {
|
||||||
|
public:
|
||||||
|
XSocketConnect() { }
|
||||||
|
XSocketConnect(int e) : XSocketErrno(e) { }
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
// XBase overrides
|
// XBase overrides
|
||||||
virtual CString getWhat() const throw();
|
virtual CString getWhat() const throw();
|
||||||
};
|
};
|
||||||
|
|
||||||
class XSocketCreate : public XSocketErrno {
|
class XSocketCreate : public XSocketErrno {
|
||||||
|
public:
|
||||||
|
XSocketCreate() { }
|
||||||
|
XSocketCreate(int e) : XSocketErrno(e) { }
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
// XBase overrides
|
// XBase overrides
|
||||||
virtual CString getWhat() const throw();
|
virtual CString getWhat() const throw();
|
||||||
|
|
|
@ -7,22 +7,6 @@
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
#include <syslog.h>
|
#include <syslog.h>
|
||||||
#include <signal.h>
|
|
||||||
#if HAVE_SYS_WAIT_H
|
|
||||||
# include <sys/wait.h>
|
|
||||||
#endif
|
|
||||||
#if !defined(WIFSIGNALED)
|
|
||||||
# define WIFSIGNALED(w) (((w) & 0xff) != 0x7f && ((w) & 0xff) != 0)
|
|
||||||
#endif
|
|
||||||
#if !defined(WIFEXITED)
|
|
||||||
# define WIFEXITED(w) (((w) & 0xff) == 0)
|
|
||||||
#endif
|
|
||||||
#if !defined(WTERMSIG)
|
|
||||||
# define WTERMSIG(w) ((w) & 0x7f)
|
|
||||||
#endif
|
|
||||||
#if !defined(WEXITSTATUS)
|
|
||||||
# define WEXITSTATUS(w) (((w) >> 8) & 0xff)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
//
|
//
|
||||||
|
@ -106,64 +90,6 @@ CUnixPlatform::installDaemonLogger(const char* name)
|
||||||
CLog::setOutputter(&CUnixPlatform::deamonLogger);
|
CLog::setOutputter(&CUnixPlatform::deamonLogger);
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
|
||||||
CUnixPlatform::restart(RestartFunc func, int minErrorCode)
|
|
||||||
{
|
|
||||||
// rely on child to catch these signals
|
|
||||||
sigset_t sigset;
|
|
||||||
sigemptyset(&sigset);
|
|
||||||
sigaddset(&sigset, SIGINT);
|
|
||||||
sigaddset(&sigset, SIGTERM);
|
|
||||||
pthread_sigmask(SIG_BLOCK, &sigset, NULL);
|
|
||||||
|
|
||||||
for (;;) {
|
|
||||||
switch (fork()) {
|
|
||||||
default:
|
|
||||||
{
|
|
||||||
// parent process. wait for child to exit.
|
|
||||||
int status;
|
|
||||||
if (wait(&status) == -1) {
|
|
||||||
// wait failed. this is unexpected so bail.
|
|
||||||
log((CLOG_CRIT "wait() failed"));
|
|
||||||
return minErrorCode;
|
|
||||||
}
|
|
||||||
|
|
||||||
// what happened? if the child exited normally with a
|
|
||||||
// status less than 16 then the child was deliberately
|
|
||||||
// terminated so we also terminate.
|
|
||||||
if (WIFEXITED(status) && WEXITSTATUS(status) < minErrorCode) {
|
|
||||||
return WEXITSTATUS(status);
|
|
||||||
}
|
|
||||||
|
|
||||||
// did child die horribly?
|
|
||||||
if (WIFSIGNALED(status)) {
|
|
||||||
switch (WTERMSIG(status)) {
|
|
||||||
case SIGHUP:
|
|
||||||
case SIGINT:
|
|
||||||
case SIGQUIT:
|
|
||||||
case SIGTERM:
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
// uh oh. bail out.
|
|
||||||
return 16;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case -1:
|
|
||||||
// fork() failed. log the error and proceed as a child
|
|
||||||
log((CLOG_WARN "fork() failed; cannot automatically restart on error"));
|
|
||||||
// fall through
|
|
||||||
|
|
||||||
case 0:
|
|
||||||
// child process
|
|
||||||
return func();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const char*
|
const char*
|
||||||
CUnixPlatform::getBasename(const char* pathname) const
|
CUnixPlatform::getBasename(const char* pathname) const
|
||||||
{
|
{
|
||||||
|
|
|
@ -16,7 +16,6 @@ public:
|
||||||
virtual EResult uninstallDaemon(const char* name);
|
virtual EResult uninstallDaemon(const char* name);
|
||||||
virtual int daemonize(const char* name, DaemonFunc);
|
virtual int daemonize(const char* name, DaemonFunc);
|
||||||
virtual void installDaemonLogger(const char* name);
|
virtual void installDaemonLogger(const char* name);
|
||||||
virtual int restart(RestartFunc, int minErrorCode);
|
|
||||||
virtual const char* getBasename(const char* pathname) const;
|
virtual const char* getBasename(const char* pathname) const;
|
||||||
virtual CString getUserDirectory() const;
|
virtual CString getUserDirectory() const;
|
||||||
virtual CString getSystemDirectory() const;
|
virtual CString getSystemDirectory() const;
|
||||||
|
|
|
@ -319,15 +319,6 @@ CWin32Platform::installDaemonLogger(const char* name)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
|
||||||
CWin32Platform::restart(RestartFunc func, int /*minErrorCode*/)
|
|
||||||
{
|
|
||||||
// FIXME -- start in separate process or thread. note that this
|
|
||||||
// isn't too critical as win32 doesn't force us to terminate for
|
|
||||||
// any reason so we should never have to restart.
|
|
||||||
return func();
|
|
||||||
}
|
|
||||||
|
|
||||||
const char*
|
const char*
|
||||||
CWin32Platform::getBasename(const char* pathname) const
|
CWin32Platform::getBasename(const char* pathname) const
|
||||||
{
|
{
|
||||||
|
|
|
@ -49,7 +49,6 @@ public:
|
||||||
virtual EResult uninstallDaemon(const char* name);
|
virtual EResult uninstallDaemon(const char* name);
|
||||||
virtual int daemonize(const char* name, DaemonFunc);
|
virtual int daemonize(const char* name, DaemonFunc);
|
||||||
virtual void installDaemonLogger(const char* name);
|
virtual void installDaemonLogger(const char* name);
|
||||||
virtual int restart(RestartFunc, int minErrorCode);
|
|
||||||
virtual const char* getBasename(const char* pathname) const;
|
virtual const char* getBasename(const char* pathname) const;
|
||||||
virtual CString getUserDirectory() const;
|
virtual CString getUserDirectory() const;
|
||||||
virtual CString getSystemDirectory() const;
|
virtual CString getSystemDirectory() const;
|
||||||
|
|
|
@ -93,6 +93,11 @@ CXWindowsScreen::CXWindowsScreen(IScreenReceiver* receiver,
|
||||||
assert(m_eventHandler != NULL);
|
assert(m_eventHandler != NULL);
|
||||||
|
|
||||||
s_screen = this;
|
s_screen = this;
|
||||||
|
|
||||||
|
// no clipboards to start with
|
||||||
|
for (ClipboardID id = 0; id < kClipboardEnd; ++id) {
|
||||||
|
m_clipboard[id] = NULL;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
CXWindowsScreen::~CXWindowsScreen()
|
CXWindowsScreen::~CXWindowsScreen()
|
||||||
|
@ -670,7 +675,10 @@ CDisplayLock::CDisplayLock(const CXWindowsScreen* screen) :
|
||||||
m_mutex(&screen->m_mutex),
|
m_mutex(&screen->m_mutex),
|
||||||
m_display(screen->m_display)
|
m_display(screen->m_display)
|
||||||
{
|
{
|
||||||
assert(m_display != NULL);
|
// note -- it's permitted for m_display to be NULL. that might
|
||||||
|
// happen if we couldn't connect to the display or if the
|
||||||
|
// display unexpectedly disconnected. the caller is expected
|
||||||
|
// to check for NULL as necessary.
|
||||||
|
|
||||||
m_mutex->lock();
|
m_mutex->lock();
|
||||||
}
|
}
|
||||||
|
|
|
@ -206,7 +206,9 @@ CXWindowsUtil::CErrorLock::CErrorLock(Display* display,
|
||||||
CXWindowsUtil::CErrorLock::~CErrorLock()
|
CXWindowsUtil::CErrorLock::~CErrorLock()
|
||||||
{
|
{
|
||||||
// make sure everything finishes before uninstalling handler
|
// make sure everything finishes before uninstalling handler
|
||||||
XSync(m_display, False);
|
if (m_display != NULL) {
|
||||||
|
XSync(m_display, False);
|
||||||
|
}
|
||||||
|
|
||||||
// restore old handler
|
// restore old handler
|
||||||
XSetErrorHandler(m_oldXHandler);
|
XSetErrorHandler(m_oldXHandler);
|
||||||
|
@ -217,7 +219,9 @@ void
|
||||||
CXWindowsUtil::CErrorLock::install(ErrorHandler handler, void* data)
|
CXWindowsUtil::CErrorLock::install(ErrorHandler handler, void* data)
|
||||||
{
|
{
|
||||||
// make sure everything finishes before installing handler
|
// make sure everything finishes before installing handler
|
||||||
XSync(m_display, False);
|
if (m_display != NULL) {
|
||||||
|
XSync(m_display, False);
|
||||||
|
}
|
||||||
|
|
||||||
// install handler
|
// install handler
|
||||||
m_handler = handler;
|
m_handler = handler;
|
||||||
|
|
|
@ -7,7 +7,6 @@
|
||||||
class IPlatform : public IInterface {
|
class IPlatform : public IInterface {
|
||||||
public:
|
public:
|
||||||
typedef int (*DaemonFunc)(IPlatform*, int argc, const char** argv);
|
typedef int (*DaemonFunc)(IPlatform*, int argc, const char** argv);
|
||||||
typedef int (*RestartFunc)();
|
|
||||||
|
|
||||||
enum EResult {
|
enum EResult {
|
||||||
kSuccess,
|
kSuccess,
|
||||||
|
@ -53,11 +52,6 @@ public:
|
||||||
// in the log to identify this process.
|
// in the log to identify this process.
|
||||||
virtual void installDaemonLogger(const char* name) = 0;
|
virtual void installDaemonLogger(const char* name) = 0;
|
||||||
|
|
||||||
// continually restart the given function in a separate process
|
|
||||||
// or thread until it exits normally with a code less than the
|
|
||||||
// given code then return the code.
|
|
||||||
virtual int restart(RestartFunc, int minErrorCode) = 0;
|
|
||||||
|
|
||||||
// accessors
|
// accessors
|
||||||
|
|
||||||
// find the basename in the given pathname
|
// find the basename in the given pathname
|
||||||
|
|
|
@ -34,6 +34,7 @@ CPrimaryClient::CPrimaryClient(IServer* server,
|
||||||
|
|
||||||
CPrimaryClient::~CPrimaryClient()
|
CPrimaryClient::~CPrimaryClient()
|
||||||
{
|
{
|
||||||
|
log((CLOG_DEBUG1 "destroying primary screen"));
|
||||||
delete m_screen;
|
delete m_screen;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -59,13 +59,11 @@ CServer::open()
|
||||||
}
|
}
|
||||||
catch (XScreenOpenFailure&) {
|
catch (XScreenOpenFailure&) {
|
||||||
// can't open screen yet. wait a few seconds to retry.
|
// can't open screen yet. wait a few seconds to retry.
|
||||||
CThread::sleep(3.0);
|
|
||||||
log((CLOG_INFO "failed to open screen"));
|
log((CLOG_INFO "failed to open screen"));
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
catch (XUnknownClient& e) {
|
catch (XUnknownClient& e) {
|
||||||
// can't open screen yet. wait a few seconds to retry.
|
// can't open screen yet. wait a few seconds to retry.
|
||||||
CThread::sleep(3.0);
|
|
||||||
log((CLOG_CRIT "unknown screen name `%s'", e.getName().c_str()));
|
log((CLOG_CRIT "unknown screen name `%s'", e.getName().c_str()));
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -1135,7 +1133,9 @@ CServer::acceptClients(void*)
|
||||||
listen->bind(m_config.getSynergyAddress());
|
listen->bind(m_config.getSynergyAddress());
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
catch (XSocketAddressInUse&) {
|
catch (XSocketBind& e) {
|
||||||
|
log((CLOG_DEBUG1 "bind failed: %s", e.getErrstr()));
|
||||||
|
|
||||||
// give up if we've waited too long
|
// give up if we've waited too long
|
||||||
if (timer.getTime() >= m_bindTimeout) {
|
if (timer.getTime() >= m_bindTimeout) {
|
||||||
log((CLOG_DEBUG1 "waited too long to bind, giving up"));
|
log((CLOG_DEBUG1 "waited too long to bind, giving up"));
|
||||||
|
@ -1143,7 +1143,6 @@ CServer::acceptClients(void*)
|
||||||
}
|
}
|
||||||
|
|
||||||
// wait a bit before retrying
|
// wait a bit before retrying
|
||||||
log((CLOG_DEBUG1 "bind failed; waiting to retry"));
|
|
||||||
CThread::sleep(5.0);
|
CThread::sleep(5.0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1419,7 +1418,9 @@ CServer::acceptHTTPClients(void*)
|
||||||
listen->bind(m_config.getHTTPAddress());
|
listen->bind(m_config.getHTTPAddress());
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
catch (XSocketAddressInUse&) {
|
catch (XSocketBind& e) {
|
||||||
|
log((CLOG_DEBUG1 "bind HTTP failed: %s", e.getErrstr()));
|
||||||
|
|
||||||
// give up if we've waited too long
|
// give up if we've waited too long
|
||||||
if (timer.getTime() >= m_bindTimeout) {
|
if (timer.getTime() >= m_bindTimeout) {
|
||||||
log((CLOG_DEBUG1 "waited too long to bind HTTP, giving up"));
|
log((CLOG_DEBUG1 "waited too long to bind HTTP, giving up"));
|
||||||
|
@ -1427,7 +1428,6 @@ CServer::acceptHTTPClients(void*)
|
||||||
}
|
}
|
||||||
|
|
||||||
// wait a bit before retrying
|
// wait a bit before retrying
|
||||||
log((CLOG_DEBUG1 "bind HTTP failed; waiting to retry"));
|
|
||||||
CThread::sleep(5.0);
|
CThread::sleep(5.0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -77,114 +77,106 @@ static
|
||||||
int
|
int
|
||||||
realMain(CMutex* mutex)
|
realMain(CMutex* mutex)
|
||||||
{
|
{
|
||||||
// s_serverLock should have mutex locked on entry
|
// caller should have mutex locked on entry
|
||||||
|
|
||||||
try {
|
int result = kExitSuccess;
|
||||||
// initialize threading library
|
do {
|
||||||
CThread::init();
|
|
||||||
|
|
||||||
// make logging thread safe
|
|
||||||
CMutex logMutex;
|
|
||||||
s_logMutex = &logMutex;
|
|
||||||
CLog::setLock(&logLock);
|
|
||||||
|
|
||||||
bool locked = true;
|
|
||||||
try {
|
try {
|
||||||
// if configuration has no screens then add this system
|
// initialize threading library
|
||||||
// as the default
|
CThread::init();
|
||||||
if (s_config.begin() == s_config.end()) {
|
|
||||||
s_config.addScreen(s_name);
|
|
||||||
}
|
|
||||||
|
|
||||||
// set the contact address, if provided, in the config.
|
// make logging thread safe
|
||||||
// otherwise, if the config doesn't have an address, use
|
CMutex logMutex;
|
||||||
// the default.
|
s_logMutex = &logMutex;
|
||||||
if (s_synergyAddress.isValid()) {
|
CLog::setLock(&logLock);
|
||||||
s_config.setSynergyAddress(s_synergyAddress);
|
|
||||||
}
|
|
||||||
else if (!s_config.getSynergyAddress().isValid()) {
|
|
||||||
s_config.setSynergyAddress(CNetworkAddress(kDefaultPort));
|
|
||||||
}
|
|
||||||
|
|
||||||
// set HTTP address is provided
|
bool opened = false;
|
||||||
if (s_httpAddress.isValid()) {
|
bool locked = true;
|
||||||
s_config.setHTTPAddress(s_httpAddress);
|
try {
|
||||||
}
|
// if configuration has no screens then add this system
|
||||||
|
// as the default
|
||||||
|
if (s_config.begin() == s_config.end()) {
|
||||||
|
s_config.addScreen(s_name);
|
||||||
|
}
|
||||||
|
|
||||||
// create server
|
// set the contact address, if provided, in the config.
|
||||||
s_server = new CServer(s_name);
|
// otherwise, if the config doesn't have an address, use
|
||||||
s_server->setConfig(s_config);
|
// the default.
|
||||||
if (!s_server->open()) {
|
if (s_synergyAddress.isValid()) {
|
||||||
|
s_config.setSynergyAddress(s_synergyAddress);
|
||||||
|
}
|
||||||
|
else if (!s_config.getSynergyAddress().isValid()) {
|
||||||
|
s_config.setSynergyAddress(CNetworkAddress(kDefaultPort));
|
||||||
|
}
|
||||||
|
|
||||||
|
// set HTTP address if provided
|
||||||
|
if (s_httpAddress.isValid()) {
|
||||||
|
s_config.setHTTPAddress(s_httpAddress);
|
||||||
|
}
|
||||||
|
|
||||||
|
// create server
|
||||||
|
s_server = new CServer(s_name);
|
||||||
|
s_server->setConfig(s_config);
|
||||||
|
if (s_server->open()) {
|
||||||
|
opened = true;
|
||||||
|
|
||||||
|
// run server (unlocked)
|
||||||
|
if (mutex != NULL) {
|
||||||
|
mutex->unlock();
|
||||||
|
}
|
||||||
|
locked = false;
|
||||||
|
s_server->run();
|
||||||
|
locked = true;
|
||||||
|
if (mutex != NULL) {
|
||||||
|
mutex->lock();
|
||||||
|
}
|
||||||
|
|
||||||
|
// clean up
|
||||||
|
s_server->close();
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
// wait a few seconds before retrying
|
||||||
|
if (s_restartable) {
|
||||||
|
CThread::sleep(3.0);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
result = kExitFailed;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// clean up
|
||||||
delete s_server;
|
delete s_server;
|
||||||
s_server = NULL;
|
s_server = NULL;
|
||||||
return 16;
|
CLog::setLock(NULL);
|
||||||
|
s_logMutex = NULL;
|
||||||
}
|
}
|
||||||
|
catch (...) {
|
||||||
// run server (unlocked)
|
// clean up
|
||||||
if (mutex != NULL) {
|
if (!locked && mutex != NULL) {
|
||||||
mutex->unlock();
|
mutex->lock();
|
||||||
|
}
|
||||||
|
if (s_server != NULL) {
|
||||||
|
if (opened) {
|
||||||
|
s_server->close();
|
||||||
|
}
|
||||||
|
delete s_server;
|
||||||
|
s_server = NULL;
|
||||||
|
}
|
||||||
|
CLog::setLock(NULL);
|
||||||
|
s_logMutex = NULL;
|
||||||
|
throw;
|
||||||
}
|
}
|
||||||
locked = false;
|
|
||||||
s_server->run();
|
|
||||||
locked = true;
|
|
||||||
if (mutex != NULL) {
|
|
||||||
mutex->lock();
|
|
||||||
}
|
|
||||||
|
|
||||||
// clean up
|
|
||||||
s_server->close();
|
|
||||||
delete s_server;
|
|
||||||
s_server = NULL;
|
|
||||||
CLog::setLock(NULL);
|
|
||||||
s_logMutex = NULL;
|
|
||||||
}
|
}
|
||||||
catch (...) {
|
catch (XBase& e) {
|
||||||
// clean up
|
log((CLOG_CRIT "failed: %s", e.what()));
|
||||||
if (!locked && mutex != NULL) {
|
|
||||||
mutex->lock();
|
|
||||||
}
|
|
||||||
if (s_server != NULL) {
|
|
||||||
s_server->close();
|
|
||||||
delete s_server;
|
|
||||||
s_server = NULL;
|
|
||||||
}
|
|
||||||
CLog::setLock(NULL);
|
|
||||||
s_logMutex = NULL;
|
|
||||||
throw;
|
|
||||||
}
|
}
|
||||||
}
|
catch (XThread&) {
|
||||||
catch (XBase& e) {
|
// terminated
|
||||||
log((CLOG_CRIT "failed: %s", e.what()));
|
return kExitTerminated;
|
||||||
return 16;
|
}
|
||||||
}
|
} while (s_restartable);
|
||||||
catch (XThread&) {
|
|
||||||
// terminated
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
return result;
|
||||||
}
|
|
||||||
|
|
||||||
static
|
|
||||||
int
|
|
||||||
restartMain()
|
|
||||||
{
|
|
||||||
return realMain(NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
// invoke realMain and wait for it. if s_restartable then keep
|
|
||||||
// restarting realMain until it returns a terminate code.
|
|
||||||
static
|
|
||||||
int
|
|
||||||
restartableMain()
|
|
||||||
{
|
|
||||||
if (s_restartable) {
|
|
||||||
CPlatform platform;
|
|
||||||
return platform.restart(restartMain, 16);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
return realMain(NULL);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -308,7 +300,7 @@ isArg(int argi, int argc, const char** argv,
|
||||||
if (argi + minRequiredParameters >= argc) {
|
if (argi + minRequiredParameters >= argc) {
|
||||||
log((CLOG_PRINT "%s: missing arguments for `%s'" BYE,
|
log((CLOG_PRINT "%s: missing arguments for `%s'" BYE,
|
||||||
pname, argv[argi], pname));
|
pname, argv[argi], pname));
|
||||||
bye(2);
|
bye(kExitArgs);
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -347,7 +339,7 @@ parse(int argc, const char** argv)
|
||||||
catch (XSocketAddress&) {
|
catch (XSocketAddress&) {
|
||||||
log((CLOG_PRINT "%s: invalid address for `%s'" BYE,
|
log((CLOG_PRINT "%s: invalid address for `%s'" BYE,
|
||||||
pname, argv[i], pname));
|
pname, argv[i], pname));
|
||||||
bye(2);
|
bye(kExitArgs);
|
||||||
}
|
}
|
||||||
++i;
|
++i;
|
||||||
}
|
}
|
||||||
|
@ -360,7 +352,7 @@ parse(int argc, const char** argv)
|
||||||
catch (XSocketAddress&) {
|
catch (XSocketAddress&) {
|
||||||
log((CLOG_PRINT "%s: invalid address for `%s'" BYE,
|
log((CLOG_PRINT "%s: invalid address for `%s'" BYE,
|
||||||
pname, argv[i], pname));
|
pname, argv[i], pname));
|
||||||
bye(2);
|
bye(kExitArgs);
|
||||||
}
|
}
|
||||||
++i;
|
++i;
|
||||||
}
|
}
|
||||||
|
@ -397,12 +389,12 @@ parse(int argc, const char** argv)
|
||||||
|
|
||||||
else if (isArg(i, argc, argv, "-h", "--help")) {
|
else if (isArg(i, argc, argv, "-h", "--help")) {
|
||||||
help();
|
help();
|
||||||
bye(0);
|
bye(kExitSuccess);
|
||||||
}
|
}
|
||||||
|
|
||||||
else if (isArg(i, argc, argv, NULL, "--version")) {
|
else if (isArg(i, argc, argv, NULL, "--version")) {
|
||||||
version();
|
version();
|
||||||
bye(0);
|
bye(kExitSuccess);
|
||||||
}
|
}
|
||||||
|
|
||||||
#if WINDOWS_LIKE
|
#if WINDOWS_LIKE
|
||||||
|
@ -412,7 +404,7 @@ parse(int argc, const char** argv)
|
||||||
log((CLOG_PRINT "%s: `--install' and `--uninstall'"
|
log((CLOG_PRINT "%s: `--install' and `--uninstall'"
|
||||||
" are mutually exclusive" BYE,
|
" are mutually exclusive" BYE,
|
||||||
pname, argv[i], pname));
|
pname, argv[i], pname));
|
||||||
bye(2);
|
bye(kExitArgs);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@ -424,7 +416,7 @@ parse(int argc, const char** argv)
|
||||||
log((CLOG_PRINT "%s: `--install' and `--uninstall'"
|
log((CLOG_PRINT "%s: `--install' and `--uninstall'"
|
||||||
" are mutually exclusive" BYE,
|
" are mutually exclusive" BYE,
|
||||||
pname, argv[i], pname));
|
pname, argv[i], pname));
|
||||||
bye(2);
|
bye(kExitArgs);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@ -438,7 +430,7 @@ parse(int argc, const char** argv)
|
||||||
else if (argv[i][0] == '-') {
|
else if (argv[i][0] == '-') {
|
||||||
log((CLOG_PRINT "%s: unrecognized option `%s'" BYE,
|
log((CLOG_PRINT "%s: unrecognized option `%s'" BYE,
|
||||||
pname, argv[i], pname));
|
pname, argv[i], pname));
|
||||||
bye(2);
|
bye(kExitArgs);
|
||||||
}
|
}
|
||||||
|
|
||||||
else {
|
else {
|
||||||
|
@ -451,7 +443,7 @@ parse(int argc, const char** argv)
|
||||||
if (i != argc) {
|
if (i != argc) {
|
||||||
log((CLOG_PRINT "%s: unrecognized option `%s'" BYE,
|
log((CLOG_PRINT "%s: unrecognized option `%s'" BYE,
|
||||||
pname, argv[i], pname));
|
pname, argv[i], pname));
|
||||||
bye(2);
|
bye(kExitArgs);
|
||||||
}
|
}
|
||||||
|
|
||||||
// increase default filter level for daemon. the user must
|
// increase default filter level for daemon. the user must
|
||||||
|
@ -474,7 +466,7 @@ parse(int argc, const char** argv)
|
||||||
if (!CLog::setFilter(s_logFilter)) {
|
if (!CLog::setFilter(s_logFilter)) {
|
||||||
log((CLOG_PRINT "%s: unrecognized log level `%s'" BYE,
|
log((CLOG_PRINT "%s: unrecognized log level `%s'" BYE,
|
||||||
pname, s_logFilter, pname));
|
pname, s_logFilter, pname));
|
||||||
bye(2);
|
bye(kExitArgs);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -499,7 +491,7 @@ loadConfig(const char* pathname, bool require)
|
||||||
if (require) {
|
if (require) {
|
||||||
log((CLOG_PRINT "%s: cannot read configuration '%s': %s",
|
log((CLOG_PRINT "%s: cannot read configuration '%s': %s",
|
||||||
pname, pathname, e.what()));
|
pname, pathname, e.what()));
|
||||||
bye(3);
|
bye(kExitConfig);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
log((CLOG_DEBUG "cannot read configuration \"%s\": %s",
|
log((CLOG_DEBUG "cannot read configuration \"%s\": %s",
|
||||||
|
@ -595,7 +587,7 @@ daemonStartup(IPlatform* iplatform, int argc, const char** argv)
|
||||||
parse(argc, argv);
|
parse(argc, argv);
|
||||||
if (s_install || s_uninstall) {
|
if (s_install || s_uninstall) {
|
||||||
// not allowed to install/uninstall from service
|
// not allowed to install/uninstall from service
|
||||||
throw CWin32Platform::CDaemonFailed(1);
|
throw CWin32Platform::CDaemonFailed(kExitArgs);
|
||||||
}
|
}
|
||||||
|
|
||||||
// load configuration
|
// load configuration
|
||||||
|
@ -609,7 +601,7 @@ static
|
||||||
int
|
int
|
||||||
daemonStartup95(IPlatform*, int, const char**)
|
daemonStartup95(IPlatform*, int, const char**)
|
||||||
{
|
{
|
||||||
return restartableMain();
|
return realMain(NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
int WINAPI
|
int WINAPI
|
||||||
|
@ -639,7 +631,7 @@ WinMain(HINSTANCE instance, HINSTANCE, LPSTR, int)
|
||||||
int result = platform.daemonize(DAEMON_NAME, &daemonStartup);
|
int 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 kExitFailed;
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
@ -654,7 +646,7 @@ WinMain(HINSTANCE instance, HINSTANCE, LPSTR, int)
|
||||||
if (GetModuleFileName(NULL, path,
|
if (GetModuleFileName(NULL, path,
|
||||||
sizeof(path) / sizeof(path[0])) == 0) {
|
sizeof(path) / sizeof(path[0])) == 0) {
|
||||||
log((CLOG_CRIT "cannot determine absolute path to program"));
|
log((CLOG_CRIT "cannot determine absolute path to program"));
|
||||||
return 16;
|
return kExitFailed;
|
||||||
}
|
}
|
||||||
|
|
||||||
// construct the command line to start the service with
|
// construct the command line to start the service with
|
||||||
|
@ -681,24 +673,24 @@ WinMain(HINSTANCE instance, HINSTANCE, LPSTR, int)
|
||||||
"Shares this system's mouse and keyboard with others.",
|
"Shares this system's mouse and keyboard with others.",
|
||||||
path, commandLine.c_str())) {
|
path, commandLine.c_str())) {
|
||||||
log((CLOG_CRIT "failed to install service"));
|
log((CLOG_CRIT "failed to install service"));
|
||||||
return 16;
|
return kExitFailed;
|
||||||
}
|
}
|
||||||
log((CLOG_PRINT "installed successfully"));
|
log((CLOG_PRINT "installed successfully"));
|
||||||
return 0;
|
return kExitSuccess;
|
||||||
}
|
}
|
||||||
else if (s_uninstall) {
|
else if (s_uninstall) {
|
||||||
switch (platform.uninstallDaemon(DAEMON_NAME)) {
|
switch (platform.uninstallDaemon(DAEMON_NAME)) {
|
||||||
case IPlatform::kSuccess:
|
case IPlatform::kSuccess:
|
||||||
log((CLOG_PRINT "uninstalled successfully"));
|
log((CLOG_PRINT "uninstalled successfully"));
|
||||||
return 0;
|
return kExitSuccess;
|
||||||
|
|
||||||
case IPlatform::kFailed:
|
case IPlatform::kFailed:
|
||||||
log((CLOG_CRIT "failed to uninstall service"));
|
log((CLOG_CRIT "failed to uninstall service"));
|
||||||
return 16;
|
return kExitFailed;
|
||||||
|
|
||||||
case IPlatform::kAlready:
|
case IPlatform::kAlready:
|
||||||
log((CLOG_CRIT "service isn't installed"));
|
log((CLOG_CRIT "service isn't installed"));
|
||||||
return 16;
|
return kExitFailed;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -716,18 +708,18 @@ WinMain(HINSTANCE instance, HINSTANCE, LPSTR, int)
|
||||||
result = platform.daemonize(DAEMON_NAME, &daemonStartup95);
|
result = platform.daemonize(DAEMON_NAME, &daemonStartup95);
|
||||||
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 kExitFailed;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
// cannot start a service from the command line so just
|
// cannot start a service from the command line so just
|
||||||
// run normally (except with log messages redirected).
|
// run normally (except with log messages redirected).
|
||||||
result = restartableMain();
|
result = realMain(NULL);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
// run
|
// run
|
||||||
result = restartableMain();
|
result = realMain(NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
CNetwork::cleanup();
|
CNetwork::cleanup();
|
||||||
|
@ -741,7 +733,7 @@ static
|
||||||
int
|
int
|
||||||
daemonStartup(IPlatform*, int, const char**)
|
daemonStartup(IPlatform*, int, const char**)
|
||||||
{
|
{
|
||||||
return restartableMain();
|
return realMain(NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
|
@ -767,11 +759,11 @@ main(int argc, char** argv)
|
||||||
result = platform.daemonize(DAEMON_NAME, &daemonStartup);
|
result = platform.daemonize(DAEMON_NAME, &daemonStartup);
|
||||||
if (result == -1) {
|
if (result == -1) {
|
||||||
log((CLOG_CRIT "failed to daemonize"));
|
log((CLOG_CRIT "failed to daemonize"));
|
||||||
return 16;
|
return kExitFailed;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
result = restartableMain();
|
result = realMain(NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
CNetwork::cleanup();
|
CNetwork::cleanup();
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
|
|
||||||
// version number
|
// version number
|
||||||
static const SInt16 kProtocolMajorVersion = 0;
|
static const SInt16 kProtocolMajorVersion = 0;
|
||||||
static const SInt16 kProtocolMinorVersion = 1;
|
static const SInt16 kProtocolMinorVersion = 7;
|
||||||
|
|
||||||
// contact port number
|
// contact port number
|
||||||
static const UInt16 kDefaultPort = 24800;
|
static const UInt16 kDefaultPort = 24800;
|
||||||
|
@ -87,7 +87,7 @@ static const char kMsgCScreenSaver[] = "CSEC%1i";
|
||||||
// sent by primary in response to a secondary screen's kMsgDInfo.
|
// sent by primary in response to a secondary screen's kMsgDInfo.
|
||||||
// this is sent for every kMsgDInfo, whether or not the primary
|
// this is sent for every kMsgDInfo, whether or not the primary
|
||||||
// had sent a kMsgQInfo.
|
// had sent a kMsgQInfo.
|
||||||
static const char kMsgCInfoAck[] = "CIAK";
|
static const char kMsgCInfoAck[] = "CIAK";
|
||||||
|
|
||||||
|
|
||||||
//
|
//
|
||||||
|
@ -165,16 +165,16 @@ static const char kMsgQInfo[] = "QINF";
|
||||||
static const char kMsgEIncompatible[] = "EICV%2i%2i";
|
static const char kMsgEIncompatible[] = "EICV%2i%2i";
|
||||||
|
|
||||||
// name provided when connecting is already in use: primary -> secondary
|
// name provided when connecting is already in use: primary -> secondary
|
||||||
static const char kMsgEBusy[] = "EBSY";
|
static const char kMsgEBusy[] = "EBSY";
|
||||||
|
|
||||||
// unknown client: primary -> secondary
|
// unknown client: primary -> secondary
|
||||||
// name provided when connecting is not in primary's screen
|
// name provided when connecting is not in primary's screen
|
||||||
// configuration map.
|
// configuration map.
|
||||||
static const char kMsgEUnknown[] = "EUNK";
|
static const char kMsgEUnknown[] = "EUNK";
|
||||||
|
|
||||||
// protocol violation: primary -> secondary
|
// protocol violation: primary -> secondary
|
||||||
// primary should disconnect after sending this message.
|
// primary should disconnect after sending this message.
|
||||||
static const char kMsgEBad[] = "EBAD";
|
static const char kMsgEBad[] = "EBAD";
|
||||||
|
|
||||||
|
|
||||||
//
|
//
|
||||||
|
|
|
@ -4,10 +4,19 @@
|
||||||
#include "BasicTypes.h"
|
#include "BasicTypes.h"
|
||||||
|
|
||||||
static const char* kCopyright = "Copyright (C) 2002 Chris Schoeneman";
|
static const char* kCopyright = "Copyright (C) 2002 Chris Schoeneman";
|
||||||
|
static const char* kContact = "Chris Schoeneman crs23@bigfoot.com";
|
||||||
|
|
||||||
// build version
|
// build version. follows linux kernel style: minor number even implies
|
||||||
|
// a release version, odd implies development version.
|
||||||
static const SInt16 kMajorVersion = 0;
|
static const SInt16 kMajorVersion = 0;
|
||||||
static const SInt16 kMinorVersion = 5;
|
static const SInt16 kMinorVersion = 9;
|
||||||
static const SInt16 kReleaseVersion = 0;
|
static const SInt16 kReleaseVersion = 7;
|
||||||
|
|
||||||
|
// exit codes
|
||||||
|
static const int kExitSuccess = 0; // successful completion
|
||||||
|
static const int kExitFailed = 1; // general failure
|
||||||
|
static const int kExitTerminated = 2; // killed by signal
|
||||||
|
static const int kExitArgs = 3; // bad arguments
|
||||||
|
static const int kExitConfig = 4; // cannot read configuration
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
Loading…
Reference in New Issue