apps/examples/userfs:  Fixes a bug with double freeing open data when dup'ed files are closed.
@@ -83,6 +83,7 @@ struct ufstest_file_s
struct ufstest_openfile_s
{
int16_t pos;
+ int16_t crefs;
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);
static int ufstest_sync(FAR void *volinfo, FAR void *openinfo);
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,
FAR struct stat *buf);
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;
+ /* 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;
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)
{
- if (openinfo != NULL)
+ FAR struct ufstest_openfile_s *opriv =
+ (FAR struct ufstest_openfile_s *)openinfo;
+
+ if (opriv != NULL)
+ {
+ if (opriv->crefs <= 1)
+ {
+ free(opriv);
+ }
+ else
{
- free(openinfo);
+ opriv->crefs--;
+ }
}
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,
- 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;
}
