summaryrefslogtreecommitdiff
path: root/nuttx/fs
diff options
context:
space:
mode:
Diffstat (limited to 'nuttx/fs')
-rw-r--r--nuttx/fs/fs_close.c134
-rw-r--r--nuttx/fs/fs_write.c122
2 files changed, 196 insertions, 60 deletions
diff --git a/nuttx/fs/fs_close.c b/nuttx/fs/fs_close.c
index a704d1d5e..5a63ba6a9 100644
--- a/nuttx/fs/fs_close.c
+++ b/nuttx/fs/fs_close.c
@@ -43,70 +43,120 @@
#include <sched.h>
#include <errno.h>
#include <nuttx/fs.h>
+
+#if defined(CONFIG_NET) && CONFIG_NSOCKET_DESCRIPTORS > 0
+# include <nuttx/net.h>
+#endif
+
#include "fs_internal.h"
/****************************************************************************
* Global Functions
****************************************************************************/
+/****************************************************************************
+ * Function: close
+ *
+ * Description:
+ * close() closes a file descriptor, so that it no longer refers to any
+ * file and may be reused. Any record locks (see fcntl(2)) held on the file
+ * it was associated with, and owned by the process, are removed (regardless
+ * of the file descriptor that was used to obtain the lock).
+ *
+ * If fd is the last copy of a particular file descriptor the resources
+ * associated with it are freed; if the descriptor was the last reference
+ * to a file which has been removed using unlink(2) the file is deleted.
+ *
+ * Parameters:
+ * fd file descriptor to close
+ *
+ * Returned Value:
+ * 0 on success; -1 on error with errno set appropriately.
+ *
+ * Assumptions:
+ *
+ ****************************************************************************/
+
int close(int fd)
{
FAR struct filelist *list;
+ FAR struct inode *inode;
+ int err;
+
+ /* Did we get a valid file descriptor? */
+
+ if ((unsigned int)fd >= CONFIG_NFILE_DESCRIPTORS)
+ {
+ /* Close a socket descriptor */
+#if defined(CONFIG_NET) && CONFIG_NSOCKET_DESCRIPTORS > 0
+ if ((unsigned int)fd < (CONFIG_NFILE_DESCRIPTORS+CONFIG_NSOCKET_DESCRIPTORS))
+ {
+ return net_close(fd);
+ }
+ else
+#endif
+ {
+ err = EBADF;
+ goto errout;
+ }
+ }
/* Get the thread-specific file list */
list = sched_getfiles();
if (!list)
{
- *get_errno_ptr() = EMFILE;
- return ERROR;
+ err = EMFILE;
+ goto errout;
}
- if ((unsigned int)fd < CONFIG_NFILE_DESCRIPTORS)
+ /* If the file was properly opened, there should be an inode assigned */
+
+ inode = list->fl_files[fd].f_inode;
+ if (!inode)
+ {
+ err = EBADF;
+ goto errout;
+ }
+
+ /* Close the driver or mountpoint. NOTES: (1) there is no
+ * exclusion mechanism here , the driver or mountpoint must be
+ * able to handle concurrent operations internally, (2) The driver
+ * may have been opened numerous times (for different file
+ * descriptors) and must also handle being closed numerous times.
+ * (3) for the case of the mountpoint, we depend on the close
+ * methods bing identical in signature and position in the operations
+ * vtable.
+ */
+
+ if (inode->u.i_ops && inode->u.i_ops->close)
{
- FAR struct inode *inode = list->fl_files[fd].f_inode;
- if (inode)
+ /* Perform the close operation (by the driver) */
+
+ int ret = inode->u.i_ops->close(&list->fl_files[fd]);
+ if (ret < 0)
{
- int ret = OK;
-
- /* Close the driver or mountpoint. NOTES: (1) there is no
- * exclusion mechanism here , the driver or mountpoint must be
- * able to handle concurrent operations internally, (2) The driver
- * may have been opened numerous times (for different file
- * descriptors) and must also handle being closed numerous times.
- * (3) for the case of the mountpoint, we depend on the close
- * methods bing identical in signature and position in the operations
- * vtable.
- */
-
- if (inode->u.i_ops && inode->u.i_ops->close)
- {
- /* Perform the close operation (by the driver) */
-
- int status = inode->u.i_ops->close(&list->fl_files[fd]);
- if (status < 0)
- {
- /* An error occurred while closing the driver */
-
- *get_errno_ptr() = -status;
- ret = ERROR;
- }
- }
-
- /* Release the file descriptor */
-
- files_release(fd);
-
- /* Decrement the reference count on the inode. This may remove the inode and
- * eliminate the name from the namespace
- */
-
- inode_release(inode);
- return ret;
+ /* An error occurred while closing the driver */
+
+ err = -ret;
+ goto errout;
}
}
- *get_errno_ptr() = EBADF;
+ /* Release the file descriptor */
+
+ files_release(fd);
+
+ /* Decrement the reference count on the inode. This may remove the inode and
+ * eliminate the name from the namespace
+ */
+
+ inode_release(inode);
+
+ return OK;
+
+errout:
+ *get_errno_ptr() = err;
return ERROR;
}
diff --git a/nuttx/fs/fs_write.c b/nuttx/fs/fs_write.c
index 60a6b8290..7de7898f4 100644
--- a/nuttx/fs/fs_write.c
+++ b/nuttx/fs/fs_write.c
@@ -47,48 +47,134 @@
#include <fcntl.h>
#include <sched.h>
#include <errno.h>
+
+#if defined(CONFIG_NET) && CONFIG_NSOCKET_DESCRIPTORS > 0
+# include <sys/socket.h>
+#endif
+
#include "fs_internal.h"
/************************************************************
* Global Functions
************************************************************/
+/****************************************************************************
+ * Function: send
+ *
+ * Description:
+ * write() writes up to nytes bytes to the file referenced by the file
+ * descriptor fd from the buffer starting at buf.
+ *
+ * Parameters:
+ * fd file descriptor (or socket descriptor) to write to
+ * buf Data to write
+ * nbytes Length of data to write
+ *
+ * Returned Value:
+ * On success, the number of bytes written are returned (zero indicates
+ * nothing was written). On error, -1 is returned, and errno is set appro‐
+ * priately:
+ *
+ * EAGAIN
+ * Non-blocking I/O has been selected using O_NONBLOCK and the write
+ * would block.
+ * EBADF
+ * fd is not a valid file descriptor or is not open for writing.
+ * EFAULT
+ * buf is outside your accessible address space.
+ * EFBIG
+ * An attempt was made to write a file that exceeds the implementation
+ * defined maximum file size or the process' file size limit, or
+ * to write at a position past the maximum allowed offset.
+ * EINTR
+ * The call was interrupted by a signal before any data was written.
+ * EINVAL
+ * fd is attached to an object which is unsuitable for writing; or
+ * the file was opened with the O_DIRECT flag, and either the address
+ * specified in buf, the value specified in count, or the current
+ * file offset is not suitably aligned.
+ * EIO
+ * A low-level I/O error occurred while modifying the inode.
+ * ENOSPC
+ * The device containing the file referred to by fd has no room for
+ * the data.
+ * EPIPE
+ * fd is connected to a pipe or socket whose reading end is closed.
+ * When this happens the writing process will also receive a SIGPIPE
+ * signal. (Thus, the write return value is seen only if the program
+ * catches, blocks or ignores this signal.)
+ *
+ * Assumptions:
+ *
+ ****************************************************************************/
+
int write(int fd, const void *buf, unsigned int nbytes)
{
FAR struct filelist *list;
- int ret = EBADF;
+ FAR struct file *this_file;
+ FAR struct inode *inode;
+ int err;
+ int ret;
+
+ /* Did we get a valid file descriptor? */
+
+ if ((unsigned int)fd >= CONFIG_NFILE_DESCRIPTORS)
+ {
+ /* Write to a socket descriptor is equivalent to send with flags == 0 */
+
+#if defined(CONFIG_NET) && CONFIG_NSOCKET_DESCRIPTORS > 0
+ if ((unsigned int)fd < (CONFIG_NFILE_DESCRIPTORS+CONFIG_NSOCKET_DESCRIPTORS))
+ {
+ return send(fd, buf, nbytes, 0);
+ }
+ else
+#endif
+ {
+ err = EBADF;
+ goto errout;
+ }
+ }
/* Get the thread-specific file list */
list = sched_getfiles();
if (!list)
{
- *get_errno_ptr() = EMFILE;
- return ERROR;
+ err = EMFILE;
+ goto errout;
}
- /* Did we get a valid file descriptor? */
+ /* Was this file opened for write access? */
- if ((unsigned int)fd < CONFIG_NFILE_DESCRIPTORS)
+ this_file = &list->fl_files[fd];
+ if ((this_file->f_oflags & O_WROK) == 0)
{
- FAR struct file *this_file = &list->fl_files[fd];
-
- /* Was this file opened for write access? */
+ err = EBADF;
+ goto errout;
+ }
- if ((this_file->f_oflags & O_WROK) != 0)
- {
- struct inode *inode = this_file->f_inode;
+ /* Is a driver registered? Does it support the write method? */
- /* Is a driver registered? Does it support the write method? */
+ inode = this_file->f_inode;
+ if (!inode || !inode->u.i_ops && inode->u.i_ops->write)
+ {
+ err = EBADF;
+ goto errout;
+ }
- if (inode && inode->u.i_ops && inode->u.i_ops->write)
- {
- /* Yes, then let it perform the write */
+ /* Yes, then let the driver perform the write */
- ret = inode->u.i_ops->write(this_file, buf, nbytes);
- }
- }
+ ret = inode->u.i_ops->write(this_file, buf, nbytes);
+ if (ret < 0)
+ {
+ err = -ret;
+ goto errout;
}
+
return ret;
+
+errout:
+ *get_errno_ptr() = err;
+ return ERROR;
}