Skip to content
Snippets Groups Projects
Commit a1faeb9c authored by Joakim Nohlgård's avatar Joakim Nohlgård
Browse files

newlib: Use vfs for file I/O syscalls

parent dcc37329
No related branches found
No related tags found
No related merge requests found
...@@ -39,6 +39,9 @@ ...@@ -39,6 +39,9 @@
#include "irq.h" #include "irq.h"
#include "log.h" #include "log.h"
#include "periph/pm.h" #include "periph/pm.h"
#if MODULE_VFS
#include "vfs.h"
#endif
#include "uart_stdio.h" #include "uart_stdio.h"
...@@ -152,137 +155,307 @@ int _kill_r(struct _reent *r, pid_t pid, int sig) ...@@ -152,137 +155,307 @@ int _kill_r(struct _reent *r, pid_t pid, int sig)
return -1; return -1;
} }
#if MODULE_VFS
/** /**
* @brief Open a file * @brief Open a file
* *
* @param r TODO * This is a wrapper around @c vfs_open
* @param name TODO
* @param mode TODO
* *
* @return TODO * @param r pointer to reent structure
* @param name file name to open
* @param flags flags, see man 3p open
* @param mode mode, file creation mode if the file is created when opening
*
* @return fd number (>= 0) on success
* @return -1 on error, @c r->_errno set to a constant from errno.h to indicate the error
*/ */
int _open_r(struct _reent *r, const char *name, int flags, int mode) int _open_r(struct _reent *r, const char *name, int flags, int mode)
{ {
(void) name; int fd = vfs_open(name, flags, mode);
(void) flags; if (fd < 0) {
(void) mode; /* vfs returns negative error codes */
r->_errno = ENODEV; /* not implemented yet */ r->_errno = -fd;
return -1; return -1;
}
return fd;
} }
/** /**
* @brief Read from a file * @brief Read bytes from an open file
* *
* All input is read from UART_0. The function will block until a byte is actually read. * This is a wrapper around @c vfs_read
* *
* Note: the read function does not buffer - data will be lost if the function is not * @param[in] r pointer to reent structure
* called fast enough. * @param[in] fd open file descriptor obtained from @c open()
* @param[out] dest destination buffer
* @param[in] count maximum number of bytes to read
* *
* TODO: implement more sophisticated read call. * @return number of bytes read on success
* @return -1 on error, @c r->_errno set to a constant from errno.h to indicate the error
*/
_ssize_t _read_r(struct _reent *r, int fd, void *dest, size_t count)
{
int res = vfs_read(fd, dest, count);
if (res < 0) {
/* vfs returns negative error codes */
r->_errno = -res;
return -1;
}
return res;
}
/**
* @brief Write bytes to an open file
* *
* @param r TODO * This is a wrapper around @c vfs_write
* @param fd TODO
* @param buffer TODO
* @param int TODO
* *
* @return TODO * @param[in] r pointer to reent structure
* @param[in] fd open file descriptor obtained from @c open()
* @param[in] src source data buffer
* @param[in] count maximum number of bytes to write
*
* @return number of bytes written on success
* @return -1 on error, @c r->_errno set to a constant from errno.h to indicate the error
*/ */
_ssize_t _read_r(struct _reent *r, int fd, void *buffer, size_t count) _ssize_t _write_r(struct _reent *r, int fd, const void *src, size_t count)
{ {
(void)r; int res = vfs_write(fd, src, count);
(void)fd; if (res < 0) {
return uart_stdio_read(buffer, count); /* vfs returns negative error codes */
r->_errno = -res;
return -1;
}
return res;
} }
/** /**
* @brief Write characters to a file * @brief Close an open file
* *
* All output is currently directed to UART_0, independent of the given file descriptor. * This is a wrapper around @c vfs_close
* The write call will further block until the byte is actually written to the UART.
* *
* TODO: implement more sophisticated write call. * If this call returns an error, the fd should still be considered invalid and
* no further attempt to use it shall be made, not even to retry @c close()
* *
* @param r TODO * @param[in] r pointer to reent structure
* @param fd TODO * @param[in] fd open file descriptor obtained from @c open()
* @param data TODO
* @param int TODO
* *
* @return TODO * @return 0 on success
* @return -1 on error, @c r->_errno set to a constant from errno.h to indicate the error
*/ */
_ssize_t _write_r(struct _reent *r, int fd, const void *data, size_t count) int _close_r(struct _reent *r, int fd)
{ {
(void) r; int res = vfs_close(fd);
(void) fd; if (res < 0) {
return uart_stdio_write(data, count); /* vfs returns negative error codes */
r->_errno = -res;
return -1;
}
return res;
} }
/** /**
* @brief Close a file * @brief Query or set options on an open file
* *
* @param r TODO * This is a wrapper around @c vfs_fcntl
* @param fd TODO
* *
* @return TODO * @param[in] r pointer to reent structure
* @param[in] fd open file descriptor obtained from @c open()
* @param[in] cmd fcntl command, see man 3p fcntl
* @param[in] arg argument to fcntl command, see man 3p fcntl
*
* @return 0 on success
* @return -1 on error, @c r->_errno set to a constant from errno.h to indicate the error
*/ */
int _close_r(struct _reent *r, int fd) int _fcntl_r (struct _reent *r, int fd, int cmd, int arg)
{ {
(void) fd; int res = vfs_fcntl(fd, cmd, arg);
r->_errno = ENODEV; /* not implemented yet */ if (res < 0) {
return -1; /* vfs returns negative error codes */
r->_errno = -res;
return -1;
}
return res;
} }
/** /**
* @brief Set position in a file * @brief Seek to position in file
* *
* @param r TODO * This is a wrapper around @c vfs_lseek
* @param fd TODO
* @param pos TODO
* @param dir TODO
* *
* @return TODO * @p whence determines the function of the seek and should be set to one of
* the following values:
*
* - @c SEEK_SET: Seek to absolute offset @p off
* - @c SEEK_CUR: Seek to current location + @p off
* - @c SEEK_END: Seek to end of file + @p off
*
* @param[in] r pointer to reent structure
* @param[in] fd open file descriptor obtained from @c open()
* @param[in] off seek offset
* @param[in] whence determines the seek method, see detailed description
*
* @return the new seek location in the file on success
* @return -1 on error, @c r->_errno set to a constant from errno.h to indicate the error
*/ */
_off_t _lseek_r(struct _reent *r, int fd, _off_t pos, int dir) _off_t _lseek_r(struct _reent *r, int fd, _off_t off, int whence)
{ {
(void) fd; int res = vfs_lseek(fd, off, whence);
(void) pos; if (res < 0) {
(void) dir; /* vfs returns negative error codes */
r->_errno = ENODEV; /* not implemented yet */ r->_errno = -res;
return -1; return -1;
}
return res;
} }
/** /**
* @brief Status of an open file * @brief Get status of an open file
* *
* @param r TODO * This is a wrapper around @c vfs_fstat
* @param fd TODO
* @param stat TODO
* *
* @return TODO * @param[in] r pointer to reent structure
* @param[in] fd open file descriptor obtained from @c open()
* @param[out] buf pointer to stat struct to fill
*
* @return 0 on success
* @return -1 on error, @c r->_errno set to a constant from errno.h to indicate the error
*/ */
int _fstat_r(struct _reent *r, int fd, struct stat *st) int _fstat_r(struct _reent *r, int fd, struct stat *buf)
{ {
(void) fd; int res = vfs_fstat(fd, buf);
(void) st; if (res < 0) {
r->_errno = ENODEV; /* not implemented yet */ /* vfs returns negative error codes */
return -1; r->_errno = -res;
return -1;
}
return 0;
} }
/** /**
* @brief Status of a file (by name) * @brief Status of a file (by name)
* *
* @param r TODO * This is a wrapper around @c vfs_fstat
* @param name TODO
* @param stat TODO
* *
* @return TODO * @param[in] r pointer to reent structure
* @param[in] name path to file
* @param[out] buf pointer to stat struct to fill
*
* @return 0 on success
* @return -1 on error, @c r->_errno set to a constant from errno.h to indicate the error
*/
int _stat_r(struct _reent *r, const char *name, struct stat *st)
{
int res = vfs_stat(name, st);
if (res < 0) {
/* vfs returns negative error codes */
r->_errno = -res;
return -1;
}
return 0;
}
/**
* @brief Unlink (delete) a file
*
* @param[in] r pointer to reent structure
* @param[in] path path to file to be deleted
*
* @return 0 on success
* @return -1 on error, @c r->_errno set to a constant from errno.h to indicate the error
*/ */
int _unlink_r(struct _reent *r, const char *path)
{
int res = vfs_unlink(path);
if (res < 0) {
/* vfs returns negative error codes */
r->_errno = -res;
return -1;
}
return 0;
}
#else /* MODULE_VFS */
/* Fallback stdio_uart wrappers for when VFS is not used, does not allow any
* other file access */
/*
* Fallback read function
*
* All input is read from uart_stdio regardless of fd number. The function will
* block until a byte is actually read.
*
* Note: the read function does not buffer - data will be lost if the function is not
* called fast enough.
*/
_ssize_t _read_r(struct _reent *r, int fd, void *buffer, size_t count)
{
(void)r;
(void)fd;
return uart_stdio_read(buffer, count);
}
/*
* Fallback write function
*
* All output is directed to uart_stdio, independent of the given file descriptor.
* The write call will further block until the byte is actually written to the UART.
*/
_ssize_t _write_r(struct _reent *r, int fd, const void *data, size_t count)
{
(void) r;
(void) fd;
return uart_stdio_write(data, count);
}
/* Stubs to avoid linking errors, these functions do not have any effect */
int _open_r(struct _reent *r, const char *name, int flags, int mode)
{
(void) name;
(void) flags;
(void) mode;
r->_errno = ENODEV;
return -1;
}
int _close_r(struct _reent *r, int fd)
{
(void) fd;
r->_errno = ENODEV;
return -1;
}
_off_t _lseek_r(struct _reent *r, int fd, _off_t pos, int dir)
{
(void) fd;
(void) pos;
(void) dir;
r->_errno = ENODEV;
return -1;
}
int _fstat_r(struct _reent *r, int fd, struct stat *st)
{
(void) fd;
(void) st;
r->_errno = ENODEV;
return -1;
}
int _stat_r(struct _reent *r, const char *name, struct stat *st) int _stat_r(struct _reent *r, const char *name, struct stat *st)
{ {
(void) name; (void) name;
(void) st; (void) st;
r->_errno = ENODEV; /* not implemented yet */ r->_errno = ENODEV;
return -1;
}
int _unlink_r(struct _reent *r, const char *path)
{
(void) path;
r->_errno = ENODEV;
return -1; return -1;
} }
#endif /* MODULE_VFS */
/** /**
* @brief Query whether output stream is a terminal * @brief Query whether output stream is a terminal
...@@ -303,21 +476,6 @@ int _isatty_r(struct _reent *r, int fd) ...@@ -303,21 +476,6 @@ int _isatty_r(struct _reent *r, int fd)
return 0; return 0;
} }
/**
* @brief Remove a file's directory entry
*
* @param r TODO
* @param path TODO
*
* @return TODO
*/
int _unlink_r(struct _reent *r, const char *path)
{
(void) path;
r->_errno = ENODEV; /* not implemented yet */
return -1;
}
/** /**
* @brief Send a signal to a thread * @brief Send a signal to a thread
* *
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment