diff options
| author | nsfisis <nsfisis@gmail.com> | 2026-06-24 03:09:17 +0900 |
|---|---|---|
| committer | nsfisis <nsfisis@gmail.com> | 2026-06-24 03:09:17 +0900 |
| commit | c5fc34a106a706ac12925c4df273a926811d260b (patch) | |
| tree | 24e798c4a00b32aa1a1f155b705d02fba9895875 /crates/shirabe-external-packages/src/symfony/console | |
| parent | b2b321a26f6a628ee8e6757eb8577613e2024e70 (diff) | |
| download | php-shirabe-c5fc34a106a706ac12925c4df273a926811d260b.tar.gz php-shirabe-c5fc34a106a706ac12925c4df273a926811d260b.tar.zst php-shirabe-c5fc34a106a706ac12925c4df273a926811d260b.zip | |
feat(process): redesign proc_* on PhpResource process handles
proc_open/proc_close/proc_get_status/proc_terminate represented the
process handle as a PhpMixed, which cannot hold a live child process or
its pipes, so they were stubs or todo!(). Model the handle as a new
PhpResource::Process variant and child pipes as a StreamBacking::Pipe,
with a native Descriptor enum for descriptorspec; proc_open now returns
io::Result and fills pipes as IndexMap<i64, PhpResource>.
Rewire the Symfony Process pipes and the Console terminal/cursor onto
the new types, removing the "PhpMixed cannot carry a PhpResource"
todo!()s. The remaining todo!()s are genuine syscall leaves
(proc_terminate signal delivery, stream_select, stream_set_blocking,
posix_kill, pty, fd>=3) left unimplemented since no syscall crate is
introduced.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Diffstat (limited to 'crates/shirabe-external-packages/src/symfony/console')
3 files changed, 49 insertions, 60 deletions
diff --git a/crates/shirabe-external-packages/src/symfony/console/cursor.rs b/crates/shirabe-external-packages/src/symfony/console/cursor.rs index 811553f..c36f9b5 100644 --- a/crates/shirabe-external-packages/src/symfony/console/cursor.rs +++ b/crates/shirabe-external-packages/src/symfony/console/cursor.rs @@ -181,31 +181,20 @@ impl Cursor { let is_tty_supported = if shirabe_php_shim::function_exists("proc_open") { *IS_TTY_SUPPORTED.get_or_init(|| { - let mut pipes = shirabe_php_shim::PhpMixed::Null; - shirabe_php_shim::php_truthy(&shirabe_php_shim::proc_open( + let mut pipes = indexmap::IndexMap::new(); + shirabe_php_shim::proc_open( "echo 1 >/dev/null", - &vec![ - shirabe_php_shim::PhpMixed::List(vec![ - shirabe_php_shim::PhpMixed::String("file".to_string()), - shirabe_php_shim::PhpMixed::String("/dev/tty".to_string()), - shirabe_php_shim::PhpMixed::String("r".to_string()), - ]), - shirabe_php_shim::PhpMixed::List(vec![ - shirabe_php_shim::PhpMixed::String("file".to_string()), - shirabe_php_shim::PhpMixed::String("/dev/tty".to_string()), - shirabe_php_shim::PhpMixed::String("w".to_string()), - ]), - shirabe_php_shim::PhpMixed::List(vec![ - shirabe_php_shim::PhpMixed::String("file".to_string()), - shirabe_php_shim::PhpMixed::String("/dev/tty".to_string()), - shirabe_php_shim::PhpMixed::String("w".to_string()), - ]), + &[ + shirabe_php_shim::Descriptor::File("/dev/tty".to_string(), "r".to_string()), + shirabe_php_shim::Descriptor::File("/dev/tty".to_string(), "w".to_string()), + shirabe_php_shim::Descriptor::File("/dev/tty".to_string(), "w".to_string()), ], &mut pipes, None, None, None, - )) + ) + .is_ok() }) } else { false diff --git a/crates/shirabe-external-packages/src/symfony/console/helper/question_helper.rs b/crates/shirabe-external-packages/src/symfony/console/helper/question_helper.rs index 1fc90bd..2bdd929 100644 --- a/crates/shirabe-external-packages/src/symfony/console/helper/question_helper.rs +++ b/crates/shirabe-external-packages/src/symfony/console/helper/question_helper.rs @@ -377,13 +377,14 @@ impl QuestionHelper { // Read a keypress while !shirabe_php_shim::feof(input_stream) { while is_stdin - && 0 == shirabe_php_shim::stream_select( - &mut r, - &mut w.clone(), - &mut w.clone(), - 0, - Some(100), - ) + && Some(0) + == shirabe_php_shim::stream_select( + &mut r, + &mut w.clone(), + &mut w.clone(), + 0, + Some(100), + ) { // Give signal handlers a chance to run r = vec![input_stream.clone()]; diff --git a/crates/shirabe-external-packages/src/symfony/console/terminal.rs b/crates/shirabe-external-packages/src/symfony/console/terminal.rs index ac4009e..c02b87f 100644 --- a/crates/shirabe-external-packages/src/symfony/console/terminal.rs +++ b/crates/shirabe-external-packages/src/symfony/console/terminal.rs @@ -208,49 +208,48 @@ impl Terminal { return None; } - let descriptorspec: Vec<PhpMixed> = vec![ - PhpMixed::List(vec![ - PhpMixed::String("pipe".to_string()), - PhpMixed::String("w".to_string()), - ]), - PhpMixed::List(vec![ - PhpMixed::String("pipe".to_string()), - PhpMixed::String("w".to_string()), - ]), + // Sparse PHP descriptorspec `[1 => ['pipe', 'w'], 2 => ['pipe', 'w']]`: fd 0 is inherited. + let descriptorspec = [ + shirabe_php_shim::Descriptor::Inherit, + shirabe_php_shim::Descriptor::Pipe("w".to_string()), + shirabe_php_shim::Descriptor::Pipe("w".to_string()), ]; - let _cp = if shirabe_php_shim::function_exists("sapi_windows_cp_set") { + let cp = if shirabe_php_shim::function_exists("sapi_windows_cp_set") { shirabe_php_shim::sapi_windows_cp_get(None) } else { 0 }; - let mut pipes = PhpMixed::Null; - let process = - shirabe_php_shim::proc_open(command, &descriptorspec, &mut pipes, None, None, None); - if !shirabe_php_shim::php_truthy(&process) { - return None; + let mut pipes: indexmap::IndexMap<i64, shirabe_php_shim::PhpResource> = + indexmap::IndexMap::new(); + let process = match shirabe_php_shim::proc_open( + command, + &descriptorspec, + &mut pipes, + None, + None, + None, + ) { + Ok(process) => process, + Err(_) => return None, + }; + + let info = pipes + .get(&1) + .and_then(shirabe_php_shim::stream_get_contents); + if let Some(pipe) = pipes.get(&1) { + shirabe_php_shim::fclose(pipe); } + if let Some(pipe) = pipes.get(&2) { + shirabe_php_shim::fclose(pipe); + } + shirabe_php_shim::proc_close(&process); - // $pipes[1] and $pipes[2] from proc_open's output array. - let _pipe1 = php_pipe(&pipes, 1); - let _pipe2 = php_pipe(&pipes, 2); - // TODO(phase-d): the pipe contents are read via stream_get_contents() and the pipes are - // fclose()d, but they are PHP stream resources the PhpMixed pipe list cannot hold. - todo!( - "Terminal: reading proc_open pipes needs PhpResource handles the PhpMixed pipe list cannot carry" - ); - } -} + if cp != 0 { + shirabe_php_shim::sapi_windows_cp_set(cp); + } -/// Indexes into the `$pipes` array populated by proc_open. -fn php_pipe(pipes: &PhpMixed, index: i64) -> PhpMixed { - match pipes { - PhpMixed::List(list) => list.get(index as usize).cloned().unwrap_or(PhpMixed::Null), - PhpMixed::Array(array) => array - .get(&index.to_string()) - .map(|v| v.clone()) - .unwrap_or(PhpMixed::Null), - _ => PhpMixed::Null, + info } } |
