performance fixes on win32 plus clean up of some warnings. also
improved error messages when uninstalling service.
This commit is contained in:
parent
21af7b2f17
commit
e3dcf7febf
|
@ -11,6 +11,11 @@ CFunctionJob::CFunctionJob(void (*func)(void*), void* arg) :
|
||||||
// do nothing
|
// do nothing
|
||||||
}
|
}
|
||||||
|
|
||||||
|
CFunctionJob::~CFunctionJob()
|
||||||
|
{
|
||||||
|
// do nothing
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
CFunctionJob::run()
|
CFunctionJob::run()
|
||||||
{
|
{
|
||||||
|
|
|
@ -6,6 +6,7 @@
|
||||||
class CFunctionJob : public IJob {
|
class CFunctionJob : public IJob {
|
||||||
public:
|
public:
|
||||||
CFunctionJob(void (*func)(void*), void* arg = NULL);
|
CFunctionJob(void (*func)(void*), void* arg = NULL);
|
||||||
|
virtual ~CFunctionJob();
|
||||||
|
|
||||||
// IJob overrides
|
// IJob overrides
|
||||||
virtual void run();
|
virtual void run();
|
||||||
|
|
|
@ -65,6 +65,11 @@ CLog::print(
|
||||||
fmt += 3;
|
fmt += 3;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// done if below priority threshold
|
||||||
|
if (priority > getMaxPriority()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// compute prefix padding length
|
// compute prefix padding length
|
||||||
int pad = g_priorityPad;
|
int pad = g_priorityPad;
|
||||||
|
|
||||||
|
@ -98,6 +103,11 @@ CLog::printt(
|
||||||
fmt += 3;
|
fmt += 3;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// done if below priority threshold
|
||||||
|
if (priority > getMaxPriority()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// compute prefix padding length
|
// compute prefix padding length
|
||||||
char stack[1024];
|
char stack[1024];
|
||||||
sprintf(stack, "%d", line);
|
sprintf(stack, "%d", line);
|
||||||
|
@ -217,34 +227,32 @@ CLog::output(
|
||||||
char* msg)
|
char* msg)
|
||||||
{
|
{
|
||||||
assert(priority >= -1 && priority < g_numPriority);
|
assert(priority >= -1 && priority < g_numPriority);
|
||||||
assert(msg != 0);
|
assert(msg != NULL);
|
||||||
|
|
||||||
if (priority <= getMaxPriority()) {
|
// insert priority label
|
||||||
// insert priority label
|
int n = -g_prioritySuffixLength;
|
||||||
int n = -g_prioritySuffixLength;
|
if (priority >= 0) {
|
||||||
if (priority >= 0) {
|
n = strlen(g_priority[priority]);
|
||||||
n = strlen(g_priority[priority]);
|
sprintf(msg + g_maxPriorityLength - n,
|
||||||
sprintf(msg + g_maxPriorityLength - n,
|
"%s:", g_priority[priority]);
|
||||||
"%s:", g_priority[priority]);
|
msg[g_maxPriorityLength + 1] = ' ';
|
||||||
msg[g_maxPriorityLength + 1] = ' ';
|
}
|
||||||
}
|
|
||||||
|
|
||||||
// put a newline at the end
|
// put a newline at the end
|
||||||
#if defined(CONFIG_PLATFORM_WIN32)
|
#if defined(CONFIG_PLATFORM_WIN32)
|
||||||
strcat(msg + g_priorityPad, "\r\n");
|
strcat(msg + g_priorityPad, "\r\n");
|
||||||
#else
|
#else
|
||||||
strcat(msg + g_priorityPad, "\n");
|
strcat(msg + g_priorityPad, "\n");
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// print it
|
// print it
|
||||||
CHoldLock lock(s_lock);
|
CHoldLock lock(s_lock);
|
||||||
if (s_outputter == NULL ||
|
if (s_outputter == NULL ||
|
||||||
!s_outputter(priority, msg + g_maxPriorityLength - n)) {
|
!s_outputter(priority, msg + g_maxPriorityLength - n)) {
|
||||||
#if defined(CONFIG_PLATFORM_WIN32)
|
#if defined(CONFIG_PLATFORM_WIN32)
|
||||||
openConsole();
|
openConsole();
|
||||||
#endif
|
#endif
|
||||||
fprintf(stderr, "%s", msg + g_maxPriorityLength - n);
|
fprintf(stderr, "%s", msg + g_maxPriorityLength - n);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -267,7 +275,7 @@ CLog::vsprint(
|
||||||
}
|
}
|
||||||
|
|
||||||
// start allocating buffers until we write the whole string
|
// start allocating buffers until we write the whole string
|
||||||
buffer = 0;
|
buffer = NULL;
|
||||||
do {
|
do {
|
||||||
delete[] buffer;
|
delete[] buffer;
|
||||||
len *= 2;
|
len *= 2;
|
||||||
|
|
|
@ -7,6 +7,7 @@ template <class T>
|
||||||
class TMethodJob : public IJob {
|
class TMethodJob : public IJob {
|
||||||
public:
|
public:
|
||||||
TMethodJob(T* object, void (T::*method)(void*), void* arg = NULL);
|
TMethodJob(T* object, void (T::*method)(void*), void* arg = NULL);
|
||||||
|
virtual ~TMethodJob();
|
||||||
|
|
||||||
// IJob overrides
|
// IJob overrides
|
||||||
virtual void run();
|
virtual void run();
|
||||||
|
@ -27,6 +28,13 @@ TMethodJob<T>::TMethodJob(T* object, void (T::*method)(void*), void* arg) :
|
||||||
// do nothing
|
// do nothing
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
inline
|
||||||
|
TMethodJob<T>::~TMethodJob()
|
||||||
|
{
|
||||||
|
// do nothing
|
||||||
|
}
|
||||||
|
|
||||||
template <class T>
|
template <class T>
|
||||||
inline
|
inline
|
||||||
void
|
void
|
||||||
|
|
|
@ -30,6 +30,12 @@
|
||||||
// this one's a little too aggressive
|
// this one's a little too aggressive
|
||||||
#pragma warning(disable: 4127) // conditional expression is constant
|
#pragma warning(disable: 4127) // conditional expression is constant
|
||||||
|
|
||||||
|
// emitted incorrectly under release build in some circumstances
|
||||||
|
#if defined(NDEBUG)
|
||||||
|
#pragma warning(disable: 4702) // unreachable code
|
||||||
|
#pragma warning(disable: 4701) // local variable maybe used uninitialized
|
||||||
|
#endif
|
||||||
|
|
||||||
#endif // (_MSC_VER >= 1200)
|
#endif // (_MSC_VER >= 1200)
|
||||||
|
|
||||||
#else
|
#else
|
||||||
|
|
|
@ -16,6 +16,7 @@
|
||||||
CMSWindowsSecondaryScreen::CMSWindowsSecondaryScreen() :
|
CMSWindowsSecondaryScreen::CMSWindowsSecondaryScreen() :
|
||||||
m_client(NULL),
|
m_client(NULL),
|
||||||
m_threadID(0),
|
m_threadID(0),
|
||||||
|
m_lastThreadID(0),
|
||||||
m_desk(NULL),
|
m_desk(NULL),
|
||||||
m_deskName(),
|
m_deskName(),
|
||||||
m_window(NULL),
|
m_window(NULL),
|
||||||
|
@ -741,17 +742,23 @@ CMSWindowsSecondaryScreen::syncDesktop() const
|
||||||
{
|
{
|
||||||
// note -- mutex must be locked on entry
|
// note -- mutex must be locked on entry
|
||||||
|
|
||||||
DWORD threadID = GetCurrentThreadId();
|
// change calling thread's desktop
|
||||||
if (!m_is95Family) {
|
if (!m_is95Family) {
|
||||||
if (GetThreadDesktop(threadID) != m_desk) {
|
if (SetThreadDesktop(m_desk) == 0) {
|
||||||
// FIXME -- this doesn't work. if we set a desktop then
|
log((CLOG_WARN "failed to set desktop: %d", GetLastError()));
|
||||||
// sending events doesn't work.
|
|
||||||
if (SetThreadDesktop(m_desk) == 0) {
|
|
||||||
log((CLOG_ERR "failed to set desktop: %d", GetLastError()));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
AttachThreadInput(threadID, m_threadID, TRUE);
|
|
||||||
|
// attach input queues if not already attached. this has a habit
|
||||||
|
// of sucking up more and more CPU each time it's called (even if
|
||||||
|
// the threads are already attached). since we only expect one
|
||||||
|
// thread to call this more than once we can save just the last
|
||||||
|
// the attached thread.
|
||||||
|
DWORD threadID = GetCurrentThreadId();
|
||||||
|
if (threadID != m_lastThreadID && threadID != m_threadID) {
|
||||||
|
m_lastThreadID = threadID;
|
||||||
|
AttachThreadInput(threadID, m_threadID, TRUE);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
CString
|
CString
|
||||||
|
|
|
@ -89,6 +89,9 @@ private:
|
||||||
// the main loop's thread id
|
// the main loop's thread id
|
||||||
DWORD m_threadID;
|
DWORD m_threadID;
|
||||||
|
|
||||||
|
// the thread id of the last attached thread
|
||||||
|
mutable DWORD m_lastThreadID;
|
||||||
|
|
||||||
// the current desk and it's name
|
// the current desk and it's name
|
||||||
HDESK m_desk;
|
HDESK m_desk;
|
||||||
CString m_deskName;
|
CString m_deskName;
|
||||||
|
|
|
@ -16,10 +16,8 @@
|
||||||
|
|
||||||
// platform dependent name of a daemon
|
// platform dependent name of a daemon
|
||||||
#if defined(CONFIG_PLATFORM_WIN32)
|
#if defined(CONFIG_PLATFORM_WIN32)
|
||||||
#define DAEMON "service"
|
|
||||||
#define DAEMON_NAME "Synergy Client"
|
#define DAEMON_NAME "Synergy Client"
|
||||||
#elif defined(CONFIG_PLATFORM_UNIX)
|
#elif defined(CONFIG_PLATFORM_UNIX)
|
||||||
#define DAEMON "daemon"
|
|
||||||
#define DAEMON_NAME "synergy"
|
#define DAEMON_NAME "synergy"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -127,8 +125,6 @@ realMain(
|
||||||
// terminated
|
// terminated
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static
|
static
|
||||||
|
@ -182,17 +178,34 @@ static
|
||||||
void
|
void
|
||||||
help()
|
help()
|
||||||
{
|
{
|
||||||
|
#if defined(CONFIG_PLATFORM_WIN32)
|
||||||
|
|
||||||
|
# define PLATFORM_ARGS \
|
||||||
|
" [--install]" \
|
||||||
|
" <server-address>\n" \
|
||||||
|
"or\n" \
|
||||||
|
" --uninstall\n"
|
||||||
|
# define PLATFORM_DESC \
|
||||||
|
" --install install server as a service.\n" \
|
||||||
|
" --uninstall uninstall server service.\n"
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
# define PLATFORM_ARGS \
|
||||||
|
" <server-address>\n"
|
||||||
|
# define PLATFORM_DESC
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
log((CLOG_PRINT
|
log((CLOG_PRINT
|
||||||
"Usage: %s"
|
"Usage: %s"
|
||||||
" [--"DAEMON"|--no-"DAEMON"]"
|
|
||||||
" [--camp|--no-camp]"
|
" [--camp|--no-camp]"
|
||||||
|
" [--daemon|--no-daemon]"
|
||||||
" [--debug <level>]"
|
" [--debug <level>]"
|
||||||
" [--name <screen-name>]"
|
" [--name <screen-name>]"
|
||||||
" [--restart|--no-restart]"
|
" [--restart|--no-restart]"
|
||||||
" [--install]"
|
PLATFORM_ARGS
|
||||||
" <server-address>\n"
|
"\n"
|
||||||
"or\n"
|
|
||||||
" --uninstall\n"
|
|
||||||
"Start the synergy mouse/keyboard sharing server.\n"
|
"Start the synergy mouse/keyboard sharing server.\n"
|
||||||
"\n"
|
"\n"
|
||||||
"* --camp keep attempting to connect to the server until\n"
|
"* --camp keep attempting to connect to the server until\n"
|
||||||
|
@ -201,8 +214,8 @@ help()
|
||||||
" -d, --debug <level> filter out log messages with priorty below level.\n"
|
" -d, --debug <level> filter out log messages with priorty below level.\n"
|
||||||
" level may be: FATAL, ERROR, WARNING, NOTE, INFO,\n"
|
" level may be: FATAL, ERROR, WARNING, NOTE, INFO,\n"
|
||||||
" DEBUG, DEBUG1, DEBUG2.\n"
|
" DEBUG, DEBUG1, DEBUG2.\n"
|
||||||
" -f, --no-"DAEMON" run the client in the foreground.\n"
|
" -f, --no-daemon run the client in the foreground.\n"
|
||||||
"* --"DAEMON" run the client as a "DAEMON".\n"
|
"* --daemon run the client as a daemon.\n"
|
||||||
" -n, --name <screen-name> use screen-name instead the hostname to identify\n"
|
" -n, --name <screen-name> use screen-name instead the hostname to identify\n"
|
||||||
" 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"
|
||||||
|
@ -210,9 +223,8 @@ help()
|
||||||
"* --restart restart the client automatically if it fails for\n"
|
"* --restart restart the client automatically if it fails for\n"
|
||||||
" some unexpected reason, including the server\n"
|
" some unexpected reason, including the server\n"
|
||||||
" disconnecting but not including failing to\n"
|
" disconnecting but not including failing to\n"
|
||||||
" connect to the server."
|
" connect to the server.\n"
|
||||||
" --install install server as a "DAEMON".\n"
|
PLATFORM_DESC
|
||||||
" --uninstall uninstall server "DAEMON".\n"
|
|
||||||
" -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"
|
||||||
"\n"
|
"\n"
|
||||||
|
@ -223,7 +235,7 @@ help()
|
||||||
"default port, %d.\n"
|
"default port, %d.\n"
|
||||||
"\n"
|
"\n"
|
||||||
"Where log messages go depends on the platform and whether or not the\n"
|
"Where log messages go depends on the platform and whether or not the\n"
|
||||||
"client is running as a "DAEMON".",
|
"client is running as a daemon.",
|
||||||
pname, kDefaultPort));
|
pname, kDefaultPort));
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -291,12 +303,12 @@ parse(
|
||||||
s_camp = false;
|
s_camp = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
else if (isArg(i, argc, argv, "-f", "--no-"DAEMON)) {
|
else if (isArg(i, argc, argv, "-f", "--no-daemon")) {
|
||||||
// not a daemon
|
// not a daemon
|
||||||
s_daemon = false;
|
s_daemon = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
else if (isArg(i, argc, argv, NULL, "--"DAEMON)) {
|
else if (isArg(i, argc, argv, NULL, "--daemon")) {
|
||||||
// daemonize
|
// daemonize
|
||||||
s_daemon = true;
|
s_daemon = true;
|
||||||
}
|
}
|
||||||
|
@ -321,12 +333,8 @@ parse(
|
||||||
bye(0);
|
bye(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if defined(CONFIG_PLATFORM_WIN32)
|
||||||
else if (isArg(i, argc, argv, NULL, "--install")) {
|
else if (isArg(i, argc, argv, NULL, "--install")) {
|
||||||
#if !defined(CONFIG_PLATFORM_WIN32)
|
|
||||||
log((CLOG_PRINT "%s: `%s' not supported on this platform" BYE,
|
|
||||||
pname, argv[i], pname));
|
|
||||||
bye(2);
|
|
||||||
#endif
|
|
||||||
s_install = true;
|
s_install = true;
|
||||||
if (s_uninstall) {
|
if (s_uninstall) {
|
||||||
log((CLOG_PRINT "%s: `--install' and `--uninstall'"
|
log((CLOG_PRINT "%s: `--install' and `--uninstall'"
|
||||||
|
@ -335,13 +343,10 @@ parse(
|
||||||
bye(2);
|
bye(2);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
else if (isArg(i, argc, argv, NULL, "--uninstall")) {
|
|
||||||
#if !defined(CONFIG_PLATFORM_WIN32)
|
|
||||||
log((CLOG_PRINT "%s: `%s' not supported on this platform" BYE,
|
|
||||||
pname, argv[i], pname));
|
|
||||||
bye(2);
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if defined(CONFIG_PLATFORM_WIN32)
|
||||||
|
else if (isArg(i, argc, argv, NULL, "--uninstall")) {
|
||||||
s_uninstall = true;
|
s_uninstall = true;
|
||||||
if (s_install) {
|
if (s_install) {
|
||||||
log((CLOG_PRINT "%s: `--install' and `--uninstall'"
|
log((CLOG_PRINT "%s: `--install' and `--uninstall'"
|
||||||
|
@ -350,6 +355,7 @@ parse(
|
||||||
bye(2);
|
bye(2);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
else if (isArg(i, argc, argv, "--", NULL)) {
|
else if (isArg(i, argc, argv, "--", NULL)) {
|
||||||
// remaining arguments are not options
|
// remaining arguments are not options
|
||||||
|
@ -490,16 +496,6 @@ daemonStartup(
|
||||||
return platform->runDaemon(realMain, daemonStop);
|
return platform->runDaemon(realMain, daemonStop);
|
||||||
}
|
}
|
||||||
|
|
||||||
static
|
|
||||||
int
|
|
||||||
daemonStartup95(
|
|
||||||
IPlatform*,
|
|
||||||
int,
|
|
||||||
const char**)
|
|
||||||
{
|
|
||||||
return realMain(NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
static
|
static
|
||||||
bool
|
bool
|
||||||
logDiscard(
|
logDiscard(
|
||||||
|
@ -556,12 +552,13 @@ WinMain(
|
||||||
// ignore
|
// ignore
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// send PRINT and FATAL output to a message box
|
||||||
|
CLog::setOutputter(&logMessageBox);
|
||||||
|
|
||||||
// if we're not starting as an NT service then reparse the command
|
// if we're not starting as an NT service then reparse the command
|
||||||
// line normally.
|
// line normally.
|
||||||
if (s_die || !s_daemon || s_install || s_uninstall ||
|
if (s_die || __argc > 1 || s_install || s_uninstall ||
|
||||||
CWin32Platform::isWindows95Family()) {
|
CWin32Platform::isWindows95Family()) {
|
||||||
// send PRINT and FATAL output to a message box
|
|
||||||
CLog::setOutputter(&logMessageBox);
|
|
||||||
|
|
||||||
// exit on bye
|
// exit on bye
|
||||||
bye = &exit;
|
bye = &exit;
|
||||||
|
@ -570,9 +567,9 @@ WinMain(
|
||||||
parse(__argc, const_cast<const char**>(__argv));
|
parse(__argc, const_cast<const char**>(__argv));
|
||||||
}
|
}
|
||||||
|
|
||||||
// if starting as a daemon then we ignore the startup command line
|
// if no arguments were provided then we're hopefully starting as
|
||||||
// here. we'll parse the command line passed in when the service
|
// a service. we'll parse the command line passed in when the
|
||||||
// control manager calls us back.
|
// service control manager calls us back.
|
||||||
else {
|
else {
|
||||||
// do nothing
|
// do nothing
|
||||||
}
|
}
|
||||||
|
@ -588,7 +585,7 @@ WinMain(
|
||||||
}
|
}
|
||||||
|
|
||||||
// construct the command line to start the service with
|
// construct the command line to start the service with
|
||||||
CString commandLine = "--"DAEMON;
|
CString commandLine = "--daemon";
|
||||||
if (s_restartable) {
|
if (s_restartable) {
|
||||||
commandLine += " --restart";
|
commandLine += " --restart";
|
||||||
}
|
}
|
||||||
|
@ -613,29 +610,42 @@ WinMain(
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
else if (s_uninstall) {
|
else if (s_uninstall) {
|
||||||
if (!platform.uninstallDaemon(DAEMON_NAME)) {
|
switch (platform.uninstallDaemon(DAEMON_NAME)) {
|
||||||
|
case IPlatform::kSuccess:
|
||||||
|
log((CLOG_PRINT "uninstalled successfully"));
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
case IPlatform::kFailed:
|
||||||
log((CLOG_CRIT "failed to uninstall service"));
|
log((CLOG_CRIT "failed to uninstall service"));
|
||||||
return 16;
|
return 16;
|
||||||
|
|
||||||
|
case IPlatform::kAlready:
|
||||||
|
log((CLOG_CRIT "service isn't installed"));
|
||||||
|
return 16;
|
||||||
}
|
}
|
||||||
log((CLOG_PRINT "uninstalled successfully"));
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// daemonize if requested
|
// daemonize if requested
|
||||||
int result;
|
int result;
|
||||||
if (s_daemon) {
|
if (__argc <= 1) {
|
||||||
if (CWin32Platform::isWindows95Family()) {
|
if (CWin32Platform::isWindows95Family()) {
|
||||||
result = platform.daemonize(DAEMON_NAME, &daemonStartup95);
|
result = -1;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
result = platform.daemonize(DAEMON_NAME, &daemonStartup);
|
result = platform.daemonize(DAEMON_NAME, &daemonStartup);
|
||||||
}
|
}
|
||||||
if (result == -1) {
|
if (result == -1) {
|
||||||
log((CLOG_CRIT "failed to start as a service"));
|
log((CLOG_CRIT "failed to start as a service" BYE, pname));
|
||||||
return 16;
|
return 16;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
// if a daemon then redirect log
|
||||||
|
if (s_daemon) {
|
||||||
|
platform.installDaemonLogger(__argv[0]);
|
||||||
|
}
|
||||||
|
|
||||||
|
// run
|
||||||
result = restartableMain();
|
result = restartableMain();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -7,7 +7,8 @@
|
||||||
const UInt32 CStreamBuffer::kChunkSize = 4096;
|
const UInt32 CStreamBuffer::kChunkSize = 4096;
|
||||||
|
|
||||||
CStreamBuffer::CStreamBuffer() :
|
CStreamBuffer::CStreamBuffer() :
|
||||||
m_size(0)
|
m_size(0),
|
||||||
|
m_headUsed(0)
|
||||||
{
|
{
|
||||||
// do nothing
|
// do nothing
|
||||||
}
|
}
|
||||||
|
@ -25,17 +26,17 @@ CStreamBuffer::peek(
|
||||||
|
|
||||||
// reserve space in first chunk
|
// reserve space in first chunk
|
||||||
ChunkList::iterator head = m_chunks.begin();
|
ChunkList::iterator head = m_chunks.begin();
|
||||||
head->reserve(n);
|
head->reserve(n + m_headUsed);
|
||||||
|
|
||||||
// consolidate chunks into the first chunk until it has n bytes
|
// consolidate chunks into the first chunk until it has n bytes
|
||||||
ChunkList::iterator scan = head;
|
ChunkList::iterator scan = head;
|
||||||
++scan;
|
++scan;
|
||||||
while (head->size() < n && scan != m_chunks.end()) {
|
while (head->size() - m_headUsed < n && scan != m_chunks.end()) {
|
||||||
head->insert(head->end(), scan->begin(), scan->end());
|
head->insert(head->end(), scan->begin(), scan->end());
|
||||||
scan = m_chunks.erase(scan);
|
scan = m_chunks.erase(scan);
|
||||||
}
|
}
|
||||||
|
|
||||||
return reinterpret_cast<const void*>(head->begin());
|
return reinterpret_cast<const void*>(head->begin() + m_headUsed);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -44,7 +45,8 @@ CStreamBuffer::pop(
|
||||||
{
|
{
|
||||||
// discard all chunks if n is greater than or equal to m_size
|
// discard all chunks if n is greater than or equal to m_size
|
||||||
if (n >= m_size) {
|
if (n >= m_size) {
|
||||||
m_size = 0;
|
m_size = 0;
|
||||||
|
m_headUsed = 0;
|
||||||
m_chunks.clear();
|
m_chunks.clear();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -55,15 +57,16 @@ CStreamBuffer::pop(
|
||||||
// discard chunks until more than n bytes would've been discarded
|
// discard chunks until more than n bytes would've been discarded
|
||||||
ChunkList::iterator scan = m_chunks.begin();
|
ChunkList::iterator scan = m_chunks.begin();
|
||||||
assert(scan != m_chunks.end());
|
assert(scan != m_chunks.end());
|
||||||
while (scan->size() <= n) {
|
while (scan->size() - m_headUsed <= n) {
|
||||||
n -= scan->size();
|
n -= scan->size() - m_headUsed;
|
||||||
scan = m_chunks.erase(scan);
|
m_headUsed = 0;
|
||||||
|
scan = m_chunks.erase(scan);
|
||||||
assert(scan != m_chunks.end());
|
assert(scan != m_chunks.end());
|
||||||
}
|
}
|
||||||
|
|
||||||
// remove left over bytes from the head chunk
|
// remove left over bytes from the head chunk
|
||||||
if (n > 0) {
|
if (n > 0) {
|
||||||
scan->erase(scan->begin(), scan->begin() + n);
|
m_headUsed += n;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -33,6 +33,7 @@ private:
|
||||||
|
|
||||||
ChunkList m_chunks;
|
ChunkList m_chunks;
|
||||||
UInt32 m_size;
|
UInt32 m_size;
|
||||||
|
UInt32 m_headUsed;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -105,6 +105,16 @@ CThread::wait(
|
||||||
return currentRep->wait(m_rep, timeout);
|
return currentRep->wait(m_rep, timeout);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if defined(CONFIG_PLATFORM_WIN32)
|
||||||
|
bool
|
||||||
|
CThread::waitForEvent(
|
||||||
|
double timeout)
|
||||||
|
{
|
||||||
|
CThreadPtr currentRep(CThreadRep::getCurrentThreadRep());
|
||||||
|
return currentRep->waitForEvent(timeout);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
void
|
void
|
||||||
CThread::testCancel()
|
CThread::testCancel()
|
||||||
{
|
{
|
||||||
|
|
|
@ -1,6 +1,8 @@
|
||||||
#ifndef CTHREAD_H
|
#ifndef CTHREAD_H
|
||||||
#define CTHREAD_H
|
#define CTHREAD_H
|
||||||
|
|
||||||
|
#include "common.h"
|
||||||
|
|
||||||
class IJob;
|
class IJob;
|
||||||
class CThreadRep;
|
class CThreadRep;
|
||||||
|
|
||||||
|
@ -103,6 +105,13 @@ public:
|
||||||
// (cancellation point)
|
// (cancellation point)
|
||||||
bool wait(double timeout = -1.0) const;
|
bool wait(double timeout = -1.0) const;
|
||||||
|
|
||||||
|
#if defined(CONFIG_PLATFORM_WIN32)
|
||||||
|
// wait for a message in the queue. returns true if a message
|
||||||
|
// is available.
|
||||||
|
// (cancellation point)
|
||||||
|
static bool waitForEvent(double timeout = -1.0);
|
||||||
|
#endif
|
||||||
|
|
||||||
// get the exit result. does an implicit wait(). returns NULL
|
// get the exit result. does an implicit wait(). returns NULL
|
||||||
// immediately if called by a thread on itself. returns NULL for
|
// immediately if called by a thread on itself. returns NULL for
|
||||||
// threads that were cancelled.
|
// threads that were cancelled.
|
||||||
|
|
|
@ -614,7 +614,45 @@ CThreadRep::wait(
|
||||||
testCancel();
|
testCancel();
|
||||||
|
|
||||||
default:
|
default:
|
||||||
// error
|
// timeout or error
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
CThreadRep::waitForEvent(
|
||||||
|
double timeout)
|
||||||
|
{
|
||||||
|
// is cancellation enabled?
|
||||||
|
const DWORD n = (isCancellable() ? 1 : 0);
|
||||||
|
|
||||||
|
// convert timeout
|
||||||
|
DWORD t;
|
||||||
|
if (timeout < 0.0) {
|
||||||
|
t = INFINITE;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
t = (DWORD)(1000.0 * timeout);
|
||||||
|
}
|
||||||
|
|
||||||
|
// wait for this thread to be cancelled or for the target thread to
|
||||||
|
// terminate.
|
||||||
|
HANDLE handles[1];
|
||||||
|
handles[0] = m_cancel;
|
||||||
|
DWORD result = MsgWaitForMultipleObjects(n, handles, FALSE, t, QS_ALLINPUT);
|
||||||
|
|
||||||
|
// handle result
|
||||||
|
switch (result) {
|
||||||
|
case WAIT_OBJECT_0 + 1:
|
||||||
|
// message is available
|
||||||
|
return true;
|
||||||
|
|
||||||
|
case WAIT_OBJECT_0 + 0:
|
||||||
|
// this thread was cancelled. does not return.
|
||||||
|
testCancel();
|
||||||
|
|
||||||
|
default:
|
||||||
|
// timeout or error
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -43,6 +43,11 @@ public:
|
||||||
// wait for thread to exit or for current thread to cancel
|
// wait for thread to exit or for current thread to cancel
|
||||||
bool wait(CThreadRep*, double timeout);
|
bool wait(CThreadRep*, double timeout);
|
||||||
|
|
||||||
|
#if defined(CONFIG_PLATFORM_WIN32)
|
||||||
|
// wait for a message on the queue
|
||||||
|
bool waitForEvent(double timeout);
|
||||||
|
#endif
|
||||||
|
|
||||||
// set the priority
|
// set the priority
|
||||||
void setPriority(int n);
|
void setPriority(int n);
|
||||||
|
|
||||||
|
|
|
@ -202,9 +202,7 @@ CMSWindowsScreen::getEvent(
|
||||||
MSG* msg) const
|
MSG* msg) const
|
||||||
{
|
{
|
||||||
// wait for an event in a cancellable way
|
// wait for an event in a cancellable way
|
||||||
while (HIWORD(GetQueueStatus(QS_ALLINPUT)) == 0) {
|
CThread::waitForEvent();
|
||||||
CThread::sleep(0.01);
|
|
||||||
}
|
|
||||||
GetMessage(msg, NULL, 0, 0);
|
GetMessage(msg, NULL, 0, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -35,12 +35,12 @@ CUnixPlatform::installDaemon(
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
CUnixPlatform::EResult
|
||||||
CUnixPlatform::uninstallDaemon(
|
CUnixPlatform::uninstallDaemon(
|
||||||
const char*)
|
const char*)
|
||||||
{
|
{
|
||||||
// daemons don't require special installation
|
// daemons don't require special installation
|
||||||
return true;
|
return kSuccess;
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
|
@ -85,12 +85,20 @@ CUnixPlatform::daemonize(
|
||||||
dup(1);
|
dup(1);
|
||||||
|
|
||||||
// hook up logger
|
// hook up logger
|
||||||
setDaemonLogger(name);
|
installDaemonLogger(name);
|
||||||
|
|
||||||
// invoke function
|
// invoke function
|
||||||
return func(this, 1, &name);
|
return func(this, 1, &name);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
CUnixPlatform::installDaemonLogger(
|
||||||
|
const char* name)
|
||||||
|
{
|
||||||
|
openlog(name, 0, LOG_DAEMON);
|
||||||
|
CLog::setOutputter(&CUnixPlatform::deamonLogger);
|
||||||
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
CUnixPlatform::restart(
|
CUnixPlatform::restart(
|
||||||
RestartFunc func,
|
RestartFunc func,
|
||||||
|
@ -195,14 +203,6 @@ CUnixPlatform::addPathComponent(
|
||||||
return path;
|
return path;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
|
||||||
CUnixPlatform::setDaemonLogger(
|
|
||||||
const char* name)
|
|
||||||
{
|
|
||||||
openlog(name, 0, LOG_DAEMON);
|
|
||||||
CLog::setOutputter(&CUnixPlatform::deamonLogger);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool
|
bool
|
||||||
CUnixPlatform::deamonLogger(
|
CUnixPlatform::deamonLogger(
|
||||||
int priority,
|
int priority,
|
||||||
|
|
|
@ -13,8 +13,9 @@ public:
|
||||||
const char* description,
|
const char* description,
|
||||||
const char* pathname,
|
const char* pathname,
|
||||||
const char* commandLine);
|
const char* commandLine);
|
||||||
virtual bool 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 int restart(RestartFunc, int minErrorCode);
|
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;
|
||||||
|
@ -23,9 +24,6 @@ public:
|
||||||
const CString& prefix,
|
const CString& prefix,
|
||||||
const CString& suffix) const;
|
const CString& suffix) const;
|
||||||
|
|
||||||
protected:
|
|
||||||
virtual void setDaemonLogger(const char* name);
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static bool deamonLogger(int, const char*);
|
static bool deamonLogger(int, const char*);
|
||||||
};
|
};
|
||||||
|
|
|
@ -180,7 +180,7 @@ CWin32Platform::installDaemon(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
IPlatform::EResult
|
||||||
CWin32Platform::uninstallDaemon(
|
CWin32Platform::uninstallDaemon(
|
||||||
const char* name)
|
const char* name)
|
||||||
{
|
{
|
||||||
|
@ -190,7 +190,7 @@ CWin32Platform::uninstallDaemon(
|
||||||
HKEY key = open95ServicesKey();
|
HKEY key = open95ServicesKey();
|
||||||
if (key == NULL) {
|
if (key == NULL) {
|
||||||
log((CLOG_ERR "cannot open RunServices registry key", GetLastError()));
|
log((CLOG_ERR "cannot open RunServices registry key", GetLastError()));
|
||||||
return false;
|
return kAlready;
|
||||||
}
|
}
|
||||||
|
|
||||||
// remove entry
|
// remove entry
|
||||||
|
@ -199,7 +199,7 @@ CWin32Platform::uninstallDaemon(
|
||||||
// clean up
|
// clean up
|
||||||
closeKey(key);
|
closeKey(key);
|
||||||
|
|
||||||
return true;
|
return kSuccess;
|
||||||
}
|
}
|
||||||
|
|
||||||
// windows NT family services
|
// windows NT family services
|
||||||
|
@ -216,26 +216,41 @@ CWin32Platform::uninstallDaemon(
|
||||||
SC_HANDLE mgr = OpenSCManager(NULL, NULL, GENERIC_WRITE);
|
SC_HANDLE mgr = OpenSCManager(NULL, NULL, GENERIC_WRITE);
|
||||||
if (mgr == NULL) {
|
if (mgr == NULL) {
|
||||||
log((CLOG_ERR "OpenSCManager failed with %d", GetLastError()));
|
log((CLOG_ERR "OpenSCManager failed with %d", GetLastError()));
|
||||||
return false;
|
return kFailed;
|
||||||
}
|
}
|
||||||
|
|
||||||
// open the service. oddly, you must open a service to delete it.
|
// open the service. oddly, you must open a service to delete it.
|
||||||
bool success;
|
EResult result;
|
||||||
SC_HANDLE service = OpenService(mgr, name, DELETE);
|
SC_HANDLE service = OpenService(mgr, name, DELETE);
|
||||||
if (service == NULL) {
|
if (service == NULL) {
|
||||||
log((CLOG_ERR "OpenService failed with %d", GetLastError()));
|
const DWORD e = GetLastError();
|
||||||
success = false;
|
log((CLOG_ERR "OpenService failed with %d", e));
|
||||||
|
result = (e == ERROR_SERVICE_DOES_NOT_EXIST) ? kAlready : kFailed;
|
||||||
}
|
}
|
||||||
|
|
||||||
else {
|
else {
|
||||||
success = (DeleteService(service) != 0);
|
if (DeleteService(service) != 0) {
|
||||||
|
result = kSuccess;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
const DWORD e = GetLastError();
|
||||||
|
switch (e) {
|
||||||
|
case ERROR_SERVICE_MARKED_FOR_DELETE:
|
||||||
|
result = kAlready;
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
result = kFailed;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
CloseServiceHandle(service);
|
CloseServiceHandle(service);
|
||||||
}
|
}
|
||||||
|
|
||||||
// close the manager
|
// close the manager
|
||||||
CloseServiceHandle(mgr);
|
CloseServiceHandle(mgr);
|
||||||
|
|
||||||
return success;
|
return result;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -303,6 +318,21 @@ CWin32Platform::daemonize(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
CWin32Platform::installDaemonLogger(
|
||||||
|
const char* name)
|
||||||
|
{
|
||||||
|
if (!CWin32Platform::isWindows95Family()) {
|
||||||
|
// open event log and direct log messages to it
|
||||||
|
if (s_eventLog == NULL) {
|
||||||
|
s_eventLog = RegisterEventSource(NULL, name);
|
||||||
|
if (s_eventLog != NULL) {
|
||||||
|
CLog::setOutputter(&CWin32Platform::serviceLogger);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
CWin32Platform::restart(
|
CWin32Platform::restart(
|
||||||
RestartFunc func,
|
RestartFunc func,
|
||||||
|
@ -643,12 +673,7 @@ CWin32Platform::serviceMain(
|
||||||
const char** argv = const_cast<const char**>(argvIn);
|
const char** argv = const_cast<const char**>(argvIn);
|
||||||
|
|
||||||
// open event log and direct log messages to it
|
// open event log and direct log messages to it
|
||||||
if (s_eventLog == NULL) {
|
installDaemonLogger(argv[0]);
|
||||||
s_eventLog = RegisterEventSource(NULL, argv[0]);
|
|
||||||
if (s_eventLog != NULL) {
|
|
||||||
CLog::setOutputter(&CWin32Platform::serviceLogger);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// create synchronization objects
|
// create synchronization objects
|
||||||
CThread::init();
|
CThread::init();
|
||||||
|
|
|
@ -46,8 +46,9 @@ public:
|
||||||
const char* description,
|
const char* description,
|
||||||
const char* pathname,
|
const char* pathname,
|
||||||
const char* commandLine);
|
const char* commandLine);
|
||||||
virtual bool 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 int restart(RestartFunc, int minErrorCode);
|
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;
|
||||||
|
|
|
@ -9,6 +9,12 @@ public:
|
||||||
typedef int (*DaemonFunc)(IPlatform*, int argc, const char** argv);
|
typedef int (*DaemonFunc)(IPlatform*, int argc, const char** argv);
|
||||||
typedef int (*RestartFunc)();
|
typedef int (*RestartFunc)();
|
||||||
|
|
||||||
|
enum EResult {
|
||||||
|
kSuccess,
|
||||||
|
kFailed,
|
||||||
|
kAlready
|
||||||
|
};
|
||||||
|
|
||||||
// manipulators
|
// manipulators
|
||||||
|
|
||||||
// install/uninstall a daemon. commandLine should *not*
|
// install/uninstall a daemon. commandLine should *not*
|
||||||
|
@ -18,12 +24,10 @@ public:
|
||||||
const char* description,
|
const char* description,
|
||||||
const char* pathname,
|
const char* pathname,
|
||||||
const char* commandLine) = 0;
|
const char* commandLine) = 0;
|
||||||
virtual bool uninstallDaemon(const char* name) = 0;
|
virtual EResult uninstallDaemon(const char* name) = 0;
|
||||||
|
|
||||||
// daemonize. this should have the side effect of sending log
|
// daemonize. this should call installDaemonLogger(). returns
|
||||||
// messages to a system message logger since messages can no
|
// true iff successful. the name is the name of the daemon.
|
||||||
// longer go to the console. returns true iff successful.
|
|
||||||
// the name is the name of the daemon.
|
|
||||||
|
|
||||||
// daemonize. this should have the side effect of sending log
|
// daemonize. this should have the side effect of sending log
|
||||||
// messages to a system message logger since messages can no
|
// messages to a system message logger since messages can no
|
||||||
|
@ -44,6 +48,11 @@ public:
|
||||||
// SetServiceStatus().
|
// SetServiceStatus().
|
||||||
virtual int daemonize(const char* name, DaemonFunc func) = 0;
|
virtual int daemonize(const char* name, DaemonFunc func) = 0;
|
||||||
|
|
||||||
|
// directs CLog to send messages to the daemon log. used when
|
||||||
|
// messages should no longer go to the console. name is used
|
||||||
|
// in the log to identify this process.
|
||||||
|
virtual void installDaemonLogger(const char* name) = 0;
|
||||||
|
|
||||||
// continually restart the given function in a separate process
|
// continually restart the given function in a separate process
|
||||||
// or thread until it exits normally with a code less than the
|
// or thread until it exits normally with a code less than the
|
||||||
// given code then return the code.
|
// given code then return the code.
|
||||||
|
|
|
@ -15,10 +15,8 @@
|
||||||
|
|
||||||
// platform dependent name of a daemon
|
// platform dependent name of a daemon
|
||||||
#if defined(CONFIG_PLATFORM_WIN32)
|
#if defined(CONFIG_PLATFORM_WIN32)
|
||||||
#define DAEMON "service"
|
|
||||||
#define DAEMON_NAME "Synergy Server"
|
#define DAEMON_NAME "Synergy Server"
|
||||||
#elif defined(CONFIG_PLATFORM_UNIX)
|
#elif defined(CONFIG_PLATFORM_UNIX)
|
||||||
#define DAEMON "daemon"
|
|
||||||
#define DAEMON_NAME "synergyd"
|
#define DAEMON_NAME "synergyd"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -36,8 +34,10 @@
|
||||||
static const char* pname = NULL;
|
static const char* pname = NULL;
|
||||||
static bool s_restartable = true;
|
static bool s_restartable = true;
|
||||||
static bool s_daemon = true;
|
static bool s_daemon = true;
|
||||||
|
#if defined(CONFIG_PLATFORM_WIN32)
|
||||||
static bool s_install = false;
|
static bool s_install = false;
|
||||||
static bool s_uninstall = false;
|
static bool s_uninstall = false;
|
||||||
|
#endif
|
||||||
static const char* s_configFile = NULL;
|
static const char* s_configFile = NULL;
|
||||||
static const char* s_logFilter = NULL;
|
static const char* s_logFilter = NULL;
|
||||||
static CString s_name;
|
static CString s_name;
|
||||||
|
@ -211,42 +211,62 @@ static
|
||||||
void
|
void
|
||||||
help()
|
help()
|
||||||
{
|
{
|
||||||
|
#if defined(CONFIG_PLATFORM_WIN32)
|
||||||
|
|
||||||
|
# define PLATFORM_ARGS \
|
||||||
|
" {--daemon|--no-daemon}" \
|
||||||
|
" [--install]\n" \
|
||||||
|
"or\n" \
|
||||||
|
" --uninstall\n"
|
||||||
|
# define PLATFORM_DESC \
|
||||||
|
" --install install server as a daemon.\n" \
|
||||||
|
" --uninstall uninstall server daemon.\n"
|
||||||
|
# define PLATFORM_EXTRA \
|
||||||
|
"At least one command line argument is required. If you don't otherwise\n" \
|
||||||
|
"need an argument use `--daemon'.\n" \
|
||||||
|
"\n"
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
# define PLATFORM_ARGS \
|
||||||
|
" [--daemon|--no-daemon]"
|
||||||
|
# define PLATFORM_DESC
|
||||||
|
# define PLATFORM_EXTRA
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
CPlatform platform;
|
CPlatform platform;
|
||||||
|
|
||||||
log((CLOG_PRINT
|
log((CLOG_PRINT
|
||||||
"Usage: %s"
|
"Usage: %s"
|
||||||
" [--address <address>]"
|
" [--address <address>]"
|
||||||
" [--config <pathname>]"
|
" [--config <pathname>]"
|
||||||
" [--"DAEMON"|--no-"DAEMON"]"
|
|
||||||
" [--debug <level>]"
|
" [--debug <level>]"
|
||||||
" [--name <screen-name>]"
|
" [--name <screen-name>]"
|
||||||
" [--restart|--no-restart]\n"
|
" [--restart|--no-restart]\n"
|
||||||
" [--install]\n"
|
PLATFORM_ARGS
|
||||||
"or\n"
|
|
||||||
" --uninstall\n"
|
|
||||||
"\n"
|
"\n"
|
||||||
"Start the synergy mouse/keyboard sharing server.\n"
|
"Start the synergy mouse/keyboard sharing server.\n"
|
||||||
"\n"
|
"\n"
|
||||||
" -a, --address <address> listen for clients on the given address.\n"
|
" -a, --address <address> listen for clients on the given address.\n"
|
||||||
" -c, --config <pathname> use the named configuration file instead\n"
|
" -c, --config <pathname> use the named configuration file instead.\n"
|
||||||
" where ~ represents the user's home directory.\n"
|
|
||||||
" -d, --debug <level> filter out log messages with priorty below level.\n"
|
" -d, --debug <level> filter out log messages with priorty below level.\n"
|
||||||
" level may be: FATAL, ERROR, WARNING, NOTE, INFO,\n"
|
" level may be: FATAL, ERROR, WARNING, NOTE, INFO,\n"
|
||||||
" DEBUG, DEBUG1, DEBUG2.\n"
|
" DEBUG, DEBUG1, DEBUG2.\n"
|
||||||
" -f, --no-"DAEMON" run the server in the foreground.\n"
|
" -f, --no-daemon run the server in the foreground.\n"
|
||||||
"* --"DAEMON" run the server as a "DAEMON".\n"
|
"* --daemon run the server as a daemon.\n"
|
||||||
" -n, --name <screen-name> use screen-name instead the hostname to identify\n"
|
" -n, --name <screen-name> use screen-name instead the hostname to identify\n"
|
||||||
" this screen in the configuration.\n"
|
" this screen in the configuration.\n"
|
||||||
" -1, --no-restart do not try to restart the server if it fails for\n"
|
" -1, --no-restart do not try to restart the server if it fails for\n"
|
||||||
" some reason.\n"
|
" some reason.\n"
|
||||||
"* --restart restart the server automatically if it fails.\n"
|
"* --restart restart the server automatically if it fails.\n"
|
||||||
" --install install server as a "DAEMON".\n"
|
PLATFORM_DESC
|
||||||
" --uninstall uninstall server "DAEMON".\n"
|
|
||||||
" -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"
|
||||||
"\n"
|
"\n"
|
||||||
"* marks defaults.\n"
|
"* marks defaults.\n"
|
||||||
"\n"
|
"\n"
|
||||||
|
PLATFORM_EXTRA
|
||||||
"The argument for --address is of the form: [<hostname>][:<port>]. The\n"
|
"The argument for --address is of the form: [<hostname>][:<port>]. The\n"
|
||||||
"hostname must be the address or hostname of an interface on the system.\n"
|
"hostname must be the address or hostname of an interface on the system.\n"
|
||||||
"The default is to listen on all interfaces. The port overrides the\n"
|
"The default is to listen on all interfaces. The port overrides the\n"
|
||||||
|
@ -260,7 +280,7 @@ help()
|
||||||
"defaults with just the server screen.\n"
|
"defaults with just the server screen.\n"
|
||||||
"\n"
|
"\n"
|
||||||
"Where log messages go depends on the platform and whether or not the\n"
|
"Where log messages go depends on the platform and whether or not the\n"
|
||||||
"server is running as a "DAEMON".",
|
"server is running as a daemon.",
|
||||||
pname,
|
pname,
|
||||||
kDefaultPort,
|
kDefaultPort,
|
||||||
platform.addPathComponent(
|
platform.addPathComponent(
|
||||||
|
@ -355,12 +375,12 @@ parse(
|
||||||
s_configFile = argv[++i];
|
s_configFile = argv[++i];
|
||||||
}
|
}
|
||||||
|
|
||||||
else if (isArg(i, argc, argv, "-f", "--no-"DAEMON)) {
|
else if (isArg(i, argc, argv, "-f", "--no-daemon")) {
|
||||||
// not a daemon
|
// not a daemon
|
||||||
s_daemon = false;
|
s_daemon = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
else if (isArg(i, argc, argv, NULL, "--"DAEMON)) {
|
else if (isArg(i, argc, argv, NULL, "--daemon")) {
|
||||||
// daemonize
|
// daemonize
|
||||||
s_daemon = true;
|
s_daemon = true;
|
||||||
}
|
}
|
||||||
|
@ -385,12 +405,8 @@ parse(
|
||||||
bye(0);
|
bye(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if defined(CONFIG_PLATFORM_WIN32)
|
||||||
else if (isArg(i, argc, argv, NULL, "--install")) {
|
else if (isArg(i, argc, argv, NULL, "--install")) {
|
||||||
#if !defined(CONFIG_PLATFORM_WIN32)
|
|
||||||
log((CLOG_PRINT "%s: `%s' not supported on this platform" BYE,
|
|
||||||
pname, argv[i], pname));
|
|
||||||
bye(2);
|
|
||||||
#endif
|
|
||||||
s_install = true;
|
s_install = true;
|
||||||
if (s_uninstall) {
|
if (s_uninstall) {
|
||||||
log((CLOG_PRINT "%s: `--install' and `--uninstall'"
|
log((CLOG_PRINT "%s: `--install' and `--uninstall'"
|
||||||
|
@ -399,13 +415,10 @@ parse(
|
||||||
bye(2);
|
bye(2);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
else if (isArg(i, argc, argv, NULL, "--uninstall")) {
|
|
||||||
#if !defined(CONFIG_PLATFORM_WIN32)
|
|
||||||
log((CLOG_PRINT "%s: `%s' not supported on this platform" BYE,
|
|
||||||
pname, argv[i], pname));
|
|
||||||
bye(2);
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if defined(CONFIG_PLATFORM_WIN32)
|
||||||
|
else if (isArg(i, argc, argv, NULL, "--uninstall")) {
|
||||||
s_uninstall = true;
|
s_uninstall = true;
|
||||||
if (s_install) {
|
if (s_install) {
|
||||||
log((CLOG_PRINT "%s: `--install' and `--uninstall'"
|
log((CLOG_PRINT "%s: `--install' and `--uninstall'"
|
||||||
|
@ -414,6 +427,7 @@ parse(
|
||||||
bye(2);
|
bye(2);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
else if (isArg(i, argc, argv, "--", NULL)) {
|
else if (isArg(i, argc, argv, "--", NULL)) {
|
||||||
// remaining arguments are not options
|
// remaining arguments are not options
|
||||||
|
@ -598,16 +612,6 @@ daemonStartup(
|
||||||
return platform->runDaemon(realMain, daemonStop);
|
return platform->runDaemon(realMain, daemonStop);
|
||||||
}
|
}
|
||||||
|
|
||||||
static
|
|
||||||
int
|
|
||||||
daemonStartup95(
|
|
||||||
IPlatform*,
|
|
||||||
int,
|
|
||||||
const char**)
|
|
||||||
{
|
|
||||||
return realMain(NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
static
|
static
|
||||||
bool
|
bool
|
||||||
logDiscard(
|
logDiscard(
|
||||||
|
@ -664,12 +668,13 @@ WinMain(
|
||||||
// ignore
|
// ignore
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// send PRINT and FATAL output to a message box
|
||||||
|
CLog::setOutputter(&logMessageBox);
|
||||||
|
|
||||||
// if we're not starting as an NT service then reparse the command
|
// if we're not starting as an NT service then reparse the command
|
||||||
// line normally.
|
// line normally.
|
||||||
if (s_die || !s_daemon || s_install || s_uninstall ||
|
if (s_die || __argc > 1 || s_install || s_uninstall ||
|
||||||
CWin32Platform::isWindows95Family()) {
|
CWin32Platform::isWindows95Family()) {
|
||||||
// send PRINT and FATAL output to a message box
|
|
||||||
CLog::setOutputter(&logMessageBox);
|
|
||||||
|
|
||||||
// exit on bye
|
// exit on bye
|
||||||
bye = &exit;
|
bye = &exit;
|
||||||
|
@ -678,9 +683,9 @@ WinMain(
|
||||||
parse(__argc, const_cast<const char**>(__argv));
|
parse(__argc, const_cast<const char**>(__argv));
|
||||||
}
|
}
|
||||||
|
|
||||||
// if starting as a daemon then we ignore the startup command line
|
// if no arguments were provided then we're hopefully starting as
|
||||||
// here. we'll parse the command line passed in when the service
|
// a service. we'll parse the command line passed in when the
|
||||||
// control manager calls us back.
|
// service control manager calls us back.
|
||||||
else {
|
else {
|
||||||
// do nothing
|
// do nothing
|
||||||
}
|
}
|
||||||
|
@ -697,7 +702,7 @@ WinMain(
|
||||||
|
|
||||||
// construct the command line to start the service with
|
// construct the command line to start the service with
|
||||||
CString commandLine;
|
CString commandLine;
|
||||||
commandLine += "--"DAEMON;
|
commandLine += "--daemon";
|
||||||
if (s_restartable) {
|
if (s_restartable) {
|
||||||
commandLine += " --restart";
|
commandLine += " --restart";
|
||||||
}
|
}
|
||||||
|
@ -725,12 +730,19 @@ WinMain(
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
else if (s_uninstall) {
|
else if (s_uninstall) {
|
||||||
if (!platform.uninstallDaemon(DAEMON_NAME)) {
|
switch (platform.uninstallDaemon(DAEMON_NAME)) {
|
||||||
|
case IPlatform::kSuccess:
|
||||||
|
log((CLOG_PRINT "uninstalled successfully"));
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
case IPlatform::kFailed:
|
||||||
log((CLOG_CRIT "failed to uninstall service"));
|
log((CLOG_CRIT "failed to uninstall service"));
|
||||||
return 16;
|
return 16;
|
||||||
|
|
||||||
|
case IPlatform::kAlready:
|
||||||
|
log((CLOG_CRIT "service isn't installed"));
|
||||||
|
return 16;
|
||||||
}
|
}
|
||||||
log((CLOG_PRINT "uninstalled successfully"));
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// load configuration
|
// load configuration
|
||||||
|
@ -740,17 +752,23 @@ WinMain(
|
||||||
int result;
|
int result;
|
||||||
if (s_daemon) {
|
if (s_daemon) {
|
||||||
if (CWin32Platform::isWindows95Family()) {
|
if (CWin32Platform::isWindows95Family()) {
|
||||||
result = platform.daemonize(DAEMON_NAME, &daemonStartup95);
|
result = -1;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
result = platform.daemonize(DAEMON_NAME, &daemonStartup);
|
result = platform.daemonize(DAEMON_NAME, &daemonStartup);
|
||||||
}
|
}
|
||||||
if (result == -1) {
|
if (result == -1) {
|
||||||
log((CLOG_CRIT "failed to start as a service"));
|
log((CLOG_CRIT "failed to start as a service" BYE, pname));
|
||||||
return 16;
|
return 16;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
// if a daemon then redirect log
|
||||||
|
if (s_daemon) {
|
||||||
|
platform.installDaemonLogger(__argv[0]);
|
||||||
|
}
|
||||||
|
|
||||||
|
// run
|
||||||
result = restartableMain();
|
result = restartableMain();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue