Minor service fixes

This commit is contained in:
ValdikSS 2017-12-21 23:52:23 +03:00
parent ccd21a4281
commit eaac2d1a80
2 changed files with 44 additions and 22 deletions

View File

@ -279,13 +279,22 @@ int main(int argc, char *argv[]) {
char *hdr_name_addr = NULL, *hdr_value_addr = NULL; char *hdr_name_addr = NULL, *hdr_value_addr = NULL;
int hdr_value_len; int hdr_value_len;
if (!running_from_service && service_register(argc, argv)) { if (!running_from_service) {
/* We've been called as a service. Register service
* and exit this thread. main() would be called from
* service.c next time.
*/
running_from_service = 1; running_from_service = 1;
return 0; if (service_register(argc, argv)) {
/* We've been called as a service. Register service
* and exit this thread. main() would be called from
* service.c next time.
*
* Note that if service_register() succeedes it does
* not return until the service is stopped.
* That is why we should set running_from_service
* before calling service_register and unset it
* afterwards.
*/
return 0;
}
running_from_service = 0;
} }
if (filter_string == NULL) { if (filter_string == NULL) {

View File

@ -7,11 +7,12 @@
static SERVICE_STATUS ServiceStatus; static SERVICE_STATUS ServiceStatus;
static SERVICE_STATUS_HANDLE hStatus; static SERVICE_STATUS_HANDLE hStatus;
static int service_argc; static int service_argc = 0;
static char **service_argv; static char **service_argv = NULL;
int service_register(int argc, char *argv[]) int service_register(int argc, char *argv[])
{ {
int i, ret;
SERVICE_TABLE_ENTRY ServiceTable[] = { SERVICE_TABLE_ENTRY ServiceTable[] = {
{SERVICE_NAME, (LPSERVICE_MAIN_FUNCTION)service_main}, {SERVICE_NAME, (LPSERVICE_MAIN_FUNCTION)service_main},
{NULL, NULL} {NULL, NULL}
@ -21,13 +22,30 @@ int service_register(int argc, char *argv[])
* arguments, which are passed from "start" command, not * arguments, which are passed from "start" command, not
* from the program command line. * from the program command line.
* We don't need this behaviour. * We don't need this behaviour.
*
* Note that if StartServiceCtrlDispatcher() succeedes
* it does not return until the service is stopped,
* so we should copy all arguments first and then
* handle the failure.
*/ */
service_argc = argc; if (!service_argc && !service_argv) {
service_argv = malloc(sizeof(void*) * argc); service_argc = argc;
for (int i = 0; i < argc; i++) { service_argv = malloc(sizeof(void*) * argc);
service_argv[i] = strdup(argv[i]); for (i = 0; i < argc; i++) {
service_argv[i] = strdup(argv[i]);
}
} }
return StartServiceCtrlDispatcher(ServiceTable);
ret = StartServiceCtrlDispatcher(ServiceTable);
if (service_argc && service_argv) {
for (i = 0; i < service_argc; i++) {
free(service_argv[i]);
}
free(service_argv);
}
return ret;
} }
void service_main(int argc __attribute__((unused)), void service_main(int argc __attribute__((unused)),
@ -53,14 +71,9 @@ void service_main(int argc __attribute__((unused)),
SetServiceStatus(hStatus, &ServiceStatus); SetServiceStatus(hStatus, &ServiceStatus);
// Calling main with saved argc & argv // Calling main with saved argc & argv
main(service_argc, service_argv); ServiceStatus.dwWin32ExitCode = main(service_argc, service_argv);
ServiceStatus.dwCurrentState = SERVICE_STOPPED;
if (ServiceStatus.dwCurrentState != SERVICE_STOPPED) { SetServiceStatus(hStatus, &ServiceStatus);
// If terminated with error
ServiceStatus.dwWin32ExitCode = 1;
ServiceStatus.dwCurrentState = SERVICE_STOPPED;
SetServiceStatus (hStatus, &ServiceStatus);
}
return; return;
} }
@ -78,6 +91,6 @@ void service_controlhandler(DWORD request)
break; break;
} }
// Report current status // Report current status
SetServiceStatus (hStatus, &ServiceStatus); SetServiceStatus(hStatus, &ServiceStatus);
return; return;
} }