Mike McCormack : server: Add directories to recursive watches as they'
re opened.
Alexandre Julliard
julliard at wine.codeweavers.com
Thu Feb 23 05:55:33 CST 2006
Module: wine
Branch: refs/heads/master
Commit: 42121085985b3995692c4b40ee1b127963785223
URL: http://source.winehq.org/git/?p=wine.git;a=commit;h=42121085985b3995692c4b40ee1b127963785223
Author: Mike McCormack <mike at codeweavers.com>
Date: Thu Feb 23 00:45:34 2006 +0900
server: Add directories to recursive watches as they're opened.
---
server/change.c | 106 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
1 files changed, 106 insertions(+), 0 deletions(-)
diff --git a/server/change.c b/server/change.c
index 923bbce..4a8d222 100644
--- a/server/change.c
+++ b/server/change.c
@@ -934,6 +934,105 @@ static int inotify_adjust_changes( struc
return 1;
}
+static char *get_basename( const char *link )
+{
+ char *buffer, *name = NULL;
+ int r, n = 0x100;
+
+ while (1)
+ {
+ buffer = malloc( n );
+ if (!buffer) break;
+
+ r = readlink( link, buffer, n );
+ if (r < 0)
+ break;
+
+ if (r < n)
+ {
+ name = buffer;
+ break;
+ }
+ free( buffer );
+ n *= 2;
+ }
+
+ if (name)
+ {
+ while (r > 0 && name[ r - 1 ] == '/' )
+ r--;
+ name[ r ] = 0;
+
+ name = strrchr( name, '/' );
+ if (name)
+ name = strdup( &name[1] );
+ }
+
+ free( buffer );
+ return name;
+}
+
+static int dir_add_to_existing_notify( struct dir *dir )
+{
+ struct inode *inode, *parent;
+ unsigned int filter = 0;
+ struct stat st, st_new;
+ char link[35], *name;
+ int wd, unix_fd;
+
+ if (!inotify_fd)
+ return 0;
+
+ unix_fd = get_unix_fd( dir->fd );
+
+ /* check if it's in the list of inodes we want to watch */
+ if (-1 == fstat( unix_fd, &st_new ))
+ return 0;
+ inode = find_inode( st_new.st_dev, st_new.st_ino );
+ if (inode)
+ return 0;
+
+ /* lookup the parent */
+ sprintf( link, "/proc/self/fd/%u/..", unix_fd );
+ if (-1 == stat( link, &st ))
+ return 0;
+
+ /*
+ * If there's no parent, stop. We could keep going adding
+ * ../ to the path until we hit the root of the tree or
+ * find a recursively watched ancestor.
+ * Assume it's too expensive to search up the tree for now.
+ */
+ parent = find_inode( st.st_dev, st.st_ino );
+ if (!parent)
+ return 0;
+
+ if (parent->wd == -1)
+ return 0;
+
+ filter = filter_from_inode( parent, 1 );
+ if (!filter)
+ return 0;
+
+ sprintf( link, "/proc/self/fd/%u", unix_fd );
+ name = get_basename( link );
+ if (!name)
+ return 0;
+ inode = inode_add( parent, st_new.st_dev, st_new.st_ino, name );
+ free( name );
+ if (!inode)
+ return 0;
+
+ /* Couldn't find this inode at the start of the function, must be new */
+ assert( inode->wd == -1 );
+
+ wd = inotify_add_dir( link, filter );
+ if (wd != -1)
+ inode_set_wd( inode, wd );
+
+ return 1;
+}
+
#else
static int init_inotify( void )
@@ -951,6 +1050,11 @@ static void free_inode( struct inode *in
assert( 0 );
}
+static int dir_add_to_existing_notify( struct dir *dir )
+{
+ return 0;
+}
+
#endif /* USE_INOTIFY */
struct object *create_dir_obj( struct fd *fd )
@@ -973,6 +1077,8 @@ struct object *create_dir_obj( struct fd
dir->fd = fd;
set_fd_user( fd, &dir_fd_ops, &dir->obj );
+ dir_add_to_existing_notify( dir );
+
return &dir->obj;
}
More information about the wine-cvs
mailing list