Martin Wickman
Martin Wickman

Reputation: 19925

Why can't I write to /dev/stdout, but php://stdout works?

I'm trying to write to stdout (or stderr) using PHP with Apache (running in the foreground in Docker).

These works:

file_put_contents( "php://stderr","works" );
file_put_contents( "php://stdout","works" );

$fh = fopen('php://stdout','w'); fwrite($fh, "works");

But these do not:

$stdout = fopen ("/dev/stdout","w"); fwrite($stdout, "fails");
$stderr = fopen ("/dev/stderr","w"); fwrite($stderr, "fails");

echo "fd1 exists:" . (file_exists('/proc/self/fd/1') ? 'yes' : 'no');
echo "fd1 writable:" . (is_writable('/proc/self/fd/1') ? 'yes' : 'no');
echo "stdout exists:" . (file_exists('/dev/stdout') ? 'yes' : 'no');
echo "stdout writable:" . (is_writable('/dev/stdout') ? 'yes' : 'no');

file_put_contents( "/proc/self/fd/1", "fails" );
file_put_contents( "/proc/self/fd/2", "fails" );
file_put_contents( "/dev/stdout", "fails" );

fwrite(STDOUT, 'fails');
fwrite(STDERR, 'fails');

/dev/stdout do exist, but is not writable. also fopen('/dev/stdout') returns FALSE.

fd1 exists:yes
fd1 writable:no
stdout exists:yes
stdout writable:no

More info:

Again, what is php://stdout doing that I don't?

Upvotes: 3

Views: 3974

Answers (1)

Martin Wickman
Martin Wickman

Reputation: 19925

The reason is that Apache forks and changes user to a less privileged one (the "apache" user) which does not have permission to write /dev/stdout. There is no easy way around this, so I ended up with a script.

The script creates a file (pipe) which is connected through a 'cat' process which writes to standard error (as root):

mkfifo -m 600 logpipe
chown apache:apache logpipe
cat <> logpipe 1>&2 &
CAT=$!

# Start apache
/usr/sbin/httpd -D FOREGROUND

# Kill the cat after apache dies
kill $CAT

Now you can set error_log = logpipe in php.ini and all php errors will be sent to stderr.

As for why php://stdout works, my guess is that PHP uses a file handle (to /dev/stdout) which is already opened by Apache.

More details here.

Upvotes: 2

Related Questions