diff --git a/server/change.c b/server/change.c index 0dd7d29d6b6..2bdc444e758 100644 --- a/server/change.c +++ b/server/change.c @@ -94,6 +94,8 @@ struct inotify_event { #define IN_DELETE 0x00000200 #define IN_DELETE_SELF 0x00000400 +#define IN_ISDIR 0x40000000 + static inline int inotify_init( void ) { int ret; @@ -664,6 +666,11 @@ static unsigned int filter_from_event( struct inotify_event *ie ) if (ie->mask & IN_CREATE) filter |= FILE_NOTIFY_CHANGE_CREATION; + if (ie->mask & IN_ISDIR) + filter &= ~FILE_NOTIFY_CHANGE_FILE_NAME; + else + filter &= ~FILE_NOTIFY_CHANGE_DIR_NAME; + return filter; } @@ -719,30 +726,22 @@ static char *inode_get_path( struct inode *inode, int sz ) return path; } -static int inode_check_dir( struct inode *parent, const char *name ) +static void inode_check_dir( struct inode *parent, const char *name ) { char *path; unsigned int filter; struct inode *inode; struct stat st; - int wd = -1, r = -1; + int wd = -1; path = inode_get_path( parent, strlen(name) ); if (!path) - return r; + return; strcat( path, name ); - r = stat( path, &st ); - if (r < 0) goto end; - - if (!S_ISDIR(st.st_mode)) - { - r = 0; + if (stat( path, &st ) < 0) goto end; - } - - r = 1; filter = filter_from_inode( parent, 1 ); if (!filter) @@ -760,7 +759,6 @@ static int inode_check_dir( struct inode *parent, const char *name ) end: free( path ); - return r; } static int prepend( char **path, const char *segment ) @@ -808,22 +806,17 @@ static void inotify_notify_all( struct inotify_event *ie ) if (ie->mask & IN_CREATE) { - switch (inode_check_dir( inode, ie->name )) - { - case 1: - filter &= ~FILE_NOTIFY_CHANGE_FILE_NAME; - break; - case 0: - filter &= ~FILE_NOTIFY_CHANGE_DIR_NAME; - break; - default: - break; - /* Maybe the file disappeared before we could check it? */ - } + if (ie->mask & IN_ISDIR) + inode_check_dir( inode, ie->name ); + action = FILE_ACTION_ADDED; } else if (ie->mask & IN_DELETE) action = FILE_ACTION_REMOVED; + else if (ie->mask & IN_MOVED_FROM) + action = FILE_ACTION_RENAMED_OLD_NAME; + else if (ie->mask & IN_MOVED_TO) + action = FILE_ACTION_RENAMED_NEW_NAME; else action = FILE_ACTION_MODIFIED;