diff options
| author | Treehugger Robot <treehugger-gerrit@google.com> | 2018-11-14 15:20:47 +0000 |
|---|---|---|
| committer | Gerrit Code Review <noreply-gerritcodereview@google.com> | 2018-11-14 15:20:47 +0000 |
| commit | e77298ce9fd0fbb6e94108f4c49c11f5efa856e1 (patch) | |
| tree | ca59dca33f1c70001fb7837cb423f0cb306b3c8d /base/file.cpp | |
| parent | af4a0e846e832a2b5729a8439e3671075901308a (diff) | |
| parent | 0790b2465ab8f2f9b0d86869a896d63358b00099 (diff) | |
Merge "base: move TemporaryFile and TemporaryDir to android-base/file.h"
Diffstat (limited to 'base/file.cpp')
| -rw-r--r-- | base/file.cpp | 97 |
1 files changed, 97 insertions, 0 deletions
diff --git a/base/file.cpp b/base/file.cpp index 3834ed42a3..e4407d073e 100644 --- a/base/file.cpp +++ b/base/file.cpp @@ -19,6 +19,8 @@ #include <errno.h> #include <fcntl.h> #include <libgen.h> +#include <stdio.h> +#include <stdlib.h> #include <sys/stat.h> #include <sys/types.h> #include <unistd.h> @@ -37,10 +39,105 @@ #include <mach-o/dyld.h> #endif #if defined(_WIN32) +#include <direct.h> #include <windows.h> #define O_NOFOLLOW 0 +#define OS_PATH_SEPARATOR '\\' +#else +#define OS_PATH_SEPARATOR '/' +#endif + +#ifdef _WIN32 +int mkstemp(char* template_name) { + if (_mktemp(template_name) == nullptr) { + return -1; + } + // Use open() to match the close() that TemporaryFile's destructor does. + // Use O_BINARY to match base file APIs. + return open(template_name, O_CREAT | O_EXCL | O_RDWR | O_BINARY, S_IRUSR | S_IWUSR); +} + +char* mkdtemp(char* template_name) { + if (_mktemp(template_name) == nullptr) { + return nullptr; + } + if (_mkdir(template_name) == -1) { + return nullptr; + } + return template_name; +} #endif +namespace { + +std::string GetSystemTempDir() { +#if defined(__ANDROID__) + const char* tmpdir = "/data/local/tmp"; + if (access(tmpdir, R_OK | W_OK | X_OK) == 0) { + return tmpdir; + } + // Tests running in app context can't access /data/local/tmp, + // so try current directory if /data/local/tmp is not accessible. + return "."; +#elif defined(_WIN32) + char tmp_dir[MAX_PATH]; + DWORD result = GetTempPathA(sizeof(tmp_dir), tmp_dir); + CHECK_NE(result, 0ul) << "GetTempPathA failed, error: " << GetLastError(); + CHECK_LT(result, sizeof(tmp_dir)) << "path truncated to: " << result; + + // GetTempPath() returns a path with a trailing slash, but init() + // does not expect that, so remove it. + CHECK_EQ(tmp_dir[result - 1], '\\'); + tmp_dir[result - 1] = '\0'; + return tmp_dir; +#else + return "/tmp"; +#endif +} + +} // namespace + +TemporaryFile::TemporaryFile() { + init(GetSystemTempDir()); +} + +TemporaryFile::TemporaryFile(const std::string& tmp_dir) { + init(tmp_dir); +} + +TemporaryFile::~TemporaryFile() { + if (fd != -1) { + close(fd); + } + if (remove_file_) { + unlink(path); + } +} + +int TemporaryFile::release() { + int result = fd; + fd = -1; + return result; +} + +void TemporaryFile::init(const std::string& tmp_dir) { + snprintf(path, sizeof(path), "%s%cTemporaryFile-XXXXXX", tmp_dir.c_str(), OS_PATH_SEPARATOR); + fd = mkstemp(path); +} + +TemporaryDir::TemporaryDir() { + init(GetSystemTempDir()); +} + +TemporaryDir::~TemporaryDir() { + rmdir(path); +} + +bool TemporaryDir::init(const std::string& tmp_dir) { + snprintf(path, sizeof(path), "%s%cTemporaryDir-XXXXXX", tmp_dir.c_str(), OS_PATH_SEPARATOR); + return (mkdtemp(path) != nullptr); +} + namespace android { namespace base { |
