Bug #53465 [PATCH]: Cannot open file descriptor streams
| From: | cataphract@php.net | Date: | Mon, 06 Dec 2010 22:24:07 +0000 |
| Subject: | Bug #53465 [PATCH]: Cannot open file descriptor streams | ||
| References: | 1 | Groups: | php.bugs |
| Request: | Send a blank email to php-bugs+get-156802@lists.php.net to get a copy of this message | ||
Edit report at http://bugs.php.net/bug.php?id=53465&edit=1
ID: 53465
Patch added by: cataphract@php.net
Reported by: dchurch at sciencelogic dot com
Summary: Cannot open file descriptor streams
Status: Open
Type: Bug
Package: Filesystem function related
Operating System: Linux
PHP Version: 5.3.3
Block user comment: N
Private report: N
New Comment:
The following patch has been added/updated:
Patch Name: php_fd_open.diff
Revision: 1291674246
URL:
http://bugs.php.net/patch-display.php?bug=53465&patch=php_fd_open.diff&revision=1291674246
Previous Comments:
------------------------------------------------------------------------
[2010-12-03 18:24:11] dchurch at sciencelogic dot com
Description:
------------
PHP cannot open, read from, or write to arbitrary file descriptors, a
feature that is necessary for communications with certain utilities that
expect input or output on certain file descriptors. When programming in
C, this functionality is provided by fdopen(). A feature request was
filed over seven years ago for PHP to have a similar capability through
the php:// stream wrapper (#26158), but the bug was marked as bogus for
no adequately defined reason.
The alternative to being able to use a fdopen()-like function is to open
the file descriptor as a named file through /dev/fd/ or /proc/self/fd/.
This works in C using fopen("/dev/fd/<descriptor>", "w"), but it does
not work in PHP because PHP incorrectly attempts to dereference the
pseudo-symlink before opening it.
I have a C program and a PHP script that both attempt to do the same
thing: open file descriptor 3 for writing using /dev/fd/3, read until
EOF from standard in and write to the file descriptor. Both should be
run as:
(executable) 3>&1 | cat
Test script:
---------------
PHP script:
<?php
$file = fopen("/dev/fd/3", "w");
if (!$file) exit(1);
$input = stream_get_contents(STDIN);
fwrite($file, $input);
fclose($file);
C program:
#include <stdio.h>
int main() {
char buf[8192];
int count;
FILE *file;
file = fopen("/dev/fd/3", "w");
if (file == NULL) {
perror("Opening /dev/fd/3");
return 1;
}
while ((count = fread(buf, 1, sizeof(buf), stdin)) > 0) {
fwrite(buf, count, 1, file);
if (feof(stdin)) break;
}
return 0;
}
Expected result:
----------------
Input should be mirrored to file descriptor 3; when called using the
command line above, it should be mirrored to standard output.
Actual result:
--------------
I get the following warning:
PHP Warning: fopen(/dev/fd/3): failed to open stream: No such file or
directory in test.php on line 2
An strace of the PHP process shows the incorrect behavior:
lstat("/dev/fd/3", {st_mode=S_IFLNK|0300, st_size=64, ...}) = 0
readlink("/dev/fd/3", "pipe:[637257]", 4096) = 13
lstat("/dev/fd/pipe:[637257]", 0x7fff76ae8140) = -1 ENOENT (No such file
or directory)
lstat("/dev/fd", {st_mode=S_IFLNK|0777, st_size=13, ...}) = 0
readlink("/dev/fd", "/proc/self/fd"..., 4096) = 13
lstat("/proc/self/fd", {st_mode=S_IFDIR|0500, st_size=0, ...}) = 0
lstat("/proc/self", {st_mode=S_IFLNK|0777, st_size=64, ...}) = 0
readlink("/proc/self", "28234"..., 4096) = 5
lstat("/proc/28234", {st_mode=S_IFDIR|0555, st_size=0, ...}) = 0
lstat("/proc", {st_mode=S_IFDIR|0555, st_size=0, ...}) = 0
open("/proc/28234/fd/pipe:[637257]", O_WRONLY|O_CREAT|O_TRUNC, 0666) =
-1 ENOENT (No such file or directory)
------------------------------------------------------------------------
--
Edit this bug report at http://bugs.php.net/bug.php?id=53465&edit=1