ruby-inotify 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +1 -0
- data/COPYING +1 -0
- data/Gemfile +4 -0
- data/README.md +6 -0
- data/Rakefile +83 -0
- data/examples/watcher.rb +30 -0
- data/lib/inotify.rb +1 -0
- data/lib/inotify/inotify_native.rb +103 -0
- data/lib/inotify/version.rb +3 -0
- data/ruby-inotify.gemspec +22 -0
- data/tests/test_1.rb +37 -0
- metadata +91 -0
data/.gitignore
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
.project
|
data/COPYING
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
You may use this extension under the same terms as ruby itself.
|
data/Gemfile
ADDED
data/README.md
ADDED
data/Rakefile
ADDED
@@ -0,0 +1,83 @@
|
|
1
|
+
# Rakefile for project management (from chris2) -*-ruby-*-
|
2
|
+
|
3
|
+
Project = 'project-template'
|
4
|
+
|
5
|
+
require 'rake/rdoctask'
|
6
|
+
require 'rake/testtask'
|
7
|
+
|
8
|
+
desc "Build and test"
|
9
|
+
task :default => [:build, :test]
|
10
|
+
|
11
|
+
desc "Do predistribution stuff"
|
12
|
+
task :predist => [:chmod, :changelog, :doc]
|
13
|
+
|
14
|
+
desc "Build"
|
15
|
+
task :build do
|
16
|
+
#ruby "ext/extconf.rb"
|
17
|
+
#system "make"
|
18
|
+
end
|
19
|
+
|
20
|
+
task :test => :build
|
21
|
+
|
22
|
+
desc "Run all the tests"
|
23
|
+
Rake::TestTask.new do |t|
|
24
|
+
t.libs << "tests"
|
25
|
+
t.libs << "lib"
|
26
|
+
t.test_files = FileList['tests/test_*.rb']
|
27
|
+
t.verbose = true
|
28
|
+
end
|
29
|
+
|
30
|
+
desc "Make an archive as .tar.gz"
|
31
|
+
task :dist => :test do
|
32
|
+
system "export DARCS_REPO=#{File.expand_path "."}; " +
|
33
|
+
"darcs dist -d #{Project}#{get_darcs_tree_version}"
|
34
|
+
end
|
35
|
+
|
36
|
+
desc "Make binaries executable"
|
37
|
+
task :chmod do
|
38
|
+
Dir["bin/*"].each { |binary| File.chmod(0775, binary) }
|
39
|
+
end
|
40
|
+
|
41
|
+
desc "Generate a ChangeLog"
|
42
|
+
task :changelog do
|
43
|
+
system "darcs changes --repo=#{ENV["DARCS_REPO"] || "."} >ChangeLog"
|
44
|
+
end
|
45
|
+
|
46
|
+
desc "Generate RDoc documentation"
|
47
|
+
Rake::RDocTask.new(:doc) do |rdoc|
|
48
|
+
rdoc.options << '--line-numbers --inline-source'
|
49
|
+
rdoc.rdoc_dir = "rdoc"
|
50
|
+
rdoc.rdoc_files.include("lib/**/*.rb", "lib/*.rb")
|
51
|
+
end
|
52
|
+
|
53
|
+
desc "Clean to distribution pristine"
|
54
|
+
task :distclean do
|
55
|
+
#system 'make distclean'
|
56
|
+
end
|
57
|
+
|
58
|
+
|
59
|
+
# Helper to retrieve the "revision number" of the darcs tree.
|
60
|
+
def get_darcs_tree_version
|
61
|
+
return "" unless File.directory? "_darcs"
|
62
|
+
|
63
|
+
changes = `darcs changes`
|
64
|
+
count = 0
|
65
|
+
tag = "0.0"
|
66
|
+
|
67
|
+
changes.each("\n\n") { |change|
|
68
|
+
head, title, desc = change.split("\n", 3)
|
69
|
+
|
70
|
+
if title =~ /^ \*/
|
71
|
+
# Normal change.
|
72
|
+
count += 1
|
73
|
+
elsif title =~ /tagged (.*)/
|
74
|
+
# Tag. We look for these.
|
75
|
+
tag = $1
|
76
|
+
break
|
77
|
+
else
|
78
|
+
warn "Unparsable change: #{change}"
|
79
|
+
end
|
80
|
+
}
|
81
|
+
|
82
|
+
"-" + tag + "." + count.to_s
|
83
|
+
end
|
data/examples/watcher.rb
ADDED
@@ -0,0 +1,30 @@
|
|
1
|
+
#!usr/bin/ruby
|
2
|
+
|
3
|
+
require 'inotify'
|
4
|
+
require 'find'
|
5
|
+
|
6
|
+
i = Inotify.new
|
7
|
+
|
8
|
+
t = Thread.new do
|
9
|
+
i.each_event do |ev|
|
10
|
+
p ev.name
|
11
|
+
p ev.mask
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
raise("Specify a directory") if !ARGV[0]
|
16
|
+
|
17
|
+
Find.find(ARGV[0]) do |e|
|
18
|
+
if ['.svn', 'CVS', 'RCS'].include? File.basename(e) or !File.directory? e
|
19
|
+
Find.prune
|
20
|
+
else
|
21
|
+
begin
|
22
|
+
puts "Adding #{e}"
|
23
|
+
i.add_watch(e, Inotify::CREATE | Inotify::DELETE | Inotify::MOVE)
|
24
|
+
rescue
|
25
|
+
puts "Skipping #{e}: #{$!}"
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
t.join
|
data/lib/inotify.rb
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require 'inotify/inotify_native'
|
@@ -0,0 +1,103 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'ffi'
|
3
|
+
|
4
|
+
class Inotify
|
5
|
+
|
6
|
+
extend FFI::Library
|
7
|
+
ffi_lib FFI::Platform::LIBC
|
8
|
+
|
9
|
+
MAX_NAME_SIZE = 4096
|
10
|
+
|
11
|
+
ACCESS = 0x00000001
|
12
|
+
MODIFY = 0x00000002
|
13
|
+
ATTRIB = 0x00000004
|
14
|
+
CLOSE_WRITE = 0x00000008
|
15
|
+
CLOSE_NOWRITE = 0x00000010
|
16
|
+
OPEN = 0x00000020
|
17
|
+
MOVED_FROM = 0x00000040
|
18
|
+
MOVED_TO = 0x00000080
|
19
|
+
CREATE = 0x00000100
|
20
|
+
DELETE = 0x00000200
|
21
|
+
DELETE_SELF = 0x00000400
|
22
|
+
MOVE_SELF = 0x00000800
|
23
|
+
# Events sent by the kernel.
|
24
|
+
UNMOUNT = 0x00002000
|
25
|
+
Q_OVERFLOW = 0x00004000
|
26
|
+
IGNORED = 0x00008000
|
27
|
+
ONLYDIR = 0x01000000
|
28
|
+
DONT_FOLLOW = 0x02000000
|
29
|
+
MASK_ADD = 0x20000000
|
30
|
+
# special flags
|
31
|
+
ISDIR = 0x40000000
|
32
|
+
ONESHOT = 0x80000000
|
33
|
+
# helper events
|
34
|
+
CLOSE = (CLOSE_WRITE | CLOSE_NOWRITE)
|
35
|
+
MOVE = (MOVED_FROM | MOVED_TO)
|
36
|
+
#All of the events
|
37
|
+
ALL_EVENTS = (ACCESS | MODIFY | ATTRIB | CLOSE_WRITE | \
|
38
|
+
CLOSE_NOWRITE | OPEN | MOVED_FROM | \
|
39
|
+
MOVED_TO | CREATE | DELETE | DELETE_SELF | MOVE_SELF)
|
40
|
+
|
41
|
+
attach_function :inotify_init, [], :int
|
42
|
+
attach_function :inotify_add_watch, [:int, :string, :uint32], :int
|
43
|
+
attach_function :inotify_rm_watch, [:int, :uint32], :int
|
44
|
+
attach_function :read, [:int, :pointer, :size_t], :ssize_t
|
45
|
+
attach_function :inotify_close, :close, [:int], :int
|
46
|
+
def initialize
|
47
|
+
@fd = self.inotify_init
|
48
|
+
@io = FFI::IO.for_fd(@fd)
|
49
|
+
end
|
50
|
+
def add_watch(string, uint32)
|
51
|
+
self.inotify_add_watch(@fd, string, uint32)
|
52
|
+
end
|
53
|
+
def rm_watch(uint32)
|
54
|
+
self.inotify_rm_watch(@fd, uint32)
|
55
|
+
end
|
56
|
+
def close
|
57
|
+
self.inotify_close(@fd)
|
58
|
+
end
|
59
|
+
def each_event
|
60
|
+
loop do
|
61
|
+
ready = IO.select([@io], nil, nil, nil)
|
62
|
+
yield self.read_event
|
63
|
+
end
|
64
|
+
end
|
65
|
+
def read_event
|
66
|
+
buf = FFI::Buffer.alloc_out(EventStruct.size + MAX_NAME_SIZE, 1, false)
|
67
|
+
ev = EventStruct.new(buf)
|
68
|
+
n = self.read(@fd, buf, buf.total)
|
69
|
+
Event.new(ev, buf)
|
70
|
+
end
|
71
|
+
|
72
|
+
class EventStruct < FFI::Struct
|
73
|
+
layout(
|
74
|
+
:wd, :int,
|
75
|
+
:mask, :uint32,
|
76
|
+
:cookie, :uint32,
|
77
|
+
:len, :uint32)
|
78
|
+
end
|
79
|
+
|
80
|
+
class Event
|
81
|
+
def initialize(struct, buf)
|
82
|
+
@struct, @buf = struct, buf
|
83
|
+
end
|
84
|
+
|
85
|
+
define_method(:wd) { @struct[:wd] }
|
86
|
+
define_method(:mask) { @struct[:mask] }
|
87
|
+
define_method(:cookie) { @struct[:cookie] }
|
88
|
+
define_method(:len) { @struct[:len] }
|
89
|
+
def name
|
90
|
+
@struct[:len] > 0 ? @buf.get_string(16, @struct[:len]) : ''
|
91
|
+
end
|
92
|
+
|
93
|
+
def inspect
|
94
|
+
"<%s name=%s mask=%s wd=%s>" % [
|
95
|
+
self.class,
|
96
|
+
self.name,
|
97
|
+
self.mask,
|
98
|
+
self.wd
|
99
|
+
]
|
100
|
+
end
|
101
|
+
end
|
102
|
+
|
103
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
$:.push File.expand_path("../lib", __FILE__)
|
3
|
+
require "inotify/version"
|
4
|
+
|
5
|
+
Gem::Specification.new do |s|
|
6
|
+
s.name = "ruby-inotify"
|
7
|
+
s.version = Inotify::VERSION
|
8
|
+
s.authors = ["Aria Stewart", "Jon Raiford"]
|
9
|
+
s.email = ["aredridel@nbtsc.org", "jon@raiford.org"]
|
10
|
+
s.homepage = "http://dinhe.net/~aredridel/projects/ruby/ruby-inotify"
|
11
|
+
s.summary = %q{Interface to Linux's Inotify (Ruby FFI version)}
|
12
|
+
s.description = %q{An interface to Linux's inotify, for watching updates to directories.}
|
13
|
+
|
14
|
+
s.files = `git ls-files`.split("\n")
|
15
|
+
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
16
|
+
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
17
|
+
s.require_paths = ["lib"]
|
18
|
+
|
19
|
+
# specify any dependencies here
|
20
|
+
# s.add_development_dependency "rspec"
|
21
|
+
s.add_runtime_dependency "ffi"
|
22
|
+
end
|
data/tests/test_1.rb
ADDED
@@ -0,0 +1,37 @@
|
|
1
|
+
require 'test/unit'
|
2
|
+
require 'inotify'
|
3
|
+
|
4
|
+
class Test1 < Test::Unit::TestCase
|
5
|
+
def setup
|
6
|
+
@inotify = Inotify.new
|
7
|
+
end
|
8
|
+
def test1
|
9
|
+
assert_equal(Inotify, @inotify.class)
|
10
|
+
end
|
11
|
+
def test2
|
12
|
+
assert(@inotify.add_watch("/tmp", Inotify::CREATE))
|
13
|
+
end
|
14
|
+
def test3
|
15
|
+
wd = @inotify.add_watch("/tmp", Inotify::CREATE)
|
16
|
+
assert_equal(Fixnum, wd.class)
|
17
|
+
assert(@inotify.rm_watch(wd))
|
18
|
+
end
|
19
|
+
def test4
|
20
|
+
@inotify.add_watch("/tmp", Inotify::CREATE)
|
21
|
+
begin
|
22
|
+
File.open(File.join("/tmp", "ruby-inotify-test-4"), 'w')
|
23
|
+
@inotify.each_event do |ev|
|
24
|
+
assert_equal(ev.class, Inotify::Event)
|
25
|
+
assert_equal(ev.inspect, "<Inotify::Event name=ruby-inotify-test-4 mask=256 wd=1>")
|
26
|
+
assert_equal(ev.name, "ruby-inotify-test-4")
|
27
|
+
assert_equal(ev.mask, Inotify::CREATE)
|
28
|
+
break
|
29
|
+
end
|
30
|
+
ensure
|
31
|
+
File.unlink(File.join("/tmp", "ruby-inotify-test-4"))
|
32
|
+
end
|
33
|
+
end
|
34
|
+
def teardown
|
35
|
+
@inotify.close
|
36
|
+
end
|
37
|
+
end
|
metadata
ADDED
@@ -0,0 +1,91 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: ruby-inotify
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
hash: 23
|
5
|
+
prerelease:
|
6
|
+
segments:
|
7
|
+
- 1
|
8
|
+
- 0
|
9
|
+
- 0
|
10
|
+
version: 1.0.0
|
11
|
+
platform: ruby
|
12
|
+
authors:
|
13
|
+
- Aria Stewart
|
14
|
+
- Jon Raiford
|
15
|
+
autorequire:
|
16
|
+
bindir: bin
|
17
|
+
cert_chain: []
|
18
|
+
|
19
|
+
date: 2011-09-06 00:00:00 Z
|
20
|
+
dependencies:
|
21
|
+
- !ruby/object:Gem::Dependency
|
22
|
+
name: ffi
|
23
|
+
prerelease: false
|
24
|
+
requirement: &id001 !ruby/object:Gem::Requirement
|
25
|
+
none: false
|
26
|
+
requirements:
|
27
|
+
- - ">="
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
hash: 3
|
30
|
+
segments:
|
31
|
+
- 0
|
32
|
+
version: "0"
|
33
|
+
type: :runtime
|
34
|
+
version_requirements: *id001
|
35
|
+
description: An interface to Linux's inotify, for watching updates to directories.
|
36
|
+
email:
|
37
|
+
- aredridel@nbtsc.org
|
38
|
+
- jon@raiford.org
|
39
|
+
executables: []
|
40
|
+
|
41
|
+
extensions: []
|
42
|
+
|
43
|
+
extra_rdoc_files: []
|
44
|
+
|
45
|
+
files:
|
46
|
+
- .gitignore
|
47
|
+
- COPYING
|
48
|
+
- Gemfile
|
49
|
+
- README.md
|
50
|
+
- Rakefile
|
51
|
+
- examples/watcher.rb
|
52
|
+
- lib/inotify.rb
|
53
|
+
- lib/inotify/inotify_native.rb
|
54
|
+
- lib/inotify/version.rb
|
55
|
+
- ruby-inotify.gemspec
|
56
|
+
- tests/test_1.rb
|
57
|
+
homepage: http://dinhe.net/~aredridel/projects/ruby/ruby-inotify
|
58
|
+
licenses: []
|
59
|
+
|
60
|
+
post_install_message:
|
61
|
+
rdoc_options: []
|
62
|
+
|
63
|
+
require_paths:
|
64
|
+
- lib
|
65
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
66
|
+
none: false
|
67
|
+
requirements:
|
68
|
+
- - ">="
|
69
|
+
- !ruby/object:Gem::Version
|
70
|
+
hash: 3
|
71
|
+
segments:
|
72
|
+
- 0
|
73
|
+
version: "0"
|
74
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
75
|
+
none: false
|
76
|
+
requirements:
|
77
|
+
- - ">="
|
78
|
+
- !ruby/object:Gem::Version
|
79
|
+
hash: 3
|
80
|
+
segments:
|
81
|
+
- 0
|
82
|
+
version: "0"
|
83
|
+
requirements: []
|
84
|
+
|
85
|
+
rubyforge_project:
|
86
|
+
rubygems_version: 1.8.10
|
87
|
+
signing_key:
|
88
|
+
specification_version: 3
|
89
|
+
summary: Interface to Linux's Inotify (Ruby FFI version)
|
90
|
+
test_files: []
|
91
|
+
|