inotify 1.0.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/lib/inotify.rb +242 -0
- metadata +44 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 65fcbfaefdda68499dd8e77c1617901f991bf6f9
|
4
|
+
data.tar.gz: 36e9bea27f4407be2e365a93ea43062e658fa533
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 0b47d2d241741bbaea1ad016a7b62c01a9deab02a61ea8d3e3cac2def963815fa697887fc2ec6a06756fb12007aa7117ceacbef54c3e268551104c5d85c3a598
|
7
|
+
data.tar.gz: 10d2ffabb1e2db35521c0339d5b2b028db0bba9ef6f4253a006624714cad0b60c433d62f73e5a7581be3f50523364fbfa4b894c95cdc5b0952832302809bbdfa
|
data/lib/inotify.rb
ADDED
@@ -0,0 +1,242 @@
|
|
1
|
+
# lib/inotify.rb
|
2
|
+
# (C) 2013 jtRIPper
|
3
|
+
#
|
4
|
+
# This program is free software; you can redistribute it and/or modify
|
5
|
+
# it under the terms of the GNU General Public License as published by
|
6
|
+
# the Free Software Foundation; either version 1, or (at your option)
|
7
|
+
# any later version.
|
8
|
+
#
|
9
|
+
# This program is distributed in the hope that it will be useful,
|
10
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
11
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
12
|
+
# GNU General Public License for more details.
|
13
|
+
#
|
14
|
+
# You should have received a copy of the GNU General Public License
|
15
|
+
# along with this program; if not, write to the Free Software
|
16
|
+
# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
17
|
+
|
18
|
+
require 'fiddle'
|
19
|
+
|
20
|
+
# Constants for each inotify event found in /usr/include/sys/inotify.h, descriptions from inotify man page (7), (note: 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 returned inotify_event structure identifies the name of the file within the directory.)
|
21
|
+
module InotifyEvents
|
22
|
+
# File was accessed (read) (*).
|
23
|
+
IN_ACCESS = 0x00000001
|
24
|
+
# File was modified (*).
|
25
|
+
IN_MODIFY = 0x00000002
|
26
|
+
# Metadata changed, e.g., permissions, timestamps, extended attributes, link count (since Linux 2.6.25), UID, GID, etc. (*).
|
27
|
+
IN_ATTRIB = 0x00000004
|
28
|
+
# File opened for writing was closed (*).
|
29
|
+
IN_CLOSE_WRITE = 0x00000008
|
30
|
+
# File not opened for writing was closed (*).
|
31
|
+
IN_CLOSE_NOWRITE = 0x00000010
|
32
|
+
# File was closed (*).
|
33
|
+
IN_CLOSE = (IN_CLOSE_WRITE | IN_CLOSE_NOWRITE)
|
34
|
+
# File was opened (*).
|
35
|
+
IN_OPEN = 0x00000020
|
36
|
+
# Generated for the directory containing the old filename when a file is renamed (*).
|
37
|
+
IN_MOVED_FROM = 0x00000040
|
38
|
+
# Generated for the directory containing the new filename when a file is renamed (*).
|
39
|
+
IN_MOVED_TO = 0x00000080
|
40
|
+
# Generated when a file is moved (*).
|
41
|
+
IN_MOVE = (IN_MOVED_FROM | IN_MOVED_TO)
|
42
|
+
# File/directory created in watched directory (*).
|
43
|
+
IN_CREATE = 0x00000100
|
44
|
+
# File/directory deleted from watched directory (*).
|
45
|
+
IN_DELETE = 0x00000200
|
46
|
+
# Watched file/directory was itself deleted.
|
47
|
+
IN_DELETE_SELF = 0x00000400
|
48
|
+
# Watched file/directory was itself moved.
|
49
|
+
IN_MOVE_SELF = 0x00000800
|
50
|
+
# Filesystem containing watched object was unmounted.
|
51
|
+
IN_UNMOUNT = 0x00002000
|
52
|
+
# Event queue overfloved.
|
53
|
+
IN_Q_OVERFLOW = 0x00004000
|
54
|
+
# Watch was removed explicitly (inotify_rm_watch(2)) or automatically (file was deleted, or filesystem was unmounted).
|
55
|
+
IN_IGNORED = 0x00008000
|
56
|
+
# Only watch pathname if it is a directory.
|
57
|
+
IN_ONLYDIR = 0x01000000
|
58
|
+
# Don't dereference pathname if it is a symbolic link.
|
59
|
+
IN_DONT_FOLLOW = 0x02000000
|
60
|
+
# 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.
|
61
|
+
IN_EXCL_UNLINK = 0x04000000
|
62
|
+
# Add (OR) events to watch mask for this pathname if it already exists (instead of replacing mask).
|
63
|
+
IN_MASK_ADD = 0x20000000
|
64
|
+
# Subject of this event is a directory.
|
65
|
+
IN_ISDIR = 0x40000000
|
66
|
+
# Monitor pathname for one event, then remove from watch list.
|
67
|
+
IN_ONESHOT = 0x80000000
|
68
|
+
# Set all events.
|
69
|
+
IN_ALL_EVENTS = (IN_ACCESS | IN_MODIFY | IN_ATTRIB | IN_CLOSE_WRITE \
|
70
|
+
| IN_CLOSE_NOWRITE | IN_OPEN | IN_MOVED_FROM \
|
71
|
+
| IN_MOVED_TO | IN_CREATE | IN_DELETE \
|
72
|
+
| IN_DELETE_SELF | IN_MOVE_SELF)
|
73
|
+
end
|
74
|
+
|
75
|
+
# The basic ctypes for every function required by inotify
|
76
|
+
module InotifyCtypes
|
77
|
+
# open libc
|
78
|
+
$libc = Fiddle.dlopen('/lib/libc.so.6')
|
79
|
+
|
80
|
+
# import required functions
|
81
|
+
$__inotify_init = Fiddle::Function.new(
|
82
|
+
$libc['inotify_init'],
|
83
|
+
[],
|
84
|
+
Fiddle::TYPE_INT
|
85
|
+
)
|
86
|
+
|
87
|
+
$__inotify_add_watch = Fiddle::Function.new(
|
88
|
+
$libc['inotify_add_watch'],
|
89
|
+
[ Fiddle::TYPE_INT, Fiddle::TYPE_VOIDP, Fiddle::TYPE_INT ],
|
90
|
+
Fiddle::TYPE_INT
|
91
|
+
)
|
92
|
+
|
93
|
+
$__inotify_rm_watch = Fiddle::Function.new(
|
94
|
+
$libc['inotify_rm_watch'],
|
95
|
+
[ Fiddle::TYPE_INT, Fiddle::TYPE_INT ],
|
96
|
+
Fiddle::TYPE_INT
|
97
|
+
)
|
98
|
+
|
99
|
+
$__read = Fiddle::Function.new(
|
100
|
+
$libc['read'],
|
101
|
+
[ Fiddle::TYPE_INT, Fiddle::TYPE_VOIDP, Fiddle::TYPE_INT ],
|
102
|
+
Fiddle::TYPE_INT
|
103
|
+
)
|
104
|
+
|
105
|
+
$__close = Fiddle::Function.new(
|
106
|
+
$libc['close'],
|
107
|
+
[ Fiddle::TYPE_INT ],
|
108
|
+
Fiddle::TYPE_INT
|
109
|
+
)
|
110
|
+
|
111
|
+
# Parse the result of read on an inotify file descriptor.
|
112
|
+
def inotify_event(buffer)
|
113
|
+
wd, mask, cookie, len, name = buffer.unpack("lLLLZ*")
|
114
|
+
event = Hash.new
|
115
|
+
event["wd"] = wd
|
116
|
+
event["mask"] = mask
|
117
|
+
event["cookie"] = cookie
|
118
|
+
event["len"] = len
|
119
|
+
event["name"] = name
|
120
|
+
event
|
121
|
+
end
|
122
|
+
|
123
|
+
# Open inotify file descriptor.
|
124
|
+
def inotify_init
|
125
|
+
$__inotify_init.call
|
126
|
+
end
|
127
|
+
|
128
|
+
# Add a path to the inotify watch.
|
129
|
+
def inotify_add_watch(fd, path, mask)
|
130
|
+
$__inotify_add_watch.call(fd, path, mask)
|
131
|
+
end
|
132
|
+
|
133
|
+
# Remove a watch descriptor from the inotify watch.
|
134
|
+
def inotify_rm_watch(fd, wd)
|
135
|
+
$__inotify_rm_watch.call(fd, wd)
|
136
|
+
end
|
137
|
+
|
138
|
+
# Allocate a buffer, call read and then parse the result.
|
139
|
+
def inotify_read(fd)
|
140
|
+
max_len = 20 + 1024 + 1
|
141
|
+
cbuff = Fiddle::Pointer.malloc(max_len)
|
142
|
+
max_len.times { |index| cbuff[index] = 0 }
|
143
|
+
len = $__read.call(fd, cbuff, max_len)
|
144
|
+
inotify_event(cbuff.to_s(len))
|
145
|
+
end
|
146
|
+
|
147
|
+
# Close inotify file descriptor.
|
148
|
+
def inotify_close(fd)
|
149
|
+
$__close.call(fd)
|
150
|
+
end
|
151
|
+
end
|
152
|
+
|
153
|
+
# High-level class for using inotify in ruby.
|
154
|
+
# puts "Watching #{ARGV[0]}"
|
155
|
+
#
|
156
|
+
# inotify = Inotify.new
|
157
|
+
# inotify.add_watch(ARGV[0], InotifyEvents::IN_CREATE|InotifyEvents::IN_MODIFY)
|
158
|
+
#
|
159
|
+
# inotify.wait_for_event() { |path, mask, name|
|
160
|
+
# puts "#{path}/#{name}"
|
161
|
+
# if inotify.event?(mask, InotifyEvents::IN_CREATE)
|
162
|
+
# puts " * created"
|
163
|
+
# end
|
164
|
+
# if inotify.event?(mask, InotifyEvents::IN_MODIFY)
|
165
|
+
# puts " * modified"
|
166
|
+
# end
|
167
|
+
# }
|
168
|
+
#
|
169
|
+
# inotify.rm_watch(ARGV[0])
|
170
|
+
|
171
|
+
class Inotify
|
172
|
+
include InotifyCtypes
|
173
|
+
include ObjectSpace
|
174
|
+
|
175
|
+
def initialize
|
176
|
+
@fd = inotify_init
|
177
|
+
@wds = {}
|
178
|
+
|
179
|
+
define_finalizer(self, proc { close })
|
180
|
+
end
|
181
|
+
|
182
|
+
# Add a path to inotify watch (events found in InotifyEvents).
|
183
|
+
def add_watch(path, event)
|
184
|
+
@wds[inotify_add_watch(@fd, path, event)] = path
|
185
|
+
end
|
186
|
+
|
187
|
+
# Remove a path from inotify watch.
|
188
|
+
def rm_watch(path)
|
189
|
+
wd = @wds.key(path)
|
190
|
+
if wd
|
191
|
+
inotify_rm_watch(@fd, wd)
|
192
|
+
end
|
193
|
+
end
|
194
|
+
|
195
|
+
# Close all watch descriptors.
|
196
|
+
def rm_all_watches()
|
197
|
+
@wds.values.each { |v| rm_watch(v) }
|
198
|
+
end
|
199
|
+
|
200
|
+
# Recursively add a path to inotify watch.
|
201
|
+
def recursive_add_watch(path, event)
|
202
|
+
add_watch(path, event)
|
203
|
+
Dir.glob("#{path}/**/*/").each { |path|
|
204
|
+
add_watch(path, event)
|
205
|
+
}
|
206
|
+
end
|
207
|
+
|
208
|
+
# Wait for an inotify event to happen, yields the path, mask, and file name.
|
209
|
+
def wait_for_event()
|
210
|
+
event = inotify_read(@fd)
|
211
|
+
yield @wds[event["wd"]], event["mask"], event["name"]
|
212
|
+
end
|
213
|
+
|
214
|
+
# Check if an event is set in an event mask.
|
215
|
+
def event?(mask, event_num)
|
216
|
+
return (mask & event_num) != 0
|
217
|
+
end
|
218
|
+
|
219
|
+
# Close the inotify file descriptor.
|
220
|
+
def close
|
221
|
+
inotify_close(@fd)
|
222
|
+
end
|
223
|
+
end
|
224
|
+
|
225
|
+
if __FILE__ == $0
|
226
|
+
puts "Watching #{ARGV[0]}"
|
227
|
+
|
228
|
+
inotify = Inotify.new
|
229
|
+
inotify.add_watch(ARGV[0], InotifyEvents::IN_CREATE|InotifyEvents::IN_MODIFY)
|
230
|
+
|
231
|
+
inotify.wait_for_event() { |path, mask, name|
|
232
|
+
puts "#{path}/#{name}"
|
233
|
+
if inotify.event?(mask, InotifyEvents::IN_CREATE)
|
234
|
+
puts " * created"
|
235
|
+
end
|
236
|
+
if inotify.event?(mask, InotifyEvents::IN_MODIFY)
|
237
|
+
puts " * modified"
|
238
|
+
end
|
239
|
+
}
|
240
|
+
|
241
|
+
inotify.rm_watch(ARGV[0])
|
242
|
+
end
|
metadata
ADDED
@@ -0,0 +1,44 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: inotify
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 1.0.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- jtripper
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2013-10-06 00:00:00.000000000 Z
|
12
|
+
dependencies: []
|
13
|
+
description: Inotify wrapper for Ruby.
|
14
|
+
email: jack@jtripper.net
|
15
|
+
executables: []
|
16
|
+
extensions: []
|
17
|
+
extra_rdoc_files: []
|
18
|
+
files:
|
19
|
+
- lib/inotify.rb
|
20
|
+
homepage: https://github.com/jtripper/inotify
|
21
|
+
licenses:
|
22
|
+
- GPLv2
|
23
|
+
metadata: {}
|
24
|
+
post_install_message:
|
25
|
+
rdoc_options: []
|
26
|
+
require_paths:
|
27
|
+
- lib
|
28
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
29
|
+
requirements:
|
30
|
+
- - '>='
|
31
|
+
- !ruby/object:Gem::Version
|
32
|
+
version: '0'
|
33
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
34
|
+
requirements:
|
35
|
+
- - '>='
|
36
|
+
- !ruby/object:Gem::Version
|
37
|
+
version: '0'
|
38
|
+
requirements: []
|
39
|
+
rubyforge_project:
|
40
|
+
rubygems_version: 2.0.3
|
41
|
+
signing_key:
|
42
|
+
specification_version: 4
|
43
|
+
summary: Inotify wrapper
|
44
|
+
test_files: []
|