2 +----------------------------------------------------------------------+
4 +----------------------------------------------------------------------+
5 | Copyright (c) 2010-present Facebook, Inc. (http://www.facebook.com) |
6 +----------------------------------------------------------------------+
7 | This source file is subject to version 3.01 of the PHP license, |
8 | that is bundled with this package in the file LICENSE, and is |
9 | available through the world-wide-web at the following url: |
10 | http://www.php.net/license/3_01.txt |
11 | If you did not receive a copy of the PHP license and are unable to |
12 | obtain it through the world-wide-web, please send a note to |
13 | license@php.net so we can mail you a copy immediately. |
14 +----------------------------------------------------------------------+
17 #include "hphp/runtime/base/php-stream-wrapper.h"
18 #include "hphp/runtime/base/runtime-error.h"
19 #include "hphp/runtime/base/plain-file.h"
20 #include "hphp/runtime/base/temp-file.h"
21 #include "hphp/runtime/base/mem-file.h"
22 #include "hphp/runtime/base/output-file.h"
23 #include "hphp/runtime/server/cli-server.h"
24 #include "hphp/runtime/server/http-protocol.h"
25 #include "hphp/runtime/ext/stream/ext_stream.h"
29 ///////////////////////////////////////////////////////////////////////////////
31 const StaticString
s_php("PHP");
32 const StaticString
s_input("Input");
33 const StaticString
s_temp("TEMP");
34 const StaticString
s_memory("MEMORY");
36 req::ptr
<File
> PhpStreamWrapper::openFD(const char *sFD
) {
38 raise_warning("Direct access to file descriptors is not "
39 "available via remote unix server execution");
42 if (RuntimeOption::ServerExecutionMode()) {
43 raise_warning("Direct access to file descriptors "
44 "is only available from command-line");
49 long nFD
= strtol(sFD
, &end
, 10);
50 if ((sFD
== end
) || (*end
!= '\0')) {
51 raise_warning("php://fd/ stream must be specified in the form "
52 "php://fd/<orig fd>");
55 long dtablesize
= getdtablesize();
56 if ((nFD
< 0) || (nFD
>= dtablesize
)) {
57 raise_warning("The file descriptors must be non-negative numbers "
58 "smaller than %ld", dtablesize
);
62 return req::make
<PlainFile
>(dup(nFD
), true, s_php
);
66 PhpStreamWrapper::open(const String
& filename
, const String
& mode
,
67 int options
, const req::ptr
<StreamContext
>& context
) {
68 if (strncasecmp(filename
.c_str(), "php://", 6)) {
72 const char *req
= filename
.c_str() + sizeof("php://") - 1;
74 auto make_from
= [] (const Variant
& f
) -> req::ptr
<File
> {
75 auto res
= dyn_cast_or_null
<PlainFile
>(f
);
76 if (!res
|| res
->isClosed()) return nullptr;
77 return req::make
<PlainFile
>(dup(res
->fd()), true, s_php
);
80 if (!strcasecmp(req
, "stdin")) {
81 return make_from(BuiltinFiles::getSTDIN());
83 if (!strcasecmp(req
, "stdout")) {
84 return make_from(BuiltinFiles::getSTDOUT());
86 if (!strcasecmp(req
, "stderr")) {
87 return make_from(BuiltinFiles::getSTDERR());
89 if (!strncasecmp(req
, "fd/", sizeof("fd/") - 1)) {
90 return openFD(req
+ sizeof("fd/") - 1);
92 if (!strncasecmp(req
, "temp", sizeof("temp") - 1)) {
93 auto file
= req::make
<TempFile
>(true, s_php
, s_temp
);
95 raise_warning("Unable to create temporary file");
100 if (!strcasecmp(req
, "memory")) {
101 auto file
= req::make
<TempFile
>(true, s_php
, s_memory
);
102 if (!file
->valid()) {
103 raise_warning("Unable to create temporary file");
107 file
->getData()->m_mode
= [mode
] {
111 for (auto c
: mode
.slice()) {
128 if (!strcasecmp(req
, "input")) {
129 auto raw_post
= g_context
->getRawPostData();
130 return req::make
<MemFile
>(
131 raw_post
.c_str(), raw_post
.size(), s_php
, s_input
);
134 if (!strcasecmp(req
, "output")) {
135 return req::make
<OutputFile
>(filename
);
141 ///////////////////////////////////////////////////////////////////////////////