Skip to content

PHP: Support proc_open #594

@adamziel

Description

@adamziel

PHPUnit and wp-cli both use proc_open and will only work correctly in WordPress Playground if that function is supported.

Today proc_open does not work becuse internally it calls fork() which is not supported in Emscripten and doesn't seem possible to polyfill.

Therefore, the only way to support proc_open is to shim it using require('child_process').spawn() similarly to how we shim popen():

js_popen_to_file: function(command, mode, exitCodePtr) {

const cp = require('child_process');
let ret;
if (modestr === 'r') {
ret = cp.spawnSync(cmdstr, [], {
shell: true,
stdio: ["inherit", "pipe", "inherit"],
});
HEAPU8[exitCodePtr] = ret.status;
require('fs').writeFileSync(pipeFilePath, ret.stdout, {
encoding: 'utf8',
flag: 'w+',
});
} else if (modestr === 'w') {

proc_open has the following signature in PHP:

proc_open(
    array|string $command,
    array $descriptor_spec,
    array &$pipes,
    ?string $cwd = null,
    ?array $env_vars = null,
    ?array $options = null
): resource|false

Handling $pipes is the most challenging bit here. Emscripten documentation doesn't explain how to create pipes – the easiest way should be reading the code and looking up examples.

If we can find a way to open Emscripten pipes and pass the data from/to the child process, that's great – that would probably involve custom Emscripten streams or devices. Otherwise, we could fake pipes by opening three temporary files in Emscripten (for stdin, stdout, stderr) and creating $pipes using those file descriptor.

cc @wojtekn @sejas @danielbachhuber @schlessera

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions