M board/linux/libiosyscalls/include/iosyscalls.hpp => board/linux/libiosyscalls/include/iosyscalls.hpp +1 -1
@@ 32,7 32,7 @@ namespace vfsn::linux::internal
auto vfs = purefs::subsystem::vfs_core();
if(!vfs) {
errno = EIO;
- return 0;
+ return -1;
}
auto ret = (vfs.get()->*lfs_fun)(std::forward<Args>(args)...);
if(ret < 0) {
M board/rt1051/newlib/include/sys/dirent.h => board/rt1051/newlib/include/sys/dirent.h +4 -18
@@ 29,28 29,14 @@ extern "C" {
struct dirent {
ino_t d_ino;
unsigned char d_type;
+ size_t d_reclen;
char d_name[NAME_MAX+1];
};
- struct DIR_ITER {
- void *dir_state;
- char name_state[NAME_MAX+1];
- };
-
- typedef struct {
- long int position;
- DIR_ITER* dir_data;
- struct dirent file_data;
- } DIR;
-
- int closedir(DIR *dirp);
- DIR *opendir(const char *dirname);
- struct dirent *readdir(DIR *dirp);
- int readdir_r(DIR *dirp, struct dirent *entry, struct dirent **result);
- void rewinddir(DIR *dirp);
- void seekdir(DIR *dirp, long int loc);
- long int telldir(DIR *dirp);
+ struct __dirstream;
+ typedef struct __dirstream DIR;
+
#ifdef __cplusplus
}
#endif
M board/rt1051/newlib/io_syscalls.cpp => board/rt1051/newlib/io_syscalls.cpp +1 -1
@@ 112,7 112,7 @@ extern "C"
}
int statvfs(const char *path, struct statvfs *buf)
{
- return syscalls::statvfs(path,buf);
+ return syscalls::statvfs( _REENT->_errno, path,buf);
}
}
M module-vfs/include/internal/newlib/vfs_io_syscalls.hpp => module-vfs/include/internal/newlib/vfs_io_syscalls.hpp +1 -1
@@ 35,6 35,6 @@ namespace vfsn::internal::syscalls
int chmod(int &_errno_, const char *path, mode_t mode);
int fchmod(int &_errno_, int fd, mode_t mode);
int fsync(int &_errno_, int fd);
- int statvfs(const char *path, struct statvfs *buf);
+ int statvfs(int &_errno_, const char *path, struct statvfs *buf);
} // namespace vfsn::internal::syscalls
D module-vfs/src/newlib/HandleManager.cpp => module-vfs/src/newlib/HandleManager.cpp +0 -27
@@ 1,27 0,0 @@
-// Copyright (c) 2017-2020, Mudita Sp. z.o.o. All rights reserved.
-// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md
-
-#include "HandleManager.hpp"
-
-namespace vfsn::internal::stdlib::impl
-{
- auto HandleManager::clearHandle(int hwnd) noexcept -> void *
- {
- if (hwnd < FIRST_HANDLE || hwnd >= MAX_HANDLES + FIRST_HANDLE) {
- return nullptr;
- }
- hwnd -= FIRST_HANDLE;
- return mHandles[hwnd].exchange(nullptr);
- }
-
- auto HandleManager::setHandle(void *hwnd) noexcept -> int
- {
- for (int h = 0; h < MAX_HANDLES; ++h) {
- void *tst_val = nullptr;
- if (mHandles[h].compare_exchange_strong(tst_val, hwnd)) {
- return h + FIRST_HANDLE;
- }
- }
- return -1;
- }
-} // namespace vfsn::internal::stdlib::impl
D module-vfs/src/newlib/HandleManager.hpp => module-vfs/src/newlib/HandleManager.hpp +0 -64
@@ 1,64 0,0 @@
-// Copyright (c) 2017-2020, Mudita Sp. z.o.o. All rights reserved.
-// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md
-
-#pragma once
-#include <cstdint>
-#include <array>
-#include <atomic>
-namespace vfsn::internal::stdlib
-{
- // Generic handle manager standard syscalls
- namespace impl
- {
- class HandleManager
- {
- /* Number of simultaneously open files by the
- * stdio library
- */
- static constexpr auto MAX_HANDLES = 128;
- /*
- * According to the POSIX standard handle no 0 is reserved for standard input
- * stream (STDIN_FILENO),
- * handle no 1 is reserved for standard output stream (STDOUT_FILENO) ,
- * handle no 2 is reserved for standard error output stream (STDERR_FILENO),
- * so the first allowed file descriptor returned by open should be 3 or greater.
- */
- static constexpr auto FIRST_HANDLE = 3;
-
- protected:
- /*
- * Atomically remove file descriptor from
- * global file descriptor table and return handle
- * which can be released by underlaying library
- */
- auto clearHandle(int hwnd) noexcept -> void *;
- auto setHandle(void *hwnd) noexcept -> int;
- auto get(int handle) const noexcept -> void *
- {
- if (handle < FIRST_HANDLE || handle >= FIRST_HANDLE + MAX_HANDLES)
- return nullptr;
- else
- return mHandles[handle - FIRST_HANDLE].load();
- }
-
- private:
- std::array<std::atomic<void *>, MAX_HANDLES> mHandles;
- };
- } // namespace impl
- template <typename T> class HandleManager : public impl::HandleManager
- {
- public:
- auto setHandle(T *hwnd) noexcept
- {
- return impl::HandleManager::setHandle(hwnd);
- }
- auto operator[](int handle) const noexcept
- {
- return reinterpret_cast<T *>(impl::HandleManager::get(handle));
- }
- auto clearHandle(int hwnd)
- {
- return reinterpret_cast<T *>(impl::HandleManager::clearHandle(hwnd));
- }
- };
-} // namespace vfsn::internal::stdlib
D module-vfs/src/newlib/vfs_internal_dirent.cpp => module-vfs/src/newlib/vfs_internal_dirent.cpp +0 -30
@@ 1,30 0,0 @@
-// Copyright (c) 2017-2020, Mudita Sp. z.o.o. All rights reserved.
-// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md
-#include "vfs_internal_dirent.hpp"
-#include <cstring>
-#include <errno.h>
-#include <new>
-#include <dirent.h>
-
-namespace vfsn::internal::dirent
-{
- DIR_ITER *diropen(int &_errno_, const char *path)
- {
- return nullptr;
- }
-
- int dirreset(int &_errno_, DIR_ITER *state)
- {
- return -1;
- }
- int dirnext(int &_errno_, DIR_ITER *state)
- {
- return -1;
- }
-
- int dirclose(int &_errno_, DIR_ITER *state)
- {
- return -1;
- }
-
-} // namespace vfsn::internal::dirent
D module-vfs/src/newlib/vfs_internal_dirent.hpp => module-vfs/src/newlib/vfs_internal_dirent.hpp +0 -13
@@ 1,13 0,0 @@
-// Copyright (c) 2017-2020, Mudita Sp. z.o.o. All rights reserved.
-// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md
-#pragma once
-
-#include <dirent.h>
-
-namespace vfsn::internal::dirent
-{
- DIR_ITER *diropen(int &_errno_, const char *path);
- int dirreset(int &_errno_, DIR_ITER *state);
- int dirnext(int &_errno_, DIR_ITER *state);
- int dirclose(int &_errno_, DIR_ITER *state);
-} // namespace vfsn::internal::dirent
M module-vfs/src/newlib/vfs_io_syscalls.cpp => module-vfs/src/newlib/vfs_io_syscalls.cpp +245 -28
@@ 1,129 1,346 @@
// Copyright (c) 2017-2020, Mudita Sp. z.o.o. All rights reserved.
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md
+
#include <errno.h>
#include <dirent.h>
-#include <log/log.hpp>
#include <fcntl.h>
-#include <cstring>
#include <unistd.h>
-#include "vfs_internal_dirent.hpp"
-#include "HandleManager.hpp"
-#include <newlib/vfs_io_syscalls.hpp>
+#include <cstring>
#include <sys/statvfs.h>
+#include <purefs/vfs_subsystem.hpp>
+#include <newlib/vfs_io_syscalls.hpp>
+
+struct __dirstream
+{
+ purefs::fs::filesystem::fsdir dirh;
+ size_t position;
+ struct dirent dir_data;
+};
+
+namespace
+{
+ template <class Base, typename T, typename... Args>
+ auto invoke_fs(int &error, T Base::*lfs_fun, Args &&... args)
+ -> decltype((static_cast<Base *>(nullptr)->*lfs_fun)(std::forward<Args>(args)...))
+ {
+ auto vfs = purefs::subsystem::vfs_core();
+ if (!vfs) {
+ error = EIO;
+ return -1;
+ }
+ auto ret = (vfs.get()->*lfs_fun)(std::forward<Args>(args)...);
+ if (ret < 0) {
+ error = -ret;
+ ret = -1;
+ }
+ return ret;
+ }
+} // namespace
namespace vfsn::internal::syscalls
{
int open(int &_errno_, const char *file, int flags, int mode)
{
- return -1;
+ return invoke_fs(_errno_, &purefs::fs::filesystem::open, file, flags, mode);
}
long close(int &_errno_, int fd)
{
- return -1;
+ return invoke_fs(_errno_, &purefs::fs::filesystem::close, fd);
}
long write(int &_errno_, int fd, const void *buf, size_t cnt)
{
- return -1;
+ return invoke_fs(_errno_, &purefs::fs::filesystem::write, fd, reinterpret_cast<const char *>(buf), cnt);
}
long read(int &_errno_, int fd, void *buf, size_t cnt)
{
- return -1;
+ return invoke_fs(_errno_, &purefs::fs::filesystem::read, fd, reinterpret_cast<char *>(buf), cnt);
}
off_t lseek(int &_errno_, int fd, off_t pos, int dir)
{
- return -1;
+ return invoke_fs(_errno_, &purefs::fs::filesystem::seek, fd, pos, dir);
}
+
int fstat(int &_errno_, int fd, struct stat *pstat)
{
- return -1;
+ if (pstat) {
+ return invoke_fs(_errno_, &purefs::fs::filesystem::fstat, fd, *pstat);
+ }
+ else {
+ _errno_ = EINVAL;
+ return -1;
+ }
}
+
int link(int &_errno_, const char *existing, const char *newLink)
{
- return -1;
+ return invoke_fs(_errno_, &purefs::fs::filesystem::link, existing, newLink);
}
+
int unlink(int &_errno_, const char *name)
{
- return -1;
+ return invoke_fs(_errno_, &purefs::fs::filesystem::unlink, name);
}
int fcntl(int &_errno_, int fd, int cmd, int arg)
{
+ _errno_ = ENOTSUP;
return -1;
}
+
int stat(int &_errno_, const char *file, struct stat *pstat)
{
- return -1;
+ if (pstat) {
+ return invoke_fs(_errno_, &purefs::fs::filesystem::stat, file, *pstat);
+ }
+ else {
+ _errno_ = EINVAL;
+ return -1;
+ }
}
int chdir(int &_errno_, const char *path)
{
- return -1;
+ return invoke_fs(_errno_, &purefs::fs::filesystem::chdir, path);
}
+
char *getcwd(int &_errno_, char *buf, size_t size)
{
- return nullptr;
+ if (!buf) {
+ _errno_ = EINVAL;
+ return nullptr;
+ }
+ auto vfs = purefs::subsystem::vfs_core();
+ if (!vfs) {
+ _errno_ = EIO;
+ return nullptr;
+ }
+ const auto ret = vfs->getcwd();
+ const auto slen = ret.copy(buf, size);
+ if (size < slen) {
+ buf[slen] = '\0';
+ }
+ return buf;
}
+
int rename(int &_errno_, const char *oldName, const char *newName)
{
- return -1;
+ return invoke_fs(_errno_, &purefs::fs::filesystem::rename, oldName, newName);
}
int mkdir(int &_errno_, const char *path, uint32_t mode)
{
- return -1;
+ return invoke_fs(_errno_, &purefs::fs::filesystem::mkdir, path, mode);
}
DIR *opendir(int &_errno_, const char *dirname)
{
- return nullptr;
+ __dirstream *ret{};
+ if (!dirname) {
+ _errno_ = EIO;
+ return ret;
+ }
+ auto vfs = purefs::subsystem::vfs_core();
+ if (!vfs) {
+ _errno_ = EIO;
+ return ret;
+ }
+ ret = new (std::nothrow) __dirstream;
+ if (!ret) {
+ _errno_ = ENOMEM;
+ return ret;
+ }
+ ret->position = 0;
+ ret->dirh = vfs->diropen(dirname);
+ if (!ret->dirh) {
+ delete ret;
+ _errno_ = EIO;
+ ret = nullptr;
+ }
+ else if (ret->dirh->error()) {
+ _errno_ = -ret->dirh->error();
+ delete ret;
+ ret = nullptr;
+ }
+ return ret;
}
int closedir(int &_errno_, DIR *dirp)
{
- return -1;
+ if (!dirp) {
+ _errno_ = EBADF;
+ return -1;
+ }
+ auto vfs = purefs::subsystem::vfs_core();
+ if (!vfs) {
+ _errno_ = EIO;
+ return -1;
+ }
+ auto ret = vfs->dirclose(dirp->dirh);
+ if (ret < 0) {
+ _errno_ = -ret;
+ ret = -1;
+ }
+ delete dirp;
+ return ret;
}
struct dirent *readdir(int &_errno_, DIR *dirp)
{
- return nullptr;
+ if (!dirp) {
+ _errno_ = EBADF;
+ return nullptr;
+ }
+ auto vfs = purefs::subsystem::vfs_core();
+ if (!vfs) {
+ _errno_ = EIO;
+ return nullptr;
+ }
+ std::string fname;
+ struct stat stdata;
+ auto ret = vfs->dirnext(dirp->dirh, fname, stdata);
+ if (ret < 0) {
+ if (ret != -ENODATA) {
+ _errno_ = -ret;
+ }
+ return nullptr;
+ }
+ else {
+ if (fname.size() >= sizeof(dirp->dir_data.d_name)) {
+ _errno_ = EOVERFLOW;
+ return nullptr;
+ }
+ dirp->position += 1;
+ dirp->dir_data.d_ino = stdata.st_ino;
+ dirp->dir_data.d_type = S_ISREG(stdata.st_mode) ? DT_REG : DT_DIR;
+ dirp->dir_data.d_reclen = fname.size();
+ std::strncpy(dirp->dir_data.d_name, fname.c_str(), sizeof(dirp->dir_data.d_name));
+ return &dirp->dir_data;
+ }
}
int readdir_r(int &_errno_, DIR *dirp, struct dirent *entry, struct dirent **result)
{
- return -1;
+ if (!dirp) {
+ _errno_ = EBADF;
+ return -1;
+ }
+ if (!*result) {
+ _errno_ = EINVAL;
+ return -1;
+ }
+ auto vfs = purefs::subsystem::vfs_core();
+ if (!vfs) {
+ _errno_ = EIO;
+ return -1;
+ }
+ std::string fname;
+ struct stat stdata;
+ auto ret = vfs->dirnext(dirp->dirh, fname, stdata);
+ if (ret == -ENODATA) {
+ *result = nullptr;
+ return 0;
+ }
+ else if (ret < 0) {
+ _errno_ = -ret;
+ return -1;
+ }
+ else {
+ if (fname.size() >= sizeof(dirp->dir_data.d_name)) {
+ _errno_ = EOVERFLOW;
+ return -1;
+ }
+ dirp->position += 1;
+ entry->d_ino = stdata.st_ino;
+ entry->d_type = S_ISREG(stdata.st_mode) ? DT_REG : DT_DIR;
+ entry->d_reclen = fname.size();
+ std::strncpy(entry->d_name, fname.c_str(), sizeof(entry->d_name));
+ *result = entry;
+ return 0;
+ }
}
void rewinddir(int &_errno_, DIR *dirp)
{
+ if (!dirp) {
+ _errno_ = EBADF;
+ return;
+ }
+ auto vfs = purefs::subsystem::vfs_core();
+ if (!vfs) {
+ _errno_ = EIO;
+ return;
+ }
+ auto res = vfs->dirreset(dirp->dirh);
+ if (res < 0) {
+ _errno_ = -res;
+ return;
+ }
+ dirp->position = 0;
}
void seekdir(int &_errno_, DIR *dirp, long int loc)
{
+ if (!dirp) {
+ _errno_ = EBADF;
+ return;
+ }
+ if (loc < 0) {
+ _errno_ = EINVAL;
+ return;
+ }
+ auto vfs = purefs::subsystem::vfs_core();
+ if (!vfs) {
+ _errno_ = EIO;
+ return;
+ }
+ if (long(dirp->position) > loc) {
+ vfs->dirreset(dirp->dirh);
+ dirp->position = 0;
+ }
+ std::string name;
+ struct stat st;
+ while ((long(dirp->position) < loc) && (vfs->dirnext(dirp->dirh, name, st)) >= 0) {
+ dirp->position += 1;
+ }
}
+
long int telldir(int &_errno_, DIR *dirp)
{
- return -1;
+ if (!dirp) {
+ _errno_ = EBADF;
+ return -1;
+ }
+ return dirp->position;
}
int chmod(int &_errno_, const char *path, mode_t mode)
{
- return -1;
+ return invoke_fs(_errno_, &purefs::fs::filesystem::chmod, path, mode);
}
+
int fchmod(int &_errno_, int fd, mode_t mode)
{
- return -1;
+ return invoke_fs(_errno_, &purefs::fs::filesystem::fchmod, fd, mode);
}
+
int fsync(int &_errno_, int fd)
{
- return -1;
+ return invoke_fs(_errno_, &purefs::fs::filesystem::fsync, fd);
}
- int statvfs(const char *path, struct statvfs *buf)
+
+ int statvfs(int &_errno_, const char *path, struct statvfs *buf)
{
- return -1;
+ if (!buf) {
+ _errno_ = EINVAL;
+ return -1;
+ }
+ else {
+ return invoke_fs(_errno_, &purefs::fs::filesystem::stat_vfs, path, *buf);
+ }
}
} // namespace vfsn::internal::syscalls
M module-vfs/targets/Target_RT1051.cmake => module-vfs/targets/Target_RT1051.cmake +0 -2
@@ 1,7 1,5 @@
set(BOARD_SOURCES ${BOARD_SOURCES}
src/newlib/vfs_io_syscalls.cpp
- src/newlib/vfs_internal_dirent.cpp
- src/newlib/HandleManager.cpp
board/rt1051/purefs/src/fs/thread_local_cwd.cpp
board/rt1051/purefs/src/vfs_subsystem_internal.cpp
CACHE INTERNAL ""