diff --git a/CHANGELOG.md b/CHANGELOG.md index b11b10f56..b827262db 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -22,6 +22,7 @@ Features: * Add `--logo-type small` to search for small logos * Support detecting brightness of external displays with DDC/CI (guard behind `--allow-slow-operations`) (Brightness) * Add option `--size-ndigits` and `--size-max-prefix` (#494) +* Add option `--processing-timeout` to the timeout when waiting for child processes. # 1.12.2 diff --git a/src/common/init.c b/src/common/init.c index 53426ad2f..e71509292 100644 --- a/src/common/init.c +++ b/src/common/init.c @@ -37,6 +37,7 @@ static void defaultConfig(void) ffStrbufInit(&instance.config.colorKeys); ffStrbufInit(&instance.config.colorTitle); ffStrbufInitS(&instance.config.keyValueSeparator, ": "); + instance.config.processingTimeout = 1000; #if defined(__linux__) || defined(__FreeBSD__) ffStrbufInit(&instance.config.playerName); diff --git a/src/common/jsonconfig.c b/src/common/jsonconfig.c index 3fa6fe37f..690254202 100644 --- a/src/common/jsonconfig.c +++ b/src/common/jsonconfig.c @@ -309,6 +309,8 @@ const char* ffParseGeneralJsonConfig(void) config->escapeBedrock = yyjson_get_bool(val); else if (ffStrEqualsIgnCase(key, "pipe")) config->pipe = yyjson_get_bool(val); + else if (ffStrEqualsIgnCase(key, "processingTimeout")) + config->processingTimeout = (int32_t) yyjson_get_int(val); #if defined(__linux__) || defined(__FreeBSD__) else if (ffStrEqualsIgnCase(key, "playerName")) diff --git a/src/common/processing.h b/src/common/processing.h index 37dfceba3..9f02e799d 100644 --- a/src/common/processing.h +++ b/src/common/processing.h @@ -5,8 +5,6 @@ #include "util/FFstrbuf.h" -#define FF_WAIT_TIMEOUT 1000 - const char* ffProcessAppendOutput(FFstrbuf* buffer, char* const argv[], bool useStdErr); static inline const char* ffProcessAppendStdOut(FFstrbuf* buffer, char* const argv[]) diff --git a/src/common/processing_linux.c b/src/common/processing_linux.c index 45311b2b1..9a468d83c 100644 --- a/src/common/processing_linux.c +++ b/src/common/processing_linux.c @@ -16,15 +16,17 @@ int waitpid_timeout(pid_t pid, int* status) { - if (FF_WAIT_TIMEOUT <= 0) + if (instance.config.processingTimeout <= 0) return waitpid(pid, status, 0); + uint32_t timeout = (uint32_t) instance.config.processingTimeout; + #if defined(__linux__) && defined(SYS_pidfd_open) // musl don't define SYS_pidfd_open FF_AUTO_CLOSE_FD int pidfd = (int) syscall(SYS_pidfd_open, pid, 0); if (pidfd >= 0) { - int res = poll(&(struct pollfd) { .events = POLLIN, .fd = pidfd }, 1, FF_WAIT_TIMEOUT); + int res = poll(&(struct pollfd) { .events = POLLIN, .fd = pidfd }, 1, (int) timeout); if (res > 0) return (int) waitpid(pid, status, WNOHANG); else if (res == 0) @@ -43,8 +45,8 @@ int waitpid_timeout(pid_t pid, int* status) int res = (int) waitpid(pid, status, WNOHANG); if (res != 0) return res; - if (ffTimeGetTick() - start < FF_WAIT_TIMEOUT) - ffTimeSleep(FF_WAIT_TIMEOUT / 10); + if (ffTimeGetTick() - start < timeout) + ffTimeSleep(timeout / 10); else { kill(pid, SIGTERM); diff --git a/src/common/processing_windows.c b/src/common/processing_windows.c index 7070d31c7..8a9885abc 100644 --- a/src/common/processing_windows.c +++ b/src/common/processing_windows.c @@ -58,9 +58,9 @@ const char* ffProcessAppendOutput(FFstrbuf* buffer, char* const argv[], bool use if(!success) return "CreateProcessA() failed"; - if (FF_WAIT_TIMEOUT > 0) + if (instance.config.processingTimeout > 0) { - DWORD ret = WaitForSingleObjectEx(piProcInfo.hProcess, FF_WAIT_TIMEOUT, TRUE); + DWORD ret = WaitForSingleObjectEx(piProcInfo.hProcess, (DWORD) instance.config.processingTimeout, TRUE); if (ret == WAIT_TIMEOUT) { TerminateProcess(piProcInfo.hProcess, 1); diff --git a/src/data/config_user.txt b/src/data/config_user.txt index e9a481727..d5eccdc8e 100644 --- a/src/data/config_user.txt +++ b/src/data/config_user.txt @@ -58,6 +58,12 @@ # Default is true. #--hide-cursor true +# Processing timeout option: +# Sets the timeout (ms) when waiting for child processes +# Must be an integer. +# Default is 1000 +#--processing-timeout 1000 + # WMI timeout option: # Sets the timeout (ms) for WMI queries. Windows only # Must be an integer. diff --git a/src/data/help.txt b/src/data/help.txt index 78af50b05..fae9abc0a 100644 --- a/src/data/help.txt +++ b/src/data/help.txt @@ -24,6 +24,8 @@ General options: --allow-slow-operations : Allow operations that are usually very slow for more detailed output --escape-bedrock : On Bedrock Linux, whether to escape the bedrock jail --pipe : Disable logo and all escape sequences + --wmi-timeout : Set the timeout (ms) for WMI queries. Windows only. Default is 5000 + --processing-timeout : Set the timeout (ms) when waiting for child processes. Default is 1000 Logo options: -l,--logo : Set the logo; if default, the name of a builtin logo or a path to a file diff --git a/src/fastfetch.c b/src/fastfetch.c index c83718fa9..fe55857fc 100644 --- a/src/fastfetch.c +++ b/src/fastfetch.c @@ -859,6 +859,8 @@ static void parseOption(FFdata* data, const char* key, const char* value) instance.config.pipe = ffOptionParseBoolean(value); else if(ffStrEqualsIgnCase(key, "--load-user-config")) data->loadUserConfig = ffOptionParseBoolean(value); + else if(ffStrEqualsIgnCase(key, "--processing-timeout")) + instance.config.processingTimeout = ffOptionParseInt32(key, value); #if defined(__linux__) || defined(__FreeBSD__) else if(ffStrEqualsIgnCase(key, "--player-name")) diff --git a/src/fastfetch.h b/src/fastfetch.h index 5c455cd70..90d6aa47c 100644 --- a/src/fastfetch.h +++ b/src/fastfetch.h @@ -50,6 +50,7 @@ typedef struct FFconfig bool multithreading; bool stat; bool noBuffer; + int32_t processingTimeout; // Module options that cannot be put in module option structure #if defined(__linux__) || defined(__FreeBSD__)