lib/inotify/inotify_native.rb in ruby-inotify-1.0.0 vs lib/inotify/inotify_native.rb in ruby-inotify-1.0.1
- old
+ new
@@ -1,97 +1,177 @@
require 'rubygems'
require 'ffi'
+ # The Inotify class is a simple wrapper around the inotify functionality provided by the OS
class Inotify
+ VERSION = "1.0.1" # :nodoc:
+
extend FFI::Library
ffi_lib FFI::Platform::LIBC
- MAX_NAME_SIZE = 4096
+ # The maximum supported size of the name argument in the inotify event structure
+ MAX_NAME_SIZE = 4096 # :nodoc:
+ # File was accessed (read) (*)
ACCESS = 0x00000001
+ # File was modified (*)
MODIFY = 0x00000002
- ATTRIB = 0x00000004
- CLOSE_WRITE = 0x00000008
+ # Metadata changed, e.g., permissions, timestamps,
+ # extended attributes, link count (since Linux 2.6.25),
+ # UID, GID, etc. (*)
+ ATTRIB = 0x00000004
+ # File opened for writing was closed (*)
+ CLOSE_WRITE = 0x00000008
+ # File not opened for writing was closed (*)
CLOSE_NOWRITE = 0x00000010
+ # File was opened (*)
OPEN = 0x00000020
+ # File moved out of watched directory (*)
MOVED_FROM = 0x00000040
+ # File moved into watched directory (*)
MOVED_TO = 0x00000080
+ # File/directory created in watched directory (*)
CREATE = 0x00000100
+ # File/directory deleted from watched directory (*)
DELETE = 0x00000200
+ # Watched file/directory was itself deleted
DELETE_SELF = 0x00000400
+ # Watched file/directory was itself moved
MOVE_SELF = 0x00000800
- # Events sent by the kernel.
+ # File system containing watched object was unmounted
UNMOUNT = 0x00002000
+ # Event queue overflowed (wd is -1 for this event)
Q_OVERFLOW = 0x00004000
+ # Watch was removed explicitly (inotify_rm_watch(2)) or
+ # automatically (file was deleted, or file system was
+ # unmounted)
IGNORED = 0x00008000
+ # (since Linux 2.6.15) Only watch pathname if it is a directory
ONLYDIR = 0x01000000
+ # (since Linux 2.6.15) Don't dereference pathname if it is a symbolic link
DONT_FOLLOW = 0x02000000
- MASK_ADD = 0x20000000
- # special flags
+ # (since Linux 2.6.36)
+ # By default, when watching events on the children of a
+ # directory, events are generated for children even after
+ # they have been unlinked from the directory. This can
+ # result in large numbers of uninteresting events for some
+ # applications (e.g., if watching /tmp, in which many
+ # applications create temporary files whose names are
+ # immediately unlinked). Specifying IN_EXCL_UNLINK
+ # changes the default behavior, so that events are not
+ # generated for children after they have been unlinked
+ # from the watched directory.
+ EXCL_UNLINK = 0x04000000
+ # Add (OR) events to watch mask for this pathname if it
+ # already exists (instead of replacing mask)
+ MASK_ADD = 0x20000000
+ # Subject of this event is a directory
ISDIR = 0x40000000
+ # Monitor pathname for one event, then remove from watch list
ONESHOT = 0x80000000
- # helper events
- CLOSE = (CLOSE_WRITE | CLOSE_NOWRITE)
- MOVE = (MOVED_FROM | MOVED_TO)
+ # Both of the close events
+ CLOSE = (CLOSE_WRITE | CLOSE_NOWRITE)
+ # Both of the move events
+ MOVE = (MOVED_FROM | MOVED_TO)
#All of the events
ALL_EVENTS = (ACCESS | MODIFY | ATTRIB | CLOSE_WRITE | \
CLOSE_NOWRITE | OPEN | MOVED_FROM | \
MOVED_TO | CREATE | DELETE | DELETE_SELF | MOVE_SELF)
attach_function :inotify_init, [], :int
attach_function :inotify_add_watch, [:int, :string, :uint32], :int
attach_function :inotify_rm_watch, [:int, :uint32], :int
attach_function :read, [:int, :pointer, :size_t], :ssize_t
attach_function :inotify_close, :close, [:int], :int
- def initialize
+
+ # When creating a new instance of this class, an inotify instance is created in the OS.
+ def initialize # :nodoc:
@fd = self.inotify_init
@io = FFI::IO.for_fd(@fd)
end
- def add_watch(string, uint32)
- self.inotify_add_watch(@fd, string, uint32)
+
+ # add_watch() adds a new watch, or modifies an existing watch, for the
+ # file whose location is specified in pathname; the caller must have read
+ # permission for this file. The events to be
+ # monitored for pathname are specified in the mask bit-mask argument.
+ # On success, inotify_add_watch() returns a nonnegative watch descriptor (wd), or
+ # -1 if an error occurred.
+ def add_watch(pathname, mask)
+ self.inotify_add_watch(@fd, pathname, mask)
end
- def rm_watch(uint32)
- self.inotify_rm_watch(@fd, uint32)
+
+ # rm_watch() removes the watch associated with the watch descriptor wd.
+ # On success, returns zero, or -1 if an error occurred.
+ def rm_watch(wd)
+ self.inotify_rm_watch(@fd, wd)
end
+
+ # close() stops the processing of events and closes the
+ # inotify instance in the OS
def close
self.inotify_close(@fd)
end
+
+ # each_event() provides an easy way to loop over all events as they occur
def each_event
loop do
ready = IO.select([@io], nil, nil, nil)
- yield self.read_event
+ event = self.read_event
+ yield event
end
end
- def read_event
+
+ # read_event() attempts to read the next inotify event from the OS
+ def read_event # :nodoc:
buf = FFI::Buffer.alloc_out(EventStruct.size + MAX_NAME_SIZE, 1, false)
ev = EventStruct.new(buf)
n = self.read(@fd, buf, buf.total)
Event.new(ev, buf)
end
- class EventStruct < FFI::Struct
+ # Internal class needed for FFI support
+ class EventStruct < FFI::Struct # :nodoc:
layout(
:wd, :int,
:mask, :uint32,
:cookie, :uint32,
:len, :uint32)
end
+ # The Inotify::Event class is used by Inotify when calling Inotify each_event method
class Event
- def initialize(struct, buf)
+
+ def initialize(struct, buf) # :nodoc:
@struct, @buf = struct, buf
end
- define_method(:wd) { @struct[:wd] }
- define_method(:mask) { @struct[:mask] }
- define_method(:cookie) { @struct[:cookie] }
- define_method(:len) { @struct[:len] }
+ # Returns the watch descriptor (wd) associated with the event
+ def wd
+ @struct[:wd]
+ end
+
+ # Returns the mask describing the event
+ def mask
+ @struct[:mask]
+ end
+
+ # Returns the cookie associated with the event. If multiple events are triggered from the
+ # same action (such as renaming a file or directory), this value will be the same.
+ def cookie
+ @struct[:cookie]
+ end
+
+ def len # :nodoc:
+ @struct[:len]
+ end
+
+ # Returns the file name associated with the event, if applicable
def name
@struct[:len] > 0 ? @buf.get_string(16, @struct[:len]) : ''
end
- def inspect
+ def inspect # :nodoc:
"<%s name=%s mask=%s wd=%s>" % [
self.class,
self.name,
self.mask,
self.wd
\ No newline at end of file