class SleepyPenguin::Inotify
Inotify
objects are used for monitoring file system events, it can monitor individual files or directories. When a directory is monitored it will return events for the directory itself and all files inside the directory.
Inotify
IO objects can be watched using IO.select or Epoll. IO#close may be called on the object when it is no longer needed.
Inotify
is available on Linux 2.6.13 or later.
require "sleepy_penguin/sp" ino = SP::Inotify.new ino.add_watch("/path/to/foo", :OPEN) ino.each do |event| p event.events # => [ :OPEN ] end
Public Class Methods
Flags may be any of the following as an Array of Symbols or Integer mask:
-
:NONBLOCK - sets the non-blocking flag on the descriptor watched.
-
:CLOEXEC - sets the close-on-exec flag
static VALUE s_new(int argc, VALUE *argv, VALUE klass) { VALUE _flags, rv; int flags; int fd; rb_scan_args(argc, argv, "01", &_flags); flags = rb_sp_get_flags(klass, _flags, RB_SP_CLOEXEC(IN_CLOEXEC)); fd = inotify_init1(flags); if (fd < 0) { if (rb_sp_gc_for_fd(errno)) fd = inotify_init1(flags); if (fd < 0) rb_sys_fail("inotify_init1"); } rv = INT2FIX(fd); rv = rb_call_super(1, &rv); rb_ivar_set(rv, id_inotify_tmp, rb_ary_new()); return rv; }
Public Instance Methods
Adds a watch on an object specified by its mask
, returns an unsigned Integer watch descriptor. flags
may be a mask of the following Inotify
constants or array of their symbolic names.
-
:ACCESS - File was accessed (read) (*)
-
:ATTRIB - Metadata changed.
-
:CLOSE_WRITE - File opened for writing was closed (*)
-
:CLOSE_NOWRITE - File not opened for writing was closed (*)
-
:CREATE - File/directory created in watched directory (*)
-
:DELETE - File/directory deleted from watched directory (*)
-
:DELETE_SELF - Watched file/directory was itself deleted
-
:MODIFY - File was modified (*)
-
:MOVE_SELF - Watched file/directory was itself moved
-
:MOVED_FROM - File moved out of watched directory (*)
-
:MOVED_TO - File moved into watched directory (*)
-
:OPEN - File was opened (*)
When monitoring a directory, the events marked with an asterisk (*) above can occur for files in the directory, in which case the name field in the Event
structure identifies the name of the file in the directory.
Shortcut flags:
-
:ALL_EVENTS - a bitmask of all the above events
-
:MOVE - :MOVED_FROM or :MOVED_TO
-
:CLOSE - :CLOSE_WRITE or :CLOSE_NOWRITE
The following watch attributes may also be included in flags:
-
:DONT_FOLLOW - don't dereference symlinks (since Linux 2.6.15)
-
:EXCL_UNLINK - don't generate unlink events for children (since 2.6.36)
-
:MASK_ADD - add events to an existing watch mask if it exists
-
:ONESHOT - monitor for one event and then remove it from the watch
-
:ONLYDIR - only watch the pathname if it is a directory
static VALUE add_watch(VALUE self, VALUE path, VALUE vmask) { int fd = rb_sp_fileno(self); const char *pathname = StringValueCStr(path); uint32_t mask = rb_sp_get_uflags(self, vmask); int rc = inotify_add_watch(fd, pathname, mask); if (rc < 0) rb_sys_fail("inotify_add_watch"); return UINT2NUM((uint32_t)rc); }
Yields each Inotify::Event
received in a blocking fashion.
static VALUE each(VALUE self) { VALUE argv = Qfalse; while (1) rb_yield(take(0, &argv, self)); return self; }
Removes a watch based on a watch descriptor Integer. The watch descriptor is a return value given by Inotify#add_watch
static VALUE rm_watch(VALUE self, VALUE vwd) { uint32_t wd = NUM2UINT(vwd); int fd = rb_sp_fileno(self); int rc = inotify_rm_watch(fd, wd); if (rc < 0) rb_sys_fail("inotify_rm_watch"); return INT2NUM(rc); }
Returns the next Inotify::Event
processed. May return nil
if nonblock
is true
.
static VALUE take(int argc, VALUE *argv, VALUE self) { struct inread_args args; VALUE nonblock; args.tmp = rb_ivar_get(self, id_inotify_tmp); if (RARRAY_LEN(args.tmp) > 0) return rb_ary_shift(args.tmp); rb_scan_args(argc, argv, "01", &nonblock); args.self = self; args.fd = rb_sp_fileno(self); args.size = 128; args.nonblock_p = RTEST(nonblock); if (args.nonblock_p) rb_sp_set_nonblock(args.fd); args.buf = 0; return rb_ensure(do_take, (VALUE)&args, rb_sp_puttlsbuf, (VALUE)args.buf); }