Skip to content

Commit

Permalink
Initial commit
Browse files Browse the repository at this point in the history
  • Loading branch information
jarib committed Sep 23, 2011
0 parents commit 63af76a
Show file tree
Hide file tree
Showing 6 changed files with 136 additions and 0 deletions.
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
*.gem
.bundle
Gemfile.lock
pkg/*
4 changes: 4 additions & 0 deletions Gemfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
source "http:https://rubygems.org"

# Specify your gem's dependencies in ffi-xattr.gemspec
gemspec
8 changes: 8 additions & 0 deletions Rakefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
require 'bundler'
Bundler::GemHelper.install_tasks

task :spec do
ruby "lib/ffi-xattr.rb"
end

task :default => :spec
24 changes: 24 additions & 0 deletions ffi-xattr.gemspec
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
# -*- encoding: utf-8 -*-
$:.push File.expand_path("../lib", __FILE__)
require "ffi-xattr/version"

Gem::Specification.new do |s|
s.name = "ffi-xattr"
s.version = Ffi::Xattr::VERSION
s.platform = Gem::Platform::RUBY
s.authors = ["Jari Bakken"]
s.email = ["[email protected]"]
s.homepage = "http:https://github.com/jarib/ffi-xattr"
s.summary = %q{Manipulate extended file attributes}
s.description = %q{Manipulate extended file attributes}

s.rubyforge_project = "ffi-xattr"

s.add_development_dependency "rspec", "~> 2.5"
s.add_dependency "ffi"

s.files = `git ls-files`.split("\n")
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
s.require_paths = ["lib"]
end
91 changes: 91 additions & 0 deletions lib/ffi-xattr.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
require 'rubygems'
require 'ffi'

class Xattr
module Lib
extend FFI::Library

ffi_lib "c"

attach_function :strerror, [:int], :string

attach_function :listxattr, [:string, :pointer, :size_t], :size_t
attach_function :setxattr, [:string, :string, :pointer, :size_t, :int], :int
attach_function :getxattr, [:string, :string, :pointer, :size_t], :int
attach_function :removexattr, [:string, :string], :int
end

def initialize(path)
raise Errno::ENOENT, path unless File.exist?(path)
@path = path
end

def list
size = Lib.listxattr(@path, nil, 0)
res_ptr = FFI::MemoryPointer.new(:pointer, size)

Lib.listxattr(@path, res_ptr, size)
res_ptr.read_string.split("\000")
end

def get(key)
size = Lib.getxattr(@path, key.to_s, nil, 0)
str_ptr = FFI::MemoryPointer.new(:char, size);
Lib.getxattr(@path, key.to_s, str_ptr, size)

str_ptr.read_string
end

def set(key, value)
key, value = key.to_s, value.to_s

check_error Lib.setxattr(@path, key, value, value.bytesize, 0)
end

def remove(key)
check_error Lib.removexattr(@path, key.to_s)
end

private

def check_error(int)
raise "unable to set xattr (#{Lib.strerror FFI.errno})" if int != 0
end
end

if __FILE__ == $0
require 'rspec/autorun'

describe Xattr do
let(:path) { "test.txt" }
let(:xattr) { Xattr.new(path) }

before { File.open(path, "w") { |io| io << "some content" } }
after { File.delete(path) }

it "has an inital empty list of xattrs" do
xattr.list.should be_kind_of(Array)
xattr.list.should be_empty
end

it "can set and get attributes" do
xattr.set "user.foo", "bar"
xattr.list.should == ["user.foo"]

xattr.get("user.foo").should == "bar"
end

it "can remove attributes" do
xattr.set "user.foo", "bar"
xattr.list.should == ["user.foo"]

xattr.remove "user.foo"
xattr.list.should == []
end

it "raises Errno::ENOENT if the file doesn't exist" do
lambda { Xattr.new("no-such-file") }.should raise_error(Errno::ENOENT)
end

end
end
5 changes: 5 additions & 0 deletions lib/ffi-xattr/version.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
module Ffi
module Xattr
VERSION = "0.0.1"
end
end

0 comments on commit 63af76a

Please sign in to comment.