1*e01b6f76SAndroid Build Coastguard Worker /*
2*e01b6f76SAndroid Build Coastguard Worker * Copyright (C) 2015 The Android Open Source Project
3*e01b6f76SAndroid Build Coastguard Worker *
4*e01b6f76SAndroid Build Coastguard Worker * Licensed under the Apache License, Version 2.0 (the "License");
5*e01b6f76SAndroid Build Coastguard Worker * you may not use this file except in compliance with the License.
6*e01b6f76SAndroid Build Coastguard Worker * You may obtain a copy of the License at
7*e01b6f76SAndroid Build Coastguard Worker *
8*e01b6f76SAndroid Build Coastguard Worker * http://www.apache.org/licenses/LICENSE-2.0
9*e01b6f76SAndroid Build Coastguard Worker *
10*e01b6f76SAndroid Build Coastguard Worker * Unless required by applicable law or agreed to in writing, software
11*e01b6f76SAndroid Build Coastguard Worker * distributed under the License is distributed on an "AS IS" BASIS,
12*e01b6f76SAndroid Build Coastguard Worker * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*e01b6f76SAndroid Build Coastguard Worker * See the License for the specific language governing permissions and
14*e01b6f76SAndroid Build Coastguard Worker * limitations under the License.
15*e01b6f76SAndroid Build Coastguard Worker */
16*e01b6f76SAndroid Build Coastguard Worker
17*e01b6f76SAndroid Build Coastguard Worker #define LOG_TAG "TestHelpers"
18*e01b6f76SAndroid Build Coastguard Worker #define LOG_NDEBUG 0
19*e01b6f76SAndroid Build Coastguard Worker
20*e01b6f76SAndroid Build Coastguard Worker #include "TestHelpers.h"
21*e01b6f76SAndroid Build Coastguard Worker
22*e01b6f76SAndroid Build Coastguard Worker #include <dirent.h>
23*e01b6f76SAndroid Build Coastguard Worker #include <fcntl.h>
24*e01b6f76SAndroid Build Coastguard Worker #include <stdlib.h>
25*e01b6f76SAndroid Build Coastguard Worker #include <sys/stat.h>
26*e01b6f76SAndroid Build Coastguard Worker #include <sys/types.h>
27*e01b6f76SAndroid Build Coastguard Worker #include <unistd.h>
28*e01b6f76SAndroid Build Coastguard Worker
29*e01b6f76SAndroid Build Coastguard Worker #include <utils/Log.h>
30*e01b6f76SAndroid Build Coastguard Worker
31*e01b6f76SAndroid Build Coastguard Worker namespace android {
32*e01b6f76SAndroid Build Coastguard Worker
33*e01b6f76SAndroid Build Coastguard Worker static const char kTmpDirTemplate[] = "/data/local/tmp/XXXXXX";
34*e01b6f76SAndroid Build Coastguard Worker
TempFile(const char * path)35*e01b6f76SAndroid Build Coastguard Worker TempFile::TempFile(const char* path) {
36*e01b6f76SAndroid Build Coastguard Worker bool needTrailingSlash = path[strlen(path) - 1] != '/';
37*e01b6f76SAndroid Build Coastguard Worker // name = path + XXXXXX + \0
38*e01b6f76SAndroid Build Coastguard Worker size_t nameLen = strlen(path) + 6 + 1;
39*e01b6f76SAndroid Build Coastguard Worker if (needTrailingSlash) nameLen++;
40*e01b6f76SAndroid Build Coastguard Worker
41*e01b6f76SAndroid Build Coastguard Worker mName = new char[nameLen];
42*e01b6f76SAndroid Build Coastguard Worker strcpy(mName, path);
43*e01b6f76SAndroid Build Coastguard Worker if (needTrailingSlash) {
44*e01b6f76SAndroid Build Coastguard Worker strcat(mName, "/");
45*e01b6f76SAndroid Build Coastguard Worker }
46*e01b6f76SAndroid Build Coastguard Worker strcat(mName, "XXXXXX");
47*e01b6f76SAndroid Build Coastguard Worker mName = mktemp(mName);
48*e01b6f76SAndroid Build Coastguard Worker LOG_FATAL_IF(mName == nullptr, "could not create temp filename %s. errno=%d", mName, errno);
49*e01b6f76SAndroid Build Coastguard Worker
50*e01b6f76SAndroid Build Coastguard Worker int result = TEMP_FAILURE_RETRY(mkfifo(mName, S_IRWXU));
51*e01b6f76SAndroid Build Coastguard Worker LOG_FATAL_IF(result < 0, "could not create fifo %s. errno=%d", mName, errno);
52*e01b6f76SAndroid Build Coastguard Worker
53*e01b6f76SAndroid Build Coastguard Worker mFd = TEMP_FAILURE_RETRY(open(mName, O_RDWR | O_NONBLOCK));
54*e01b6f76SAndroid Build Coastguard Worker LOG_FATAL_IF(mFd < 0, "could not open fifo %s. errno=%d", mName, errno);
55*e01b6f76SAndroid Build Coastguard Worker }
56*e01b6f76SAndroid Build Coastguard Worker
~TempFile()57*e01b6f76SAndroid Build Coastguard Worker TempFile::~TempFile() {
58*e01b6f76SAndroid Build Coastguard Worker if (unlink(mName) < 0) {
59*e01b6f76SAndroid Build Coastguard Worker ALOGE("could not unlink %s. errno=%d", mName, errno);
60*e01b6f76SAndroid Build Coastguard Worker }
61*e01b6f76SAndroid Build Coastguard Worker if (close(mFd) < 0) {
62*e01b6f76SAndroid Build Coastguard Worker ALOGE("could not close %d. errno=%d", mFd, errno);
63*e01b6f76SAndroid Build Coastguard Worker }
64*e01b6f76SAndroid Build Coastguard Worker delete[] mName;
65*e01b6f76SAndroid Build Coastguard Worker }
66*e01b6f76SAndroid Build Coastguard Worker
TempDir()67*e01b6f76SAndroid Build Coastguard Worker TempDir::TempDir() {
68*e01b6f76SAndroid Build Coastguard Worker mName = new char[sizeof(kTmpDirTemplate)];
69*e01b6f76SAndroid Build Coastguard Worker strcpy(mName, kTmpDirTemplate);
70*e01b6f76SAndroid Build Coastguard Worker mName = mkdtemp(mName);
71*e01b6f76SAndroid Build Coastguard Worker LOG_FATAL_IF(mName == nullptr, "could not allocate tempdir %s", mName);
72*e01b6f76SAndroid Build Coastguard Worker }
73*e01b6f76SAndroid Build Coastguard Worker
~TempDir()74*e01b6f76SAndroid Build Coastguard Worker TempDir::~TempDir() {
75*e01b6f76SAndroid Build Coastguard Worker auto tmpDir = opendir(mName);
76*e01b6f76SAndroid Build Coastguard Worker while (auto entry = readdir(tmpDir)) {
77*e01b6f76SAndroid Build Coastguard Worker if (strcmp(entry->d_name, ".") == 0 ||
78*e01b6f76SAndroid Build Coastguard Worker strcmp(entry->d_name, "..") == 0) {
79*e01b6f76SAndroid Build Coastguard Worker continue;
80*e01b6f76SAndroid Build Coastguard Worker }
81*e01b6f76SAndroid Build Coastguard Worker ALOGD("stale file %s, removing", entry->d_name);
82*e01b6f76SAndroid Build Coastguard Worker unlink(entry->d_name);
83*e01b6f76SAndroid Build Coastguard Worker }
84*e01b6f76SAndroid Build Coastguard Worker closedir(tmpDir);
85*e01b6f76SAndroid Build Coastguard Worker rmdir(mName);
86*e01b6f76SAndroid Build Coastguard Worker delete mName;
87*e01b6f76SAndroid Build Coastguard Worker }
88*e01b6f76SAndroid Build Coastguard Worker
newTempFile()89*e01b6f76SAndroid Build Coastguard Worker TempFile* TempDir::newTempFile() {
90*e01b6f76SAndroid Build Coastguard Worker return new TempFile(mName);
91*e01b6f76SAndroid Build Coastguard Worker }
92*e01b6f76SAndroid Build Coastguard Worker
93*e01b6f76SAndroid Build Coastguard Worker } // namespace android
94