apps/examples/userfs: Fixes a bug with double freeing open data when dup'ed files are closed.
This commit is contained in:
parent
9ce13f74e7
commit
3dd64af3db
@ -83,6 +83,7 @@ struct ufstest_file_s
|
|||||||
struct ufstest_openfile_s
|
struct ufstest_openfile_s
|
||||||
{
|
{
|
||||||
int16_t pos;
|
int16_t pos;
|
||||||
|
int16_t crefs;
|
||||||
FAR struct ufstest_file_s *file;
|
FAR struct ufstest_file_s *file;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -110,7 +111,7 @@ static int ufstest_ioctl(FAR void *volinfo, FAR void *openinfo, int cmd,
|
|||||||
unsigned long arg);
|
unsigned long arg);
|
||||||
static int ufstest_sync(FAR void *volinfo, FAR void *openinfo);
|
static int ufstest_sync(FAR void *volinfo, FAR void *openinfo);
|
||||||
static int ufstest_dup(FAR void *volinfo, FAR void *oldinfo,
|
static int ufstest_dup(FAR void *volinfo, FAR void *oldinfo,
|
||||||
FAR void *newinfo);
|
FAR void **newinfo);
|
||||||
static int ufstest_fstat(FAR void *volinfo, FAR void *openinfo,
|
static int ufstest_fstat(FAR void *volinfo, FAR void *openinfo,
|
||||||
FAR struct stat *buf);
|
FAR struct stat *buf);
|
||||||
static int ufstest_opendir(FAR void *volinfo, FAR const char *relpath,
|
static int ufstest_opendir(FAR void *volinfo, FAR const char *relpath,
|
||||||
@ -243,6 +244,14 @@ static int ufstest_open(FAR void *volinfo, FAR const char *relpath,
|
|||||||
|
|
||||||
opriv->file = file;
|
opriv->file = file;
|
||||||
|
|
||||||
|
/* Initiallly, there is one refernce count on the open data. This may
|
||||||
|
* be incremented in the event that the file is dup'ed.
|
||||||
|
*/
|
||||||
|
|
||||||
|
opriv->crefs = 1;
|
||||||
|
|
||||||
|
/* Return the opaque reference to the open data */
|
||||||
|
|
||||||
*openinfo = opriv;
|
*openinfo = opriv;
|
||||||
return OK;
|
return OK;
|
||||||
}
|
}
|
||||||
@ -252,9 +261,19 @@ static int ufstest_open(FAR void *volinfo, FAR const char *relpath,
|
|||||||
|
|
||||||
static int ufstest_close(FAR void *volinfo, FAR void *openinfo)
|
static int ufstest_close(FAR void *volinfo, FAR void *openinfo)
|
||||||
{
|
{
|
||||||
if (openinfo != NULL)
|
FAR struct ufstest_openfile_s *opriv =
|
||||||
|
(FAR struct ufstest_openfile_s *)openinfo;
|
||||||
|
|
||||||
|
if (opriv != NULL)
|
||||||
{
|
{
|
||||||
free(openinfo);
|
if (opriv->crefs <= 1)
|
||||||
|
{
|
||||||
|
free(opriv);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
opriv->crefs--;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return OK;
|
return OK;
|
||||||
@ -360,9 +379,18 @@ static int ufstest_sync(FAR void *volinfo, FAR void *openinfo)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static int ufstest_dup(FAR void *volinfo, FAR void *oldinfo,
|
static int ufstest_dup(FAR void *volinfo, FAR void *oldinfo,
|
||||||
FAR void *newinfo)
|
FAR void **newinfo)
|
||||||
{
|
{
|
||||||
memcpy(newinfo, oldinfo, sizeof(struct ufstest_openfile_s));
|
FAR struct ufstest_openfile_s *opriv =
|
||||||
|
(FAR struct ufstest_openfile_s *)oldinfo;
|
||||||
|
|
||||||
|
/* Increment the reference count on the open info */
|
||||||
|
|
||||||
|
opriv->crefs++;
|
||||||
|
|
||||||
|
/* And just copy the openinfo reference */
|
||||||
|
|
||||||
|
*newinfo = oldinfo;
|
||||||
return OK;
|
return OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user