RInotify 0.9-i586-linux

Sign up to get free protection for your applications and to get access to all the features.
data/ext/rinotify.c ADDED
@@ -0,0 +1,289 @@
1
+ /*****************************************************
2
+ * copyright (C) 2007 by Rob Merrell
3
+ * rob@migrob.com
4
+ *
5
+ * ***************************************************/
6
+
7
+ #include "ruby.h"
8
+ #include "rinotify.h"
9
+ #include "rinotify_event.h"
10
+
11
+ #include <sys/inotify.h>
12
+ #include <sys/time.h>
13
+ #include <sys/ioctl.h>
14
+ #include <unistd.h>
15
+
16
+ // extension entry point
17
+ void Init_rinotify() {
18
+ rb_cRInotify = rb_define_class("RInotify", rb_cObject);
19
+ rb_cRInotifyEvent = rb_define_class("RInotifyEvent", rb_cObject);
20
+
21
+ // initialize all of the events
22
+ rinotify_declare_events(rb_cRInotify);
23
+
24
+
25
+ // RInotify.new
26
+ rb_define_alloc_func(rb_cRInotify, rb_rinotify_new);
27
+
28
+ // RInotify.version
29
+ rb_define_method(rb_cRInotify, "version", rb_rinotify_version, 0);
30
+
31
+ // RInotify.close
32
+ rb_define_method(rb_cRInotify, "close", rb_rinotify_close, 0);
33
+
34
+ // RInotify.add_watch
35
+ rb_define_method(rb_cRInotify, "add_watch", rb_rinotify_add_watch, 2);
36
+
37
+ // RInotify.rm_watch
38
+ rb_define_method(rb_cRInotify, "rm_watch", rb_rinotify_rm_watch, 1);
39
+
40
+ // RInotify.wait_for_events
41
+ rb_define_method(rb_cRInotify, "wait_for_events", rb_rinotify_wait_for_events, 1);
42
+
43
+ // RInotify.each_event
44
+ rb_define_method(rb_cRInotify, "each_event", rb_rinotify_each_event, 0);
45
+
46
+ // RInotify.watch_descriptors
47
+ rb_define_method(rb_cRInotify, "watch_descriptors", rb_rinotify_watch_descriptors, 0);
48
+
49
+ // RInotify.event_queue_size
50
+ rb_define_method(rb_cRInotify, "event_queue_size", rb_rinotify_queue_size, 0);
51
+
52
+
53
+ /* The following methods are implemented in rinotify_event.c */
54
+
55
+ // RInotifyEvent.name
56
+ rb_define_method(rb_cRInotifyEvent, "name", rb_rinotify_event_name, 0);
57
+
58
+ // RInotifyEvent.watch_descriptor
59
+ rb_define_method(rb_cRInotifyEvent, "watch_descriptor", rb_rinotify_event_watch_descriptor, 0);
60
+
61
+ // RInotifyEvent.check_mask
62
+ rb_define_method(rb_cRInotifyEvent, "check_mask", rb_rinotify_event_check_mask, 1);
63
+ }
64
+
65
+
66
+ static VALUE rb_rinotify_new(VALUE klass) {
67
+ VALUE initialized_class;
68
+
69
+ // initialize inotify
70
+ int *inotify = NULL;
71
+ inotify = malloc(sizeof(int));
72
+ *inotify = inotify_init();
73
+
74
+ if (*inotify < 0)
75
+ rb_sys_fail("inotify_init");
76
+
77
+ // make sure free is called because we malloc'd above
78
+ initialized_class = Data_Wrap_Struct(klass, NULL, free, inotify);
79
+
80
+ // initialize all of the instance variables for this class
81
+ rinotify_declare_instance_vars(initialized_class);
82
+
83
+ return initialized_class;
84
+ }
85
+
86
+
87
+ static VALUE rb_rinotify_version(VALUE self) {
88
+ return rb_str_new2(CURRENT_VERSION);
89
+ }
90
+
91
+
92
+ static VALUE rb_rinotify_close(VALUE self) {
93
+ int *inotify = NULL, close_return;
94
+ Data_Get_Struct(self, int, inotify);
95
+
96
+ // close and clean up inotify
97
+ close_return = close(*inotify);
98
+ if (close_return)
99
+ rb_sys_fail("close");
100
+
101
+ return Qnil;
102
+ }
103
+
104
+
105
+ static VALUE rb_rinotify_add_watch(VALUE self, VALUE filename, VALUE event_masks) {
106
+ int *inotify = NULL, watch_desc;
107
+ VALUE watch_desc_id, watch_descriptor_list;
108
+ Data_Get_Struct(self, int, inotify);
109
+
110
+ // add the watch
111
+ watch_desc = inotify_add_watch(*inotify, RSTRING(filename)->ptr, NUM2INT(event_masks));
112
+ if (watch_desc < 0)
113
+ rb_sys_fail("add_watch");
114
+
115
+ watch_desc_id = INT2NUM(watch_desc);
116
+
117
+ // add the watch descriptor to our list
118
+ watch_descriptor_list = rb_iv_get(self, "@watch_descriptors");
119
+ rb_hash_aset(watch_descriptor_list, watch_desc_id, filename);
120
+
121
+ return watch_desc_id;
122
+ }
123
+
124
+
125
+ static VALUE rb_rinotify_rm_watch(VALUE self, VALUE watch_desc) {
126
+ int *inotify = NULL, rm_return;
127
+ Data_Get_Struct(self, int, inotify);
128
+
129
+ // remove the watch
130
+ rm_return = inotify_rm_watch(*inotify, NUM2INT(watch_desc));
131
+ if (rm_return < 0)
132
+ rb_sys_fail("rm_watch");
133
+
134
+ return INT2NUM(rm_return);
135
+ }
136
+
137
+
138
+ static VALUE rb_rinotify_wait_for_events(VALUE self, VALUE time_value) {
139
+ struct timeval time;
140
+ fd_set rfds;
141
+ int select_ret, *inotify = NULL;
142
+
143
+ Data_Get_Struct(self, int, inotify);
144
+
145
+ // set the timout value
146
+ time.tv_sec = NUM2INT(time_value);
147
+ time.tv_usec = 0;
148
+
149
+ // add inotify to the file descriptor set
150
+ FD_ZERO(&rfds);
151
+ FD_SET(*inotify, &rfds);
152
+
153
+ select_ret = rb_thread_select(*inotify + 1, &rfds, NULL, NULL, &time);
154
+
155
+ if (select_ret < 0)
156
+ rb_sys_fail("select");
157
+
158
+ // no events are available and we have timed out
159
+ else if (!select_ret)
160
+ return Qfalse;
161
+
162
+ // events are available
163
+ else if (FD_ISSET(*inotify, &rfds))
164
+ return Qtrue;
165
+
166
+ // to keep the compiler happy...
167
+ return Qfalse;
168
+ }
169
+
170
+
171
+ static VALUE rb_rinotify_each_event(VALUE self) {
172
+ struct inotify_event *event = NULL, *tmp_event = NULL;
173
+ int *inotify = NULL, i = 0, len;
174
+ char buffer[BUFFER_SIZE];
175
+
176
+ Data_Get_Struct(self, int, inotify);
177
+
178
+ len = read(*inotify, buffer, BUFFER_SIZE);
179
+
180
+ // read each event
181
+ while (i < len) {
182
+ tmp_event = (struct inotify_event *) &buffer[i];
183
+
184
+ // copy the tmp_event into our malloc'd event so that it doesn't
185
+ // go out of scope after we yield the object
186
+ event = malloc(EVENT_SIZE + tmp_event->len);
187
+ memmove(event, tmp_event, EVENT_SIZE + tmp_event->len);
188
+
189
+ // construct the RInotifyEvent object
190
+ rb_yield(rb_rinotify_event_new(event));
191
+
192
+ i += EVENT_SIZE + event->len;
193
+ }
194
+
195
+ return Qnil;
196
+ }
197
+
198
+
199
+ static VALUE rb_rinotify_watch_descriptors(VALUE self) {
200
+ return rb_iv_get(self, "@watch_descriptors");
201
+ }
202
+
203
+
204
+ static VALUE rb_rinotify_queue_size(VALUE self) {
205
+ int *inotify = NULL, return_val;
206
+ unsigned int queue_size;
207
+
208
+ Data_Get_Struct(self, int, inotify);
209
+
210
+ // get the queue size
211
+ return_val = ioctl(*inotify, FIONREAD, &queue_size);
212
+
213
+ if (return_val < 0)
214
+ rb_sys_fail("event_queue_size");
215
+
216
+ return UINT2NUM(queue_size);
217
+ }
218
+
219
+
220
+ static void rinotify_declare_events(VALUE klass) {
221
+ // watch events
222
+ rb_const_set(klass, rb_intern("IN_ACCESS"), INT2NUM(IN_ACCESS));
223
+ rb_const_set(klass, rb_intern("ACCESS"), INT2NUM(IN_ACCESS));
224
+
225
+ rb_const_set(klass, rb_intern("IN_MODIFY"), INT2NUM(IN_MODIFY));
226
+ rb_const_set(klass, rb_intern("MODIFY"), INT2NUM(IN_MODIFY));
227
+
228
+ rb_const_set(klass, rb_intern("IN_ATTRIB"), INT2NUM(IN_ATTRIB));
229
+ rb_const_set(klass, rb_intern("ATTRIB"), INT2NUM(IN_ATTRIB));
230
+
231
+ rb_const_set(klass, rb_intern("IN_CLOSE_WRITE"), INT2NUM(IN_CLOSE_WRITE));
232
+ rb_const_set(klass, rb_intern("CLOSE_WRITE"), INT2NUM(IN_CLOSE_WRITE));
233
+
234
+ rb_const_set(klass, rb_intern("IN_CLOSE_NOWRITE"), INT2NUM(IN_CLOSE_NOWRITE));
235
+ rb_const_set(klass, rb_intern("CLOSE_NOWRITE"), INT2NUM(IN_CLOSE_NOWRITE));
236
+
237
+ rb_const_set(klass, rb_intern("IN_OPEN"), INT2NUM(IN_OPEN));
238
+ rb_const_set(klass, rb_intern("OPEN"), INT2NUM(IN_OPEN));
239
+
240
+ rb_const_set(klass, rb_intern("IN_MOVED_FROM"), INT2NUM(IN_MOVED_FROM));
241
+ rb_const_set(klass, rb_intern("MOVED_FROM"), INT2NUM(IN_MOVED_FROM));
242
+
243
+ rb_const_set(klass, rb_intern("IN_MOVED_TO"), INT2NUM(IN_MOVED_TO));
244
+ rb_const_set(klass, rb_intern("MOVED_TO"), INT2NUM(IN_MOVED_TO));
245
+
246
+ rb_const_set(klass, rb_intern("IN_CREATE"), INT2NUM(IN_CREATE));
247
+ rb_const_set(klass, rb_intern("CREATE"), INT2NUM(IN_CREATE));
248
+
249
+ rb_const_set(klass, rb_intern("IN_DELETE"), INT2NUM(IN_DELETE));
250
+ rb_const_set(klass, rb_intern("DELETE"), INT2NUM(IN_DELETE));
251
+
252
+ rb_const_set(klass, rb_intern("IN_DELETE_SELF"), INT2NUM(IN_DELETE_SELF));
253
+ rb_const_set(klass, rb_intern("DELETE_SELF"), INT2NUM(IN_DELETE_SELF));
254
+
255
+ // sent by any watch
256
+ rb_const_set(klass, rb_intern("IN_UNMOUNT"), INT2NUM(IN_UNMOUNT));
257
+ rb_const_set(klass, rb_intern("UNMOUNT"), INT2NUM(IN_UNMOUNT));
258
+
259
+ rb_const_set(klass, rb_intern("IN_Q_OVERFLOW"), INT2NUM(IN_Q_OVERFLOW));
260
+ rb_const_set(klass, rb_intern("Q_OVERFLOW"), INT2NUM(IN_Q_OVERFLOW));
261
+
262
+ rb_const_set(klass, rb_intern("IN_IGNORED"), INT2NUM(IN_IGNORED));
263
+ rb_const_set(klass, rb_intern("IGNORED"), INT2NUM(IN_IGNORED));
264
+
265
+ // helper events
266
+ rb_const_set(klass, rb_intern("IN_CLOSE"), INT2NUM(IN_CLOSE));
267
+ rb_const_set(klass, rb_intern("CLOSE"), INT2NUM(IN_CLOSE));
268
+
269
+ rb_const_set(klass, rb_intern("IN_MOVE"), INT2NUM(IN_MOVE));
270
+ rb_const_set(klass, rb_intern("MOVE"), INT2NUM(IN_MOVE));
271
+
272
+ // special flags
273
+ rb_const_set(klass, rb_intern("IN_ISDIR"), INT2NUM(IN_ISDIR));
274
+ rb_const_set(klass, rb_intern("ISDIR"), INT2NUM(IN_ISDIR));
275
+
276
+ rb_const_set(klass, rb_intern("IN_ONESHOT"), INT2NUM(IN_ONESHOT));
277
+ rb_const_set(klass, rb_intern("ONESHOT"), INT2NUM(IN_ONESHOT));
278
+
279
+ rb_const_set(klass, rb_intern("IN_ALL_EVENTS"), INT2NUM(IN_ALL_EVENTS));
280
+ rb_const_set(klass, rb_intern("ALL_EVENTS"), INT2NUM(IN_ALL_EVENTS));
281
+ }
282
+
283
+
284
+ static void rinotify_declare_instance_vars(VALUE klass) {
285
+ // Array: holds a listing of all watch descriptors and the filename or directory name
286
+ // that they happen to be watching
287
+ VALUE watch_descriptors = rb_hash_new();
288
+ rb_iv_set(klass, "@watch_descriptors", watch_descriptors);
289
+ }
data/ext/rinotify.h ADDED
@@ -0,0 +1,163 @@
1
+ /*****************************************************
2
+ * copyright (C) 2007 by Rob Merrell
3
+ * rob@migrob.com
4
+ *
5
+ * ***************************************************/
6
+
7
+ #ifndef RINOTIFY_H
8
+ #define RINOTIFY_H
9
+
10
+ #include "ruby.h"
11
+ #include <sys/inotify.h>
12
+
13
+ #define CURRENT_VERSION "0.9"
14
+ #define EVENT_SIZE sizeof(struct inotify_event)
15
+ #define BUFFER_SIZE 16384
16
+
17
+ // RInotify class
18
+ static VALUE rb_cRInotify;
19
+
20
+ /* Non Ruby-implimented Prototypes */
21
+
22
+ // declare the inotify events as constants
23
+ static void rinotify_declare_events(VALUE);
24
+
25
+ // declare any instance variables we will need
26
+ static void rinotify_declare_instance_vars(VALUE);
27
+
28
+
29
+
30
+ /* Ruby Prototypes */
31
+
32
+ /*
33
+ * call-seq:
34
+ * RInotify.new -> RInotify
35
+ *
36
+ * Returns a new RInotify object.
37
+ *
38
+ * Example Usage:
39
+ * @rinotify = RInotify.new
40
+ */
41
+ static VALUE rb_rinotify_new(VALUE);
42
+
43
+
44
+ /*
45
+ * call-seq:
46
+ * RInotify.version -> String
47
+ *
48
+ * Returns the current version.
49
+ *
50
+ * Example Usage:
51
+ * @rinotify.version => "0.1.0"
52
+ */
53
+ static VALUE rb_rinotify_version(VALUE);
54
+
55
+
56
+ /*
57
+ * call-seq:
58
+ * RInotify.close -> nil
59
+ *
60
+ * Clean up and close inotify.
61
+ *
62
+ * Example Usage:
63
+ * @rinotify.close
64
+ */
65
+ static VALUE rb_rinotify_close(VALUE);
66
+
67
+
68
+ /*
69
+ * call-seq:
70
+ * RInotify.add_watch(filename, event masks) -> watch descriptor
71
+ *
72
+ * Adds a watch on a file or directory.
73
+ *
74
+ * The event masks are simple a bitmask and should be joined like:
75
+ * RInotify::OPEN | RInotify::MODIFY
76
+ *
77
+ * Example Usage:
78
+ * @rinotify = RInotify.new
79
+ * @rinotify.add_watch("/home/rob/Desktop/my_file.txt", RInotify::MODIFY | RInotify::DELETE_SELF | RInotify::OPEN)
80
+ */
81
+ static VALUE rb_rinotify_add_watch(VALUE, VALUE, VALUE);
82
+
83
+
84
+ /*
85
+ * call-seq:
86
+ * RInotify.rm_watch(watch descriptor) -> closed watch descriptor
87
+ *
88
+ * Remove a watch descriptor. Note that this is not a necessary step
89
+ * when closing inotify.
90
+ *
91
+ * Example Usage:
92
+ * @rinotify = RInotify.new
93
+ * wd = @rinotify.add_watch("/home/rob/Desktop/my_file.txt", RInotify::MODIFY | RInotify::DELETE_SELF | RInotify::OPEN)
94
+ * @rinotify.rm_watch(wd)
95
+ */
96
+ static VALUE rb_rinotify_rm_watch(VALUE, VALUE);
97
+
98
+
99
+ /*
100
+ * call-seq:
101
+ * RInotify.wait_for_events(seconds to time out) -> true or false
102
+ *
103
+ * Waits for events to be received from inotify.
104
+ * Returns true when there are events waiting in the queue
105
+ * and false if not.
106
+ *
107
+ * Example Usage:
108
+ * @rinotify = RInotify.new
109
+ * @rinotify.add_watch("/home/rob/Desktop/my_file.txt", RInotify::MODIFY | RInotify::DELETE_SELF | RInotify::OPEN)
110
+ *
111
+ * # set time out at 5 seconds
112
+ * has_events = @rinotify.wait_for_events(5)
113
+ */
114
+ static VALUE rb_rinotify_wait_for_events(VALUE, VALUE);
115
+
116
+
117
+ /*
118
+ * call-seq:
119
+ * RInotify.each_event -> RInotifyEvent
120
+ *
121
+ * Yields an RInotifyEvent object in a block
122
+ *
123
+ * Example Usage:
124
+ * has_events = @rinotify.wait_for_events(5)
125
+ * if has_events
126
+ * @rinotify.each_event {|revent|
127
+ * ...
128
+ * }
129
+ * end
130
+ */
131
+ static VALUE rb_rinotify_each_event(VALUE);
132
+
133
+
134
+ /*
135
+ * call-seq:
136
+ * RInotify.watch_descriptors -> Hash(watch descriptor, file name)
137
+ *
138
+ * Returns a hash of all watch_descriptors and file name of each file or directory
139
+ * being watched.
140
+ *
141
+ * Example Usage:
142
+ * @rinotify.watch_descriptors => [1, "/home/rob/Desktop/my_file.txt"]
143
+ */
144
+ static VALUE rb_rinotify_watch_descriptors(VALUE);
145
+
146
+
147
+ /*
148
+ * call-seq:
149
+ * RInotify.event_queue_size -> Fixnum
150
+ *
151
+ * Returns the current size of the event queue. This is useful if you want to throttle
152
+ * your event checks
153
+ *
154
+ * Example Usage:
155
+ * while (queue_size < 128)
156
+ * if @rinotify.wait_for_events(5)
157
+ * queue_size = @rinotify.event_queue_size
158
+ * end
159
+ * end
160
+ */
161
+ static VALUE rb_rinotify_queue_size(VALUE);
162
+
163
+ #endif
@@ -0,0 +1,55 @@
1
+ #include "ruby.h"
2
+ #include "rinotify_event.h"
3
+
4
+ #include <sys/inotify.h>
5
+
6
+ VALUE rb_rinotify_event_new(struct inotify_event *event) {
7
+ VALUE rinotify_event;
8
+
9
+ // initialize the object
10
+ rinotify_event = Data_Wrap_Struct(rb_cRInotifyEvent, NULL, free, event);
11
+ rb_obj_call_init(rinotify_event, 0, NULL);
12
+
13
+ return rinotify_event;
14
+ }
15
+
16
+
17
+ VALUE rb_rinotify_event_name(VALUE self) {
18
+ VALUE name;
19
+ struct inotify_event *event;
20
+ Data_Get_Struct(self, struct inotify_event, event);
21
+
22
+ // if watching for events in a directory inotify will tell us the name
23
+ if (event->len) {
24
+ name = rb_str_new2(event->name);
25
+ } else {
26
+ // watching a single file doesn't waste space with a filename so return nil
27
+ name = Qnil;
28
+ }
29
+
30
+ return name;
31
+ }
32
+
33
+
34
+ VALUE rb_rinotify_event_watch_descriptor(VALUE self) {
35
+ struct inotify_event *event;
36
+ Data_Get_Struct(self, struct inotify_event, event);
37
+
38
+ return INT2NUM(event->wd);
39
+ }
40
+
41
+
42
+ VALUE rb_rinotify_event_check_mask(VALUE self, VALUE masks) {
43
+ VALUE return_val;
44
+ struct inotify_event *event;
45
+ Data_Get_Struct(self, struct inotify_event, event);
46
+
47
+ // check if the mask is part of the event
48
+ if (event->mask & NUM2INT(masks))
49
+ return_val = Qtrue;
50
+ else
51
+ return_val = Qfalse;
52
+
53
+ return return_val;
54
+ }
55
+
@@ -0,0 +1,60 @@
1
+ /*****************************************************
2
+ * copyright (C) 2007 by Rob Merrell
3
+ * rob@migrob.com
4
+ *
5
+ * ***************************************************/
6
+
7
+ #ifndef RINOTIFY_EVENT_H
8
+ #define RINOTIFY_EVENT_H
9
+
10
+ #include "ruby.h"
11
+ #include <sys/inotify.h>
12
+
13
+ // RInotifyEvent class
14
+ VALUE rb_cRInotifyEvent;
15
+
16
+ /* Ruby Prototypes */
17
+
18
+ // returns a new RInotifyEvent object. This method should only be called by RInotify.each_event
19
+ VALUE rb_rinotify_event_new(struct inotify_event*);
20
+
21
+
22
+ /*
23
+ * call-seq:
24
+ * RInotifyEvent.name -> event name
25
+ *
26
+ * Returns the name of the event if the watched file is a directory. If it is a file
27
+ * nil is returned. In this case the event name can be found by looking the watch descriptor
28
+ * up using RInotify.watch_descriptors.
29
+ *
30
+ * Example Usage:
31
+ * rinotify_event.name -> "/home/rob/desktop/tmp/test"
32
+ */
33
+ VALUE rb_rinotify_event_name(VALUE);
34
+
35
+
36
+ /*
37
+ * call-seq:
38
+ * RInotifyEvent.watch_descriptor -> event watch descriptor
39
+ *
40
+ * Returns the watch descriptor that the event belongs to.
41
+ *
42
+ * Example Usage:
43
+ * rinotify_event.watch_descriptor -> 1
44
+ */
45
+ VALUE rb_rinotify_event_watch_descriptor(VALUE);
46
+
47
+
48
+ /*
49
+ * call-seq:
50
+ * RInotifyEvent.check_mask(mask) -> boolean
51
+ *
52
+ * Returns true or false if the current event contains the mask(s)
53
+ *
54
+ * Example Usage:
55
+ * rinotify_event->check_mask(RInotify::MODIFY) -> true
56
+ * rinotify_event->check_mask(RInotify::DELETE_SELF) -> false
57
+ */
58
+ VALUE rb_rinotify_event_check_mask(VALUE, VALUE);
59
+
60
+ #endif
data/extconf.rb ADDED
@@ -0,0 +1,3 @@
1
+ require 'mkmf'
2
+
3
+ create_makefile('rinotify', 'ext')
metadata ADDED
@@ -0,0 +1,49 @@
1
+ --- !ruby/object:Gem::Specification
2
+ rubygems_version: 0.9.2
3
+ specification_version: 1
4
+ name: RInotify
5
+ version: !ruby/object:Gem::Version
6
+ version: "0.9"
7
+ date: 2007-04-17 00:00:00 -06:00
8
+ summary: A Ruby wrapper for Linux's inotify
9
+ require_paths:
10
+ - .
11
+ email: rob@migrob.com
12
+ homepage: http://rinotify.migrob.com
13
+ rubyforge_project:
14
+ description:
15
+ autorequire: RInotify
16
+ default_executable:
17
+ bindir: bin
18
+ has_rdoc: false
19
+ required_ruby_version: !ruby/object:Gem::Version::Requirement
20
+ requirements:
21
+ - - ">"
22
+ - !ruby/object:Gem::Version
23
+ version: 0.0.0
24
+ version:
25
+ platform: i586-linux
26
+ signing_key:
27
+ cert_chain:
28
+ post_install_message:
29
+ authors:
30
+ - Rob Merrell
31
+ files:
32
+ - ext/rinotify_event.c
33
+ - ext/rinotify.c
34
+ - ext/rinotify_event.h
35
+ - ext/rinotify.h
36
+ test_files: []
37
+
38
+ rdoc_options: []
39
+
40
+ extra_rdoc_files: []
41
+
42
+ executables: []
43
+
44
+ extensions:
45
+ - extconf.rb
46
+ requirements: []
47
+
48
+ dependencies: []
49
+