• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
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
30 const char reportTopDir[] = "reports";
31 android::String8 FileUtil::mDirPath;
32 
prepare(android::String8 & dirPath)33 bool 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 
FileUtil()73 FileUtil::FileUtil()
74 {
75 
76 }
77 
~FileUtil()78 FileUtil::~FileUtil()
79 {
80     if (mFile.is_open()) {
81         mFile.close();
82     }
83 }
84 
init(const char * fileName)85 bool 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 
doVprintf(bool fileOnly,int loglevel,const char * fmt,va_list ap)98 bool 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 
doPrintf(const char * fmt,...)128 bool 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 }
136