inotify-ffi-dev 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (4) hide show
  1. data/README.md +11 -0
  2. data/inotify-ffi-dev.gemspec +26 -0
  3. data/lib/inotify-ffi.rb +178 -0
  4. metadata +57 -0
@@ -0,0 +1,11 @@
1
+ # inotify-ffi
2
+
3
+ Blatant, unashamed rip-off of [samples/inotify.rb](http://github.com/ffi/ffi/blob/master/samples/inotify.rb)
4
+
5
+ Now a gem.
6
+
7
+ ## Install
8
+ gem install inotify-ffi
9
+
10
+ ## Thanks
11
+ halorgium for async_each_event
@@ -0,0 +1,26 @@
1
+ Gem::Specification.new do |s|
2
+ s.specification_version = 2 if s.respond_to? :specification_version=
3
+ s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
4
+
5
+ s.name = 'inotify-ffi-dev'
6
+ s.version = '0.1.0'
7
+ s.date = '2009-11-19'
8
+
9
+ s.description = "ffi interface for inotify"
10
+ s.summary = s.description
11
+
12
+ s.authors = ["Blake Mizerany"]
13
+ s.email = "blake.mizerany@gmail.com"
14
+
15
+ s.files = %w[
16
+ README.md
17
+ inotify-ffi-dev.gemspec
18
+ lib/inotify-ffi.rb
19
+ ]
20
+
21
+ s.extra_rdoc_files = %w[README.md]
22
+
23
+ s.homepage = "http://github.com/bmizerany/inotify-ffi/"
24
+ s.require_paths = %w[lib]
25
+ s.rubygems_version = '1.1.1'
26
+ end
@@ -0,0 +1,178 @@
1
+ require 'ffi'
2
+
3
+ module Inotify
4
+ extend FFI::Library
5
+
6
+ attach_function :init, :inotify_init, [ ], :int
7
+ attach_function :add_watch, :inotify_add_watch, [ :int, :string, :uint ], :int
8
+ attach_function :rm_watch, :inotify_rm_watch, [ :int, :uint ], :int
9
+ attach_function :read, [ :int, :buffer_out, :uint ], :int
10
+
11
+ def self.watch(path, event_mask = IN_ALL_EVENTS)
12
+ Watcher.setup(path, event_mask)
13
+ end
14
+
15
+ class Watcher
16
+ def self.setup(path, event_mask)
17
+ new(path, event_mask).setup
18
+ end
19
+
20
+ def initialize(path, event_mask)
21
+ @path, @event_mask = path, event_mask
22
+ end
23
+ attr_reader :io
24
+
25
+ def setup
26
+ @fd = Inotify.init
27
+ @wd = Inotify.add_watch(@fd, @path, @event_mask)
28
+ @io = FFI::IO.for_fd(@fd)
29
+ self
30
+ end
31
+
32
+ def each_event
33
+ loop do
34
+ ready = IO.select([ @io ], nil, nil, nil)
35
+ yield Inotify.process_event(@fd)
36
+ end
37
+ end
38
+
39
+ def async_each_event(&blk)
40
+ mod = Module.new do
41
+ include Connection
42
+ define_method(:notify_event, &blk)
43
+ end
44
+ EM.watch(@io, mod) do |c|
45
+ c.notify_readable = true
46
+ end
47
+ end
48
+ end
49
+
50
+ def self.process_event(fd)
51
+ buf = FFI::Buffer.alloc_out(EventStruct.size + 4096, 1, false)
52
+ ev = EventStruct.new(buf)
53
+ n = Inotify.read(fd, buf, buf.total)
54
+ Event.new(ev, buf)
55
+ end
56
+
57
+ module Connection
58
+ def notify_readable
59
+ notify_event(Inotify.process_event(@fd))
60
+ end
61
+
62
+ def notify_event(ev)
63
+ raise "Implement #notify_event on #{self.class}"
64
+ end
65
+ end
66
+
67
+ class Event
68
+ def initialize(struct, buf)
69
+ @struct, @buf = struct, buf
70
+ end
71
+
72
+ def mask ; @struct[:mask] ; end
73
+ def wd ; @struct[:wd] ; end
74
+ def len ; @struct[:len] ; end
75
+
76
+ def is?(*c)
77
+ c.all? {|c| (mask & c) > 0 }
78
+ end
79
+
80
+ def inspect
81
+ "<%s: wd:%s mask:%s len=%s>" % [
82
+ name,
83
+ @struct[:wd],
84
+ @struct[:mask],
85
+ @struct[:len]
86
+ ]
87
+ end
88
+
89
+ def mask_names
90
+ Const.constants.select do |const|
91
+ value = Const.const_get(const)
92
+ @struct[:mask] & value > 0
93
+ end
94
+ end
95
+
96
+ def name
97
+ @struct[:len] >= 0 ? @buf.get_string(@struct[:len]) : '<unknown>'
98
+ end
99
+
100
+ end
101
+
102
+ class EventStruct < FFI::Struct
103
+ layout \
104
+ :wd, :int,
105
+ :mask, :uint,
106
+ :cookie, :uint,
107
+ :len, :uint
108
+ end
109
+
110
+ module Const
111
+ IN_ACCESS = 0x00000001
112
+ IN_MODIFY = 0x00000002
113
+ IN_ATTRIB = 0x00000004
114
+ IN_CLOSE_WRITE = 0x00000008
115
+ IN_CLOSE_NOWRITE = 0x00000010
116
+ IN_OPEN = 0x00000020
117
+ IN_MOVED_FROM = 0x00000040
118
+ IN_MOVED_TO = 0x00000080
119
+ IN_CREATE = 0x00000100
120
+ IN_DELETE = 0x00000200
121
+ IN_DELETE_SELF = 0x00000400
122
+ IN_MOVE_SELF = 0x00000800
123
+ # Events sent by the kernel.
124
+ IN_UNMOUNT = 0x00002000
125
+ IN_Q_OVERFLOW = 0x00004000
126
+ IN_IGNORED = 0x00008000
127
+ IN_ONLYDIR = 0x01000000
128
+ IN_DONT_FOLLOW = 0x02000000
129
+ IN_MASK_ADD = 0x20000000
130
+ IN_ISDIR = 0x40000000
131
+ IN_ONESHOT = 0x80000000
132
+ end
133
+ include Const
134
+
135
+ IN_MOVE = (IN_MOVED_FROM | IN_MOVED_TO)
136
+ IN_CLOSE = (IN_CLOSE_WRITE | IN_CLOSE_NOWRITE)
137
+ IN_ALL_EVENTS = (IN_ACCESS | IN_MODIFY | IN_ATTRIB | IN_CLOSE_WRITE \
138
+ | IN_CLOSE_NOWRITE | IN_OPEN | IN_MOVED_FROM \
139
+ | IN_MOVED_TO | IN_CREATE | IN_DELETE \
140
+ | IN_DELETE_SELF | IN_MOVE_SELF)
141
+ end
142
+
143
+ if $0 == __FILE__
144
+ ######
145
+ require 'pp'
146
+ require 'eventmachine'
147
+
148
+ watcher = Inotify.watch("/tmp")
149
+ if ENV["EM"]
150
+ module Callback
151
+ include Inotify::Connection
152
+
153
+ def notify_event(ev)
154
+ puts ev.inspect
155
+ pp ev.mask_names
156
+ end
157
+ end
158
+
159
+ EM.run do
160
+ EM.watch(watcher.io, Callback) do |c|
161
+ c.notify_readable = true
162
+ end
163
+ end
164
+ elsif ENV["EM2"]
165
+ EM.run do
166
+ watcher.async_each_event do |ev|
167
+ puts ev.inspect
168
+ pp ev.mask_names
169
+ end
170
+ end
171
+ else
172
+ watcher.each_event do |ev|
173
+ puts ev.inspect
174
+ pp ev.mask_names
175
+ end
176
+ end
177
+ ######
178
+ end
metadata ADDED
@@ -0,0 +1,57 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: inotify-ffi-dev
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Blake Mizerany
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+
12
+ date: 2009-11-19 00:00:00 -08:00
13
+ default_executable:
14
+ dependencies: []
15
+
16
+ description: ffi interface for inotify
17
+ email: blake.mizerany@gmail.com
18
+ executables: []
19
+
20
+ extensions: []
21
+
22
+ extra_rdoc_files:
23
+ - README.md
24
+ files:
25
+ - README.md
26
+ - inotify-ffi-dev.gemspec
27
+ - lib/inotify-ffi.rb
28
+ has_rdoc: true
29
+ homepage: http://github.com/bmizerany/inotify-ffi/
30
+ licenses: []
31
+
32
+ post_install_message:
33
+ rdoc_options: []
34
+
35
+ require_paths:
36
+ - lib
37
+ required_ruby_version: !ruby/object:Gem::Requirement
38
+ requirements:
39
+ - - ">="
40
+ - !ruby/object:Gem::Version
41
+ version: "0"
42
+ version:
43
+ required_rubygems_version: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ version: "0"
48
+ version:
49
+ requirements: []
50
+
51
+ rubyforge_project:
52
+ rubygems_version: 1.3.5
53
+ signing_key:
54
+ specification_version: 2
55
+ summary: ffi interface for inotify
56
+ test_files: []
57
+