summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--nuttx/ChangeLog1
-rw-r--r--nuttx/Documentation/NuttX.html1
-rw-r--r--nuttx/TODO6
-rw-r--r--nuttx/fs/fs_close.c27
-rw-r--r--nuttx/fs/fs_files.c135
-rw-r--r--nuttx/fs/fs_internal.h1
6 files changed, 99 insertions, 72 deletions
diff --git a/nuttx/ChangeLog b/nuttx/ChangeLog
index 39d4fa603..be4610ec0 100644
--- a/nuttx/ChangeLog
+++ b/nuttx/ChangeLog
@@ -383,6 +383,7 @@
* Added a test for redirection of stdio through pipes
* Fixed error in dup and dup2: Must call open/close methods in fs/driver so that
driver can correctly maintain open reference counts.
+ * Same issue on closing file descriptors in exit()
* Fixed in error in stdio flush logic. Needed ssize_t vs size_t for error
check.
diff --git a/nuttx/Documentation/NuttX.html b/nuttx/Documentation/NuttX.html
index e7a60182c..e75d27e30 100644
--- a/nuttx/Documentation/NuttX.html
+++ b/nuttx/Documentation/NuttX.html
@@ -1032,6 +1032,7 @@ nuttx-0.3.12 2008-xx-xx Gregory Nutt <spudmonkey@racsa.co.cr>
* Added a test for redirection of stdio through pipes
* Fixed error in dup and dup2: Must call open/close methods in fs/driver so that
driver can correctly maintain open reference counts.
+ * Same issue on closing file descriptors in exit()
* Fixed in error in stdio flush logic. Needed ssize_t vs size_t for error
check.
diff --git a/nuttx/TODO b/nuttx/TODO
index bc9187550..66399c13f 100644
--- a/nuttx/TODO
+++ b/nuttx/TODO
@@ -242,12 +242,6 @@ o File system / Generic drivers (fs/, drivers/)
when there are not open references to the pipe/FIFO.
Priority: Medium
- Desccripton: dup and dup2 need to call into driver. Most drivers
- will maintain internal open counts. dup and dup2 logically
- increase the open count but do not interact with the driver
- Status: Open
- Priority: Medium
-
o Pascal Add-On (pcode/)
^^^^^^^^^^^^^^^^^^^^^^
diff --git a/nuttx/fs/fs_close.c b/nuttx/fs/fs_close.c
index 736788a2e..6a152540d 100644
--- a/nuttx/fs/fs_close.c
+++ b/nuttx/fs/fs_close.c
@@ -82,7 +82,7 @@ int close(int fd)
int err;
#if CONFIG_NFILE_DESCRIPTORS > 0
FAR struct filelist *list;
- FAR struct inode *inode;
+ int ret;
/* Did we get a valid file descriptor? */
@@ -116,8 +116,7 @@ int close(int fd)
/* If the file was properly opened, there should be an inode assigned */
- inode = list->fl_files[fd].f_inode;
- if (!inode)
+ if (!list->fl_files[fd].f_inode)
{
err = EBADF;
goto errout;
@@ -133,30 +132,18 @@ int close(int fd)
* vtable.
*/
- if (inode->u.i_ops && inode->u.i_ops->close)
+ ret = files_close(&list->fl_files[fd]);
+ if (ret < 0)
{
- /* Perform the close operation (by the driver) */
+ /* An error occurred while closing the driver */
- int ret = inode->u.i_ops->close(&list->fl_files[fd]);
- if (ret < 0)
- {
- /* An error occurred while closing the driver */
-
- err = -ret;
- goto errout;
- }
+ err = -ret;
+ goto errout;
}
/* 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;
#endif
diff --git a/nuttx/fs/fs_files.c b/nuttx/fs/fs_files.c
index 6f4941dce..30b3caca9 100644
--- a/nuttx/fs/fs_files.c
+++ b/nuttx/fs/fs_files.c
@@ -67,6 +67,9 @@
* Private Functions
****************************************************************************/
+/****************************************************************************
+ * Name: _files_semtake
+ ****************************************************************************/
static void _files_semtake(FAR struct filelist *list)
{
/* Take the semaphore (perhaps waiting) */
@@ -81,22 +84,32 @@ static void _files_semtake(FAR struct filelist *list)
}
}
+/****************************************************************************
+ * Name: _files_semgive
+ ****************************************************************************/
#define _files_semgive(list) sem_post(&list->fl_sem)
/****************************************************************************
- * Pulblic Functions
+ * Public Functions
****************************************************************************/
-/* This is called from the FS initialization logic to configure
- * the files.
- */
-
+/****************************************************************************
+ * Name: files_initialize
+ *
+ * Description:
+ * This is called from the FS initialization logic to configure the files.
+ *
+ ****************************************************************************/
void files_initialize(void)
{
}
-/* Allocate a list of files for a new task */
-
+/****************************************************************************
+ * Name: files_alloclist
+ *
+ * Description: Allocate a list of files for a new task
+ *
+ ****************************************************************************/
FAR struct filelist *files_alloclist(void)
{
FAR struct filelist *list;
@@ -114,8 +127,12 @@ FAR struct filelist *files_alloclist(void)
return list;
}
-/* Increase the reference count on a file list */
-
+/****************************************************************************
+ * Name: files_addreflist
+ *
+ * Description: Increase the reference count on a file list
+ *
+ ****************************************************************************/
int files_addreflist(FAR struct filelist *list)
{
if (list)
@@ -135,8 +152,44 @@ int files_addreflist(FAR struct filelist *list)
return OK;
}
-/* Release a reference to the file list */
+/****************************************************************************
+ * Name: files_close
+ *
+ * Description: Close an inode (if open)
+ *
+ ****************************************************************************/
+int files_close(FAR struct file *filep)
+{
+ struct inode *inode = filep->f_inode;
+ int ret = OK;
+ /* Check if the struct file is open (i.e., assigned an inode) */
+
+ if (inode)
+ {
+ /* Close the file, driver, or mountpoint. */
+
+ if (inode->u.i_ops && inode->u.i_ops->close)
+ {
+ /* Perform the close operation */
+
+ ret = inode->u.i_ops->close(filep);
+ }
+
+ /* And release the inode */
+
+ inode_release(inode);
+ filep->f_inode = NULL;
+ }
+ return ret;
+}
+
+/****************************************************************************
+ * Name: files_releaselist
+ *
+ * Description: Release a reference to the file list
+ *
+ ****************************************************************************/
int files_releaselist(FAR struct filelist *list)
{
int crefs;
@@ -168,26 +221,25 @@ int files_releaselist(FAR struct filelist *list)
for (i = 0; i < CONFIG_NFILE_DESCRIPTORS; i++)
{
- FAR struct inode *inode = list->fl_files[i].f_inode;
- if (inode)
- {
- inode_release(inode);
- }
+ (void)files_close(&list->fl_files[i]);
}
- /* Destroy the semaphore and release the filelist */
+ /* Destroy the semaphore and release the filelist */
- (void)sem_destroy(&list->fl_sem);
- sched_free(list);
+ (void)sem_destroy(&list->fl_sem);
+ sched_free(list);
}
}
return OK;
}
-/* Assign an inode to a specific files structure. this is the
- * heart of dup2.
- */
-
+/****************************************************************************
+ * Name: files_dup
+ *
+ * Description:
+ * Assign an inode to a specific files structure. This is the heart of dup2.
+ *
+ ****************************************************************************/
int files_dup(FAR struct file *filep1, FAR struct file *filep2)
{
FAR struct filelist *list;
@@ -222,27 +274,12 @@ int files_dup(FAR struct file *filep1, FAR struct file *filep2)
* close the file and release the inode.
*/
- inode = filep2->f_inode;
- if (inode)
+ ret = files_close(filep2);
+ if (ret < 0)
{
- /* Close the file, driver, or mountpoint. */
+ /* An error occurred while closing the driver */
- if (inode->u.i_ops && inode->u.i_ops->close)
- {
- /* Perform the close operation */
-
- ret = inode->u.i_ops->close(filep2);
- if (ret < 0)
- {
- /* An error occurred while closing the driver */
-
- goto errout_with_ret;
- }
- }
-
- /* Release the inode */
-
- inode_release(filep2->f_inode);
+ goto errout_with_ret;
}
/* Increment the reference count on the contained inode */
@@ -304,11 +341,14 @@ errout:
return ERROR;
}
-/* Allocate a struct files instance and associate it with an
- * inode instance. Returns the file descriptor == index into
- * the files array.
- */
-
+/****************************************************************************
+ * Name: files_allocate
+ *
+ * Description:
+ * Allocate a struct files instance and associate it with an inode instance.
+ * Returns the file descriptor == index into the files array.
+ *
+ ****************************************************************************/
int files_allocate(FAR struct inode *inode, int oflags, off_t pos)
{
FAR struct filelist *list;
@@ -334,6 +374,9 @@ int files_allocate(FAR struct inode *inode, int oflags, off_t pos)
return ERROR;
}
+/****************************************************************************
+ * Name: files_release
+ ****************************************************************************/
void files_release(int filedes)
{
FAR struct filelist *list;
diff --git a/nuttx/fs/fs_internal.h b/nuttx/fs/fs_internal.h
index b20843d2f..936761d4a 100644
--- a/nuttx/fs/fs_internal.h
+++ b/nuttx/fs/fs_internal.h
@@ -210,6 +210,7 @@ EXTERN void inode_release(FAR struct inode *inode);
EXTERN void weak_function files_initialize(void);
EXTERN int files_allocate(FAR struct inode *inode, int oflags, off_t pos);
EXTERN void files_release(int filedes);
+EXTERN int files_close(struct file *filep);
#undef EXTERN
#if defined(__cplusplus)