blob: e40b7e357c18b9ddad6d3145721a3219388a0f8b [file] [log] [blame]
Keun young Park4bbb5d72012-03-26 18:31:29 -07001/*
2 * Copyright (C) 2012 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License"); you may not
5 * use this file except in compliance with the License. You may obtain a copy of
6 * 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, WITHOUT
12 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13 * License for the specific language governing permissions and limitations under
14 * the License.
15 */
16#include <time.h>
17#include <sys/stat.h>
18#include <sys/types.h>
19#include <errno.h>
20
21#include "Log.h"
22#include "StringUtil.h"
23#include "FileUtil.h"
24
25
26// This class is used by Log. So we cannot use LOG? macros here.
27#define _LOGD_(x...) do { fprintf(stderr, x); fprintf(stderr, "\n"); } while(0)
28
29// reported generated under reports/YYYY_MM_DD_HH_MM_SS dir
30const char reportTopDir[] = "reports";
31android::String8 FileUtil::mDirPath;
32
33bool FileUtil::prepare(android::String8& dirPath)
34{
35 if (mDirPath.length() != 0) {
36 dirPath = mDirPath;
37 _LOGD_("mDirPath %s", mDirPath.string());
38 return true;
39 }
40
41 time_t timeNow = time(NULL);
42 if (timeNow == ((time_t)-1)) {
43 _LOGD_("time error");
44 return false;
45 }
46 // tm is allocated in static buffer, and should not be freed.
47 struct tm* tm = localtime(&timeNow);
48 if (tm == NULL) {
49 _LOGD_("localtime error");
50 return false;
51 }
52 int result = mkdir(reportTopDir, S_IRWXU);
53 if ((result == -1) && (errno != EEXIST)) {
54 _LOGD_("mkdir of topdir failed, error %d", errno);
55 return false;
56 }
57 android::String8 path;
58 if (path.appendFormat("%s/%04d_%02d_%02d_%02d_%02d_%02d", reportTopDir,tm->tm_year + 1900,
59 tm->tm_mon + 1, tm->tm_mday, tm->tm_hour, tm->tm_min, tm->tm_sec) != 0) {
60 return false;
61 }
62 result = mkdir(path.string(), S_IRWXU);
63 if ((result == -1) && (errno != EEXIST)) {
64 _LOGD_("mkdir of report dir failed, error %d", errno);
65 return false;
66 }
67 mDirPath = path;
68 dirPath = path;
69
70 return true;
71}
72
73FileUtil::FileUtil()
74{
75
76}
77
78FileUtil::~FileUtil()
79{
80 if (mFile.is_open()) {
81 mFile.close();
82 }
83}
84
85bool FileUtil::init(const char* fileName)
86{
87 if (fileName == NULL) {
88 return true;
89 }
90
91 mFile.open(fileName, std::ios::out | std::ios::trunc);
92 if (!mFile.is_open()) {
93 return false;
94 }
95 return true;
96}
97
98bool FileUtil::doVprintf(bool fileOnly, int loglevel, const char *fmt, va_list ap)
99{
100 // prevent messed up log in multi-thread env. Still multi-line logs can be messed up.
101 android::Mutex::Autolock lock(mWriteLock);
102 int start = 0;
103 if (loglevel != -1) {
104 mBuffer[0] = '0' + loglevel;
105 mBuffer[1] = '>';
106 start = 2;
107 }
108 int size;
109 size = vsnprintf(mBuffer + start, BUFFER_SIZE - start - 2, fmt, ap); // 2 for \n\0
110 if (size < 0) {
111 fprintf(stderr, "FileUtil::vprintf failed");
112 return false;
113 }
114 size += start;
115 mBuffer[size] = '\n';
116 size++;
117 mBuffer[size] = 0;
118
119 if (!fileOnly) {
120 fprintf(stdout, "%s", mBuffer);
121 }
122 if (mFile.is_open()) {
123 mFile<<mBuffer;
124 }
125 return true;
126}
127
128bool FileUtil::doPrintf(const char* fmt, ...)
129{
130 va_list ap;
131 va_start(ap, fmt);
132 bool result = doVprintf(false, -1, fmt, ap);
133 va_end(ap);
134 return result;
135}