From 58daab21cd043e1dc37024a7f99b396788372918 Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Sat, 9 Mar 2024 14:19:48 +0100 Subject: Merging upstream version 1.44.3. Signed-off-by: Daniel Baumann --- fluent-bit/src/win32/winsvc.c | 148 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 148 insertions(+) create mode 100644 fluent-bit/src/win32/winsvc.c (limited to 'fluent-bit/src/win32') diff --git a/fluent-bit/src/win32/winsvc.c b/fluent-bit/src/win32/winsvc.c new file mode 100644 index 000000000..9e0942ee5 --- /dev/null +++ b/fluent-bit/src/win32/winsvc.c @@ -0,0 +1,148 @@ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ + +/* Fluent Bit + * ========== + * Copyright (C) 2019-2020 The Fluent Bit Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include + +struct flb_config; +extern struct flb_config *config; +extern int flb_engine_exit(struct flb_config*); +extern int flb_main(int, char**); + +/* Windows Service utils */ +#define svc_name "fluent-bit" +static SERVICE_STATUS_HANDLE hstatus; +static int win32_argc; +static char **win32_argv; + +/* + * A Windows Service uses 'C:\Windows\System32' as working directory + * by default. Here we use a more intuitive default path (where + * fluent-bit.exe exists). + */ +static int update_default_workdir(void) +{ + char path[MAX_PATH]; + + if (win32_argc < 1) { + return -1; + } + + if (strcpy_s(path, MAX_PATH, win32_argv[0])) { + return -1; + } + + if (!PathRemoveFileSpecA(path)) { + return -1; + } + + if (!SetCurrentDirectoryA(path)) { + return -1; + } + + return 0; +} + +static void svc_notify(DWORD status) +{ + SERVICE_STATUS ss; + + ss.dwServiceType = SERVICE_WIN32_OWN_PROCESS; + ss.dwCurrentState = status; + ss.dwWin32ExitCode = NO_ERROR; + ss.dwServiceSpecificExitCode = NO_ERROR; + ss.dwControlsAccepted = SERVICE_ACCEPT_STOP; + ss.dwWaitHint = 30000; + ss.dwCheckPoint = 0; + + /* + * According to MSDN (SetServiceStatus), accepting control on + * SERVICE_START_PENDING can crash the service. + */ + if (status == SERVICE_START_PENDING) { + ss.dwControlsAccepted = 0; + } + + SetServiceStatus(hstatus, &ss); +} + +static void WINAPI svc_handler(DWORD ctrl) +{ + switch (ctrl) + { + case SERVICE_CONTROL_STOP: + svc_notify(SERVICE_STOP_PENDING); + flb_engine_exit(config); + return; + default: + break; + } +} + +static void WINAPI svc_main(DWORD svc_argc, LPTSTR *svc_argv) +{ + hstatus = RegisterServiceCtrlHandler(svc_name, svc_handler); + if (!hstatus) { + return; + } + + update_default_workdir(); + + svc_notify(SERVICE_START_PENDING); + flb_main(win32_argc, win32_argv); + svc_notify(SERVICE_STOPPED); +} + +/* + * Notify SCM that Fluent Bit is running. + * + * Note: Call this function in the main execution flow (immediately + * before the engine is starting). + */ +void win32_started(void) +{ + if (hstatus) { + svc_notify(SERVICE_RUNNING); + } +} + +static const SERVICE_TABLE_ENTRY svc_table[] = { + {svc_name, svc_main}, + {NULL, NULL} +}; + +int win32_main(int argc, char **argv) +{ + win32_argc = argc; + win32_argv = argv; + + if (StartServiceCtrlDispatcher(svc_table)) { + return 0; + } + + if (GetLastError() != ERROR_FAILED_SERVICE_CONTROLLER_CONNECT) { + return -1; + } + + /* + * If we cannot connect to SCM, we assume that "fluent-bit.exe" + * was invoked from the command line. + */ + return flb_main(argc, argv); +} -- cgit v1.2.3