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,14 +279,23 @@ 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) {
running_from_service = 1;
if (service_register(argc, argv)) {
/* We've been called as a service. Register service /* We've been called as a service. Register service
* and exit this thread. main() would be called from * and exit this thread. main() would be called from
* service.c next time. * 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.
*/ */
running_from_service = 1;
return 0; return 0;
} }
running_from_service = 0;
}
if (filter_string == NULL) { if (filter_string == NULL) {
filter_string = malloc(strlen(filter_string_template) + 1); filter_string = malloc(strlen(filter_string_template) + 1);

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.
*/ */
if (!service_argc && !service_argv) {
service_argc = argc; service_argc = argc;
service_argv = malloc(sizeof(void*) * argc); service_argv = malloc(sizeof(void*) * argc);
for (int i = 0; i < argc; i++) { for (i = 0; i < argc; i++) {
service_argv[i] = strdup(argv[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);
if (ServiceStatus.dwCurrentState != SERVICE_STOPPED) {
// If terminated with error
ServiceStatus.dwWin32ExitCode = 1;
ServiceStatus.dwCurrentState = SERVICE_STOPPED; ServiceStatus.dwCurrentState = SERVICE_STOPPED;
SetServiceStatus(hStatus, &ServiceStatus); SetServiceStatus(hStatus, &ServiceStatus);
}
return; return;
} }