1--TEST-- 2pcntl: pcntl_sigprocmask(), pcntl_sigwaitinfo(), pcntl_sigtimedwait() 3--SKIPIF-- 4<?php 5 if (!extension_loaded('pcntl')) die('skip pcntl extension not available'); 6 elseif (!extension_loaded('posix')) die('skip posix extension not available'); 7 elseif (!function_exists('pcntl_sigwaitinfo') or !function_exists('pcntl_sigtimedwait')) die('skip required functionality is not available'); 8 elseif (!defined('CLD_EXITED')) die('skip CLD_EXITED not defined'); 9 elseif (getenv('SKIP_ASAN')) die('skip Fails intermittently under asan/msan'); 10?> 11--FILE-- 12<?php 13 14$pid = pcntl_fork(); 15if ($pid == -1) { 16 die('failed'); 17} else if ($pid) { 18 pcntl_sigprocmask(SIG_BLOCK, array(SIGCHLD,(string)SIGTERM)); 19 $oldset = array(); 20 pcntl_sigprocmask(SIG_BLOCK, array(), $oldset); 21 var_dump(in_array(SIGCHLD, $oldset)); 22 var_dump(in_array(SIGTERM, $oldset)); 23 24 posix_kill(posix_getpid(), SIGTERM); 25 $signo = pcntl_sigwaitinfo(array(SIGTERM), $siginfo); 26 echo "signo == SIGTERM\n"; 27 var_dump($signo === SIGTERM && $signo === $siginfo['signo']); 28 echo "code === SI_USER || SI_NOINFO\n"; 29 if (defined('SI_NOINFO')) { 30 var_dump(($siginfo['code'] === SI_USER) || ($siginfo['code'] === SI_NOINFO)); 31 } else { 32 var_dump($siginfo['code'] === SI_USER); 33 } 34 35 pcntl_signal(SIGCHLD, function($signo){}); 36 posix_kill($pid, SIGTERM); 37 $signo = pcntl_sigwaitinfo(array((string)SIGCHLD), $siginfo); 38 echo "signo == SIGCHLD\n"; 39 var_dump($signo === SIGCHLD && $signo === $siginfo['signo']); 40 echo "code === CLD_KILLED\n"; 41 var_dump($siginfo['code'] === CLD_KILLED); 42 echo "signo === SIGCHLD\n"; 43 var_dump($siginfo['signo'] === SIGCHLD); 44 echo "signo === uid\n"; 45 var_dump($siginfo['uid'] === posix_getuid()); 46 echo "signo === pid\n"; 47 var_dump($siginfo['pid'] === $pid); 48 pcntl_waitpid($pid, $status); 49 50 set_error_handler(function($errno, $errstr) { echo "Error triggered\n"; }, E_WARNING); 51 52 echo "sigprocmask with invalid arguments\n"; 53 54 /* Valgrind expectedly complains about this: 55 * "sigprocmask: unknown 'how' field 2147483647" 56 * Skip */ 57 if (getenv("USE_ZEND_ALLOC") !== '0') { 58 var_dump(pcntl_sigprocmask(PHP_INT_MAX, array(SIGTERM))); 59 } else { 60 echo "Error triggered\n"; 61 echo "bool(false)\n"; 62 } 63 var_dump(pcntl_sigprocmask(SIG_SETMASK, array(0))); 64 65 echo "sigwaitinfo with invalid arguments\n"; 66 var_dump(pcntl_sigwaitinfo(array(0))); 67 68 echo "sigtimedwait with invalid arguments\n"; 69 var_dump(pcntl_sigtimedwait(array(SIGTERM), $signo, PHP_INT_MAX, PHP_INT_MAX)); 70} else { 71 $siginfo = NULL; 72 pcntl_sigtimedwait(array(SIGINT), $siginfo, 3600, 0); 73 exit; 74} 75 76?> 77--EXPECT-- 78bool(true) 79bool(true) 80signo == SIGTERM 81bool(true) 82code === SI_USER || SI_NOINFO 83bool(true) 84signo == SIGCHLD 85bool(true) 86code === CLD_KILLED 87bool(true) 88signo === SIGCHLD 89bool(true) 90signo === uid 91bool(true) 92signo === pid 93bool(true) 94sigprocmask with invalid arguments 95Error triggered 96bool(false) 97Error triggered 98bool(false) 99sigwaitinfo with invalid arguments 100Error triggered 101bool(false) 102sigtimedwait with invalid arguments 103Error triggered 104int(-1) 105