extattr 0.2 → 0.4
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +5 -5
- data/HISTORY.ja.md +49 -0
- data/LICENSE.md +4 -1
- data/QUICKREF.ja.md +112 -0
- data/README.md +55 -132
- data/Rakefile +193 -86
- data/ext/extattr-extattr.h +18 -18
- data/ext/extattr-windows.h +5 -5
- data/ext/extattr-xattr.h +6 -6
- data/ext/extattr.c +279 -217
- data/ext/extconf.rb +6 -7
- data/gemstub.rb +22 -0
- data/lib/extattr.rb +249 -32
- data/test/test_extattr.rb +75 -0
- metadata +34 -24
- data/spec/extattr_spec.rb +0 -62
data/ext/extattr.c
CHANGED
@@ -2,14 +2,16 @@
|
|
2
2
|
|
3
3
|
/*
|
4
4
|
* extattr.c
|
5
|
-
* AUTHOR:: dearblue <dearblue@
|
5
|
+
* AUTHOR:: dearblue <dearblue@users.osdn.me>
|
6
6
|
* LICENSE:: 2-clause BSD License
|
7
|
-
*
|
7
|
+
* PROJECT-PAGE:: https://github.com/dearblue/ruby-extattr
|
8
8
|
*/
|
9
9
|
|
10
10
|
#include <ruby.h>
|
11
11
|
#include <ruby/io.h>
|
12
12
|
#include <ruby/intern.h>
|
13
|
+
#include <ruby/version.h>
|
14
|
+
#include <ctype.h>
|
13
15
|
|
14
16
|
|
15
17
|
static VALUE file_extattr_list_main(VALUE file, int fd, int namespace1);
|
@@ -29,8 +31,11 @@ static VALUE file_s_extattr_delete_main(VALUE path, int namespace1, VALUE name);
|
|
29
31
|
static VALUE file_s_extattr_delete_link_main(VALUE path, int namespace1, VALUE name);
|
30
32
|
|
31
33
|
// Init_extattr から呼び出される、環境ごとの初期設定。
|
32
|
-
static void
|
34
|
+
static void extattr_init_implement(void);
|
33
35
|
|
36
|
+
#if RUBY_API_VERSION_CODE >= 20700
|
37
|
+
# define rb_obj_infect(OBJ, SRC) ((void)0)
|
38
|
+
#endif
|
34
39
|
|
35
40
|
#define RDOC(...)
|
36
41
|
|
@@ -38,6 +43,11 @@ static void ext_init_implement(void);
|
|
38
43
|
|
39
44
|
#define LOGF(FORMAT, ...) { fprintf(stderr, "%s:%d:%s: " FORMAT "\n", __FILE__, __LINE__, __func__, __VA_ARGS__); }
|
40
45
|
|
46
|
+
static VALUE mExtAttr;
|
47
|
+
|
48
|
+
static ID id_downcase;
|
49
|
+
static ID id_to_path;
|
50
|
+
|
41
51
|
|
42
52
|
static inline VALUE
|
43
53
|
hash_lookup(VALUE hash, VALUE key, VALUE default_value)
|
@@ -54,8 +64,8 @@ hash_lookup(VALUE hash, VALUE key, VALUE default_value)
|
|
54
64
|
static inline int
|
55
65
|
file2fd(VALUE file)
|
56
66
|
{
|
67
|
+
rb_check_type(file, RUBY_T_FILE);
|
57
68
|
rb_io_t *fptr;
|
58
|
-
// FIXME: ファイルであることを確認すべき
|
59
69
|
GetOpenFile(file, fptr);
|
60
70
|
return fptr->fd;
|
61
71
|
}
|
@@ -79,6 +89,66 @@ ext_error_namespace(VALUE path, int namespace1)
|
|
79
89
|
ext_error_extattr(EPERM, path, rb_sprintf("namespace=%d", namespace1));
|
80
90
|
}
|
81
91
|
|
92
|
+
static VALUE
|
93
|
+
aux_to_path(VALUE path)
|
94
|
+
{
|
95
|
+
if (rb_respond_to(path, id_to_path)) {
|
96
|
+
VALUE args[] = { path };
|
97
|
+
path = rb_funcall2(path, id_to_path, 1, args);
|
98
|
+
rb_check_type(path, RUBY_T_STRING);
|
99
|
+
} else {
|
100
|
+
path = StringValue(path);
|
101
|
+
}
|
102
|
+
|
103
|
+
return path;
|
104
|
+
}
|
105
|
+
|
106
|
+
static void
|
107
|
+
aux_sys_fail(VALUE filesrc, const char *funcname)
|
108
|
+
{
|
109
|
+
VALUE tmp;
|
110
|
+
filesrc = aux_to_path(filesrc);
|
111
|
+
if (funcname) {
|
112
|
+
tmp = rb_sprintf("%s (%s error)", StringValueCStr(filesrc), funcname);
|
113
|
+
} else {
|
114
|
+
tmp = rb_sprintf("%s", StringValueCStr(filesrc));
|
115
|
+
}
|
116
|
+
rb_sys_fail(StringValueCStr(tmp));
|
117
|
+
}
|
118
|
+
|
119
|
+
static size_t
|
120
|
+
aux_str_getmem(VALUE obj, const char **pp)
|
121
|
+
{
|
122
|
+
switch (rb_type(obj)) {
|
123
|
+
case RUBY_T_STRING:
|
124
|
+
break;
|
125
|
+
case RUBY_T_SYMBOL:
|
126
|
+
obj = rb_id2str(rb_sym2id(obj));
|
127
|
+
break;
|
128
|
+
default:
|
129
|
+
rb_raise(rb_eTypeError, "expect string or symbol for namespace");
|
130
|
+
}
|
131
|
+
|
132
|
+
size_t len;
|
133
|
+
RSTRING_GETMEM(obj, *pp, len);
|
134
|
+
return len;
|
135
|
+
}
|
136
|
+
|
137
|
+
static int
|
138
|
+
aux_memcasecmp(const char *a, const char *b, size_t n)
|
139
|
+
{
|
140
|
+
// MEMO: memicmp() があればそちらを使うべき?
|
141
|
+
|
142
|
+
for (; n > 0; n--, a++, b++) {
|
143
|
+
int c = tolower(*(const unsigned char *)a) - tolower(*(const unsigned char *)b);
|
144
|
+
if (c) {
|
145
|
+
return (c > 0) ? 1 : -1;
|
146
|
+
}
|
147
|
+
}
|
148
|
+
|
149
|
+
return 0;
|
150
|
+
}
|
151
|
+
|
82
152
|
|
83
153
|
#if defined(HAVE_SYS_EXTATTR_H)
|
84
154
|
# include "extattr-extattr.h"
|
@@ -91,14 +161,72 @@ ext_error_namespace(VALUE path, int namespace1)
|
|
91
161
|
#endif
|
92
162
|
|
93
163
|
|
94
|
-
static VALUE
|
164
|
+
static VALUE
|
165
|
+
aux_should_be_string(VALUE obj)
|
166
|
+
{
|
167
|
+
rb_check_type(obj, RUBY_T_STRING);
|
168
|
+
return obj;
|
169
|
+
}
|
170
|
+
|
171
|
+
static int
|
172
|
+
convert_namespace_int(VALUE namespace)
|
173
|
+
{
|
174
|
+
int n = NUM2INT(namespace);
|
175
|
+
|
176
|
+
if (n == EXTATTR_NAMESPACE_USER ||
|
177
|
+
n == EXTATTR_NAMESPACE_SYSTEM) {
|
178
|
+
|
179
|
+
return n;
|
180
|
+
}
|
181
|
+
|
182
|
+
rb_raise(rb_eArgError,
|
183
|
+
"wrong namespace value - #<%s:%p>",
|
184
|
+
rb_obj_classname(namespace), (void *)namespace);
|
185
|
+
}
|
186
|
+
|
187
|
+
static int
|
188
|
+
convert_namespace_str(VALUE namespace)
|
189
|
+
{
|
190
|
+
static const char ns_user[] = "user";
|
191
|
+
static const int ns_user_len = sizeof(ns_user) / sizeof(ns_user[0]) - 1;
|
192
|
+
static const char ns_system[] = "system";
|
193
|
+
static const int ns_system_len = sizeof(ns_system) / sizeof(ns_system[0]) - 1;
|
194
|
+
|
195
|
+
const char *p;
|
196
|
+
size_t len = aux_str_getmem(namespace, &p);
|
197
|
+
|
198
|
+
if (len == ns_user_len && aux_memcasecmp(p, ns_user, ns_user_len) == 0) {
|
199
|
+
return EXTATTR_NAMESPACE_USER;
|
200
|
+
} else if (len == ns_system_len && aux_memcasecmp(p, ns_system, ns_system_len) == 0) {
|
201
|
+
return EXTATTR_NAMESPACE_SYSTEM;
|
202
|
+
} else {
|
203
|
+
rb_raise(rb_eArgError,
|
204
|
+
"wrong namespace - %s (expected to user or system)",
|
205
|
+
StringValueCStr(namespace));
|
206
|
+
}
|
207
|
+
}
|
95
208
|
|
96
209
|
static int
|
97
|
-
|
210
|
+
conv_namespace(VALUE namespace)
|
98
211
|
{
|
99
|
-
|
212
|
+
if (NIL_P(namespace)) {
|
213
|
+
return EXTATTR_NAMESPACE_USER;
|
214
|
+
} else if (rb_obj_is_kind_of(namespace, rb_cNumeric)) {
|
215
|
+
return convert_namespace_int(namespace);
|
216
|
+
} else if (rb_obj_is_kind_of(namespace, rb_cString) ||
|
217
|
+
rb_obj_is_kind_of(namespace, rb_cSymbol)) {
|
218
|
+
return convert_namespace_str(rb_String(namespace));
|
219
|
+
} else {
|
220
|
+
rb_raise(rb_eArgError,
|
221
|
+
"wrong namespace object - %p",
|
222
|
+
(void *)namespace);
|
223
|
+
}
|
100
224
|
}
|
101
225
|
|
226
|
+
#if RUBY_API_VERSION_CODE >= 20700
|
227
|
+
static void ext_check_file_security(VALUE file, VALUE name, VALUE data) { }
|
228
|
+
static void ext_check_path_security(VALUE path, VALUE name, VALUE data) { }
|
229
|
+
#else
|
102
230
|
static void
|
103
231
|
ext_check_file_security(VALUE file, VALUE name, VALUE data)
|
104
232
|
{
|
@@ -174,297 +302,231 @@ ext_check_path_security(VALUE path, VALUE name, VALUE data)
|
|
174
302
|
rb_insecure_operation();
|
175
303
|
}
|
176
304
|
}
|
305
|
+
#endif
|
177
306
|
|
178
307
|
|
179
308
|
/*
|
180
309
|
* call-seq:
|
181
|
-
*
|
182
|
-
*
|
183
|
-
*
|
184
|
-
* 開いているファイルの拡張属性名一覧を得ます。
|
185
|
-
*
|
186
|
-
* ブロックが指定された場合、一つ一つの拡張属性名を渡してブロックが評価されます。ブロックの戻り値は無視されます。
|
187
|
-
*/
|
188
|
-
static VALUE
|
189
|
-
file_extattr_list(int argc, VALUE argv[], VALUE file)
|
190
|
-
{
|
191
|
-
VALUE opts = Qnil;
|
192
|
-
rb_scan_args(argc, argv, "0:", &opts);
|
193
|
-
ext_check_file_security(file, Qnil, Qnil);
|
194
|
-
return file_extattr_list_main(file, file2fd(file),
|
195
|
-
ext_get_namespace(opts));
|
196
|
-
}
|
197
|
-
|
198
|
-
/*
|
199
|
-
* call-seq:
|
200
|
-
* extattr_list(path, namespace: File::EXTATTR_NAMESPACE_USER) -> names array
|
201
|
-
* extattr_list(path, namespace: File::EXTATTR_NAMESPACE_USER) { |name| ... } -> nil
|
202
|
-
*
|
203
|
-
* ファイル名を指定すること以外は File#extattr_list と同じです。
|
310
|
+
* list(path, namespace) -> names array
|
311
|
+
* list(path, namespace) { |name| ... } -> nil
|
204
312
|
*/
|
205
313
|
static VALUE
|
206
|
-
|
314
|
+
ext_s_list(VALUE mod, VALUE path, VALUE namespace)
|
207
315
|
{
|
208
|
-
|
209
|
-
|
210
|
-
|
211
|
-
|
212
|
-
|
316
|
+
if (rb_obj_is_kind_of(path, rb_cFile)) {
|
317
|
+
ext_check_file_security(path, Qnil, Qnil);
|
318
|
+
return file_extattr_list_main(path, file2fd(path),
|
319
|
+
conv_namespace(namespace));
|
320
|
+
} else {
|
321
|
+
ext_check_path_security(path, Qnil, Qnil);
|
322
|
+
return file_s_extattr_list_main(aux_to_path(path),
|
323
|
+
conv_namespace(namespace));
|
324
|
+
}
|
213
325
|
}
|
214
326
|
|
215
327
|
/*
|
216
328
|
* call-seq:
|
217
|
-
* extattr_list!(path, namespace
|
218
|
-
* extattr_list!(path, namespace
|
219
|
-
*
|
220
|
-
* シンボリックリンクに対する操作という以外は、File.extattr_list と同じです。
|
329
|
+
* extattr_list!(path, namespace) -> names array
|
330
|
+
* extattr_list!(path, namespace) { |name| ... } -> nil
|
221
331
|
*/
|
222
332
|
static VALUE
|
223
|
-
|
333
|
+
ext_s_list_link(VALUE mod, VALUE path, VALUE namespace)
|
224
334
|
{
|
225
|
-
|
226
|
-
|
227
|
-
|
228
|
-
|
229
|
-
|
335
|
+
if (rb_obj_is_kind_of(path, rb_cFile)) {
|
336
|
+
ext_check_file_security(path, Qnil, Qnil);
|
337
|
+
return file_extattr_list_main(path, file2fd(path),
|
338
|
+
conv_namespace(namespace));
|
339
|
+
} else {
|
340
|
+
ext_check_path_security(path, Qnil, Qnil);
|
341
|
+
return file_s_extattr_list_link_main(aux_to_path(path),
|
342
|
+
conv_namespace(namespace));
|
343
|
+
}
|
230
344
|
}
|
231
345
|
|
232
346
|
|
233
347
|
/*
|
234
348
|
* call-seq:
|
235
|
-
*
|
236
|
-
*
|
237
|
-
* 拡張属性の大きさを取得します。
|
349
|
+
* size(path, namespace, name) -> size
|
238
350
|
*/
|
239
351
|
static VALUE
|
240
|
-
|
352
|
+
ext_s_size(VALUE mod, VALUE path, VALUE namespace, VALUE name)
|
241
353
|
{
|
242
|
-
|
243
|
-
|
244
|
-
|
245
|
-
|
246
|
-
|
247
|
-
|
248
|
-
|
249
|
-
|
250
|
-
|
251
|
-
/*
|
252
|
-
* call-seq:
|
253
|
-
* extattr_size(path, name, namespace: File::EXTATTR_NAMESPACE_USER) -> size
|
254
|
-
*/
|
255
|
-
static VALUE
|
256
|
-
file_s_extattr_size(int argc, VALUE argv[], VALUE file)
|
257
|
-
{
|
258
|
-
VALUE path, name, opts = Qnil;
|
259
|
-
rb_scan_args(argc, argv, "2:", &path, &name, &opts);
|
260
|
-
ext_check_path_security(path, name, Qnil);
|
261
|
-
Check_Type(name, RUBY_T_STRING);
|
262
|
-
return file_s_extattr_size_main(StringValue(path),
|
263
|
-
ext_get_namespace(opts),
|
264
|
-
StringValue(name));
|
354
|
+
if (rb_obj_is_kind_of(path, rb_cFile)) {
|
355
|
+
ext_check_file_security(path, name, Qnil);
|
356
|
+
return file_extattr_size_main(path, file2fd(path), conv_namespace(namespace),
|
357
|
+
aux_should_be_string(name));
|
358
|
+
} else {
|
359
|
+
ext_check_path_security(path, name, Qnil);
|
360
|
+
return file_s_extattr_size_main(aux_to_path(path), conv_namespace(namespace),
|
361
|
+
aux_should_be_string(name));
|
362
|
+
}
|
265
363
|
}
|
266
364
|
|
267
365
|
/*
|
268
366
|
* call-seq:
|
269
|
-
*
|
367
|
+
* size!(path, namespace, name) -> size
|
270
368
|
*/
|
271
369
|
static VALUE
|
272
|
-
|
370
|
+
ext_s_size_link(VALUE mod, VALUE path, VALUE namespace, VALUE name)
|
273
371
|
{
|
274
|
-
|
275
|
-
|
276
|
-
|
277
|
-
|
278
|
-
|
279
|
-
|
280
|
-
|
372
|
+
if (rb_obj_is_kind_of(path, rb_cFile)) {
|
373
|
+
ext_check_file_security(path, name, Qnil);
|
374
|
+
return file_extattr_size_main(path, file2fd(path), conv_namespace(namespace),
|
375
|
+
aux_should_be_string(name));
|
376
|
+
} else {
|
377
|
+
ext_check_path_security(path, name, Qnil);
|
378
|
+
return file_s_extattr_size_link_main(aux_to_path(path), conv_namespace(namespace),
|
379
|
+
aux_should_be_string(name));
|
380
|
+
}
|
281
381
|
}
|
282
382
|
|
283
383
|
|
284
384
|
/*
|
285
385
|
* call-seq:
|
286
|
-
*
|
386
|
+
* get(path, namespace, name) -> data
|
287
387
|
*/
|
288
388
|
static VALUE
|
289
|
-
|
389
|
+
ext_s_get(VALUE mod, VALUE path, VALUE namespace, VALUE name)
|
290
390
|
{
|
291
|
-
VALUE
|
292
|
-
|
293
|
-
|
294
|
-
|
295
|
-
|
296
|
-
|
297
|
-
|
298
|
-
|
299
|
-
|
300
|
-
}
|
391
|
+
VALUE v;
|
392
|
+
if (rb_obj_is_kind_of(path, rb_cFile)) {
|
393
|
+
ext_check_file_security(path, name, Qnil);
|
394
|
+
v = file_extattr_get_main(path, file2fd(path), conv_namespace(namespace),
|
395
|
+
aux_should_be_string(name));
|
396
|
+
} else {
|
397
|
+
ext_check_path_security(path, name, Qnil);
|
398
|
+
v = file_s_extattr_get_main(aux_to_path(path), conv_namespace(namespace),
|
399
|
+
aux_should_be_string(name));
|
400
|
+
}
|
301
401
|
|
302
|
-
|
303
|
-
* call-seq:
|
304
|
-
* extattr_get(path, name, namespace: File::EXTATTR_NAMESPACE_USER) -> data
|
305
|
-
*/
|
306
|
-
static VALUE
|
307
|
-
file_s_extattr_get(int argc, VALUE argv[], VALUE file)
|
308
|
-
{
|
309
|
-
VALUE path, name, opts = Qnil;
|
310
|
-
rb_scan_args(argc, argv, "2:", &path, &name, &opts);
|
311
|
-
ext_check_path_security(path, name, Qnil);
|
312
|
-
Check_Type(name, RUBY_T_STRING);
|
313
|
-
VALUE v = file_s_extattr_get_main(StringValue(path),
|
314
|
-
ext_get_namespace(opts),
|
315
|
-
StringValue(name));
|
316
|
-
OBJ_INFECT(v, path);
|
402
|
+
rb_obj_infect(v, path);
|
317
403
|
return v;
|
318
404
|
}
|
319
405
|
|
320
406
|
/*
|
321
407
|
* call-seq:
|
322
|
-
*
|
408
|
+
* get!(path, namespace, name) -> data
|
323
409
|
*/
|
324
410
|
static VALUE
|
325
|
-
|
411
|
+
ext_s_get_link(VALUE mod, VALUE path, VALUE namespace, VALUE name)
|
326
412
|
{
|
327
|
-
VALUE
|
328
|
-
|
329
|
-
|
330
|
-
|
331
|
-
|
332
|
-
|
333
|
-
|
334
|
-
|
413
|
+
VALUE v;
|
414
|
+
if (rb_obj_is_kind_of(path, rb_cFile)) {
|
415
|
+
ext_check_file_security(path, name, Qnil);
|
416
|
+
v = file_extattr_get_main(path, file2fd(path), conv_namespace(namespace),
|
417
|
+
aux_should_be_string(name));
|
418
|
+
} else {
|
419
|
+
ext_check_path_security(path, name, Qnil);
|
420
|
+
v = file_s_extattr_get_link_main(aux_to_path(path), conv_namespace(namespace),
|
421
|
+
aux_should_be_string(name));
|
422
|
+
}
|
423
|
+
|
424
|
+
rb_obj_infect(v, path);
|
335
425
|
return v;
|
336
426
|
}
|
337
427
|
|
338
428
|
|
339
429
|
/*
|
340
430
|
* call-seq:
|
341
|
-
*
|
431
|
+
* set(path, namespace, name, data) -> nil
|
342
432
|
*/
|
343
433
|
static VALUE
|
344
|
-
|
434
|
+
ext_s_set(VALUE mod, VALUE path, VALUE namespace, VALUE name, VALUE data)
|
345
435
|
{
|
346
|
-
|
347
|
-
|
348
|
-
|
349
|
-
|
350
|
-
|
351
|
-
|
352
|
-
|
353
|
-
|
354
|
-
|
355
|
-
|
356
|
-
|
357
|
-
* call-seq:
|
358
|
-
* extattr_set(path, name, data, namespace: File::EXTATTR_NAMESPACE_USER) -> nil
|
359
|
-
*/
|
360
|
-
static VALUE
|
361
|
-
file_s_extattr_set(int argc, VALUE argv[], VALUE file)
|
362
|
-
{
|
363
|
-
VALUE path, name, data, opts = Qnil;
|
364
|
-
rb_scan_args(argc, argv, "3:", &path, &name, &data, &opts);
|
365
|
-
ext_check_path_security(path, name, data);
|
366
|
-
Check_Type(name, RUBY_T_STRING);
|
367
|
-
return file_s_extattr_set_main(StringValue(path),
|
368
|
-
ext_get_namespace(opts),
|
369
|
-
StringValue(name),
|
370
|
-
StringValue(data));
|
436
|
+
if (rb_obj_is_kind_of(path, rb_cFile)) {
|
437
|
+
ext_check_file_security(path, name, Qnil);
|
438
|
+
return file_extattr_set_main(path, file2fd(path),
|
439
|
+
conv_namespace(namespace),
|
440
|
+
aux_should_be_string(name), aux_should_be_string(data));
|
441
|
+
} else {
|
442
|
+
ext_check_path_security(path, name, Qnil);
|
443
|
+
return file_s_extattr_set_main(aux_to_path(path),
|
444
|
+
conv_namespace(namespace),
|
445
|
+
aux_should_be_string(name), aux_should_be_string(data));
|
446
|
+
}
|
371
447
|
}
|
372
448
|
|
373
449
|
/*
|
374
450
|
* call-seq:
|
375
|
-
*
|
451
|
+
* set!(path, namespace, name, data) -> nil
|
376
452
|
*/
|
377
453
|
static VALUE
|
378
|
-
|
454
|
+
ext_s_set_link(VALUE mod, VALUE path, VALUE namespace, VALUE name, VALUE data)
|
379
455
|
{
|
380
|
-
|
381
|
-
|
382
|
-
|
383
|
-
|
384
|
-
|
385
|
-
|
386
|
-
|
387
|
-
|
456
|
+
if (rb_obj_is_kind_of(path, rb_cFile)) {
|
457
|
+
ext_check_file_security(path, name, Qnil);
|
458
|
+
return file_extattr_set_main(path, file2fd(path),
|
459
|
+
conv_namespace(namespace),
|
460
|
+
aux_should_be_string(name), aux_should_be_string(data));
|
461
|
+
} else {
|
462
|
+
ext_check_path_security(path, name, Qnil);
|
463
|
+
return file_s_extattr_set_link_main(aux_to_path(path),
|
464
|
+
conv_namespace(namespace),
|
465
|
+
aux_should_be_string(name), aux_should_be_string(data));
|
466
|
+
}
|
388
467
|
}
|
389
468
|
|
390
469
|
|
391
470
|
/*
|
392
471
|
* call-seq:
|
393
|
-
*
|
394
|
-
*/
|
395
|
-
static VALUE
|
396
|
-
file_extattr_delete(int argc, VALUE argv[], VALUE file)
|
397
|
-
{
|
398
|
-
VALUE name, opts = Qnil;
|
399
|
-
rb_scan_args(argc, argv, "1:", &name, &opts);
|
400
|
-
ext_check_file_security(file, name, Qnil);
|
401
|
-
Check_Type(name, RUBY_T_STRING);
|
402
|
-
return file_extattr_delete_main(file, file2fd(file),
|
403
|
-
ext_get_namespace(opts),
|
404
|
-
StringValue(name));
|
405
|
-
}
|
406
|
-
|
407
|
-
/*
|
408
|
-
* call-seq:
|
409
|
-
* extattr_delete(path, name, namespace: File::EXTATTR_NAMESPACE_USER) -> nil
|
472
|
+
* delete(path, namespace, name) -> nil
|
410
473
|
*/
|
411
474
|
static VALUE
|
412
|
-
|
475
|
+
ext_s_delete(VALUE mod, VALUE path, VALUE namespace, VALUE name)
|
413
476
|
{
|
414
|
-
|
415
|
-
|
416
|
-
|
417
|
-
|
418
|
-
|
419
|
-
|
420
|
-
|
477
|
+
if (rb_obj_is_kind_of(path, rb_cFile)) {
|
478
|
+
ext_check_file_security(path, name, Qnil);
|
479
|
+
return file_extattr_delete_main(path, file2fd(path), conv_namespace(namespace),
|
480
|
+
aux_should_be_string(name));
|
481
|
+
} else {
|
482
|
+
ext_check_path_security(path, name, Qnil);
|
483
|
+
return file_s_extattr_delete_main(aux_to_path(path), conv_namespace(namespace),
|
484
|
+
aux_should_be_string(name));
|
485
|
+
}
|
421
486
|
}
|
422
487
|
|
423
488
|
/*
|
424
489
|
* call-seq:
|
425
|
-
*
|
490
|
+
* delete!(path, namespace, name) -> nil
|
426
491
|
*/
|
427
492
|
static VALUE
|
428
|
-
|
493
|
+
ext_s_delete_link(VALUE mod, VALUE path, VALUE namespace, VALUE name)
|
429
494
|
{
|
430
|
-
|
431
|
-
|
432
|
-
|
433
|
-
|
434
|
-
|
435
|
-
|
436
|
-
|
495
|
+
if (rb_obj_is_kind_of(path, rb_cFile)) {
|
496
|
+
ext_check_file_security(path, name, Qnil);
|
497
|
+
return file_extattr_delete_main(path, file2fd(path), conv_namespace(namespace),
|
498
|
+
aux_should_be_string(name));
|
499
|
+
} else {
|
500
|
+
ext_check_path_security(path, name, Qnil);
|
501
|
+
return file_s_extattr_delete_link_main(aux_to_path(path), conv_namespace(namespace),
|
502
|
+
aux_should_be_string(name));
|
503
|
+
}
|
437
504
|
}
|
438
505
|
|
439
506
|
|
440
507
|
void
|
441
508
|
Init_extattr(void)
|
442
509
|
{
|
443
|
-
|
444
|
-
|
445
|
-
|
446
|
-
|
447
|
-
|
448
|
-
|
449
|
-
|
450
|
-
|
451
|
-
|
452
|
-
|
453
|
-
|
454
|
-
rb_define_singleton_method(
|
455
|
-
rb_define_singleton_method(
|
456
|
-
|
457
|
-
|
458
|
-
rb_define_singleton_method(
|
459
|
-
rb_define_singleton_method(
|
460
|
-
|
461
|
-
|
462
|
-
rb_define_singleton_method(
|
463
|
-
|
464
|
-
|
465
|
-
rb_define_method(rb_cFile, "extattr_delete", RUBY_METHOD_FUNC(file_extattr_delete), -1);
|
466
|
-
rb_define_singleton_method(rb_cFile, "extattr_delete", RUBY_METHOD_FUNC(file_s_extattr_delete), -1);
|
467
|
-
rb_define_singleton_method(rb_cFile, "extattr_delete!", RUBY_METHOD_FUNC(file_s_extattr_delete_link), -1);
|
468
|
-
|
469
|
-
ext_init_implement();
|
510
|
+
#if HAVE_RB_EXT_RACTOR_SAFE
|
511
|
+
rb_ext_ractor_safe(true);
|
512
|
+
#endif
|
513
|
+
id_downcase = rb_intern("downcase");
|
514
|
+
id_to_path = rb_intern("to_path");
|
515
|
+
|
516
|
+
mExtAttr = rb_define_module("ExtAttr");
|
517
|
+
rb_define_const(mExtAttr, "USER", ID2SYM(rb_intern("user")));
|
518
|
+
rb_define_const(mExtAttr, "SYSTEM", ID2SYM(rb_intern("system")));
|
519
|
+
|
520
|
+
rb_define_singleton_method(mExtAttr, "list", RUBY_METHOD_FUNC(ext_s_list), 2);
|
521
|
+
rb_define_singleton_method(mExtAttr, "list!", RUBY_METHOD_FUNC(ext_s_list_link), 2);
|
522
|
+
rb_define_singleton_method(mExtAttr, "size", RUBY_METHOD_FUNC(ext_s_size), 3);
|
523
|
+
rb_define_singleton_method(mExtAttr, "size!", RUBY_METHOD_FUNC(ext_s_size_link), 3);
|
524
|
+
rb_define_singleton_method(mExtAttr, "get", RUBY_METHOD_FUNC(ext_s_get), 3);
|
525
|
+
rb_define_singleton_method(mExtAttr, "get!", RUBY_METHOD_FUNC(ext_s_get_link), 3);
|
526
|
+
rb_define_singleton_method(mExtAttr, "set", RUBY_METHOD_FUNC(ext_s_set), 4);
|
527
|
+
rb_define_singleton_method(mExtAttr, "set!", RUBY_METHOD_FUNC(ext_s_set_link), 4);
|
528
|
+
rb_define_singleton_method(mExtAttr, "delete", RUBY_METHOD_FUNC(ext_s_delete), 3);
|
529
|
+
rb_define_singleton_method(mExtAttr, "delete!", RUBY_METHOD_FUNC(ext_s_delete_link), 3);
|
530
|
+
|
531
|
+
extattr_init_implement();
|
470
532
|
}
|
data/ext/extconf.rb
CHANGED
@@ -1,11 +1,8 @@
|
|
1
1
|
#!ruby
|
2
|
-
#vim: set fileencoding:utf-8
|
3
|
-
|
4
|
-
raise "require ruby-1.9.3+" unless RUBY_VERSION >= "1.9.3"
|
5
2
|
|
6
3
|
require "mkmf"
|
7
4
|
|
8
|
-
|
5
|
+
have_func("rb_ext_ractor_safe", "ruby.h")
|
9
6
|
|
10
7
|
case
|
11
8
|
when have_header("sys/extattr.h")
|
@@ -19,6 +16,9 @@ when have_header("sys/xattr.h")
|
|
19
16
|
when have_header("winnt.h") && have_header("ntdef.h") && have_header("psapi.h") &&
|
20
17
|
have_header("ddk/ntifs.h") && have_header("ddk/winddk.h") &&
|
21
18
|
have_library("ntoskrnl") && have_library("ntdll") && have_library("psapi")
|
19
|
+
if RbConfig::CONFIG["arch"] =~ /mingw/
|
20
|
+
$LDFLAGS << " -static-libgcc -static-libstdc++"
|
21
|
+
end
|
22
22
|
|
23
23
|
else
|
24
24
|
$stderr.puts <<EOM
|
@@ -28,6 +28,5 @@ EOM
|
|
28
28
|
exit 1
|
29
29
|
end
|
30
30
|
|
31
|
-
|
32
|
-
|
33
|
-
create_makefile "extattr"
|
31
|
+
ver = RUBY_VERSION.slice(/\d+\.\d+/)
|
32
|
+
create_makefile File.join(ver, "extattr")
|