blob: 337ba7c440833de19c24177db8c66e988bf7bd7e [file] [log] [blame]
Dan Albert58310b42015-03-13 23:06:01 -07001/*
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
Elliott Hughes4f713192015-12-04 22:00:26 -080017#include "android-base/logging.h"
18#include "android-base/test_utils.h"
Spencer Low40d0c7a2015-07-31 20:21:35 -070019#include "utils/Compat.h" // For OS_PATH_SEPARATOR.
Dan Albert58310b42015-03-13 23:06:01 -070020
Dan Albert0c4b3a32015-04-29 11:32:23 -070021#include <fcntl.h>
Dan Albert58310b42015-03-13 23:06:01 -070022#include <stdio.h>
23#include <stdlib.h>
Dan Albert0c4b3a32015-04-29 11:32:23 -070024#include <sys/stat.h>
Dan Albert58310b42015-03-13 23:06:01 -070025#include <unistd.h>
26
Dan Albert0c4b3a32015-04-29 11:32:23 -070027#if defined(_WIN32)
28#include <windows.h>
Spencer Low40d0c7a2015-07-31 20:21:35 -070029#include <direct.h>
Dan Albert0c4b3a32015-04-29 11:32:23 -070030#endif
31
Alex Vallée47d67c92015-05-06 16:26:00 -040032#include <string>
33
Spencer Low40d0c7a2015-07-31 20:21:35 -070034#ifdef _WIN32
35int 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.
Spencer Low2fbeb0c2015-09-01 14:57:58 -070040 // 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);
Spencer Low40d0c7a2015-07-31 20:21:35 -070043}
44
45char* 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
Alex Vallée47d67c92015-05-06 16:26:00 -040056static std::string GetSystemTempDir() {
Dan Albert0c4b3a32015-04-29 11:32:23 -070057#if defined(__ANDROID__)
Alex Vallée47d67c92015-05-06 16:26:00 -040058 return "/data/local/tmp";
Dan Albert0c4b3a32015-04-29 11:32:23 -070059#elif defined(_WIN32)
Spencer Low40d0c7a2015-07-31 20:21:35 -070060 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;
Dan Albert0c4b3a32015-04-29 11:32:23 -070070#else
Alex Vallée47d67c92015-05-06 16:26:00 -040071 return "/tmp";
Dan Albert0c4b3a32015-04-29 11:32:23 -070072#endif
Dan Albert58310b42015-03-13 23:06:01 -070073}
74
Alex Vallée47d67c92015-05-06 16:26:00 -040075TemporaryFile::TemporaryFile() {
76 init(GetSystemTempDir());
77}
78
Dan Albert58310b42015-03-13 23:06:01 -070079TemporaryFile::~TemporaryFile() {
80 close(fd);
Alex Vallée47d67c92015-05-06 16:26:00 -040081 unlink(path);
Dan Albert58310b42015-03-13 23:06:01 -070082}
83
Alex Vallée47d67c92015-05-06 16:26:00 -040084void TemporaryFile::init(const std::string& tmp_dir) {
Spencer Low40d0c7a2015-07-31 20:21:35 -070085 snprintf(path, sizeof(path), "%s%cTemporaryFile-XXXXXX", tmp_dir.c_str(),
86 OS_PATH_SEPARATOR);
Alex Vallée47d67c92015-05-06 16:26:00 -040087 fd = mkstemp(path);
Dan Albert58310b42015-03-13 23:06:01 -070088}
Alex Vallée47d67c92015-05-06 16:26:00 -040089
Alex Vallée47d67c92015-05-06 16:26:00 -040090TemporaryDir::TemporaryDir() {
91 init(GetSystemTempDir());
92}
93
94TemporaryDir::~TemporaryDir() {
95 rmdir(path);
96}
97
98bool TemporaryDir::init(const std::string& tmp_dir) {
Spencer Low40d0c7a2015-07-31 20:21:35 -070099 snprintf(path, sizeof(path), "%s%cTemporaryDir-XXXXXX", tmp_dir.c_str(),
100 OS_PATH_SEPARATOR);
Alex Vallée47d67c92015-05-06 16:26:00 -0400101 return (mkdtemp(path) != nullptr);
102}