capng_c 0.1.3 → 0.1.8

Sign up to get free protection for your applications and to get access to all the features.
@@ -13,21 +13,50 @@
13
13
 
14
14
  #include <capng.h>
15
15
 
16
- struct CapNG {};
17
-
18
- static void capng_free(void* capng);
19
-
20
- static const rb_data_type_t rb_capng_type = {
21
- "capng/capng",
22
- {
23
- 0,
24
- capng_free,
25
- 0,
26
- },
27
- NULL,
28
- NULL,
29
- RUBY_TYPED_FREE_IMMEDIATELY
30
- };
16
+ /* clang-format off */
17
+ /*
18
+ * Document-class: CapNG
19
+ *
20
+ * CapNG class.
21
+ *
22
+ * @example
23
+ * # Current process capability example
24
+ * require 'capng'
25
+ *
26
+ * @capng = CapNG.new(:current_process)
27
+ * @capng.have_capability?(:effective, :dac_read_search)
28
+ *
29
+ * @example
30
+ * # Other process capability example
31
+ * require 'capng'
32
+ *
33
+ * @capng = CapNG.new(:other_process, 12345)
34
+ * @capng.have_capability?(:effective, :dac_override)
35
+ *
36
+ * @example
37
+ * # File capability example
38
+ * require 'capng'
39
+ *
40
+ * @capng = CapNG.new(:file, "/path/to/file")
41
+ * @capng.have_capability?(:effective, :chown)
42
+ */
43
+ /* clang-format on */
44
+
45
+ struct CapNG
46
+ {};
47
+
48
+ static void
49
+ capng_free(void* capng);
50
+
51
+ static const rb_data_type_t rb_capng_type = { "capng/capng",
52
+ {
53
+ 0,
54
+ capng_free,
55
+ 0,
56
+ },
57
+ NULL,
58
+ NULL,
59
+ RUBY_TYPED_FREE_IMMEDIATELY };
31
60
 
32
61
  static void
33
62
  capng_free(void* ptr)
@@ -40,19 +69,27 @@ rb_capng_alloc(VALUE klass)
40
69
  {
41
70
  VALUE obj;
42
71
  struct CapNG* capng;
43
- obj = TypedData_Make_Struct(
44
- klass, struct CapNG, &rb_capng_type, capng);
72
+ obj = TypedData_Make_Struct(klass, struct CapNG, &rb_capng_type, capng);
45
73
  return obj;
46
74
  }
47
75
 
76
+ /*
77
+ * Initalize CapNG class.
78
+ *
79
+ * @overload initialize(target=nil, pid_or_file=nil)
80
+ * @option param target [String or Symbol] Specify capability target.
81
+ * @option param pid_or_file [String or Symbol] Querying XPath.
82
+ * @return [nil]
83
+ *
84
+ */
48
85
  static VALUE
49
- rb_capng_initialize(int argc, VALUE *argv, VALUE self)
86
+ rb_capng_initialize(int argc, VALUE* argv, VALUE self)
50
87
  {
51
88
  VALUE rb_target, rb_pid_or_file;
52
89
  int result = 0;
53
- char *target = NULL;
90
+ char* target = NULL;
54
91
  int pid = 0, fd = 0;
55
- rb_io_t *fptr = NULL;
92
+ rb_io_t* fptr = NULL;
56
93
 
57
94
  rb_scan_args(argc, argv, "02", &rb_target, &rb_pid_or_file);
58
95
 
@@ -88,31 +125,54 @@ rb_capng_initialize(int argc, VALUE *argv, VALUE self)
88
125
  fptr = RFILE(rb_pid_or_file)->fptr;
89
126
  fd = fptr->fd;
90
127
  result = capng_get_caps_fd(fd);
91
- if (result != 0) {
92
- rb_raise(rb_eRuntimeError, "Couldn't get current file capability");
93
- }
128
+ /* Just store result into instance variable. */
129
+ /* This is because capng_get_caps_fd should return 0 if file cap is not set. */
130
+ rb_iv_set(self, "@return_code", INT2NUM(result));
94
131
  }
95
132
 
96
133
  return Qnil;
97
134
  }
98
135
 
