Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependents: UAVCAN UAVCAN_Subscriber
file_storage_backend.hpp
00001 /**************************************************************************** 00002 * 00003 * Copyright (c) 2015 PX4 Development Team. All rights reserved. 00004 * Author: Pavel Kirienko <pavel.kirienko@gmail.com> 00005 * David Sidrane <david_s5@usa.net> 00006 * 00007 ****************************************************************************/ 00008 00009 #ifndef UAVCAN_POSIX_DYNAMIC_NODE_ID_SERVER_FILE_STORAGE_BACKEND_HPP_INCLUDED 00010 #define UAVCAN_POSIX_DYNAMIC_NODE_ID_SERVER_FILE_STORAGE_BACKEND_HPP_INCLUDED 00011 00012 #include <sys/stat.h> 00013 #include <cstdio> 00014 #include <cstddef> 00015 #include <cstdlib> 00016 #include <cstring> 00017 #include <cerrno> 00018 #include <unistd.h> 00019 #include <fcntl.h> 00020 00021 #include <uavcan/protocol/dynamic_node_id_server/storage_backend.hpp> 00022 00023 namespace uavcan_posix 00024 { 00025 namespace dynamic_node_id_server 00026 { 00027 /** 00028 * This interface implements a POSIX compliant IStorageBackend interface 00029 */ 00030 class FileStorageBackend : public uavcan::dynamic_node_id_server::IStorageBackend 00031 { 00032 /** 00033 * Maximum length of full path including / and key max 00034 */ 00035 enum { MaxPathLength = 128 }; 00036 00037 enum { FilePermissions = 438 }; ///< 0o666 00038 00039 /** 00040 * This type is used for the path 00041 */ 00042 typedef uavcan::MakeString<MaxPathLength>::Type PathString; 00043 00044 PathString base_path; 00045 00046 protected: 00047 virtual String get(const String& key) const 00048 { 00049 using namespace std; 00050 PathString path = base_path.c_str(); 00051 path += key; 00052 String value; 00053 int fd = open(path.c_str(), O_RDONLY); 00054 if (fd >= 0) 00055 { 00056 char buffer[MaxStringLength + 1]; 00057 (void)memset(buffer, 0, sizeof(buffer)); 00058 ssize_t remaining = MaxStringLength; 00059 ssize_t total_read = 0; 00060 ssize_t nread = 0; 00061 do 00062 { 00063 nread = ::read(fd, &buffer[total_read], remaining); 00064 if (nread > 0) 00065 { 00066 remaining -= nread, 00067 total_read += nread; 00068 } 00069 } 00070 while (nread > 0 && remaining > 0); 00071 (void)close(fd); 00072 if (total_read > 0) 00073 { 00074 for (int i = 0; i < total_read; i++) 00075 { 00076 if (buffer[i] == ' ' || buffer[i] == '\n' || buffer[i] == '\r') 00077 { 00078 buffer[i] = '\0'; 00079 break; 00080 } 00081 } 00082 value = buffer; 00083 } 00084 } 00085 return value; 00086 } 00087 00088 virtual void set(const String& key, const String& value) 00089 { 00090 using namespace std; 00091 PathString path = base_path.c_str(); 00092 path += key; 00093 int fd = open(path.c_str(), O_WRONLY | O_CREAT | O_TRUNC, FilePermissions); 00094 if (fd >= 0) 00095 { 00096 ssize_t remaining = value.size(); 00097 ssize_t total_written = 0; 00098 ssize_t written = 0; 00099 do 00100 { 00101 written = write(fd, &value.c_str()[total_written], remaining); 00102 if (written > 0) 00103 { 00104 total_written += written; 00105 remaining -= written; 00106 } 00107 } 00108 while (written > 0 && remaining > 0); 00109 00110 (void)fsync(fd); 00111 (void)close(fd); 00112 } 00113 } 00114 00115 public: 00116 /** 00117 * Initializes the file based backend storage by passing a path to 00118 * the directory where the key named files will be stored. 00119 * The return value should be 0 on success. 00120 * If it is -ErrInvalidConfiguration then the the path name is too long to 00121 * accommodate the trailing slash and max key length. 00122 */ 00123 int init(const PathString& path) 00124 { 00125 using namespace std; 00126 00127 int rv = -uavcan::ErrInvalidParam; 00128 00129 if (path.size() > 0) 00130 { 00131 base_path = path.c_str(); 00132 00133 if (base_path.back() == '/') 00134 { 00135 base_path.pop_back(); 00136 } 00137 00138 rv = 0; 00139 struct stat sb; 00140 if (stat(base_path.c_str(), &sb) != 0 || !S_ISDIR(sb.st_mode)) 00141 { 00142 // coverity[toctou] 00143 rv = mkdir(base_path.c_str(), S_IRWXU | S_IRWXG | S_IRWXO); 00144 } 00145 if (rv >= 0) 00146 { 00147 base_path.push_back('/'); 00148 if ((base_path.size() + MaxStringLength) > MaxPathLength) 00149 { 00150 rv = -uavcan::ErrInvalidConfiguration; 00151 } 00152 } 00153 } 00154 return rv; 00155 } 00156 }; 00157 } 00158 } 00159 00160 #endif // Include guard
Generated on Tue Jul 12 2022 17:17:31 by
1.7.2