summaryrefslogtreecommitdiff
path: root/ext/standard/php_fopen_wrapper.c
diff options
context:
space:
mode:
Diffstat (limited to 'ext/standard/php_fopen_wrapper.c')
-rw-r--r--ext/standard/php_fopen_wrapper.c33
1 files changed, 33 insertions, 0 deletions
diff --git a/ext/standard/php_fopen_wrapper.c b/ext/standard/php_fopen_wrapper.c
index 8340da42a8..2a7a2793c7 100644
--- a/ext/standard/php_fopen_wrapper.c
+++ b/ext/standard/php_fopen_wrapper.c
@@ -257,6 +257,39 @@ php_stream * php_stream_url_wrap_php(php_stream_wrapper *wrapper, char *path, ch
} else {
fd = dup(STDERR_FILENO);
}
+ } else if (!strncasecmp(path, "fd/", 3)) {
+ char *start,
+ *end;
+ long fildes_ori;
+ int dtablesize;
+
+ start = &path[3];
+ fildes_ori = strtol(start, &end, 10);
+ if (end == start || (*end != '\0' && *end != '/')) {
+ php_stream_wrapper_log_error(wrapper, options TSRMLS_CC,
+ "php://fd/ stream must be specified in the form php://fd/<orig fd>");
+ return NULL;
+ }
+
+#if HAVE_UNISTD_H
+ dtablesize = getdtablesize();
+#else
+ dtablesize = INT_MAX;
+#endif
+
+ if (fildes_ori < 0 || fildes_ori >= dtablesize) {
+ php_stream_wrapper_log_error(wrapper, options TSRMLS_CC,
+ "The file descriptors must be non-negative numbers smaller than %d", dtablesize);
+ return NULL;
+ }
+
+ fd = dup(fildes_ori);
+ if (fd == -1) {
+ php_stream_wrapper_log_error(wrapper, options TSRMLS_CC,
+ "Error duping file descriptor %d; possibly it doesn't exist: "
+ "[%d]: %s", fildes_ori, errno, strerror(errno));
+ return NULL;
+ }
} else if (!strncasecmp(path, "filter/", 7)) {
/* Save time/memory when chain isn't specified */
if (strchr(mode, 'r') || strchr(mode, '+')) {