Skip to content

Commit 2a4e295

Browse files
authored
[NFC][WasmFS] Reorganize source files (#16286)
- Combine memory_file.cpp and memory_file_backend.cpp into memory_backend.cpp - Rename memory_file.h to memory_backend.h - Split path parsing out into paths.h and paths.cpp - Move backend implementations into a new backends directory
1 parent 5da3ca4 commit 2a4e295

14 files changed

+265
-240
lines changed

system/lib/wasmfs/memory_file.cpp renamed to system/lib/wasmfs/backends/memory_backend.cpp

Lines changed: 20 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,17 @@
22
// Emscripten is available under two separate licenses, the MIT license and the
33
// University of Illinois/NCSA Open Source License. Both these licenses can be
44
// found in the LICENSE file.
5-
// This file defines the memory file class of the new file system.
6-
// This should be the only backend file type defined in a header since it is the
7-
// default type. Current Status: Work in Progress. See
8-
// https://github.com/emscripten-core/emscripten/issues/15041.
95

10-
#include "memory_file.h"
6+
// This file defines the memory file backend of the new file system.
7+
// Current Status: Work in Progress.
8+
// See https://github.com/emscripten-core/emscripten/issues/15041.
9+
10+
#include "backend.h"
11+
#include "memory_backend.h"
12+
#include "wasmfs.h"
1113

1214
namespace wasmfs {
15+
1316
__wasi_errno_t MemoryFile::write(const uint8_t* buf, size_t len, off_t offset) {
1417
if (offset + len > buffer.size()) {
1518
buffer.resize(offset + len);
@@ -27,4 +30,16 @@ __wasi_errno_t MemoryFile::read(uint8_t* buf, size_t len, off_t offset) {
2730

2831
return __WASI_ERRNO_SUCCESS;
2932
}
33+
34+
class MemoryFileBackend : public Backend {
35+
public:
36+
std::shared_ptr<DataFile> createFile(mode_t mode) override {
37+
return std::make_shared<MemoryFile>(mode, this);
38+
}
39+
};
40+
41+
backend_t createMemoryFileBackend() {
42+
return wasmFS.addBackend(std::make_unique<MemoryFileBackend>());
43+
}
44+
3045
} // namespace wasmfs

system/lib/wasmfs/file.cpp

Lines changed: 0 additions & 161 deletions
Original file line numberDiff line numberDiff line change
@@ -108,165 +108,4 @@ size_t Symlink::getSize() {
108108
return target.size();
109109
}
110110

111-
//
112-
// Path Parsing utilities
113-
//
114-
115-
ParsedPath getParsedPath(std::vector<std::string> pathParts,
116-
long& err,
117-
std::shared_ptr<File> forbiddenAncestor,
118-
std::optional<__wasi_fd_t> baseFD) {
119-
std::shared_ptr<Directory> curr;
120-
auto begin = pathParts.begin();
121-
122-
if (pathParts.empty()) {
123-
err = -ENOENT;
124-
return ParsedPath{{}, nullptr};
125-
}
126-
127-
// Check if the first path element is '/', indicating an absolute path.
128-
if (pathParts[0] == "/") {
129-
curr = wasmFS.getRootDirectory();
130-
begin++;
131-
// If the pathname is the root directory, return the root as the child.
132-
if (pathParts.size() == 1) {
133-
return ParsedPath{curr->locked(), curr};
134-
}
135-
} else {
136-
// This is a relative path. It is either relative to the current working
137-
// directory if no base FD is given, or if the base FD is the special value
138-
// indicating the CWD.
139-
if (baseFD && *baseFD != AT_FDCWD) {
140-
auto lockedOpenDir = wasmFS.getLockedFileTable()[*baseFD].locked();
141-
auto openDir = lockedOpenDir.getFile();
142-
if (!openDir->is<Directory>()) {
143-
err = -EBADF;
144-
return ParsedPath{{}, nullptr};
145-
}
146-
curr = openDir->dynCast<Directory>();
147-
} else {
148-
curr = wasmFS.getCWD();
149-
}
150-
}
151-
152-
for (auto pathPart = begin; pathPart != pathParts.end() - 1; ++pathPart) {
153-
// Find the next entry in the current directory entry
154-
#ifdef WASMFS_DEBUG
155-
curr->locked().printKeys();
156-
#endif
157-
auto entry = curr->locked().getEntry(*pathPart);
158-
159-
if (forbiddenAncestor) {
160-
if (entry == forbiddenAncestor) {
161-
err = -EINVAL;
162-
return ParsedPath{{}, nullptr};
163-
}
164-
}
165-
166-
// An entry is defined in the current directory's entries vector.
167-
if (!entry) {
168-
err = -ENOENT;
169-
return ParsedPath{{}, nullptr};
170-
}
171-
172-
curr = entry->dynCast<Directory>();
173-
174-
// If file is nullptr, then the file was not a Directory.
175-
// TODO: Change this to accommodate symlinks
176-
if (!curr) {
177-
err = -ENOTDIR;
178-
return ParsedPath{{}, nullptr};
179-
}
180-
181-
#ifdef WASMFS_DEBUG
182-
emscripten_console_log(*pathPart->c_str());
183-
#endif
184-
}
185-
186-
// Lock the parent once.
187-
auto lockedCurr = curr->locked();
188-
auto child = lockedCurr.getEntry(*(pathParts.end() - 1));
189-
return ParsedPath{std::move(lockedCurr), child};
190-
}
191-
192-
std::shared_ptr<Directory> getDir(std::vector<std::string>::iterator begin,
193-
std::vector<std::string>::iterator end,
194-
long& err,
195-
std::shared_ptr<File> forbiddenAncestor) {
196-
197-
std::shared_ptr<File> curr;
198-
// Check if the first path element is '/', indicating an absolute path.
199-
if (*begin == "/") {
200-
curr = wasmFS.getRootDirectory();
201-
begin++;
202-
} else {
203-
curr = wasmFS.getCWD();
204-
}
205-
206-
for (auto it = begin; it != end; ++it) {
207-
auto directory = curr->dynCast<Directory>();
208-
209-
// If file is nullptr, then the file was not a Directory.
210-
// TODO: Change this to accommodate symlinks
211-
if (!directory) {
212-
err = -ENOTDIR;
213-
return nullptr;
214-
}
215-
216-
// Find the next entry in the current directory entry
217-
#ifdef WASMFS_DEBUG
218-
directory->locked().printKeys();
219-
#endif
220-
curr = directory->locked().getEntry(*it);
221-
222-
if (forbiddenAncestor) {
223-
if (curr == forbiddenAncestor) {
224-
err = -EINVAL;
225-
return nullptr;
226-
}
227-
}
228-
229-
// Requested entry (file or directory)
230-
if (!curr) {
231-
err = -ENOENT;
232-
return nullptr;
233-
}
234-
235-
#ifdef WASMFS_DEBUG
236-
emscripten_console_log(it->c_str());
237-
#endif
238-
}
239-
240-
auto currDirectory = curr->dynCast<Directory>();
241-
242-
if (!currDirectory) {
243-
err = -ENOTDIR;
244-
return nullptr;
245-
}
246-
247-
return currDirectory;
248-
}
249-
250-
// TODO: Check for trailing slash, i.e. /foo/bar.txt/
251-
// Currently any trailing slash is ignored.
252-
std::vector<std::string> splitPath(char* pathname) {
253-
std::vector<std::string> pathParts;
254-
char newPathName[strlen(pathname) + 1];
255-
strcpy(newPathName, pathname);
256-
257-
// TODO: Other path parsing edge cases.
258-
char* current;
259-
// Handle absolute path.
260-
if (newPathName[0] == '/') {
261-
pathParts.push_back("/");
262-
}
263-
264-
current = strtok(newPathName, "/");
265-
while (current != NULL) {
266-
pathParts.push_back(current);
267-
current = strtok(NULL, "/");
268-
}
269-
270-
return pathParts;
271-
}
272111
} // namespace wasmfs

system/lib/wasmfs/file.h

Lines changed: 0 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -264,37 +264,4 @@ struct ParsedPath {
264264
std::shared_ptr<File> child;
265265
};
266266

267-
// Call getParsedPath if one needs a locked handle to a parent dir and a
268-
// shared_ptr to its child file, given a file path.
269-
// TODO: When locking the directory structure is refactored, parent should be
270-
// returned as a pointer, similar to child.
271-
// Will return an empty handle if the parent is not a directory.
272-
//
273-
// Will error if the forbiddenAncestor is encountered while processing.
274-
// If the forbiddenAncestor is encountered, err will be set to EINVAL and
275-
// an empty parent handle will be returned.
276-
//
277-
// If baseFD is provided, and the path is relative, then it will be interpreted
278-
// relative to the base. That is the behavior that the *at() syscalls require.
279-
ParsedPath getParsedPath(std::vector<std::string> pathParts,
280-
long& err,
281-
std::shared_ptr<File> forbiddenAncestor = nullptr,
282-
std::optional<__wasi_fd_t> baseFD = {});
283-
284-
// Call getDir if one needs a parent directory of a file path.
285-
// TODO: Remove this when directory structure locking is refactored and use
286-
// getParsedPath instead. Obtains parent directory of a given pathname.
287-
// Will return a nullptr if the parent is not a directory. Will error if the
288-
// forbiddenAncestor is encountered while processing. If the forbiddenAncestor
289-
// is encountered, err will be set to EINVAL and nullptr will be returned.
290-
std::shared_ptr<Directory>
291-
getDir(std::vector<std::string>::iterator begin,
292-
std::vector<std::string>::iterator end,
293-
long& err,
294-
std::shared_ptr<File> forbiddenAncestor = nullptr);
295-
296-
// Return a vector of the '/'-delimited components of a path. The first
297-
// element will be "/" iff the path is an absolute path.
298-
std::vector<std::string> splitPath(char* pathname);
299-
300267
} // namespace wasmfs

system/lib/wasmfs/js_api.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
#include <unistd.h>
88

99
#include "file.h"
10+
#include "paths.h"
1011

1112
using namespace wasmfs;
1213

File renamed without changes.

system/lib/wasmfs/memory_file_backend.cpp

Lines changed: 0 additions & 26 deletions
This file was deleted.

0 commit comments

Comments
 (0)