inotify 1.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (3) hide show
  1. checksums.yaml +7 -0
  2. data/lib/inotify.rb +242 -0
  3. 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: []