-
Notifications
You must be signed in to change notification settings - Fork 7.9k
Fix GH-11498: SIGCHLD is not always returned from proc_open #11509
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
Conversation
Linux, and maybe other unixes, may merge multiple standard signals into a single one. This causes issues when keeping track of process IDs. Solve this by manually checking which children are dead using waitpid(). Test case is based on taka-oyama's test code.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The code looks correct to me, nice work!
while (true) { | ||
do { | ||
errno = 0; | ||
pid = waitpid(WAIT_ANY, &status, WNOHANG); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Linux docs say that waitpid
with WNOHANG
can't EINTR
, but then again https://www.gnu.org/software/libc/manual/html_node/Merged-Signals.html looks like the code this is proposing, so it's probably better to keep it. Also not sure about other Unix systems.
Btw, might be good to link the above somewhere.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
About Linux docs: yes, but POSIX doesn't specify that so we should indeed keep it :) https://pubs.opengroup.org/onlinepubs/9699919799/functions/waitpid.html
And yes, forgot to link that, my mistake.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'll actually add that as a note too; otherwise we risk someone in the future going like "well this cannot happen, yeet"
I forgot to add this in phpGH-11509.
FYI building on musl the |
Thanks @nielsdos! I'll adjust. |
Thx |
@iluuu1994 the issue with musl is that Mostly all distros based on it has rolling release cycle, so it will need to adjust test few times a year. Please point me what I can use as example, so I willing to give a try to add it using Alpinelinux stable release |
Thank you! All Alpinelinux infra using docker, except builders so there's preexisting images for sure but devil in nitpicks |
@iluuu1994 this commit changes the way how SIGCHLD is handled in PHP. Previously, upon receiving a SIGCHLD you could do a pcntl_wait loop to check for all terminated childs. This commit makes this impossible. Is this intended behavior as this is not BC. For example, this no longer works:
|
@dicode-nl Hmm. I did not consider this. The BC break was definitely not intended. I think PHP automatically splitting |
I didn't consider this either. |
@iluuu1994 I'm not sure either which way to go. At least it should be documented. For me it feels more natural to call waitpid and others to get the child status, but this commit makes that virtually impossible. |
@nielsdos Good points. It seems like most functions in pcntl are just thin wrappers. Since the issue can be solved in PHP as demonstrated by @dicode-nl, it might be better to revert the change. |
Ok for me |
I've file the revert PR here: #11863 |
Linux, and maybe other unixes, may merge multiple standard signals into a single one. This causes issues when keeping track of process IDs. Solve this by manually checking which children are dead using waitpid().
Test case is based on taka-oyama's test code.