newlib: Use vfs for file I/O syscalls
This commit is contained in:
parent
dcc37329df
commit
a1faeb9ca1
|
@ -39,6 +39,9 @@
|
|||
#include "irq.h"
|
||||
#include "log.h"
|
||||
#include "periph/pm.h"
|
||||
#if MODULE_VFS
|
||||
#include "vfs.h"
|
||||
#endif
|
||||
|
||||
#include "uart_stdio.h"
|
||||
|
||||
|
@ -152,40 +155,237 @@ int _kill_r(struct _reent *r, pid_t pid, int sig)
|
|||
return -1;
|
||||
}
|
||||
|
||||
#if MODULE_VFS
|
||||
/**
|
||||
* @brief Open a file
|
||||
*
|
||||
* @param r TODO
|
||||
* @param name TODO
|
||||
* @param mode TODO
|
||||
* This is a wrapper around @c vfs_open
|
||||
*
|
||||
* @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)
|
||||
{
|
||||
(void) name;
|
||||
(void) flags;
|
||||
(void) mode;
|
||||
r->_errno = ENODEV; /* not implemented yet */
|
||||
return -1;
|
||||
int fd = vfs_open(name, flags, mode);
|
||||
if (fd < 0) {
|
||||
/* vfs returns negative error codes */
|
||||
r->_errno = -fd;
|
||||
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
|
||||
*
|
||||
* @param[in] r pointer to reent structure
|
||||
* @param[in] fd open file descriptor obtained from @c open()
|
||||
* @param[out] dest destination buffer
|
||||
* @param[in] count maximum number of bytes to read
|
||||
*
|
||||
* @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
|
||||
*
|
||||
* This is a wrapper around @c vfs_write
|
||||
*
|
||||
* @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 _write_r(struct _reent *r, int fd, const void *src, size_t count)
|
||||
{
|
||||
int res = vfs_write(fd, src, count);
|
||||
if (res < 0) {
|
||||
/* vfs returns negative error codes */
|
||||
r->_errno = -res;
|
||||
return -1;
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Close an open file
|
||||
*
|
||||
* This is a wrapper around @c vfs_close
|
||||
*
|
||||
* 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[in] r pointer to reent structure
|
||||
* @param[in] fd open file descriptor obtained from @c open()
|
||||
*
|
||||
* @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 res = vfs_close(fd);
|
||||
if (res < 0) {
|
||||
/* vfs returns negative error codes */
|
||||
r->_errno = -res;
|
||||
return -1;
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Query or set options on an open file
|
||||
*
|
||||
* This is a wrapper around @c vfs_fcntl
|
||||
*
|
||||
* @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 _fcntl_r (struct _reent *r, int fd, int cmd, int arg)
|
||||
{
|
||||
int res = vfs_fcntl(fd, cmd, arg);
|
||||
if (res < 0) {
|
||||
/* vfs returns negative error codes */
|
||||
r->_errno = -res;
|
||||
return -1;
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Seek to position in file
|
||||
*
|
||||
* This is a wrapper around @c vfs_lseek
|
||||
*
|
||||
* @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 off, int whence)
|
||||
{
|
||||
int res = vfs_lseek(fd, off, whence);
|
||||
if (res < 0) {
|
||||
/* vfs returns negative error codes */
|
||||
r->_errno = -res;
|
||||
return -1;
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get status of an open file
|
||||
*
|
||||
* This is a wrapper around @c vfs_fstat
|
||||
*
|
||||
* @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 *buf)
|
||||
{
|
||||
int res = vfs_fstat(fd, buf);
|
||||
if (res < 0) {
|
||||
/* vfs returns negative error codes */
|
||||
r->_errno = -res;
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Status of a file (by name)
|
||||
*
|
||||
* This is a wrapper around @c vfs_fstat
|
||||
*
|
||||
* @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.
|
||||
*
|
||||
* TODO: implement more sophisticated read call.
|
||||
*
|
||||
* @param r TODO
|
||||
* @param fd TODO
|
||||
* @param buffer TODO
|
||||
* @param int TODO
|
||||
*
|
||||
* @return TODO
|
||||
*/
|
||||
_ssize_t _read_r(struct _reent *r, int fd, void *buffer, size_t count)
|
||||
{
|
||||
|
@ -194,20 +394,11 @@ _ssize_t _read_r(struct _reent *r, int fd, void *buffer, size_t count)
|
|||
return uart_stdio_read(buffer, count);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Write characters to a file
|
||||
/*
|
||||
* Fallback write function
|
||||
*
|
||||
* All output is currently directed to UART_0, independent of the given file descriptor.
|
||||
* 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.
|
||||
*
|
||||
* TODO: implement more sophisticated write call.
|
||||
*
|
||||
* @param r TODO
|
||||
* @param fd TODO
|
||||
* @param data TODO
|
||||
* @param int TODO
|
||||
*
|
||||
* @return TODO
|
||||
*/
|
||||
_ssize_t _write_r(struct _reent *r, int fd, const void *data, size_t count)
|
||||
{
|
||||
|
@ -216,74 +407,56 @@ _ssize_t _write_r(struct _reent *r, int fd, const void *data, size_t count)
|
|||
return uart_stdio_write(data, count);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Close a file
|
||||
*
|
||||
* @param r TODO
|
||||
* @param fd TODO
|
||||
*
|
||||
* @return TODO
|
||||
*/
|
||||
int _close_r(struct _reent *r, int fd)
|
||||
/* 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) fd;
|
||||
r->_errno = ENODEV; /* not implemented yet */
|
||||
(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;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set position in a file
|
||||
*
|
||||
* @param r TODO
|
||||
* @param fd TODO
|
||||
* @param pos TODO
|
||||
* @param dir TODO
|
||||
*
|
||||
* @return TODO
|
||||
*/
|
||||
_off_t _lseek_r(struct _reent *r, int fd, _off_t pos, int dir)
|
||||
{
|
||||
(void) fd;
|
||||
(void) pos;
|
||||
(void) dir;
|
||||
r->_errno = ENODEV; /* not implemented yet */
|
||||
r->_errno = ENODEV;
|
||||
return -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Status of an open file
|
||||
*
|
||||
* @param r TODO
|
||||
* @param fd TODO
|
||||
* @param stat TODO
|
||||
*
|
||||
* @return TODO
|
||||
*/
|
||||
int _fstat_r(struct _reent *r, int fd, struct stat *st)
|
||||
{
|
||||
(void) fd;
|
||||
(void) st;
|
||||
r->_errno = ENODEV; /* not implemented yet */
|
||||
r->_errno = ENODEV;
|
||||
return -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Status of a file (by name)
|
||||
*
|
||||
* @param r TODO
|
||||
* @param name TODO
|
||||
* @param stat TODO
|
||||
*
|
||||
* @return TODO
|
||||
*/
|
||||
int _stat_r(struct _reent *r, const char *name, struct stat *st)
|
||||
{
|
||||
(void) name;
|
||||
(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;
|
||||
}
|
||||
#endif /* MODULE_VFS */
|
||||
|
||||
/**
|
||||
* @brief Query whether output stream is a terminal
|
||||
*
|
||||
|
@ -303,21 +476,6 @@ int _isatty_r(struct _reent *r, int fd)
|
|||
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
|
||||
*
|
||||
|
|
Loading…
Reference in New Issue