1<?php 2 3function run_server(string $payloadFile): string { 4 $cmd = [getenv("TEST_PHP_EXECUTABLE"), "-n", __DIR__ . "/payload_server.php", $payloadFile]; 5 $descriptorspec = array( 6 0 => STDIN, 7 1 => STDOUT, 8 2 => ['pipe', 'w'], 9 ); 10 $proc = proc_open($cmd, $descriptorspec, $pipes); 11 12 // First, wait for the payload server to declare itself ready. 13 $bound = null; 14 stream_set_blocking($pipes[2], false); 15 for ($i = 0; $i < 60; $i++) { 16 usleep(50000); // 50ms per try 17 $status = proc_get_status($proc); 18 if (empty($status['running'])) { 19 echo "Server is not running\n"; 20 proc_terminate($proc); 21 exit(1); 22 } 23 while (($line = fgets($pipes[2])) !== false) { 24 if (preg_match('/FB payload server listening on (.+)/', $line, $matches)) { 25 $bound = $matches[1]; 26 // Now that we've identified the listen address, close STDERR. 27 // Otherwise the pipe may clog up with unread log messages. 28 fclose($pipes[2]); 29 break 2; 30 } 31 } 32 } 33 34 if ($bound === null) { 35 echo "Server did not output startup message"; 36 proc_terminate($proc); 37 exit(1); 38 } 39 40 // Now wait for a connection to succeed. 41 // note: even when server prints 'FB payload server listening on localhost:12345' 42 // it might not be listening yet...need to wait until fsockopen() call returns 43 $error = "Unable to connect to server\n"; 44 for ($i=0; $i < 60; $i++) { 45 usleep(50000); // 50ms per try 46 $status = proc_get_status($proc); 47 $fp = fsockopen("tcp://$bound"); 48 // Failure, the server is no longer running 49 if (!($status && $status['running'])) { 50 $error = "Server is not running\n"; 51 break; 52 } 53 // Success, Connected to servers 54 if ($fp) { 55 $error = ''; 56 break; 57 } 58 } 59 60 if ($fp) { 61 fclose($fp); 62 } 63 64 if ($error) { 65 echo $error; 66 proc_terminate($proc); 67 exit(1); 68 } 69 70 register_shutdown_function( 71 function($proc) { 72 proc_terminate($proc); 73 /* Wait for server to shutdown */ 74 for ($i = 0; $i < 60; $i++) { 75 $status = proc_get_status($proc); 76 if (!($status && $status['running'])) { 77 break; 78 } 79 usleep(50000); 80 } 81 }, 82 $proc 83 ); 84 85 return $bound; 86} 87