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