2 * Copyright (C) 2009-2011 Red Hat Inc.
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19 (* Please read generator/README first. *)
26 open Generator_docstrings
27 open Generator_optgroups
28 open Generator_actions
29 open Generator_structs
33 (* Generate Perl xs code, a sort of crazy variation of C with macros. *)
34 let rec generate_perl_xs () =
35 generate_header CStyle LGPLv2plus;
45 #define PRId64 \"lld\"
49 my_newSVll(long long val) {
55 len = snprintf(buf, 100, \"%%\" PRId64, val);
56 return newSVpv(buf, len);
61 #define PRIu64 \"llu\"
65 my_newSVull(unsigned long long val) {
71 len = snprintf(buf, 100, \"%%\" PRIu64, val);
72 return newSVpv(buf, len);
76 /* http://www.perlmonks.org/?node_id=680842 */
78 XS_unpack_charPtrPtr (SV *arg) {
83 if (!arg || !SvOK (arg) || !SvROK (arg) || SvTYPE (SvRV (arg)) != SVt_PVAV)
84 croak (\"array reference expected\");
86 av = (AV *)SvRV (arg);
87 ret = malloc ((av_len (av) + 1 + 1) * sizeof (char *));
89 croak (\"malloc failed\");
91 for (i = 0; i <= av_len (av); i++) {
92 SV **elem = av_fetch (av, i, 0);
95 croak (\"missing element in list\");
97 ret[i] = SvPV_nolen (*elem);
105 /* http://www.perlmonks.org/?node=338857 */
107 _event_callback_wrapper (guestfs_h *g,
112 const char *buf, size_t buf_len,
113 const uint64_t *array, size_t array_len)
119 XPUSHs (sv_2mortal (my_newSVull (event)));
120 XPUSHs (sv_2mortal (newSViv (event_handle)));
121 XPUSHs (sv_2mortal (newSVpvn (buf ? buf : \"\", buf_len)));
124 for (i = 0; i < array_len; ++i)
125 av_push (av, my_newSVull (array[i]));
126 XPUSHs (sv_2mortal (newRV ((SV *) av)));
128 call_sv ((SV *) cb, G_VOID | G_DISCARD | G_EVAL);
134 get_all_event_callbacks (guestfs_h *g, size_t *len_rtn)
141 /* Count the length of the array that will be needed. */
143 cb = guestfs_first_private (g, &key);
145 if (strncmp (key, \"_perl_event_\", strlen (\"_perl_event_\")) == 0)
147 cb = guestfs_next_private (g, &key);
150 /* Copy them into the return array. */
151 r = guestfs_safe_malloc (g, sizeof (SV *) * (*len_rtn));
154 cb = guestfs_first_private (g, &key);
156 if (strncmp (key, \"_perl_event_\", strlen (\"_perl_event_\")) == 0) {
160 cb = guestfs_next_private (g, &key);
167 _close_handle (guestfs_h *g)
174 /* As in the OCaml bindings, there is a hard to solve case where the
175 * caller can delete a callback from within the callback, resulting
176 * in a double-free here. XXX
178 cbs = get_all_event_callbacks (g, &len);
182 for (i = 0; i < len; ++i)
183 SvREFCNT_dec (cbs[i]);
187 MODULE = Sys::Guestfs PACKAGE = Sys::Guestfs
194 RETVAL = guestfs_create ();
196 croak (\"could not create guestfs handle\");
197 guestfs_set_error_handler (RETVAL, NULL, NULL);
205 /* For the 'g' argument above we do the conversion explicitly and
206 * don't rely on the typemap, because if the handle has been
207 * explicitly closed we don't want the typemap conversion to
210 HV *hv = (HV *) SvRV (sv);
211 SV **svp = hv_fetch (hv, \"_g\", 2, 0);
213 guestfs_h *g = (guestfs_h *) SvIV (*svp);
222 /* Avoid double-free in DESTROY method. */
223 HV *hv = (HV *) SvRV (ST(0));
224 (void) hv_delete (hv, \"_g\", 2, G_DISCARD);
227 set_event_callback (g, cb, event_bitmask)
235 eh = guestfs_set_event_callback (g, _event_callback_wrapper,
236 event_bitmask, 0, cb);
238 croak (\"%%s\", guestfs_last_error (g));
240 /* Increase the refcount for this callback, since we are storing
241 * it in the opaque C libguestfs handle. We need to remember that
242 * we did this, so we can decrease the refcount for all undeleted
243 * callbacks left around at close time (see _close_handle).
247 snprintf (key, sizeof key, \"_perl_event_%%d\", eh);
248 guestfs_set_private (g, key, cb);
250 RETVAL = newSViv (eh);
255 delete_event_callback (g, event_handle)
262 snprintf (key, sizeof key, \"_perl_event_%%d\", event_handle);
263 cb = guestfs_get_private (g, key);
266 guestfs_set_private (g, key, NULL);
267 guestfs_delete_event_callback (g, event_handle);
276 errnum = guestfs_last_errno (g);
277 RETVAL = newSViv (errnum);
285 guestfs_user_cancel (g);
290 fun (name, (ret, args, optargs as style), _, _, _, _, _) ->
292 | RErr -> pr "void\n"
293 | RInt _ -> pr "SV *\n"
294 | RInt64 _ -> pr "SV *\n"
295 | RBool _ -> pr "SV *\n"
296 | RConstString _ -> pr "SV *\n"
297 | RConstOptString _ -> pr "SV *\n"
298 | RString _ -> pr "SV *\n"
299 | RBufferOut _ -> pr "SV *\n"
301 | RStruct _ | RStructList _
303 pr "void\n" (* all lists returned implictly on the stack *)
305 (* Call and arguments. *)
308 fun arg -> pr ", %s" (name_of_argt arg)
310 if optargs <> [] then
313 pr " guestfs_h *g;\n";
317 | Pathname n | Device n | Dev_or_Path n | String n
318 | FileIn n | FileOut n | Key n ->
322 pr " size_t %s_size = SvCUR (ST(%d));\n" n (i+1)
324 (* http://www.perlmonks.org/?node_id=554277
325 * Note that the implicit handle argument means we have
326 * to add 1 to the ST(x) operator.
328 pr " char *%s = SvOK(ST(%d)) ? SvPV_nolen(ST(%d)) : NULL;\n" n (i+1) (i+1)
329 | StringList n | DeviceList n -> pr " char **%s;\n" n
330 | Bool n -> pr " int %s;\n" n
331 | Int n -> pr " int %s;\n" n
332 | Int64 n -> pr " int64_t %s;\n" n
333 | Pointer (t, n) -> pr " %s %s;\n" t n
336 (* PREINIT section (local variable declarations). *)
347 pr " const char *r;\n";
348 | RConstOptString _ ->
349 pr " const char *r;\n";
352 | RStringList _ | RHashtable _ ->
354 pr " size_t i, n;\n";
355 | RStruct (_, typ) ->
356 pr " struct guestfs_%s *r;\n" typ;
357 | RStructList (_, typ) ->
358 pr " struct guestfs_%s_list *r;\n" typ;
363 pr " size_t size;\n";
366 if optargs <> [] then (
367 pr " struct guestfs_%s_argv optargs_s = { .bitmask = 0 };\n" name;
368 pr " struct guestfs_%s_argv *optargs = &optargs_s;\n" name;
369 pr " size_t items_i;\n";
372 (* CODE or PPCODE section. PPCODE is used where we are
373 * returning void, or where we push the return value on the stack
374 * ourselves. Using CODE means we will manipulate RETVAL.
386 | RConstOptString n ->
390 | RStringList n | RHashtable n ->
399 (* For optional arguments, convert these from the XSUB "items"
402 if optargs <> [] then (
403 let uc_name = String.uppercase name in
404 let skip = List.length args + 1 in
405 pr " if (((items - %d) & 1) != 0)\n" skip;
406 pr " croak (\"expecting an even number of extra parameters\");\n";
407 pr " for (items_i = %d; items_i < items; items_i += 2) {\n" skip;
408 pr " uint64_t this_mask;\n";
409 pr " const char *this_arg;\n";
411 pr " this_arg = SvPV_nolen (ST (items_i));\n";
415 let n = name_of_argt argt in
416 let uc_n = String.uppercase n in
417 pr "if (strcmp (this_arg, \"%s\") == 0) {\n" n;
418 pr " optargs_s.%s = " n;
422 | Int64 _ -> pr "SvIV (ST (items_i+1))"
423 | String _ -> pr "SvPV_nolen (ST (items_i+1))"
427 pr " this_mask = GUESTFS_%s_%s_BITMASK;\n" uc_name uc_n;
431 pr "croak (\"unknown optional argument '%%s'\", this_arg);\n";
432 pr " if (optargs_s.bitmask & this_mask)\n";
433 pr " croak (\"optional argument '%%s' given twice\",\n";
435 pr " optargs_s.bitmask |= this_mask;\n";
440 (* The call to the C function. *)
442 pr " r = guestfs_%s " name
444 pr " r = guestfs_%s_argv " name;
445 generate_c_call_args ~handle:"g" style;
448 (* Cleanup any arguments. *)
451 | Pathname _ | Device _ | Dev_or_Path _ | String _ | OptString _
452 | Bool _ | Int _ | Int64 _
453 | FileIn _ | FileOut _
454 | BufferIn _ | Key _ | Pointer _ -> ()
455 | StringList n | DeviceList n -> pr " free (%s);\n" n
458 (* Check return value for errors and return it if necessary. *)
461 pr " if (r == -1)\n";
462 pr " croak (\"%%s\", guestfs_last_error (g));\n";
465 pr " if (r == -1)\n";
466 pr " croak (\"%%s\", guestfs_last_error (g));\n";
467 pr " RETVAL = newSViv (r);\n";
471 pr " if (r == -1)\n";
472 pr " croak (\"%%s\", guestfs_last_error (g));\n";
473 pr " RETVAL = my_newSVll (r);\n";
477 pr " if (r == NULL)\n";
478 pr " croak (\"%%s\", guestfs_last_error (g));\n";
479 pr " RETVAL = newSVpv (r, 0);\n";
482 | RConstOptString n ->
483 pr " if (r == NULL)\n";
484 pr " RETVAL = &PL_sv_undef;\n";
486 pr " RETVAL = newSVpv (r, 0);\n";
490 pr " if (r == NULL)\n";
491 pr " croak (\"%%s\", guestfs_last_error (g));\n";
492 pr " RETVAL = newSVpv (r, 0);\n";
496 | RStringList n | RHashtable n ->
497 pr " if (r == NULL)\n";
498 pr " croak (\"%%s\", guestfs_last_error (g));\n";
499 pr " for (n = 0; r[n] != NULL; ++n) /**/;\n";
500 pr " EXTEND (SP, n);\n";
501 pr " for (i = 0; i < n; ++i) {\n";
502 pr " PUSHs (sv_2mortal (newSVpv (r[i], 0)));\n";
503 pr " free (r[i]);\n";
506 | RStruct (n, typ) ->
507 let cols = cols_of_struct typ in
508 generate_perl_struct_code typ cols name style n
509 | RStructList (n, typ) ->
510 let cols = cols_of_struct typ in
511 generate_perl_struct_list_code typ cols name style n
513 pr " if (r == NULL)\n";
514 pr " croak (\"%%s\", guestfs_last_error (g));\n";
515 pr " RETVAL = newSVpvn (r, size);\n";
524 and generate_perl_struct_list_code typ cols name style n =
525 pr " if (r == NULL)\n";
526 pr " croak (\"%%s\", guestfs_last_error (g));\n";
527 pr " EXTEND (SP, r->len);\n";
528 pr " for (i = 0; i < r->len; ++i) {\n";
529 pr " hv = newHV ();\n";
533 pr " (void) hv_store (hv, \"%s\", %d, newSVpv (r->val[i].%s, 0), 0);\n"
534 name (String.length name) name
536 pr " (void) hv_store (hv, \"%s\", %d, newSVpv (r->val[i].%s, 32), 0);\n"
537 name (String.length name) name
539 pr " (void) hv_store (hv, \"%s\", %d, newSVpvn (r->val[i].%s, r->val[i].%s_len), 0);\n"
540 name (String.length name) name name
541 | name, (FBytes|FUInt64) ->
542 pr " (void) hv_store (hv, \"%s\", %d, my_newSVull (r->val[i].%s), 0);\n"
543 name (String.length name) name
545 pr " (void) hv_store (hv, \"%s\", %d, my_newSVll (r->val[i].%s), 0);\n"
546 name (String.length name) name
547 | name, (FInt32|FUInt32) ->
548 pr " (void) hv_store (hv, \"%s\", %d, newSVnv (r->val[i].%s), 0);\n"
549 name (String.length name) name
551 pr " (void) hv_store (hv, \"%s\", %d, newSVpv (&r->val[i].%s, 1), 0);\n"
552 name (String.length name) name
553 | name, FOptPercent ->
554 pr " (void) hv_store (hv, \"%s\", %d, newSVnv (r->val[i].%s), 0);\n"
555 name (String.length name) name
557 pr " PUSHs (sv_2mortal (newRV ((SV *) hv)));\n";
559 pr " guestfs_free_%s_list (r);\n" typ
561 and generate_perl_struct_code typ cols name style n =
562 pr " if (r == NULL)\n";
563 pr " croak (\"%%s\", guestfs_last_error (g));\n";
564 pr " EXTEND (SP, 2 * %d);\n" (List.length cols);
566 fun ((name, _) as col) ->
567 pr " PUSHs (sv_2mortal (newSVpv (\"%s\", 0)));\n" name;
571 pr " PUSHs (sv_2mortal (newSVpv (r->%s, 0)));\n"
574 pr " PUSHs (sv_2mortal (newSVpvn (r->%s, r->%s_len)));\n"
577 pr " PUSHs (sv_2mortal (newSVpv (r->%s, 32)));\n"
579 | name, (FBytes|FUInt64) ->
580 pr " PUSHs (sv_2mortal (my_newSVull (r->%s)));\n"
583 pr " PUSHs (sv_2mortal (my_newSVll (r->%s)));\n"
585 | name, (FInt32|FUInt32) ->
586 pr " PUSHs (sv_2mortal (newSVnv (r->%s)));\n"
589 pr " PUSHs (sv_2mortal (newSVpv (&r->%s, 1)));\n"
591 | name, FOptPercent ->
592 pr " PUSHs (sv_2mortal (newSVnv (r->%s)));\n"
597 (* Generate Sys/Guestfs.pm. *)
598 and generate_perl_pm () =
599 generate_header HashStyle LGPLv2plus;
606 Sys::Guestfs - Perl bindings for libguestfs
612 my $h = Sys::Guestfs->new ();
613 $h->add_drive_opts ('guest.img', format => 'raw');
615 $h->mount_options ('', '/dev/sda1', '/');
616 $h->touch ('/hello');
621 The C<Sys::Guestfs> module provides a Perl XS binding to the
622 libguestfs API for examining and modifying virtual machine
625 Amongst the things this is good for: making batch configuration
626 changes to guests, getting disk used/free statistics (see also:
627 virt-df), migrating between virtualization systems (see also:
628 virt-p2v), performing partial backups, performing partial guest
629 clones, cloning guests and changing registry/UUID/hostname info, and
632 Libguestfs uses Linux kernel and qemu code, and can access any type of
633 guest filesystem that Linux and qemu can, including but not limited
634 to: ext2/3/4, btrfs, FAT and NTFS, LVM, many different disk partition
635 schemes, qcow, qcow2, vmdk.
637 Libguestfs provides ways to enumerate guest storage (eg. partitions,
638 LVs, what filesystem is in each LV, etc.). It can also run commands
639 in the context of the guest. Also you can access filesystems over
642 See also L<Sys::Guestfs::Lib(3)> for a set of useful library
643 functions for using libguestfs from Perl, including integration
648 All errors turn into calls to C<croak> (see L<Carp(3)>).
650 The error string from libguestfs is directly available from
651 C<$@>. Use the C<last_errno> method if you want to get the errno.
659 package Sys::Guestfs;
664 # This version number changes whenever a new function
665 # is added to the libguestfs API. It is not directly
666 # related to the libguestfs version number.
667 use vars qw($VERSION);
671 XSLoader::load ('Sys::Guestfs');
677 =item $h = Sys::Guestfs->new ();
679 Create a new guestfs handle.
685 my $class = ref ($proto) || $proto;
687 my $g = Sys::Guestfs::_create ();
688 my $self = { _g => $g };
695 Explicitly close the guestfs handle.
697 B<Note:> You should not usually call this function. The handle will
698 be closed implicitly when its reference count goes to zero (eg.
699 when it goes out of scope or the program ends). This call is
700 only required in some exceptional cases, such as where the program
701 may contain cached references to the handle 'somewhere' and you
702 really have to have the close happen right away. After calling
703 C<close> the program must not call any method (including C<close>)
704 on the handle (but the implicit call to C<DESTROY> that happens
705 when the final reference is cleaned up is OK).
710 fun (name, bitmask) ->
711 pr "=item $Sys::Guestfs::EVENT_%s\n" (String.uppercase name);
713 pr "See L<guestfs(3)/GUESTFS_EVENT_%s>.\n"
714 (String.uppercase name);
718 pr "our $EVENT_%s = 0x%x;\n" (String.uppercase name) bitmask;
723 =item $event_handle = $h->set_event_callback (\\&cb, $event_bitmask);
725 Register C<cb> as a callback function for all of the events
726 in C<$event_bitmask> (one or more C<$Sys::Guestfs::EVENT_*> flags
727 logically or'd together).
729 This function returns an event handle which
730 can be used to delete the callback using C<delete_event_callback>.
732 The callback function receives 4 parameters:
734 &cb ($event, $event_handle, $buf, $array)
740 The event which happened (equal to one of C<$Sys::Guestfs::EVENT_*>).
748 For some event types, this is a message buffer (ie. a string).
752 For some event types (notably progress events), this is
753 an array of integers.
757 You should carefully read the documentation for
758 L<guestfs(3)/guestfs_set_event_callback> before using
761 =item $h->delete_event_callback ($event_handle);
763 This removes the callback which was previously registered using
764 C<set_event_callback>.
766 =item $errnum = $h->last_errno ();
768 This returns the last error number (errno) that happened on the
771 If successful, an errno integer not equal to zero is returned.
773 If no error number is available, this returns 0.
774 See L<guestfs(3)/guestfs_last_errno> for more details of why
777 You can use the standard Perl module L<Errno(3)> to compare
778 the numeric error returned from this call with symbolic
781 $h->mkdir (\"/foo\");
782 if ($h->last_errno() == Errno::EEXIST()) {
783 # mkdir failed because the directory exists already.
786 =item $h->user_cancel ();
788 Cancel current transfer. This is safe to call from Perl signal
789 handlers and threads.
795 (* Actions. We only need to print documentation for these as
796 * they are pulled in from the XS code automatically.
799 fun (name, style, _, flags, _, _, longdesc) ->
800 if not (List.mem NotInDocs flags) then (
801 let longdesc = replace_str longdesc "C<guestfs_" "C<$h-E<gt>" in
803 generate_perl_prototype name style;
805 pr "%s\n\n" longdesc;
806 if List.mem ProtocolLimitWarning flags then
807 pr "%s\n\n" protocol_limit_warning;
808 match deprecation_notice flags with
810 | Some txt -> pr "%s\n\n" txt
812 ) all_functions_sorted;
816 (* Introspection hash. *)
817 pr "use vars qw(%%guestfs_introspection);\n";
818 pr "%%guestfs_introspection = (\n";
820 fun (name, (ret, args, optargs), _, _, _, shortdesc, _) ->
821 pr " \"%s\" => {\n" name;
824 | RErr -> pr "'void'"
825 | RInt _ -> pr "'int'"
826 | RBool _ -> pr "'bool'"
827 | RInt64 _ -> pr "'int64'"
828 | RConstString _ -> pr "'const string'"
829 | RConstOptString _ -> pr "'const nullable string'"
830 | RString _ -> pr "'string'"
831 | RStringList _ -> pr "'string list'"
832 | RHashtable _ -> pr "'hash'"
833 | RStruct (_, typ) -> pr "'struct %s'" typ
834 | RStructList (_, typ) -> pr "'struct %s list'" typ
835 | RBufferOut _ -> pr "'buffer'"
838 let pr_type i = function
839 | Pathname n -> pr "[ '%s', 'string(path)', %d ]" n i
840 | Device n -> pr "[ '%s', 'string(device)', %d ]" n i
841 | Dev_or_Path n -> pr "[ '%s', 'string(dev_or_path)', %d ]" n i
842 | String n -> pr "[ '%s', 'string', %d ]" n i
843 | FileIn n -> pr "[ '%s', 'string(filename)', %d ]" n i
844 | FileOut n -> pr "[ '%s', 'string(filename)', %d ]" n i
845 | Key n -> pr "[ '%s', 'string(key)', %d ]" n i
846 | BufferIn n -> pr "[ '%s', 'buffer', %d ]" n i
847 | OptString n -> pr "[ '%s', 'nullable string', %d ]" n i
848 | StringList n -> pr "[ '%s', 'string list', %d ]" n i
849 | DeviceList n -> pr "[ '%s', 'string(device) list', %d ]" n i
850 | Bool n -> pr "[ '%s', 'bool', %d ]" n i
851 | Int n -> pr "[ '%s', 'int', %d ]" n i
852 | Int64 n -> pr "[ '%s', 'int64', %d ]" n i
853 | Pointer (t, n) -> pr "[ '%s', 'pointer(%s)', %d ]" n t i
862 if optargs <> [] then (
863 pr " optargs => {\n";
865 pr " %s => " (name_of_argt arg);
871 pr " name => \"%s\",\n" name;
872 pr " description => %S,\n" shortdesc;
874 ) all_functions_sorted;
885 From time to time we add new libguestfs APIs. Also some libguestfs
886 APIs won't be available in all builds of libguestfs (the Fedora
887 build is full-featured, but other builds may disable features).
888 How do you test whether the APIs that your Perl program needs are
889 available in the version of C<Sys::Guestfs> that you are using?
891 To test if a particular function is available in the C<Sys::Guestfs>
892 class, use the ordinary Perl UNIVERSAL method C<can(METHOD)>
893 (see L<perlobj(1)>). For example:
896 if (defined (Sys::Guestfs->can (\"set_verbose\"))) {
897 print \"\\$h->set_verbose is available\\n\";
900 Perl does not offer a way to list the arguments of a method, and
901 from time to time we may add extra arguments to calls that take
902 optional arguments. For this reason, we provide a global hash
903 variable C<%%guestfs_introspection> which contains the arguments
904 and their types for each libguestfs method. The keys of this
905 hash are the method names, and the values are an hashref
906 containing useful introspection information about the method
907 (further fields may be added to this in future).
910 $Sys::Guestfs::guestfs_introspection{mkfs_opts}
912 ret => 'void', # return type
913 args => [ # required arguments
914 [ 'fstype', 'string', 0 ],
915 [ 'device', 'string(device)', 1 ],
917 optargs => { # optional arguments
918 blocksize => [ 'blocksize', 'int', 0 ],
919 features => [ 'features', 'string', 1 ],
920 inode => [ 'inode', 'int', 2 ],
921 sectorsize => [ 'sectorsize', 'int', 3 ],
923 name => \"mkfs_opts\",
924 description => \"make a filesystem\",
927 To test if particular features are supported by the current
928 build, use the L</available> method like the example below. Note
929 that the appliance must be launched first.
931 $h->available ( [\"augeas\"] );
933 Since the L</available> method croaks if the feature is not supported,
934 you might also want to wrap this in an eval and return a boolean.
935 In fact this has already been done for you: use
936 L<Sys::Guestfs::Lib(3)/feature_available>.
938 For further discussion on this topic, refer to
939 L<guestfs(3)/AVAILABILITY>.
941 =head1 STORING DATA IN THE HANDLE
943 The handle returned from L</new> is a hash reference. The hash
944 normally contains a single element:
947 _g => [private data used by libguestfs]
950 Callers can add other elements to this hash to store data for their own
951 purposes. The data lasts for the lifetime of the handle.
953 Any fields whose names begin with an underscore are reserved
954 for private use by libguestfs. We may add more in future.
956 It is recommended that callers prefix the name of their field(s)
957 with some unique string, to avoid conflicts with other users.
961 Copyright (C) %s Red Hat Inc.
965 Please see the file COPYING.LIB for the full license.
971 L<http://libguestfs.org>,
972 L<Sys::Guestfs::Lib(3)>.
977 and generate_perl_prototype name (ret, args, optargs) =
986 | RBufferOut n -> pr "$%s = " n
988 | RHashtable n -> pr "%%%s = " n
990 | RStructList (n,_) -> pr "@%s = " n
993 let comma = ref false in
996 if !comma then pr ", ";
999 | Pathname n | Device n | Dev_or_Path n | String n
1000 | OptString n | Bool n | Int n | Int64 n | FileIn n | FileOut n
1001 | BufferIn n | Key n | Pointer (_, n) ->
1003 | StringList n | DeviceList n ->
1008 if !comma then pr " [, " else pr "[";
1010 let n = name_of_argt arg in