F´ Flight Software - C/C++ Documentation  NASA-v1.6.0
A framework for building embedded system applications to NASA flight quality standards.
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
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  NATIVE_INT_TYPE writeSize = static_cast<NATIVE_INT_TYPE>(size);
65  Os::File::Status stat = this->m_file.write(buf,writeSize,true);
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 += 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  U64 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%d",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, false);
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
Fw::String::STRING_SIZE
@ STRING_SIZE
Storage for string.
Definition: String.hpp:15
Os::File::close
void close()
close file
Definition: File.cpp:37
Svc::LogFile::set_log_file
bool set_log_file(const char *fileName, const U32 maxSize, const U32 maxBackups=10)
Set log file and max size.
Definition: LogFile.cpp:81
Os::File::NOT_OPENED
@ NOT_OPENED
file hasn't been opened yet
Definition: File.hpp:30
StringUtils.hpp
FileSystem.hpp
LogFile.hpp
Svc::LogFile::~LogFile
~LogFile()
Destructor.
Definition: LogFile.cpp:28
U64
#define U64(C)
Definition: sha.h:176
Os::File::write
Status write(const void *buffer, NATIVE_INT_TYPE &size, bool waitForDone=true)
write size; will return amount written or errno
Definition: File.cpp:33
NATIVE_INT_TYPE
int NATIVE_INT_TYPE
native integer type declaration
Definition: BasicTypes.hpp:27
Os::FileSystem::OP_OK
@ OP_OK
Operation was successful.
Definition: FileSystem.hpp:16
Os::File::open
Status open(const char *fileName, Mode mode)
open file. Writing creates file if it doesn't exist
Definition: File.cpp:13
File.hpp
FW_ASSERT
#define FW_ASSERT(...)
Definition: Assert.hpp:9
Svc::LogFile::write_to_log
bool write_to_log(const char *const buf, const U32 size)
Write the passed buf to the log if possible.
Definition: LogFile.cpp:40
Svc::LogFile::m_maxFileSize
U32 m_maxFileSize
Definition: LogFile.hpp:64
Os::File::OPEN_CREATE
@ OPEN_CREATE
Open file for writing and truncates file if it exists, ie same flags as creat()
Definition: File.hpp:20
Svc
Definition: ActiveRateGroupCfg.hpp:18
Fw::StringUtils::string_length
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:20
Os::File::Status
Status
Definition: File.hpp:24
Svc::LogFile::LogFile
LogFile()
Constructor.
Definition: LogFile.cpp:22
Os::File::OP_OK
@ OP_OK
Operation was successful.
Definition: File.hpp:25
Os::FileSystem::getFileSize
Status getFileSize(const char *path, U64 &size)
append file origin to destination file. If boolean true, creates a brand new file if the destination ...
Definition: FileSystem.cpp:40
Svc::LogFile::m_file
Os::File m_file
Definition: LogFile.hpp:61
Svc::LogFile::m_currentFileSize
U32 m_currentFileSize
Definition: LogFile.hpp:70
Svc::LogFile::m_fileName
Fw::String m_fileName
Definition: LogFile.hpp:58
Svc::LogFile::m_openFile
bool m_openFile
Definition: LogFile.hpp:67