Bug #55614 [Fbk->Asn]: pcntl_signal() + fgetc() is not allowing me to break with CTRL+C

From: Date: Thu, 08 Jul 2021 06:21:26 +0000
Subject: Bug #55614 [Fbk->Asn]: pcntl_signal() + fgetc() is not allowing me to break with CTRL+C
References: 1  Groups: php.bugs 
Request: Send a blank email to php-bugs+get-234892@lists.php.net to get a copy of this message
Edit report at https://bugs.php.net/bug.php?id=55614&edit=1 ID: 55614 User updated by: i3367890 at gmail dot com Reported by: i3367890 at gmail dot com Summary: pcntl_signal() + fgetc() is not allowing me to break with CTRL+C -Status: Feedback +Status: Assigned Type: Bug Package: PCNTL related -Operating System: (Arch) Linux +Operating System: (Arch, Debian) Linux -PHP Version: 5.3.8 +PHP Version: 5.3.8 - 8.0.7 Assigned To: cmb Block user comment: N Private report: N New Comment: Wow, I completely forgot about posting this. Thanks for following up. Unfortunately it does still seem to be hanging around. $ php --version PHP 8.0.7 (cli) (built: Jun 4 2021 23:17:30) ( NTS ) Copyright (c) The PHP Group Zend Engine v4.0.7, Copyright (c) Zend Technologies with Zend OPcache v8.0.7, Copyright (c), by Zend Technologies (This is from deb.sury.org. I'm on Debian now.) $ php -r "declare(ticks = 1); function quit() { print \"X\\n\"; die; } pcntl_signal(SIGINT, \"quit\"); fgetc(STDIN);" ^C^C^C^C^C^C^\Quit $ _ Continuous ^C^C^C still simply retries forever: PHP tty | strace tty | ... | rt_sigprocmask(SIG_UNBLOCK, [INT], NULL, 8) = 0 | read(0, 0x7fd24947f000, 8192) = ? ERESTARTSYS (To be restarted if SA_RESTART is set) ^C ---------------^ | --- SIGINT {si_signo=SIGINT, si_code=SI_KERNEL} --- | rt_sigreturn({mask=[]}) = 0 | read(0, 0x7fd24947f000, 8192) = ? ERESTARTSYS (To be restarted if SA_RESTART is set) ^C ---------------^ | --- SIGINT {si_signo=SIGINT, si_code=SI_KERNEL} --- | rt_sigreturn({mask=[]}) = 0 | read(0, 0x7fd24947f000, 8192) = ? ERESTARTSYS (To be restarted if SA_RESTART is set) ^C ---------------^ | --- SIGINT {si_signo=SIGINT, si_code=SI_KERNEL} --- | rt_sigreturn({mask=[]}) = 0 | read(0, "x\n", 8192) = 2 'x' + ------------^ <Return> | rt_sigprocmask(SIG_BLOCK, ~[RTMIN RT_1], [], 8) = 0 Exit-> | write(1, "X\n", 2) = 2 | rt_sigprocmask(SIG_BLOCK, ~[RTMIN RT_1], ~[KILL STOP RTMIN RT_1], 8) = 0 | rt_sigprocmask(SIG_SETMASK, ~[KILL STOP RTMIN RT_1], NULL, 8) = 0 | rt_sigprocmask(SIG_SETMASK, [], NULL, 8) = 0 | close(2) = 0 | close(1) = 0 | close(0) = 0 | munmap(..., ...) = 0 | ... (NB, the note about stty cbreak at the end of the 2nd comment is somewhat orthogonal to this bug; inputting any text then pressing Return IMO suffices to demonstrate that normal input is consumed correctly.) Setting restart_signals to false still consumes one ^C before responding correctly to the second: $ strace -o /dev/pts/26 php -r "declare(ticks = 1); function quit() { print \"X\\n\"; die; } pcntl_signal(SIGINT, \"quit\", 0); fgetc(STDIN);" ^C^CX PHP tty | strace tty | rt_sigprocmask(SIG_UNBLOCK, [INT], NULL, 8) = 0 | read(0, 0x7f66fb47e000, 8192) = ? ERESTARTSYS (To be restarted if SA_RESTART is set) ^C 1 -------------^ | --- SIGINT {si_signo=SIGINT, si_code=SI_KERNEL} --- | rt_sigreturn({mask=[]}) = -1 EINTR (Interrupted system call) | read(0, 0x7f66fb47e000, 8192) = ? ERESTARTSYS (To be restarted if SA_RESTART is set) ^C 2 -------------^ | --- SIGINT {si_signo=SIGINT, si_code=SI_KERNEL} --- | rt_sigreturn({mask=[]}) = -1 EINTR (Interrupted system call) | rt_sigprocmask(SIG_BLOCK, ~[RTMIN RT_1], [], 8) = 0 Exit-> | write(1, "X\n", 2) = 2 | rt_sigprocmask(SIG_BLOCK, ~[RTMIN RT_1], ~[KILL STOP RTMIN RT_1], 8) = 0 | rt_sigprocmask(SIG_SETMASK, ~[KILL STOP RTMIN RT_1], NULL, 8) = 0 | rt_sigprocmask(SIG_SETMASK, [], NULL, 8) = 0 | close(2) = 0 | close(1) = 0 | close(0) = 0 | munmap(0x7f66f7cb7000, 29808) = 0 | munmap(0x7f66f7cbf000, 16592) = 0 Previous Comments: ------------------------------------------------------------------------ [2021-07-06 16:18:40] cmb@php.net Is this still an issue with any of the actively supported PHP versions[1]? [1] <https://www.php.net/supported-versions.php> ------------------------------------------------------------------------ [2011-09-06 03:24:59] i3367890 at gmail dot com I forgot to mention something! In the first script pressing a key (any key) causes PHP to shut down properly. Here's what it looks like: My console | strace console | (....) | rt_sigprocmask(SIG_SETMASK, [], NULL, 8) = 0 | read(0, 0x8b825f8, 8192) = ? ERESTARTSYS (To be restarted) ^C ---------------^ | --- SIGINT (Interrupt) @ 0 (0) --- I | sigreturn() = ? (mask now []) pressed | read(0, "d", 8192) = 1 "d" -------------^ | rt_sigprocmask(SIG_BLOCK, ~[RTMIN RT_1], [], 8) = 0 ! --> | write(1, "X\n", 2) = 2 | rt_sigprocmask(SIG_BLOCK, ~[RTMIN RT_1], ~[KILL STOP RTMIN RT_1], 8) = 0 | rt_sigprocmask(SIG_SETMASK, ~[KILL STOP RTMIN RT_1], NULL, 8) = 0 | close(2) = 0 My console | strace console | (....) ======= NOTE: ======= If fgetc(STDIN) does not return immediately after a single character - it doesn't on my system, it waits for a newline - you might need to run "stty cbreak". When you're done run "stty -cbreak" if you want to switch whatever cbreak does back off, or just close the terminal. i336 ------------------------------------------------------------------------ [2011-09-06 03:15:08] i3367890 at gmail dot com Description: ------------ Running the following code at the commandline as demonstrated simply does not work for me. It gobbles up all presses of ^C and will not quit (^\ ie CTRL+\ produces SIGQUIT and is useful in this situation): php -r "declare(ticks = 1); function quit() { print \"X\\n\"; die; } pcntl_signal(SIGINT, \"quit\"); fgetc(STDIN);" Running the following, on the other hand, works for me just fine. php -r "declare(ticks = 1); function quit() { print \"X\\n\"; die; } pcntl_signal(SIGINT, \"quit\"); while(1) { sleep(1); };" Pressing ^C shuts the script down nicely. I see no problems with the first code example. It should work, right? Here's what strace is saying: My console | strace console | (....) | rt_sigprocmask(SIG_BLOCK, ~[RTMIN RT_1], [], 8) = 0 | rt_sigprocmask(SIG_SETMASK, [], NULL, 8) = 0 | read(0, 0x943e5f4, 8192) = ? ERESTARTSYS (To be restarted) | --- SIGINT (Interrupt) @ 0 (0) --- | sigreturn() = ? (mask now []) | read(0, 0x943e5f4, 8192) = ? ERESTARTSYS (To be restarted) ^C ---------------^ | --- SIGINT (Interrupt) @ 0 (0) --- | sigreturn() = ? (mask now []) | read(0, 0x943e5f4, 8192) = ? ERESTARTSYS (To be restarted) ^C ---------------^ | --- SIGINT (Interrupt) @ 0 (0) --- | sigreturn() = ? (mask now []) | read(0, (waiting) ---------^ It gets even more interesting. Setting parameter 3 to pcntl_signal, restart_signals, to false makes PHP gobble up one ^C *then* quit: php -r "declare(ticks = 1); function quit() { print \"X\\n\"; die; } pcntl_signal(SIGINT, \"quit\", 0); fgetc(STDIN);" Like so: My console | strace console | (...) | rt_sigprocmask(SIG_BLOCK, ~[RTMIN RT_1], [], 8) = 0 | rt_sigprocmask(SIG_SETMASK, [], NULL, 8) = 0 | rt_sigaction(SIGINT, {0x82d8690, ~[RTMIN RT_1], SA_INTERRUPT}, {SIG_DFL, [], 0}, 8) = 0 | rt_sigprocmask(SIG_BLOCK, ~[RTMIN RT_1], [], 8) = 0 | rt_sigprocmask(SIG_SETMASK, [], NULL, 8) = 0 | read(0, 0x9e985f8, 8192) = ? ERESTARTSYS (To be restarted) ^C --------------^ | --- SIGINT (Interrupt) @ 0 (0) --- | sigreturn() = ? (mask now []) | read(0, 0x9e985f8, 8192) = ? ERESTARTSYS (To be restarted) ^C --------------^ | --- SIGINT (Interrupt) @ 0 (0) --- | sigreturn() = ? (mask now []) | rt_sigprocmask(SIG_BLOCK, ~[RTMIN RT_1], [], 8) = 0 ! --> | write(1, "X\n", 2) = 2 | rt_sigprocmask(SIG_BLOCK, ~[RTMIN RT_1], ~[KILL STOP RTMIN RT_1], 8) = 0 | rt_sigprocmask(SIG_SETMASK, ~[KILL STOP RTMIN RT_1], NULL, 8) = 0 | close(2) = 0 | close(1) = 0 | (...) As you can see from my exclamation, *the custom quit function is WORKING* in the second example, just not straight away. PHP seems to be having indigestion with the restart_syscalls bit...? I wasn't sure what to put in what boxes since there were multiple scripts and backtraces (if you could call them such) so I put them all here. Hope that's okay. i336 ------------------------------------------------------------------------ -- Edit this bug report at https://bugs.php.net/bug.php?id=55614&edit=1

« previous php.bugs (#234892) next »