#pike __REAL_VERSION__ |
#require constant(System._Inotify.parse_event) |
|
|
|
|
|
inherit System._Inotify; |
|
|
|
|
|
|
string describe_mask(int mask) { |
array(string) list = ({}); |
|
foreach (sort(indices(this_program));; string name) { |
if (has_prefix(name, "IN_")) { |
int value = `[](this_program, name); |
|
if (value == (value & mask)) list += ({ name }); |
} |
} |
|
return list * "|"; |
} |
|
class Watch { |
string name; |
function(int, int, string, mixed ...:void) callback; |
int mask; |
array extra; |
|
void create(string name, int mask, |
function(int, int, string, mixed ...:void) callback, |
array extra) { |
this::name = name; |
this::mask = mask; |
this::callback = callback; |
this::extra = extra; |
} |
} |
|
class DirWatch { |
inherit Watch; |
|
void handle_event(int wd, int mask, int cookie, |
int|string name) { |
if (name) { |
name = (has_suffix(this::name, "/") |
? this::name : (this::name+"/")) + name; |
} else { |
name = this::name; |
} |
|
callback(mask, cookie, name, @extra); |
} |
} |
|
class FileWatch { |
inherit Watch; |
|
void handle_event(int wd, int mask, int cookie, |
int|string name) { |
callback(mask, cookie, this::name, @extra); |
} |
} |
|
|
|
|
|
|
|
|
|
|
class Instance { |
inherit _Instance; |
protected mapping(int:object) watches = ([]); |
|
void event_callback(int wd, int event, int cookie, string path) |
{ |
Watch watch = watches[wd]; |
if (watch) { |
if (event == IN_IGNORED) { |
m_delete(watches, wd); |
werror("Watch %O (wd: %d) deleted.\n", watch, wd); |
} |
watch->handle_event(wd, event, cookie, path); |
} |
} |
|
void create() { |
set_event_callback(event_callback); |
set_nonblocking(); |
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
int add_watch(string filename, int mask, |
function(int, int, string, mixed ...:void) callback, |
mixed ... extra) |
{ |
int wd = ::add_watch(filename, mask); |
|
|
# if constant(@module@.IN_MASK_ADD) |
|
* just in case we want to use the mask in the watches later, |
* they better be correct |
*/ |
if ((mask & IN_MASK_ADD) && has_index(watches, wd)) { |
mask |= watches[wd]->mask; |
} |
# endif |
|
if (Stdio.is_dir(filename)) { |
watches[wd] = DirWatch(filename, mask, callback, extra); |
} else { |
watches[wd] = FileWatch(filename, mask, callback, extra); |
} |
|
return wd; |
} |
} |
|
|