136
+ /*
137
+ * Retrieve capability API status code on [CapNG#initialize] and file capability target.
138
+ *
139
+ * @return [@return_code]
140
+ *
141
+ */
142
+ static VALUE
143
+ rb_capng_return_code(VALUE self)
144
+ {
145
+ return rb_iv_get(self, "@return_code");
146
+ }
147
+
148
+ /*
149
+ * Clear capabilities on specified target.
150
+ *
151
+ * @param rb_select_name_or_enum [Symbol or String or Fixnum] targets are CAPS, BOUNDS,
152
+ * BOTH, and AMBIENT for supported platform.
153
+ *
154
+ * @return [nil]
155
+ *
156
+ */
99
157
  static VALUE
100
158
  rb_capng_clear(VALUE self, VALUE rb_select_name_or_enum)
101
159
  {
102
160
  capng_select_t select = 0;
103
161
 
104
162
  switch (TYPE(rb_select_name_or_enum)) {
105
- case T_SYMBOL:
106
- select = select_name_to_select_type(RSTRING_PTR(rb_sym2str(rb_select_name_or_enum)));
107
- break;
108
- case T_STRING:
109
- select = select_name_to_select_type(StringValuePtr(rb_select_name_or_enum));
110
- break;
111
- case T_FIXNUM:
112
- select = NUM2INT(rb_select_name_or_enum);
113
- break;
114
- default:
115
- rb_raise(rb_eArgError, "Expected a String or a Symbol instance, or a capability type constant");
163
+ case T_SYMBOL:
164
+ select =
165
+ select_name_to_select_type(RSTRING_PTR(rb_sym2str(rb_select_name_or_enum)));
166
+ break;
167
+ case T_STRING:
168
+ select = select_name_to_select_type(StringValuePtr(rb_select_name_or_enum));
169
+ break;
170
+ case T_FIXNUM:
171
+ select = NUM2INT(rb_select_name_or_enum);
172
+ break;
173
+ default:
174
+ rb_raise(rb_eArgError,
175
+ "Expected a String or a Symbol instance, or a capability type constant");
116
176
  }
117
177
 
118
178
  capng_clear(select);
@@ -120,23 +180,34 @@ rb_capng_clear(VALUE self, VALUE rb_select_name_or_enum)
120
180
  return Qnil;
121
181
  }
122
182
 
183
+ /*
184
+ * Fill capabilities on specified target.
185
+ *
186
+ * @param rb_select_name_or_enum [Symbol or String or Fixnum] targets are CAPS, BOUNDS,
187
+ * BOTH, and AMBIENT for supported platform.
188
+ *
189
+ * @return [nil]
190
+ *
191
+ */
123
192
  static VALUE
124
193
  rb_capng_fill(VALUE self, VALUE rb_select_name_or_enum)
125
194
  {
126
195
  capng_select_t select = 0;
127
196
 
128
197
  switch (TYPE(rb_select_name_or_enum)) {
129
- case T_SYMBOL:
130
- select = select_name_to_select_type(RSTRING_PTR(rb_sym2str(rb_select_name_or_enum)));
131
- break;
132
- case T_STRING:
133
- select = select_name_to_select_type(StringValuePtr(rb_select_name_or_enum));
134
- break;
135
- case T_FIXNUM:
136
- select = NUM2INT(rb_select_name_or_enum);
137
- break;
138
- default:
139
- rb_raise(rb_eArgError, "Expected a String or a Symbol instance, or a capability type constant");
198
+ case T_SYMBOL:
199
+ select =
200
+ select_name_to_select_type(RSTRING_PTR(rb_sym2str(rb_select_name_or_enum)));
201
+ break;
202
+ case T_STRING:
203
+ select = select_name_to_select_type(StringValuePtr(rb_select_name_or_enum));
204
+ break;
205
+ case T_FIXNUM:
206
+ select = NUM2INT(rb_select_name_or_enum);
207
+ break;
208
+ default:
209
+ rb_raise(rb_eArgError,
210
+ "Expected a String or a Symbol instance, or a capability type constant");
140
211
  }
141
212
 
142
213
  capng_fill(select);
@@ -144,6 +215,14 @@ rb_capng_fill(VALUE self, VALUE rb_select_name_or_enum)
144
215
  return Qnil;
145
216
  }
146
217
 
218
+ /*
219
+ * Specify process ID to retrieve other process capabilities.
220
+ *
221
+ * @param rb_pid [Fixnum] Process ID.
222
+ *
223
+ * @return [nil]
224
+ *
225
+ */
147
226
  static VALUE
148
227
  rb_capng_setpid(VALUE self, VALUE rb_pid)
