1 /* 2 * Copyright (C) 2015 The Android Open Source Project 3 * 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 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 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. 15 */ 16 17 #include "android-base/logging.h" 18 #include "android-base/test_utils.h" 19 #include "utils/Compat.h" // For OS_PATH_SEPARATOR. 20 21 #include <fcntl.h> 22 #include <stdio.h> 23 #include <stdlib.h> 24 #include <sys/stat.h> 25 #include <unistd.h> 26 27 #if defined(_WIN32) 28 #include <windows.h> 29 #include <direct.h> 30 #endif 31 32 #include <string> 33 34 #ifdef _WIN32 35 int mkstemp(char* template_name) { 36 if (_mktemp(template_name) == nullptr) { 37 return -1; 38 } 39 // Use open() to match the close() that TemporaryFile's destructor does. 40 // Use O_BINARY to match base file APIs. 41 return open(template_name, O_CREAT | O_EXCL | O_RDWR | O_BINARY, 42 S_IRUSR | S_IWUSR); 43 } 44 45 char* mkdtemp(char* template_name) { 46 if (_mktemp(template_name) == nullptr) { 47 return nullptr; 48 } 49 if (_mkdir(template_name) == -1) { 50 return nullptr; 51 } 52 return template_name; 53 } 54 #endif 55 56 static std::string GetSystemTempDir() { 57 #if defined(__ANDROID__) 58 return "/data/local/tmp"; 59 #elif defined(_WIN32) 60 char tmp_dir[MAX_PATH]; 61 DWORD result = GetTempPathA(sizeof(tmp_dir), tmp_dir); 62 CHECK_NE(result, 0ul) << "GetTempPathA failed, error: " << GetLastError(); 63 CHECK_LT(result, sizeof(tmp_dir)) << "path truncated to: " << result; 64 65 // GetTempPath() returns a path with a trailing slash, but init() 66 // does not expect that, so remove it. 67 CHECK_EQ(tmp_dir[result - 1], '\\'); 68 tmp_dir[result - 1] = '\0'; 69 return tmp_dir; 70 #else 71 return "/tmp"; 72 #endif 73 } 74 75 TemporaryFile::TemporaryFile() { 76 init(GetSystemTempDir()); 77 } 78 79 TemporaryFile::~TemporaryFile() { 80 close(fd); 81 unlink(path); 82 } 83 84 void TemporaryFile::init(const std::string& tmp_dir) { 85 snprintf(path, sizeof(path), "%s%cTemporaryFile-XXXXXX", tmp_dir.c_str(), 86 OS_PATH_SEPARATOR); 87 fd = mkstemp(path); 88 } 89 90 TemporaryDir::TemporaryDir() { 91 init(GetSystemTempDir()); 92 } 93 94 TemporaryDir::~TemporaryDir() { 95 rmdir(path); 96 } 97 98 bool TemporaryDir::init(const std::string& tmp_dir) { 99 snprintf(path, sizeof(path), "%s%cTemporaryDir-XXXXXX", tmp_dir.c_str(), 100 OS_PATH_SEPARATOR); 101 return (mkdtemp(path) != nullptr); 102 } 103