Class: SleepyPenguin::Inotify

Inherits:
IO
  • Object
show all
Defined in:
ext/sleepy_penguin/inotify.c,
ext/sleepy_penguin/inotify.c,
lib/sleepy_penguin.rb

Overview

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

Defined Under Namespace

Classes: Event

Class Method Summary collapse

Instance Method Summary collapse

Class Method Details

.new(*args) ⇒ Object

Inotify.new() -> Inotify IO object

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



18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
# File 'ext/sleepy_penguin/inotify.c', line 18

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;
}

Instance Method Details

#__takeObject

ino.take() -> Inotify::Event or nil

Returns the next Inotify::Event processed. May return nil if nonblock is true. :stopdoc:



10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
# File 'lib/sleepy_penguin.rb', line 10

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);
}

#add_watch(path, vmask) ⇒ Object

ino.add_watch(path, flags) -> Integer

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



82
83
84
85
86
87
88
89
90
91
92
93
# File 'ext/sleepy_penguin/inotify.c', line 82

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);
}

#eachObject

ino.each { |event| … } -> ino

Yields each Inotify::Event received in a blocking fashion.



277
278
279
280
281
282
283
284
285
# File 'ext/sleepy_penguin/inotify.c', line 277

static VALUE each(VALUE self)
{
	VALUE argv = Qfalse;

	while (1)
		rb_yield(take(0, &argv, self));

	return self;
}

#rm_watch(vwd) ⇒ Object

ino.rm_watch(watch_descriptor) -> 0

Removes a watch based on a watch descriptor Integer. The watch descriptor is a return value given by Inotify#add_watch



102
103
104
105
106
107
108
109
110
111
# File 'ext/sleepy_penguin/inotify.c', line 102

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);
}

#take(*args) ⇒ Object

ino.take() -> Inotify::Event or nil

Returns the next Inotify::Event processed. May return nil if nonblock is true.



221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
# File 'ext/sleepy_penguin/inotify.c', line 221

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);
}