Module: Ligarb::Inotify
- Defined in:
- lib/ligarb/inotify.rb
Constant Summary collapse
- LIBC =
Fiddle.dlopen(nil)
- InotifyInit1 =
Fiddle::Function.new( LIBC["inotify_init1"], [Fiddle::TYPE_INT], Fiddle::TYPE_INT )
- InotifyAddWatch =
Fiddle::Function.new( LIBC["inotify_add_watch"], [Fiddle::TYPE_INT, Fiddle::TYPE_VOIDP, Fiddle::TYPE_UINT32_T], Fiddle::TYPE_INT )
- InotifyRmWatch =
Fiddle::Function.new( LIBC["inotify_rm_watch"], [Fiddle::TYPE_INT, Fiddle::TYPE_INT], Fiddle::TYPE_INT )
- IN_CLOSE_WRITE =
inotify event masks
0x00000008- IN_CLOEXEC =
O_CLOEXEC on x86_64
0x00080000- EVENT_HEADER_SIZE =
struct inotify_event fixed part: int wd, uint32 mask, uint32 cookie, uint32 len
16
Class Method Summary collapse
- .add_watch(fd, path) ⇒ Object
-
.watch_file(path, &block) ⇒ Object
Watch a file for writes.
Class Method Details
.add_watch(fd, path) ⇒ Object
69 70 71 72 73 |
# File 'lib/ligarb/inotify.rb', line 69 def self.add_watch(fd, path) wd = InotifyAddWatch.call(fd, path, IN_CLOSE_WRITE) raise SystemCallError.new("inotify_add_watch: #{path}", Fiddle.last_error) if wd < 0 wd end |
.watch_file(path, &block) ⇒ Object
Watch a file for writes. Yields each time the file is written and closed. Blocks the calling thread. Caller should wrap in Thread.new.
39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 |
# File 'lib/ligarb/inotify.rb', line 39 def self.watch_file(path, &block) fd = InotifyInit1.call(IN_CLOEXEC) raise SystemCallError.new("inotify_init1", Fiddle.last_error) if fd < 0 io = IO.for_fd(fd, autoclose: true) wd = add_watch(fd, path) loop do # IO.select releases GVL while waiting IO.select([io]) buf = io.read_nonblock(4096, exception: false) next if buf == :wait_readable || buf.nil? # Parse events — may contain multiple events offset = 0 while offset + EVENT_HEADER_SIZE <= buf.bytesize _wd, mask, , name_len = buf.byteslice(offset, EVENT_HEADER_SIZE).unpack("iIII") offset += EVENT_HEADER_SIZE + name_len if mask & IN_CLOSE_WRITE != 0 block.call end end rescue IOError, Errno::EBADF break end ensure io&.close rescue nil end |