ffi-xattr 0.1.0 → 0.2.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.
- checksums.yaml +5 -5
- data/.gitignore +1 -0
- data/README.md +0 -3
- data/lib/ffi-xattr/error.rb +1 -1
- data/lib/ffi-xattr/extensions/file.rb +9 -0
- data/lib/ffi-xattr/extensions/pathname.rb +9 -0
- data/lib/ffi-xattr/extensions.rb +3 -0
- data/lib/ffi-xattr/freebsd_lib.rb +62 -0
- data/lib/ffi-xattr/version.rb +1 -1
- data/lib/ffi-xattr.rb +19 -3
- data/spec/extensions_spec.rb +35 -0
- data/spec/xattr_spec.rb +18 -14
- metadata +9 -5
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 4e89f2e515824d33bf4cfe74b95eea1526e35092c669bb5f4280c8d4c86071d4
|
4
|
+
data.tar.gz: 3369d3f39135d5176d1b24077eb380ff5140aa78498ccbd9f0b0291d2c36484c
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: ea47fac5b6f82cf0c065724f3283bb72fe81f0636eb9613be1e7f89f42066e52cc038a8fa2d00ee12b8faa88f74dbb830f795eea1144ec7943f18bb40c134ef1
|
7
|
+
data.tar.gz: fd88cae5f42ca84e36214b76c82afedfd367c5e60e3767d786221ec62dbf95d9c9ea6ccf4e395ea55a2be9a66524bc015edad49b744505d7dcfca239b720145a
|
data/.gitignore
CHANGED
data/README.md
CHANGED
data/lib/ffi-xattr/error.rb
CHANGED
@@ -0,0 +1,62 @@
|
|
1
|
+
class Xattr # :nodoc: all
|
2
|
+
module Lib
|
3
|
+
extend FFI::Library
|
4
|
+
|
5
|
+
ffi_lib "c"
|
6
|
+
|
7
|
+
EXTATTR_NAMESPACE_USER = 1
|
8
|
+
|
9
|
+
attach_function :extattr_list_file, [:string, :int, :pointer, :size_t], :ssize_t
|
10
|
+
attach_function :extattr_set_file, [:string, :int, :string, :pointer, :size_t], :ssize_t
|
11
|
+
attach_function :extattr_get_file, [:string, :int, :string, :pointer, :size_t], :ssize_t
|
12
|
+
attach_function :extattr_delete_file, [:string, :int, :string], :ssize_t
|
13
|
+
|
14
|
+
attach_function :extattr_list_link, [:string, :int, :pointer, :size_t], :ssize_t
|
15
|
+
attach_function :extattr_set_link, [:string, :int, :string, :pointer, :size_t], :ssize_t
|
16
|
+
attach_function :extattr_get_link, [:string, :int, :string, :pointer, :size_t], :ssize_t
|
17
|
+
attach_function :extattr_delete_link, [:string, :int, :string], :ssize_t
|
18
|
+
|
19
|
+
class << self
|
20
|
+
def list(path, no_follow)
|
21
|
+
method = no_follow ? :extattr_list_link : :extattr_list_file
|
22
|
+
size = send(method, path, EXTATTR_NAMESPACE_USER, nil, 0)
|
23
|
+
res_ptr = FFI::MemoryPointer.new(:pointer, size)
|
24
|
+
send(method, path, EXTATTR_NAMESPACE_USER, res_ptr, size)
|
25
|
+
|
26
|
+
res = []
|
27
|
+
bytes = res_ptr.read_string(size).bytes
|
28
|
+
until bytes.empty?
|
29
|
+
size = bytes.shift
|
30
|
+
res << bytes.shift(size).map(&:chr).join
|
31
|
+
end
|
32
|
+
|
33
|
+
res
|
34
|
+
end
|
35
|
+
|
36
|
+
def get(path, no_follow, key)
|
37
|
+
method = no_follow ? :extattr_get_link : :extattr_get_file
|
38
|
+
size = send(method, path, EXTATTR_NAMESPACE_USER, key, nil, 0)
|
39
|
+
return unless size > 0
|
40
|
+
|
41
|
+
str_ptr = FFI::MemoryPointer.new(:char, size)
|
42
|
+
send(method, path, EXTATTR_NAMESPACE_USER, key, str_ptr, size)
|
43
|
+
|
44
|
+
str_ptr.read_string(size)
|
45
|
+
end
|
46
|
+
|
47
|
+
def set(path, no_follow, key, value)
|
48
|
+
method = no_follow ? :extattr_set_link : :extattr_set_file
|
49
|
+
#require 'byebug'
|
50
|
+
#byebug
|
51
|
+
|
52
|
+
Error.check send(method, path, EXTATTR_NAMESPACE_USER, key, value, value.bytesize)
|
53
|
+
end
|
54
|
+
|
55
|
+
def remove(path, no_follow, key)
|
56
|
+
method = no_follow ? :extattr_delete_link : :extattr_delete_file
|
57
|
+
Error.check send(method, path, EXTATTR_NAMESPACE_USER, key)
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
end
|
62
|
+
end
|
data/lib/ffi-xattr/version.rb
CHANGED
data/lib/ffi-xattr.rb
CHANGED
@@ -5,6 +5,8 @@ require 'ffi-xattr/error'
|
|
5
5
|
case RUBY_PLATFORM
|
6
6
|
when /linux/
|
7
7
|
require 'ffi-xattr/linux_lib'
|
8
|
+
when /freebsd/
|
9
|
+
require 'ffi-xattr/freebsd_lib'
|
8
10
|
when /darwin|bsd/
|
9
11
|
require 'ffi-xattr/darwin_lib'
|
10
12
|
when /mingw/
|
@@ -19,8 +21,16 @@ class Xattr
|
|
19
21
|
# Create a new Xattr instance with path.
|
20
22
|
# Use <tt>:no_follow => true</tt> in options to work on symlink itself instead of following it.
|
21
23
|
def initialize(path, options = {})
|
22
|
-
|
23
|
-
|
24
|
+
@path =
|
25
|
+
if path.respond_to?(:to_path)
|
26
|
+
path.to_path
|
27
|
+
elsif path.respond_to?(:to_str)
|
28
|
+
path.to_str
|
29
|
+
else
|
30
|
+
path
|
31
|
+
end
|
32
|
+
raise Errno::ENOENT, @path unless File.exist?(@path)
|
33
|
+
|
24
34
|
@no_follow = !!options[:no_follow]
|
25
35
|
end
|
26
36
|
|
@@ -54,11 +64,17 @@ class Xattr
|
|
54
64
|
end
|
55
65
|
|
56
66
|
# Returns hash of extended attributes
|
57
|
-
|
67
|
+
|
68
|
+
def to_hash
|
58
69
|
res = {}
|
59
70
|
each { |k,v| res[k] = v }
|
60
71
|
|
61
72
|
res
|
62
73
|
end
|
63
74
|
|
75
|
+
alias_method :to_h, :to_hash
|
76
|
+
|
77
|
+
def as_json(*args)
|
78
|
+
to_hash
|
79
|
+
end
|
64
80
|
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
require 'ffi-xattr/extensions'
|
2
|
+
|
3
|
+
describe "Xattr extensions" 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
|
+
describe "File.xattr" do
|
11
|
+
it "should return an Xattr for the supplied path" do
|
12
|
+
x = File.xattr(path)
|
13
|
+
|
14
|
+
x.should be_kind_of(Xattr)
|
15
|
+
|
16
|
+
#and operate on the real path
|
17
|
+
x["user.file"] = "foo"
|
18
|
+
Xattr.new(path)["user.file"].should == "foo"
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
describe "Pathname#xattr" do
|
23
|
+
it "should return an Xattr for the underlying path" do
|
24
|
+
p = Pathname.new(path)
|
25
|
+
x = p.xattr
|
26
|
+
|
27
|
+
x.should be_kind_of(Xattr)
|
28
|
+
|
29
|
+
#and operate on the real path
|
30
|
+
x["user.path"] = "foo"
|
31
|
+
Xattr.new(path)["user.path"].should == "foo"
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
end
|
data/spec/xattr_spec.rb
CHANGED
@@ -57,7 +57,7 @@ describe Xattr do
|
|
57
57
|
value.should == "world"
|
58
58
|
end
|
59
59
|
|
60
|
-
called.should
|
60
|
+
called.should == true
|
61
61
|
end
|
62
62
|
|
63
63
|
it "is Enumerable" do
|
@@ -67,11 +67,13 @@ describe Xattr do
|
|
67
67
|
xattr.to_a.should == [['user.foo', 'bar']]
|
68
68
|
end
|
69
69
|
|
70
|
-
it "returns a Hash for #as_json" do
|
70
|
+
it "returns a Hash for #to_hash, #to_h, #as_json" do
|
71
71
|
xattr['user.foo'] = 'bar'
|
72
72
|
xattr['user.bar'] = 'baz'
|
73
73
|
|
74
|
-
xattr.
|
74
|
+
xattr.to_hash.should == {'user.foo' => 'bar', 'user.bar' => 'baz'}
|
75
|
+
xattr.to_h.should == {'user.foo' => 'bar', 'user.bar' => 'baz'}
|
76
|
+
xattr.as_json(foo: 1).should == {'user.foo' => 'bar', 'user.bar' => 'baz'}
|
75
77
|
end
|
76
78
|
|
77
79
|
it "raises Errno::ENOENT if the file doesn't exist" do
|
@@ -82,20 +84,22 @@ describe Xattr do
|
|
82
84
|
lambda{ Xattr.new(1) }.should raise_error(TypeError)
|
83
85
|
end
|
84
86
|
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
end
|
87
|
+
it "should work with object that can be converted to string" do
|
88
|
+
super_path = double("super_path")
|
89
|
+
super_path.should_receive(:to_str).and_return(path)
|
89
90
|
|
90
|
-
|
91
|
-
|
92
|
-
|
91
|
+
Xattr.new(super_path).set('user.foo', 'bar')
|
92
|
+
|
93
|
+
Xattr.new(path).get('user.foo').should == 'bar'
|
93
94
|
end
|
94
95
|
|
95
|
-
it "should work with object that can be
|
96
|
-
|
97
|
-
|
98
|
-
|
96
|
+
it "should work with object that can be coerced to string with #to_path" do
|
97
|
+
to_path_obj = double("to_path")
|
98
|
+
to_path_obj.should_receive(:to_path).and_return(path)
|
99
|
+
|
100
|
+
Xattr.new(to_path_obj).set('user.to_path', 'bar')
|
101
|
+
|
102
|
+
Xattr.new(path).get('user.to_path').should == 'bar'
|
99
103
|
end
|
100
104
|
|
101
105
|
describe "respecting :no_follow option" do
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: ffi-xattr
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Jari Bakken
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2022-05-16 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: ffi
|
@@ -69,9 +69,14 @@ files:
|
|
69
69
|
- lib/ffi-xattr.rb
|
70
70
|
- lib/ffi-xattr/darwin_lib.rb
|
71
71
|
- lib/ffi-xattr/error.rb
|
72
|
+
- lib/ffi-xattr/extensions.rb
|
73
|
+
- lib/ffi-xattr/extensions/file.rb
|
74
|
+
- lib/ffi-xattr/extensions/pathname.rb
|
75
|
+
- lib/ffi-xattr/freebsd_lib.rb
|
72
76
|
- lib/ffi-xattr/linux_lib.rb
|
73
77
|
- lib/ffi-xattr/version.rb
|
74
78
|
- lib/ffi-xattr/windows_lib.rb
|
79
|
+
- spec/extensions_spec.rb
|
75
80
|
- spec/xattr_spec.rb
|
76
81
|
homepage: http://github.com/jarib/ffi-xattr
|
77
82
|
licenses: []
|
@@ -91,11 +96,10 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
91
96
|
- !ruby/object:Gem::Version
|
92
97
|
version: '0'
|
93
98
|
requirements: []
|
94
|
-
|
95
|
-
rubygems_version: 2.2.0
|
99
|
+
rubygems_version: 3.0.3.1
|
96
100
|
signing_key:
|
97
101
|
specification_version: 4
|
98
102
|
summary: Manipulate extended file attributes
|
99
103
|
test_files:
|
104
|
+
- spec/extensions_spec.rb
|
100
105
|
- spec/xattr_spec.rb
|
101
|
-
has_rdoc:
|