From: Myah Caron qsniyg@protonmail.com
Wine-bug: https://bugs.winehq.org/show_bug.cgi?id=56068 Signed-off-by: Myah Caron qsniyg@protonmail.com --- configure.ac | 1 + programs/timeout/Makefile.in | 6 + programs/timeout/timeout_main.c | 218 ++++++++++++++++++++++++++++++++ 3 files changed, 225 insertions(+) create mode 100644 programs/timeout/Makefile.in create mode 100644 programs/timeout/timeout_main.c
diff --git a/configure.ac b/configure.ac index 3f54230b46b..3ae541232ca 100644 --- a/configure.ac +++ b/configure.ac @@ -3523,6 +3523,7 @@ WINE_CONFIG_MAKEFILE(programs/tasklist) WINE_CONFIG_MAKEFILE(programs/tasklist/tests) WINE_CONFIG_MAKEFILE(programs/taskmgr) WINE_CONFIG_MAKEFILE(programs/termsv) +WINE_CONFIG_MAKEFILE(programs/timeout) WINE_CONFIG_MAKEFILE(programs/uninstaller) WINE_CONFIG_MAKEFILE(programs/unlodctr) WINE_CONFIG_MAKEFILE(programs/view) diff --git a/programs/timeout/Makefile.in b/programs/timeout/Makefile.in new file mode 100644 index 00000000000..4502a291175 --- /dev/null +++ b/programs/timeout/Makefile.in @@ -0,0 +1,6 @@ +MODULE = timeout.exe + +EXTRADLLFLAGS = -mconsole + +SOURCES = \ + timeout_main.c diff --git a/programs/timeout/timeout_main.c b/programs/timeout/timeout_main.c new file mode 100644 index 00000000000..9b99385c927 --- /dev/null +++ b/programs/timeout/timeout_main.c @@ -0,0 +1,218 @@ +/* + * timeout program + * + * Copyright (C) 2024 Myah Caron + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <conio.h> + +#include <windows.h> + +HANDLE hStdin; + +static void usage(void) +{ + printf("Usage: timeout [-t] seconds [-nobreak]\n\n" + "Options:\n" + " -t Timeout in seconds to wait.\n" + " -nobreak Ignore key presses.\n" + " -? Display this help message.\n"); +} + +static BOOL is_key_hit(void) +{ + INPUT_RECORD *records = NULL; + DWORD count = 0, i; + BOOL retval = FALSE; + + GetNumberOfConsoleInputEvents(hStdin, &count); + if (!count) + return FALSE; + + records = malloc(count * sizeof(INPUT_RECORD)); + if (!records) + return FALSE; + + if (!ReadConsoleInputA(hStdin, records, count, &count)) + return FALSE; + + for (i = 0; i < count; i++) + { + if (records[i].EventType == KEY_EVENT && + records[i].Event.KeyEvent.bKeyDown && + records[i].Event.KeyEvent.uChar.AsciiChar) + { + retval = TRUE; + break; + } + } + + free(records); + + return retval; +} + +static void wait_for_input(void) +{ + for (;;) + { + if (WaitForSingleObject(hStdin, INFINITE) == WAIT_OBJECT_0 && is_key_hit()) + break; + } +} + +static BOOL wait_for_input_with_timeout(int timeout_millis) +{ + ULONGLONG starting_ticks = GetTickCount64(); + + while (timeout_millis > 0) + { + if (WaitForSingleObject(hStdin, timeout_millis) == WAIT_OBJECT_0 && is_key_hit()) + return TRUE; + + timeout_millis -= GetTickCount64() - starting_ticks; + } + + return FALSE; +} + +int __cdecl main(int argc, char** argv) +{ + ULONGLONG starting_ticks = GetTickCount64(); + LONGLONG wait_millis; + int i, timeout = 0; + BOOL timeout_set = FALSE, nobreak = FALSE; + + if (argc == 1) + { + usage(); + return 1; + } + + for (i = 1; i < argc; i++) + { + if (argv[i][0] == '-' || argv[i][0] == '/') + { + if (!strcmp(argv[i] + 1, "t")) + { + if (i == argc - 1) + { + printf("Missing value for option %s\n", argv[i]); + exit(1); + } + + timeout = atoi(argv[++i]); + timeout_set = TRUE; + } + else if (!strcmp(argv[i] + 1, "nobreak")) + { + nobreak = TRUE; + } + else if (!strcmp(argv[i] + 1, "?")) + { + usage(); + return 0; + } + else if (!strcmp(argv[i] + 1, "1")) + { + timeout = -1; + timeout_set = TRUE; + } + else + { + printf("Invalid argument: %s\n", argv[i]); + usage(); + return 1; + } + } + else + { + timeout = atoi(argv[i]); + timeout_set = TRUE; + } + } + + if (!timeout_set) + { + usage(); + return 1; + } + + if (timeout < -1 || timeout > 99999) + { + printf("Timeout out of range: Valid range is -1 to 99999.\n"); + return 1; + } + + hStdin = GetStdHandle(STD_INPUT_HANDLE); + + printf("\n"); + + if (timeout < 0) + { + if (!nobreak) + { + printf("Press any key to continue ..."); + wait_for_input(); + } + else + { + printf("Press CTRL+C to quit ..."); + + for (;;) + { + Sleep(10000); + } + } + + return 0; + } + + for (;;) + { + wait_millis = (timeout * 1000) - (GetTickCount64() - starting_ticks); + if (wait_millis > 1000) + wait_millis = 1000; + if (wait_millis < 0) + wait_millis = 0; + + if (!nobreak) + { + printf("\rWaiting for %d seconds, press a key to continue ...", timeout); + + if (wait_millis > 0 && wait_for_input_with_timeout(wait_millis)) + break; + } + else + { + printf("\rWaiting for %d seconds, press CTRL+C to quit ...", timeout); + + if (wait_millis > 0) + Sleep(wait_millis); + } + + timeout--; + + if (timeout <= 0) + break; + } + + return 0; +}