Bug #78548 [NEW]: Feature request: pcntl_signal_names() -> array of compiled-in signal labels
| From: | asmqb7 at gmail dot com | Date: | Mon, 16 Sep 2019 04:38:20 +0000 |
| Subject: | Bug #78548 [NEW]: Feature request: pcntl_signal_names() -> array of compiled-in signal labels | ||
| Groups: | php.bugs | ||
| Request: | Send a blank email to php-bugs+get-222759@lists.php.net to get a copy of this message | ||
From: asmqb7 at gmail dot com
Operating system: Linux
PHP version: 7.4.0RC1
Package: PCNTL related
Bug Type: Bug
Bug description:Feature request: pcntl_signal_names() -> array of compiled-in signal labels
Description:
------------
I recently wanted a long-running application to print out something like
"Exiting on SIGINT (2)" at exit.
Everything was easy to get working - except for actually determining
what signal maps to what label. This isn't trivial to do because
a) Signal numbers are OS-specific.
Glancing at
https://elixir.bootlin.com/linux/v4.3/source/arch/x86/include/uapi/asm/signal.h#L38
and
https://www.freebsd.org/cgi/man.cgi?query=signal&manpath=FreeBSD+12.0-RELEASE,
I see
- SIGSTKFLT is 16 on Linux and SIGURG on FreeBSD
- SIGSTOP is 19 on Linux and 16 on FreeBSD
So the same number can be different identifiers, and the same identifier
can be different numbers. Point already probably known but ok.
b) Signal support can be compiled out of PHP based on #defines - see
https://github.com/php/php-src/blob/99ce142f6e37e803ce7c0fdaece79b9813c33543/ext/pcntl/pcntl.c#L258
With both of these things in mind, the only workable approach was to
hardcode a list and fill it in as best as I could. This approach is
listed is in the Test Script section below.
Far better would be a function, named as in the summary or with any
other sensible name, that returns any of
- ['SIGHUP', 'SIGINT', ...]
- ['SIGHUP' => 1, 'SIGINT' => 2, ...]
- [1 => 'SIGHUP', 2 => 'SIGINT', ...]
All three provide equivalent levels of functionality, because
get_defined_constants() maps the labels to their correct values. To be
extremely specific, the sole purpose of this function is to provide a
list of which signals are *defined*.
Using get_defined_constants() is unworkable because...
Array
(
<irrelevant; snipped>
[SIG_IGN] => 1
[SIG_DFL] => 0
[SIG_ERR] => -1
[SIGHUP] => 1
[SIGINT] => 2
[SIGQUIT] => 3
<rest of defined signals; snipped>
[SIGBABY] => 31
[SIGRTMIN] => 34
[SIGRTMAX] => 64
<irrelevant; snipped>
[SIG_BLOCK] => 0
[SIG_UNBLOCK] => 1
[SIG_SETMASK] => 2
<irrelevant; snipped>
)
...it lumps the signal names in with a bunch of other things that have
values that clash with signal values, so when I didn't filter the list
properly (/^SIG[^_]/) my final list was like [SIG_DFL, SIG_IGN,
SIG_UNBLOCK, SIG_SETMASK, SIGQUIT] - because SIG_DFL has a value of -1,
and SIG_UNBLOCK (which overwrote SIGHUP) a value of 1.
The secondary implicit purpose of the function I describe is to return
an array that _only_ has signal names in it.
The chances of pcntl's constants changing substantively anytime soon are
VERY unlikely, but... no. I'm not parsing the output of
get_defined_constants(). That specific brand of "just make it work" is
the kind of hand-wavy programming that fails years later in interesting
and sometimes catastrophic ways, and is what got PHP its reputation as a
poor-quality environment.
Test script:
---------------
$pcntl_constants = get_defined_constants(true)['pcntl'];
foreach ([
'SIGHUP', 'SIGPIPE', 'SIGXFSZ',
'SIGINT', 'SIGALRM', 'SIGVTALRM',
'SIGQUIT', 'SIGTERM', 'SIGPROF',
'SIGILL', 'SIGSTKFLT', 'SIGWINCH',
'SIGTRAP', 'SIGCLD', 'SIGPOLL',
'SIGABRT', 'SIGCHLD', 'SIGIO',
'SIGIOT', 'SIGCONT', 'SIGPWR',
'SIGBUS', 'SIGSTOP', 'SIGSYS',
'SIGFPE', 'SIGTSTP', 'SIGBABY',
'SIGKILL', 'SIGTTIN', 'SIGRTMIN',
'SIGUSR1', 'SIGTTOU', 'SIGRTMAX',
'SIGSEGV', 'SIGURG',
'SIGUSR2', 'SIGXCPU'
] as $siglabel) {
if (isset($pcntl_constants[$siglabel])) {
$siglabels[$pcntl_constants[$siglabel]] = $siglabel;
}
}
// The list is formatted as columns (current fad :) ) so fix it
ksort($siglabels);
// Do something with $siglabels
var_dump($siglabels);
Expected result:
----------------
The test script contains a user-supplied array of signals. I'd like to
not have to provide this.
Actual result:
--------------
I'd like to have a magic function that, notwithstanding a bit of
processing to get the results into the format I want, gives me a list of
$siglabels without my having to supply them.
--
Edit bug report at https://bugs.php.net/bug.php?id=78548&edit=1
--
Fix committed: https://bugs.php.net/fix.php?id=78548&r=fixed
Fixed in release: https://bugs.php.net/fix.php?id=78548&r=alreadyfixed
Need backtrace: https://bugs.php.net/fix.php?id=78548&r=needtrace
Need Reproduce Script: https://bugs.php.net/fix.php?id=78548&r=needscript
Try newer version: https://bugs.php.net/fix.php?id=78548&r=oldversion
Not developer issue: https://bugs.php.net/fix.php?id=78548&r=support
Expected behavior: https://bugs.php.net/fix.php?id=78548&r=notwrong
Not enough info: https://bugs.php.net/fix.php?id=78548&r=notenoughinfo
Submitted twice: https://bugs.php.net/fix.php?id=78548&r=submittedtwice
register_globals: https://bugs.php.net/fix.php?id=78548&r=globals
PHP version support discontinued: https://bugs.php.net/fix.php?id=78548&r=phptooold
Daylight Savings: https://bugs.php.net/fix.php?id=78548&r=dst
IIS Stability: https://bugs.php.net/fix.php?id=78548&r=isapi
Install GNU Sed: https://bugs.php.net/fix.php?id=78548&r=gnused
Floating point limitations: https://bugs.php.net/fix.php?id=78548&r=float
No Zend Extensions: https://bugs.php.net/fix.php?id=78548&r=nozend
MySQL Configuration Error: https://bugs.php.net/fix.php?id=78548&r=mysqlcfg