X-Git-Url: http://git.annexia.org/?p=libguestfs.git;a=blobdiff_plain;f=generator%2Fgenerator_ruby.ml;h=1f75b46012c91138655aba833b2e826d23cead00;hp=a21334a0c8ea4cd2fdfcc16e6c8598ed28bcb00c;hb=0a7b734d2f54d4e98882532da9887feb66c9824a;hpb=1e9e351f178dcb425c4796c90fe7c8c5c250d100 diff --git a/generator/generator_ruby.ml b/generator/generator_ruby.ml index a21334a..1f75b46 100644 --- a/generator/generator_ruby.ml +++ b/generator/generator_ruby.ml @@ -50,6 +50,15 @@ let rec generate_ruby_c () = #define RARRAY_LEN(r) (RARRAY((r))->len) #endif +/* For Ruby < 1.8 */ +#ifndef RSTRING_LEN +#define RSTRING_LEN(r) (RSTRING((r))->len) +#endif + +#ifndef RSTRING_PTR +#define RSTRING_PTR(r) (RSTRING((r))->ptr) +#endif + static VALUE m_guestfs; /* guestfs module */ static VALUE c_guestfs; /* guestfs_h handle */ static VALUE e_Error; /* used for all errors */ @@ -84,6 +93,7 @@ ruby_guestfs_free (void *gvp) rb_gc_unregister_address (roots[i]); free (roots[i]); } + free (roots); } } @@ -214,7 +224,8 @@ ruby_event_callback_wrapper (guestfs_h *g, const uint64_t *array, size_t array_len) { size_t i; - VALUE eventv, event_handlev, bufv, arrayv, argv; + VALUE eventv, event_handlev, bufv, arrayv; + VALUE argv[5]; eventv = ULL2NUM (event); event_handlev = INT2NUM (event_handle); @@ -225,35 +236,41 @@ ruby_event_callback_wrapper (guestfs_h *g, for (i = 0; i < array_len; ++i) rb_ary_push (arrayv, ULL2NUM (array[i])); - /* Wrap up the arguments in an array which will be unpacked - * and passed as multiple arguments. This is a crap limitation - * of rb_rescue. + /* This is a crap limitation of rb_rescue. * http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/~poffice/mail/ruby-talk/65698 */ - argv = rb_ary_new2 (5); - rb_ary_store (argv, 0, * (VALUE *) data /* function */); - rb_ary_store (argv, 1, eventv); - rb_ary_store (argv, 2, event_handlev); - rb_ary_store (argv, 3, bufv); - rb_ary_store (argv, 4, arrayv); - - rb_rescue (ruby_event_callback_wrapper_wrapper, argv, + argv[0] = * (VALUE *) data; /* function */ + argv[1] = eventv; + argv[2] = event_handlev; + argv[3] = bufv; + argv[4] = arrayv; + + rb_rescue (ruby_event_callback_wrapper_wrapper, (VALUE) argv, ruby_event_callback_handle_exception, Qnil); } static VALUE -ruby_event_callback_wrapper_wrapper (VALUE argv) +ruby_event_callback_wrapper_wrapper (VALUE argvv) { + VALUE *argv = (VALUE *) argvv; VALUE fn, eventv, event_handlev, bufv, arrayv; - fn = rb_ary_entry (argv, 0); - eventv = rb_ary_entry (argv, 1); - event_handlev = rb_ary_entry (argv, 2); - bufv = rb_ary_entry (argv, 3); - arrayv = rb_ary_entry (argv, 4); + fn = argv[0]; - rb_funcall (fn, rb_intern (\"call\"), 4, - eventv, event_handlev, bufv, arrayv); + /* Check the Ruby callback still exists. For reasons which are not + * fully understood, even though we registered this as a global root, + * it is still possible for the callback to go away (fn value remains + * but its type changes from T_DATA to T_NONE). (RHBZ#733297) + */ + if (rb_type (fn) != T_NONE) { + eventv = argv[1]; + event_handlev = argv[2]; + bufv = argv[3]; + arrayv = argv[4]; + + rb_funcall (fn, rb_intern (\"call\"), 4, + eventv, event_handlev, bufv, arrayv); + } return Qnil; } @@ -264,7 +281,7 @@ ruby_event_callback_handle_exception (VALUE not_used, VALUE exn) /* Callbacks aren't supposed to throw exceptions. The best we * can do is to print the error. */ - fprintf (stderr, \"libguestfs: exception in callback: %%s\", + fprintf (stderr, \"libguestfs: exception in callback: %%s\\n\", StringValueCStr (exn)); return Qnil; @@ -339,10 +356,6 @@ ruby_user_cancel (VALUE gv) doc ^ "\n\n" ^ protocol_limit_warning else doc in let doc = - if List.mem DangerWillRobinson flags then - doc ^ "\n\n" ^ danger_will_robinson - else doc in - let doc = match deprecation_notice flags with | None -> doc | Some txt -> doc ^ "\n\n" ^ txt in @@ -413,11 +426,11 @@ ruby_user_cancel (VALUE gv) pr " const char *%s = StringValueCStr (%sv);\n" n n; | BufferIn n -> pr " Check_Type (%sv, T_STRING);\n" n; - pr " const char *%s = RSTRING (%sv)->ptr;\n" n n; + pr " const char *%s = RSTRING_PTR (%sv);\n" n n; pr " if (!%s)\n" n; pr " rb_raise (rb_eTypeError, \"expected string for parameter %%s of %%s\",\n"; pr " \"%s\", \"%s\");\n" n name; - pr " size_t %s_size = RSTRING (%sv)->len;\n" n n + pr " size_t %s_size = RSTRING_LEN (%sv);\n" n n | OptString n -> pr " const char *%s = !NIL_P (%sv) ? StringValueCStr (%sv) : NULL;\n" n n n | StringList n | DeviceList n -> @@ -454,20 +467,19 @@ ruby_user_cancel (VALUE gv) pr " VALUE v;\n"; List.iter ( fun argt -> - let n = name_of_argt argt in + let n = name_of_optargt argt in let uc_n = String.uppercase n in pr " v = rb_hash_lookup (optargsv, ID2SYM (rb_intern (\"%s\")));\n" n; pr " if (v != Qnil) {\n"; (match argt with - | Bool n -> + | OBool n -> pr " optargs_s.%s = RTEST (v);\n" n; - | Int n -> + | OInt n -> pr " optargs_s.%s = NUM2INT (v);\n" n; - | Int64 n -> + | OInt64 n -> pr " optargs_s.%s = NUM2LL (v);\n" n; - | String _ -> + | OString _ -> pr " optargs_s.%s = StringValueCStr (v);\n" n - | _ -> assert false ); pr " optargs_s.bitmask |= GUESTFS_%s_%s_BITMASK;\n" uc_name uc_n; pr " }\n";