1b4f7616fd618875768b8fffc122b58bdb84a9969Elliott Hughes/*
2b4f7616fd618875768b8fffc122b58bdb84a9969Elliott Hughes * Copyright (C) 2013 The Android Open Source Project
3b4f7616fd618875768b8fffc122b58bdb84a9969Elliott Hughes *
4b4f7616fd618875768b8fffc122b58bdb84a9969Elliott Hughes * Licensed under the Apache License, Version 2.0 (the "License");
5b4f7616fd618875768b8fffc122b58bdb84a9969Elliott Hughes * you may not use this file except in compliance with the License.
6b4f7616fd618875768b8fffc122b58bdb84a9969Elliott Hughes * You may obtain a copy of the License at
7b4f7616fd618875768b8fffc122b58bdb84a9969Elliott Hughes *
8b4f7616fd618875768b8fffc122b58bdb84a9969Elliott Hughes *      http://www.apache.org/licenses/LICENSE-2.0
9b4f7616fd618875768b8fffc122b58bdb84a9969Elliott Hughes *
10b4f7616fd618875768b8fffc122b58bdb84a9969Elliott Hughes * Unless required by applicable law or agreed to in writing, software
11b4f7616fd618875768b8fffc122b58bdb84a9969Elliott Hughes * distributed under the License is distributed on an "AS IS" BASIS,
12b4f7616fd618875768b8fffc122b58bdb84a9969Elliott Hughes * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13b4f7616fd618875768b8fffc122b58bdb84a9969Elliott Hughes * See the License for the specific language governing permissions and
14b4f7616fd618875768b8fffc122b58bdb84a9969Elliott Hughes * limitations under the License.
15b4f7616fd618875768b8fffc122b58bdb84a9969Elliott Hughes */
16b4f7616fd618875768b8fffc122b58bdb84a9969Elliott Hughes
17eda26bc1ffc60dc722a375095b9de4fd86959a1dChristopher Ferris#include <fcntl.h>
18b4f7616fd618875768b8fffc122b58bdb84a9969Elliott Hughes#include <unistd.h>
19b4f7616fd618875768b8fffc122b58bdb84a9969Elliott Hughes
20d4934a70e69365c97b1378820152e134a0089b5eCalin Juravletemplate<int (*mk_fn)(char*)>
21fe317a3775e16d466bb884a8e054fd77f7087bb3Calin Juravleclass GenericTemporaryFile {
22b4f7616fd618875768b8fffc122b58bdb84a9969Elliott Hughes public:
23d4934a70e69365c97b1378820152e134a0089b5eCalin Juravle  GenericTemporaryFile(const char* dirpath = NULL) {
24d4934a70e69365c97b1378820152e134a0089b5eCalin Juravle    if (dirpath != NULL) {
25d4934a70e69365c97b1378820152e134a0089b5eCalin Juravle      init(dirpath);
26d4934a70e69365c97b1378820152e134a0089b5eCalin Juravle    } else {
27d4934a70e69365c97b1378820152e134a0089b5eCalin Juravle      // Since we might be running on the host or the target, and if we're
28d4934a70e69365c97b1378820152e134a0089b5eCalin Juravle      // running on the host we might be running under bionic or glibc,
29d4934a70e69365c97b1378820152e134a0089b5eCalin Juravle      // let's just try both possible temporary directories and take the
30d4934a70e69365c97b1378820152e134a0089b5eCalin Juravle      // first one that works.
31d4934a70e69365c97b1378820152e134a0089b5eCalin Juravle      init("/data/local/tmp");
32d4934a70e69365c97b1378820152e134a0089b5eCalin Juravle      if (fd == -1) {
33d4934a70e69365c97b1378820152e134a0089b5eCalin Juravle        init("/tmp");
34d4934a70e69365c97b1378820152e134a0089b5eCalin Juravle      }
35925753aa1175ae58b24bbfe2d9e38eb4fe3f579dElliott Hughes    }
36b4f7616fd618875768b8fffc122b58bdb84a9969Elliott Hughes  }
37b4f7616fd618875768b8fffc122b58bdb84a9969Elliott Hughes
38fe317a3775e16d466bb884a8e054fd77f7087bb3Calin Juravle  ~GenericTemporaryFile() {
39b4f7616fd618875768b8fffc122b58bdb84a9969Elliott Hughes    close(fd);
40b4f7616fd618875768b8fffc122b58bdb84a9969Elliott Hughes    unlink(filename);
41b4f7616fd618875768b8fffc122b58bdb84a9969Elliott Hughes  }
42b4f7616fd618875768b8fffc122b58bdb84a9969Elliott Hughes
43eda26bc1ffc60dc722a375095b9de4fd86959a1dChristopher Ferris  void reopen() {
44eda26bc1ffc60dc722a375095b9de4fd86959a1dChristopher Ferris    close(fd);
45eda26bc1ffc60dc722a375095b9de4fd86959a1dChristopher Ferris    fd = open(filename, O_RDWR);
46eda26bc1ffc60dc722a375095b9de4fd86959a1dChristopher Ferris  }
47eda26bc1ffc60dc722a375095b9de4fd86959a1dChristopher Ferris
48b4f7616fd618875768b8fffc122b58bdb84a9969Elliott Hughes  int fd;
49b4f7616fd618875768b8fffc122b58bdb84a9969Elliott Hughes  char filename[1024];
50925753aa1175ae58b24bbfe2d9e38eb4fe3f579dElliott Hughes
51925753aa1175ae58b24bbfe2d9e38eb4fe3f579dElliott Hughes private:
52925753aa1175ae58b24bbfe2d9e38eb4fe3f579dElliott Hughes  void init(const char* tmp_dir) {
53925753aa1175ae58b24bbfe2d9e38eb4fe3f579dElliott Hughes    snprintf(filename, sizeof(filename), "%s/TemporaryFile-XXXXXX", tmp_dir);
54d4934a70e69365c97b1378820152e134a0089b5eCalin Juravle    fd = mk_fn(filename);
55925753aa1175ae58b24bbfe2d9e38eb4fe3f579dElliott Hughes  }
56b4f7616fd618875768b8fffc122b58bdb84a9969Elliott Hughes};
57fe317a3775e16d466bb884a8e054fd77f7087bb3Calin Juravle
58fe317a3775e16d466bb884a8e054fd77f7087bb3Calin Juravletypedef GenericTemporaryFile<mkstemp> TemporaryFile;
59d4934a70e69365c97b1378820152e134a0089b5eCalin Juravle
60d4934a70e69365c97b1378820152e134a0089b5eCalin Juravleclass TemporaryDir {
61d4934a70e69365c97b1378820152e134a0089b5eCalin Juravle public:
62d4934a70e69365c97b1378820152e134a0089b5eCalin Juravle  TemporaryDir() {
63d4934a70e69365c97b1378820152e134a0089b5eCalin Juravle    if (!init("/data/local/tmp")) {
64d4934a70e69365c97b1378820152e134a0089b5eCalin Juravle      init("/tmp");
65d4934a70e69365c97b1378820152e134a0089b5eCalin Juravle    }
66d4934a70e69365c97b1378820152e134a0089b5eCalin Juravle  }
67d4934a70e69365c97b1378820152e134a0089b5eCalin Juravle
68d4934a70e69365c97b1378820152e134a0089b5eCalin Juravle  ~TemporaryDir() {
69d4934a70e69365c97b1378820152e134a0089b5eCalin Juravle    rmdir(dirname);
70d4934a70e69365c97b1378820152e134a0089b5eCalin Juravle  }
71d4934a70e69365c97b1378820152e134a0089b5eCalin Juravle
72d4934a70e69365c97b1378820152e134a0089b5eCalin Juravle  char dirname[1024];
73d4934a70e69365c97b1378820152e134a0089b5eCalin Juravle
74d4934a70e69365c97b1378820152e134a0089b5eCalin Juravle private:
75d4934a70e69365c97b1378820152e134a0089b5eCalin Juravle  bool init(const char* tmp_dir) {
76d4934a70e69365c97b1378820152e134a0089b5eCalin Juravle    snprintf(dirname, sizeof(dirname), "%s/TemporaryDir-XXXXXX", tmp_dir);
77d4934a70e69365c97b1378820152e134a0089b5eCalin Juravle    return (mkdtemp(dirname) != NULL);
78d4934a70e69365c97b1378820152e134a0089b5eCalin Juravle  }
79d4934a70e69365c97b1378820152e134a0089b5eCalin Juravle
80d4934a70e69365c97b1378820152e134a0089b5eCalin Juravle};
81