X-Git-Url: https://main.carlh.net/gitweb/?a=blobdiff_plain;f=libs%2Fpbd%2Fsystem_exec.cc;h=60e73badfcf19eb567ebe72f91a2a63253608819;hb=b11a18d226ba505c3f873f9bbf242fbb9391f42f;hp=5d2db21efca71118012c1009c62f3dab084b52e3;hpb=f0dbd6c0855e76a87d97a1774f2e97a5b9211ae6;p=ardour.git diff --git a/libs/pbd/system_exec.cc b/libs/pbd/system_exec.cc index 5d2db21efc..60e73badfc 100644 --- a/libs/pbd/system_exec.cc +++ b/libs/pbd/system_exec.cc @@ -55,7 +55,10 @@ using namespace std; using namespace PBD; static void * interposer_thread (void *arg); + +#ifndef PLATFORM_WINDOWS /* POSIX Process only */ static void close_fd (int& fd) { if (fd >= 0) ::close (fd); fd = -1; } +#endif #if (!defined PLATFORM_WINDOWS && defined NO_VFORK) /* @@ -195,10 +198,13 @@ SystemExec::SystemExec (std::string command, const std::map s { init (); make_argp_escaped(command, subs); - if (!find_file_in_search_path (Searchpath (Glib::getenv ("PATH")), argp[0], cmd)) { - // not found in path - use as-is - cmd = argp[0]; + + if (find_file (Searchpath (Glib::getenv ("PATH")), argp[0], cmd)) { + // argp[0] exists in $PATH` - set it to the actual path where it was found + free (argp[0]); + argp[0] = strdup(cmd.c_str ()); } + // else argp[0] not found in path - leave it as-is, it might be an absolute path // Glib::find_program_in_path () is only available in Glib >= 2.28 // cmd = Glib::find_program_in_path (argp[0]); @@ -281,13 +287,13 @@ SystemExec::~SystemExec () terminate (); if (envp) { for (int i=0;envp[i];++i) { - free(envp[i]); + free(envp[i]); } free (envp); } if (argp) { for (int i=0;argp[i];++i) { - free(argp[i]); + free(argp[i]); } free (argp); } @@ -410,8 +416,7 @@ int SystemExec::wait (int options) { while (is_running()) { - WaitForSingleObject(pid->hProcess, INFINITE); - Sleep(20); + WaitForSingleObject(pid->hProcess, 40); } return 0; } @@ -419,7 +424,12 @@ SystemExec::wait (int options) bool SystemExec::is_running () { - return pid?true:false; + if (!pid) return false; + DWORD exit_code; + if (GetExitCodeProcess(pid->hProcess, &exit_code)) { + if (exit_code == STILL_ACTIVE) return true; + } + return false; } int @@ -802,6 +812,10 @@ SystemExec::start (int stderr_mode, const char *vfork_exec_wrapper) #else signal(SIGPIPE, SIG_DFL); #endif + if (!vfork_exec_wrapper) { + error << _("Cannot start external process, no vfork wrapper") << endmsg; + return -1; + } int good_fds[2] = { pok[1], -1 }; close_allv(good_fds); @@ -864,7 +878,16 @@ SystemExec::output_interposer() for (;fcntl(rfd, F_GETFL)!=-1;) { r = read(rfd, buf, sizeof(buf)); if (r < 0 && (errno == EINTR || errno == EAGAIN)) { - ::usleep(1000); + fd_set rfds; + struct timeval tv; + FD_ZERO(&rfds); + FD_SET(rfd, &rfds); + tv.tv_sec = 0; + tv.tv_usec = 10000; + int rv = select(1, &rfds, NULL, NULL, &tv); + if (rv == -1) { + break; + } continue; } if (r <= 0) {