F´ Flight Software - C/C++ Documentation  devel
A framework for building embedded system applications to NASA flight quality standards.
LogFile.cpp
Go to the documentation of this file.
1 // \copyright
2 // Copyright 2009-2015, by the California Institute of Technology.
3 // ALL RIGHTS RESERVED. United States Government Sponsorship
4 // acknowledged.
5 
7 #include <Fw/Types/Assert.hpp>
8 #include <Os/File.hpp>
9 #include <Os/FileSystem.hpp>
10 #include <limits>
11 #include <cstring>
12 #include <cstdio>
13 #include <Fw/Types/StringUtils.hpp>
14 
15 
16 namespace Svc {
17 
18  // ----------------------------------------------------------------------
19  // Initialization/Exiting
20  // ----------------------------------------------------------------------
21 
23  m_fileName(), m_file(), m_maxFileSize(0), m_openFile(false), m_currentFileSize(0)
24  {
25 
26  }
27 
29  {
30  // Close the file if needed:
31  if (this->m_openFile) {
32  this->m_file.close();
33  }
34  }
35 
36  // ----------------------------------------------------------------------
37  // Member Functions
38  // ----------------------------------------------------------------------
39 
40  bool LogFile::write_to_log(const char *const buf, const U32 size)
41  {
42 
43  FW_ASSERT(buf != nullptr);
44 
45  bool status = true;
46 
47  // Print to file if there is one, and given a valid size:
48  if (this->m_openFile && size > 0) {
49 
50  // Make sure we won't exceed the maximum size:
51  // Note: second condition in if statement is true if there is overflow
52  // in the addition below
53  U32 projectedSize = this->m_currentFileSize + size;
54  if ( projectedSize > this->m_maxFileSize ||
55  (this->m_currentFileSize > (std::numeric_limits<U32>::max() - size)) ) {
56 
57  status = false;
58  this->m_openFile = false;
59  this->m_file.close();
60  }
61  // Won't exceed max size, so write to file:
62  else {
63 
64  FwSignedSizeType writeSize = size;
65  Os::File::Status stat = this->m_file.write(reinterpret_cast<const U8*>(buf),writeSize,Os::File::WAIT);
66 
67  // Assert that we are not trying to write to a file we never opened:
69 
70  // Only return a good status if the write was valid
71  status = (writeSize > 0);
72 
73  this->m_currentFileSize += static_cast<U32>(writeSize);
74  }
75  }
76 
77  return status;
78  }
79 
80 
81  bool LogFile::set_log_file(const char* fileName, const U32 maxSize, const U32 maxBackups)
82  {
83  FW_ASSERT(fileName != nullptr);
84 
85  // If there is already a previously open file then close it:
86  if (this->m_openFile) {
87  this->m_openFile = false;
88  this->m_file.close();
89  }
90 
91  // If file name is too large, return failure:
92  U32 fileNameSize = Fw::StringUtils::string_length(fileName, Fw::String::STRING_SIZE);
93  if (fileNameSize == Fw::String::STRING_SIZE) {
94  return false;
95  }
96 
97  U32 suffix = 0;
98  FwSignedSizeType tmp;
99  char fileNameFinal[Fw::String::STRING_SIZE];
100  (void) strncpy(fileNameFinal,fileName,
102  fileNameFinal[Fw::String::STRING_SIZE-1] = 0;
103 
104  // Check if file already exists, and if it does try to tack on a suffix.
105  // Quit after 10 suffix addition tries (first try is w/ the original name).
106  bool failedSuffix = false;
107  while (Os::FileSystem::getFileSize(fileNameFinal,tmp) == Os::FileSystem::OP_OK) {
108 
109  // If the file name was the max size, then can't append a suffix,
110  // so just fail:
111  if (fileNameSize == (Fw::String::STRING_SIZE-1)) {
112  return false;
113  }
114 
115  // Not able to create a new non-existing file in maxBackups tries, then mark that it failed:
116  if (suffix >= maxBackups) {
117  failedSuffix = true;
118  break;
119  }
120 
121  NATIVE_INT_TYPE stat = snprintf(fileNameFinal,Fw::String::STRING_SIZE,
122  "%s%" PRIu32,fileName,suffix);
123 
124  // If there was error, then just fail:
125  if (stat <= 0) {
126  return false;
127  }
128 
129  // There should never be truncation:
131 
132  ++suffix;
133  }
134 
135  // If failed trying to make a new file, just use the original file
136  if (failedSuffix) {
137  (void) strncpy(fileNameFinal,fileName,
139  fileNameFinal[Fw::String::STRING_SIZE-1] = 0;
140  }
141 
142  // Open the file (using CREATE so that it truncates an already existing file):
143  Os::File::Status stat = this->m_file.open(fileNameFinal, Os::File::OPEN_CREATE, Os::File::OverwriteType::NO_OVERWRITE);
144 
145  // Bad status when trying to open the file:
146  if (stat != Os::File::OP_OK) {
147  return false;
148  }
149 
150  this->m_currentFileSize = 0;
151  this->m_maxFileSize = maxSize;
152  this->m_fileName = fileNameFinal;
153  this->m_openFile = true;
154 
155  return true;
156  }
157 
158 
159 } // namespace Svc
#define FW_ASSERT(...)
Definition: Assert.hpp:14
PlatformIntType NATIVE_INT_TYPE
Definition: BasicTypes.h:51
uint8_t U8
8-bit unsigned integer
Definition: BasicTypes.h:26
PlatformSignedSizeType FwSignedSizeType
Definition: FpConfig.h:25
@ STRING_SIZE
Definition: String.hpp:21
void close() override
close the file, if not opened then do nothing
Definition: File.cpp:69
Os::FileInterface::Status open(const char *path, Mode mode)
open file with supplied path and mode
Definition: File.cpp:45
Status write(const U8 *buffer, FwSignedSizeType &size)
write data to this file from the supplied buffer bounded by size
Definition: File.cpp:162
@ WAIT
Do wait for read/write operation to finish.
Definition: File.hpp:58
@ NOT_OPENED
file hasn't been opened yet
Definition: File.hpp:35
@ OP_OK
Operation was successful.
Definition: File.hpp:30
@ OPEN_CREATE
Open file for writing and truncates file if it exists, ie same flags as creat()
Definition: File.hpp:22
U32 string_length(const CHAR *source, U32 max_len)
get the length of the source string or max_len if the string is longer than max_len.
Definition: StringUtils.cpp:23
Status getFileSize(const char *path, FwSizeType &size)
Definition: FileSystem.cpp:38
@ OP_OK
Operation was successful.
Definition: FileSystem.hpp:15
~LogFile()
Destructor.
Definition: LogFile.cpp:28
Os::File m_file
Definition: LogFile.hpp:61
U32 m_currentFileSize
Definition: LogFile.hpp:70
LogFile()
Constructor.
Definition: LogFile.cpp:22
bool set_log_file(const char *fileName, const U32 maxSize, const U32 maxBackups=10)
Set log file and max size.
Definition: LogFile.cpp:81
bool write_to_log(const char *const buf, const U32 size)
Write the passed buf to the log if possible.
Definition: LogFile.cpp:40
bool m_openFile
Definition: LogFile.hpp:67
U32 m_maxFileSize
Definition: LogFile.hpp:64
Fw::String m_fileName
Definition: LogFile.hpp:58