Keun young Park | 4bbb5d7 | 2012-03-26 18:31:29 -0700 | [diff] [blame^] | 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 | |
| 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 | |
| 73 | FileUtil::FileUtil() |
| 74 | { |
| 75 | |
| 76 | } |
| 77 | |
| 78 | FileUtil::~FileUtil() |
| 79 | { |
| 80 | if (mFile.is_open()) { |
| 81 | mFile.close(); |
| 82 | } |
| 83 | } |
| 84 | |
| 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 | |
| 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 | |
| 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 | } |