Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I call Linux dup2 from PHP?

Tags:

linux

php

Unfortunately, I've found all the solutions for executing external programs not suitable, so I use my own implementation, which is pcntl_exec after pcntl_fork.

But now I need to redirect stderr/stdout of the executed program into some file. It's obvious, that I should use some sort of dup2 Linux call after pcntl_fork, but the only dup2 I can see in PHP is eio_dup2, which looks like it operates not the regular streams (like stderr/stdout), but some async streams.

How can I call dup2 from PHP or how can I redirect std* without it?

The same question (though, without details) has no answers: How do I invoke a dup2() syscall from PHP ?

like image 881
Dmitry Ginzburg Avatar asked Sep 27 '22 21:09

Dmitry Ginzburg


1 Answers

Here comes a way without the need of dup2. It is based on this answer.

$pid = pcntl_fork();

switch($pid) {

    case 0:
        // Standard streams (stdin, stdout, stderr) are inherited from
        // parent to child process. We need to close and re-open stdout 
        // before calling pcntl_exec()

        // Close STDOUT
        fclose(STDOUT);

        // Open a new file descriptor. It will be stdout since 
        // stdout has been closed before and 1 is the lowest free
        // file descriptor
        $new_stdout = fopen("test.out", "w");

        // Now exec the child. It's output goes to test.out
        pcntl_exec('/bin/ls');

        // If `pcntl_exec()` succeeds we should not enter this line. However,
        // since we have omitted error checking (see below) it is a good idea
        // to keep the break statement
        break; 

    case -1: 
        echo "error:fork()\n";
        exit(1);

    default:
        echo "Started child $pid\n";
}

Error handling has been omitted for brevity. But keep in mind that in system programming should carefully handle any function return value.

like image 144
hek2mgl Avatar answered Sep 30 '22 08:09

hek2mgl