@@ -51,7 +51,11 @@ public function testStartWillAssignPipes()
5151
5252 public function testStartWithoutAnyPipesWillNotAssignPipes ()
5353 {
54- $ process = new Process ('exit 0 ' , null , null , array ());
54+ if (DIRECTORY_SEPARATOR === '\\' ) {
55+ $ process = new Process ('cmd /c exit 0 ' , null , null , array ());
56+ } else {
57+ $ process = new Process ('exit 0 ' , null , null , array ());
58+ }
5559 $ process ->start ($ this ->createLoop ());
5660
5761 $ this ->assertNull ($ process ->stdin );
@@ -84,7 +88,7 @@ public function testIsRunning()
8488 {
8589 if (DIRECTORY_SEPARATOR === '\\' ) {
8690 // Windows doesn't have a sleep command and also does not support process pipes
87- $ process = new Process (' php -r ' . escapeshellarg ('sleep(1); ' ), null , null , array ());
91+ $ process = new Process ($ this -> getPhpBinary () . ' -r ' . escapeshellarg ('sleep(1); ' ), null , null , array ());
8892 } else {
8993 $ process = new Process ('sleep 1 ' );
9094 }
@@ -156,7 +160,11 @@ public function testReceivesProcessOutputFromStdoutRedirectedToFile()
156160 {
157161 $ tmp = tmpfile ();
158162
159- $ cmd = 'echo test ' ;
163+ if (DIRECTORY_SEPARATOR === '\\' ) {
164+ $ cmd = 'cmd /c echo test ' ;
165+ } else {
166+ $ cmd = 'echo test ' ;
167+ }
160168
161169 $ loop = $ this ->createLoop ();
162170 $ process = new Process ($ cmd , null , null , array (1 => $ tmp ));
@@ -168,6 +176,27 @@ public function testReceivesProcessOutputFromStdoutRedirectedToFile()
168176 $ this ->assertEquals ('test ' , rtrim (stream_get_contents ($ tmp )));
169177 }
170178
179+ public function testReceivesProcessOutputFromTwoCommandsChainedStdoutRedirectedToFile ()
180+ {
181+ $ tmp = tmpfile ();
182+
183+ if (DIRECTORY_SEPARATOR === '\\' ) {
184+ // omit whitespace before "&&" and quotation marks as Windows will actually echo this otherwise
185+ $ cmd = 'cmd /c echo hello&& cmd /c echo world ' ;
186+ } else {
187+ $ cmd = 'echo "hello" && echo "world" ' ;
188+ }
189+
190+ $ loop = $ this ->createLoop ();
191+ $ process = new Process ($ cmd , null , null , array (1 => $ tmp ));
192+ $ process ->start ($ loop );
193+
194+ $ loop ->run ();
195+
196+ rewind ($ tmp );
197+ $ this ->assertEquals ("hello \nworld " , str_replace ("\r\n" , "\n" , rtrim (stream_get_contents ($ tmp ))));
198+ }
199+
171200 public function testReceivesProcessOutputFromStdoutAttachedToSocket ()
172201 {
173202 if (DIRECTORY_SEPARATOR === '\\' ) {
@@ -199,9 +228,14 @@ public function testReceivesProcessOutputFromStdoutRedirectedToSocketProcess()
199228 // create TCP/IP server on random port and wait for client connection
200229 $ server = stream_socket_server ('tcp://127.0.0.1:0 ' );
201230
202- $ cmd = 'echo test ' ;
231+ if (DIRECTORY_SEPARATOR === '\\' ) {
232+ $ cmd = 'cmd /c echo test ' ;
233+ } else {
234+ $ cmd = 'exec echo test ' ;
235+ }
236+
203237 $ code = '$s=stream_socket_client($argv[1]);do{$d=fread(STDIN,8192);fwrite($s,$d);}while(!feof(STDIN));fclose($s); ' ;
204- $ cmd .= ' | php -r ' . escapeshellarg ($ code ) . ' ' . escapeshellarg (stream_socket_get_name ($ server , false ));
238+ $ cmd .= ' | ' . $ this -> getPhpBinary () . ' -r ' . escapeshellarg ($ code ) . ' ' . escapeshellarg (stream_socket_get_name ($ server , false ));
205239
206240 $ loop = $ this ->createLoop ();
207241
@@ -505,7 +539,13 @@ public function testDetectsClosingProcessEvenWhenAllStdioPipesHaveBeenClosed()
505539 public function testDetectsClosingProcessEvenWhenStartedWithoutPipes ()
506540 {
507541 $ loop = $ this ->createLoop ();
508- $ process = new Process ('exit 0 ' , null , null , array ());
542+
543+ if (DIRECTORY_SEPARATOR === '\\' ) {
544+ $ process = new Process ('cmd /c exit 0 ' , null , null , array ());
545+ } else {
546+ $ process = new Process ('exit 0 ' , null , null , array ());
547+ }
548+
509549 $ process ->start ($ loop , 0.001 );
510550
511551 $ time = microtime (true );
@@ -548,10 +588,11 @@ public function testStartAlreadyRunningProcess()
548588 {
549589 if (DIRECTORY_SEPARATOR === '\\' ) {
550590 // Windows doesn't have a sleep command and also does not support process pipes
551- $ process = new Process (' php -r ' . escapeshellarg ('sleep(1); ' ), null , null , array ());
591+ $ process = new Process ($ this -> getPhpBinary () . ' -r ' . escapeshellarg ('sleep(1); ' ), null , null , array ());
552592 } else {
553593 $ process = new Process ('sleep 1 ' );
554594 }
595+ //var_dump($process);
555596
556597 $ process ->start ($ this ->createLoop ());
557598 $ process ->start ($ this ->createLoop ());
@@ -561,7 +602,7 @@ public function testTerminateProcesWithoutStartingReturnsFalse()
561602 {
562603 if (DIRECTORY_SEPARATOR === '\\' ) {
563604 // Windows doesn't have a sleep command and also does not support process pipes
564- $ process = new Process (' php -r ' . escapeshellarg ('sleep(1); ' ), null , null , array ());
605+ $ process = new Process ($ this -> getPhpBinary () . ' -r ' . escapeshellarg ('sleep(1); ' ), null , null , array ());
565606 } else {
566607 $ process = new Process ('sleep 1 ' );
567608 }
@@ -573,7 +614,7 @@ public function testTerminateWillExit()
573614 {
574615 if (DIRECTORY_SEPARATOR === '\\' ) {
575616 // Windows doesn't have a sleep command and also does not support process pipes
576- $ process = new Process (' php -r ' . escapeshellarg ('sleep(10); ' ), null , null , array ());
617+ $ process = new Process ($ this -> getPhpBinary () . ' -r ' . escapeshellarg ('sleep(10); ' ), null , null , array ());
577618 } else {
578619 $ process = new Process ('sleep 10 ' );
579620 }
@@ -771,6 +812,11 @@ public function assertSoon(\Closure $callback, $timeout = 20000, $interval = 200
771812 }
772813 }
773814
815+ /**
816+ * Returns the path to the PHP binary. This is already escapescaped via `escapeshellarg()`.
817+ *
818+ * @return string
819+ */
774820 private function getPhpBinary ()
775821 {
776822 $ runtime = new Runtime ();
0 commit comments