ruby-libvirt-catphish 0.7.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,6 @@
1
+ #ifndef STORAGE_H
2
+ #define STORAGE_H
3
+
4
+ void ruby_libvirt_storage_init(void);
5
+
6
+ #endif
@@ -0,0 +1,392 @@
1
+ /*
2
+ * stream.c: virStream methods
3
+ *
4
+ * Copyright (C) 2007,2010 Red Hat Inc.
5
+ * Copyright (C) 2013-2016 Chris Lalancette <clalancette@gmail.com>
6
+ *
7
+ * This library is free software; you can redistribute it and/or
8
+ * modify it under the terms of the GNU Lesser General Public
9
+ * License as published by the Free Software Foundation; either
10
+ * version 2.1 of the License, or (at your option) any later version.
11
+ *
12
+ * This library is distributed in the hope that it will be useful,
13
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
14
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15
+ * Lesser General Public License for more details.
16
+ *
17
+ * You should have received a copy of the GNU Lesser General Public
18
+ * License along with this library; if not, write to the Free Software
19
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20
+ */
21
+
22
+ #include <ruby.h>
23
+ #include <libvirt/libvirt.h>
24
+ #include <libvirt/virterror.h>
25
+ #include "common.h"
26
+ #include "connect.h"
27
+ #include "extconf.h"
28
+
29
+ #if HAVE_TYPE_VIRSTREAMPTR
30
+ static VALUE c_stream;
31
+
32
+ static void stream_free(void *s)
33
+ {
34
+ ruby_libvirt_free_struct(Stream, s);
35
+ }
36
+
37
+ virStreamPtr ruby_libvirt_stream_get(VALUE s)
38
+ {
39
+ ruby_libvirt_get_struct(Stream, s);
40
+ }
41
+
42
+ VALUE ruby_libvirt_stream_new(virStreamPtr s, VALUE conn)
43
+ {
44
+ return ruby_libvirt_new_class(c_stream, s, conn, stream_free);
45
+ }
46
+
47
+ /*
48
+ * call-seq:
49
+ * stream.send(buffer) -> Fixnum
50
+ *
51
+ * Call virStreamSend[http://www.libvirt.org/html/libvirt-libvirt-stream.html#virStreamSend]
52
+ * to send the data in buffer out to the stream. The return value is the
53
+ * number of bytes sent, which may be less than the size of the buffer. If
54
+ * an error occurred, -1 is returned. If the transmit buffers are full and the
55
+ * stream is marked non-blocking, returns -2.
56
+ */
57
+ static VALUE libvirt_stream_send(VALUE s, VALUE buffer)
58
+ {
59
+ int ret;
60
+
61
+ StringValue(buffer);
62
+
63
+ ret = virStreamSend(ruby_libvirt_stream_get(s), RSTRING_PTR(buffer),
64
+ RSTRING_LEN(buffer));
65
+ ruby_libvirt_raise_error_if(ret == -1, e_RetrieveError, "virStreamSend",
66
+ ruby_libvirt_connect_get(s));
67
+
68
+ return INT2NUM(ret);
69
+ }
70
+
71
+ /*
72
+ * call-seq:
73
+ * stream.recv(bytes) -> [return_value, data]
74
+ *
75
+ * Call virStreamRecv[http://www.libvirt.org/html/libvirt-libvirt-stream.html#virStreamRecv]
76
+ * to receive up to bytes amount of data from the stream. The return is an
77
+ * array with two elements; the return code from the virStreamRecv call and
78
+ * the data (as a String) read from the stream. If an error occurred, the
79
+ * return_value is set to -1. If there is no data pending and the stream is
80
+ * marked as non-blocking, return_value is set to -2.
81
+ */
82
+ static VALUE libvirt_stream_recv(VALUE s, VALUE bytes)
83
+ {
84
+ char *data;
85
+ int ret;
86
+ VALUE result;
87
+
88
+ data = alloca(sizeof(char) * NUM2INT(bytes));
89
+
90
+ ret = virStreamRecv(ruby_libvirt_stream_get(s), data, NUM2INT(bytes));
91
+ ruby_libvirt_raise_error_if(ret < 0, e_RetrieveError, "virStreamRecv",
92
+ ruby_libvirt_connect_get(s));
93
+
94
+ result = rb_ary_new2(2);
95
+
96
+ rb_ary_store(result, 0, INT2NUM(ret));
97
+ rb_ary_store(result, 1, rb_str_new(data, ret));
98
+
99
+ return result;
100
+ }
101
+
102
+ static int internal_sendall(virStreamPtr RUBY_LIBVIRT_UNUSED(st), char *data,
103
+ size_t nbytes, void *opaque)
104
+ {
105
+ VALUE result, retcode, buffer;
106
+
107
+ result = rb_yield_values(2, (VALUE)opaque, INT2NUM(nbytes));
108
+
109
+ if (TYPE(result) != T_ARRAY) {
110
+ rb_raise(rb_eTypeError, "wrong type (expected Array)");
111
+ }
112
+
113
+ if (RARRAY_LEN(result) != 2) {
114
+ rb_raise(rb_eArgError, "wrong number of arguments (%ld for 2)",
115
+ RARRAY_LEN(result));
116
+ }
117
+
118
+ retcode = rb_ary_entry(result, 0);
119
+ buffer = rb_ary_entry(result, 1);
120
+
121
+ if (NUM2INT(retcode) < 0) {
122
+ return NUM2INT(retcode);
123
+ }
124
+
125
+ StringValue(buffer);
126
+
127
+ if (RSTRING_LEN(buffer) > (int)nbytes) {
128
+ rb_raise(rb_eArgError, "asked for %zd bytes, block returned %ld",
129
+ nbytes, RSTRING_LEN(buffer));
130
+ }
131
+
132
+ memcpy(data, RSTRING_PTR(buffer), RSTRING_LEN(buffer));
133
+
134
+ return RSTRING_LEN(buffer);
135
+ }
136
+
137
+ /*
138
+ * call-seq:
139
+ * stream.sendall(opaque=nil){|opaque, nbytes| send block} -> nil
140
+ *
141
+ * Call virStreamSendAll[http://www.libvirt.org/html/libvirt-libvirt-stream.html#virStreamSendAll]
142
+ * to send the entire data stream. The send block is required and is executed
143
+ * one or more times to send data. Each invocation of the send block yields
144
+ * the opaque data passed into the initial call and the number of bytes this
145
+ * iteration is prepared to handle. The send block should return an array of
146
+ * 2 elements; the first element should be the return code from the block
147
+ * (-1 for error, 0 otherwise), and the second element should be the data
148
+ * that the block prepared to send.
149
+ */
150
+ static VALUE libvirt_stream_sendall(int argc, VALUE *argv, VALUE s)
151
+ {
152
+ VALUE opaque = RUBY_Qnil;
153
+ int ret;
154
+
155
+ if (!rb_block_given_p()) {
156
+ rb_raise(rb_eRuntimeError, "A block must be provided");
157
+ }
158
+
159
+ rb_scan_args(argc, argv, "01", &opaque);
160
+
161
+ ret = virStreamSendAll(ruby_libvirt_stream_get(s), internal_sendall,
162
+ (void *)opaque);
163
+ ruby_libvirt_raise_error_if(ret < 0, e_RetrieveError, "virStreamSendAll",
164
+ ruby_libvirt_connect_get(s));
165
+
166
+ return Qnil;
167
+ }
168
+
169
+ static int internal_recvall(virStreamPtr RUBY_LIBVIRT_UNUSED(st),
170
+ const char *buf, size_t nbytes, void *opaque)
171
+ {
172
+ VALUE result;
173
+
174
+ result = rb_yield_values(2, rb_str_new(buf, nbytes), (VALUE)opaque);
175
+
176
+ if (TYPE(result) != T_FIXNUM) {
177
+ rb_raise(rb_eArgError, "wrong type (expected an integer)");
178
+ }
179
+
180
+ return NUM2INT(result);
181
+ }
182
+
183
+ /*
184
+ * call-seq:
185
+ * stream.recvall(opaque){|data, opaque| receive block} -> nil
186
+ *
187
+ * Call virStreamRecvAll[http://www.libvirt.org/html/libvirt-libvirt-stream.html#virStreamRecvAll]
188
+ * to receive the entire data stream. The receive block is required and is
189
+ * called one or more times to receive data. Each invocation of the receive
190
+ * block yields the data received and the opaque data passed into the initial
191
+ * call. The block should return -1 if an error occurred and 0 otherwise.
192
+ */
193
+ static VALUE libvirt_stream_recvall(int argc, VALUE *argv, VALUE s)
194
+ {
195
+ VALUE opaque = RUBY_Qnil;
196
+ int ret;
197
+
198
+ if (!rb_block_given_p()) {
199
+ rb_raise(rb_eRuntimeError, "A block must be provided");
200
+ }
201
+
202
+ rb_scan_args(argc, argv, "01", &opaque);
203
+
204
+ ret = virStreamRecvAll(ruby_libvirt_stream_get(s), internal_recvall,
205
+ (void *)opaque);
206
+ ruby_libvirt_raise_error_if(ret < 0, e_RetrieveError, "virStreamRecvAll",
207
+ ruby_libvirt_connect_get(s));
208
+
209
+ return Qnil;
210
+ }
211
+
212
+ static void stream_event_callback(virStreamPtr st, int events, void *opaque)
213
+ {
214
+ VALUE passthrough = (VALUE)opaque;
215
+ VALUE cb, cb_opaque, news, s;
216
+
217
+ if (TYPE(passthrough) != T_ARRAY) {
218
+ rb_raise(rb_eTypeError,
219
+ "wrong domain event lifecycle callback argument type (expected Array)");
220
+ }
221
+
222
+ if (RARRAY_LEN(passthrough) != 3) {
223
+ rb_raise(rb_eArgError, "wrong number of arguments (%ld for 3)",
224
+ RARRAY_LEN(passthrough));
225
+ }
226
+
227
+ cb = rb_ary_entry(passthrough, 0);
228
+ cb_opaque = rb_ary_entry(passthrough, 1);
229
+ s = rb_ary_entry(passthrough, 2);
230
+
231
+ news = ruby_libvirt_stream_new(st, ruby_libvirt_conn_attr(s));
232
+ if (strcmp(rb_obj_classname(cb), "Symbol") == 0) {
233
+ rb_funcall(rb_class_of(cb), rb_to_id(cb), 3, news, INT2NUM(events),
234
+ cb_opaque);
235
+ }
236
+ else if (strcmp(rb_obj_classname(cb), "Proc") == 0) {
237
+ rb_funcall(cb, rb_intern("call"), 3, news, INT2NUM(events), cb_opaque);
238
+ }
239
+ else {
240
+ rb_raise(rb_eTypeError,
241
+ "wrong stream event callback (expected Symbol or Proc)");
242
+ }
243
+ }
244
+
245
+ /*
246
+ * call-seq:
247
+ * stream.event_add_callback(events, callback, opaque=nil) -> nil
248
+ *
249
+ * Call virStreamEventAddCallback[http://www.libvirt.org/html/libvirt-libvirt-stream.html#virStreamEventAddCallback]
250
+ * to register a callback to be notified when a stream becomes readable or
251
+ * writeable. The events parameter is an integer representing the events the
252
+ * user is interested in; it should be one or more of EVENT_READABLE,
253
+ * EVENT_WRITABLE, EVENT_ERROR, and EVENT_HANGUP, ORed together. The callback
254
+ * can either be a Symbol (that is the name of a method to callback) or a Proc.
255
+ * The callback should accept 3 parameters: a pointer to the Stream object
256
+ * itself, the integer that represents the events that actually occurred, and
257
+ * an opaque pointer that was (optionally) passed into
258
+ * stream.event_add_callback to begin with.
259
+ */
260
+ static VALUE libvirt_stream_event_add_callback(int argc, VALUE *argv, VALUE s)
261
+ {
262
+ VALUE events = RUBY_Qnil, callback = RUBY_Qnil, opaque = RUBY_Qnil, passthrough;
263
+ int ret;
264
+
265
+ rb_scan_args(argc, argv, "21", &events, &callback, &opaque);
266
+
267
+ if (!ruby_libvirt_is_symbol_or_proc(callback)) {
268
+ rb_raise(rb_eTypeError,
269
+ "wrong argument type (expected Symbol or Proc)");
270
+ }
271
+
272
+ passthrough = rb_ary_new2(3);
273
+ rb_ary_store(passthrough, 0, callback);
274
+ rb_ary_store(passthrough, 1, opaque);
275
+ rb_ary_store(passthrough, 2, s);
276
+
277
+ ret = virStreamEventAddCallback(ruby_libvirt_stream_get(s), NUM2INT(events),
278
+ stream_event_callback, (void *)passthrough,
279
+ NULL);
280
+ ruby_libvirt_raise_error_if(ret < 0, e_RetrieveError,
281
+ "virStreamEventAddCallback",
282
+ ruby_libvirt_connect_get(s));
283
+
284
+ return Qnil;
285
+ }
286
+
287
+ /*
288
+ * call-seq:
289
+ * stream.event_update_callback(events) -> nil
290
+ *
291
+ * Call virStreamEventUpdateCallback[http://www.libvirt.org/html/libvirt-libvirt-stream.html#virStreamEventUpdateCallback]
292
+ * to change the events that the event callback is looking for. The events
293
+ * parameter is an integer representing the events the user is interested in;
294
+ * it should be one or more of EVENT_READABLE, EVENT_WRITABLE, EVENT_ERROR,
295
+ * and EVENT_HANGUP, ORed together.
296
+ */
297
+ static VALUE libvirt_stream_event_update_callback(VALUE s, VALUE events)
298
+ {
299
+ ruby_libvirt_generate_call_nil(virStreamEventUpdateCallback,
300
+ ruby_libvirt_connect_get(s),
301
+ ruby_libvirt_stream_get(s), NUM2INT(events));
302
+ }
303
+
304
+ /*
305
+ * call-seq:
306
+ * stream.event_remove_callback -> nil
307
+ *
308
+ * Call virStreamEventRemoveCallback[http://www.libvirt.org/html/libvirt-libvirt-stream.html#virStreamEventRemoveCallback]
309
+ * to remove the event callback currently registered to this stream.
310
+ */
311
+ static VALUE libvirt_stream_event_remove_callback(VALUE s)
312
+ {
313
+ ruby_libvirt_generate_call_nil(virStreamEventRemoveCallback,
314
+ ruby_libvirt_connect_get(s),
315
+ ruby_libvirt_stream_get(s));
316
+ }
317
+
318
+ /*
319
+ * call-seq:
320
+ * stream.finish -> nil
321
+ *
322
+ * Call virStreamFinish[http://www.libvirt.org/html/libvirt-libvirt-stream.html#virStreamFinish]
323
+ * to finish this stream. Finish is typically used when the stream is no
324
+ * longer needed and needs to be cleaned up.
325
+ */
326
+ static VALUE libvirt_stream_finish(VALUE s)
327
+ {
328
+ ruby_libvirt_generate_call_nil(virStreamFinish, ruby_libvirt_connect_get(s),
329
+ ruby_libvirt_stream_get(s));
330
+ }
331
+
332
+ /*
333
+ * call-seq:
334
+ * stream.abort -> nil
335
+ *
336
+ * Call virStreamAbort[http://www.libvirt.org/html/libvirt-libvirt-stream.html#virStreamAbort]
337
+ * to abort this stream. Abort is typically used when something on the stream
338
+ * has failed, and the stream needs to be cleaned up.
339
+ */
340
+ static VALUE libvirt_stream_abort(VALUE s)
341
+ {
342
+ ruby_libvirt_generate_call_nil(virStreamAbort, ruby_libvirt_connect_get(s),
343
+ ruby_libvirt_stream_get(s));
344
+ }
345
+
346
+ /*
347
+ * call-seq:
348
+ * stream.free -> nil
349
+ *
350
+ * Call virStreamFree[http://www.libvirt.org/html/libvirt-libvirt-stream.html#virStreamFree]
351
+ * to free this stream. The object will no longer be valid after this call.
352
+ */
353
+ static VALUE libvirt_stream_free(VALUE s)
354
+ {
355
+ ruby_libvirt_generate_call_free(Stream, s);
356
+ }
357
+ #endif
358
+
359
+ /*
360
+ * Class Libvirt::Stream
361
+ */
362
+ void ruby_libvirt_stream_init(void)
363
+ {
364
+ #if HAVE_TYPE_VIRSTREAMPTR
365
+ c_stream = rb_define_class_under(m_libvirt, "Stream", rb_cObject);
366
+
367
+ rb_define_attr(c_stream, "connection", 1, 0);
368
+
369
+ rb_define_const(c_stream, "NONBLOCK", INT2NUM(VIR_STREAM_NONBLOCK));
370
+ rb_define_const(c_stream, "EVENT_READABLE",
371
+ INT2NUM(VIR_STREAM_EVENT_READABLE));
372
+ rb_define_const(c_stream, "EVENT_WRITABLE",
373
+ INT2NUM(VIR_STREAM_EVENT_WRITABLE));
374
+ rb_define_const(c_stream, "EVENT_ERROR", INT2NUM(VIR_STREAM_EVENT_ERROR));
375
+ rb_define_const(c_stream, "EVENT_HANGUP", INT2NUM(VIR_STREAM_EVENT_HANGUP));
376
+
377
+ rb_define_method(c_stream, "send", libvirt_stream_send, 1);
378
+ rb_define_method(c_stream, "recv", libvirt_stream_recv, 1);
379
+ rb_define_method(c_stream, "sendall", libvirt_stream_sendall, -1);
380
+ rb_define_method(c_stream, "recvall", libvirt_stream_recvall, -1);
381
+
382
+ rb_define_method(c_stream, "event_add_callback",
383
+ libvirt_stream_event_add_callback, -1);
384
+ rb_define_method(c_stream, "event_update_callback",
385
+ libvirt_stream_event_update_callback, 1);
386
+ rb_define_method(c_stream, "event_remove_callback",
387
+ libvirt_stream_event_remove_callback, 0);
388
+ rb_define_method(c_stream, "finish", libvirt_stream_finish, 0);
389
+ rb_define_method(c_stream, "abort", libvirt_stream_abort, 0);
390
+ rb_define_method(c_stream, "free", libvirt_stream_free, 0);
391
+ #endif
392
+ }
@@ -0,0 +1,9 @@
1
+ #ifndef STREAM_H
2
+ #define STREAM_H
3
+
4
+ void ruby_libvirt_stream_init(void);
5
+
6
+ VALUE ruby_libvirt_stream_new(virStreamPtr s, VALUE conn);
7
+ virStreamPtr ruby_libvirt_stream_get(VALUE s);
8
+
9
+ #endif
data/lib/libvirt.rb ADDED
@@ -0,0 +1,40 @@
1
+ #
2
+ # libvirt.rb: main module for the ruby-libvirt bindings
3
+ #
4
+ # Copyright (C) 2007 Red Hat, Inc.
5
+ #
6
+ # Distributed under the GNU Lesser General Public License v2.1 or later.
7
+ # See COPYING for details
8
+ #
9
+ # David Lutterkort <dlutter@redhat.com>
10
+
11
+ require '_libvirt'
12
+
13
+ module Libvirt
14
+
15
+ # A version in Libvirt's representation
16
+ class Version
17
+ attr_reader :version, :type
18
+
19
+ def initialize(type, version)
20
+ @type = type
21
+ @version = version
22
+ end
23
+
24
+ def major
25
+ version / 1000000
26
+ end
27
+
28
+ def minor
29
+ version % 1000000 / 1000
30
+ end
31
+
32
+ def release
33
+ version % 1000
34
+ end
35
+
36
+ def to_s
37
+ "#{major}.#{minor}.#{release}"
38
+ end
39
+ end
40
+ end