149
228
  {
@@ -154,6 +233,13 @@ rb_capng_setpid(VALUE self, VALUE rb_pid)
154
233
  return Qnil;
155
234
  }
156
235
 
236
+ /*
237
+ * Specify process ID to retrieve process capabilities. If not
238
+ * calling #setpid before, it returns current process' capabilities.
239
+ *
240
+ * @return [Boolean]
241
+ *
242
+ */
157
243
  static VALUE
158
244
  rb_capng_get_caps_process(VALUE self)
159
245
  {
@@ -166,9 +252,21 @@ rb_capng_get_caps_process(VALUE self)
166
252
  return Qfalse;
167
253
  }
168
254
 
255
+ /*
256
+ * Update capabilities.
257
+ *
258
+ * @param rb_action_name_or_action [Symbol or String or Fixnum] ADD or DROP.
259
+ * @param rb_capability_name_or_type [Symbol or String or Fixnum]
260
+ * Effective/Inheritable/Permitted/Ambient (If supported) or their combinations
261
+ * @param rb_capability_or_name [Symbol or String or Fixnum] Capability name or constants.
262
+ *
263
+ * @see: [CapNG::Capability])
264
+ *
265
+ * @return [Boolean]
266
+ */
169
267
  static VALUE
170
- rb_capng_update(VALUE self,
171
- VALUE rb_action_name_or_action, VALUE rb_capability_name_or_type, VALUE rb_capability_or_name)
268
+ rb_capng_update(VALUE self, VALUE rb_action_name_or_action,
269
+ VALUE rb_capability_name_or_type, VALUE rb_capability_or_name)
172
270
  {
173
271
  int result = 0;
174
272
  unsigned int capability = 0;
@@ -176,45 +274,52 @@ rb_capng_update(VALUE self,
176
274
  capng_act_t action = 0;
177
275
 
178
276
  switch (TYPE(rb_action_name_or_action)) {
179
- case T_SYMBOL:
180
- action = action_name_to_action_type(RSTRING_PTR(rb_sym2str(rb_action_name_or_action)));
181
- break;
182
- case T_STRING:
183
- action = action_name_to_action_type(StringValuePtr(rb_action_name_or_action));
184
- break;
185
- case T_FIXNUM:
186
- action = NUM2INT(rb_action_name_or_action);
187
- break;
188
- default:
189
- rb_raise(rb_eArgError, "Expected a String or a Symbol instance, or a capability type constant");
277
+ case T_SYMBOL:
278
+ action =
279
+ action_name_to_action_type(RSTRING_PTR(rb_sym2str(rb_action_name_or_action)));
280
+ break;
281
+ case T_STRING:
282
+ action = action_name_to_action_type(StringValuePtr(rb_action_name_or_action));
283
+ break;
284
+ case T_FIXNUM:
285
+ action = NUM2INT(rb_action_name_or_action);
286
+ break;
287
+ default:
288
+ rb_raise(rb_eArgError,
289
+ "Expected a String or a Symbol instance, or a capability type constant");
190
290
  }
191
291
 
192
292
  switch (TYPE(rb_capability_name_or_type)) {
193
- case T_SYMBOL:
194
- capability_type = capability_type_name_to_capability_type(RSTRING_PTR(rb_sym2str(rb_capability_name_or_type)));
195
- break;
196
- case T_STRING:
197
- capability_type = capability_type_name_to_capability_type(StringValuePtr(rb_capability_name_or_type));
198
- break;
199
- case T_FIXNUM:
200
- capability_type = NUM2INT(rb_capability_name_or_type);
201
- break;
202
- default:
203
- rb_raise(rb_eArgError, "Expected a String or a Symbol instance, or a capability type constant");
293
+ case T_SYMBOL:
294
+ capability_type = capability_type_name_to_capability_type(
295
+ RSTRING_PTR(rb_sym2str(rb_capability_name_or_type)));
296
+ break;
297
+ case T_STRING:
298
+ capability_type = capability_type_name_to_capability_type(
299
+ StringValuePtr(rb_capability_name_or_type));
300
+ break;
301
+ case T_FIXNUM:
302
+ capability_type = NUM2INT(rb_capability_name_or_type);
303
+ break;
304
+ default:
305
+ rb_raise(rb_eArgError,
306
+ "Expected a String or a Symbol instance, or a capability type constant");
204
307
  }
205
308
 
206
309
  switch (TYPE(rb_capability_or_name)) {
207
- case T_SYMBOL:
208
- capability = capng_name_to_capability(RSTRING_PTR(rb_sym2str(rb_capability_or_name)));
209
- break;
210
- case T_STRING:
211
- capability = capng_name_to_capability(StringValuePtr(rb_capability_or_name));
212
- break;
213
- case T_FIXNUM:
214
- capability = NUM2INT(rb_capability_or_name);
215
- break;
216
- default:
217
- rb_raise(rb_eArgError, "Expected a String or a Symbol instance, or a capability constant");
310
+ case T_SYMBOL:
311
+ capability =
312
+ capng_name_to_capability(RSTRING_PTR(rb_sym2str(rb_capability_or_name)));
313
+ break;
314
+ case T_STRING:
315
+ capability = capng_name_to_capability(StringValuePtr(rb_capability_or_name));
316
+ break;
317
+ case T_FIXNUM:
318
+ capability = NUM2INT(rb_capability_or_name);
319
+ break;
320
+ default:
321
+ rb_raise(rb_eArgError,
322
+ "Expected a String or a Symbol instance, or a capability constant");
218
323
  }
219
324
 
220
325
  result = capng_update(action, capability_type, capability);
@@ -225,6 +330,15 @@ rb_capng_update(VALUE self,
225
330
  return Qfalse;
226
331
  }
227
332
 
333
+ /*
334
+ * Apply capabilities on specified target.
335
+ *
336
+ * @param rb_select_name_or_enum [Symbol or String or Fixnum]
337
+ * targets are CAPS, BOUNDS, BOTH, and AMBIENT for supported platform.
338
+ *
339
+ * @return [Boolean]
340
+ *
341
+ */
228
342
  static VALUE
229
343
  rb_capng_apply(VALUE self, VALUE rb_select_name_or_enum)
230
344
  {
@@ -232,17 +346,19 @@ rb_capng_apply(VALUE self, VALUE rb_select_name_or_enum)
232
346
  capng_select_t select = 0;
233
347
 
234
348
  switch (TYPE(rb_select_name_or_enum)) {
235
- case T_SYMBOL:
236
- select = select_name_to_select_type(RSTRING_PTR(rb_sym2str(rb_select_name_or_enum)));
237
- break;
238
- case T_STRING:
239
- select = select_name_to_select_type(StringValuePtr(rb_select_name_or_enum));
240
- break;
241
- case T_FIXNUM:
242
- select = NUM2INT(rb_select_name_or_enum);
243
- break;
244
- default:
245
- rb_raise(rb_eArgError, "Expected a String or a Symbol instance, or a capability type constant");
349
+ case T_SYMBOL:
350
+ select =
351
+ select_name_to_select_type(RSTRING_PTR(rb_sym2str(rb_select_name_or_enum)));
352
+ break;
353
+ case T_STRING:
354
+ select = select_name_to_select_type(StringValuePtr(rb_select_name_or_enum));
355
+ break;
356
+ case T_FIXNUM:
357
+ select = NUM2INT(rb_select_name_or_enum);
358
+ break;
359
+ default:
360
+ rb_raise(rb_eArgError,
361
+ "Expected a String or a Symbol instance, or a capability type constant");
246
362
  }
247
363
 
248
364
  result = capng_apply(select);
@@ -253,6 +369,12 @@ rb_capng_apply(VALUE self, VALUE rb_select_name_or_enum)
253
369
  return Qfalse;
254
370
  }
255
371
 
372
+ /*
373
+ * Lock capabilities.
374
+ *
375
+ * @return [Boolean]
376
+ *
377
+ */
256
378
  static VALUE
257
379
  rb_capng_lock(VALUE self)
258
380
  {
@@ -266,6 +388,14 @@ rb_capng_lock(VALUE self)
266
388
  return Qfalse;
267
389
  }
268
390
 
391
+ /*
392
+ * Change the credentials retaining capabilities.
393
+ * @param rb_uid [Fixnum] User ID.
394
+ * @param rb_gid [Fixnum] Group ID.
395
+ * @param rb_flags [Fixnum] CapNG::Flags constants.
396
+ *
397
+ * @see: capng_change_id(3)
398
+ */
269
399
  static VALUE
270
400
  rb_capng_change_id(VALUE self, VALUE rb_uid, VALUE rb_gid, VALUE rb_flags)
271
401
  {
@@ -276,9 +406,20 @@ rb_capng_change_id(VALUE self, VALUE rb_uid, VALUE rb_gid, VALUE rb_flags)
276
406
  if (result == 0)
277
407
  return Qtrue;
278
408
  else
279
- rb_raise(rb_eRuntimeError, "Calling capng_change_id is failed with: (exitcode: %d)\n", result);
409
+ rb_raise(rb_eRuntimeError,
410
+ "Calling capng_change_id is failed with: (exitcode: %d)\n",
411
+ result);
280
412
  }
281
413
 
414
+ /*
415
+ * Check whether capabilities on specified target or not.
416
+ *
417
+ * @param rb_select_name_or_enum [Symbol or String or Fixnum]
418
+ * targets are CAPS, BOUNDS, BOTH, and AMBIENT for supported platform.
419
+ *
420
+ * @return [Integer]
421
+ *
422
+ */
282
423
  static VALUE
283
424
  rb_capng_have_capabilities_p(VALUE self, VALUE rb_select_name_or_enum)
284
425
  {
@@ -286,56 +427,77 @@ rb_capng_have_capabilities_p(VALUE self, VALUE rb_select_name_or_enum)
286
427
  capng_select_t select = 0;
287
428
 
288
429
  switch (TYPE(rb_select_name_or_enum)) {
289
- case T_SYMBOL:
290
- select = select_name_to_select_type(RSTRING_PTR(rb_sym2str(rb_select_name_or_enum)));
291
- break;
292
- case T_STRING:
293
- select = select_name_to_select_type(StringValuePtr(rb_select_name_or_enum));
294
- break;
295
- case T_FIXNUM:
296
- select = NUM2INT(rb_select_name_or_enum);
297
- break;
298
- default:
299
- rb_raise(rb_eArgError, "Expected a String or a Symbol instance, or a capability type constant");
430
+ case T_SYMBOL:
431
+ select =
432
+ select_name_to_select_type(RSTRING_PTR(rb_sym2str(rb_select_name_or_enum)));
433
+ break;
434
+ case T_STRING:
435
+ select = select_name_to_select_type(StringValuePtr(rb_select_name_or_enum));
436
+ break;
437
+ case T_FIXNUM:
438
+ select = NUM2INT(rb_select_name_or_enum);
439
+ break;
440
+ default:
441
+ rb_raise(rb_eArgError,
442
+ "Expected a String or a Symbol instance, or a capability type constant");
300
443
  }
301
444
  result = capng_have_capabilities(select);
302
445
 
303
446
  return INT2NUM(result);
304
447
  }
305
448
 
449
+ /*
450
+ * Check whether capabilities on specified target or not.
451
+ *
452
+ * @param rb_capability_name_or_type [Symbol or String or Fixnum] types are EFFECTIVE,
453
+ * INHERITABLE, PERMITTED, and AMBIENT for supported platform.
454
+ * @param rb_capability_or_name [Symbol or String or Fixnum]
455
+ * Capability name or constants.
456
+ *
457
+ * @see: [CapNG::Capability]
458
+ *
459
+ * @return [Boolean]
460
+ *
461
+ */
306
462
  static VALUE
307
- rb_capng_have_capability_p(VALUE self, VALUE rb_capability_name_or_type, VALUE rb_capability_or_name)
463
+ rb_capng_have_capability_p(VALUE self, VALUE rb_capability_name_or_type,
464
+ VALUE rb_capability_or_name)
308
465
  {
309
466
  int result = 0;
310
467
  unsigned int capability = 0;
311
468
  capng_type_t capability_type = 0;
312
469
 
313
470
  switch (TYPE(rb_capability_name_or_type)) {
314
- case T_SYMBOL:
315
- capability_type = capability_type_name_to_capability_type(RSTRING_PTR(rb_sym2str(rb_capability_name_or_type)));
316
- break;
317
- case T_STRING:
318
- capability_type = capability_type_name_to_capability_type(StringValuePtr(rb_capability_name_or_type));
319
- break;
320
- case T_FIXNUM:
321
- capability_type = NUM2INT(rb_capability_name_or_type);
322
- break;
323
- default:
324
- rb_raise(rb_eArgError, "Expected a String or a Symbol instance, or a capability type constant");
471
+ case T_SYMBOL:
472
+ capability_type = capability_type_name_to_capability_type(
473
+ RSTRING_PTR(rb_sym2str(rb_capability_name_or_type)));
474
+ break;
475
+ case T_STRING:
476
+ capability_type = capability_type_name_to_capability_type(
477
+ StringValuePtr(rb_capability_name_or_type));
478
+ break;
479
+ case T_FIXNUM:
480
+ capability_type = NUM2INT(rb_capability_name_or_type);
481
+ break;
482
+ default:
483
+ rb_raise(rb_eArgError,
484
+ "Expected a String or a Symbol instance, or a capability type constant");
325
485
  }
326
486
 
327
487
  switch (TYPE(rb_capability_or_name)) {
328
- case T_SYMBOL:
329
- capability = capng_name_to_capability(RSTRING_PTR(rb_sym2str(rb_capability_or_name)));
330
- break;
331
- case T_STRING:
332
- capability = capng_name_to_capability(StringValuePtr(rb_capability_or_name));
333
- break;
334
- case T_FIXNUM:
335
- capability = NUM2INT(rb_capability_or_name);
336
- break;
337
- default:
338
- rb_raise(rb_eArgError, "Expected a String or a Symbol instance, or a capability constant");
488
+ case T_SYMBOL:
489
+ capability =
490
+ capng_name_to_capability(RSTRING_PTR(rb_sym2str(rb_capability_or_name)));
491
+ break;
492
+ case T_STRING:
493
+ capability = capng_name_to_capability(StringValuePtr(rb_capability_or_name));
494
+ break;
495
+ case T_FIXNUM:
496
+ capability = NUM2INT(rb_capability_or_name);
497
+ break;
498
+ default:
499
+ rb_raise(rb_eArgError,
500
+ "Expected a String or a Symbol instance, or a capability constant");
339
501
  }
340
502
 
341
503
  result = capng_have_capability(capability_type, capability);
@@ -346,11 +508,19 @@ rb_capng_have_capability_p(VALUE self, VALUE rb_capability_name_or_type, VALUE r
346
508
  return Qfalse;
347
509
  }
348
510
 
511
+ /*
512
+ * Retrieve capabilities from file.
513
+ *
514
+ * @param rb_file [File] target file object
515
+ *
516
+ * @return [Boolean]
517
+ *
518
+ */
349
519
  static VALUE
350
520
  rb_capng_get_caps_file(VALUE self, VALUE rb_file)
351
521
  {
352
522
  int result = 0, fd = 0;
353
- rb_io_t *fptr = NULL;
523
+ rb_io_t* fptr = NULL;
354
524
 
355
525
  Check_Type(rb_file, T_FILE);
356
526
 
@@ -367,11 +537,19 @@ rb_capng_get_caps_file(VALUE self, VALUE rb_file)
367
537
  return Qfalse;
368
538
  }
369
539
 
540
+ /*
541
+ * Apply capabilities on specified target (file specific version).
542
+ *
543
+ * @param rb_file [File] target file object
544
+ *
545
+ * @return [Boolean]
546
+ *
547
+ */
370
548
  static VALUE
371
549
  rb_capng_apply_caps_file(VALUE self, VALUE rb_file)
372
550
  {
373
551
  int result = 0, fd = 0;
374
- rb_io_t *fptr = NULL;
552
+ rb_io_t* fptr = NULL;
375
553
 
376
554
  Check_Type(rb_file, T_FILE);
377
555
 
@@ -389,15 +567,15 @@ rb_capng_apply_caps_file(VALUE self, VALUE rb_file)
389
567
  return Qfalse;
390
568
  }
391
569
 
392
-
393
570
  void
394
571
  Init_capng(void)
395
572
  {
396
- rb_cCapNG = rb_define_class("CapNG", rb_cObject);
573
+ VALUE rb_cCapNG = rb_define_class("CapNG", rb_cObject);
397
574
 
398
575
  rb_define_alloc_func(rb_cCapNG, rb_capng_alloc);
399
576
 
400
577
  rb_define_method(rb_cCapNG, "initialize", rb_capng_initialize, -1);
578
+ rb_define_method(rb_cCapNG, "return_code", rb_capng_return_code, 0);
401
579
  rb_define_method(rb_cCapNG, "clear", rb_capng_clear, 1);
402
580
  rb_define_method(rb_cCapNG, "fill", rb_capng_fill, 1);
403
581
  rb_define_method(rb_cCapNG, "setpid", rb_capng_setpid, 1);