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/temp-file.h"
18 #include "hphp/runtime/base/stat-cache.h"
19 #include "hphp/runtime/base/runtime-error.h"
21 #include "hphp/util/logger.h"
25 ///////////////////////////////////////////////////////////////////////////////
26 // constructor and destructor
28 TempFile::TempFile(bool autoDelete
/* = true */,
29 const String
& wrapper_type
,
30 const String
& stream_type
)
31 : PlainFile(nullptr, false, wrapper_type
, stream_type
),
32 m_autoDelete(autoDelete
) {
35 // open a temporary file
36 snprintf(path
, sizeof(path
), "/tmp/XXXXXX");
37 int fd
= mkstemp(path
);
39 raise_warning("Unable to open temporary file");
43 m_stream
= fdopen(fd
, "r+");
45 m_rawName
= std::string(path
);
48 TempFile::~TempFile() {
52 void TempFile::sweep() {
59 bool TempFile::open(const String
& /*filename*/, const String
& /*mode*/) {
60 raise_fatal_error((std::string("cannot open a temp file ") +
64 bool TempFile::close() {
65 invokeFiltersOnClose();
69 bool TempFile::closeImpl() {
74 s_pcloseRet
= ::fclose(m_stream
);
75 ret
= (s_pcloseRet
== 0);
80 if (!m_rawName
.empty()) {
82 unlink(m_rawName
.c_str());
90 bool TempFile::seek(int64_t offset
, int whence
/* = SEEK_SET */) {
93 if (whence
== SEEK_CUR
) {
94 off_t result
= lseek(getFd(), 0, SEEK_CUR
);
95 if (result
!= (off_t
)-1) {
96 offset
+= result
- (bufferedLen() + getPosition());
98 if (offset
> 0 && offset
< bufferedLen()) {
99 setReadPosition(getReadPosition() + offset
);
100 setPosition(getPosition() + offset
);
103 offset
+= getPosition();
105 } else if (whence
== SEEK_END
) {
106 if (getLength() == -1) {
107 Logger::Verbose("%s/%d: error finding end of file", __FUNCTION__
,
111 offset
+= getLength();
115 if (offset
> getLength() || getLength() == -1) return false;
117 // invalidate the current buffer
120 // clear the eof flag
123 // lseek instead of seek to be consistent with read
124 off_t result
= lseek(getFd(), offset
, whence
);
126 return result
!= (off_t
)-1;
129 int64_t TempFile::tell() {
131 if (getLength() < 0) return -1;
132 return getPosition();
135 bool TempFile::truncate(int64_t size
) {
137 seek(size
, SEEK_SET
);
138 return ftruncate(getFd(), size
) == 0;
141 int64_t TempFile::getLength() {
143 if (StatCache::lstat(File::TranslatePathWithFileCache(m_rawName
).c_str(), &sb
)) {
144 Logger::Verbose("%s/%d: %s", __FUNCTION__
, __LINE__
,
145 folly::errnoStr(errno
).c_str());
146 // use fstat directly
147 if (fstat(getFd(), &sb
) != 0) return -1;
153 ///////////////////////////////////////////////////////////////////////////////