// Copyright 2018 The gVisor Authors. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. #ifndef GVISOR_TEST_UTIL_TEMP_PATH_H_ #define GVISOR_TEST_UTIL_TEMP_PATH_H_ #include #include #include #include "absl/strings/str_cat.h" #include "absl/strings/string_view.h" #include "test/util/posix_error.h" namespace gvisor { namespace testing { // Returns an absolute path for a file in `dir` that does not yet exist. // Distinct calls to NewTempAbsPathInDir from the same process, even from // multiple threads, are guaranteed to return different paths. Distinct calls to // NewTempAbsPathInDir from different processes are not synchronized. std::string NewTempAbsPathInDir(absl::string_view const dir); // Like NewTempAbsPathInDir, but the returned path is in the test's temporary // directory, as provided by the testing framework. std::string NewTempAbsPath(); // Like NewTempAbsPathInDir, but the returned path is relative (to the current // working directory). std::string NewTempRelPath(); // Returns the absolute path for the test temp dir. std::string GetAbsoluteTestTmpdir(); // Represents a temporary file or directory. class TempPath { public: // Default creation mode for files. static constexpr mode_t kDefaultFileMode = 0644; // Default creation mode for directories. static constexpr mode_t kDefaultDirMode = 0755; // Creates a temporary file in directory `parent` with mode `mode` and // contents `content`. static PosixErrorOr CreateFileWith(absl::string_view parent, absl::string_view content, mode_t mode); // Creates an empty temporary subdirectory in directory `parent` with mode // `mode`. static PosixErrorOr CreateDirWith(absl::string_view parent, mode_t mode); // Creates a temporary symlink in directory `parent` to destination `dest`. static PosixErrorOr CreateSymlinkTo(absl::string_view parent, std::string const& dest); // Creates an empty temporary file in directory `parent` with mode // kDefaultFileMode. static PosixErrorOr CreateFileIn(absl::string_view parent); // Creates an empty temporary subdirectory in directory `parent` with mode // kDefaultDirMode. static PosixErrorOr CreateDirIn(absl::string_view parent); // Creates an empty temporary file in the test's temporary directory with mode // `mode`. static PosixErrorOr CreateFileMode(mode_t mode); // Creates an empty temporary file in the test's temporary directory with // mode kDefaultFileMode. static PosixErrorOr CreateFile(); // Creates an empty temporary subdirectory in the test's temporary directory // with mode kDefaultDirMode. static PosixErrorOr CreateDir(); // Constructs a TempPath that represents nothing. TempPath() = default; // Constructs a TempPath that represents the given path, which will be deleted // when the TempPath is destroyed. explicit TempPath(std::string path) : path_(std::move(path)) {} // Attempts to delete the represented temporary file or directory (in the // latter case, also attempts to delete its contents). ~TempPath(); // Attempts to delete the represented temporary file or directory, then // transfers ownership of the path represented by orig to this TempPath. TempPath(TempPath&& orig); TempPath& operator=(TempPath&& orig); // Changes the path this TempPath represents. If the TempPath already // represented a path, deletes and returns that path. Otherwise returns the // empty string. std::string reset(std::string newpath); std::string reset() { return reset(""); } // Forgets and returns the path this TempPath represents. The path is not // deleted. std::string release(); // Returns the path this TempPath represents. std::string path() const { return path_; } private: template static PosixErrorOr CreateIn(absl::string_view const parent, F const& f) { std::string path = NewTempAbsPathInDir(parent); RETURN_IF_ERRNO(f(path)); return TempPath(std::move(path)); } std::string path_; }; } // namespace testing } // namespace gvisor #endif // GVISOR_TEST_UTIL_TEMP_PATH_H_