2 * Copyright (C) 2008 Martin Willi
3 * Hochschule fuer Technik Rapperswil
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License as published by the
7 * Free Software Foundation; either version 2 of the License, or (at your
8 * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
10 * This program is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
12 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
25 #undef PACKAGE_TARNAME
26 #undef PACKAGE_VERSION
38 * Guest invocation callback
40 static pid_t
invoke(void *null
, guest_t
*guest
, char *args
[], int argc
)
44 args
[argc
] = "con0=xterm";
50 dup2(open("/dev/null", 0), 1);
51 dup2(open("/dev/null", 0), 2);
52 execvp(args
[0], args
);
55 rb_raise(rb_eException
, "starting guest failed");
63 * SIGCHLD signal handler
65 static void sigchld_handler(int signal
, siginfo_t
*info
, void* ptr
)
67 enumerator_t
*enumerator
;
70 enumerator
= dumm
->create_guest_enumerator(dumm
);
71 while (enumerator
->enumerate(enumerator
, &guest
))
73 if (guest
->get_pid(guest
) == info
->si_pid
)
75 guest
->sigchild(guest
);
79 enumerator
->destroy(enumerator
);
85 static VALUE
guest_get(VALUE
class, VALUE key
)
87 enumerator_t
*enumerator
;
88 guest_t
*guest
, *found
= NULL
;
90 enumerator
= dumm
->create_guest_enumerator(dumm
);
91 while (enumerator
->enumerate(enumerator
, &guest
))
93 if (streq(guest
->get_name(guest
), StringValuePtr(key
)))
99 enumerator
->destroy(enumerator
);
104 return Data_Wrap_Struct(class, NULL
, NULL
, found
);
107 static VALUE
guest_each(int argc
, VALUE
*argv
, VALUE
class)
109 enumerator_t
*enumerator
;
112 if (!rb_block_given_p())
114 rb_raise(rb_eArgError
, "must be called with a block");
116 enumerator
= dumm
->create_guest_enumerator(dumm
);
117 while (enumerator
->enumerate(enumerator
, &guest
))
119 rb_yield(Data_Wrap_Struct(class, NULL
, NULL
, guest
));
121 enumerator
->destroy(enumerator
);
125 static VALUE
guest_new(VALUE
class, VALUE name
, VALUE kernel
,
126 VALUE master
, VALUE mem
)
131 guest
= dumm
->create_guest(dumm
, StringValuePtr(name
), StringValuePtr(kernel
),
132 StringValuePtr(master
), FIX2INT(mem
));
137 return Data_Wrap_Struct(class, NULL
, NULL
, guest
);
140 static VALUE
guest_to_s(VALUE self
)
144 Data_Get_Struct(self
, guest_t
, guest
);
145 return rb_str_new2(guest
->get_name(guest
));
148 static VALUE
guest_start(VALUE self
)
152 Data_Get_Struct(self
, guest_t
, guest
);
154 if (guest
->start(guest
, invoke
, NULL
, NULL
))
161 static VALUE
guest_stop(VALUE self
)
165 Data_Get_Struct(self
, guest_t
, guest
);
167 if (guest
->stop(guest
, NULL
))
174 static VALUE
guest_add_iface(VALUE self
, VALUE name
)
179 Data_Get_Struct(self
, guest_t
, guest
);
180 iface
= guest
->create_iface(guest
, StringValuePtr(name
));
183 return Data_Wrap_Struct(rbc_iface
, NULL
, NULL
, iface
);
188 static VALUE
guest_get_iface(VALUE self
, VALUE key
)
190 enumerator_t
*enumerator
;
191 iface_t
*iface
, *found
= NULL
;
194 Data_Get_Struct(self
, guest_t
, guest
);
195 enumerator
= guest
->create_iface_enumerator(guest
);
196 while (enumerator
->enumerate(enumerator
, &iface
))
198 if (streq(iface
->get_guestif(iface
), StringValuePtr(key
)))
204 enumerator
->destroy(enumerator
);
209 return Data_Wrap_Struct(rbc_iface
, NULL
, NULL
, iface
);
212 static VALUE
guest_each_iface(int argc
, VALUE
*argv
, VALUE self
)
214 enumerator_t
*enumerator
;
218 if (!rb_block_given_p())
220 rb_raise(rb_eArgError
, "must be called with a block");
222 Data_Get_Struct(self
, guest_t
, guest
);
223 enumerator
= guest
->create_iface_enumerator(guest
);
224 while (enumerator
->enumerate(enumerator
, &iface
))
226 rb_yield(Data_Wrap_Struct(rbc_iface
, NULL
, NULL
, iface
));
228 enumerator
->destroy(enumerator
);
232 static VALUE
guest_delete(VALUE self
)
236 Data_Get_Struct(self
, guest_t
, guest
);
237 dumm
->delete_guest(dumm
, guest
);
241 static void guest_init()
243 rbc_guest
= rb_define_class_under(rbm_dumm
, "Guest", rb_cObject
);
244 rb_define_singleton_method(rbc_guest
, "[]", guest_get
, 1);
245 rb_define_singleton_method(rbc_guest
, "each", guest_each
, -1);
246 rb_define_singleton_method(rbc_guest
, "new", guest_new
, 4);
247 rb_define_method(rbc_guest
, "to_s", guest_to_s
, 0);
248 rb_define_method(rbc_guest
, "start", guest_start
, 0);
249 rb_define_method(rbc_guest
, "stop", guest_stop
, 0);
250 rb_define_method(rbc_guest
, "add", guest_add_iface
, 1);
251 rb_define_method(rbc_guest
, "[]", guest_get_iface
, 1);
252 rb_define_method(rbc_guest
, "each", guest_each_iface
, -1);
253 rb_define_method(rbc_guest
, "delete", guest_delete
, 0);
259 static VALUE
bridge_get(VALUE
class, VALUE key
)
261 enumerator_t
*enumerator
;
262 bridge_t
*bridge
, *found
= NULL
;
264 enumerator
= dumm
->create_bridge_enumerator(dumm
);
265 while (enumerator
->enumerate(enumerator
, &bridge
))
267 if (streq(bridge
->get_name(bridge
), StringValuePtr(key
)))
273 enumerator
->destroy(enumerator
);
278 return Data_Wrap_Struct(class, NULL
, NULL
, found
);
281 static VALUE
bridge_each(int argc
, VALUE
*argv
, VALUE
class)
283 enumerator_t
*enumerator
;
286 if (!rb_block_given_p())
288 rb_raise(rb_eArgError
, "must be called with a block");
290 enumerator
= dumm
->create_bridge_enumerator(dumm
);
291 while (enumerator
->enumerate(enumerator
, &bridge
))
293 rb_yield(Data_Wrap_Struct(class, NULL
, NULL
, bridge
));
295 enumerator
->destroy(enumerator
);
299 static VALUE
bridge_new(VALUE
class, VALUE name
)
304 bridge
= dumm
->create_bridge(dumm
, StringValuePtr(name
));
309 return Data_Wrap_Struct(class, NULL
, NULL
, bridge
);
312 static VALUE
bridge_to_s(VALUE self
)
316 Data_Get_Struct(self
, bridge_t
, bridge
);
317 return rb_str_new2(bridge
->get_name(bridge
));
320 static VALUE
bridge_each_iface(int argc
, VALUE
*argv
, VALUE self
)
322 enumerator_t
*enumerator
;
326 if (!rb_block_given_p())
328 rb_raise(rb_eArgError
, "must be called with a block");
330 Data_Get_Struct(self
, bridge_t
, bridge
);
331 enumerator
= bridge
->create_iface_enumerator(bridge
);
332 while (enumerator
->enumerate(enumerator
, &iface
))
334 rb_yield(Data_Wrap_Struct(rbc_iface
, NULL
, NULL
, iface
));
336 enumerator
->destroy(enumerator
);
340 static VALUE
bridge_delete(VALUE self
)
344 Data_Get_Struct(self
, bridge_t
, bridge
);
345 dumm
->delete_bridge(dumm
, bridge
);
349 static void bridge_init()
351 rbc_bridge
= rb_define_class_under(rbm_dumm
, "Bridge", rb_cObject
);
352 rb_define_singleton_method(rbc_bridge
, "[]", bridge_get
, 1);
353 rb_define_singleton_method(rbc_bridge
, "each", bridge_each
, -1);
354 rb_define_singleton_method(rbc_bridge
, "new", bridge_new
, 1);
355 rb_define_method(rbc_bridge
, "to_s", bridge_to_s
, 0);
356 rb_define_method(rbc_bridge
, "each", bridge_each_iface
, -1);
357 rb_define_method(rbc_bridge
, "delete", bridge_delete
, 0);
363 static VALUE
iface_to_s(VALUE self
)
367 Data_Get_Struct(self
, iface_t
, iface
);
368 return rb_str_new2(iface
->get_hostif(iface
));
371 static VALUE
iface_connect(VALUE self
, VALUE vbridge
)
376 Data_Get_Struct(self
, iface_t
, iface
);
377 Data_Get_Struct(vbridge
, bridge_t
, bridge
);
378 if (bridge
->connect_iface(bridge
, iface
))
385 static VALUE
iface_disconnect(VALUE self
)
390 Data_Get_Struct(self
, iface_t
, iface
);
391 bridge
= iface
->get_bridge(iface
);
392 if (bridge
&& bridge
->disconnect_iface(bridge
, iface
))
399 static VALUE
iface_delete(VALUE self
)
404 Data_Get_Struct(self
, iface_t
, iface
);
405 guest
= iface
->get_guest(iface
);
406 guest
->destroy_iface(guest
, iface
);
410 static void iface_init()
412 rbc_iface
= rb_define_class_under(rbm_dumm
, "Iface", rb_cObject
);
413 rb_define_method(rbc_iface
, "to_s", iface_to_s
, 0);
414 rb_define_method(rbc_iface
, "connect", iface_connect
, 1);
415 rb_define_method(rbc_iface
, "disconnect", iface_disconnect
, 0);
416 rb_define_method(rbc_iface
, "delete", iface_delete
, 0);
420 * main routine, parses args and reads from console
422 int main(int argc
, char *argv
[])
425 struct sigaction action
;
428 ruby_init_loadpath();
430 /* there are to many to report, rubyruby... */
431 setenv("LEAK_DETECTIVE_DISABLE", "1", 1);
435 dumm
= dumm_create(NULL
);
437 rbm_dumm
= rb_define_module("Dumm");
443 sigemptyset(&action
.sa_mask
);
444 action
.sa_sigaction
= sigchld_handler
;
445 action
.sa_flags
= SA_SIGINFO
;
446 sigaction(SIGCHLD
, &action
, NULL
);
449 rb_eval_string_protect("include Dumm", &state
);
450 rb_eval_string_protect("IRB.start", &state
);
458 action
.sa_handler
= SIG_DFL
;
460 sigaction(SIGCHLD
, &action
, NULL
);