(* libguestfs
- * Copyright (C) 2009-2010 Red Hat Inc.
+ * Copyright (C) 2009-2011 Red Hat Inc.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
open Generator_optgroups
open Generator_actions
open Generator_structs
+open Generator_events
(* Generate C API. *)
if newline then pr "\n"
(* Generate C call arguments, eg "(handle, foo, bar)" *)
-and generate_c_call_args ?handle (ret, args, optargs) =
+and generate_c_call_args ?handle ?(implicit_size_ptr = "&size")
+ (ret, args, optargs) =
pr "(";
let comma = ref false in
let next () =
next ();
pr "%s" (name_of_argt arg)
) args;
- (* For RBufferOut calls, add implicit &size parameter. *)
+ (* For RBufferOut calls, add implicit size pointer parameter. *)
(match ret with
| RBufferOut _ ->
next ();
- pr "&size"
+ pr "%s" implicit_size_ptr
| _ -> ()
);
(* For calls with optional arguments, add implicit optargs parameter. *)
pr "This function takes a key or passphrase parameter which
could contain sensitive material. Read the section
L</KEYS AND PASSPHRASES> for more information.\n\n";
- (match deprecation_notice flags with
+ (match deprecation_notice ~prefix:"guestfs_" flags with
| None -> ()
| Some txt -> pr "%s\n\n" txt
);
#include <stdint.h>
#include <stdarg.h>
+#ifdef __GNUC__
+# define GUESTFS_GCC_VERSION \\
+ (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__)
+#endif
+
/* The handle. */
#ifndef GUESTFS_TYPEDEF_H
#define GUESTFS_TYPEDEF_H 1
extern guestfs_abort_cb guestfs_get_out_of_memory_handler (guestfs_h *g);
/* Events. */
+";
+
+ List.iter (
+ fun (name, bitmask) ->
+ pr "#define GUESTFS_EVENT_%-16s 0x%04x\n"
+ (String.uppercase name) bitmask
+ ) events;
+ pr "#define GUESTFS_EVENT_%-16s UINT64_MAX\n" "ALL";
+ pr "\n";
+
+ pr "\
+#ifndef GUESTFS_TYPEDEF_EVENT_CALLBACK
+#define GUESTFS_TYPEDEF_EVENT_CALLBACK 1
+typedef void (*guestfs_event_callback) (
+ guestfs_h *g,
+ void *opaque,
+ uint64_t event,
+ int event_handle,
+ int flags,
+ const char *buf, size_t buf_len,
+ const uint64_t *array, size_t array_len);
+#endif
+
+#define LIBGUESTFS_HAVE_SET_EVENT_CALLBACK 1
+extern int guestfs_set_event_callback (guestfs_h *g,
+ guestfs_event_callback cb,
+ uint64_t event_bitmask,
+ int flags,
+ void *opaque);
+#define LIBGUESTFS_HAVE_DELETE_EVENT_CALLBACK 1
+extern void guestfs_delete_event_callback (guestfs_h *g, int event_handle);
+
+/* Old-style event handling. In new code use guestfs_set_event_callback. */
#ifndef GUESTFS_TYPEDEF_LOG_MESSAGE_CB
#define GUESTFS_TYPEDEF_LOG_MESSAGE_CB 1
typedef void (*guestfs_log_message_cb) (guestfs_h *g, void *opaque, char *buf, int len);
extern void guestfs_set_private (guestfs_h *g, const char *key, void *data);
#define LIBGUESTFS_HAVE_GET_PRIVATE 1
extern void *guestfs_get_private (guestfs_h *g, const char *key);
+#define LIBGUESTFS_HAVE_FIRST_PRIVATE 1
+extern void *guestfs_first_private (guestfs_h *g, const char **key_rtn);
+#define LIBGUESTFS_HAVE_NEXT_PRIVATE 1
+extern void *guestfs_next_private (guestfs_h *g, const char **key_rtn);
/* Structures. */
";
~prefix:"guestfs_" ~suffix:"_argv" ~optarg_proto:Argv
shortname style;
);
+
+ pr "\n";
) all_functions_sorted;
pr "\
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
+#include <assert.h>
#include \"guestfs.h\"
#include \"guestfs-internal.h\"
return 0;
}
-";
+/* Convenience wrapper for tracing. */
+static FILE *
+trace_open (guestfs_h *g)
+{
+ assert (g->trace_fp == NULL);
+ g->trace_buf = NULL;
+ g->trace_len = 0;
+ g->trace_fp = open_memstream (&g->trace_buf, &g->trace_len);
+ if (g->trace_fp)
+ return g->trace_fp;
+ else
+ return stderr;
+}
- let error_code_of = function
- | RErr | RInt _ | RInt64 _ | RBool _ -> "-1"
- | RConstString _ | RConstOptString _
- | RString _ | RStringList _
- | RStruct _ | RStructList _
- | RHashtable _ | RBufferOut _ -> "NULL"
- in
+static void
+trace_send_line (guestfs_h *g)
+{
+ char *buf;
+ size_t len;
+
+ if (g->trace_fp) {
+ fclose (g->trace_fp);
+ g->trace_fp = NULL;
+
+ /* The callback might invoke other libguestfs calls, so keep
+ * a copy of the pointer to the buffer and length.
+ */
+ buf = g->trace_buf;
+ len = g->trace_len;
+ g->trace_buf = NULL;
+ guestfs___call_callbacks_message (g, GUESTFS_EVENT_TRACE, buf, len);
+
+ free (buf);
+ }
+}
+
+";
(* Generate code to check String-like parameters are not passed in
* as NULL (returning an error if they are).
pr " if (%s == NULL) {\n" n;
pr " error (g, \"%%s: %%s: parameter cannot be NULL\",\n";
pr " \"%s\", \"%s\");\n" shortname n;
- pr " return %s;\n" (error_code_of ret);
+ let errcode =
+ match errcode_of_ret ret with
+ | `CannotReturnError ->
+ if shortname = "test0rconstoptstring" then (* XXX hack *)
+ `ErrorIsNULL
+ else
+ failwithf
+ "%s: RConstOptString function has invalid parameter '%s'"
+ shortname n
+ | (`ErrorIsMinusOne |`ErrorIsNULL) as e -> e in
+ pr " return %s;\n" (string_of_errcode errcode);
pr " }\n";
pr_newline := true
pr " optargs->%s == NULL) {\n" n;
pr " error (g, \"%%s: %%s: optional parameter cannot be NULL\",\n";
pr " \"%s\", \"%s\");\n" shortname n;
- pr " return %s;\n" (error_code_of ret);
+ let errcode =
+ match errcode_of_ret ret with
+ | `CannotReturnError -> assert false
+ | (`ErrorIsMinusOne |`ErrorIsNULL) as e -> e in
+ pr " return %s;\n" (string_of_errcode errcode);
pr " }\n";
pr_newline := true
pr " if (optargs->bitmask & UINT64_C(0x%Lx)) {\n" mask;
pr " error (g, \"%%s: unknown option in guestfs_%%s_argv->bitmask (this can happen if a program is compiled against a newer version of libguestfs, then dynamically linked to an older version)\",\n";
pr " \"%s\", \"%s\");\n" shortname shortname;
- pr " return %s;\n" (error_code_of ret);
+ let errcode =
+ match errcode_of_ret ret with
+ | `CannotReturnError -> assert false
+ | (`ErrorIsMinusOne |`ErrorIsNULL) as e -> e in
+ pr " return %s;\n" (string_of_errcode errcode);
pr " }\n";
pr "\n";
in
pr "\n"
);
- pr " fprintf (stderr, \"%s\");\n" shortname;
+ pr " trace_fp = trace_open (g);\n";
+
+ pr " fprintf (trace_fp, \"%%s\", \"%s\");\n" shortname;
(* Required arguments. *)
List.iter (
| FileIn n
| FileOut n ->
(* guestfish doesn't support string escaping, so neither do we *)
- pr " fprintf (stderr, \" \\\"%%s\\\"\", %s);\n" n
+ pr " fprintf (trace_fp, \" \\\"%%s\\\"\", %s);\n" n
| Key n ->
(* don't print keys *)
- pr " fprintf (stderr, \" \\\"***\\\"\");\n"
+ pr " fprintf (trace_fp, \" \\\"***\\\"\");\n"
| OptString n -> (* string option *)
- pr " if (%s) fprintf (stderr, \" \\\"%%s\\\"\", %s);\n" n n;
- pr " else fprintf (stderr, \" null\");\n"
+ pr " if (%s) fprintf (trace_fp, \" \\\"%%s\\\"\", %s);\n" n n;
+ pr " else fprintf (trace_fp, \" null\");\n"
| StringList n
| DeviceList n -> (* string list *)
- pr " fputc (' ', stderr);\n";
- pr " fputc ('\"', stderr);\n";
+ pr " fputc (' ', trace_fp);\n";
+ pr " fputc ('\"', trace_fp);\n";
pr " for (i = 0; %s[i]; ++i) {\n" n;
- pr " if (i > 0) fputc (' ', stderr);\n";
- pr " fputs (%s[i], stderr);\n" n;
+ pr " if (i > 0) fputc (' ', trace_fp);\n";
+ pr " fputs (%s[i], trace_fp);\n" n;
pr " }\n";
- pr " fputc ('\"', stderr);\n";
+ pr " fputc ('\"', trace_fp);\n";
| Bool n -> (* boolean *)
- pr " fputs (%s ? \" true\" : \" false\", stderr);\n" n
+ pr " fputs (%s ? \" true\" : \" false\", trace_fp);\n" n
| Int n -> (* int *)
- pr " fprintf (stderr, \" %%d\", %s);\n" n
+ pr " fprintf (trace_fp, \" %%d\", %s);\n" n
| Int64 n ->
- pr " fprintf (stderr, \" %%\" PRIi64, %s);\n" n
+ pr " fprintf (trace_fp, \" %%\" PRIi64, %s);\n" n
| BufferIn n -> (* RHBZ#646822 *)
- pr " fputc (' ', stderr);\n";
- pr " guestfs___print_BufferIn (stderr, %s, %s_size);\n" n n
+ pr " fputc (' ', trace_fp);\n";
+ pr " guestfs___print_BufferIn (trace_fp, %s, %s_size);\n" n n
| Pointer (t, n) ->
- pr " fprintf (stderr, \" (%s)%%p\", %s);\n" t n
+ pr " fprintf (trace_fp, \" (%s)%%p\", %s);\n" t n
) args;
(* Optional arguments. *)
uc_shortname uc_n;
(match argt with
| String n ->
- pr " fprintf (stderr, \" \\\"%%s:%%s\\\"\", \"%s\", optargs->%s);\n" n n
+ pr " fprintf (trace_fp, \" \\\"%%s:%%s\\\"\", \"%s\", optargs->%s);\n" n n
| Bool n ->
- pr " fprintf (stderr, \" \\\"%%s:%%s\\\"\", \"%s\", optargs->%s ? \"true\" : \"false\");\n" n n
+ pr " fprintf (trace_fp, \" \\\"%%s:%%s\\\"\", \"%s\", optargs->%s ? \"true\" : \"false\");\n" n n
| Int n ->
- pr " fprintf (stderr, \" \\\"%%s:%%d\\\"\", \"%s\", optargs->%s);\n" n n
+ pr " fprintf (trace_fp, \" \\\"%%s:%%d\\\"\", \"%s\", optargs->%s);\n" n n
| Int64 n ->
- pr " fprintf (stderr, \" \\\"%%s:%%\" PRIi64 \"\\\"\", \"%s\", optargs->%s);\n" n n
+ pr " fprintf (trace_fp, \" \\\"%%s:%%\" PRIi64 \"\\\"\", \"%s\", optargs->%s);\n" n n
| _ -> assert false
);
) optargs;
+ pr " trace_send_line (g);\n";
pr " }\n";
pr "\n";
in
- let trace_return ?(indent = 2) (ret, _, _) rv =
+ let trace_return ?(indent = 2) shortname (ret, _, _) rv =
let indent = spaces indent in
pr "%sif (trace_flag) {\n" indent;
pr "\n"
);
- pr "%s fputs (\" = \", stderr);\n" indent;
+ pr "%s trace_fp = trace_open (g);\n" indent;
+
+ pr "%s fprintf (trace_fp, \"%%s = \", \"%s\");\n" indent shortname;
+
(match ret with
| RErr | RInt _ | RBool _ ->
- pr "%s fprintf (stderr, \"%%d\", %s);\n" indent rv
+ pr "%s fprintf (trace_fp, \"%%d\", %s);\n" indent rv
| RInt64 _ ->
- pr "%s fprintf (stderr, \"%%\" PRIi64, %s);\n" indent rv
+ pr "%s fprintf (trace_fp, \"%%\" PRIi64, %s);\n" indent rv
| RConstString _ | RString _ ->
- pr "%s fprintf (stderr, \"\\\"%%s\\\"\", %s);\n" indent rv
+ pr "%s fprintf (trace_fp, \"\\\"%%s\\\"\", %s);\n" indent rv
| RConstOptString _ ->
- pr "%s fprintf (stderr, \"\\\"%%s\\\"\", %s != NULL ? %s : \"NULL\");\n"
+ pr "%s fprintf (trace_fp, \"\\\"%%s\\\"\", %s != NULL ? %s : \"NULL\");\n"
indent rv rv
| RBufferOut _ ->
- pr "%s guestfs___print_BufferOut (stderr, %s, *size_r);\n" indent rv
+ pr "%s guestfs___print_BufferOut (trace_fp, %s, *size_r);\n" indent rv
| RStringList _ | RHashtable _ ->
- pr "%s fputs (\"[\\\"\", stderr);\n" indent;
+ pr "%s fputs (\"[\", trace_fp);\n" indent;
pr "%s for (i = 0; %s[i]; ++i) {\n" indent rv;
- pr "%s if (i > 0) fputs (\"\\\", \\\"\", stderr);\n" indent;
- pr "%s fputs (%s[i], stderr);\n" indent rv;
+ pr "%s if (i > 0) fputs (\", \", trace_fp);\n" indent;
+ pr "%s fputs (\"\\\"\", trace_fp);\n" indent;
+ pr "%s fputs (%s[i], trace_fp);\n" indent rv;
+ pr "%s fputs (\"\\\"\", trace_fp);\n" indent;
pr "%s }\n" indent;
- pr "%s fputs (\"\\\"]\", stderr);\n" indent;
+ pr "%s fputs (\"]\", trace_fp);\n" indent;
| RStruct (_, typ) ->
(* XXX There is code generated for guestfish for printing
* these structures. We need to make it generally available
* for all callers
*)
- pr "%s fprintf (stderr, \"<struct guestfs_%s *>\");\n"
+ pr "%s fprintf (trace_fp, \"<struct guestfs_%s *>\");\n"
indent typ (* XXX *)
| RStructList (_, typ) ->
- pr "%s fprintf (stderr, \"<struct guestfs_%s_list *>\");\n"
+ pr "%s fprintf (trace_fp, \"<struct guestfs_%s_list *>\");\n"
indent typ (* XXX *)
);
- pr "%s fputc ('\\n', stderr);\n" indent;
+ pr "%s trace_send_line (g);\n" indent;
pr "%s}\n" indent;
pr "\n";
in
- let trace_return_error ?(indent = 2) (ret, _, _) =
+ let trace_return_error ?(indent = 2) shortname (ret, _, _) errcode =
let indent = spaces indent in
pr "%sif (trace_flag)\n" indent;
- (match ret with
- | RErr | RInt _ | RBool _
- | RInt64 _ ->
- pr "%s fputs (\" = -1 (error)\\n\", stderr);\n" indent
- | RConstString _ | RString _
- | RConstOptString _
- | RBufferOut _
- | RStringList _ | RHashtable _
- | RStruct _
- | RStructList _ ->
- pr "%s fputs (\" = NULL (error)\\n\", stderr);\n" indent
- );
+ pr "%s guestfs___trace (g, \"%%s = %%s (error)\",\n" indent;
+ pr "%s \"%s\", \"%s\");\n"
+ indent shortname (string_of_errcode errcode)
in
(* For non-daemon functions, generate a wrapper around each function. *)
shortname style;
pr "{\n";
pr " int trace_flag = g->trace;\n";
+ pr " FILE *trace_fp;\n";
(match ret with
| RErr | RInt _ | RBool _ ->
pr " int r;\n"
| RInt64 _ ->
pr " int64_t r;\n"
- | RConstString _ | RConstOptString _ ->
+ | RConstString _ ->
+ pr " const char *r;\n"
+ | RConstOptString _ ->
pr " const char *r;\n"
| RString _ | RBufferOut _ ->
pr " char *r;\n"
reject_unknown_optargs shortname style;
trace_call shortname style;
pr " r = guestfs__%s " shortname;
- generate_c_call_args ~handle:"g" style;
+ generate_c_call_args ~handle:"g" ~implicit_size_ptr:"size_r" style;
pr ";\n";
- trace_return style "r";
+ pr "\n";
+ (match errcode_of_ret ret with
+ | (`ErrorIsMinusOne | `ErrorIsNULL) as errcode ->
+ pr " if (r != %s) {\n" (string_of_errcode errcode);
+ trace_return ~indent:4 shortname style "r";
+ pr " } else {\n";
+ trace_return_error ~indent:4 shortname style errcode;
+ pr " }\n";
+ | `CannotReturnError ->
+ trace_return shortname style "r";
+ );
+ pr "\n";
pr " return r;\n";
pr "}\n";
pr "\n"
List.iter (
fun (shortname, (ret, args, optargs as style), _, _, _, _, _) ->
let name = "guestfs_" ^ shortname in
- let error_code = error_code_of ret in
+ let errcode =
+ match errcode_of_ret ret with
+ | `CannotReturnError -> assert false
+ | (`ErrorIsMinusOne | `ErrorIsNULL) as e -> e in
(* Generate the action stub. *)
if optargs = [] then
pr " int serial;\n";
pr " int r;\n";
pr " int trace_flag = g->trace;\n";
+ pr " FILE *trace_fp;\n";
(match ret with
| RErr | RInt _ | RBool _ ->
pr " int ret_v;\n"
(* Check we are in the right state for sending a request. *)
pr " if (check_state (g, \"%s\") == -1) {\n" shortname;
- trace_return_error ~indent:4 style;
- pr " return %s;\n" error_code;
+ trace_return_error ~indent:4 shortname style errcode;
+ pr " return %s;\n" (string_of_errcode errcode);
pr " }\n";
pr " guestfs___set_busy (g);\n";
pr "\n";
| BufferIn n ->
pr " /* Just catch grossly large sizes. XDR encoding will make this precise. */\n";
pr " if (%s_size >= GUESTFS_MESSAGE_MAX) {\n" n;
- trace_return_error ~indent:4 style;
+ trace_return_error ~indent:4 shortname style errcode;
pr " error (g, \"%%s: size of input buffer too large\", \"%s\");\n"
shortname;
pr " guestfs___end_busy (g);\n";
- pr " return %s;\n" error_code;
+ pr " return %s;\n" (string_of_errcode errcode);
pr " }\n";
pr " args.%s.%s_val = (char *) %s;\n" n n n;
pr " args.%s.%s_len = %s_size;\n" n n n
pr " else\n";
pr " args.%s = 0;\n" n
| String n ->
- pr " args.%s = (char *) %s;\n" n n;
+ pr " args.%s = (char *) optargs->%s;\n" n n;
pr " else\n";
pr " args.%s = (char *) \"\";\n" n
| _ -> assert false
);
pr " if (serial == -1) {\n";
pr " guestfs___end_busy (g);\n";
- trace_return_error ~indent:4 style;
- pr " return %s;\n" error_code;
+ trace_return_error ~indent:4 shortname style errcode;
+ pr " return %s;\n" (string_of_errcode errcode);
pr " }\n";
pr "\n";
pr " r = guestfs___send_file (g, %s);\n" n;
pr " if (r == -1) {\n";
pr " guestfs___end_busy (g);\n";
- trace_return_error ~indent:4 style;
- pr " return %s;\n" error_code;
+ trace_return_error ~indent:4 shortname style errcode;
+ pr " /* daemon will send an error reply which we discard */\n";
+ pr " guestfs___recv_discard (g, \"%s\");\n" shortname;
+ pr " return %s;\n" (string_of_errcode errcode);
pr " }\n";
pr " if (r == -2) /* daemon cancelled */\n";
pr " goto read_reply;\n";
pr " if (r == -1) {\n";
pr " guestfs___end_busy (g);\n";
- trace_return_error ~indent:4 style;
- pr " return %s;\n" error_code;
+ trace_return_error ~indent:4 shortname style errcode;
+ pr " return %s;\n" (string_of_errcode errcode);
pr " }\n";
pr "\n";
pr " if (check_reply_header (g, &hdr, GUESTFS_PROC_%s, serial) == -1) {\n"
(String.uppercase shortname);
pr " guestfs___end_busy (g);\n";
- trace_return_error ~indent:4 style;
- pr " return %s;\n" error_code;
+ trace_return_error ~indent:4 shortname style errcode;
+ pr " return %s;\n" (string_of_errcode errcode);
pr " }\n";
pr "\n";
pr " if (hdr.status == GUESTFS_STATUS_ERROR) {\n";
- trace_return_error ~indent:4 style;
+ trace_return_error ~indent:4 shortname style errcode;
pr " int errnum = 0;\n";
pr " if (err.errno_string[0] != '\\0')\n";
pr " errnum = guestfs___string_to_errno (err.errno_string);\n";
pr " free (err.error_message);\n";
pr " free (err.errno_string);\n";
pr " guestfs___end_busy (g);\n";
- pr " return %s;\n" error_code;
+ pr " return %s;\n" (string_of_errcode errcode);
pr " }\n";
pr "\n";
| FileOut n ->
pr " if (guestfs___recv_file (g, %s) == -1) {\n" n;
pr " guestfs___end_busy (g);\n";
- trace_return_error ~indent:4 style;
- pr " return %s;\n" error_code;
+ trace_return_error ~indent:4 shortname style errcode;
+ pr " return %s;\n" (string_of_errcode errcode);
pr " }\n";
pr "\n";
| _ -> ()
pr " ret_v = p;\n";
pr " }\n";
);
- trace_return style "ret_v";
+ trace_return shortname style "ret_v";
pr " return ret_v;\n";
pr "}\n\n"
) daemon_functions;
(* Get the name of the last regular argument. *)
let last_arg =
- match args with
- | [] -> "g"
- | args -> name_of_argt (List.hd (List.rev args)) in
+ match ret with
+ | RBufferOut _ -> "size_r"
+ | _ ->
+ match args with
+ | [] -> "g"
+ | args -> name_of_argt (List.hd (List.rev args)) in
- let rerrcode, rtype =
+ let rtype =
match ret with
- | RErr | RInt _ | RBool _ -> "-1", "int "
- | RInt64 _ -> "-1", "int64_t "
- | RConstString _ | RConstOptString _ -> "NULL", "const char *"
- | RString _ | RBufferOut _ -> "NULL", "char *"
- | RStringList _ | RHashtable _ -> "NULL", "char **"
- | RStruct (_, typ) -> "NULL", sprintf "struct guestfs_%s *" typ
+ | RErr | RInt _ | RBool _ -> "int "
+ | RInt64 _ -> "int64_t "
+ | RConstString _ | RConstOptString _ -> "const char *"
+ | RString _ | RBufferOut _ -> "char *"
+ | RStringList _ | RHashtable _ -> "char **"
+ | RStruct (_, typ) -> sprintf "struct guestfs_%s *" typ
| RStructList (_, typ) ->
- "NULL", sprintf "struct guestfs_%s_list *" typ in
+ sprintf "struct guestfs_%s_list *" typ in
(* The regular variable args function, just calls the _va variant. *)
generate_prototype ~extern:false ~semicolon:false ~newline:true
pr "\n";
pr " va_start (optargs, %s);\n" last_arg;
pr " %sr = guestfs_%s_va " rtype shortname;
- generate_c_call_args ~handle:"g" style;
+ generate_c_call_args ~handle:"g" ~implicit_size_ptr:"size_r" style;
pr ";\n";
pr " va_end (optargs);\n";
pr "\n";
pr " break;\n";
) optargs;
+ let errcode =
+ match errcode_of_ret ret with
+ | `CannotReturnError -> assert false
+ | (`ErrorIsMinusOne | `ErrorIsNULL) as e -> e in
+
pr " default:\n";
pr " error (g, \"%%s: unknown option %%d (this can happen if a program is compiled against a newer version of libguestfs, then dynamically linked to an older version)\",\n";
pr " \"%s\", i);\n" shortname;
- pr " return %s;\n" rerrcode;
+ pr " return %s;\n" (string_of_errcode errcode);
pr " }\n";
pr "\n";
pr " uint64_t i_mask = UINT64_C(1) << i;\n";
pr " if (optargs_s.bitmask & i_mask) {\n";
pr " error (g, \"%%s: same optional argument specified more than once\",\n";
pr " \"%s\");\n" shortname;
- pr " return %s;\n" rerrcode;
+ pr " return %s;\n" (string_of_errcode errcode);
pr " }\n";
pr " optargs_s.bitmask |= i_mask;\n";
pr " }\n";
pr "\n";
pr " return guestfs_%s_argv " shortname;
- generate_c_call_args ~handle:"g" style;
+ generate_c_call_args ~handle:"g" ~implicit_size_ptr:"size_r" style;
pr ";\n";
pr "}\n\n"
| _ -> ()
let globals = [
"guestfs_create";
"guestfs_close";
+ "guestfs_delete_event_callback";
+ "guestfs_first_private";
"guestfs_get_error_handler";
"guestfs_get_out_of_memory_handler";
"guestfs_get_private";
"guestfs_last_errno";
"guestfs_last_error";
+ "guestfs_next_private";
"guestfs_set_close_callback";
"guestfs_set_error_handler";
+ "guestfs_set_event_callback";
"guestfs_set_launch_done_callback";
"guestfs_set_log_message_callback";
"guestfs_set_out_of_memory_handler";