diff options
author | Gregory Nutt <gnutt@nuttx.org> | 2014-10-04 07:31:13 -0600 |
---|---|---|
committer | Gregory Nutt <gnutt@nuttx.org> | 2014-10-04 07:31:13 -0600 |
commit | 3c0867199106a5f0b961693e92cf0355e0db95f8 (patch) | |
tree | f6e97edfcf3d71dcbcc1b03ece9a434df3d60b95 /nuttx/fs/vfs | |
parent | 30ccac4b4397871b553b7cb5ef6c4ee5334664e9 (diff) | |
download | nuttx-3c0867199106a5f0b961693e92cf0355e0db95f8.tar.gz nuttx-3c0867199106a5f0b961693e92cf0355e0db95f8.tar.bz2 nuttx-3c0867199106a5f0b961693e92cf0355e0db95f8.zip |
Add pread() and pwrite()
Diffstat (limited to 'nuttx/fs/vfs')
-rw-r--r-- | nuttx/fs/vfs/Make.defs | 8 | ||||
-rw-r--r-- | nuttx/fs/vfs/fs_pread.c | 129 | ||||
-rw-r--r-- | nuttx/fs/vfs/fs_pwrite.c | 127 | ||||
-rw-r--r-- | nuttx/fs/vfs/fs_read.c | 6 |
4 files changed, 267 insertions, 3 deletions
diff --git a/nuttx/fs/vfs/Make.defs b/nuttx/fs/vfs/Make.defs index 2919b40b5..583aaf070 100644 --- a/nuttx/fs/vfs/Make.defs +++ b/nuttx/fs/vfs/Make.defs @@ -43,6 +43,10 @@ ifneq ($(CONFIG_NSOCKET_DESCRIPTORS),0) CSRCS += fs_close.c fs_read.c fs_write.c fs_ioctl.c fs_poll.c fs_select.c +# Support for positional file access + +CSRCS += fs_pread.c fs_pwrite.c + # Support for network access using streams ifneq ($(CONFIG_NFILE_STREAMS),0) @@ -70,6 +74,10 @@ CSRCS += fs_fsync.c fs_ioctl.c fs_lseek.c fs_mkdir.c fs_open.c fs_poll.c CSRCS += fs_read.c fs_rename.c fs_rmdir.c fs_stat.c fs_statfs.c fs_select.c CSRCS += fs_unlink.c fs_write.c +# Support for positional file access + +CSRCS += fs_pread.c fs_pwrite.c + # Stream support ifneq ($(CONFIG_NFILE_STREAMS),0) diff --git a/nuttx/fs/vfs/fs_pread.c b/nuttx/fs/vfs/fs_pread.c new file mode 100644 index 000000000..621ffa7ff --- /dev/null +++ b/nuttx/fs/vfs/fs_pread.c @@ -0,0 +1,129 @@ +/**************************************************************************** + * fs/vfs/fs_pread.c + * + * Copyright (C) 2014 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt <gnutt@nuttx.org> + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include <nuttx/config.h> + +#include <sys/types.h> +#include <unistd.h> +#include <errno.h> + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: pread + * + * Description: + * The pread() function performs the same action as read(), except that it + * reads from a given position in the file without changing the file + * pointer. The first three arguments to pread() are the same as read() + * with the addition of a fourth argument offset for the desired position + * inside the file. An attempt to perform a pread() on a file that is + * incapable of seeking results in an error. + * + * NOTE: This function could have been wholly implemented within libc but + * it is not. Why? Because if pread were implemented in libc, it would + * require four system calls. If it is implemented within the kernel, + * only three. + * + * Parameters: + * file File structure instance + * buf User-provided to save the data + * nbytes The maximum size of the user-provided buffer + * offset The file offset + * + * Return: + * The positive non-zero number of bytes read on success, 0 on if an + * end-of-file condition, or -1 on failure with errno set appropriately. + * See read() return values + * + ****************************************************************************/ + +ssize_t pread(int fd, FAR void *buf, size_t nbytes, off_t offset) +{ + off_t savepos; + off_t pos; + ssize_t ret; + int errcode; + + /* Perform the lseek to the current position. This will not move the + * file pointer, but will return its current setting + */ + + savepos = lseek(fd, 0, SEEK_CUR); + if (savepos == (off_t)-1) + { + /* lseek might fail if this if the media is not seekable */ + + return ERROR; + } + + /* Then seek to the correct position in the file */ + + pos = lseek(fd, offset, SEEK_CUR); + if (pos == (off_t)-1) + { + /* This might fail is the offset is beyond the end of file */ + + return ERROR; + } + + /* Then perform the read operation */ + + ret = read(fd, buf, nbytes); + errcode = get_errno(); + + /* Restore the file position */ + + pos = lseek(fd, savepos, SEEK_CUR); + if (pos == (off_t)-1 && ret >= 0) + { + /* This really should not fail */ + + return ERROR; + } + + set_errno(errcode); + return ret; +} diff --git a/nuttx/fs/vfs/fs_pwrite.c b/nuttx/fs/vfs/fs_pwrite.c new file mode 100644 index 000000000..a1e6a05d4 --- /dev/null +++ b/nuttx/fs/vfs/fs_pwrite.c @@ -0,0 +1,127 @@ +/**************************************************************************** + * fs/vfs/fs_pwrite.c + * + * Copyright (C) 2014 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt <gnutt@nuttx.org> + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include <nuttx/config.h> + +#include <sys/types.h> +#include <unistd.h> +#include <errno.h> + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: pwrite + * + * Description: + * The pwrite() function performs the same action as write(), except that + * it writes into a given position without changing the file pointer. The + * first three arguments to pwrite() are the same as write() with the + * addition of a fourth argument offset for the desired position inside + * the file. + * + * NOTE: This function could have been wholly implemented within libc but + * it is not. Why? Because if pwrite were implemented in libc, it would + * require four system calls. If it is implemented within the kernel, + * only three. + * + * Parameters: + * fd file descriptor (or socket descriptor) to write to + * buf Data to write + * nbytes Length of data to write + * + * Return: + * The positive non-zero number of bytes read on success, 0 on if an + * end-of-file condition, or -1 on failure with errno set appropriately. + * See write() return values + * + ****************************************************************************/ + +ssize_t pwrite(int fd, FAR const void *buf, size_t nbytes, off_t offset) +{ + off_t savepos; + off_t pos; + ssize_t ret; + int errcode; + + /* Perform the lseek to the current position. This will not move the + * file pointer, but will return its current setting + */ + + savepos = lseek(fd, 0, SEEK_CUR); + if (savepos == (off_t)-1) + { + /* lseek might fail if this if the media is not seekable */ + + return ERROR; + } + + /* Then seek to the correct position in the file */ + + pos = lseek(fd, offset, SEEK_CUR); + if (pos == (off_t)-1) + { + /* This might fail is the offset is beyond the end of file */ + + return ERROR; + } + + /* Then perform the write operation */ + + ret = write(fd, buf, nbytes); + errcode = get_errno(); + + /* Restore the file position */ + + pos = lseek(fd, savepos, SEEK_CUR); + if (pos == (off_t)-1 && ret >= 0) + { + /* This really should not fail */ + + return ERROR; + } + + set_errno(errcode); + return ret; +} diff --git a/nuttx/fs/vfs/fs_read.c b/nuttx/fs/vfs/fs_read.c index 5b0e09db0..d9b7ed23a 100644 --- a/nuttx/fs/vfs/fs_read.c +++ b/nuttx/fs/vfs/fs_read.c @@ -69,7 +69,7 @@ * * Return: * The positive non-zero number of bytes read on success, 0 on if an - * end-of-file condition, or -1 on failure withi errno set appropriately. + * end-of-file condition, or -1 on failure with errno set appropriately. * ****************************************************************************/ @@ -101,7 +101,7 @@ ssize_t file_read(FAR struct file *filep, FAR void *buf, size_t nbytes) else if (inode && inode->u.i_ops && inode->u.i_ops->read) { /* Yes.. then let it perform the read. NOTE that for the case of the - * mountpoint, we depend on the read methods bing identical in + * mountpoint, we depend on the read methods being identical in * signature and position in the operations vtable. */ @@ -135,7 +135,7 @@ ssize_t file_read(FAR struct file *filep, FAR void *buf, size_t nbytes) * * Return: * The positive non-zero number of bytes read on success, 0 on if an - * end-of-file condition, or -1 on failure withi errno set appropriately. + * end-of-file condition, or -1 on failure with errno set appropriately. * ****************************************************************************/ |