extattr 0.1.2-x86-mingw32 → 0.2-x86-mingw32
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 +7 -0
- data/{LICENSE.txt → LICENSE.md} +2 -0
- data/README.md +161 -0
- data/Rakefile +105 -0
- data/ext/extattr-extattr.h +192 -0
- data/ext/extattr-windows.h +724 -0
- data/ext/extattr-xattr.h +229 -0
- data/ext/extattr.c +227 -102
- data/ext/extconf.rb +14 -12
- data/lib/1.9.1/extattr.so +0 -0
- data/lib/2.0.0/extattr.so +0 -0
- data/lib/2.1.0/extattr.so +0 -0
- data/lib/extattr.rb +47 -0
- data/{rspecs/extattr.rb → spec/extattr_spec.rb} +0 -0
- metadata +54 -31
- data/README.txt +0 -73
- data/ext/extattr.bsd +0 -186
- data/ext/extattr.linux +0 -222
- data/ext/extattr.windows +0 -460
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: d6d99eac254bb8d67558c05ea93da19496757a29
|
4
|
+
data.tar.gz: f87a14e3b9c35ee3eec6b615fed29b9c7bdcea89
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 698259f2a814973dd961bb2cc86e1146a90e284fad84dafaedd4e32f28fd07d344172e8c2bf86c42b8ef03e85404b9e579a60ed362d054000d3de8086f5a6185
|
7
|
+
data.tar.gz: 5fc508d721df9c7203fe670479c34aaa1ab72a312fd4c4a1c80ac9dc82a6efbe9fd7c5e15043ae4aa5a37a745eb93bf73e6b9c1078a3b75ce13d18b3b1229759
|
data/{LICENSE.txt → LICENSE.md}
RENAMED
data/README.md
ADDED
@@ -0,0 +1,161 @@
|
|
1
|
+
# @markup markdown
|
2
|
+
|
3
|
+
# extattr
|
4
|
+
|
5
|
+
extattr is filesystem extended attributes operation library for FreeBSD, GNU/Linux and Microsoft Windows.
|
6
|
+
|
7
|
+
***END OF DOCUMENT IN ENGLISH***
|
8
|
+
|
9
|
+
----
|
10
|
+
|
11
|
+
***START OF DOCUMENT IN JAPANESE***
|
12
|
+
|
13
|
+
extattr はファイルシステムの拡張属性を操作するライブラリで、FreeBSD、GNU/Linux、Windows に対応しています。
|
14
|
+
|
15
|
+
サポートされる環境で、統一的なメソッドを提供します。
|
16
|
+
|
17
|
+
実装については、以下のようになっています。
|
18
|
+
|
19
|
+
- FreeBSD: extattr (`extattr_list`, `extattr_get`, `extattr_set`, `extattr_delete`)
|
20
|
+
- GNU/Linux: xattr (`listxattr`, `getxattr`, `setxattr`, `removexattr`)
|
21
|
+
- Microsoft Windows: NTFS ADS (代替データストリーム) / 拡張ファイル属性 (`NtQueryEaFile`, `NtSetEaFile`)
|
22
|
+
|
23
|
+
|
24
|
+
## Support ruby version
|
25
|
+
|
26
|
+
- ruby-1.9.3+
|
27
|
+
- ruby-2.0+
|
28
|
+
- ruby-2.1+
|
29
|
+
|
30
|
+
|
31
|
+
## Tested system
|
32
|
+
|
33
|
+
- PC-BSD/AMD64 10.0
|
34
|
+
- lubuntu 13.10 (i386)
|
35
|
+
- Microsoft Windows XP Professional SP3
|
36
|
+
- Microsoft Windows 7 Professional SP1
|
37
|
+
|
38
|
+
|
39
|
+
## 簡易リファレンスマニュアル
|
40
|
+
|
41
|
+
クラスメソッドに『!』がついているものはシンボリックリンクに対する操作となります。
|
42
|
+
|
43
|
+
キーワード引数の `namespace` を与えると、拡張属性の名前空間を指定できます。
|
44
|
+
|
45
|
+
規定値は `File::EXTATTR_NAMESPACE_USER` で、ほかの値は `File::EXTATTR_NAMESPACE_SYSTEM` のみが指定できます。
|
46
|
+
|
47
|
+
|
48
|
+
### 拡張属性の属性名を取得
|
49
|
+
|
50
|
+
File.extattr_list(path, namespace: File::EXTATTR_NAMESPACE_USER) -> array
|
51
|
+
File.extattr_list(path, namespace: File::EXTATTR_NAMESPACE_USER) { |name| ... } -> nil
|
52
|
+
File.extattr_list!(path, namespace: File::EXTATTR_NAMESPACE_USER) -> array
|
53
|
+
File.extattr_list!(path, namespace: File::EXTATTR_NAMESPACE_USER) { |name| ... } -> nil
|
54
|
+
File#extattr_list(namespace: File::EXTATTR_NAMESPACE_USER) -> array
|
55
|
+
File#extattr_list(namespace: File::EXTATTR_NAMESPACE_USER) { |name| ... } -> nil
|
56
|
+
|
57
|
+
### 拡張属性の要素の大きさを取得
|
58
|
+
|
59
|
+
File.extattr_size(path, name, namespace: File::EXTATTR_NAMESPACE_USER) -> size
|
60
|
+
File.extattr_size!(path, name, namespace: File::EXTATTR_NAMESPACE_USER) -> size
|
61
|
+
File#extattr_size(name, namespace: File::EXTATTR_NAMESPACE_USER) -> size
|
62
|
+
|
63
|
+
### 拡張属性の要素を取得
|
64
|
+
|
65
|
+
File.extattr_get(path, name, namespace: File::EXTATTR_NAMESPACE_USER) -> data (String)
|
66
|
+
File.extattr_get!(path, name, namespace: File::EXTATTR_NAMESPACE_USER) -> data (String)
|
67
|
+
File#extattr_get(name, namespace: File::EXTATTR_NAMESPACE_USER) -> data (String)
|
68
|
+
|
69
|
+
### 拡張属性の要素を設定
|
70
|
+
|
71
|
+
File.extattr_set(path, name, data, namespace: File::EXTATTR_NAMESPACE_USER) -> nil
|
72
|
+
File.extattr_set!(path, name, data, namespace: File::EXTATTR_NAMESPACE_USER) -> nil
|
73
|
+
File#extattr_set(name, data, namespace: File::EXTATTR_NAMESPACE_USER) -> nil
|
74
|
+
|
75
|
+
### 拡張属性の要素を削除
|
76
|
+
|
77
|
+
File.extattr_delete(path, name, namespace: File::EXTATTR_NAMESPACE_USER) -> nil
|
78
|
+
File.extattr_delete!(path, name, namespace: File::EXTATTR_NAMESPACE_USER) -> nil
|
79
|
+
File#extattr_delete(name, namespace: File::EXTATTR_NAMESPACE_USER) -> nil
|
80
|
+
|
81
|
+
### 拡張属性の属性名と要素を列挙する
|
82
|
+
|
83
|
+
File.extattr_each(path, namespace: File::EXTATTR_NAMESPACE_USER) -> Enumerator
|
84
|
+
File.extattr_each(path, namespace: File::EXTATTR_NAMESPACE_USER) { |name, data| ... } -> nil
|
85
|
+
File.extattr_each!(path, namespace: File::EXTATTR_NAMESPACE_USER) -> Enumerator
|
86
|
+
File.extattr_each!(path, namespace: File::EXTATTR_NAMESPACE_USER) { |name, data| ... } -> nil
|
87
|
+
File#extattr_each(namespace: File::EXTATTR_NAMESPACE_USER) -> Enumerator
|
88
|
+
File#extattr_each(namespace: File::EXTATTR_NAMESPACE_USER) { |name, data| ... } -> file
|
89
|
+
|
90
|
+
|
91
|
+
## GNU/Linux における特記事項
|
92
|
+
|
93
|
+
- GNU/Linux で利用されている名前空間〈security〉〈trusted〉には未対応です。
|
94
|
+
|
95
|
+
|
96
|
+
## Microsoft Windows における特記事項
|
97
|
+
|
98
|
+
- Windows XP 以降を必要とします。Win2k でも動作するかもしれません (未検証)。
|
99
|
+
Windows 9x シリーズでは `require "extattr"` の段階で例外が発生すると思われます (未検証)。
|
100
|
+
- `File::EXTATTR_NAMESPACE_USER` は (比較的よく利用される) NTFS ADS に対する操作で、`File::EXTATTR_NAMESPACE_SYSTEM` が本来の (あまり利用されていない) 拡張ファイル属性に対する操作となります。
|
101
|
+
- リパースポイント (ジャンクションやシンボリックリンク) に対する NTFS ADS は要素の取得や設定、削除は出来ません。
|
102
|
+
必ずリンク先に対する操作となります (やり方がわかりません)。
|
103
|
+
- 64 KiB を超える NTFS ADS は取得も設定も出来ません。
|
104
|
+
これは『拡張属性』と捉えた場合、巨大なデータを扱えるべきではないという考えによるためです
|
105
|
+
(本当のところは FreeBSD の拡張属性が最大 64KiB 弱であることが由来です)。
|
106
|
+
- 巨大な NTFS ADS を扱いたい場合は、`File.open` でファイルとして扱えるので自由に読み書きできます。
|
107
|
+
これは ruby に限ったことではなく、Windows による仕様です。
|
108
|
+
この場合の与えるファイル名は、`path + ":" + name` という形になります。
|
109
|
+
|
110
|
+
filepath = "sample.txt"
|
111
|
+
extattrname = "category"
|
112
|
+
ntfs_ads_name = filepath + ":" + extattrname
|
113
|
+
File.open(ntfs_ads_name, "r") do |file|
|
114
|
+
...
|
115
|
+
end
|
116
|
+
|
117
|
+
## 既知のバグ
|
118
|
+
|
119
|
+
### `extattr_list` のブロック内で `extattr_set` `extattr_delete` を行うと思いがけない副作用が起こる場合がある
|
120
|
+
|
121
|
+
解決方法: `extattr_set` か `extattr_delete` のどちらかを同時に利用したい場合、`extattr_list.each` を用いてください。
|
122
|
+
|
123
|
+
|
124
|
+
## 変更履歴
|
125
|
+
|
126
|
+
### 0.1
|
127
|
+
|
128
|
+
はじめてのりりーす
|
129
|
+
|
130
|
+
- 拡張ファイル属性の一覧、取得、設定、削除を行うことが出来ます
|
131
|
+
- **セキュリティリスクあり**: `$SAFE` の確認や汚染状態の伝播を行ないません
|
132
|
+
- Windows 版では、NTFS ADS に対する操作となります。`File::EXTATTR_NAMESPACE_USER` のみが有効です
|
133
|
+
|
134
|
+
### 0.2
|
135
|
+
|
136
|
+
- セーフレベルに関する改善
|
137
|
+
- `$SAFE` と汚染状態を確認するようになりました
|
138
|
+
- 汚染状態を伝播させるようになりました
|
139
|
+
- バージョン情報と実装 API に関する情報の取得
|
140
|
+
- `File::EXTATTR_VERSION` 定数によって、バージョン情報が取得できるようになりました
|
141
|
+
- `File::EXTATTR_IMPLEMENT` 定数によって、実装に関する情報が取得できるようになりました
|
142
|
+
- 機能の改善
|
143
|
+
- `File.extattr_each` / `File#extattr_each` によって、ファイル拡張属性の名前と値を繰り返し取得できるようになりました
|
144
|
+
- Windows 版に関する改善
|
145
|
+
- `File::EXTATTR_NAMESPACE_SYSTEM` によって、本来の拡張ファイル属性の操作が行えるようになりました
|
146
|
+
(NtQueryEaFile / NtSetEaFile)
|
147
|
+
|
148
|
+
|
149
|
+
## 参考資料
|
150
|
+
|
151
|
+
- extattr
|
152
|
+
- <http://www.freebsd.org/cgi/man.cgi?query=extattr&sektion=2>
|
153
|
+
- xattr
|
154
|
+
- <http://linuxjm.sourceforge.jp/html/LDP_man-pages/man2/listxattr.2.html>
|
155
|
+
- windows
|
156
|
+
- <http://msdn.microsoft.com/en-us/library/cc232069.aspx>
|
157
|
+
- <http://undocumented.ntinternals.net/UserMode/Undocumented%20Functions/NT%20Objects/File/FILE_INFORMATION_CLASS.html>
|
158
|
+
- <http://undocumented.ntinternals.net/UserMode/Undocumented%20Functions/NT%20Objects/File/NtQueryInformationFile.html>
|
159
|
+
- <http://undocumented.ntinternals.net/UserMode/Undocumented%20Functions/NT%20Objects/File/NtQueryEaFile.html>
|
160
|
+
- <http://undocumented.ntinternals.net/UserMode/Undocumented%20Functions/NT%20Objects/File/NtSetEaFile.html>
|
161
|
+
- <http://www.zezula.net/en/fstools/filetest.html>
|
data/Rakefile
ADDED
@@ -0,0 +1,105 @@
|
|
1
|
+
#vim: set fileencoding:utf-8
|
2
|
+
|
3
|
+
AUTHOR = "dearblue"
|
4
|
+
EMAIL = "dearblue@users.sourceforge.jp"
|
5
|
+
WEBSITE = "http://sourceforge.jp/projects/rutsubo/"
|
6
|
+
LICENSE = "2-clause BSD License"
|
7
|
+
PACKAGE = "extattr"
|
8
|
+
VERSION = "0.2"
|
9
|
+
PLATFORM_NATIVE = Gem::Platform.local.to_s
|
10
|
+
GEMFILE = "#{PACKAGE}-#{VERSION}.gem"
|
11
|
+
GEMFILE_NATIVE = "#{PACKAGE}-#{VERSION}-#{PLATFORM_NATIVE}.gem"
|
12
|
+
GEMSPEC = "#{PACKAGE}.gemspec"
|
13
|
+
GEMSPEC_NATIVE = "#{PACKAGE}-#{PLATFORM_NATIVE}.gemspec"
|
14
|
+
SUMMARY = "extended attribute operation library for ruby"
|
15
|
+
DESCRIPTION = <<EOS
|
16
|
+
extattr is extended file attribute operation library for ruby.
|
17
|
+
Supported for FreeBSD (extattr), GNU/Linux (xattr) and Microsoft Windows (NTFS ADS + Extended Attributes).
|
18
|
+
EOS
|
19
|
+
|
20
|
+
RUBY19 = ENV["RUBY19"]
|
21
|
+
RUBY20 = ENV["RUBY20"]
|
22
|
+
RUBY21 = ENV["RUBY21"]
|
23
|
+
RUBYSET = [RUBY19, RUBY20, RUBY21].compact
|
24
|
+
|
25
|
+
#RUBY_VERSIONS = [RUBY20].map { |ruby| [`#{ruby} -e "puts RUBY_VERSION"`.slice(/\d+\.\d+/), ruby] }
|
26
|
+
RUBY_VERSIONS = RUBYSET.map { |ruby| [`#{ruby} -e "puts RbConfig::CONFIG['ruby_version']"`.chomp, ruby] }
|
27
|
+
|
28
|
+
BINFILES = FileList["bin/*"]
|
29
|
+
EXTFILES = FileList["ext/{*.h,*.c,*.cc}"]
|
30
|
+
LIBFILES = FileList["lib/**/*.rb"]
|
31
|
+
SOFILES_SET = RUBY_VERSIONS.map { |(ver, ruby)| ["lib/#{ver}/#{PACKAGE}.so", ruby] }
|
32
|
+
SOFILES = SOFILES_SET.map { |(lib, ruby)| lib }
|
33
|
+
EXTCONF = FileList["ext/extconf.rb"]
|
34
|
+
|
35
|
+
SPECSTUB = Gem::Specification.new do |s|
|
36
|
+
s.name = PACKAGE
|
37
|
+
s.version = VERSION
|
38
|
+
s.summary = SUMMARY
|
39
|
+
s.description = DESCRIPTION
|
40
|
+
s.homepage = WEBSITE
|
41
|
+
s.license = LICENSE
|
42
|
+
s.author = AUTHOR
|
43
|
+
s.email = EMAIL
|
44
|
+
s.executables = BINFILES.map { |n| File.basename n }
|
45
|
+
s.files = %w(LICENSE.md README.md Rakefile) + FileList["spec/*.rb"] + BINFILES + EXTCONF + EXTFILES + LIBFILES
|
46
|
+
s.rdoc_options = %w(--charset UTF-8 --main README.md)
|
47
|
+
#s.rdoc_options = %w(--charset UTF-8 --locale ja --main README.md)
|
48
|
+
s.has_rdoc = false
|
49
|
+
s.required_ruby_version = ">= 1.9.3"
|
50
|
+
s.add_development_dependency "rspec", "~> 2.14"
|
51
|
+
s.add_development_dependency "rake", "~> 10.0"
|
52
|
+
end
|
53
|
+
|
54
|
+
|
55
|
+
task :default => :gem
|
56
|
+
task :gem => [GEMFILE_NATIVE, GEMFILE]
|
57
|
+
task :gemspec => GEMSPEC
|
58
|
+
task :gemspec_native => GEMSPEC_NATIVE
|
59
|
+
task :gemfile => GEMFILE
|
60
|
+
task :gemfile_native => GEMFILE_NATIVE
|
61
|
+
|
62
|
+
task :rdoc do
|
63
|
+
sh "yardoc --charset UTF-8 --locale ja --main README.md README.md LICENSE.md #{(EXTFILES + LIBFILES).join(" ")}"
|
64
|
+
end
|
65
|
+
|
66
|
+
|
67
|
+
file GEMFILE => [GEMSPEC] + BINFILES + EXTFILES + LIBFILES do
|
68
|
+
sh "gem build #{GEMSPEC}"
|
69
|
+
end
|
70
|
+
|
71
|
+
file GEMFILE_NATIVE => [GEMSPEC_NATIVE] + BINFILES + EXTFILES + LIBFILES + SOFILES do
|
72
|
+
sh "gem build #{GEMSPEC_NATIVE}"
|
73
|
+
end
|
74
|
+
|
75
|
+
file GEMSPEC => __FILE__ do
|
76
|
+
s = SPECSTUB.dup
|
77
|
+
s.extensions += EXTCONF
|
78
|
+
File.write(GEMSPEC, s.to_ruby, mode: "wb")
|
79
|
+
end
|
80
|
+
|
81
|
+
file GEMSPEC_NATIVE => __FILE__ do
|
82
|
+
s = SPECSTUB.dup
|
83
|
+
s.files += SOFILES
|
84
|
+
s.platform = PLATFORM_NATIVE
|
85
|
+
File.write(GEMSPEC_NATIVE, s.to_ruby, mode: "wb")
|
86
|
+
end
|
87
|
+
|
88
|
+
SOFILES_SET.each do |(soname, ruby)|
|
89
|
+
sodir = File.dirname(soname)
|
90
|
+
makefile = File.join(sodir, "Makefile")
|
91
|
+
|
92
|
+
directory sodir
|
93
|
+
|
94
|
+
file soname => [makefile] + EXTFILES do
|
95
|
+
cd sodir do
|
96
|
+
sh "make"
|
97
|
+
end
|
98
|
+
end
|
99
|
+
|
100
|
+
file makefile => [sodir] + EXTCONF do
|
101
|
+
cd sodir do
|
102
|
+
sh "#{ruby} ../../ext/extconf.rb"
|
103
|
+
end
|
104
|
+
end
|
105
|
+
end
|
@@ -0,0 +1,192 @@
|
|
1
|
+
#include <sys/types.h>
|
2
|
+
#include <sys/extattr.h>
|
3
|
+
|
4
|
+
|
5
|
+
static void
|
6
|
+
extattr_list_name(const char list[], size_t size, VALUE infection_source, void (*func)(void *, VALUE), void *userdata)
|
7
|
+
{
|
8
|
+
// Each list entry consists of a single byte containing the length of
|
9
|
+
// the attribute name, followed by the attribute name.
|
10
|
+
// The attribute name is not terminated by ASCII 0 (nul).
|
11
|
+
const char *ptr = list;
|
12
|
+
const char *end = list + size;
|
13
|
+
|
14
|
+
while (ptr < end) {
|
15
|
+
size_t len = (uint8_t)*ptr ++;
|
16
|
+
if (ptr + len > end) { return; }
|
17
|
+
VALUE v = rb_str_new(ptr, len);
|
18
|
+
OBJ_INFECT(v, infection_source);
|
19
|
+
func(userdata, v);
|
20
|
+
ptr += len;
|
21
|
+
}
|
22
|
+
}
|
23
|
+
|
24
|
+
static int
|
25
|
+
get_extattr_list_size(int (*extattr_list)(), intptr_t d, int namespace1)
|
26
|
+
{
|
27
|
+
int size = extattr_list(d, namespace1, NULL, 0);
|
28
|
+
if (size < 0) { rb_sys_fail("extattr_list call error"); }
|
29
|
+
return size;
|
30
|
+
}
|
31
|
+
|
32
|
+
static VALUE
|
33
|
+
extattr_list_common(int (*extattr_list)(), intptr_t d, VALUE infection_source, int namespace1)
|
34
|
+
{
|
35
|
+
size_t size = get_extattr_list_size(extattr_list, d, namespace1);
|
36
|
+
VALUE buf;
|
37
|
+
char *ptr = ALLOCV(buf, size);
|
38
|
+
|
39
|
+
ssize_t size1 = extattr_list(d, namespace1, ptr, size);
|
40
|
+
if (size1 < 0) { rb_sys_fail("extattr_list call error"); }
|
41
|
+
|
42
|
+
VALUE list = Qnil;
|
43
|
+
if (rb_block_given_p()) {
|
44
|
+
extattr_list_name(ptr, size1, infection_source,
|
45
|
+
(void (*)(void *, VALUE))rb_yield_values, (void *)(1));
|
46
|
+
} else {
|
47
|
+
list = rb_ary_new();
|
48
|
+
OBJ_INFECT(list, infection_source);
|
49
|
+
extattr_list_name(ptr, size1, infection_source,
|
50
|
+
(void (*)(void *, VALUE))rb_ary_push, (void *)list);
|
51
|
+
}
|
52
|
+
ALLOCV_END(buf);
|
53
|
+
|
54
|
+
return list;
|
55
|
+
}
|
56
|
+
|
57
|
+
static VALUE
|
58
|
+
file_extattr_list_main(VALUE file, int fd, int namespace1)
|
59
|
+
{
|
60
|
+
return extattr_list_common(extattr_list_fd, fd, file, namespace1);
|
61
|
+
}
|
62
|
+
|
63
|
+
static VALUE
|
64
|
+
file_s_extattr_list_main(VALUE path, int namespace1)
|
65
|
+
{
|
66
|
+
return extattr_list_common(extattr_list_file, (intptr_t)StringValueCStr(path), path, namespace1);
|
67
|
+
}
|
68
|
+
|
69
|
+
static VALUE
|
70
|
+
file_s_extattr_list_link_main(VALUE path, int namespace1)
|
71
|
+
{
|
72
|
+
return extattr_list_common(extattr_list_link, (intptr_t)StringValueCStr(path), path, namespace1);
|
73
|
+
}
|
74
|
+
|
75
|
+
|
76
|
+
static VALUE
|
77
|
+
extattr_size_common(int (*extattr_get)(), intptr_t d, int namespace1, VALUE name)
|
78
|
+
{
|
79
|
+
ssize_t size = extattr_get(d, namespace1, RSTRING_PTR(name), NULL, 0);
|
80
|
+
if (size < 0) { rb_sys_fail("extattr_get call error"); }
|
81
|
+
return SIZET2NUM(size);
|
82
|
+
}
|
83
|
+
|
84
|
+
static VALUE
|
85
|
+
file_extattr_size_main(VALUE file, int fd, int namespace1, VALUE name)
|
86
|
+
{
|
87
|
+
return extattr_size_common(extattr_get_fd, fd, namespace1, name);
|
88
|
+
}
|
89
|
+
|
90
|
+
static VALUE
|
91
|
+
file_s_extattr_size_main(VALUE path, int namespace1, VALUE name)
|
92
|
+
{
|
93
|
+
return extattr_size_common(extattr_get_file, (intptr_t)StringValueCStr(path), namespace1, name);
|
94
|
+
}
|
95
|
+
|
96
|
+
static VALUE
|
97
|
+
file_s_extattr_size_link_main(VALUE path, int namespace1, VALUE name)
|
98
|
+
{
|
99
|
+
return extattr_size_common(extattr_get_link, (intptr_t)StringValueCStr(path), namespace1, name);
|
100
|
+
}
|
101
|
+
|
102
|
+
|
103
|
+
static VALUE
|
104
|
+
extattr_get_common(int (*extattr_get)(), intptr_t d, VALUE path, int namespace1, VALUE name)
|
105
|
+
{
|
106
|
+
ssize_t size = extattr_get(d, namespace1, RSTRING_PTR(name), NULL, 0);
|
107
|
+
if (size < 0) { rb_sys_fail(StringValueCStr(path)); }
|
108
|
+
VALUE buf = rb_str_buf_new(size);
|
109
|
+
size = extattr_get(d, namespace1, RSTRING_PTR(name), RSTRING_PTR(buf), size);
|
110
|
+
if (size < 0) { rb_sys_fail(StringValueCStr(path)); }
|
111
|
+
rb_str_set_len(buf, size);
|
112
|
+
return buf;
|
113
|
+
}
|
114
|
+
|
115
|
+
static VALUE
|
116
|
+
file_extattr_get_main(VALUE file, int fd, int namespace1, VALUE name)
|
117
|
+
{
|
118
|
+
return extattr_get_common(extattr_get_fd, fd, RFILE(file)->fptr->pathv, namespace1, name);
|
119
|
+
}
|
120
|
+
|
121
|
+
static VALUE
|
122
|
+
file_s_extattr_get_main(VALUE path, int namespace1, VALUE name)
|
123
|
+
{
|
124
|
+
return extattr_get_common(extattr_get_file, (intptr_t)StringValueCStr(path), path, namespace1, name);
|
125
|
+
}
|
126
|
+
|
127
|
+
static VALUE
|
128
|
+
file_s_extattr_get_link_main(VALUE path, int namespace1, VALUE name)
|
129
|
+
{
|
130
|
+
return extattr_get_common(extattr_get_link, (intptr_t)StringValueCStr(path), path, namespace1, name);
|
131
|
+
}
|
132
|
+
|
133
|
+
|
134
|
+
static VALUE
|
135
|
+
extattr_set_common(int (*extattr_set)(), intptr_t d, int namespace1, VALUE name, VALUE data)
|
136
|
+
{
|
137
|
+
int status = extattr_set(d, namespace1, RSTRING_PTR(name), RSTRING_PTR(data), RSTRING_LEN(data));
|
138
|
+
if (status < 0) { rb_sys_fail("extattr_set call error"); }
|
139
|
+
return Qnil;
|
140
|
+
}
|
141
|
+
|
142
|
+
static VALUE
|
143
|
+
file_extattr_set_main(VALUE file, int fd, int namespace1, VALUE name, VALUE data)
|
144
|
+
{
|
145
|
+
return extattr_set_common(extattr_set_fd, fd, namespace1, name, data);
|
146
|
+
}
|
147
|
+
|
148
|
+
static VALUE
|
149
|
+
file_s_extattr_set_main(VALUE path, int namespace1, VALUE name, VALUE data)
|
150
|
+
{
|
151
|
+
return extattr_set_common(extattr_set_file, (intptr_t)StringValueCStr(path), namespace1, name, data);
|
152
|
+
}
|
153
|
+
|
154
|
+
static VALUE
|
155
|
+
file_s_extattr_set_link_main(VALUE path, int namespace1, VALUE name, VALUE data)
|
156
|
+
{
|
157
|
+
return extattr_set_common(extattr_set_link, (intptr_t)StringValueCStr(path), namespace1, name, data);
|
158
|
+
}
|
159
|
+
|
160
|
+
|
161
|
+
static VALUE
|
162
|
+
extattr_delete_common(int (*extattr_delete)(), intptr_t d, int namespace1, VALUE name)
|
163
|
+
{
|
164
|
+
int status = extattr_delete(d, namespace1, RSTRING_PTR(name), NULL, 0);
|
165
|
+
if (status < 0) { rb_sys_fail("extattr_delete call error"); }
|
166
|
+
return Qnil;
|
167
|
+
}
|
168
|
+
|
169
|
+
static VALUE
|
170
|
+
file_extattr_delete_main(VALUE file, int fd, int namespace1, VALUE name)
|
171
|
+
{
|
172
|
+
return extattr_delete_common(extattr_delete_fd, fd, namespace1, name);
|
173
|
+
}
|
174
|
+
|
175
|
+
static VALUE
|
176
|
+
file_s_extattr_delete_main(VALUE path, int namespace1, VALUE name)
|
177
|
+
{
|
178
|
+
return extattr_delete_common(extattr_delete_file, (intptr_t)StringValueCStr(path), namespace1, name);
|
179
|
+
}
|
180
|
+
|
181
|
+
static VALUE
|
182
|
+
file_s_extattr_delete_link_main(VALUE path, int namespace1, VALUE name)
|
183
|
+
{
|
184
|
+
return extattr_delete_common(extattr_delete_link, (intptr_t)StringValueCStr(path), namespace1, name);
|
185
|
+
}
|
186
|
+
|
187
|
+
|
188
|
+
static void
|
189
|
+
ext_init_implement(void)
|
190
|
+
{
|
191
|
+
rb_define_const(rb_cFile, "EXTATTR_IMPLEMANT", rb_str_freeze(rb_str_new_cstr("extattr")));
|
192
|
+
}
|