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]);
186 MODULE = Sys::Guestfs PACKAGE = Sys::Guestfs
193 RETVAL = guestfs_create ();
195 croak (\"could not create guestfs handle\");
196 guestfs_set_error_handler (RETVAL, NULL, NULL);
204 /* For the 'g' argument above we do the conversion explicitly and
205 * don't rely on the typemap, because if the handle has been
206 * explicitly closed we don't want the typemap conversion to
209 HV *hv = (HV *) SvRV (sv);
210 SV **svp = hv_fetch (hv, \"_g\", 2, 0);
212 guestfs_h *g = (guestfs_h *) SvIV (*svp);
221 /* Avoid double-free in DESTROY method. */
222 HV *hv = (HV *) SvRV (ST(0));
223 (void) hv_delete (hv, \"_g\", 2, G_DISCARD);
226 set_event_callback (g, cb, event_bitmask)
234 eh = guestfs_set_event_callback (g, _event_callback_wrapper,
235 event_bitmask, 0, cb);
237 croak (\"%%s\", guestfs_last_error (g));
239 /* Increase the refcount for this callback, since we are storing
240 * it in the opaque C libguestfs handle. We need to remember that
241 * we did this, so we can decrease the refcount for all undeleted
242 * callbacks left around at close time (see _close_handle).
246 snprintf (key, sizeof key, \"_perl_event_%%d\", eh);
247 guestfs_set_private (g, key, cb);
249 RETVAL = newSViv (eh);
254 delete_event_callback (g, event_handle)
261 snprintf (key, sizeof key, \"_perl_event_%%d\", event_handle);
262 cb = guestfs_get_private (g, key);
265 guestfs_set_private (g, key, NULL);
266 guestfs_delete_event_callback (g, event_handle);
275 errnum = guestfs_last_errno (g);
276 RETVAL = newSViv (errnum);
284 guestfs_user_cancel (g);
289 fun (name, (ret, args, optargs as style), _, _, _, _, _) ->
291 | RErr -> pr "void\n"
292 | RInt _ -> pr "SV *\n"
293 | RInt64 _ -> pr "SV *\n"
294 | RBool _ -> pr "SV *\n"
295 | RConstString _ -> pr "SV *\n"
296 | RConstOptString _ -> pr "SV *\n"
297 | RString _ -> pr "SV *\n"
298 | RBufferOut _ -> pr "SV *\n"
300 | RStruct _ | RStructList _
302 pr "void\n" (* all lists returned implictly on the stack *)
304 (* Call and arguments. *)
307 fun arg -> pr ", %s" (name_of_argt arg)
309 if optargs <> [] then
312 pr " guestfs_h *g;\n";
316 | Pathname n | Device n | Dev_or_Path n | String n
317 | FileIn n | FileOut n | Key n ->
321 pr " size_t %s_size = SvCUR (ST(%d));\n" n (i+1)
323 (* http://www.perlmonks.org/?node_id=554277
324 * Note that the implicit handle argument means we have
325 * to add 1 to the ST(x) operator.
327 pr " char *%s = SvOK(ST(%d)) ? SvPV_nolen(ST(%d)) : NULL;\n" n (i+1) (i+1)
328 | StringList n | DeviceList n -> pr " char **%s;\n" n
329 | Bool n -> pr " int %s;\n" n
330 | Int n -> pr " int %s;\n" n
331 | Int64 n -> pr " int64_t %s;\n" n
332 | Pointer (t, n) -> pr " %s %s;\n" t n
335 (* PREINIT section (local variable declarations). *)
346 pr " const char *r;\n";
347 | RConstOptString _ ->
348 pr " const char *r;\n";
351 | RStringList _ | RHashtable _ ->
353 pr " size_t i, n;\n";
354 | RStruct (_, typ) ->
355 pr " struct guestfs_%s *r;\n" typ;
356 | RStructList (_, typ) ->
357 pr " struct guestfs_%s_list *r;\n" typ;
362 pr " size_t size;\n";
365 if optargs <> [] then (
366 pr " struct guestfs_%s_argv optargs_s = { .bitmask = 0 };\n" name;
367 pr " struct guestfs_%s_argv *optargs = &optargs_s;\n" name;
368 pr " size_t items_i;\n";
371 (* CODE or PPCODE section. PPCODE is used where we are
372 * returning void, or where we push the return value on the stack
373 * ourselves. Using CODE means we will manipulate RETVAL.
385 | RConstOptString n ->
389 | RStringList n | RHashtable n ->
398 (* For optional arguments, convert these from the XSUB "items"
401 if optargs <> [] then (
402 let uc_name = String.uppercase name in
403 let skip = List.length args + 1 in
404 pr " if (((items - %d) & 1) != 0)\n" skip;
405 pr " croak (\"expecting an even number of extra parameters\");\n";
406 pr " for (items_i = %d; items_i < items; items_i += 2) {\n" skip;
407 pr " uint64_t this_mask;\n";
408 pr " const char *this_arg;\n";
410 pr " this_arg = SvPV_nolen (ST (items_i));\n";
414 let n = name_of_argt argt in
415 let uc_n = String.uppercase n in
416 pr "if (strcmp (this_arg, \"%s\") == 0) {\n" n;
417 pr " optargs_s.%s = " n;
421 | Int64 _ -> pr "SvIV (ST (items_i+1))"
422 | String _ -> pr "SvPV_nolen (ST (items_i+1))"
426 pr " this_mask = GUESTFS_%s_%s_BITMASK;\n" uc_name uc_n;
430 pr "croak (\"unknown optional argument '%%s'\", this_arg);\n";
431 pr " if (optargs_s.bitmask & this_mask)\n";
432 pr " croak (\"optional argument '%%s' given twice\",\n";
434 pr " optargs_s.bitmask |= this_mask;\n";
439 (* The call to the C function. *)
441 pr " r = guestfs_%s " name
443 pr " r = guestfs_%s_argv " name;
444 generate_c_call_args ~handle:"g" style;
447 (* Cleanup any arguments. *)
450 | Pathname _ | Device _ | Dev_or_Path _ | String _ | OptString _
451 | Bool _ | Int _ | Int64 _
452 | FileIn _ | FileOut _
453 | BufferIn _ | Key _ | Pointer _ -> ()
454 | StringList n | DeviceList n -> pr " free (%s);\n" n
457 (* Check return value for errors and return it if necessary. *)
460 pr " if (r == -1)\n";
461 pr " croak (\"%%s\", guestfs_last_error (g));\n";
464 pr " if (r == -1)\n";
465 pr " croak (\"%%s\", guestfs_last_error (g));\n";
466 pr " RETVAL = newSViv (r);\n";
470 pr " if (r == -1)\n";
471 pr " croak (\"%%s\", guestfs_last_error (g));\n";
472 pr " RETVAL = my_newSVll (r);\n";
476 pr " if (r == NULL)\n";
477 pr " croak (\"%%s\", guestfs_last_error (g));\n";
478 pr " RETVAL = newSVpv (r, 0);\n";
481 | RConstOptString n ->
482 pr " if (r == NULL)\n";
483 pr " RETVAL = &PL_sv_undef;\n";
485 pr " RETVAL = newSVpv (r, 0);\n";
489 pr " if (r == NULL)\n";
490 pr " croak (\"%%s\", guestfs_last_error (g));\n";
491 pr " RETVAL = newSVpv (r, 0);\n";
495 | RStringList n | RHashtable n ->
496 pr " if (r == NULL)\n";
497 pr " croak (\"%%s\", guestfs_last_error (g));\n";
498 pr " for (n = 0; r[n] != NULL; ++n) /**/;\n";
499 pr " EXTEND (SP, n);\n";
500 pr " for (i = 0; i < n; ++i) {\n";
501 pr " PUSHs (sv_2mortal (newSVpv (r[i], 0)));\n";
502 pr " free (r[i]);\n";
505 | RStruct (n, typ) ->
506 let cols = cols_of_struct typ in
507 generate_perl_struct_code typ cols name style n
508 | RStructList (n, typ) ->
509 let cols = cols_of_struct typ in
510 generate_perl_struct_list_code typ cols name style n
512 pr " if (r == NULL)\n";
513 pr " croak (\"%%s\", guestfs_last_error (g));\n";
514 pr " RETVAL = newSVpvn (r, size);\n";
523 and generate_perl_struct_list_code typ cols name style n =
524 pr " if (r == NULL)\n";
525 pr " croak (\"%%s\", guestfs_last_error (g));\n";
526 pr " EXTEND (SP, r->len);\n";
527 pr " for (i = 0; i < r->len; ++i) {\n";
528 pr " hv = newHV ();\n";
532 pr " (void) hv_store (hv, \"%s\", %d, newSVpv (r->val[i].%s, 0), 0);\n"
533 name (String.length name) name
535 pr " (void) hv_store (hv, \"%s\", %d, newSVpv (r->val[i].%s, 32), 0);\n"
536 name (String.length name) name
538 pr " (void) hv_store (hv, \"%s\", %d, newSVpvn (r->val[i].%s, r->val[i].%s_len), 0);\n"
539 name (String.length name) name name
540 | name, (FBytes|FUInt64) ->
541 pr " (void) hv_store (hv, \"%s\", %d, my_newSVull (r->val[i].%s), 0);\n"
542 name (String.length name) name
544 pr " (void) hv_store (hv, \"%s\", %d, my_newSVll (r->val[i].%s), 0);\n"
545 name (String.length name) name
546 | name, (FInt32|FUInt32) ->
547 pr " (void) hv_store (hv, \"%s\", %d, newSVnv (r->val[i].%s), 0);\n"
548 name (String.length name) name
550 pr " (void) hv_store (hv, \"%s\", %d, newSVpv (&r->val[i].%s, 1), 0);\n"
551 name (String.length name) name
552 | name, FOptPercent ->
553 pr " (void) hv_store (hv, \"%s\", %d, newSVnv (r->val[i].%s), 0);\n"
554 name (String.length name) name
556 pr " PUSHs (sv_2mortal (newRV ((SV *) hv)));\n";
558 pr " guestfs_free_%s_list (r);\n" typ
560 and generate_perl_struct_code typ cols name style n =
561 pr " if (r == NULL)\n";
562 pr " croak (\"%%s\", guestfs_last_error (g));\n";
563 pr " EXTEND (SP, 2 * %d);\n" (List.length cols);
565 fun ((name, _) as col) ->
566 pr " PUSHs (sv_2mortal (newSVpv (\"%s\", 0)));\n" name;
570 pr " PUSHs (sv_2mortal (newSVpv (r->%s, 0)));\n"
573 pr " PUSHs (sv_2mortal (newSVpvn (r->%s, r->%s_len)));\n"
576 pr " PUSHs (sv_2mortal (newSVpv (r->%s, 32)));\n"
578 | name, (FBytes|FUInt64) ->
579 pr " PUSHs (sv_2mortal (my_newSVull (r->%s)));\n"
582 pr " PUSHs (sv_2mortal (my_newSVll (r->%s)));\n"
584 | name, (FInt32|FUInt32) ->
585 pr " PUSHs (sv_2mortal (newSVnv (r->%s)));\n"
588 pr " PUSHs (sv_2mortal (newSVpv (&r->%s, 1)));\n"
590 | name, FOptPercent ->
591 pr " PUSHs (sv_2mortal (newSVnv (r->%s)));\n"
596 (* Generate Sys/Guestfs.pm. *)
597 and generate_perl_pm () =
598 generate_header HashStyle LGPLv2plus;
605 Sys::Guestfs - Perl bindings for libguestfs
611 my $h = Sys::Guestfs->new ();
612 $h->add_drive_opts ('guest.img', format => 'raw');
614 $h->mount_options ('', '/dev/sda1', '/');
615 $h->touch ('/hello');
620 The C<Sys::Guestfs> module provides a Perl XS binding to the
621 libguestfs API for examining and modifying virtual machine
624 Amongst the things this is good for: making batch configuration
625 changes to guests, getting disk used/free statistics (see also:
626 virt-df), migrating between virtualization systems (see also:
627 virt-p2v), performing partial backups, performing partial guest
628 clones, cloning guests and changing registry/UUID/hostname info, and
631 Libguestfs uses Linux kernel and qemu code, and can access any type of
632 guest filesystem that Linux and qemu can, including but not limited
633 to: ext2/3/4, btrfs, FAT and NTFS, LVM, many different disk partition
634 schemes, qcow, qcow2, vmdk.
636 Libguestfs provides ways to enumerate guest storage (eg. partitions,
637 LVs, what filesystem is in each LV, etc.). It can also run commands
638 in the context of the guest. Also you can access filesystems over
641 See also L<Sys::Guestfs::Lib(3)> for a set of useful library
642 functions for using libguestfs from Perl, including integration
647 All errors turn into calls to C<croak> (see L<Carp(3)>).
649 The error string from libguestfs is directly available from
650 C<$@>. Use the C<last_errno> method if you want to get the errno.
658 package Sys::Guestfs;
663 # This version number changes whenever a new function
664 # is added to the libguestfs API. It is not directly
665 # related to the libguestfs version number.
666 use vars qw($VERSION);
670 XSLoader::load ('Sys::Guestfs');
676 =item $h = Sys::Guestfs->new ();
678 Create a new guestfs handle.
684 my $class = ref ($proto) || $proto;
686 my $g = Sys::Guestfs::_create ();
687 my $self = { _g => $g };
694 Explicitly close the guestfs handle.
696 B<Note:> You should not usually call this function. The handle will
697 be closed implicitly when its reference count goes to zero (eg.
698 when it goes out of scope or the program ends). This call is
699 only required in some exceptional cases, such as where the program
700 may contain cached references to the handle 'somewhere' and you
701 really have to have the close happen right away. After calling
702 C<close> the program must not call any method (including C<close>)
703 on the handle (but the implicit call to C<DESTROY> that happens
704 when the final reference is cleaned up is OK).
709 fun (name, bitmask) ->
710 pr "=item $Sys::Guestfs::EVENT_%s\n" (String.uppercase name);
712 pr "See L<guestfs(3)/GUESTFS_EVENT_%s>.\n"
713 (String.uppercase name);
717 pr "our $EVENT_%s = 0x%x;\n" (String.uppercase name) bitmask;
722 =item $event_handle = $h->set_event_callback (\\&cb, $event_bitmask);
724 Register C<cb> as a callback function for all of the events
725 in C<$event_bitmask> (one or more C<$Sys::Guestfs::EVENT_*> flags
726 logically or'd together).
728 This function returns an event handle which
729 can be used to delete the callback using C<delete_event_callback>.
731 The callback function receives 4 parameters:
733 &cb ($event, $event_handle, $buf, $array)
739 The event which happened (equal to one of C<$Sys::Guestfs::EVENT_*>).
747 For some event types, this is a message buffer (ie. a string).
751 For some event types (notably progress events), this is
752 an array of integers.
756 You should carefully read the documentation for
757 L<guestfs(3)/guestfs_set_event_callback> before using
760 =item $h->delete_event_callback ($event_handle);
762 This removes the callback which was previously registered using
763 C<set_event_callback>.
765 =item $errnum = $h->last_errno ();
767 This returns the last error number (errno) that happened on the
770 If successful, an errno integer not equal to zero is returned.
772 If no error number is available, this returns 0.
773 See L<guestfs(3)/guestfs_last_errno> for more details of why
776 You can use the standard Perl module L<Errno(3)> to compare
777 the numeric error returned from this call with symbolic
780 $h->mkdir (\"/foo\");
781 if ($h->last_errno() == Errno::EEXIST()) {
782 # mkdir failed because the directory exists already.
785 =item $h->user_cancel ();
787 Cancel current transfer. This is safe to call from Perl signal
788 handlers and threads.
794 (* Actions. We only need to print documentation for these as
795 * they are pulled in from the XS code automatically.
798 fun (name, style, _, flags, _, _, longdesc) ->
799 if not (List.mem NotInDocs flags) then (
800 let longdesc = replace_str longdesc "C<guestfs_" "C<$h-E<gt>" in
802 generate_perl_prototype name style;
804 pr "%s\n\n" longdesc;
805 if List.mem ProtocolLimitWarning flags then
806 pr "%s\n\n" protocol_limit_warning;
807 match deprecation_notice flags with
809 | Some txt -> pr "%s\n\n" txt
811 ) all_functions_sorted;
815 (* Introspection hash. *)
816 pr "use vars qw(%%guestfs_introspection);\n";
817 pr "%%guestfs_introspection = (\n";
819 fun (name, (ret, args, optargs), _, _, _, shortdesc, _) ->
820 pr " \"%s\" => {\n" name;
823 | RErr -> pr "'void'"
824 | RInt _ -> pr "'int'"
825 | RBool _ -> pr "'bool'"
826 | RInt64 _ -> pr "'int64'"
827 | RConstString _ -> pr "'const string'"
828 | RConstOptString _ -> pr "'const nullable string'"
829 | RString _ -> pr "'string'"
830 | RStringList _ -> pr "'string list'"
831 | RHashtable _ -> pr "'hash'"
832 | RStruct (_, typ) -> pr "'struct %s'" typ
833 | RStructList (_, typ) -> pr "'struct %s list'" typ
834 | RBufferOut _ -> pr "'buffer'"
837 let pr_type i = function
838 | Pathname n -> pr "[ '%s', 'string(path)', %d ]" n i
839 | Device n -> pr "[ '%s', 'string(device)', %d ]" n i
840 | Dev_or_Path n -> pr "[ '%s', 'string(dev_or_path)', %d ]" n i
841 | String n -> pr "[ '%s', 'string', %d ]" n i
842 | FileIn n -> pr "[ '%s', 'string(filename)', %d ]" n i
843 | FileOut n -> pr "[ '%s', 'string(filename)', %d ]" n i
844 | Key n -> pr "[ '%s', 'string(key)', %d ]" n i
845 | BufferIn n -> pr "[ '%s', 'buffer', %d ]" n i
846 | OptString n -> pr "[ '%s', 'nullable string', %d ]" n i
847 | StringList n -> pr "[ '%s', 'string list', %d ]" n i
848 | DeviceList n -> pr "[ '%s', 'string(device) list', %d ]" n i
849 | Bool n -> pr "[ '%s', 'bool', %d ]" n i
850 | Int n -> pr "[ '%s', 'int', %d ]" n i
851 | Int64 n -> pr "[ '%s', 'int64', %d ]" n i
852 | Pointer (t, n) -> pr "[ '%s', 'pointer(%s)', %d ]" n t i
861 if optargs <> [] then (
862 pr " optargs => {\n";
864 pr " %s => " (name_of_argt arg);
870 pr " name => \"%s\",\n" name;
871 pr " description => %S,\n" shortdesc;
873 ) all_functions_sorted;
884 From time to time we add new libguestfs APIs. Also some libguestfs
885 APIs won't be available in all builds of libguestfs (the Fedora
886 build is full-featured, but other builds may disable features).
887 How do you test whether the APIs that your Perl program needs are
888 available in the version of C<Sys::Guestfs> that you are using?
890 To test if a particular function is available in the C<Sys::Guestfs>
891 class, use the ordinary Perl UNIVERSAL method C<can(METHOD)>
892 (see L<perlobj(1)>). For example:
895 if (defined (Sys::Guestfs->can (\"set_verbose\"))) {
896 print \"\\$h->set_verbose is available\\n\";
899 Perl does not offer a way to list the arguments of a method, and
900 from time to time we may add extra arguments to calls that take
901 optional arguments. For this reason, we provide a global hash
902 variable C<%%guestfs_introspection> which contains the arguments
903 and their types for each libguestfs method. The keys of this
904 hash are the method names, and the values are an hashref
905 containing useful introspection information about the method
906 (further fields may be added to this in future).
909 $Sys::Guestfs::guestfs_introspection{mkfs_opts}
911 ret => 'void', # return type
912 args => [ # required arguments
913 [ 'fstype', 'string', 0 ],
914 [ 'device', 'string(device)', 1 ],
916 optargs => { # optional arguments
917 blocksize => [ 'blocksize', 'int', 0 ],
918 features => [ 'features', 'string', 1 ],
919 inode => [ 'inode', 'int', 2 ],
920 sectorsize => [ 'sectorsize', 'int', 3 ],
922 name => \"mkfs_opts\",
923 description => \"make a filesystem\",
926 To test if particular features are supported by the current
927 build, use the L</available> method like the example below. Note
928 that the appliance must be launched first.
930 $h->available ( [\"augeas\"] );
932 Since the L</available> method croaks if the feature is not supported,
933 you might also want to wrap this in an eval and return a boolean.
934 In fact this has already been done for you: use
935 L<Sys::Guestfs::Lib(3)/feature_available>.
937 For further discussion on this topic, refer to
938 L<guestfs(3)/AVAILABILITY>.
940 =head1 STORING DATA IN THE HANDLE
942 The handle returned from L</new> is a hash reference. The hash
943 normally contains a single element:
946 _g => [private data used by libguestfs]
949 Callers can add other elements to this hash to store data for their own
950 purposes. The data lasts for the lifetime of the handle.
952 Any fields whose names begin with an underscore are reserved
953 for private use by libguestfs. We may add more in future.
955 It is recommended that callers prefix the name of their field(s)
956 with some unique string, to avoid conflicts with other users.
960 Copyright (C) %s Red Hat Inc.
964 Please see the file COPYING.LIB for the full license.
970 L<http://libguestfs.org>,
971 L<Sys::Guestfs::Lib(3)>.
976 and generate_perl_prototype name (ret, args, optargs) =
985 | RBufferOut n -> pr "$%s = " n
987 | RHashtable n -> pr "%%%s = " n
989 | RStructList (n,_) -> pr "@%s = " n
992 let comma = ref false in
995 if !comma then pr ", ";
998 | Pathname n | Device n | Dev_or_Path n | String n
999 | OptString n | Bool n | Int n | Int64 n | FileIn n | FileOut n
1000 | BufferIn n | Key n | Pointer (_, n) ->
1002 | StringList n | DeviceList n ->
1007 if !comma then pr " [, " else pr "[";
1009 let n = name_of_argt arg in