diff --git a/fs/aio/aio.h b/fs/aio/aio.h index 0716b09bcf2..e6b85cc6276 100644 --- a/fs/aio/aio.h +++ b/fs/aio/aio.h @@ -67,10 +67,12 @@ * pre-allocated, the number pre-allocated controlled by CONFIG_FS_NAIOC. */ +struct file; struct aio_container_s { dq_entry_t aioc_link; /* Supports a doubly linked list */ FAR struct aiocb *aioc_aiocbp; /* The contained AIO control block */ + FAR struct file *aioc_filep; /* File structure to use with the I/O */ struct work_s aioc_work; /* Used to defer I/O to the work thread */ pid_t aioc_pid; /* ID of the waiting task */ uint8_t aioc_prio; /* Priority of the waiting task */ @@ -182,7 +184,8 @@ void aioc_free(FAR struct aio_container_s *aioc); * Returned Value: * A reference to the new AIO control block container. This function * will not fail but will wait if necessary for the resources to perform - * this operation. + * this operation. NULL will be returned on certain errors with the + * errno value already set appropriately. * ****************************************************************************/ diff --git a/fs/aio/aio_fsync.c b/fs/aio/aio_fsync.c index 3df22bec6db..25573df45c7 100644 --- a/fs/aio/aio_fsync.c +++ b/fs/aio/aio_fsync.c @@ -46,6 +46,7 @@ #include #include +#include #include "aio/aio.h" @@ -103,9 +104,9 @@ static void aio_fsync_worker(FAR void *arg) pid = aioc->aioc_pid; aiocbp = aioc_decant(aioc); - /* Perform the fsync using aio_fildes */ + /* Perform the fsync using aioc_filep */ - ret = fsync(aiocbp->aio_fildes); + ret = file_fsync(aioc->aioc_filep); if (ret < 0) { int errcode = get_errno(); @@ -218,12 +219,18 @@ int aio_fsync(int op, FAR struct aiocb *aiocbp) aiocbp->aio_result = -EINPROGRESS; aiocbp->aio_priv = NULL; - /* Create a container for the AIO control block. This will not fail but - * may cause us to block if there are insufficient resources to satisfy - * the request. + /* Create a container for the AIO control block. This may cause us to + * block if there are insufficient resources to satisfy the request. */ aioc = aio_contain(aiocbp); + if (!aioc) + { + /* The errno has already been set (probably EBADF) */ + + aiocbp->aio_result = -get_errno(); + return ERROR; + } /* Defer the work to the worker thread */ diff --git a/fs/aio/aio_read.c b/fs/aio/aio_read.c index c627a0d87ab..5ee7db11978 100644 --- a/fs/aio/aio_read.c +++ b/fs/aio/aio_read.c @@ -106,14 +106,14 @@ static void aio_read_worker(FAR void *arg) /* Perform the read using: * - * aio_fildes - File descriptor + * aioc_filep - File structure pointer * aio_buf - Location of buffer * aio_nbytes - Length of transfer * aio_offset - File offset */ - nread = pread(aiocbp->aio_fildes, (FAR void *)aiocbp->aio_buf, - aiocbp->aio_nbytes, aiocbp->aio_offset); + nread = file_pread(aioc->aioc_filep, (FAR void *)aiocbp->aio_buf, + aiocbp->aio_nbytes, aiocbp->aio_offset); /* Set the result of the read */ @@ -266,12 +266,18 @@ int aio_read(FAR struct aiocb *aiocbp) aiocbp->aio_result = -EINPROGRESS; aiocbp->aio_priv = NULL; - /* Create a container for the AIO control block. This will not fail but - * may cause us to block if there are insufficient resources to satisfy - * the request. + /* Create a container for the AIO control block. This may cause us to + * block if there are insufficient resources to satisfy the request. */ aioc = aio_contain(aiocbp); + if (!aioc) + { + /* The errno has already been set (probably EBADF) */ + + aiocbp->aio_result = -get_errno(); + return ERROR; + } /* Defer the work to the worker thread */ diff --git a/fs/aio/aio_write.c b/fs/aio/aio_write.c index 2b1233e25c1..86f45c61de8 100644 --- a/fs/aio/aio_write.c +++ b/fs/aio/aio_write.c @@ -39,6 +39,7 @@ #include +#include #include #include #include @@ -73,6 +74,21 @@ * Private Functions ****************************************************************************/ +/**************************************************************************** + * Name: file_fcntl + ****************************************************************************/ + +static inline int file_fcntl(FAR struct file *filep, int cmd, ...) +{ + va_list ap; + int ret; + + va_start(ap, cmd); + ret = file_vfcntl(filep, cmd, ap); + va_end(ap); + return ret; +} + /**************************************************************************** * Name: aio_write_worker * @@ -108,7 +124,7 @@ static void aio_write_worker(FAR void *arg) /* Call fcntl(F_GETFL) to get the file open mode. */ - oflags = fcntl(aiocbp->aio_fildes, F_GETFL); + oflags = file_fcntl(aioc->aioc_filep, F_GETFL); if (oflags < 0) { int errcode = get_errno(); @@ -119,7 +135,7 @@ static void aio_write_worker(FAR void *arg) { /* Perform the write using: * - * aio_fildes - File descriptor + * aioc_filep - File descriptor * aio_buf - Location of buffer * aio_nbytes - Length of transfer * aio_offset - File offset @@ -131,16 +147,16 @@ static void aio_write_worker(FAR void *arg) { /* Append to the current file position */ - nwritten = write(aiocbp->aio_fildes, - (FAR const void *)aiocbp->aio_buf, - aiocbp->aio_nbytes); + nwritten = file_write(aioc->aioc_filep, + (FAR const void *)aiocbp->aio_buf, + aiocbp->aio_nbytes); } else { - nwritten = pwrite(aiocbp->aio_fildes, - (FAR const void *)aiocbp->aio_buf, - aiocbp->aio_nbytes, - aiocbp->aio_offset); + nwritten = file_pwrite(aioc->aioc_filep, + (FAR const void *)aiocbp->aio_buf, + aiocbp->aio_nbytes, + aiocbp->aio_offset); } /* Set the result of the write */ @@ -297,12 +313,18 @@ int aio_write(FAR struct aiocb *aiocbp) aiocbp->aio_result = -EINPROGRESS; aiocbp->aio_priv = NULL; - /* Create a container for the AIO control block. This will not fail but - * may cause us to block if there are insufficient resources to satisfy - * the request. + /* Create a container for the AIO control block. This may cause us to + * block if there are insufficient resources to satisfy the request. */ aioc = aio_contain(aiocbp); + if (!aioc) + { + /* The errno has already been set (probably EBADF) */ + + aiocbp->aio_result = -get_errno(); + return ERROR; + } /* Defer the work to the worker thread */ diff --git a/fs/aio/aioc_contain.c b/fs/aio/aioc_contain.c index e608a86598f..34842bd21c7 100644 --- a/fs/aio/aioc_contain.c +++ b/fs/aio/aioc_contain.c @@ -41,6 +41,8 @@ #include +#include + #include "aio/aio.h" #ifdef CONFIG_FS_AIO @@ -80,15 +82,27 @@ * Returned Value: * A reference to the new AIO control block container. This function * will not fail but will wait if necessary for the resources to perform - * this operation. + * this operation. NULL will be returned on certain errors with the + * errno value already set appropriately. * ****************************************************************************/ FAR struct aio_container_s *aio_contain(FAR struct aiocb *aiocbp) { FAR struct aio_container_s *aioc; + FAR struct file *filep; struct sched_param param; + /* Get the file structure corresponding to the file descriptor. */ + + filep = fs_getfilep(aiocbp->aio_fildes); + if (!filep) + { + /* The errno value has already been set */ + + return NULL; + } + /* Allocate the AIO control block container, waiting for one to become * available if necessary. This should never fail. */ @@ -100,6 +114,7 @@ FAR struct aio_container_s *aio_contain(FAR struct aiocb *aiocbp) memset(aioc, 0, sizeof(struct aio_container_s)); aioc->aioc_aiocbp = aiocbp; + aioc->aioc_filep = filep; aioc->aioc_pid = getpid(); DEBUGVERIFY(sched_getparam (aioc->aioc_pid, ¶m)); diff --git a/fs/inode/fs_files.c b/fs/inode/fs_files.c index f39ea8b81af..4f82b15126e 100644 --- a/fs/inode/fs_files.c +++ b/fs/inode/fs_files.c @@ -200,7 +200,7 @@ void files_releaselist(FAR struct filelist *list) } /**************************************************************************** - * Name: files_dup + * Name: file_dup2 * * Description: * Assign an inode to a specific files structure. This is the heart of @@ -208,7 +208,7 @@ void files_releaselist(FAR struct filelist *list) * ****************************************************************************/ -int files_dup(FAR struct file *filep1, FAR struct file *filep2) +int file_dup2(FAR struct file *filep1, FAR struct file *filep2) { FAR struct filelist *list; FAR struct inode *inode; diff --git a/fs/vfs/Make.defs b/fs/vfs/Make.defs index 583aaf070e1..1780eabd626 100644 --- a/fs/vfs/Make.defs +++ b/fs/vfs/Make.defs @@ -69,10 +69,10 @@ else # Common file/socket descriptor support -CSRCS += fs_close.c fs_dup.c fs_dup2.c fs_fcntl.c fs_filedup.c fs_filedup2.c -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 +CSRCS += fs_close.c fs_dup.c fs_dup2.c fs_fcntl.c fs_dupfd.c fs_dupfd2.c +CSRCS += fs_fsync.c fs_getfilep.c fs_ioctl.c fs_lseek.c fs_mkdir.c fs_open.c +CSRCS += fs_poll.c fs_read.c fs_rename.c fs_rmdir.c fs_stat.c fs_statfs.c +CSRCS += fs_select.c fs_unlink.c fs_write.c # Support for positional file access diff --git a/fs/vfs/fs_dup.c b/fs/vfs/fs_dup.c index 2c4dd785d08..5981dc8cd5e 100644 --- a/fs/vfs/fs_dup.c +++ b/fs/vfs/fs_dup.c @@ -68,7 +68,7 @@ int dup(int fd) { - int ret = OK; + int ret = OK; /* Check the range of the descriptor to see if we got a file or a socket * descriptor. */ @@ -79,19 +79,19 @@ int dup(int fd) /* Its a valid file descriptor.. dup the file descriptor using any * other file descriptor*/ - ret = file_dup(fd, 0); + ret = fs_dupfd(fd, 0); } else #endif { - /* Not a vailid file descriptor. Did we get a valid socket descriptor? */ + /* Not a valid file descriptor. Did we get a valid socket descriptor? */ #if defined(CONFIG_NET) && CONFIG_NSOCKET_DESCRIPTORS > 0 if ((unsigned int)fd < (CONFIG_NFILE_DESCRIPTORS+CONFIG_NSOCKET_DESCRIPTORS)) { /* Yes.. dup the socket descriptor */ - ret = net_dup(fd, CONFIG_NFILE_DESCRIPTORS); + ret = net_dupsd(fd, CONFIG_NFILE_DESCRIPTORS); } else #endif diff --git a/fs/vfs/fs_dup2.c b/fs/vfs/fs_dup2.c index ff6eabdb405..3164e0b2f5f 100644 --- a/fs/vfs/fs_dup2.c +++ b/fs/vfs/fs_dup2.c @@ -87,7 +87,7 @@ int dup2(int fd1, int fd2) { /* Yes.. dup the socket descriptor */ - return net_dup2(fd1, fd2); + return net_dupsd2(fd1, fd2); } else { @@ -101,7 +101,7 @@ int dup2(int fd1, int fd2) { /* Its a valid file descriptor.. dup the file descriptor */ - return file_dup2(fd1, fd2); + return fs_dupfd2(fd1, fd2); } } diff --git a/fs/vfs/fs_filedup.c b/fs/vfs/fs_dupfd.c similarity index 75% rename from fs/vfs/fs_filedup.c rename to fs/vfs/fs_dupfd.c index f474a096e1e..5d319641d7e 100644 --- a/fs/vfs/fs_filedup.c +++ b/fs/vfs/fs_dupfd.c @@ -1,7 +1,7 @@ /**************************************************************************** - * fs/vfs/fs_filedup.c + * fs/vfs/fs_dupfd.c * - * Copyright (C) 2007-2009, 2011-2013 Gregory Nutt. All rights reserved. + * Copyright (C) 2007-2009, 2011-2014 Gregory Nutt. All rights reserved. * Author: Gregory Nutt * * Redistribution and use in source and binary forms, with or without @@ -53,43 +53,33 @@ * Pre-processor Definitions ****************************************************************************/ -#define DUP_ISOPEN(fd, list) \ - ((unsigned int)fd < CONFIG_NFILE_DESCRIPTORS && \ - list->fl_files[fd].f_inode != NULL) +#define DUP_ISOPEN(filep) (filep->f_inode != NULL) /**************************************************************************** * Private Functions ****************************************************************************/ /**************************************************************************** - * Global Functions + * Public Functions ****************************************************************************/ /**************************************************************************** - * Name: file_dup OR dup + * Name: file_dup * * Description: - * Clone a file descriptor 'fd' to an arbitray descriptor number (any value - * greater than or equal to 'minfd'). If socket descriptors are - * implemented, then this is called by dup() for the case of file - * descriptors. If socket descriptors are not implemented, then this - * function IS dup(). + * Equivalent to the non-standard fs_dupfd() function except that it + * accepts a struct file instance instead of a file descriptor. Currently + * used only by file_vfcntl(); * ****************************************************************************/ -int file_dup(int fd, int minfd) +int file_dup(FAR struct file *filep, int minfd) { - FAR struct filelist *list; int fd2; - /* Get the thread-specific file list */ - - list = sched_getfiles(); - DEBUGASSERT(list); - /* Verify that fd is a valid, open file descriptor */ - if (!DUP_ISOPEN(fd, list)) + if (!DUP_ISOPEN(filep)) { set_errno(EBADF); return ERROR; @@ -97,23 +87,51 @@ int file_dup(int fd, int minfd) /* Increment the reference count on the contained inode */ - inode_addref(list->fl_files[fd].f_inode); + inode_addref(filep->f_inode); /* Then allocate a new file descriptor for the inode */ - fd2 = files_allocate(list->fl_files[fd].f_inode, - list->fl_files[fd].f_oflags, - list->fl_files[fd].f_pos, - minfd); + fd2 = files_allocate(filep->f_inode, filep->f_oflags, filep->f_pos, minfd); if (fd2 < 0) { set_errno(EMFILE); - inode_release(list->fl_files[fd].f_inode); + inode_release(filep->f_inode); return ERROR; } return fd2; } +/**************************************************************************** + * Name: fs_dupfd OR dup + * + * Description: + * Clone a file descriptor 'fd' to an arbitray descriptor number (any value + * greater than or equal to 'minfd'). If socket descriptors are + * implemented, then this is called by dup() for the case of file + * descriptors. If socket descriptors are not implemented, then this + * function IS dup(). + * + ****************************************************************************/ + +int fs_dupfd(int fd, int minfd) +{ + FAR struct file *filep; + + /* Get the file structure corresponding to the file descriptor. */ + + filep = fs_getfilep(fd); + if (!filep) + { + /* The errno value has already been set */ + + return ERROR; + } + + /* Let file_dup() do the real work */ + + return file_dup(filep, minfd); +} + #endif /* CONFIG_NFILE_DESCRIPTORS > 0 */ diff --git a/fs/vfs/fs_filedup2.c b/fs/vfs/fs_dupfd2.c similarity index 83% rename from fs/vfs/fs_filedup2.c rename to fs/vfs/fs_dupfd2.c index 73b29c32e31..6043430bdc5 100644 --- a/fs/vfs/fs_filedup2.c +++ b/fs/vfs/fs_dupfd2.c @@ -1,7 +1,7 @@ /**************************************************************************** - * fs/vfs/fs_filedup2.c + * fs/vfs/fs_dupfd2.c * - * Copyright (C) 2007-2009, 2011-2013 Gregory Nutt. All rights reserved. + * Copyright (C) 2007-2009, 2011-2014 Gregory Nutt. All rights reserved. * Author: Gregory Nutt * * Redistribution and use in source and binary forms, with or without @@ -51,9 +51,7 @@ * Pre-processor Definitions ****************************************************************************/ -#define DUP_ISOPEN(fd, list) \ - ((unsigned int)fd < CONFIG_NFILE_DESCRIPTORS && \ - list->fl_files[fd].f_inode != NULL) +#define DUP_ISOPEN(filep) (filep->f_inode != NULL) /**************************************************************************** * Private Functions @@ -64,7 +62,7 @@ ****************************************************************************/ /**************************************************************************** - * Name: file_dup2 OR dup2 + * Name: fs_dupfd2 OR dup2 * * Description: * Clone a file descriptor to a specific descriptor number. If socket @@ -75,25 +73,29 @@ ****************************************************************************/ #if defined(CONFIG_NET) && CONFIG_NSOCKET_DESCRIPTORS > 0 -int file_dup2(int fd1, int fd2) +int fs_dupfd2(int fd1, int fd2) #else int dup2(int fd1, int fd2) #endif { - FAR struct filelist *list; + FAR struct file *filep1; + FAR struct file *filep2; - /* Get the thread-specific file list */ + /* Get the file structures corresponding to the file descriptors. */ - list = sched_getfiles(); - if (!list) + filep1 = fs_getfilep(fd1); + filep2 = fs_getfilep(fd2); + + if (!filep1 || !filep2) { - set_errno(EMFILE); + /* The errno value has already been set */ + return ERROR; } - /* Verify that fd is a valid, open file descriptor */ + /* Verify that fd1 is a valid, open file descriptor */ - if (!DUP_ISOPEN(fd1, list)) + if (!DUP_ISOPEN(filep1)) { set_errno(EBADF); return ERROR; @@ -106,15 +108,9 @@ int dup2(int fd1, int fd2) return fd1; } - /* Verify fd2 */ - - if ((unsigned int)fd2 >= CONFIG_NFILE_DESCRIPTORS) - { - set_errno(EBADF); - return ERROR; - } + /* Perform the dup2 operation */ - return files_dup(&list->fl_files[fd1], &list->fl_files[fd2]); + return file_dup2(filep1, filep2); } #endif /* CONFIG_NFILE_DESCRIPTORS > 0 */ diff --git a/fs/vfs/fs_fcntl.c b/fs/vfs/fs_fcntl.c index 6e4ebefb135..f4d67ae457f 100644 --- a/fs/vfs/fs_fcntl.c +++ b/fs/vfs/fs_fcntl.c @@ -1,7 +1,7 @@ /**************************************************************************** * fs/vfs/fs_fcntl.c * - * Copyright (C) 2009, 2012-2013 Gregory Nutt. All rights reserved. + * Copyright (C) 2009, 2012-2014 Gregory Nutt. All rights reserved. * Author: Gregory Nutt * * Redistribution and use in source and binary forms, with or without @@ -58,26 +58,28 @@ * Private Functions ****************************************************************************/ +/**************************************************************************** + * Public Functions + ****************************************************************************/ + /**************************************************************************** * Name: file_vfcntl + * + * Description: + * Similar to the standard vfcntl function except that is accepts a struct + * struct file instance instead of a file descriptor. Currently used + * only by aio_fcntl(); + * ****************************************************************************/ #if CONFIG_NFILE_DESCRIPTORS > 0 -static inline int file_vfcntl(int fd, int cmd, va_list ap) +int file_vfcntl(FAR struct file *filep, int cmd, va_list ap) { - FAR struct filelist *list; - FAR struct file *filep; int err = 0; int ret = OK; - /* Get the thread-specific file list */ - - list = sched_getfiles(); - DEBUGASSERT(list); - /* Was this file opened ? */ - filep = &list->fl_files[fd]; if (!filep->f_inode) { err = EBADF; @@ -98,7 +100,7 @@ static inline int file_vfcntl(int fd, int cmd, va_list ap) */ { - ret = file_dup(fd, va_arg(ap, int)); + ret = file_dup(filep, va_arg(ap, int)); } break; @@ -216,16 +218,13 @@ static inline int file_vfcntl(int fd, int cmd, va_list ap) } #endif /* CONFIG_NFILE_DESCRIPTORS > 0 */ -/**************************************************************************** - * Global Functions - ****************************************************************************/ - /**************************************************************************** * Name: fcntl ****************************************************************************/ int fcntl(int fd, int cmd, ...) { + FAR struct file *filep; va_list ap; int ret; @@ -238,9 +237,19 @@ int fcntl(int fd, int cmd, ...) #if CONFIG_NFILE_DESCRIPTORS > 0 if ((unsigned int)fd < CONFIG_NFILE_DESCRIPTORS) { - /* Yes.. defer file operations to file_vfcntl() */ + /* Get the file structure corresponding to the file descriptor. */ + + filep = fs_getfilep(fd); + if (!filep) + { + /* The errno value has already been set */ - ret = file_vfcntl(fd, cmd, ap); + return ERROR; + } + + /* Let file_vfcntl() do the real work */ + + ret = file_vfcntl(filep, cmd, ap); } else #endif @@ -266,4 +275,3 @@ int fcntl(int fd, int cmd, ...) va_end(ap); return ret; } - diff --git a/fs/vfs/fs_fdopen.c b/fs/vfs/fs_fdopen.c index ece6f0fe9bf..882337da11d 100644 --- a/fs/vfs/fs_fdopen.c +++ b/fs/vfs/fs_fdopen.c @@ -65,22 +65,28 @@ #if CONFIG_NFILE_DESCRIPTORS > 0 static inline int fs_checkfd(FAR struct tcb_s *tcb, int fd, int oflags) { - FAR struct filelist *flist; - FAR struct inode *inode; + FAR struct file *filep; + FAR struct inode *inode; DEBUGASSERT(tcb && tcb->group); - /* Get the file list from the task group */ + /* Get the file structure corresponding to the file descriptor. */ - flist = &tcb->group->tg_filelist; + filep = fs_getfilep(fd); + if (!filep) + { + /* The errno value has already been set */ + + return ERROR; + } /* Get the inode associated with the file descriptor. This should * normally be the case if fd >= 0. But not in the case where the - * called attempts to explictly stdin with fdopen(0) but stdin has + * called attempts to explicitly stdin with fdopen(0) but stdin has * been closed. */ - inode = flist->fl_files[fd].f_inode; + inode = filep->f_inode; if (!inode) { /* No inode -- descriptor does not correspond to an open file */ diff --git a/fs/vfs/fs_fsync.c b/fs/vfs/fs_fsync.c index d608cda5f3a..24e1841428e 100644 --- a/fs/vfs/fs_fsync.c +++ b/fs/vfs/fs_fsync.c @@ -1,7 +1,7 @@ /**************************************************************************** * fs/vfs/fs_fsync.c * - * Copyright (C) 2007-2009, 2013 Gregory Nutt. All rights reserved. + * Copyright (C) 2007-2009, 2013-2014 Gregory Nutt. All rights reserved. * Author: Gregory Nutt * * Redistribution and use in source and binary forms, with or without @@ -70,36 +70,22 @@ ****************************************************************************/ /**************************************************************************** - * Name: fsync + * Name: file_fsync * * Description: - * This func simply binds inode sync methods to the sync system call. + * Equivalent to the standard fsync() function except that is accepts a + * struct file instance instead of a file descriptor. Currently used + * only by aio_fsync(); * ****************************************************************************/ -int fsync(int fd) +int file_fsync(FAR struct file *filep) { - FAR struct filelist *list; - FAR struct file *filep; - struct inode *inode; - int ret; - - /* Get the thread-specific file list */ - - list = sched_getfiles(); - DEBUGASSERT(list); - - /* Did we get a valid file descriptor? */ - - if ((unsigned int)fd >= CONFIG_NFILE_DESCRIPTORS) - { - ret = EBADF; - goto errout; - } + struct inode *inode; + int ret; /* Was this file opened for write access? */ - filep = &list->fl_files[fd]; if ((filep->f_oflags & O_WROK) == 0) { ret = EBADF; @@ -134,3 +120,29 @@ int fsync(int fd) return ERROR; } +/**************************************************************************** + * Name: fsync + * + * Description: + * This func simply binds inode sync methods to the sync system call. + * + ****************************************************************************/ + +int fsync(int fd) +{ + FAR struct file *filep; + + /* Get the file structure corresponding to the file descriptor. */ + + filep = fs_getfilep(fd); + if (!filep) + { + /* The errno value has already been set */ + + return ERROR; + } + + /* Perform the fsync operation */ + + return file_fsync(filep); +} diff --git a/fs/vfs/fs_getfilep.c b/fs/vfs/fs_getfilep.c new file mode 100644 index 00000000000..165d00434ce --- /dev/null +++ b/fs/vfs/fs_getfilep.c @@ -0,0 +1,112 @@ +/**************************************************************************** + * fs/vfs/fs_getfilep.c + * + * Copyright (C) 2014 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * 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 +#include +#include + +#include +#include +#include +#include + +#include "inode/inode.h" + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: fs_getfilep + * + * Description: + * Given a file descriptor, return the corresponding instance of struct + * file. NOTE that this function will currently fail if it is provided + * with a socket descriptor. + * + * Parameters: + * fd - The file descriptor + * + * Return: + * A point to the corresponding struct file instance is returned on + * success. On failure, NULL is returned and the errno value is + * set appropriately (EBADF). + * + ****************************************************************************/ + +FAR struct file *fs_getfilep(int fd) +{ + FAR struct filelist *list; + int errcode; + + if ((unsigned int)fd >= CONFIG_NFILE_DESCRIPTORS) + { + errcode = EBADF; + goto errout; + } + + /* The descriptor is in a valid range to file descriptor... Get the + * thread-specific file list. + */ + + list = sched_getfiles(); + + /* The file list can be NULL under one obscure cornercase: When memory + * management debug output is enabled. Then there may be attempts to + * write to stdout from malloc before the group data has been allocated. + */ + + if (!list) + { + errcode = EAGAIN; + goto errout; + } + + /* And return the file pointer from the list */ + + return &list->fl_files[fd]; + +errout: + set_errno(errcode); + return NULL; +} diff --git a/fs/vfs/fs_ioctl.c b/fs/vfs/fs_ioctl.c index b0a7ad78658..c0165cf7bd8 100644 --- a/fs/vfs/fs_ioctl.c +++ b/fs/vfs/fs_ioctl.c @@ -1,7 +1,7 @@ /**************************************************************************** * fs/vfs/fs_ioctl.c * - * Copyright (C) 2007-2010, 2012-2013 Gregory Nutt. All rights reserved. + * Copyright (C) 2007-2010, 2012-2014 Gregory Nutt. All rights reserved. * Author: Gregory Nutt * * Redistribution and use in source and binary forms, with or without @@ -89,7 +89,6 @@ int ioctl(int fd, int req, unsigned long arg) { int err; #if CONFIG_NFILE_DESCRIPTORS > 0 - FAR struct filelist *list; FAR struct file *filep; FAR struct inode *inode; int ret = OK; @@ -115,16 +114,19 @@ int ioctl(int fd, int req, unsigned long arg) } #if CONFIG_NFILE_DESCRIPTORS > 0 - /* Get the thread-specific file list */ + /* Get the file structure corresponding to the file descriptor. */ - list = sched_getfiles(); - DEBUGASSERT(list); + filep = fs_getfilep(fd); + if (!filep) + { + /* The errno value has already been set */ + + return ERROR; + } /* Is a driver registered? Does it support the ioctl method? */ - filep = &list->fl_files[fd]; inode = filep->f_inode; - if (inode && inode->u.i_ops && inode->u.i_ops->ioctl) { /* Yes, then let it perform the ioctl */ diff --git a/fs/vfs/fs_lseek.c b/fs/vfs/fs_lseek.c index a4a45b5fd28..7136d2ce118 100644 --- a/fs/vfs/fs_lseek.c +++ b/fs/vfs/fs_lseek.c @@ -50,7 +50,7 @@ #if CONFIG_NFILE_DESCRIPTORS > 0 /**************************************************************************** - * Global Functions + * Public Functions ****************************************************************************/ /**************************************************************************** @@ -71,9 +71,6 @@ * ****************************************************************************/ -#ifndef CONFIG_NET_SENDFILE -static inline -#endif off_t file_seek(FAR struct file *filep, off_t offset, int whence) { FAR struct inode *inode; @@ -172,26 +169,21 @@ off_t file_seek(FAR struct file *filep, off_t offset, int whence) off_t lseek(int fd, off_t offset, int whence) { - FAR struct filelist *list; + FAR struct file *filep; - /* Did we get a valid file descriptor? */ + /* Get the file structure corresponding to the file descriptor. */ - if ((unsigned int)fd >= CONFIG_NFILE_DESCRIPTORS) + filep = fs_getfilep(fd); + if (!filep) { - set_errno(EBADF); + /* The errno value has already been set */ + return (off_t)ERROR; } - else - { - /* Get the thread-specific file list */ - - list = sched_getfiles(); - DEBUGASSERT(list); - /* Then let file_seek do the real work */ + /* Then let file_seek do the real work */ - return file_seek(&list->fl_files[fd], offset, whence); - } + return file_seek(filep, offset, whence); } #endif diff --git a/fs/vfs/fs_open.c b/fs/vfs/fs_open.c index 4c0596e7f62..fd6562ac3dd 100644 --- a/fs/vfs/fs_open.c +++ b/fs/vfs/fs_open.c @@ -91,19 +91,14 @@ int inode_checkflags(FAR struct inode *inode, int oflags) int open(const char *path, int oflags, ...) { - FAR struct filelist *list; - FAR struct inode *inode; - FAR const char *relpath = NULL; + FAR struct file *filep; + FAR struct inode *inode; + FAR const char *relpath = NULL; #if defined(CONFIG_FILE_MODE) || !defined(CONFIG_DISABLE_MOUNTPOINT) - mode_t mode = 0666; + mode_t mode = 0666; #endif - int ret; - int fd; - - /* Get the thread-specific file list */ - - list = sched_getfiles(); - DEBUGASSERT(list); + int ret; + int fd; #ifdef CONFIG_FILE_MODE # ifdef CONFIG_CPP_HAVE_WARNING @@ -168,6 +163,16 @@ int open(const char *path, int oflags, ...) goto errout_with_inode; } + /* Get the file structure corresponding to the file descriptor. */ + + filep = fs_getfilep(fd); + if (!filep) + { + /* The errno value has already been set */ + + return ERROR; + } + /* Perform the driver open operation. NOTE that the open method may be * called many times. The driver/mountpoint logic should handled this * because it may also be closed that many times. @@ -179,13 +184,12 @@ int open(const char *path, int oflags, ...) #ifndef CONFIG_DISABLE_MOUNTPOINT if (INODE_IS_MOUNTPT(inode)) { - ret = inode->u.i_mops->open((FAR struct file*)&list->fl_files[fd], - relpath, oflags, mode); + ret = inode->u.i_mops->open(filep, relpath, oflags, mode); } else #endif { - ret = inode->u.i_ops->open((FAR struct file*)&list->fl_files[fd]); + ret = inode->u.i_ops->open(filep); } } diff --git a/fs/vfs/fs_poll.c b/fs/vfs/fs_poll.c index 70150891734..3bdc817ca84 100644 --- a/fs/vfs/fs_poll.c +++ b/fs/vfs/fs_poll.c @@ -97,10 +97,9 @@ static void poll_semtake(FAR sem_t *sem) #if CONFIG_NFILE_DESCRIPTORS > 0 static int poll_fdsetup(int fd, FAR struct pollfd *fds, bool setup) { - FAR struct filelist *list; - FAR struct file *filep; - FAR struct inode *inode; - int ret = -ENOSYS; + FAR struct file *filep; + FAR struct inode *inode; + int ret = -ENOSYS; /* Check for a valid file descriptor */ @@ -120,18 +119,21 @@ static int poll_fdsetup(int fd, FAR struct pollfd *fds, bool setup) } } - /* Get the thread-specific file list */ + /* Get the file pointer corresponding to this file descriptor */ - list = sched_getfiles(); - DEBUGASSERT(list); + filep = fs_getfilep(fd); + if (!filep) + { + /* The errno value has already been set */ + + return ERROR; + } /* Is a driver registered? Does it support the poll method? * If not, return -ENOSYS */ - filep = &list->fl_files[fd]; inode = filep->f_inode; - if (inode && inode->u.i_ops && inode->u.i_ops->poll) { /* Yes, then setup the poll */ diff --git a/fs/vfs/fs_pread.c b/fs/vfs/fs_pread.c index 3e494343927..e80efe66a08 100644 --- a/fs/vfs/fs_pread.c +++ b/fs/vfs/fs_pread.c @@ -43,6 +43,8 @@ #include #include +#include + /**************************************************************************** * Private Functions ****************************************************************************/ @@ -52,56 +54,38 @@ ****************************************************************************/ /**************************************************************************** - * Name: pread + * Name: file_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 + * Equivalent to the standard pread function except that is accepts a + * struct file instance instead of a file descriptor. Currently used + * only by aio_read(); * ****************************************************************************/ -ssize_t pread(int fd, FAR void *buf, size_t nbytes, off_t offset) +ssize_t file_pread(FAR struct file *filep, 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 + /* Perform the seek to the current position. This will not move the * file pointer, but will return its current setting */ - savepos = lseek(fd, 0, SEEK_CUR); + savepos = file_seek(filep, 0, SEEK_CUR); if (savepos == (off_t)-1) { - /* lseek might fail if this if the media is not seekable */ + /* file_seek 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_SET); + pos = file_seek(filep, offset, SEEK_SET); if (pos == (off_t)-1) { /* This might fail is the offset is beyond the end of file */ @@ -111,12 +95,12 @@ ssize_t pread(int fd, FAR void *buf, size_t nbytes, off_t offset) /* Then perform the read operation */ - ret = read(fd, buf, nbytes); + ret = file_read(filep, buf, nbytes); errcode = get_errno(); /* Restore the file position */ - pos = lseek(fd, savepos, SEEK_SET); + pos = file_seek(filep, savepos, SEEK_SET); if (pos == (off_t)-1 && ret >= 0) { /* This really should not fail */ @@ -127,3 +111,51 @@ ssize_t pread(int fd, FAR void *buf, size_t nbytes, off_t offset) set_errno(errcode); return ret; } + +/**************************************************************************** + * 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) +{ + FAR struct file *filep; + + /* Get the file structure corresponding to the file descriptor. */ + + filep = fs_getfilep(fd); + if (!filep) + { + /* The errno value has already been set */ + + return (ssize_t)ERROR; + } + + /* Let file_pread do the real work */ + + return file_pread(filep, buf, nbytes, offset); +} diff --git a/fs/vfs/fs_pwrite.c b/fs/vfs/fs_pwrite.c index e7c1cf70010..43630c455a4 100644 --- a/fs/vfs/fs_pwrite.c +++ b/fs/vfs/fs_pwrite.c @@ -43,6 +43,8 @@ #include #include +#include + /**************************************************************************** * Private Functions ****************************************************************************/ @@ -52,54 +54,38 @@ ****************************************************************************/ /**************************************************************************** - * Name: pwrite + * Name: file_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 + * Equivalent to the standard pwrite function except that is accepts a + * struct file instance instead of a file descriptor. Currently used + * only by aio_write(); * ****************************************************************************/ -ssize_t pwrite(int fd, FAR const void *buf, size_t nbytes, off_t offset) +ssize_t file_pwrite(FAR struct file *filep, 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 + /* Perform the seek to the current position. This will not move the * file pointer, but will return its current setting */ - savepos = lseek(fd, 0, SEEK_CUR); + savepos = file_seek(filep, 0, SEEK_CUR); if (savepos == (off_t)-1) { - /* lseek might fail if this if the media is not seekable */ + /* file_seek 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_SET); + pos = file_seek(filep, offset, SEEK_SET); if (pos == (off_t)-1) { /* This might fail is the offset is beyond the end of file */ @@ -109,12 +95,12 @@ ssize_t pwrite(int fd, FAR const void *buf, size_t nbytes, off_t offset) /* Then perform the write operation */ - ret = write(fd, buf, nbytes); + ret = file_write(filep, buf, nbytes); errcode = get_errno(); /* Restore the file position */ - pos = lseek(fd, savepos, SEEK_SET); + pos = file_seek(filep, savepos, SEEK_SET); if (pos == (off_t)-1 && ret >= 0) { /* This really should not fail */ @@ -125,3 +111,49 @@ ssize_t pwrite(int fd, FAR const void *buf, size_t nbytes, off_t offset) set_errno(errcode); return ret; } + +/**************************************************************************** + * 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) +{ + FAR struct file *filep; + + /* Get the file structure corresponding to the file descriptor. */ + + filep = fs_getfilep(fd); + if (!filep) + { + /* The errno value has already been set */ + + return (ssize_t)ERROR; + } + + /* Let file_pread do the real work */ + + return file_pwrite(filep, buf, nbytes, offset); +} diff --git a/fs/vfs/fs_read.c b/fs/vfs/fs_read.c index d9b7ed23a15..c5cdc701e65 100644 --- a/fs/vfs/fs_read.c +++ b/fs/vfs/fs_read.c @@ -1,7 +1,7 @@ /**************************************************************************** * fs/vfs/fs_read.c * - * Copyright (C) 2007-2009, 2012-2013 Gregory Nutt. All rights reserved. + * Copyright (C) 2007-2009, 2012-2014 Gregory Nutt. All rights reserved. * Author: Gregory Nutt * * Redistribution and use in source and binary forms, with or without @@ -73,10 +73,6 @@ * ****************************************************************************/ -#if CONFIG_NFILE_DESCRIPTORS > 0 -#ifndef CONFIG_NET_SENDFILE -static inline -#endif ssize_t file_read(FAR struct file *filep, FAR void *buf, size_t nbytes) { FAR struct inode *inode; @@ -120,7 +116,6 @@ ssize_t file_read(FAR struct file *filep, FAR void *buf, size_t nbytes) return ret; } -#endif /* CONFIG_NFILE_DESCRIPTORS > 0 */ /**************************************************************************** * Name: read @@ -141,10 +136,6 @@ ssize_t file_read(FAR struct file *filep, FAR void *buf, size_t nbytes) ssize_t read(int fd, FAR void *buf, size_t nbytes) { -#if CONFIG_NFILE_DESCRIPTORS > 0 - FAR struct filelist *list; -#endif - /* Did we get a valid file descriptor? */ #if CONFIG_NFILE_DESCRIPTORS > 0 @@ -168,16 +159,23 @@ ssize_t read(int fd, FAR void *buf, size_t nbytes) #if CONFIG_NFILE_DESCRIPTORS > 0 else { - /* Thee descriptor is in a valid range to file descriptor... do the - * read. Get the thread-specific file list. + FAR struct file *filep; + + /* The descriptor is in a valid range to file descriptor... do the + * read. First, get the file structure. */ - list = sched_getfiles(); - DEBUGASSERT(list); + filep = fs_getfilep(fd); + if (!filep) + { + /* The errno value has already been set */ + + return ERROR; + } /* Then let file_read do all of the work */ - return file_read(&list->fl_files[fd], buf, nbytes); + return file_read(filep, buf, nbytes); } #endif } diff --git a/fs/vfs/fs_sendfile.c b/fs/vfs/fs_sendfile.c index e5d93569631..05c3d976eb4 100644 --- a/fs/vfs/fs_sendfile.c +++ b/fs/vfs/fs_sendfile.c @@ -127,18 +127,23 @@ ssize_t sendfile(int outfd, int infd, off_t *offset, size_t count) if ((unsigned int)outfd >= CONFIG_NFILE_DESCRIPTORS && (unsigned int)infd < CONFIG_NFILE_DESCRIPTORS) { - FAR struct filelist *list; + FAR struct file *filep; - /* This appears to be a file-to-socket transfer. Get the thread- - * specific file list. + /* This appears to be a file-to-socket transfer. Get the file + * structure. */ - list = sched_getfiles(); - DEBUGASSERT(list); + filep = fs_getfilep(fd); + if (!filep) + { + /* The errno value has already been set */ + + return ERROR; + } /* Then let net_sendfile do the work. */ - return net_sendfile(outfd, &list->fl_files[infd], offset, count); + return net_sendfile(outfd, filep, offset, count); } else #endif diff --git a/fs/vfs/fs_write.c b/fs/vfs/fs_write.c index 1c0ab8ea171..830e56dcc02 100644 --- a/fs/vfs/fs_write.c +++ b/fs/vfs/fs_write.c @@ -1,7 +1,7 @@ /**************************************************************************** * fs/vfs/fs_write.c * - * Copyright (C) 2007-2009, 2012-2013 Gregory Nutt. All rights reserved. + * Copyright (C) 2007-2009, 2012-2014 Gregory Nutt. All rights reserved. * Author: Gregory Nutt * * Redistribution and use in source and binary forms, with or without @@ -55,33 +55,28 @@ * Private Functions ****************************************************************************/ -#if CONFIG_NFILE_DESCRIPTORS > 0 -static inline ssize_t file_write(int fd, FAR const void *buf, size_t nbytes) +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: file_write + * + * Description: + * Equivalent to the standard write() function except that is accepts a + * struct file instance instead of a file descriptor. Currently used + * only by aio_write(); + * + ****************************************************************************/ + +ssize_t file_write(FAR struct file *filep, FAR const void *buf, size_t nbytes) { - FAR struct filelist *list; - FAR struct file *filep; FAR struct inode *inode; int ret; int err; - /* Get the thread-specific file list */ - - list = sched_getfiles(); - - /* The file list can be NULL under one obscure cornercase: When memory - * management debug output is enabled. Then there may be attempts to - * write to stdout from malloc before the group data has been allocated. - */ - - if (!list) - { - err = EAGAIN; - goto errout; - } - /* Was this file opened for write access? */ - filep = &list->fl_files[fd]; if ((filep->f_oflags & O_WROK) == 0) { err = EBADF; @@ -112,11 +107,6 @@ static inline ssize_t file_write(int fd, FAR const void *buf, size_t nbytes) set_errno(err); return ERROR; } -#endif - -/**************************************************************************** - * Public Functions - ****************************************************************************/ /*************************************************************************** * Name: write @@ -170,6 +160,10 @@ static inline ssize_t file_write(int fd, FAR const void *buf, size_t nbytes) ssize_t write(int fd, FAR const void *buf, size_t nbytes) { +#if CONFIG_NFILE_DESCRIPTORS > 0 + FAR struct file *filep; +#endif + /* Did we get a valid file descriptor? */ #if CONFIG_NFILE_DESCRIPTORS > 0 @@ -186,10 +180,21 @@ ssize_t write(int fd, FAR const void *buf, size_t nbytes) #endif } - /* The descriptor is in the right range to be a file descriptor... write to the file */ - #if CONFIG_NFILE_DESCRIPTORS > 0 - return file_write(fd, buf, nbytes); + /* The descriptor is in the right range to be a file descriptor... write + * to the file. + */ + + filep = fs_getfilep(fd); + if (!filep) + { + /* The errno value has already been set */ + + return ERROR; + } + + /* Perform the write operation using the file descriptor as an index */ + + return file_write(filep, buf, nbytes); #endif } - diff --git a/include/nuttx/fs/fs.h b/include/nuttx/fs/fs.h index 46cf47f8778..077b9800b21 100644 --- a/include/nuttx/fs/fs.h +++ b/include/nuttx/fs/fs.h @@ -44,6 +44,7 @@ #include #include +#include #include #include #include @@ -505,7 +506,7 @@ void files_releaselist(FAR struct filelist *list); #endif /**************************************************************************** - * Name: files_dup + * Name: file_dup2 * * Description: * Assign an inode to a specific files structure. This is the heart of @@ -514,12 +515,12 @@ void files_releaselist(FAR struct filelist *list); ****************************************************************************/ #if CONFIG_NFILE_DESCRIPTORS > 0 -int files_dup(FAR struct file *filep1, FAR struct file *filep2); +int file_dup2(FAR struct file *filep1, FAR struct file *filep2); #endif /* fs_filedup.c *************************************************************/ /**************************************************************************** - * Name: file_dup OR dup + * Name: fs_dupfd OR dup * * Description: * Clone a file descriptor 'fd' to an arbitray descriptor number (any value @@ -534,12 +535,24 @@ int files_dup(FAR struct file *filep1, FAR struct file *filep2); ****************************************************************************/ #if CONFIG_NFILE_DESCRIPTORS > 0 -int file_dup(int fd, int minfd); +int fs_dupfd(int fd, int minfd); #endif +/**************************************************************************** + * Name: file_dup + * + * Description: + * Equivalent to the non-standard fs_dupfd() function except that it + * accepts a struct file instance instead of a file descriptor. Currently + * used only by file_vfcntl(); + * + ****************************************************************************/ + +int file_dup(FAR struct file *filep, int minfd); + /* fs_filedup2.c ************************************************************/ /**************************************************************************** - * Name: file_dup2 OR dup2 + * Name: fs_dupfd2 OR dup2 * * Description: * Clone a file descriptor to a specific descriptor number. If socket @@ -554,9 +567,9 @@ int file_dup(int fd, int minfd); #if CONFIG_NFILE_DESCRIPTORS > 0 #if defined(CONFIG_NET) && CONFIG_NSOCKET_DESCRIPTORS > 0 -int file_dup2(int fd1, int fd2); +int fs_dupfd2(int fd1, int fd2); #else -# define file_dup2(fd1, fd2) dup2(fd1, fd2) +# define fs_dupfd2(fd1, fd2) dup2(fd1, fd2) #endif #endif @@ -653,22 +666,92 @@ int lib_flushall(FAR struct streamlist *list); ssize_t lib_sendfile(int outfd, int infd, off_t *offset, size_t count); #endif -/* fs/fs_fileread.c *********************************************************/ +/* fs/fs_getfilep.c *********************************************************/ +/**************************************************************************** + * Name: fs_getfilep + * + * Description: + * Given a file descriptor, return the corresponding instance of struct + * file. NOTE that this function will currently fail if it is provided + * with a socket descriptor. + * + * Parameters: + * fd - The file descriptor + * + * Return: + * A point to the corresponding struct file instance is returned on + * success. On failure, NULL is returned and the errno value is + * set appropriately (EBADF). + * + ****************************************************************************/ + +#if CONFIG_NFILE_DESCRIPTORS > 0 +FAR struct file *fs_getfilep(int fd); +#endif + +/* fs/fs_read.c *************************************************************/ /**************************************************************************** * Name: file_read * * Description: * Equivalent to the standard read() function except that is accepts a * struct file instance instead of a file descriptor. Currently used - * only by net_sendfile() + * only by net_sendfile() and aio_read(); * ****************************************************************************/ -#if CONFIG_NFILE_DESCRIPTORS > 0 && defined(CONFIG_NET_SENDFILE) +#if CONFIG_NFILE_DESCRIPTORS > 0 ssize_t file_read(FAR struct file *filep, FAR void *buf, size_t nbytes); #endif -/* fs/fs_fileread.c *********************************************************/ +/* fs/fs_write.c ************************************************************/ +/**************************************************************************** + * Name: file_write + * + * Description: + * Equivalent to the standard write() function except that is accepts a + * struct file instance instead of a file descriptor. Currently used + * only by aio_write(); + * + ****************************************************************************/ + +#if CONFIG_NFILE_DESCRIPTORS > 0 +ssize_t file_write(FAR struct file *filep, FAR const void *buf, size_t nbytes); +#endif + +/* fs/fs_pread.c ************************************************************/ +/**************************************************************************** + * Name: file_pread + * + * Description: + * Equivalent to the standard pread function except that is accepts a + * struct file instance instead of a file descriptor. Currently used + * only by aio_read(); + * + ****************************************************************************/ + +#if CONFIG_NFILE_DESCRIPTORS > 0 +ssize_t file_pread(FAR struct file *filep, FAR void *buf, size_t nbytes, + off_t offset); +#endif + +/* fs/fs_pwrite.c ***********************************************************/ +/**************************************************************************** + * Name: file_pwrite + * + * Description: + * Equivalent to the standard pwrite function except that is accepts a + * struct file instance instead of a file descriptor. Currently used + * only by aio_write(); + * + ****************************************************************************/ + +#if CONFIG_NFILE_DESCRIPTORS > 0 +ssize_t file_pwrite(FAR struct file *filep, FAR const void *buf, + size_t nbytes, off_t offset); +#endif + +/* fs/fs_lseek.c ************************************************************/ /**************************************************************************** * Name: file_seek * @@ -679,10 +762,40 @@ ssize_t file_read(FAR struct file *filep, FAR void *buf, size_t nbytes); * ****************************************************************************/ -#if CONFIG_NFILE_DESCRIPTORS > 0 && defined(CONFIG_NET_SENDFILE) +#if CONFIG_NFILE_DESCRIPTORS > 0 off_t file_seek(FAR struct file *filep, off_t offset, int whence); #endif +/* fs/fs_fsync.c ************************************************************/ +/**************************************************************************** + * Name: file_fsync + * + * Description: + * Equivalent to the standard fsync() function except that is accepts a + * struct file instance instead of a file descriptor. Currently used + * only by aio_fsync(); + * + ****************************************************************************/ + +#if CONFIG_NFILE_DESCRIPTORS > 0 +int file_fsync(FAR struct file *filep); +#endif + +/* fs/fs_fcntl.c ************************************************************/ +/**************************************************************************** + * Name: file_vfcntl + * + * Description: + * Similar to the standard vfcntl function except that is accepts a struct + * struct file instance instead of a file descriptor. Currently used + * only by aio_fcntl(); + * + ****************************************************************************/ + +#if CONFIG_NFILE_DESCRIPTORS > 0 +int file_vfcntl(FAR struct file *filep, int cmd, va_list ap); +#endif + /* drivers/dev_null.c *******************************************************/ /**************************************************************************** * Name: devnull_register diff --git a/include/nuttx/net/net.h b/include/nuttx/net/net.h index b37f14a0435..f2cf839b323 100644 --- a/include/nuttx/net/net.h +++ b/include/nuttx/net/net.h @@ -871,7 +871,7 @@ int net_poll(int sockfd, struct pollfd *fds, bool setup); #endif /**************************************************************************** - * Function: net_dup + * Function: net_dupsd * * Description: * Clone a socket descriptor to an arbitray descriptor number. If file @@ -881,10 +881,10 @@ int net_poll(int sockfd, struct pollfd *fds, bool setup); * ****************************************************************************/ -int net_dup(int sockfd, int minsd); +int net_dupsd(int sockfd, int minsd); /**************************************************************************** - * Function: net_dup2 + * Function: net_dupsd2 * * Description: * Clone a socket descriptor to an arbitray descriptor number. If file @@ -894,13 +894,13 @@ int net_dup(int sockfd, int minsd); * ****************************************************************************/ -int net_dup2(int sockfd1, int sockfd2); +int net_dupsd2(int sockfd1, int sockfd2); /**************************************************************************** * Function: net_clone * * Description: - * Performs the low level, common portion of net_dup() and net_dup2() + * Performs the low level, common portion of net_dupsd() and net_dupsd2() * ****************************************************************************/ diff --git a/net/socket/Make.defs b/net/socket/Make.defs index 7cc4a4be651..44645261ad7 100644 --- a/net/socket/Make.defs +++ b/net/socket/Make.defs @@ -36,7 +36,7 @@ # Include socket source files SOCK_CSRCS += bind.c connect.c getsockname.c recv.c recvfrom.c socket.c -SOCK_CSRCS += sendto.c net_sockets.c net_close.c net_dup.c net_dup2.c +SOCK_CSRCS += sendto.c net_sockets.c net_close.c net_dupsd.c net_dupsd2.c SOCK_CSRCS += net_clone.c net_poll.c net_vfcntl.c # TCP/IP support diff --git a/net/socket/net_clone.c b/net/socket/net_clone.c index 94a1436728b..4c761857d18 100644 --- a/net/socket/net_clone.c +++ b/net/socket/net_clone.c @@ -60,7 +60,7 @@ * Function: net_clone * * Description: - * Performs the low level, common portion of net_dup() and net_dup2() + * Performs the low level, common portion of net_dupsd() and net_dupsd2() * ****************************************************************************/ diff --git a/net/socket/net_dup.c b/net/socket/net_dupsd.c similarity index 98% rename from net/socket/net_dup.c rename to net/socket/net_dupsd.c index 0c8a35c0b19..3d286923e8b 100644 --- a/net/socket/net_dup.c +++ b/net/socket/net_dupsd.c @@ -1,5 +1,5 @@ /**************************************************************************** - * net/socket/net_dup.c + * net/socket/net_dupsd.c * * Copyright (C) 2009 Gregory Nutt. All rights reserved. * Author: Gregory Nutt @@ -57,7 +57,7 @@ ****************************************************************************/ /**************************************************************************** - * Function: net_dup + * Function: net_dupsd * * Description: * Clone a socket descriptor to an arbitray descriptor number. If file @@ -67,7 +67,7 @@ * ****************************************************************************/ -int net_dup(int sockfd, int minsd) +int net_dupsd(int sockfd, int minsd) { FAR struct socket *psock1 = sockfd_socket(sockfd); FAR struct socket *psock2; diff --git a/net/socket/net_dup2.c b/net/socket/net_dupsd2.c similarity index 97% rename from net/socket/net_dup2.c rename to net/socket/net_dupsd2.c index 0631237224e..2919b4374c3 100644 --- a/net/socket/net_dup2.c +++ b/net/socket/net_dupsd2.c @@ -1,5 +1,5 @@ /**************************************************************************** - * net/socket/net_dup2.c + * net/socket/net_dupsd2.c * * Copyright (C) 2009, 2011 Gregory Nutt. All rights reserved. * Author: Gregory Nutt @@ -53,7 +53,7 @@ ****************************************************************************/ /**************************************************************************** - * Function: net_dup2 + * Function: net_dupsd2 * * Description: * Clone a socket descriptor to an arbitray descriptor number. If file @@ -64,7 +64,7 @@ ****************************************************************************/ #if CONFIG_NFILE_DESCRIPTORS > 0 -int net_dup2(int sockfd1, int sockfd2) +int net_dupsd2(int sockfd1, int sockfd2) #else int dup2(int sockfd1, int sockfd2) #endif diff --git a/net/socket/net_vfcntl.c b/net/socket/net_vfcntl.c index 2c79197ee85..7ec6f48d782 100644 --- a/net/socket/net_vfcntl.c +++ b/net/socket/net_vfcntl.c @@ -108,7 +108,7 @@ int net_vfcntl(int sockfd, int cmd, va_list ap) */ { - ret = net_dup(sockfd, va_arg(ap, int)); + ret = net_dupsd(sockfd, va_arg(ap, int)); } break; diff --git a/sched/group/group_setupidlefiles.c b/sched/group/group_setupidlefiles.c index 55cd0ba02fe..a18af782abd 100644 --- a/sched/group/group_setupidlefiles.c +++ b/sched/group/group_setupidlefiles.c @@ -113,8 +113,8 @@ int group_setupidlefiles(FAR struct task_tcb_s *tcb) { /* Successfully opened /dev/console as stdin (fd == 0) */ - (void)file_dup2(0, 1); - (void)file_dup2(0, 2); + (void)fs_dupfd2(0, 1); + (void)fs_dupfd2(0, 2); } else { diff --git a/sched/group/group_setuptaskfiles.c b/sched/group/group_setuptaskfiles.c index 978dc4400e6..a1db88023f7 100644 --- a/sched/group/group_setuptaskfiles.c +++ b/sched/group/group_setuptaskfiles.c @@ -120,7 +120,7 @@ static inline void sched_dupfiles(FAR struct task_tcb_s *tcb) { /* Yes... duplicate it for the child */ - (void)files_dup(&parent[i], &child[i]); + (void)file_dup2(&parent[i], &child[i]); } } }