11#include " pros/rtos.hpp"
2+ #include " system/vfs/file_descriptor.hpp"
23#include " system/vfs/file_driver.hpp"
34
45#include < array>
56#include < cerrno>
7+ #include < concepts>
68#include < mutex>
79#include < optional>
810#include < stdexcept>
911#include < string>
12+ #include < sys/unistd.h>
1013#include < unordered_map>
1114
1215namespace zest ::fs {
@@ -47,6 +50,28 @@ int32_t zest::fs::FileDriver::update_vfs_entry(zest::fs::FileDescriptor fd, std:
4750 return 0 ;
4851}
4952
53+ static auto with_fd (int file, std::invocable<zest::fs::FileEntry> auto func) {
54+ using ReturnType = decltype (func (zest::fs::FileEntry{}))::value_type;
55+ struct _reent * r = _REENT;
56+ zest::fs::FileEntry file_entry;
57+ try {
58+ file_entry = fd_data.at (file).value ();
59+ } catch (std::bad_optional_access) {
60+ r->_errno = EBADF;
61+ return ReturnType{-1 };
62+ } catch (std::out_of_range) {
63+ r->_errno = EBADF;
64+ return ReturnType{-1 };
65+ }
66+ auto result = func (file_entry);
67+ if (result) {
68+ return result.value ();
69+ } else {
70+ r->_errno = result.error ().value ();
71+ return ReturnType{-1 };
72+ }
73+ }
74+
5075// newlib fs stubs: these must be extern "C" to prevent name mangling,
5176// which would prevent newlib from linking to these functions properly
5277
@@ -116,50 +141,20 @@ char* getcwd(char* buf, size_t size) {
116141}
117142
118143ssize_t _write (int file, void * buf, size_t len) {
119- struct _reent * r = _REENT;
120- try {
121- auto file_entry = fd_data.at (file).value ();
122- auto result = file_entry.driver ->write (
144+ return with_fd (file, [=](zest::fs::FileEntry file_entry) {
145+ return file_entry.driver ->write (
123146 file_entry.data ,
124147 std::span<std::byte>{static_cast <std::byte*>(buf), len}
125148 );
126- if (result) {
127- return result.value ();
128- } else {
129- r->_errno = result.error ().value ();
130- return -1 ;
131- }
132- } catch (std::bad_optional_access) {
133- r->_errno = EBADF;
134- return -1 ;
135- } catch (std::out_of_range) {
136- r->_errno = EBADF;
137- return -1 ;
138- }
149+ });
139150}
140151
141152ssize_t _read (int file, void * buf, size_t len) {
142- struct _reent * r = _REENT;
143- zest::fs::FileEntry file_entry;
144- try {
145- file_entry = fd_data.at (file).value ();
146-
147- } catch (std::bad_optional_access) {
148- r->_errno = EBADF;
149- return -1 ;
150- } catch (std::out_of_range) {
151- r->_errno = EBADF;
152- return -1 ;
153- }
154- auto result = file_entry.driver ->read (
155- file_entry.data ,
156- std::span<std::byte>{static_cast <std::byte*>(buf), len}
157- );
158- if (result) {
159- return result.value ();
160- } else {
161- r->_errno = result.error ().value ();
162- return -1 ;
163- }
153+ return with_fd (file, [=](zest::fs::FileEntry file_entry) {
154+ return file_entry.driver ->read (
155+ file_entry.data ,
156+ std::span<std::byte>{static_cast <std::byte*>(buf), len}
157+ );
158+ });
164159}
165160}
0 commit comments