• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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
mkstemp(char * template_name)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 
mkdtemp(char * template_name)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 
GetSystemTempDir()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 
TemporaryFile()75 TemporaryFile::TemporaryFile() {
76   init(GetSystemTempDir());
77 }
78 
~TemporaryFile()79 TemporaryFile::~TemporaryFile() {
80   close(fd);
81   unlink(path);
82 }
83 
init(const std::string & tmp_dir)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 
TemporaryDir()90 TemporaryDir::TemporaryDir() {
91   init(GetSystemTempDir());
92 }
93 
~TemporaryDir()94 TemporaryDir::~TemporaryDir() {
95   rmdir(path);
96 }
97 
init(const std::string & tmp_dir)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