@@ -34,6 +34,7 @@ class QuestionHelper extends Helper
34
34
private $ inputStream ;
35
35
private static $ shell ;
36
36
private static $ stty = true ;
37
+ private static $ stdinIsInteractive = true ;
37
38
38
39
/**
39
40
* Asks a question to the user.
@@ -417,35 +418,28 @@ private function getHiddenResponse(OutputInterface $output, $inputStream, bool $
417
418
return $ value ;
418
419
}
419
420
420
- if (self :: $ stty && Terminal::hasSttyAvailable ()) {
421
+ if (Terminal::hasSttyAvailable ()) {
421
422
$ sttyMode = shell_exec ('stty -g ' );
422
-
423
423
shell_exec ('stty -echo ' );
424
- $ value = fgets ($ inputStream , 4096 );
425
- shell_exec (sprintf ('stty %s ' , $ sttyMode ));
424
+ } elseif ($ this ->isInteractiveInput ($ inputStream )) {
425
+ throw new RuntimeException ('Unable to hide the response. ' );
426
+ }
426
427
427
- if (false === $ value ) {
428
- throw new MissingInputException ('Aborted. ' );
429
- }
430
- if ($ trimmable ) {
431
- $ value = trim ($ value );
432
- }
433
- $ output ->writeln ('' );
428
+ $ value = fgets ($ inputStream , 4096 );
434
429
435
- return $ value ;
430
+ if (Terminal::hasSttyAvailable ()) {
431
+ shell_exec (sprintf ('stty %s ' , $ sttyMode ));
436
432
}
437
433
438
- if (false !== $ shell = $ this ->getShell ()) {
439
- $ readCmd = 'csh ' === $ shell ? 'set mypassword = $< ' : 'read -r mypassword ' ;
440
- $ command = sprintf ("/usr/bin/env %s -c 'stty -echo; %s; stty echo; echo \$mypassword' 2> /dev/null " , $ shell , $ readCmd );
441
- $ sCommand = shell_exec ($ command );
442
- $ value = $ trimmable ? rtrim ($ sCommand ) : $ sCommand ;
443
- $ output ->writeln ('' );
444
-
445
- return $ value ;
434
+ if (false === $ value ) {
435
+ throw new MissingInputException ('Aborted. ' );
446
436
}
437
+ if ($ trimmable ) {
438
+ $ value = trim ($ value );
439
+ }
440
+ $ output ->writeln ('' );
447
441
448
- throw new RuntimeException ( ' Unable to hide the response. ' ) ;
442
+ return $ value ;
449
443
}
450
444
451
445
/**
@@ -473,56 +467,35 @@ private function validateAttempts(callable $interviewer, OutputInterface $output
473
467
throw $ e ;
474
468
} catch (\Exception $ error ) {
475
469
}
476
-
477
- $ attempts = $ attempts ?? -(int ) $ this ->askForever ();
478
470
}
479
471
480
472
throw $ error ;
481
473
}
482
474
483
- /**
484
- * Returns a valid unix shell.
485
- *
486
- * @return string|bool The valid shell name, false in case no valid shell is found
487
- */
488
- private function getShell ()
475
+ private function isInteractiveInput ($ inputStream ): bool
489
476
{
490
- if (null !== self :: $ shell ) {
491
- return self :: $ shell ;
477
+ if (' php://stdin ' !== ( stream_get_meta_data ( $ inputStream )[ ' uri ' ] ?? null ) ) {
478
+ return false ;
492
479
}
493
480
494
- self ::$ shell = false ;
495
-
496
- if (file_exists ('/usr/bin/env ' )) {
497
- // handle other OSs with bash/zsh/ksh/csh if available to hide the answer
498
- $ test = "/usr/bin/env %s -c 'echo OK' 2> /dev/null " ;
499
- foreach (['bash ' , 'zsh ' , 'ksh ' , 'csh ' ] as $ sh ) {
500
- if ('OK ' === rtrim (shell_exec (sprintf ($ test , $ sh )))) {
501
- self ::$ shell = $ sh ;
502
- break ;
503
- }
504
- }
505
- }
506
-
507
- return self ::$ shell ;
508
- }
509
-
510
- private function askForever (): bool
511
- {
512
- $ inputStream = $ this ->inputStream ?: fopen ('php://stdin ' , 'r ' );
513
-
514
- if ('php://stdin ' !== (stream_get_meta_data ($ inputStream )['url ' ] ?? null )) {
515
- return true ;
481
+ if (null !== self ::$ stdinIsInteractive ) {
482
+ return self ::$ stdinIsInteractive ;
516
483
}
517
484
518
485
if (\function_exists ('stream_isatty ' )) {
519
- return stream_isatty ($ inputStream );
486
+ return self :: $ stdinIsInteractive = stream_isatty (fopen ( ' php://stdin ' , ' r ' ) );
520
487
}
521
488
522
489
if (\function_exists ('posix_isatty ' )) {
523
- return posix_isatty ($ inputStream );
490
+ return self :: $ stdinIsInteractive = posix_isatty (fopen ( ' php://stdin ' , ' r ' ) );
524
491
}
525
492
526
- return true ;
493
+ if (!\function_exists ('exec ' )) {
494
+ return self ::$ stdinIsInteractive = true ;
495
+ }
496
+
497
+ exec ('stty 2> /dev/null ' , $ output , $ status );
498
+
499
+ return self ::$ stdinIsInteractive = 1 !== $ status ;
527
500
}
528
501
}
0 commit comments