F´ Flight Software - C/C++ Documentation  NASA-v1.6.0
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 
14 
15 namespace Svc {
16 
17  // ----------------------------------------------------------------------
18  // Initialization/Exiting
19  // ----------------------------------------------------------------------
20 
22  m_fileName(), m_file(), m_maxFileSize(0), m_openFile(false), m_currentFileSize(0)
23  {
24 
25  }
26 
28  {
29  // Close the file if needed:
30  if (this->m_openFile) {
31  this->m_file.close();
32  }
33  }
34 
35  // ----------------------------------------------------------------------
36  // Member Functions
37  // ----------------------------------------------------------------------
38 
39  bool LogFile::write_to_log(const char *const buf, const U32 size)
40  {
41 
42  FW_ASSERT(buf != nullptr);
43 
44  bool status = true;
45 
46  // Print to file if there is one, and given a valid size:
47  if (this->m_openFile && size > 0) {
48 
49  // Make sure we won't exceed the maximum size:
50  // Note: second condition in if statement is true if there is overflow
51  // in the addition below
52  U32 projectedSize = this->m_currentFileSize + size;
53  if ( projectedSize > this->m_maxFileSize ||
54  (this->m_currentFileSize > (std::numeric_limits<U32>::max() - size)) ) {
55 
56  status = false;
57  this->m_openFile = false;
58  this->m_file.close();
59  }
60  // Won't exceed max size, so write to file:
61  else {
62 
63  NATIVE_INT_TYPE writeSize = static_cast<NATIVE_INT_TYPE>(size);
64  Os::File::Status stat = this->m_file.write(buf,writeSize,true);
65 
66  // Assert that we are not trying to write to a file we never opened:
68 
69  // Only return a good status if the write was valid
70  status = (writeSize > 0);
71 
72  this->m_currentFileSize += writeSize;
73  }
74  }
75 
76  return status;
77  }
78 
79 
80  bool LogFile::set_log_file(const char* fileName, const U32 maxSize, const U32 maxBackups)
81  {
82  FW_ASSERT(fileName != nullptr);
83 
84  // If there is already a previously open file then close it:
85  if (this->m_openFile) {
86  this->m_openFile = false;
87  this->m_file.close();
88  }
89 
90  // If file name is too large, return failure:
91  U32 fileNameSize = strnlen(fileName, Fw::String::STRING_SIZE);
92  if (fileNameSize == Fw::String::STRING_SIZE) {
93  return false;
94  }
95 
96  U32 suffix = 0;
97  U64 tmp;
98  char fileNameFinal[Fw::String::STRING_SIZE];
99  (void) strncpy(fileNameFinal,fileName,
101  fileNameFinal[Fw::String::STRING_SIZE-1] = 0;
102 
103  // Check if file already exists, and if it does try to tack on a suffix.
104  // Quit after 10 suffix addition tries (first try is w/ the original name).
105  bool failedSuffix = false;
106  while (Os::FileSystem::getFileSize(fileNameFinal,tmp) == Os::FileSystem::OP_OK) {
107 
108  // If the file name was the max size, then can't append a suffix,
109  // so just fail:
110  if (fileNameSize == (Fw::String::STRING_SIZE-1)) {
111  return false;
112  }
113 
114  // Not able to create a new non-existing file in maxBackups tries, then mark that it failed:
115  if (suffix >= maxBackups) {
116  failedSuffix = true;
117  break;
118  }
119 
120  NATIVE_INT_TYPE stat = snprintf(fileNameFinal,Fw::String::STRING_SIZE,
121  "%s%d",fileName,suffix);
122 
123  // If there was error, then just fail:
124  if (stat <= 0) {
125  return false;
126  }
127 
128  // There should never be truncation:
130 
131  ++suffix;
132  }
133 
134  // If failed trying to make a new file, just use the original file
135  if (failedSuffix) {
136  (void) strncpy(fileNameFinal,fileName,
138  fileNameFinal[Fw::String::STRING_SIZE-1] = 0;
139  }
140 
141  // Open the file (using CREATE so that it truncates an already existing file):
142  Os::File::Status stat = this->m_file.open(fileNameFinal, Os::File::OPEN_CREATE, false);
143 
144  // Bad status when trying to open the file:
145  if (stat != Os::File::OP_OK) {
146  return false;
147  }
148 
149  this->m_currentFileSize = 0;
150  this->m_maxFileSize = maxSize;
151  this->m_fileName = fileNameFinal;
152  this->m_openFile = true;
153 
154  return true;
155  }
156 
157 
158 } // namespace Svc
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:80
Os::File::NOT_OPENED
@ NOT_OPENED
file hasn't been opened yet
Definition: File.hpp:30
FileSystem.hpp
LogFile.hpp
Assert.hpp
Svc::LogFile::~LogFile
~LogFile()
Destructor.
Definition: LogFile.cpp:27
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
Os::FileSystem::OP_OK
@ OP_OK
Operation was successful.
Definition: FileSystem.hpp:16
Fw::String::STRING_SIZE
@ STRING_SIZE
Storage for string.
Definition: String.hpp:15
FW_ASSERT
#define FW_ASSERT(...)
Definition: Assert.hpp:8
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
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:39
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: ActiveRateGroupImplCfg.hpp:18
Os::File::Status
Status
Definition: File.hpp:24
Svc::LogFile::LogFile
LogFile()
Constructor.
Definition: LogFile.cpp:21
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
NATIVE_INT_TYPE
int NATIVE_INT_TYPE
native integer type declaration
Definition: BasicTypes.hpp:29
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