diff options
Diffstat (limited to 'drivers/unix')
-rw-r--r-- | drivers/unix/os_unix.cpp | 43 | ||||
-rw-r--r-- | drivers/unix/os_unix.h | 8 |
2 files changed, 51 insertions, 0 deletions
diff --git a/drivers/unix/os_unix.cpp b/drivers/unix/os_unix.cpp index ffeb5ad752..1a8cd53486 100644 --- a/drivers/unix/os_unix.cpp +++ b/drivers/unix/os_unix.cpp @@ -168,11 +168,13 @@ void OS_Unix::initialize_core() { NetSocketPosix::make_default(); IPUnix::make_default(); + process_map = memnew((HashMap<ProcessID, ProcessInfo>)); _setup_clock(); } void OS_Unix::finalize_core() { + memdelete(process_map); NetSocketPosix::cleanup(); } @@ -582,6 +584,11 @@ Dictionary OS_Unix::execute_with_pipe(const String &p_path, const List<String> & err_pipe.instantiate(); err_pipe->open_existing(pipe_err[0], 0); + ProcessInfo pi; + process_map_mutex.lock(); + process_map->insert(pid, pi); + process_map_mutex.unlock(); + ret["stdio"] = main_pipe; ret["stderr"] = err_pipe; ret["pid"] = pid; @@ -698,6 +705,11 @@ Error OS_Unix::create_process(const String &p_path, const List<String> &p_argume raise(SIGKILL); } + ProcessInfo pi; + process_map_mutex.lock(); + process_map->insert(pid, pi); + process_map_mutex.unlock(); + if (r_child_id) { *r_child_id = pid; } @@ -720,14 +732,45 @@ int OS_Unix::get_process_id() const { } bool OS_Unix::is_process_running(const ProcessID &p_pid) const { + MutexLock lock(process_map_mutex); + const ProcessInfo *pi = process_map->getptr(p_pid); + + if (pi && !pi->is_running) { + return false; + } + int status = 0; if (waitpid(p_pid, &status, WNOHANG) != 0) { + if (pi) { + pi->is_running = false; + pi->exit_code = status; + } return false; } return true; } +int OS_Unix::get_process_exit_code(const ProcessID &p_pid) const { + MutexLock lock(process_map_mutex); + const ProcessInfo *pi = process_map->getptr(p_pid); + + if (pi && !pi->is_running) { + return pi->exit_code; + } + + int status = 0; + if (waitpid(p_pid, &status, WNOHANG) != 0) { + status = WIFEXITED(status) ? WEXITSTATUS(status) : status; + if (pi) { + pi->is_running = false; + pi->exit_code = status; + } + return status; + } + return -1; +} + String OS_Unix::get_locale() const { if (!has_environment("LANG")) { return "en"; diff --git a/drivers/unix/os_unix.h b/drivers/unix/os_unix.h index 2936c28797..a107e7a0e3 100644 --- a/drivers/unix/os_unix.h +++ b/drivers/unix/os_unix.h @@ -37,6 +37,13 @@ #include "drivers/unix/ip_unix.h" class OS_Unix : public OS { + struct ProcessInfo { + mutable bool is_running = true; + mutable int exit_code = -1; + }; + HashMap<ProcessID, ProcessInfo> *process_map = nullptr; + Mutex process_map_mutex; + protected: // UNIX only handles the core functions. // inheriting platforms under unix (eg. X11) should handle the rest @@ -81,6 +88,7 @@ public: virtual Error kill(const ProcessID &p_pid) override; virtual int get_process_id() const override; virtual bool is_process_running(const ProcessID &p_pid) const override; + virtual int get_process_exit_code(const ProcessID &p_pid) const override; virtual bool has_environment(const String &p_var) const override; virtual String get_environment(const String &p_var) const override; |