Skip to content

Commit

Permalink
fs: file_dup2 shouldn't destroy filep2 before the duplication of file…
Browse files Browse the repository at this point in the history
…p1 succeed

Signed-off-by: Xiang Xiao <xiaoxiang@xiaomi.com>
Change-Id: I10956f5e32cc0add414076465c06a24a858e52bc
  • Loading branch information
xiaoxiang781216 authored and anchao committed Jan 8, 2021
1 parent 2889315 commit b343caa
Showing 1 changed file with 19 additions and 22 deletions.
41 changes: 19 additions & 22 deletions fs/inode/fs_files.c
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,7 @@ int file_dup2(FAR struct file *filep1, FAR struct file *filep2)
{
FAR struct filelist *list;
FAR struct inode *inode;
struct file temp;
int ret;

if (filep1 == NULL || filep1->f_inode == NULL || filep2 == NULL)
Expand Down Expand Up @@ -169,18 +170,6 @@ int file_dup2(FAR struct file *filep1, FAR struct file *filep2)
}
}

/* If there is already an inode contained in the new file structure,
* close the file and release the inode.
*/

ret = file_close(filep2);
if (ret < 0)
{
/* An error occurred while closing the driver */

goto errout_with_sem;
}

/* Increment the reference count on the contained inode */

inode = filep1->f_inode;
Expand All @@ -192,9 +181,10 @@ int file_dup2(FAR struct file *filep1, FAR struct file *filep2)

/* Then clone the file structure */

filep2->f_oflags = filep1->f_oflags;
filep2->f_pos = filep1->f_pos;
filep2->f_inode = inode;
temp.f_oflags = filep1->f_oflags;
temp.f_pos = filep1->f_pos;
temp.f_inode = inode;
temp.f_priv = filep1->f_priv;

/* Call the open method on the file, driver, mountpoint so that it
* can maintain the correct open counts.
Expand All @@ -207,14 +197,14 @@ int file_dup2(FAR struct file *filep1, FAR struct file *filep2)
{
/* Dup the open file on the in the new file structure */

ret = inode->u.i_mops->dup(filep1, filep2);
ret = inode->u.i_mops->dup(filep1, &temp);
}
else
#endif
{
/* (Re-)open the pseudo file or device driver */

ret = inode->u.i_ops->open(filep2);
ret = inode->u.i_ops->open(&temp);
}

/* Handle open failures */
Expand All @@ -225,6 +215,17 @@ int file_dup2(FAR struct file *filep1, FAR struct file *filep2)
}
}

/* If there is already an inode contained in the new file structure,
* close the file and release the inode.
*/

ret = file_close(filep2);
DEBUGASSERT(ret == 0);

/* Return the file structure */

memcpy(filep2, &temp, sizeof(temp));

if (list != NULL)
{
_files_semgive(list);
Expand All @@ -235,11 +236,7 @@ int file_dup2(FAR struct file *filep1, FAR struct file *filep2)
/* Handle various error conditions */

errout_with_inode:

inode_release(filep2->f_inode);
filep2->f_oflags = 0;
filep2->f_pos = 0;
filep2->f_inode = NULL;
inode_release(inode);

errout_with_sem:
if (list != NULL)
Expand Down

0 comments on commit b343caa

Please sign in to comment.