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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: 03fc82a1353a14b6b48327682f8efb5327f8d4a6
4
- data.tar.gz: dd6a2abd62dd605cb0aae1cb65551e69f4c2d00f
2
+ SHA256:
3
+ metadata.gz: 4e89f2e515824d33bf4cfe74b95eea1526e35092c669bb5f4280c8d4c86071d4
4
+ data.tar.gz: 3369d3f39135d5176d1b24077eb380ff5140aa78498ccbd9f0b0291d2c36484c
5
5
  SHA512:
6
- metadata.gz: f9cc1cbaab866ac3a6d89d7066b8621ba66eb36ac45032df2a59b0c92a7d57fc297d3db3ed02bed7d41c05aa00520690f84d182979feca7ec881f5eb0ad7200c
7
- data.tar.gz: 73dc271860f7c541aac07195bdfe4cc3746bee9fa0755917967fe899f90ff91934b2f915230446f19bcbd947bda236a37cf372fb6aeb89d0d84840d02e68b244
6
+ metadata.gz: ea47fac5b6f82cf0c065724f3283bb72fe81f0636eb9613be1e7f89f42066e52cc038a8fa2d00ee12b8faa88f74dbb830f795eea1144ec7943f18bb40c134ef1
7
+ data.tar.gz: fd88cae5f42ca84e36214b76c82afedfd367c5e60e3767d786221ec62dbf95d9c9ea6ccf4e395ea55a2be9a66524bc015edad49b744505d7dcfca239b720145a
data/.gitignore CHANGED
@@ -3,3 +3,4 @@
3
3
  Gemfile.lock
4
4
  pkg/*
5
5
  /doc/
6
+ vendor
data/README.md CHANGED
@@ -3,9 +3,6 @@ ffi-xattr
3
3
 
4
4
  Ruby library to manage extended file attributes.
5
5
 
6
- [![Build Status](https://secure.travis-ci.org/jarib/ffi-xattr.png)](http://travis-ci.org/jarib/ffi-xattr)
7
-
8
-
9
6
  Example
10
7
  -------
11
8
 
@@ -16,7 +16,7 @@ class Xattr # :nodoc: all
16
16
  end
17
17
 
18
18
  def check(int)
19
- raise SystemCallError.new(*last) if int != 0
19
+ raise SystemCallError.new(*last) if int < 0
20
20
  end
21
21
  end
22
22
  end
@@ -0,0 +1,9 @@
1
+ require 'ffi-xattr'
2
+
3
+ class File
4
+
5
+ # Returns an Xattr object for the named file (see Xattr).
6
+ def self.xattr(file_name)
7
+ Xattr.new(file_name)
8
+ end
9
+ end
@@ -0,0 +1,9 @@
1
+ require 'ffi-xattr/extensions/file'
2
+
3
+ class Pathname
4
+ # Returns an Xattr object.
5
+ # See File.xattr.
6
+ def xattr
7
+ File.xattr(self)
8
+ end
9
+ end
@@ -0,0 +1,3 @@
1
+ require 'ffi-xattr/extensions/file'
2
+ require 'ffi-xattr/extensions/pathname'
3
+
@@ -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
@@ -1,3 +1,3 @@
1
1
  class Xattr
2
- VERSION = "0.1.0"
2
+ VERSION = "0.2.0"
3
3
  end
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
- raise Errno::ENOENT, path unless File.exist?(path)
23
- @path = path.to_str
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
- def as_json(*args)
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 be_true
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.as_json.should == {'user.foo' => 'bar', 'user.bar' => 'baz'}
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
- class SuperPath
86
- def initialize(path)
87
- @path = path
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
- def to_str
91
- @path.dup
92
- end
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 directly converted to string" do
96
- super_path = SuperPath.new(path)
97
- Xattr.new(super_path).set('user.foo', 'bar')
98
- Xattr.new(super_path).get('user.foo').should == 'bar'
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.1.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: 2014-01-30 00:00:00.000000000 Z
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
- rubyforge_project: ffi-xattr
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: