apps/examples/userfs: Fixes a bug with double freeing open data when dup'ed files are closed.

This commit is contained in:
Gregory Nutt 2017-11-05 17:43:04 -06:00
parent 9ce13f74e7
commit 3dd64af3db

View File

@ -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;
} }