esp8266ndn
NDN Arduino library for ESP8266 and more
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
linux.hpp
Go to the documentation of this file.
1#ifndef NDNPH_PORT_FS_LINUX_HPP
2#define NDNPH_PORT_FS_LINUX_HPP
3
4#include "../../core/common.hpp"
5#include <fcntl.h>
6#include <libgen.h>
7#include <limits.h>
8#include <sys/stat.h>
9#include <unistd.h>
10
11namespace ndnph {
12namespace port_fs_linux {
13namespace detail {
14
15class Mkdirp {
16public:
17 bool create(const char* path) {
18 size_t pathLen = strlen(path);
19 if (pathLen <= 1 || pathLen >= sizeof(m_path) - 1 || path[pathLen - 1] == '/') {
20 return false;
21 }
22 return createDir(path, 0);
23 }
24
25private:
26 bool createDir(const char* path, int up) {
27 const char* dir = toDirname(path, up);
28 if (::stat(dir, &m_stat) == 0) {
29 return S_ISDIR(m_stat.st_mode);
30 } else if (errno == ENOENT) {
31 bool ok = createDir(path, up + 1);
32 if (!ok) {
33 return false;
34 }
35 }
36
37 dir = toDirname(path, up);
38 return ::mkdir(dir, 0700) == 0;
39 }
40
41 const char* toDirname(const char* path, int up) {
42 strncpy(m_path, path, sizeof(m_path));
43 char* dir = m_path;
44 for (int i = 0; i < up; ++i) {
45 dir = ::dirname(dir);
46 }
47 return dir;
48 }
49
50private:
51 char m_path[PATH_MAX];
52 struct stat m_stat;
53};
54
55class FdCloser {
56public:
57 explicit FdCloser(int fd = -1)
58 : m_fd(fd) {}
59
61 close();
62 }
63
65 if (fd != m_fd) {
66 close();
67 m_fd = fd;
68 }
69 return *this;
70 }
71
72 operator int() const {
73 return m_fd;
74 }
75
76 void close() {
77 if (m_fd >= 0) {
78 ::close(m_fd);
79 m_fd = -1;
80 }
81 }
82
83private:
84 int m_fd = -1;
85};
86
87} // namespace detail
88
90class FileStore {
91public:
96 bool open(const char* path) {
97 if (!detail::Mkdirp().create(path)) {
98 return false;
99 }
100
101 m_dfd = ::open(path, O_RDONLY | O_DIRECTORY);
102 return m_dfd >= 0;
103 }
104
109 int read(const char* filename, uint8_t* buffer, size_t count) {
110 detail::FdCloser fd(::openat(m_dfd, filename, O_RDONLY));
111 if (fd < 0) {
112 if (errno == ENOENT) {
113 return 0;
114 }
115 return -errno;
116 }
117
118 ssize_t nRead = ::read(fd, buffer, count);
119 if (nRead < 0) {
120 return -errno;
121 }
122 if (static_cast<size_t>(nRead) == count) {
123 return ::lseek(fd, 0, SEEK_END);
124 }
125 return static_cast<int>(nRead);
126 }
127
132 bool write(const char* filename, const uint8_t* buffer, size_t count) {
133 detail::FdCloser fd(::openat(m_dfd, filename, O_WRONLY | O_CREAT, 0600));
134 ssize_t nWrite = ::write(fd, buffer, count);
135 return static_cast<size_t>(nWrite) == count;
136 }
137
142 bool unlink(const char* filename) {
143 int res = ::unlinkat(m_dfd, filename, 0);
144 return res == 0 || errno == ENOENT;
145 }
146
147private:
148 detail::FdCloser m_dfd;
149};
150
151} // namespace port_fs_linux
152
153#ifdef NDNPH_PORT_FS_LINUX
154namespace port {
155using FileStore = port_fs_linux::FileStore;
156} // namespace port
157#endif
158
159} // namespace ndnph
160
161#endif // NDNPH_PORT_FS_LINUX_HPP
File storage on Linux filesystem.
Definition linux.hpp:90
bool open(const char *path)
Open path directory as FileStore, creating directories as necessary.
Definition linux.hpp:96
int read(const char *filename, uint8_t *buffer, size_t count)
Read content of filename file into buffer .
Definition linux.hpp:109
bool write(const char *filename, const uint8_t *buffer, size_t count)
Write buffer into filename file.
Definition linux.hpp:132
bool unlink(const char *filename)
Delete filename file.
Definition linux.hpp:142
~FdCloser()
Definition linux.hpp:60
FdCloser & operator=(int fd)
Definition linux.hpp:64
FdCloser(int fd=-1)
Definition linux.hpp:57
void close()
Definition linux.hpp:76
bool create(const char *path)
Definition linux.hpp:17
Definition fs.hpp:33