void
ArchDaemonWindows::stop(const char* name)
{
	// open service manager
	SC_HANDLE mgr = OpenSCManager(NULL, NULL, GENERIC_READ);
	if (mgr == NULL) {
		throw XArchDaemonFailed(new XArchEvalWindows());
	}

	// open the service
	SC_HANDLE service = OpenService(
		mgr, name,
		SERVICE_STOP | SERVICE_QUERY_STATUS);

	if (service == NULL) {
		CloseServiceHandle(mgr);
		throw XArchDaemonFailed(new XArchEvalWindows());
	}

	// ask the service to stop, asynchronously
	SERVICE_STATUS ss;
	if (!ControlService(service, SERVICE_CONTROL_STOP, &ss)) {
		DWORD dwErrCode = GetLastError(); 
		if (dwErrCode != ERROR_SERVICE_NOT_ACTIVE) {
			throw XArchDaemonFailed(new XArchEvalWindows());
		}
	}
}
Beispiel #2
0
void
CArchAppUtilWindows::stopService()
{
	// open service manager
	SC_HANDLE mgr = OpenSCManager(NULL, NULL, GENERIC_READ);
	if (mgr == NULL) {
		throw XArchDaemonFailed(new XArchEvalWindows());
	}

	// open the service
	SC_HANDLE service = OpenService(
		mgr, app().daemonName(),
		SERVICE_STOP | SERVICE_QUERY_STATUS);

	if (service == NULL) {
		CloseServiceHandle(mgr);
		throw XArchDaemonFailed(new XArchEvalWindows());
	}

	// ask the service to stop, asynchronously
	SERVICE_STATUS ss;
	if (!ControlService(service, SERVICE_CONTROL_STOP, &ss)) {
		DWORD dwErrCode = GetLastError(); 
		if (dwErrCode != ERROR_SERVICE_NOT_ACTIVE) {
			LOG((CLOG_ERR "cannot stop service '%s'", app().daemonName()));
			throw XArchDaemonFailed(new XArchEvalWindows());
		}
	}

	LOG((CLOG_INFO "service '%s' stopping asynchronously", app().daemonName()));
}
Beispiel #3
0
void
CArchAppUtilWindows::startService()
{
	// open service manager
	SC_HANDLE mgr = OpenSCManager(NULL, NULL, GENERIC_READ);
	if (mgr == NULL) {
		throw XArchDaemonFailed(new XArchEvalWindows());
	}

	// open the service
	SC_HANDLE service = OpenService(
		mgr, app().daemonName(), SERVICE_START);

	if (service == NULL) {
		CloseServiceHandle(mgr);
		throw XArchDaemonFailed(new XArchEvalWindows());
	}

	// start the service
	if (StartService(service, 0, NULL)) {
		LOG((CLOG_INFO "service '%s' started", app().daemonName()));
	}
	else {
		throw XArchDaemonFailed(new XArchEvalWindows());
	}
}
int
ArchDaemonWindows::daemonize(const char* name, DaemonFunc func)
{
	assert(name != NULL);
	assert(func != NULL);

	// save daemon function
	m_daemonFunc = func;

	// construct the service entry
	SERVICE_TABLE_ENTRY entry[2];
	entry[0].lpServiceName = const_cast<char*>(name);
	entry[0].lpServiceProc = &ArchDaemonWindows::serviceMainEntry;
	entry[1].lpServiceName = NULL;
	entry[1].lpServiceProc = NULL;

	// hook us up to the service control manager.  this won't return
	// (if successful) until the processes have terminated.
	s_daemon = this;
	if (StartServiceCtrlDispatcher(entry) == 0) {
		// StartServiceCtrlDispatcher failed
		s_daemon = NULL;
		throw XArchDaemonFailed(new XArchEvalWindows);
	}

	s_daemon = NULL;
	return m_daemonResult;
}
void
ArchDaemonWindows::start(const char* name)
{
	// open service manager
	SC_HANDLE mgr = OpenSCManager(NULL, NULL, GENERIC_READ);
	if (mgr == NULL) {
		throw XArchDaemonFailed(new XArchEvalWindows());
	}

	// open the service
	SC_HANDLE service = OpenService(
		mgr, name, SERVICE_START);

	if (service == NULL) {
		CloseServiceHandle(mgr);
		throw XArchDaemonFailed(new XArchEvalWindows());
	}

	// start the service
	if (!StartService(service, 0, NULL)) {
		throw XArchDaemonFailed(new XArchEvalWindows());
	}
}
int
CArchDaemonUnix::daemonize(const char* name, DaemonFunc func)
{
    // fork so shell thinks we're done and so we're not a process
    // group leader
    switch (fork()) {
    case -1:
        // failed
        throw XArchDaemonFailed(new XArchEvalUnix(errno));

    case 0:
        // child
        break;

    default:
        // parent exits
        exit(0);
    }

    // become leader of a new session
    setsid();

    // chdir to root so we don't keep mounted filesystems points busy
    chdir("/");

    // mask off permissions for any but owner
    umask(077);

    // close open files.  we only expect stdin, stdout, stderr to be open.
    close(0);
    close(1);
    close(2);

    // attach file descriptors 0, 1, 2 to /dev/null so inadvertent use
    // of standard I/O safely goes in the bit bucket.
    open("/dev/null", O_RDONLY);
    open("/dev/null", O_RDWR);
    dup(1);

    // invoke function
    return func(1, &name);
}
Beispiel #7
0
int
ArchDaemonUnix::daemonize(const char* name, DaemonFunc func)
{
#ifdef __APPLE__
	if (alreadyDaemonized())
		return func(1, &name);
#endif
	
	// fork so shell thinks we're done and so we're not a process
	// group leader
	switch (fork()) {
	case -1:
		// failed
		throw XArchDaemonFailed(new XArchEvalUnix(errno));

	case 0:
		// child
		break;

	default:
		// parent exits
		exit(0);
	}

	// become leader of a new session
	setsid();
	
#ifndef __APPLE__
	// NB: don't run chdir on apple; causes strange behaviour.
	// chdir to root so we don't keep mounted filesystems points busy
	// TODO: this is a bit of a hack - can we find a better solution?
	int chdirErr = chdir("/");
	if (chdirErr)
		// NB: file logging actually isn't working at this point!
		LOG((CLOG_ERR "chdir error: %i", chdirErr));
#endif

	// mask off permissions for any but owner
	umask(077);

	// close open files.  we only expect stdin, stdout, stderr to be open.
	close(0);
	close(1);
	close(2);

	// attach file descriptors 0, 1, 2 to /dev/null so inadvertent use
	// of standard I/O safely goes in the bit bucket.
	open("/dev/null", O_RDONLY);
	open("/dev/null", O_RDWR);
	
	int dupErr = dup(1);
	if (dupErr)
		// NB: file logging actually isn't working at this point!
		LOG((CLOG_ERR "dup error: %i", dupErr));
	
#ifdef __APPLE__
	return execSelfNonDaemonized();
#endif
	
	// invoke function
	return func(1, &name);
}
int
CArchDaemonWindows::daemonize(const char* name, DaemonFunc func)
{
	assert(name != NULL);
	assert(func != NULL);

	// windows 95 family services
	if (CArchMiscWindows::isWindows95Family()) {
		typedef DWORD (WINAPI *RegisterServiceProcessT)(DWORD, DWORD);

		// mark this process as a service so it's not killed when the
		// user logs off.
		HINSTANCE kernel = LoadLibrary("kernel32.dll");
		if (kernel == NULL) {
			throw XArchDaemonFailed(new XArchEvalWindows);
		}
		RegisterServiceProcessT RegisterServiceProcess =
								reinterpret_cast<RegisterServiceProcessT>(
									GetProcAddress(kernel,
										"RegisterServiceProcess"));
		if (RegisterServiceProcess == NULL) {
			// missing RegisterServiceProcess function
			DWORD err = GetLastError();
			FreeLibrary(kernel);
			throw XArchDaemonFailed(new XArchEvalWindows(err));
		}
		if (RegisterServiceProcess(0, 1) == 0) {
			// RegisterServiceProcess failed
			DWORD err = GetLastError();
			FreeLibrary(kernel);
			throw XArchDaemonFailed(new XArchEvalWindows(err));
		}
		FreeLibrary(kernel);

		// now simply call the daemon function
		return func(1, &name);
	}

	// windows NT family services
	else {
		// save daemon function
		m_daemonFunc = func;

		// construct the service entry
		SERVICE_TABLE_ENTRY entry[2];
		entry[0].lpServiceName = const_cast<char*>(name);
		entry[0].lpServiceProc = &CArchDaemonWindows::serviceMainEntry;
		entry[1].lpServiceName = NULL;
		entry[1].lpServiceProc = NULL;

		// hook us up to the service control manager.  this won't return
		// (if successful) until the processes have terminated.
		s_daemon = this;
		if (StartServiceCtrlDispatcher(entry) == 0) {
			// StartServiceCtrlDispatcher failed
			s_daemon = NULL;
			throw XArchDaemonFailed(new XArchEvalWindows);
		}

		s_daemon = NULL;
		return m_daemonResult;
	}
}