From eb00ca816f642fa48c0fff2e32cce54a49f04987 Mon Sep 17 00:00:00 2001 From: Benjamin Valentin Date: Mon, 24 Aug 2020 23:53:10 +0200 Subject: [PATCH 1/2] picolibc: enable read/write etc. functions without VFS The read()/write() functions still work without VFS when reading/writing to stdin, stdout or stderr. Provide dummy functions for the remaining fs functions so linking does not fail with !VFS. --- sys/picolibc_syscalls_default/syscalls.c | 80 ++++++++++++++++++++++-- 1 file changed, 75 insertions(+), 5 deletions(-) diff --git a/sys/picolibc_syscalls_default/syscalls.c b/sys/picolibc_syscalls_default/syscalls.c index 1782610d08..a54397d2bf 100644 --- a/sys/picolibc_syscalls_default/syscalls.c +++ b/sys/picolibc_syscalls_default/syscalls.c @@ -23,6 +23,7 @@ #include #include #include +#include #include "log.h" #include "periph/pm.h" @@ -55,8 +56,8 @@ _exit(int n) __attribute__ ((weak)) int kill(pid_t pid, int sig) { - (void) pid; - (void) sig; + (void)pid; + (void)sig; errno = ESRCH; /* not implemented yet */ return -1; } @@ -129,6 +130,9 @@ pid_t getpid(void) #if MODULE_VFS #include "vfs.h" +#else +#include +#endif /** * @brief Open a file @@ -144,6 +148,7 @@ pid_t getpid(void) */ int open(const char *name, int flags, int mode) { +#ifdef MODULE_VFS int fd = vfs_open(name, flags, mode); if (fd < 0) { /* vfs returns negative error codes */ @@ -151,6 +156,13 @@ int open(const char *name, int flags, int mode) return -1; } return fd; +#else + (void)name; + (void)flags; + (void)mode; + errno = ENODEV; + return -1; +#endif } /** @@ -167,6 +179,7 @@ int open(const char *name, int flags, int mode) */ _READ_WRITE_RETURN_TYPE read(int fd, void *dest, size_t count) { +#ifdef MODULE_VFS int res = vfs_read(fd, dest, count); if (res < 0) { /* vfs returns negative error codes */ @@ -174,6 +187,14 @@ _READ_WRITE_RETURN_TYPE read(int fd, void *dest, size_t count) return -1; } return res; +#else + if (fd != STDIN_FILENO) { + errno = ENOTSUP; + return -1; + } + + return stdio_read(dest, count); +#endif } /** @@ -190,6 +211,7 @@ _READ_WRITE_RETURN_TYPE read(int fd, void *dest, size_t count) */ _READ_WRITE_RETURN_TYPE write(int fd, const void *src, size_t count) { +#ifdef MODULE_VFS int res = vfs_write(fd, src, count); if (res < 0) { /* vfs returns negative error codes */ @@ -197,6 +219,14 @@ _READ_WRITE_RETURN_TYPE write(int fd, const void *src, size_t count) return -1; } return res; +#else + if (fd != STDOUT_FILENO && fd != STDERR_FILENO) { + errno = ENOTSUP; + return -1; + } + + return stdio_write(src, count); +#endif } /** @@ -214,6 +244,7 @@ _READ_WRITE_RETURN_TYPE write(int fd, const void *src, size_t count) */ int close(int fd) { +#ifdef MODULE_VFS int res = vfs_close(fd); if (res < 0) { /* vfs returns negative error codes */ @@ -221,6 +252,11 @@ int close(int fd) return -1; } return res; +#else + (void)fd; + errno = ENOTSUP; + return -1; +#endif } /** @@ -250,8 +286,9 @@ clock_t times(struct tms *ptms) * @return 0 on success * @return -1 on error, @c errno set to a constant from errno.h to indicate the error */ -int fcntl (int fd, int cmd, int arg) +int fcntl(int fd, int cmd, int arg) { +#ifdef MODULE_VFS int res = vfs_fcntl(fd, cmd, arg); if (res < 0) { /* vfs returns negative error codes */ @@ -259,6 +296,13 @@ int fcntl (int fd, int cmd, int arg) return -1; } return res; +#else + (void)fd; + (void)cmd; + (void)arg; + errno = ENOTSUP; + return -1; +#endif } /** @@ -282,6 +326,7 @@ int fcntl (int fd, int cmd, int arg) */ off_t lseek(int fd, _off_t off, int whence) { +#ifdef MODULE_VFS int res = vfs_lseek(fd, off, whence); if (res < 0) { /* vfs returns negative error codes */ @@ -289,6 +334,13 @@ off_t lseek(int fd, _off_t off, int whence) return -1; } return res; +#else + (void)fd; + (void)off; + (void)whence; + errno = ENOTSUP; + return -1; +#endif } /** @@ -304,6 +356,7 @@ off_t lseek(int fd, _off_t off, int whence) */ int fstat(int fd, struct stat *buf) { +#ifdef MODULE_VFS int res = vfs_fstat(fd, buf); if (res < 0) { /* vfs returns negative error codes */ @@ -311,6 +364,12 @@ int fstat(int fd, struct stat *buf) return -1; } return 0; +#else + (void)fd; + (void)buf; + errno = ENOTSUP; + return -1; +#endif } /** @@ -326,6 +385,7 @@ int fstat(int fd, struct stat *buf) */ int stat(const char *name, struct stat *st) { +#ifdef MODULE_VFS int res = vfs_stat(name, st); if (res < 0) { /* vfs returns negative error codes */ @@ -333,6 +393,12 @@ int stat(const char *name, struct stat *st) return -1; } return 0; +#else + (void)name; + (void)st; + errno = ENODEV; + return -1; +#endif } /** @@ -345,6 +411,7 @@ int stat(const char *name, struct stat *st) */ int unlink(const char *path) { +#ifdef MODULE_VFS int res = vfs_unlink(path); if (res < 0) { /* vfs returns negative error codes */ @@ -352,6 +419,9 @@ int unlink(const char *path) return -1; } return 0; +#else + (void)path; + errno = ENODEV; + return -1; +#endif } - -#endif /* MODULE_VFS */ From 3f35564b3679dd19445dde5f4fd392ca8b2e0ade Mon Sep 17 00:00:00 2001 From: Benjamin Valentin Date: Tue, 25 Aug 2020 08:17:20 +0200 Subject: [PATCH 2/2] picolibc: implement rmdir(), remove() & rewind() Those are used by `tests/pkg_fatfs_vfs`. --- sys/picolibc_syscalls_default/syscalls.c | 55 ++++++++++++++++++++++++ 1 file changed, 55 insertions(+) diff --git a/sys/picolibc_syscalls_default/syscalls.c b/sys/picolibc_syscalls_default/syscalls.c index a54397d2bf..9b2e439242 100644 --- a/sys/picolibc_syscalls_default/syscalls.c +++ b/sys/picolibc_syscalls_default/syscalls.c @@ -343,6 +343,16 @@ off_t lseek(int fd, _off_t off, int whence) #endif } +/** + * @brief Sets the file position indicator to the the beginning of the file. + * + * @param[in] stream open file descriptor obtained from @c fopen() + */ +void rewind(FILE *stream) +{ + fseek(stream, 0L, SEEK_SET); +} + /** * @brief Get status of an open file * @@ -425,3 +435,48 @@ int unlink(const char *path) return -1; #endif } + +/** + * @brief Deletes a directory, which must be empty + * + * @param[in] path path to directory to be deleted + * + * @return 0 on success + * @return -1 on error, @c errno set to a constant from errno.h to indicate the error + */ +int rmdir(const char *path) +{ +#ifdef MODULE_VFS + int res = vfs_rmdir(path); + if (res < 0) { + /* vfs returns negative error codes */ + errno = -res; + return -1; + } + return 0; +#else + (void)path; + errno = ENODEV; + return -1; +#endif +} + +/** + * @brief Remove (delete) a file or directory + * + * remove() deletes a name from the filesystem. + * It calls unlink(2) for files, and rmdir(2) for directories. + * + * @param[in] path path to file or directory to be deleted + * + * @return 0 on success + * @return -1 on error, @c errno set to a constant from errno.h to indicate the error + */ +int remove(const char *path) +{ + if (unlink(path) == 0) { + return 0; + } + + return rmdir(path); +}