-
Notifications
You must be signed in to change notification settings - Fork 7.9k
Implement pcntl_waitid #14617
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Implement pcntl_waitid #14617
Changes from 27 commits
1fe4de1
0483f22
ecefc18
c8ff3b6
2dd62b9
0ccd92f
712b536
dfe3bfe
e23bc2d
651df1f
3ab725d
93f4fad
ee6b65d
4830687
e3cfd08
ba5d347
324b79c
ab07bc0
f01aeb3
52fce3d
d39033a
5deaba1
e1399cf
d173be1
5793dcd
509c92f
31f3856
a0df466
8763548
5021e88
1bf8873
25fc4db
2df267a
9124b1e
80a1da8
ea33122
5f540d8
595b9c4
0011541
1993ec1
19e0612
207ea17
e69f6c7
ed38397
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -125,6 +125,24 @@ static zend_class_entry *QosClass_ce; | |
|
||
#define LONG_CONST(c) (zend_long) c | ||
|
||
#ifdef HAVE_WAITID | ||
#if defined(HAVE_LINUX_WAIT_H) | ||
#include <linux/wait.h> | ||
#endif | ||
#if defined (P_ALL) | ||
#define HAVE_POSIX_IDTYPES 1 | ||
#endif | ||
#if defined (P_PIDFD) | ||
#define HAVE_LINUX_IDTYPES 1 | ||
#endif | ||
#if defined (P_UID) | ||
#define HAVE_NETBSD_IDTYPES 1 | ||
#endif | ||
#if defined (P_JAILID) | ||
#define HAVE_FREEBSD_IDTYPES 1 | ||
#endif | ||
#endif | ||
|
||
#include "Zend/zend_enum.h" | ||
#include "Zend/zend_max_execution_timer.h" | ||
|
||
|
@@ -385,6 +403,45 @@ PHP_FUNCTION(pcntl_waitpid) | |
} | ||
/* }}} */ | ||
|
||
#ifdef HAVE_WAITID | ||
PHP_FUNCTION(pcntl_waitid) | ||
{ | ||
zend_long idtype = P_PID; | ||
zend_long id = 0; | ||
bool id_is_null = 1; | ||
zval *user_siginfo = NULL; | ||
zend_long options = WEXITED; | ||
|
||
ZEND_PARSE_PARAMETERS_START(2, 4) | ||
Z_PARAM_LONG(idtype) | ||
Z_PARAM_LONG_OR_NULL(id, id_is_null) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. why is this parameter nullable? Apparently, it's not used anywhere.
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It's a minor style point. From the API design standpoint it's not strictly necessary to allow For example, compare: pcntl_waitid(P_ALL, null, $info); with pcntl_waitid(P_ALL, 0, $info); or even pcntl_waitid(P_ALL, 42, $info); They all do the same thing, but IMHO the first version best communicates to the person reading the PHP code that we don't really care about the value of the second param ( In the C code, the |
||
Z_PARAM_OPTIONAL | ||
Z_PARAM_ZVAL(user_siginfo) | ||
Z_PARAM_LONG(options) | ||
ZEND_PARSE_PARAMETERS_END(); | ||
|
||
errno = 0; | ||
siginfo_t siginfo; | ||
|
||
int status = waitid((idtype_t) idtype, (id_t) id, &siginfo, (int) options); | ||
|
||
if (status == -1) { | ||
if (errno == EINVAL) { | ||
zend_value_error("An invalid value was specified for options, or idtype and id specify an invalid set of processes"); | ||
RETURN_THROWS(); | ||
} | ||
PCNTL_G(last_error) = errno; | ||
php_error_docref(NULL, E_WARNING, "%s", strerror(errno)); | ||
RETURN_FALSE; | ||
} | ||
vrza marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
// TODO verify that passing SIGCHLD does what we need | ||
pcntl_siginfo_to_zval(SIGCHLD, &siginfo, user_siginfo); | ||
|
||
RETURN_TRUE; | ||
} | ||
#endif | ||
|
||
/* {{{ Waits on or returns the status of a forked child as defined by the waitpid() system call */ | ||
PHP_FUNCTION(pcntl_wait) | ||
{ | ||
|
@@ -1685,7 +1742,7 @@ PHP_FUNCTION(pcntl_setcpuaffinity) | |
zend_argument_value_error(2, "cpu id must be between 0 and " ZEND_ULONG_FMT " (" ZEND_LONG_FMT ")", maxcpus, cpu); | ||
RETURN_THROWS(); | ||
} | ||
|
||
if (!PCNTL_CPU_ISSET(cpu, mask)) { | ||
PCNTL_CPU_SET(cpu, mask); | ||
} | ||
|
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,76 @@ | ||
--TEST-- | ||
pcntl_waitid() | ||
--EXTENSIONS-- | ||
pcntl | ||
posix | ||
--SKIPIF-- | ||
<?php | ||
if (!function_exists('pcntl_waitid')) die('skip pcntl_waitid unavailable'); | ||
?> | ||
--FILE-- | ||
<?php | ||
$pid = pcntl_fork(); | ||
if ($pid == -1) { | ||
die("failed"); | ||
} else if ($pid) { | ||
// invalid idtype | ||
try { | ||
pcntl_waitid(-42, $pid, $siginfo, WSTOPPED); | ||
} catch (\ValueError $e) { | ||
echo $e->getMessage() . \PHP_EOL; | ||
} | ||
try { | ||
pcntl_waitid(PHP_INT_MAX, $pid, $siginfo, WSTOPPED); | ||
} catch (\ValueError $e) { | ||
echo $e->getMessage() . \PHP_EOL; | ||
} | ||
// invalid flags | ||
try { | ||
pcntl_waitid(P_PID, $pid, $siginfo, -42); | ||
} catch (\ValueError $e) { | ||
echo $e->getMessage() . \PHP_EOL; | ||
} | ||
try { | ||
pcntl_waitid(P_PID, $pid, $siginfo, PHP_INT_MAX); | ||
} catch (\ValueError $e) { | ||
echo $e->getMessage() . \PHP_EOL; | ||
} | ||
// need at least one of WEXITED, WSTOPPED, WCONTINUED flagd | ||
try { | ||
pcntl_waitid(P_PID, $pid, $siginfo, WNOHANG); | ||
} catch (\ValueError $e) { | ||
echo $e->getMessage() . \PHP_EOL; | ||
} | ||
|
||
// with WNOHANG, call succeeds but there is no PID state change | ||
$result = pcntl_waitid(P_PID, $pid, $siginfo, WEXITED | WNOHANG); | ||
var_dump($result); | ||
var_dump($siginfo["pid"]); | ||
|
||
$result = pcntl_waitid(P_PID, $pid, $siginfo, WSTOPPED); | ||
var_dump($result); | ||
|
||
posix_kill($pid, SIGCONT); | ||
$result = pcntl_waitid(P_PID, $pid, $siginfo, WCONTINUED); | ||
var_dump($result); | ||
|
||
$result = pcntl_waitid(P_PID, $pid, $siginfo, WEXITED); | ||
var_dump($result); | ||
var_dump($siginfo["status"]); | ||
} else { | ||
posix_kill(posix_getpid(), SIGSTOP); | ||
exit(42); | ||
} | ||
?> | ||
--EXPECTF-- | ||
An invalid value was specified for options, or idtype and id specify an invalid set of processes | ||
An invalid value was specified for options, or idtype and id specify an invalid set of processes | ||
An invalid value was specified for options, or idtype and id specify an invalid set of processes | ||
An invalid value was specified for options, or idtype and id specify an invalid set of processes | ||
An invalid value was specified for options, or idtype and id specify an invalid set of processes | ||
bool(true) | ||
int(0) | ||
bool(true) | ||
bool(true) | ||
bool(true) | ||
int(42) |
Uh oh!
There was an error while loading. Please reload this page.