capng_c 0.1.3 → 0.1.8

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.
@@ -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);