fs_close: provide inotify call for close
Close operation on file should lead to IN_CLOSE_WRITE or IN_CLOSE_NOWRITE notifications. This commits adds the notification support. Notifying on close is a little bit trickier as a lower layer may not have the full file path after successful close and inode release. Calling notification before close is not a solution since close might not end successfully. The solution is to obtain and buffer the path before calling close and then pass the buffered path to the notify_close. This required the change in notify_close function arguments: filep is no longer required, path and oflags are passed instead. Signed-off-by: Michal Lenc <michallenc@seznam.cz>
This commit is contained in:
parent
939c10ea34
commit
531dbaf561
3 changed files with 51 additions and 5 deletions
|
|
@ -1342,15 +1342,15 @@ void notify_open(FAR const char *path, int oflags)
|
|||
*
|
||||
****************************************************************************/
|
||||
|
||||
void notify_close(FAR struct file *filep)
|
||||
void notify_close(FAR const char *path, int oflags)
|
||||
{
|
||||
if (filep->f_oflags & O_WROK)
|
||||
if (oflags & O_WROK)
|
||||
{
|
||||
notify_queue_filep_event(filep, IN_CLOSE_WRITE);
|
||||
notify_queue_path_event(path, IN_CLOSE_WRITE);
|
||||
}
|
||||
else
|
||||
{
|
||||
notify_queue_filep_event(filep, IN_CLOSE_NOWRITE);
|
||||
notify_queue_path_event(path, IN_CLOSE_NOWRITE);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -42,7 +42,7 @@
|
|||
/* These are internal OS interface and are not available to applications */
|
||||
|
||||
void notify_open(FAR const char *path, int oflags);
|
||||
void notify_close(FAR struct file *filep);
|
||||
void notify_close(FAR const char *path, int oflags);
|
||||
void notify_close2(FAR struct inode *inode);
|
||||
void notify_read(FAR struct file *filep);
|
||||
void notify_write(FAR struct file *filep);
|
||||
|
|
|
|||
|
|
@ -36,6 +36,33 @@
|
|||
#include "inode/inode.h"
|
||||
#include "vfs/lock.h"
|
||||
|
||||
/****************************************************************************
|
||||
* Private Functions
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef CONFIG_FS_NOTIFY
|
||||
static FAR char *file_get_path(FAR struct file *filep)
|
||||
{
|
||||
FAR char *pathbuffer;
|
||||
int ret;
|
||||
|
||||
pathbuffer = lib_get_pathbuffer();
|
||||
if (pathbuffer == NULL)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ret = file_fcntl(filep, F_GETPATH, pathbuffer);
|
||||
if (ret < 0)
|
||||
{
|
||||
lib_put_pathbuffer(pathbuffer);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return pathbuffer;
|
||||
}
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
****************************************************************************/
|
||||
|
|
@ -60,11 +87,22 @@
|
|||
int file_close_without_clear(FAR struct file *filep)
|
||||
{
|
||||
struct inode *inode;
|
||||
#ifdef CONFIG_FS_NOTIFY
|
||||
FAR char *path;
|
||||
#endif
|
||||
int ret = OK;
|
||||
|
||||
DEBUGASSERT(filep != NULL);
|
||||
inode = filep->f_inode;
|
||||
|
||||
#ifdef CONFIG_FS_NOTIFY
|
||||
/* We lose the path and inode during close and release, so obtain it
|
||||
* in advance. Then we pass it to notify_close function.
|
||||
*/
|
||||
|
||||
path = file_get_path(filep);
|
||||
#endif
|
||||
|
||||
/* Check if the struct file is open (i.e., assigned an inode) */
|
||||
|
||||
if (inode)
|
||||
|
|
@ -84,6 +122,14 @@ int file_close_without_clear(FAR struct file *filep)
|
|||
|
||||
if (ret >= 0)
|
||||
{
|
||||
#ifdef CONFIG_FS_NOTIFY
|
||||
if (path != NULL)
|
||||
{
|
||||
notify_close(path, filep->f_oflags);
|
||||
lib_put_pathbuffer(path);
|
||||
}
|
||||
#endif
|
||||
|
||||
inode_release(inode);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue