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