diff options
Diffstat (limited to 'drivers/unix/os_unix.cpp')
-rw-r--r-- | drivers/unix/os_unix.cpp | 68 |
1 files changed, 30 insertions, 38 deletions
diff --git a/drivers/unix/os_unix.cpp b/drivers/unix/os_unix.cpp index e7550903a8..25dee6aedb 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 @@ -136,7 +126,9 @@ void OS_Unix::initialize_core() { RWLockDummy::make_default(); #else ThreadPosix::make_default(); +#if !defined(OSX_ENABLED) && !defined(IPHONE_ENABLED) SemaphorePosix::make_default(); +#endif MutexPosix::make_default(); RWLockPosix::make_default(); #endif @@ -154,14 +146,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 +170,7 @@ String OS_Unix::get_stdin_string(bool p_block) { return ""; } -String OS_Unix::get_name() { +String OS_Unix::get_name() const { return "Unix"; } @@ -205,7 +189,7 @@ uint64_t OS_Unix::get_system_time_secs() const { uint64_t OS_Unix::get_system_time_msecs() const { struct timeval tv_now; gettimeofday(&tv_now, NULL); - return uint64_t(tv_now.tv_sec * 1000 + tv_now.tv_usec / 1000); + return uint64_t(tv_now.tv_sec) * 1000 + uint64_t(tv_now.tv_usec) / 1000; } OS::Date OS_Unix::get_date(bool utc) const { @@ -272,7 +256,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) { } } @@ -292,7 +276,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. @@ -316,17 +300,23 @@ Error OS_Unix::execute(const String &p_path, const List<String> &p_arguments, bo } FILE *f = popen(argss.utf8().get_data(), "r"); - ERR_FAIL_COND_V(!f, ERR_CANT_OPEN); + ERR_FAIL_COND_V_MSG(!f, ERR_CANT_OPEN, "Cannot pipe stream from process running with following arguments '" + argss + "'."); 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; + *r_exitcode = WEXITSTATUS(rv); return OK; } @@ -336,6 +326,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 +355,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 +420,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 +439,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; } |