diff options
Diffstat (limited to 'drivers/unix/os_unix.cpp')
-rw-r--r-- | drivers/unix/os_unix.cpp | 67 |
1 files changed, 31 insertions, 36 deletions
diff --git a/drivers/unix/os_unix.cpp b/drivers/unix/os_unix.cpp index ce1c183242..ab5590dba4 100644 --- a/drivers/unix/os_unix.cpp +++ b/drivers/unix/os_unix.cpp @@ -72,8 +72,7 @@ static double _clock_scale = 0; static void _setup_clock() { mach_timebase_info_data_t info; kern_return_t ret = mach_timebase_info(&info); - ERR_EXPLAIN("OS CLOCK IS NOT WORKING!"); - ERR_FAIL_COND(ret != 0); + ERR_FAIL_COND_MSG(ret != 0, "OS CLOCK IS NOT WORKING!"); _clock_scale = ((double)info.numer / (double)info.denom) / 1000.0; _clock_start = mach_absolute_time() * _clock_scale; } @@ -85,8 +84,7 @@ static void _setup_clock() { #endif static void _setup_clock() { struct timespec tv_now = { 0, 0 }; - ERR_EXPLAIN("OS CLOCK IS NOT WORKING!"); - ERR_FAIL_COND(clock_gettime(GODOT_CLOCK, &tv_now) != 0); + ERR_FAIL_COND_MSG(clock_gettime(GODOT_CLOCK, &tv_now) != 0, "OS CLOCK IS NOT WORKING!"); _clock_start = ((uint64_t)tv_now.tv_nsec / 1000L) + (uint64_t)tv_now.tv_sec * 1000000L; } #endif @@ -108,6 +106,7 @@ void OS_Unix::initialize_debugging() { if (ScriptDebugger::get_singleton() != NULL) { struct sigaction action; + memset(&action, 0, sizeof(action)); action.sa_handler = handle_interrupt; sigaction(SIGINT, &action, NULL); } @@ -118,15 +117,6 @@ int OS_Unix::unix_initialize_audio(int p_audio_driver) { return 0; } -// Very simple signal handler to reap processes where ::execute was called with -// !p_blocking -void handle_sigchld(int sig) { - int saved_errno = errno; - while (waitpid((pid_t)(-1), 0, WNOHANG) > 0) { - } - errno = saved_errno; -} - void OS_Unix::initialize_core() { #ifdef NO_THREADS @@ -154,14 +144,6 @@ void OS_Unix::initialize_core() { #endif _setup_clock(); - - struct sigaction sa; - sa.sa_handler = &handle_sigchld; - sigemptyset(&sa.sa_mask); - sa.sa_flags = SA_RESTART | SA_NOCLDSTOP; - if (sigaction(SIGCHLD, &sa, 0) == -1) { - perror("ERROR sigaction() failed:"); - } } void OS_Unix::finalize_core() { @@ -186,7 +168,7 @@ String OS_Unix::get_stdin_string(bool p_block) { return ""; } -String OS_Unix::get_name() { +String OS_Unix::get_name() const { return "Unix"; } @@ -272,7 +254,7 @@ OS::TimeZoneInfo OS_Unix::get_time_zone_info() const { void OS_Unix::delay_usec(uint32_t p_usec) const { - struct timespec rem = { static_cast<time_t>(p_usec / 1000000), static_cast<long>((p_usec % 1000000) * 1000) }; + struct timespec rem = { static_cast<time_t>(p_usec / 1000000), (static_cast<long>(p_usec) % 1000000) * 1000 }; while (nanosleep(&rem, &rem) == EINTR) { } } @@ -282,7 +264,7 @@ uint64_t OS_Unix::get_ticks_usec() const { uint64_t longtime = mach_absolute_time() * _clock_scale; #else // Unchecked return. Static analyzers might complain. - // If _setup_clock() succeded, we assume clock_gettime() works. + // If _setup_clock() succeeded, we assume clock_gettime() works. struct timespec tv_now = { 0, 0 }; clock_gettime(GODOT_CLOCK, &tv_now); uint64_t longtime = ((uint64_t)tv_now.tv_nsec / 1000L) + (uint64_t)tv_now.tv_sec * 1000000L; @@ -292,7 +274,7 @@ uint64_t OS_Unix::get_ticks_usec() const { return longtime; } -Error OS_Unix::execute(const String &p_path, const List<String> &p_arguments, bool p_blocking, ProcessID *r_child_id, String *r_pipe, int *r_exitcode, bool read_stderr) { +Error OS_Unix::execute(const String &p_path, const List<String> &p_arguments, bool p_blocking, ProcessID *r_child_id, String *r_pipe, int *r_exitcode, bool read_stderr, Mutex *p_pipe_mutex) { #ifdef __EMSCRIPTEN__ // Don't compile this code at all to avoid undefined references. @@ -319,11 +301,17 @@ Error OS_Unix::execute(const String &p_path, const List<String> &p_arguments, bo ERR_FAIL_COND_V(!f, ERR_CANT_OPEN); char buf[65535]; + while (fgets(buf, 65535, f)) { + if (p_pipe_mutex) { + p_pipe_mutex->lock(); + } (*r_pipe) += buf; + if (p_pipe_mutex) { + p_pipe_mutex->unlock(); + } } - int rv = pclose(f); if (r_exitcode) *r_exitcode = rv; @@ -336,6 +324,13 @@ Error OS_Unix::execute(const String &p_path, const List<String> &p_arguments, bo if (pid == 0) { // is child + + if (!p_blocking) { + // For non blocking calls, create a new session-ID so parent won't wait for it. + // This ensures the process won't go zombie at end. + setsid(); + } + Vector<CharString> cs; cs.push_back(p_path.utf8()); for (int i = 0; i < p_arguments.size(); i++) @@ -358,6 +353,7 @@ Error OS_Unix::execute(const String &p_path, const List<String> &p_arguments, bo waitpid(pid, &status, 0); if (r_exitcode) *r_exitcode = WEXITSTATUS(status); + } else { if (r_child_id) @@ -422,10 +418,7 @@ Error OS_Unix::open_dynamic_library(const String p_path, void *&p_library_handle } p_library_handle = dlopen(path.utf8().get_data(), RTLD_NOW); - if (!p_library_handle) { - ERR_EXPLAIN("Can't open dynamic library: " + p_path + ". Error: " + dlerror()); - ERR_FAIL_V(ERR_CANT_OPEN); - } + ERR_FAIL_COND_V_MSG(!p_library_handle, ERR_CANT_OPEN, "Can't open dynamic library: " + p_path + ". Error: " + dlerror()); return OK; } @@ -444,12 +437,9 @@ Error OS_Unix::get_dynamic_library_symbol_handle(void *p_library_handle, const S error = dlerror(); if (error != NULL) { - if (!p_optional) { - ERR_EXPLAIN("Can't resolve symbol " + p_name + ". Error: " + error); - ERR_FAIL_V(ERR_CANT_RESOLVE); - } else { - return ERR_CANT_RESOLVE; - } + ERR_FAIL_COND_V_MSG(!p_optional, ERR_CANT_RESOLVE, "Can't resolve symbol " + p_name + ". Error: " + error + "."); + + return ERR_CANT_RESOLVE; } return OK; } @@ -469,6 +459,11 @@ String OS_Unix::get_environment(const String &p_var) const { return ""; } +bool OS_Unix::set_environment(const String &p_var, const String &p_value) const { + + return setenv(p_var.utf8().get_data(), p_value.utf8().get_data(), /* overwrite: */ true) == 0; +} + int OS_Unix::get_processor_count() const { return sysconf(_SC_NPROCESSORS_CONF); |