From 850a84584da49ae105146f3a51d445447383160e Mon Sep 17 00:00:00 2001 From: Relintai Date: Wed, 27 Jul 2022 14:46:53 +0200 Subject: [PATCH] ported: Add OS::is_process_running function. Adds the is_process_running function to the native OS class and exposes it to script. This is implemented on Windows and Unix platforms. A stub is provided for other platforms that do not support this function. Documentation is updated to reflect new API function. - mdavisprog https://github.com/godotengine/godot/commit/53fb0440d39337bacc6bdd4c386874d67cba939a I did change it a bit. --- core/bind/core_bind.cpp | 5 +++++ core/bind/core_bind.h | 1 + core/os/os.cpp | 6 +++++- core/os/os.h | 1 + doc/classes/OS.xml | 9 +++++++++ drivers/unix/os_unix.cpp | 11 ++++++++++- drivers/unix/os_unix.h | 1 + platform/windows/os_windows.cpp | 19 +++++++++++++++++++ platform/windows/os_windows.h | 1 + 9 files changed, 52 insertions(+), 2 deletions(-) diff --git a/core/bind/core_bind.cpp b/core/bind/core_bind.cpp index 780b33c00..07b5a98f2 100644 --- a/core/bind/core_bind.cpp +++ b/core/bind/core_bind.cpp @@ -508,6 +508,10 @@ Error _OS::kill(int p_pid) { return OS::get_singleton()->kill(p_pid); } +bool _OS::is_process_running(int p_pid) const { + return OS::get_singleton()->is_process_running(p_pid); +} + int _OS::get_process_id() const { return OS::get_singleton()->get_process_id(); }; @@ -1343,6 +1347,7 @@ void _OS::_bind_methods() { ClassDB::bind_method(D_METHOD("execute", "path", "arguments", "blocking", "output", "read_stderr", "open_console"), &_OS::execute, DEFVAL(true), DEFVAL(Array()), DEFVAL(false), DEFVAL(false)); ClassDB::bind_method(D_METHOD("kill", "pid"), &_OS::kill); ClassDB::bind_method(D_METHOD("shell_open", "uri"), &_OS::shell_open); + ClassDB::bind_method(D_METHOD("is_process_running", "pid"), &_OS::is_process_running); ClassDB::bind_method(D_METHOD("get_process_id"), &_OS::get_process_id); ClassDB::bind_method(D_METHOD("get_environment", "variable"), &_OS::get_environment); diff --git a/core/bind/core_bind.h b/core/bind/core_bind.h index 8d982c215..6dc9704af 100644 --- a/core/bind/core_bind.h +++ b/core/bind/core_bind.h @@ -247,6 +247,7 @@ public: Error kill(int p_pid); Error shell_open(String p_uri); + bool is_process_running(int p_pid) const; int get_process_id() const; bool has_environment(const String &p_var) const; diff --git a/core/os/os.cpp b/core/os/os.cpp index 2252ba1bd..984128a17 100644 --- a/core/os/os.cpp +++ b/core/os/os.cpp @@ -295,7 +295,11 @@ String OS::get_executable_path() const { int OS::get_process_id() const { return -1; -}; +} + +bool OS::is_process_running(const ProcessID &p_pid) const { + return false; +} void OS::vibrate_handheld(int p_duration_ms) { WARN_PRINT("vibrate_handheld() only works with Android and iOS"); diff --git a/core/os/os.h b/core/os/os.h index f87163823..e167c704d 100644 --- a/core/os/os.h +++ b/core/os/os.h @@ -323,6 +323,7 @@ public: virtual Error execute(const String &p_path, const List &p_arguments, bool p_blocking = true, ProcessID *r_child_id = nullptr, String *r_pipe = nullptr, int *r_exitcode = nullptr, bool read_stderr = false, Mutex *p_pipe_mutex = nullptr, bool p_open_console = false) = 0; virtual Error kill(const ProcessID &p_pid) = 0; virtual int get_process_id() const; + virtual bool is_process_running(const ProcessID &p_pid) const; virtual void vibrate_handheld(int p_duration_ms = 500); virtual Error shell_open(String p_uri); diff --git a/doc/classes/OS.xml b/doc/classes/OS.xml index 4e74e1bc7..859a8ec3d 100644 --- a/doc/classes/OS.xml +++ b/doc/classes/OS.xml @@ -686,6 +686,15 @@ Returns [code]true[/code] if the [b]OK[/b] button should appear on the left and [b]Cancel[/b] on the right. + + + + + Returns [code]true[/code] if the child process ID ([code]pid[/code]) is still running or [code]false[/code] if it has terminated. + Must be a valid ID generated from [method execute]. + [b]Note:[/b] This method is implemented on Android, iOS, Linux, macOS and Windows. + + diff --git a/drivers/unix/os_unix.cpp b/drivers/unix/os_unix.cpp index 323c4f76d..dfa3ecac1 100644 --- a/drivers/unix/os_unix.cpp +++ b/drivers/unix/os_unix.cpp @@ -361,7 +361,16 @@ Error OS_Unix::kill(const ProcessID &p_pid) { int OS_Unix::get_process_id() const { return getpid(); -}; +} + +bool OS_Unix::is_process_running(const ProcessID &p_pid) const { + int status = 0; + if (waitpid(p_pid, &status, WNOHANG) != 0) { + return false; + } + + return true; +} bool OS_Unix::has_environment(const String &p_var) const { return getenv(p_var.utf8().get_data()) != nullptr; diff --git a/drivers/unix/os_unix.h b/drivers/unix/os_unix.h index aa35273fb..42d7c8020 100644 --- a/drivers/unix/os_unix.h +++ b/drivers/unix/os_unix.h @@ -86,6 +86,7 @@ public: virtual Error execute(const String &p_path, const List &p_arguments, bool p_blocking = true, ProcessID *r_child_id = nullptr, String *r_pipe = nullptr, int *r_exitcode = nullptr, bool read_stderr = false, Mutex *p_pipe_mutex = nullptr, bool p_open_console = false); virtual Error kill(const ProcessID &p_pid); virtual int get_process_id() const; + virtual bool is_process_running(const ProcessID &p_pid) const; virtual bool has_environment(const String &p_var) const; virtual String get_environment(const String &p_var) const; diff --git a/platform/windows/os_windows.cpp b/platform/windows/os_windows.cpp index 217d5d3f9..a4a0b28fd 100644 --- a/platform/windows/os_windows.cpp +++ b/platform/windows/os_windows.cpp @@ -2890,6 +2890,25 @@ int OS_Windows::get_process_id() const { return _getpid(); } +bool OS_Windows::is_process_running(const ProcessID &p_pid) const { + if (!process_map->has(p_pid)) { + return false; + } + + const PROCESS_INFORMATION &pi = (*process_map)[p_pid].pi; + + DWORD dw_exit_code = 0; + if (!GetExitCodeProcess(pi.hProcess, &dw_exit_code)) { + return false; + } + + if (dw_exit_code != STILL_ACTIVE) { + return false; + } + + return true; +} + Error OS_Windows::set_cwd(const String &p_cwd) { if (_wchdir(p_cwd.c_str()) != 0) return ERR_CANT_OPEN; diff --git a/platform/windows/os_windows.h b/platform/windows/os_windows.h index 12ab5cfd0..16ef13d48 100644 --- a/platform/windows/os_windows.h +++ b/platform/windows/os_windows.h @@ -501,6 +501,7 @@ public: virtual Error execute(const String &p_path, const List &p_arguments, bool p_blocking = true, ProcessID *r_child_id = NULL, String *r_pipe = NULL, int *r_exitcode = NULL, bool read_stderr = false, Mutex *p_pipe_mutex = NULL, bool p_open_console = false); virtual Error kill(const ProcessID &p_pid); virtual int get_process_id() const; + virtual bool is_process_running(const ProcessID &p_pid) const; virtual bool has_environment(const String &p_var) const; virtual String get_environment(const String &p_var) const;