1--TEST-- 2sapi_windows_set_ctrl_handler() 3--SKIPIF-- 4<?php 5 6include "skipif.inc"; 7 8if (strtoupper(substr(PHP_OS, 0, 3)) !== 'WIN') 9 die("skip this test is for Windows platforms only"); 10?> 11--FILE-- 12<?php 13 14$is_child = isset($argv[1]); 15 16 17if ($is_child) { 18 function handler($evt) 19 { 20 exit(3); 21 } 22 23 sapi_windows_set_ctrl_handler('handler'); 24 25 while(1) usleep(100); 26} else { 27 $cmd = getenv('TEST_PHP_EXECUTABLE_ESCAPED') . " -n " . $argv[0] . " 1"; 28 $spec = [0 => ["pipe", "r"], 1 => ["pipe", "w"]]; 29 30 $proc = proc_open($cmd, $spec, $pipes, NULL, NULL, ["bypass_shell" => true, "create_process_group" => true]); 31 32 if (!is_resource($proc)) { 33 die("Failed to start child. "); 34 } 35 36 $child_pid = proc_get_status($proc)["pid"]; 37 echo "Started child $child_pid\n"; 38 usleep(300); 39 40 $cmd = "tasklist /FI \"PID eq $child_pid\" /NH"; 41 echo "Running `$cmd` to check the process indeed exists:\n"; 42 echo trim(shell_exec($cmd)) . "\n"; 43 44 $evt = PHP_WINDOWS_EVENT_CTRL_C; 45 echo "Sending ", get_evt_name($evt), " to child $child_pid\n"; 46 $ret = sapi_windows_generate_ctrl_event($evt, $child_pid); 47 48 echo ($ret ? "Successfully" : "Unsuccessfuly"), " sent ", get_evt_name($evt), " to child $child_pid\n"; 49 50 $max = 5000; $total = 0; $step = 100; 51 while(proc_get_status($proc)["running"] && $max > $total) { 52 usleep($step); 53 $total += $step; 54 } 55 56 $status = proc_get_status($proc); 57 if ($status["running"]) { 58 echo "Child $child_pid didn't exit after {$max}us\n"; 59 foreach ($pipes as $pipe) { 60 fclose($pipe); 61 } 62 proc_terminate($proc); 63 } else { 64 echo "Child $child_pid exit with status ", $status["exitcode"], " after {$total}us\n"; 65 } 66} 67 68function get_evt_name(int $evt) : ?string 69{ 70 if (PHP_WINDOWS_EVENT_CTRL_C == $evt) { 71 return "CTRL+C"; 72 } if (PHP_WINDOWS_EVENT_CTRL_BREAK == $evt) { 73 return "CTRL+BREAK"; 74 } 75 76 return NULL; 77} 78 79?> 80--EXPECTF-- 81Started child %d 82Running `tasklist /FI "PID eq %d" /NH` to check the process indeed exists: 83php.exe%w%d%s 84Sending CTRL+C to child %d 85Successfully sent CTRL+C to child %d 86Child %d exit with status 3 after %dus 87