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/file-stream-wrapper.h"
18 #include "hphp/runtime/base/unit-cache.h"
19 #include "hphp/runtime/base/runtime-error.h"
20 #include "hphp/runtime/base/plain-file.h"
21 #include "hphp/runtime/base/directory.h"
22 #include "hphp/runtime/server/static-content-cache.h"
23 #include "hphp/runtime/base/file-util.h"
24 #include "hphp/runtime/base/string-util.h"
25 #include "hphp/runtime/ext/stream/ext_stream.h"
27 #include <boost/filesystem/operations.hpp>
31 #include <folly/portability/Stdlib.h>
32 #include <folly/portability/SysStat.h>
35 ///////////////////////////////////////////////////////////////////////////////
37 req::ptr
<MemFile
> FileStreamWrapper::openFromCache(const String
& filename
,
39 if (!StaticContentCache::TheFileCache
) {
44 FileCache::GetRelativePath(File::TranslatePath(filename
).c_str());
45 auto file
= req::make
<MemFile
>();
46 bool ret
= file
->open(relative
, mode
);
54 FileStreamWrapper::open(const String
& filename
, const String
& mode
, int options
,
55 const req::ptr
<StreamContext
>& /*context*/) {
57 if (StringUtil::IsFileUrl(filename
)) {
58 fname
= StringUtil::DecodeFileUrl(filename
);
60 raise_warning("invalid file:// URL");
67 if (auto file
= openFromCache(fname
, mode
)) {
71 if (options
& File::USE_INCLUDE_PATH
) {
73 String resolved_fname
= resolveVmInclude(fname
.get(), "", &s
);
74 if (!resolved_fname
.isNull()) {
75 fname
= resolved_fname
;
79 auto file
= req::make
<PlainFile
>();
80 bool ret
= file
->open(File::TranslatePath(fname
), mode
);
82 raise_warning("%s", file
->getLastError().c_str());
88 req::ptr
<Directory
> FileStreamWrapper::opendir(const String
& path
) {
89 auto tpath
= File::TranslatePath(path
);
90 if (File::IsVirtualDirectory(tpath
)) {
91 return req::make
<CachedDirectory
>(tpath
);
94 auto dir
= req::make
<PlainDirectory
>(tpath
);
95 if (!dir
->isValid()) {
96 raise_warning("%s", dir
->getLastError().c_str());
102 int FileStreamWrapper::unlink(const String
& path
) {
103 int ret
= ::unlink(File::TranslatePath(path
).data());
109 folly::errnoStr(errno
).c_str()
115 int FileStreamWrapper::rename(const String
& oldname
, const String
& newname
) {
117 RuntimeOption::UseDirectCopy
?
118 FileUtil::directRename(File::TranslatePath(oldname
).data(),
119 File::TranslatePath(newname
).data())
121 FileUtil::rename(File::TranslatePath(oldname
).data(),
122 File::TranslatePath(newname
).data());
126 int FileStreamWrapper::mkdir(const String
& path
, int mode
, int options
) {
127 if (options
& k_STREAM_MKDIR_RECURSIVE
) {
128 ERROR_RAISE_WARNING(mkdir_recursive(path
, mode
));
131 ERROR_RAISE_WARNING(::mkdir(File::TranslatePath(path
).data(), mode
));
135 int FileStreamWrapper::mkdir_recursive(const String
& path
, int mode
) {
136 String fullpath
= File::TranslatePath(path
);
137 if (fullpath
.size() > PATH_MAX
) {
138 errno
= ENAMETOOLONG
;
142 // Check first if the whole path exists
143 if (access(fullpath
.data(), F_OK
) >= 0) {
148 char dir
[PATH_MAX
+1];
150 strncpy(dir
, fullpath
.data(), sizeof(dir
));
152 for (p
= dir
+ 1; *p
; p
++) {
153 if (FileUtil::isDirSeparator(*p
)) {
155 if (::access(dir
, F_OK
) < 0) {
156 if (::mkdir(dir
, mode
) < 0) {
160 *p
= FileUtil::getDirSeparator();
164 if (::access(dir
, F_OK
) < 0) {
165 if (::mkdir(dir
, mode
) < 0) {
173 ///////////////////////////////////////////////////////////////////////////////