php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #79994 pcntl_signal_get_handler() should return SIG_IGN for externally ignored signals
Submitted: 2020-08-18 21:07 UTC Modified: 2020-08-18 22:35 UTC
From: weirdan at gmail dot com Assigned:
Status: Open Package: PCNTL related
PHP Version: 7.4.9 OS: Linux (Debian/sid)
Private report: No CVE-ID: None
Welcome back! If you're the original bug submitter, here's where you can edit the bug or add additional notes.
If you forgot your password, you can retrieve your password here.
Password:
Status:
Package:
Bug Type:
Summary:
From: weirdan at gmail dot com
New email:
PHP Version: OS:

 

 [2020-08-18 21:07 UTC] weirdan at gmail dot com
Description:
------------
Originally discovered by John Stevenson here: https://github.com/composer/xdebug-handler/issues/109#issuecomment-675462698

When signal is set to be ignored by the process that calls php binary, pcntl_signal_get_handler() run in the context of that binary reports that same signal as using default handler (SIG_DFL). However it's clearly doesn't use default handler, as can demonstrated by the script below. If it was using default handler, you'd be able to abort the script with Ctrl-C, but you can't.

PS: use Ctrl-\ to stop it.

Test script:
---------------
<?php
var_dump(
    "Is default handler is used for sigint?", 
    pcntl_signal_get_handler(SIGINT) === SIG_DFL
);

while (true) {
    echo ".";
    sleep(2);
}

// Run it as follows (in bash/zsh):
// $ trap "" SIGINT; php test.php; trap - SIGINT;

Expected result:
----------------
string(38) "Is default handler is used for sigint?"
bool(false)
..................


Actual result:
--------------
string(38) "Is default handler is used for sigint?"
bool(true)
..................


Patches

Pull Requests

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2020-08-18 21:18 UTC] requinix@php.net
Not a bug, but I'll get to that.

First, a question: what should pcntl_signal_get_handler() be returning?
 [2020-08-18 21:21 UTC] weirdan at gmail dot com
It should return SIG_IGN in this case.
 [2020-08-18 21:43 UTC] requinix@php.net
-Summary: pcntl_signal_get_handler() returns SIG_DFL for externally ignored signals +Summary: pcntl_signal_get_handler() should return SIG_IGN for externally ignored signals
 [2020-08-18 21:43 UTC] requinix@php.net
Ah, you're reporting something slightly different than I thought. That's why I like asking questions. I'm slightly rewording the summary in case I'm not the only one mistaken.

Assuming that trap(1) is calling signal(7) or sigaction(7) with SIG_IGN, and given that sigaction is capable of returning the current signal handler (including whether it's ignored), then I agree that returning SIG_IGN is better than SIG_DFL.

Currently, PHP is returning what PHP was told to do. No custom handler means SIG_DFL.

I don't see that signal can return the current handler, though, so unless there's another function that can then this change in behavior may have to be platform-dependent.
 [2020-08-18 22:31 UTC] weirdan at gmail dot com
> I don't see that signal can return the current handler, though, so unless there's another function that can then this change in behavior may have to be platform-dependent.

Doesn't PHP use sigaction(), rather than signal() though? Looking at zend_sigaction() signature [1] it appears it should be possible to query the installed handler by calling zend_sigaction(SIGINT, NULL, &handler). As far as I can see, initial signal handlers are populated exactly the same way (but with actual sigaction()) into the global_orig_handlers [2] and then copied to zend_signal_globals on every request [3], from where they can be accessed by zend_sigaction() 

[1] https://github.com/php/php-src/blob/91fbd12d5736b3cc9fc6bc2545e877dd65be1f6c/Zend/zend_signal.c#L226
[2] https://github.com/php/php-src/blob/91fbd12d5736b3cc9fc6bc2545e877dd65be1f6c/Zend/zend_signal.c#L394-L404
[3] https://github.com/php/php-src/blob/91fbd12d5736b3cc9fc6bc2545e877dd65be1f6c/Zend/zend_signal.c#L376
 [2020-08-18 22:35 UTC] requinix@php.net
> Doesn't PHP use sigaction(), rather than signal() though?
I saw a "php_signal" function and didn't look too closely, but yes: php_signal -> php_signal4 -> zend_signal -> sigaction. So that's good.
 
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Thu Nov 21 19:01:29 2024 UTC