ffi-xattr 0.0.1
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/.gitignore +4 -0
- data/Gemfile +4 -0
- data/Rakefile +8 -0
- data/ffi-xattr.gemspec +24 -0
- data/lib/ffi-xattr.rb +91 -0
- data/lib/ffi-xattr/version.rb +5 -0
- data/spec/xattr_spec.rb +34 -0
- metadata +82 -0
data/.gitignore
ADDED
data/Gemfile
ADDED
data/Rakefile
ADDED
data/ffi-xattr.gemspec
ADDED
@@ -0,0 +1,24 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
$:.push File.expand_path("../lib", __FILE__)
|
3
|
+
require "ffi-xattr/version"
|
4
|
+
|
5
|
+
Gem::Specification.new do |s|
|
6
|
+
s.name = "ffi-xattr"
|
7
|
+
s.version = Xattr::VERSION
|
8
|
+
s.platform = Gem::Platform::RUBY
|
9
|
+
s.authors = ["Jari Bakken"]
|
10
|
+
s.email = ["jari.bakken@gmail.com"]
|
11
|
+
s.homepage = "http://github.com/jarib/ffi-xattr"
|
12
|
+
s.summary = %q{Manipulate extended file attributes}
|
13
|
+
s.description = %q{Manipulate extended file attributes}
|
14
|
+
|
15
|
+
s.rubyforge_project = "ffi-xattr"
|
16
|
+
|
17
|
+
s.add_development_dependency "rspec", "~> 2.5"
|
18
|
+
s.add_dependency "ffi"
|
19
|
+
|
20
|
+
s.files = `git ls-files`.split("\n")
|
21
|
+
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
22
|
+
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
23
|
+
s.require_paths = ["lib"]
|
24
|
+
end
|
data/lib/ffi-xattr.rb
ADDED
@@ -0,0 +1,91 @@
|
|
1
|
+
require 'ffi'
|
2
|
+
require 'ffi-xattr/version'
|
3
|
+
|
4
|
+
class Xattr
|
5
|
+
module Lib
|
6
|
+
extend FFI::Library
|
7
|
+
|
8
|
+
ffi_lib "c"
|
9
|
+
|
10
|
+
attach_function :strerror, [:int], :string
|
11
|
+
|
12
|
+
attach_function :listxattr, [:string, :pointer, :size_t], :size_t
|
13
|
+
attach_function :setxattr, [:string, :string, :pointer, :size_t, :int], :int
|
14
|
+
attach_function :getxattr, [:string, :string, :pointer, :size_t], :int
|
15
|
+
attach_function :removexattr, [:string, :string], :int
|
16
|
+
end
|
17
|
+
|
18
|
+
def initialize(path)
|
19
|
+
raise Errno::ENOENT, path unless File.exist?(path)
|
20
|
+
@path = path
|
21
|
+
end
|
22
|
+
|
23
|
+
def list
|
24
|
+
size = Lib.listxattr(@path, nil, 0)
|
25
|
+
res_ptr = FFI::MemoryPointer.new(:pointer, size)
|
26
|
+
|
27
|
+
Lib.listxattr(@path, res_ptr, size)
|
28
|
+
res_ptr.read_string.split("\000")
|
29
|
+
end
|
30
|
+
|
31
|
+
def get(key)
|
32
|
+
size = Lib.getxattr(@path, key.to_s, nil, 0)
|
33
|
+
str_ptr = FFI::MemoryPointer.new(:char, size);
|
34
|
+
Lib.getxattr(@path, key.to_s, str_ptr, size)
|
35
|
+
|
36
|
+
str_ptr.read_string
|
37
|
+
end
|
38
|
+
|
39
|
+
def set(key, value)
|
40
|
+
key, value = key.to_s, value.to_s
|
41
|
+
|
42
|
+
check_error Lib.setxattr(@path, key, value, value.bytesize, 0)
|
43
|
+
end
|
44
|
+
|
45
|
+
def remove(key)
|
46
|
+
check_error Lib.removexattr(@path, key.to_s)
|
47
|
+
end
|
48
|
+
|
49
|
+
private
|
50
|
+
|
51
|
+
def check_error(int)
|
52
|
+
raise "unable to set xattr (#{Lib.strerror FFI.errno})" if int != 0
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
if __FILE__ == $0
|
57
|
+
require 'rspec/autorun'
|
58
|
+
|
59
|
+
describe Xattr do
|
60
|
+
let(:path) { "test.txt" }
|
61
|
+
let(:xattr) { Xattr.new(path) }
|
62
|
+
|
63
|
+
before { File.open(path, "w") { |io| io << "some content" } }
|
64
|
+
after { File.delete(path) }
|
65
|
+
|
66
|
+
it "has an inital empty list of xattrs" do
|
67
|
+
xattr.list.should be_kind_of(Array)
|
68
|
+
xattr.list.should be_empty
|
69
|
+
end
|
70
|
+
|
71
|
+
it "can set and get attributes" do
|
72
|
+
xattr.set "user.foo", "bar"
|
73
|
+
xattr.list.should == ["user.foo"]
|
74
|
+
|
75
|
+
xattr.get("user.foo").should == "bar"
|
76
|
+
end
|
77
|
+
|
78
|
+
it "can remove attributes" do
|
79
|
+
xattr.set "user.foo", "bar"
|
80
|
+
xattr.list.should == ["user.foo"]
|
81
|
+
|
82
|
+
xattr.remove "user.foo"
|
83
|
+
xattr.list.should == []
|
84
|
+
end
|
85
|
+
|
86
|
+
it "raises Errno::ENOENT if the file doesn't exist" do
|
87
|
+
lambda { Xattr.new("no-such-file") }.should raise_error(Errno::ENOENT)
|
88
|
+
end
|
89
|
+
|
90
|
+
end
|
91
|
+
end
|
data/spec/xattr_spec.rb
ADDED
@@ -0,0 +1,34 @@
|
|
1
|
+
require 'ffi-xattr'
|
2
|
+
|
3
|
+
describe Xattr do
|
4
|
+
let(:path) { "test.txt" }
|
5
|
+
let(:xattr) { Xattr.new(path) }
|
6
|
+
|
7
|
+
before { File.open(path, "w") { |io| io << "some content" } }
|
8
|
+
after { File.delete(path) }
|
9
|
+
|
10
|
+
it "has an inital empty list of xattrs" do
|
11
|
+
xattr.list.should be_kind_of(Array)
|
12
|
+
xattr.list.should be_empty
|
13
|
+
end
|
14
|
+
|
15
|
+
it "can set and get attributes" do
|
16
|
+
xattr.set "user.foo", "bar"
|
17
|
+
xattr.list.should == ["user.foo"]
|
18
|
+
|
19
|
+
xattr.get("user.foo").should == "bar"
|
20
|
+
end
|
21
|
+
|
22
|
+
it "can remove attributes" do
|
23
|
+
xattr.set "user.foo", "bar"
|
24
|
+
xattr.list.should == ["user.foo"]
|
25
|
+
|
26
|
+
xattr.remove "user.foo"
|
27
|
+
xattr.list.should == []
|
28
|
+
end
|
29
|
+
|
30
|
+
it "raises Errno::ENOENT if the file doesn't exist" do
|
31
|
+
lambda { Xattr.new("no-such-file") }.should raise_error(Errno::ENOENT)
|
32
|
+
end
|
33
|
+
|
34
|
+
end
|
metadata
ADDED
@@ -0,0 +1,82 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: ffi-xattr
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
prerelease:
|
5
|
+
version: 0.0.1
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Jari Bakken
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
|
13
|
+
date: 2011-09-23 00:00:00 Z
|
14
|
+
dependencies:
|
15
|
+
- !ruby/object:Gem::Dependency
|
16
|
+
name: rspec
|
17
|
+
prerelease: false
|
18
|
+
requirement: &id001 !ruby/object:Gem::Requirement
|
19
|
+
none: false
|
20
|
+
requirements:
|
21
|
+
- - ~>
|
22
|
+
- !ruby/object:Gem::Version
|
23
|
+
version: "2.5"
|
24
|
+
type: :development
|
25
|
+
version_requirements: *id001
|
26
|
+
- !ruby/object:Gem::Dependency
|
27
|
+
name: ffi
|
28
|
+
prerelease: false
|
29
|
+
requirement: &id002 !ruby/object:Gem::Requirement
|
30
|
+
none: false
|
31
|
+
requirements:
|
32
|
+
- - ">="
|
33
|
+
- !ruby/object:Gem::Version
|
34
|
+
version: "0"
|
35
|
+
type: :runtime
|
36
|
+
version_requirements: *id002
|
37
|
+
description: Manipulate extended file attributes
|
38
|
+
email:
|
39
|
+
- jari.bakken@gmail.com
|
40
|
+
executables: []
|
41
|
+
|
42
|
+
extensions: []
|
43
|
+
|
44
|
+
extra_rdoc_files: []
|
45
|
+
|
46
|
+
files:
|
47
|
+
- .gitignore
|
48
|
+
- Gemfile
|
49
|
+
- Rakefile
|
50
|
+
- ffi-xattr.gemspec
|
51
|
+
- lib/ffi-xattr.rb
|
52
|
+
- lib/ffi-xattr/version.rb
|
53
|
+
- spec/xattr_spec.rb
|
54
|
+
homepage: http://github.com/jarib/ffi-xattr
|
55
|
+
licenses: []
|
56
|
+
|
57
|
+
post_install_message:
|
58
|
+
rdoc_options: []
|
59
|
+
|
60
|
+
require_paths:
|
61
|
+
- lib
|
62
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
63
|
+
none: false
|
64
|
+
requirements:
|
65
|
+
- - ">="
|
66
|
+
- !ruby/object:Gem::Version
|
67
|
+
version: "0"
|
68
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
69
|
+
none: false
|
70
|
+
requirements:
|
71
|
+
- - ">="
|
72
|
+
- !ruby/object:Gem::Version
|
73
|
+
version: "0"
|
74
|
+
requirements: []
|
75
|
+
|
76
|
+
rubyforge_project: ffi-xattr
|
77
|
+
rubygems_version: 1.8.10
|
78
|
+
signing_key:
|
79
|
+
specification_version: 3
|
80
|
+
summary: Manipulate extended file attributes
|
81
|
+
test_files: []
|
82
|
+
|