EvalEmitDVArray: varray
[hiphop-php.git] / hphp / runtime / base / php-stream-wrapper.cpp
blobd11db71d35cd9a1a8d62bbf227746fe55d435817
1 /*
2 +----------------------------------------------------------------------+
3 | HipHop for PHP |
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"
26 #include <memory>
28 namespace HPHP {
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) {
37 if (is_cli_mode()) {
38 raise_warning("Direct access to file descriptors is not "
39 "available via remote unix server execution");
40 return nullptr;
42 if (RuntimeOption::ServerExecutionMode()) {
43 raise_warning("Direct access to file descriptors "
44 "is only available from command-line");
45 return nullptr;
48 char *end = nullptr;
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>");
53 return nullptr;
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);
59 return nullptr;
62 return req::make<PlainFile>(dup(nFD), true, s_php);
65 req::ptr<File>
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)) {
69 return nullptr;
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);
94 if (!file->valid()) {
95 raise_warning("Unable to create temporary file");
96 return nullptr;
98 return 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");
104 return nullptr;
107 file->getData()->m_mode = [mode] {
108 if (mode.empty()) {
109 return "w+b";
111 for (auto c : mode.slice()) {
112 switch (c) {
113 case '+':
114 case 'w':
115 case 'a':
116 case 'x':
117 case 'c':
118 return "w+b";
119 default:
120 break;
123 return "rb";
124 }();
125 return file;
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);
138 return nullptr;
141 ///////////////////////////////////////////////////////////////////////////////