blob: 5c2fe4f75cccbc2372a37485d98a1a4beab1e7e4 [file] [log] [blame]
Elliott Hughesb4f76162013-09-19 16:27:24 -07001/*
2 * Copyright (C) 2013 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
Christopher Ferriseda26bc2014-06-12 13:16:36 -070017#include <fcntl.h>
Elliott Hughesb4f76162013-09-19 16:27:24 -070018#include <unistd.h>
19
Elliott Hughes31165ed2014-09-23 17:34:29 -070020#include "private/bionic_macros.h"
21
22template <typename T = int (*)(char*)>
Calin Juravlefe317a32014-02-21 15:11:03 +000023class GenericTemporaryFile {
Elliott Hughesb4f76162013-09-19 16:27:24 -070024 public:
Elliott Hughes31165ed2014-09-23 17:34:29 -070025 GenericTemporaryFile(T mk_fn = mkstemp) : mk_fn(mk_fn) {
26 // Since we might be running on the host or the target, and if we're
27 // running on the host we might be running under bionic or glibc,
28 // let's just try both possible temporary directories and take the
29 // first one that works.
30 init("/data/local/tmp");
31 if (fd == -1) {
32 init("/tmp");
Elliott Hughes925753a2013-10-18 13:17:18 -070033 }
Elliott Hughesb4f76162013-09-19 16:27:24 -070034 }
35
Elliott Hughes31165ed2014-09-23 17:34:29 -070036 GenericTemporaryFile(const char* dirpath, T mk_fn = mkstemp) : mk_fn(mk_fn) {
37 init(dirpath);
38 }
39
Calin Juravlefe317a32014-02-21 15:11:03 +000040 ~GenericTemporaryFile() {
Elliott Hughesb4f76162013-09-19 16:27:24 -070041 close(fd);
42 unlink(filename);
43 }
44
Christopher Ferriseda26bc2014-06-12 13:16:36 -070045 void reopen() {
46 close(fd);
47 fd = open(filename, O_RDWR);
48 }
49
Elliott Hughesb4f76162013-09-19 16:27:24 -070050 int fd;
51 char filename[1024];
Elliott Hughes925753a2013-10-18 13:17:18 -070052
53 private:
Elliott Hughes31165ed2014-09-23 17:34:29 -070054 T mk_fn;
55
Elliott Hughes925753a2013-10-18 13:17:18 -070056 void init(const char* tmp_dir) {
57 snprintf(filename, sizeof(filename), "%s/TemporaryFile-XXXXXX", tmp_dir);
Calin Juravled4934a72014-02-24 16:13:50 +000058 fd = mk_fn(filename);
Elliott Hughes925753a2013-10-18 13:17:18 -070059 }
Elliott Hughes31165ed2014-09-23 17:34:29 -070060
61 DISALLOW_COPY_AND_ASSIGN(GenericTemporaryFile);
Elliott Hughesb4f76162013-09-19 16:27:24 -070062};
Calin Juravlefe317a32014-02-21 15:11:03 +000063
Elliott Hughes31165ed2014-09-23 17:34:29 -070064typedef GenericTemporaryFile<> TemporaryFile;
Calin Juravled4934a72014-02-24 16:13:50 +000065
66class TemporaryDir {
67 public:
68 TemporaryDir() {
69 if (!init("/data/local/tmp")) {
70 init("/tmp");
71 }
72 }
73
74 ~TemporaryDir() {
75 rmdir(dirname);
76 }
77
78 char dirname[1024];
79
80 private:
81 bool init(const char* tmp_dir) {
82 snprintf(dirname, sizeof(dirname), "%s/TemporaryDir-XXXXXX", tmp_dir);
83 return (mkdtemp(dirname) != NULL);
84 }
85
Elliott Hughes31165ed2014-09-23 17:34:29 -070086 DISALLOW_COPY_AND_ASSIGN(TemporaryDir);
Calin Juravled4934a72014-02-24 16:13:50 +000087};