Browse Source

newlib: Use vfs for file I/O syscalls

pr/rotary
Joakim Nohlgård 7 years ago
parent
commit
a1faeb9ca1
  1. 330
      sys/newlib/syscalls.c

330
sys/newlib/syscalls.c

@ -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,137 +155,307 @@ 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
*
* Note: the read function does not buffer - data will be lost if the function is not
* called fast enough.
* @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
*
* 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
* @param fd TODO
* @param buffer TODO
* @param int TODO
* This is a wrapper around @c vfs_write
*
* @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;
(void)fd;
return uart_stdio_read(buffer, count);
int res = vfs_write(fd, src, count);
if (res < 0) {
/* 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.
* The write call will further block until the byte is actually written to the UART.
* This is a wrapper around @c vfs_close
*
* 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 fd TODO
* @param data TODO
* @param int TODO
* @param[in] r pointer to reent structure
* @param[in] fd open file descriptor obtained from @c open()
*
* @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;
(void) fd;
return uart_stdio_write(data, count);
int res = vfs_close(fd);
if (res < 0) {
/* 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
* @param fd TODO
* This is a wrapper around @c vfs_fcntl
*
* @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;
r->_errno = ENODEV; /* not implemented yet */
return -1;
int res = vfs_fcntl(fd, cmd, arg);
if (res < 0) {
/* 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
* @param fd TODO
* @param pos TODO
* @param dir TODO
* This is a wrapper around @c vfs_lseek
*
* @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;
(void) pos;
(void) dir;
r->_errno = ENODEV; /* not implemented yet */
return -1;
int res = vfs_lseek(fd, off, whence);
if (res < 0) {
/* vfs returns negative error codes */
r->_errno = -res;
return -1;
}
return res;
}
/**
* @brief Status of an open file
* @brief Get status of an open file
*
* @param r TODO
* @param fd TODO
* @param stat TODO
* This is a wrapper around @c vfs_fstat
*
* @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;
(void) st;
r->_errno = ENODEV; /* not implemented yet */
return -1;
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)
*
* @param r TODO
* @param name TODO
* @param stat TODO
* This is a wrapper around @c vfs_fstat
*
* @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)
{
(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…
Cancel
Save