Skip to content

Commit 3f73325

Browse files
authored
Merge 0e40fc6 into 9bd31ff
2 parents 9bd31ff + 0e40fc6 commit 3f73325

File tree

2 files changed

+76
-2
lines changed

2 files changed

+76
-2
lines changed

NEWS.adoc

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,11 @@ https://github.com/networkupstools/nut/milestone/12
114114
operations. (Re-)registration of the "Network UPS Tools" service should
115115
now populate a nice description of it. The `-U` (uninstall) action should
116116
now also try to stop the service first. [PR #3235]
117+
* Using `nut.exe -N` for testing and pressing 'Ctrl+C' should now cause the
118+
started daemons to be killed off. Previously they would linger and e.g.
119+
preclude subsequent experiments with the service wrapper. Console close
120+
events are ignored, so there is a way to indefinitely keep the daemons
121+
started by test-mode wrapper running (kill via Task Manager). [#3312]
117122
* Revised WIN32 `WSAStartup()` and registration of `atexit(WSACleanup)` to
118123
only be done once per program (and cleanups to be always registered); this
119124
impacts the C `libupsclient` and C++ `libnutclient` libraries (and so most

scripts/Windows/wininit.c

Lines changed: 71 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ typedef struct conn_s {
3838
struct conn_s *next;
3939
} conn_t;
4040

41+
static int exit_flag = 0;
4142
static DWORD upsd_pid = 0;
4243
static DWORD upsmon_pid = 0;
4344
static DWORD upsdrvctl_pid = 0;
@@ -581,6 +582,54 @@ static void ReportSvcStatus(
581582
SetServiceStatus(SvcStatusHandle, &SvcStatus);
582583
}
583584

585+
/* For `nut.exe -N` runs
586+
* https://learn.microsoft.com/en-us/windows/console/registering-a-control-handler-function
587+
*/
588+
static BOOL WINAPI ConsoleCtrlHandler(DWORD Ctrl)
589+
{
590+
switch(Ctrl)
591+
{
592+
case CTRL_C_EVENT:
593+
print_event(LOG_INFO, "Ctrl+C received on console");
594+
exit_flag = 1; /* Break SvcMain() infinite loop */
595+
if (upsmon_pid) {
596+
print_event(LOG_INFO, "Stopping upsmon");
597+
stop_upsmon();
598+
}
599+
if (upsd_pid) {
600+
print_event(LOG_INFO, "Stopping upsd");
601+
stop_upsd();
602+
}
603+
if (upsdrvctl_pid) {
604+
print_event(LOG_INFO, "Stopping drivers");
605+
stop_drivers();
606+
}
607+
exit_flag = 2; /* Allow to finish SvcMain() infinite loop and proceed to exit() */
608+
/* confirm that the user wants to exit */
609+
return TRUE;
610+
611+
case CTRL_CLOSE_EVENT:
612+
print_event(LOG_INFO, "Close event received on console, currently ignored");
613+
return FALSE;
614+
615+
case CTRL_BREAK_EVENT:
616+
print_event(LOG_INFO, "Ctrl+Break event received on console, currently ignored");
617+
return FALSE;
618+
619+
/* TOTHINK: Do we in fact want these two handled specially? */
620+
case CTRL_LOGOFF_EVENT:
621+
print_event(LOG_INFO, "Logoff event received on console, currently ignored");
622+
return FALSE;
623+
624+
case CTRL_SHUTDOWN_EVENT:
625+
print_event(LOG_INFO, "Shutdown event received on console, currently ignored");
626+
return FALSE;
627+
628+
default:
629+
return FALSE;
630+
}
631+
}
632+
584633
static void WINAPI SvcCtrlHandler(DWORD Ctrl)
585634
{
586635
switch(Ctrl)
@@ -659,7 +708,7 @@ static void close_all(void)
659708
static void WINAPI SvcMain(DWORD argc, LPTSTR *argv)
660709
{
661710
DWORD ret;
662-
HANDLE handles[MAXIMUM_WAIT_OBJECTS]; /* 64 per current WinAPI sheaders */
711+
HANDLE handles[MAXIMUM_WAIT_OBJECTS]; /* 64 per current WinAPI headers */
663712
size_t maxhandle = 0;
664713
pipe_conn_t *conn;
665714
DWORD priority;
@@ -697,7 +746,7 @@ static void WINAPI SvcMain(DWORD argc, LPTSTR *argv)
697746
SvcReady();
698747
}
699748

700-
while (1) {
749+
while (!exit_flag) {
701750
maxhandle = 0;
702751
memset(&handles, 0, sizeof(handles));
703752

@@ -766,6 +815,10 @@ static void WINAPI SvcMain(DWORD argc, LPTSTR *argv)
766815
}
767816
}
768817

818+
/* Do not check on daemons nor revive them in vain if we are exiting */
819+
if (exit_flag)
820+
break;
821+
769822
/* Check on each daemon: Was it supposed to run? Does it still? */
770823
if (upsdrvctl_pid) {
771824
DWORD status = 0;
@@ -785,6 +838,10 @@ static void WINAPI SvcMain(DWORD argc, LPTSTR *argv)
785838
}
786839
}
787840

841+
/* Do not check on daemons nor revive them in vain if we are exiting */
842+
if (exit_flag)
843+
break;
844+
788845
if (upsd_pid) {
789846
DWORD status = 0;
790847
BOOL res = FALSE;
@@ -803,6 +860,10 @@ static void WINAPI SvcMain(DWORD argc, LPTSTR *argv)
803860
}
804861
}
805862

863+
/* Do not check on daemons nor revive them in vain if we are exiting */
864+
if (exit_flag)
865+
break;
866+
806867
if (upsmon_pid) {
807868
DWORD status = 0;
808869
BOOL res = FALSE;
@@ -821,6 +882,10 @@ static void WINAPI SvcMain(DWORD argc, LPTSTR *argv)
821882
}
822883
}
823884
}
885+
886+
while (exit_flag < 2) {
887+
Sleep(1000);
888+
}
824889
}
825890

826891
static void help(const char *arg_progname)
@@ -1020,6 +1085,10 @@ int main(int argc, char **argv)
10201085
}
10211086
}
10221087
else {
1088+
if (!SetConsoleCtrlHandler(ConsoleCtrlHandler, TRUE)) {
1089+
upslog_with_errno(LOG_ERR, "SetConsoleCtrlHandler failed, may ignore Ctrl+C");
1090+
}
1091+
10231092
SvcMain(argc, argv);
10241093
}
10251094

0 commit comments

Comments
 (0)