@@ -57,12 +57,21 @@ pid_t ProcessHandleImpl::id() const
5757}
5858
5959
60+ int ProcessHandleImpl::statusToExitCode (int status)
61+ {
62+ if (WIFEXITED (status))
63+ return WEXITSTATUS (status);
64+ else
65+ return -WTERMSIG (status);
66+ }
67+
68+
6069int ProcessHandleImpl::wait () const
6170{
6271 if (wait (0 ) != _pid)
6372 throw SystemException (" Cannot wait for process" , NumberFormatter::format (_pid));
6473
65- return WEXITSTATUS (_status.value ());
74+ return statusToExitCode (_status.value ());
6675}
6776
6877
@@ -73,7 +82,7 @@ int ProcessHandleImpl::wait(int options) const
7382 int rc;
7483 do
7584 {
76- rc = waitpid (_pid, &status, options);
85+ rc = :: waitpid (_pid, &status, options);
7786 }
7887 while (rc < 0 && errno == EINTR);
7988 if (rc == _pid)
@@ -83,10 +92,9 @@ int ProcessHandleImpl::wait(int options) const
8392 }
8493 else if (rc < 0 && errno == ECHILD)
8594 {
86- // Looks like another thread was lucky and it should update the status for us shortly
87- _event.wait ();
88-
89- if (_status.has_value ())
95+ // Another thread reaped the process; wait for it to update the status.
96+ // Use a timeout to prevent hanging indefinitely if something goes wrong.
97+ if (_event.tryWait (5000 ) && _status.has_value ())
9098 {
9199 rc = _pid;
92100 }
@@ -98,21 +106,20 @@ int ProcessHandleImpl::wait(int options) const
98106
99107int ProcessHandleImpl::tryWait () const
100108{
101- int status;
102- int rc;
103- do
104- {
105- rc = waitpid (_pid, &status, WNOHANG);
106- }
107- while (rc < 0 && errno == EINTR);
109+ int rc = wait (WNOHANG);
108110 if (rc == 0 )
109111 return -1 ;
110112 if (rc != _pid)
111113 throw SystemException (" Cannot wait for process" , NumberFormatter::format (_pid));
112- if (WIFEXITED (status)) // normal termination
113- return WEXITSTATUS (status);
114- else // termination by a signal
115- return 256 + WTERMSIG (status);
114+ return statusToExitCode (_status.value ());
115+ }
116+
117+
118+ bool ProcessHandleImpl::isRunning () const
119+ {
120+ if (_status.has_value ())
121+ return false ;
122+ return wait (WNOHANG) == 0 ;
116123}
117124
118125
@@ -121,14 +128,14 @@ int ProcessHandleImpl::tryWait() const
121128//
122129ProcessImpl::PIDImpl ProcessImpl::idImpl ()
123130{
124- return getpid ();
131+ return :: getpid ();
125132}
126133
127134
128135void ProcessImpl::timesImpl (long & userTime, long & kernelTime)
129136{
130137 struct rusage usage;
131- getrusage (RUSAGE_SELF, &usage);
138+ :: getrusage (RUSAGE_SELF, &usage);
132139 userTime = usage.ru_utime .tv_sec ;
133140 kernelTime = usage.ru_stime .tv_sec ;
134141}
@@ -137,7 +144,7 @@ void ProcessImpl::timesImpl(long& userTime, long& kernelTime)
137144void ProcessImpl::timesMicrosecondsImpl (Poco::Int64& userTime, Poco::Int64& kernelTime)
138145{
139146 struct rusage usage;
140- getrusage (RUSAGE_SELF, &usage);
147+ :: getrusage (RUSAGE_SELF, &usage);
141148 userTime = static_cast <Poco::Int64>(usage.ru_utime .tv_sec )*1000000 + usage.ru_utime .tv_usec ;
142149 kernelTime = static_cast <Poco::Int64>(usage.ru_stime .tv_sec )*1000000 + usage.ru_stime .tv_usec ;
143150}
@@ -186,17 +193,17 @@ ProcessHandleImpl* ProcessImpl::launchImpl(const std::string& command, const Arg
186193 envPtr = &envPtrs[0 ];
187194 }
188195
189- int pid = spawn (command.c_str (), 3 , fdmap, &inherit, argv, envPtr);
196+ int pid = :: spawn (command.c_str (), 3 , fdmap, &inherit, argv, envPtr);
190197 delete [] argv;
191198 if (pid == -1 )
192199 throw SystemException (" cannot spawn" , command);
193200
194201 if (inPipe) inPipe->close (Pipe::CLOSE_READ);
195- if (options & PROCESS_CLOSE_STDIN) close (STDIN_FILENO);
202+ if (options & PROCESS_CLOSE_STDIN) :: close (STDIN_FILENO);
196203 if (outPipe) outPipe->close (Pipe::CLOSE_WRITE);
197- if (options & PROCESS_CLOSE_STDOUT) close (STDOUT_FILENO);
204+ if (options & PROCESS_CLOSE_STDOUT) :: close (STDOUT_FILENO);
198205 if (errPipe) errPipe->close (Pipe::CLOSE_WRITE);
199- if (options & PROCESS_CLOSE_STDERR) close (STDERR_FILENO);
206+ if (options & PROCESS_CLOSE_STDERR) :: close (STDERR_FILENO);
200207 return new ProcessHandleImpl (pid);
201208 }
202209 else
@@ -234,7 +241,7 @@ ProcessHandleImpl* ProcessImpl::launchByForkExecImpl(const std::string& command,
234241
235242 const char * pInitialDirectory = initialDirectory.empty () ? nullptr : initialDirectory.c_str ();
236243
237- int pid = fork ();
244+ int pid = :: fork ();
238245 if (pid < 0 )
239246 {
240247 throw SystemException (" Cannot fork process for" , command);
@@ -243,7 +250,7 @@ ProcessHandleImpl* ProcessImpl::launchByForkExecImpl(const std::string& command,
243250 {
244251 if (pInitialDirectory)
245252 {
246- if (chdir (pInitialDirectory) != 0 )
253+ if (:: chdir (pInitialDirectory) != 0 )
247254 {
248255 break ;
249256 }
@@ -253,33 +260,33 @@ ProcessHandleImpl* ProcessImpl::launchByForkExecImpl(const std::string& command,
253260 char * p = &envChars[0 ];
254261 while (*p)
255262 {
256- putenv (p);
263+ :: putenv (p);
257264 while (*p) ++p;
258265 ++p;
259266 }
260267
261268 // setup redirection
262269 if (inPipe)
263270 {
264- dup2 (inPipe->readHandle (), STDIN_FILENO);
271+ :: dup2 (inPipe->readHandle (), STDIN_FILENO);
265272 inPipe->close (Pipe::CLOSE_BOTH);
266273 }
267- if (options & PROCESS_CLOSE_STDIN) close (STDIN_FILENO);
274+ if (options & PROCESS_CLOSE_STDIN) :: close(STDIN_FILENO);
268275
269276 // outPipe and errPipe may be the same, so we dup first and close later
270- if (outPipe) dup2 (outPipe->writeHandle (), STDOUT_FILENO);
271- if (errPipe) dup2 (errPipe->writeHandle (), STDERR_FILENO);
277+ if (outPipe) :: dup2 (outPipe->writeHandle (), STDOUT_FILENO);
278+ if (errPipe) :: dup2 (errPipe->writeHandle (), STDERR_FILENO);
272279 if (outPipe) outPipe->close (Pipe::CLOSE_BOTH);
273- if (options & PROCESS_CLOSE_STDOUT) close (STDOUT_FILENO);
280+ if (options & PROCESS_CLOSE_STDOUT) :: close (STDOUT_FILENO);
274281 if (errPipe) errPipe->close (Pipe::CLOSE_BOTH);
275- if (options & PROCESS_CLOSE_STDERR) close (STDERR_FILENO);
282+ if (options & PROCESS_CLOSE_STDERR) :: close (STDERR_FILENO);
276283 // close all open file descriptors other than stdin, stdout, stderr
277- long fdMax = sysconf (_SC_OPEN_MAX);
284+ long fdMax = :: sysconf (_SC_OPEN_MAX);
278285 // on some systems, sysconf(_SC_OPEN_MAX) returns a ridiculously high number
279286 if (fdMax > CLOSE_FD_MAX) fdMax = CLOSE_FD_MAX;
280287 for (long j = 3 ; j < fdMax; ++j)
281288 {
282- close (j);
289+ :: close (j);
283290 }
284291
285292 // Create a new process group so the entire tree can be signaled.
@@ -289,7 +296,7 @@ ProcessHandleImpl* ProcessImpl::launchByForkExecImpl(const std::string& command,
289296 _exit (PROCESS_EXIT_SETPGID_FAILED);
290297 }
291298
292- execvp (argv[0 ], &argv[0 ]);
299+ :: execvp (argv[0 ], &argv[0 ]);
293300 break ;
294301 }
295302
@@ -322,7 +329,7 @@ void ProcessImpl::killImpl(ProcessHandleImpl& handle)
322329
323330void ProcessImpl::killImpl (PIDImpl pid)
324331{
325- if (kill (pid, SIGKILL) != 0 )
332+ if (:: kill (pid, SIGKILL) != 0 )
326333 {
327334 switch (errno)
328335 {
@@ -339,13 +346,13 @@ void ProcessImpl::killImpl(PIDImpl pid)
339346
340347bool ProcessImpl::isRunningImpl (const ProcessHandleImpl& handle)
341348{
342- return isRunningImpl ( handle.id () );
349+ return handle.isRunning ( );
343350}
344351
345352
346353bool ProcessImpl::isRunningImpl (PIDImpl pid)
347354{
348- if (kill (pid, 0 ) == 0 )
355+ if (:: kill (pid, 0 ) == 0 )
349356 {
350357 return true ;
351358 }
@@ -358,7 +365,7 @@ bool ProcessImpl::isRunningImpl(PIDImpl pid)
358365
359366void ProcessImpl::requestTerminationImpl (PIDImpl pid)
360367{
361- if (kill (pid, SIGINT) != 0 )
368+ if (:: kill (pid, SIGINT) != 0 )
362369 {
363370 switch (errno)
364371 {
0 commit comments