Open pieterb opened 11 years ago
Hmpf... I can't attach the patch as a file, but here it is:
diff --git a/lib/ffi-xattr.rb b/lib/ffi-xattr.rb
index 0b8ddcb..82e77b3 100644
--- a/lib/ffi-xattr.rb
+++ b/lib/ffi-xattr.rb
@@ -3,7 +3,7 @@ require 'ffi-xattr/version'
require 'ffi-xattr/error'
case RUBY_PLATFORM
-when /linux/
+when /linux/, /java/i
require 'ffi-xattr/linux_lib'
when /darwin|bsd/
require 'ffi-xattr/darwin_lib'
@@ -17,8 +17,12 @@ class Xattr
# Create a new Xattr instance with path.
# Use <tt>:no_follow => true</tt> in options to work on symlink itself instead of following it.
def initialize(path, options = {})
- raise Errno::ENOENT, path unless File.exist?(path)
- @path = path.to_str
+ if path.respond_to? :fileno
+ @path = path.fileno
+ else
+ @path = path.to_str
+ raise Errno::ENOENT, path unless File.exist?(@path)
+ end
@no_follow = !!options[:no_follow]
end
diff --git a/lib/ffi-xattr/darwin_lib.rb b/lib/ffi-xattr/darwin_lib.rb
index 59f0810..92850bf 100644
--- a/lib/ffi-xattr/darwin_lib.rb
+++ b/lib/ffi-xattr/darwin_lib.rb
@@ -4,42 +4,71 @@ class Xattr # :nodoc: all
ffi_lib "System"
- attach_function :listxattr, [:string, :pointer, :size_t, :int], :ssize_t
- attach_function :getxattr, [:string, :string, :pointer, :size_t, :uint, :int], :ssize_t
- attach_function :setxattr, [:string, :string, :pointer, :size_t, :uint, :int], :int
- attach_function :removexattr, [:string, :string, :int], :int
+ attach_function :listxattr, [:string, :pointer, :size_t, :int], :ssize_t
+ attach_function :getxattr, [:string, :string, :pointer, :size_t, :uint, :int], :ssize_t
+ attach_function :setxattr, [:string, :string, :pointer, :size_t, :uint, :int], :int
+ attach_function :removexattr, [:string, :string, :int], :int
+
+ attach_function :flistxattr, [:int, :pointer, :size_t, :int], :ssize_t
+ attach_function :fgetxattr, [:int, :string, :pointer, :size_t, :uint, :int], :ssize_t
+ attach_function :fsetxattr, [:int, :string, :pointer, :size_t, :uint, :int], :int
+ attach_function :fremovexattr, [:int, :string, :int], :int
XATTR_NOFOLLOW = 0x0001
class << self
def list(path, no_follow)
- options = no_follow ? XATTR_NOFOLLOW : 0
- size = listxattr(path, nil, 0, options)
+ if path.kind_of?(Integer)
+ options = 0
+ method = :flistxattr
+ else
+ options = no_follow ? XATTR_NOFOLLOW : 0
+ method = :listxattr
+ end
+ size = send(method, path, nil, 0, options)
res_ptr = FFI::MemoryPointer.new(:pointer, size)
- listxattr(path, res_ptr, size, options)
+ send(method, path, res_ptr, size, options)
res_ptr.read_string(size).split("\000")
end
def get(path, no_follow, key)
- options = no_follow ? XATTR_NOFOLLOW : 0
- size = getxattr(path, key, nil, 0, 0, options)
+ if path.kind_of?(Integer)
+ options = 0
+ method = :fgetxattr
+ else
+ options = no_follow ? XATTR_NOFOLLOW : 0
+ method = :getxattr
+ end
+ size = send(method, path, key, nil, 0, 0, options)
return unless size > 0
str_ptr = FFI::MemoryPointer.new(:char, size)
- getxattr(path, key, str_ptr, size, 0, options)
+ send(method, path, key, str_ptr, size, 0, options)
str_ptr.read_string(size)
end
def set(path, no_follow, key, value)
- options = no_follow ? XATTR_NOFOLLOW : 0
- Error.check setxattr(path, key, value, value.bytesize, 0, options)
+ if path.kind_of?(Integer)
+ options = 0
+ method = :fsetxattr
+ else
+ options = no_follow ? XATTR_NOFOLLOW : 0
+ method = :setxattr
+ end
+ Error.check send(method, path, key, value, value.bytesize, 0, options)
end
def remove(path, no_follow, key)
- options = no_follow ? XATTR_NOFOLLOW : 0
- Error.check removexattr(path, key, options)
+ if path.kind_of?(Integer)
+ options = 0
+ method = :fremovexattr
+ else
+ options = no_follow ? XATTR_NOFOLLOW : 0
+ method = :removexattr
+ end
+ Error.check send(method, path, key, options)
end
end
diff --git a/lib/ffi-xattr/linux_lib.rb b/lib/ffi-xattr/linux_lib.rb
index e90a8ad..a7a9718 100644
--- a/lib/ffi-xattr/linux_lib.rb
+++ b/lib/ffi-xattr/linux_lib.rb
@@ -16,10 +16,18 @@ class Xattr # :nodoc: all
attach_function :lgetxattr, [:string, :string, :pointer, :size_t], :int
attach_function :lremovexattr, [:string, :string], :int
+ attach_function :flistxattr, [:int, :pointer, :size_t], :size_t
+ attach_function :fsetxattr, [:int, :string, :pointer, :size_t, :int], :int
+ attach_function :fgetxattr, [:int, :string, :pointer, :size_t], :int
+ attach_function :fremovexattr, [:int, :string], :int
+
class << self
def list(path, no_follow)
- method = no_follow ? :llistxattr : :listxattr
- size = send(method, path, nil, 0)
+ method = path.kind_of?(Integer) ? :flistxattr :
+ no_follow ? :llistxattr : :listxattr
+ $stderr.puts method.to_s
+ Error.check( size = send(method, path, nil, 0) )
+ $stderr.puts size.to_s
res_ptr = FFI::MemoryPointer.new(:pointer, size)
send(method, path, res_ptr, size)
@@ -27,7 +35,8 @@ class Xattr # :nodoc: all
end
def get(path, no_follow, key)
- method = no_follow ? :lgetxattr : :getxattr
+ method = path.kind_of?(Integer) ? :fgetxattr :
+ no_follow ? :lgetxattr : :getxattr
size = send(method, path, key, nil, 0)
return unless size > 0
@@ -38,12 +47,14 @@ class Xattr # :nodoc: all
end
def set(path, no_follow, key, value)
- method = no_follow ? :lsetxattr : :setxattr
+ method = path.kind_of?(Integer) ? :fsetxattr :
+ no_follow ? :lsetxattr : :setxattr
Error.check send(method, path, key, value, value.bytesize, 0)
end
def remove(path, no_follow, key)
- method = no_follow ? :lremovexattr : :removexattr
+ method = path.kind_of?(Integer) ? :fremovexattr :
+ no_follow ? :lremovexattr : :removexattr
Error.check send(method, path, key)
end
end
Currently, the gem supports
listxattr
,getxattr
,setxattr
andremovexattr
for manipulating extended attributes on files, andl*xattr
for manipulating symbolic links. However, on my platform there's also the function familyf*xattr
, to manipulate extended attributes on file descriptors.setxattr
listxattr
getxattr
removexattr
lsetxattr
llistxattr
lgetxattr
lremovexattr
fsetxattr
flistxattr
fgetxattr
fremovexattr
I tried to create a patch, but didn't get it to work because I don't know enough about ffi. I'll try to append a patch file to this issue, so you can see what I'm trying to achieve.