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.
- data/README.md +11 -0
- data/inotify-ffi-dev.gemspec +26 -0
- data/lib/inotify-ffi.rb +178 -0
- metadata +57 -0
data/README.md
ADDED
@@ -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
|
data/lib/inotify-ffi.rb
ADDED
@@ -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
|
+
|