2 * Copyright 2015 Facebook, Inc.
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
17 #include <folly/experimental/TestUtil.h>
19 #include <sys/types.h>
23 #include <boost/regex.hpp>
24 #include <folly/Conv.h>
25 #include <folly/Exception.h>
32 fs::path generateUniquePath(fs::path path, StringPiece namePrefix) {
34 path = fs::temp_directory_path();
36 if (namePrefix.empty()) {
37 path /= fs::unique_path();
39 path /= fs::unique_path(
40 to<std::string>(namePrefix, ".%%%%-%%%%-%%%%-%%%%"));
47 TemporaryFile::TemporaryFile(StringPiece namePrefix,
50 bool closeOnDestruction)
52 closeOnDestruction_(closeOnDestruction),
54 path_(generateUniquePath(std::move(dir), namePrefix)) {
55 fd_ = open(path_.c_str(), O_RDWR | O_CREAT | O_EXCL, 0666);
56 checkUnixError(fd_, "open failed");
58 if (scope_ == Scope::UNLINK_IMMEDIATELY) {
59 boost::system::error_code ec;
60 fs::remove(path_, ec);
62 LOG(WARNING) << "unlink on construction failed: " << ec;
69 const fs::path& TemporaryFile::path() const {
70 CHECK(scope_ != Scope::UNLINK_IMMEDIATELY);
71 DCHECK(!path_.empty());
75 TemporaryFile::~TemporaryFile() {
76 if (fd_ != -1 && closeOnDestruction_) {
77 if (close(fd_) == -1) {
78 PLOG(ERROR) << "close failed";
82 // If we previously failed to unlink() (UNLINK_IMMEDIATELY), we'll
84 if (scope_ != Scope::PERMANENT && !path_.empty()) {
85 boost::system::error_code ec;
86 fs::remove(path_, ec);
88 LOG(WARNING) << "unlink on destruction failed: " << ec;
93 TemporaryDirectory::TemporaryDirectory(StringPiece namePrefix,
97 path_(generateUniquePath(std::move(dir), namePrefix)) {
98 fs::create_directory(path_);
101 TemporaryDirectory::~TemporaryDirectory() {
102 if (scope_ == Scope::DELETE_ON_DESTRUCTION) {
103 boost::system::error_code ec;
104 fs::remove_all(path_, ec);
106 LOG(WARNING) << "recursive delete on destruction failed: " << ec;
111 ChangeToTempDir::ChangeToTempDir() : initialPath_(fs::current_path()) {
112 std::string p = dir_.path().native();
116 ChangeToTempDir::~ChangeToTempDir() {
117 std::string p = initialPath_.native();
123 bool hasPCREPatternMatch(StringPiece pattern, StringPiece target) {
124 return boost::regex_match(
127 boost::regex(pattern.begin(), pattern.end())
131 bool hasNoPCREPatternMatch(StringPiece pattern, StringPiece target) {
132 return !hasPCREPatternMatch(pattern, target);
135 } // namespace detail