diff --git a/examples/userfs/userfs_main.c b/examples/userfs/userfs_main.c index a007778e7..f53a75365 100644 --- a/examples/userfs/userfs_main.c +++ b/examples/userfs/userfs_main.c @@ -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) { - free(openinfo); + if (opriv->crefs <= 1) + { + free(opriv); + } + else + { + 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; }