let c_type =
match argt with
| Bool n -> "int "
- | Int n -> "int64_t "
- | Int64 n -> "int "
+ | Int n -> "int "
+ | Int64 n -> "int64_t "
| String n -> "const char *"
| _ -> assert false (* checked in generator_checks *) in
let uc_shortname = String.uppercase shortname in
extern void *guestfs_safe_malloc (guestfs_h *g, size_t nbytes);
extern void *guestfs_safe_calloc (guestfs_h *g, size_t n, size_t s);
extern const char *guestfs_tmpdir (void);
+#ifdef GUESTFS_PRIVATE_FOR_EACH_DISK
+extern int guestfs___for_each_disk (guestfs_h *g, virDomainPtr dom, int (*)(guestfs_h *g, const char *filename, const char *format, void *data), void *data);
+#endif
/* End of private functions. */
#ifdef __cplusplus
#include <stdint.h>
#include <string.h>
#include <inttypes.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/stat.h>
#include \"guestfs.h\"
#include \"guestfs-internal.h\"
let needs_i =
match ret with
- | RStringList _ | RHashtable _ | RStructList _ -> true
+ | RStringList _ | RHashtable _ -> true
| _ -> false in
if needs_i then (
pr "%s size_t i;\n" indent;
(* Client-side stubs for each function. *)
List.iter (
fun (shortname, (ret, args, optargs as style), _, _, _, _, _) ->
- if optargs <> [] then
- failwithf "optargs not yet implemented for daemon functions";
-
let name = "guestfs_" ^ shortname in
let error_code = error_code_of ret in
(* Generate the action stub. *)
if optargs = [] then
generate_prototype ~extern:false ~semicolon:false ~newline:true
- ~handle:"g" name style
+ ~handle:"g" ~prefix:"guestfs_" shortname style
else
generate_prototype ~extern:false ~semicolon:false ~newline:true
- ~handle:"g" ~suffix:"_argv" ~optarg_proto:Argv name style;
+ ~handle:"g" ~prefix:"guestfs_" ~suffix:"_argv"
+ ~optarg_proto:Argv shortname style;
pr "{\n";
| RStructList (_, typ) ->
pr " struct guestfs_%s_list *ret_v;\n" typ
);
+
+ let has_filein =
+ List.exists (function FileIn _ -> true | _ -> false) args in
+ if has_filein then (
+ pr " uint64_t progress_hint = 0;\n";
+ pr " struct stat progress_stat;\n";
+ ) else
+ pr " const uint64_t progress_hint = 0;\n";
+
pr "\n";
check_null_strings shortname style;
reject_unknown_optargs shortname style;
trace_call shortname style;
+
+ (* Calculate the total size of all FileIn arguments to pass
+ * as a progress bar hint.
+ *)
+ List.iter (
+ function
+ | FileIn n ->
+ pr " if (stat (%s, &progress_stat) == 0 &&\n" n;
+ pr " S_ISREG (progress_stat.st_mode))\n";
+ pr " progress_hint += progress_stat.st_size;\n";
+ pr "\n";
+ | _ -> ()
+ ) args;
+
+ (* 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;
pr "\n";
(* Send the main header and arguments. *)
- (match args with
- | [] ->
- pr " serial = guestfs___send (g, GUESTFS_PROC_%s, NULL, NULL);\n"
- (String.uppercase shortname)
- | args ->
- List.iter (
- function
- | Pathname n | Device n | Dev_or_Path n | String n | Key n ->
- pr " args.%s = (char *) %s;\n" n n
- | OptString n ->
- pr " args.%s = %s ? (char **) &%s : NULL;\n" n n n
- | StringList n | DeviceList n ->
- pr " args.%s.%s_val = (char **) %s;\n" n n n;
- pr " for (args.%s.%s_len = 0; %s[args.%s.%s_len]; args.%s.%s_len++) ;\n" n n n n n n n;
- | Bool n ->
- pr " args.%s = %s;\n" n n
- | Int n ->
- pr " args.%s = %s;\n" n n
+ if args = [] && optargs = [] then (
+ pr " serial = guestfs___send (g, GUESTFS_PROC_%s, progress_hint, 0,\n"
+ (String.uppercase shortname);
+ pr " NULL, NULL);\n"
+ ) else (
+ List.iter (
+ function
+ | Pathname n | Device n | Dev_or_Path n | String n | Key n ->
+ pr " args.%s = (char *) %s;\n" n n
+ | OptString n ->
+ pr " args.%s = %s ? (char **) &%s : NULL;\n" n n n
+ | StringList n | DeviceList n ->
+ pr " args.%s.%s_val = (char **) %s;\n" n n n;
+ pr " for (args.%s.%s_len = 0; %s[args.%s.%s_len]; args.%s.%s_len++) ;\n" n n n n n n n;
+ | Bool n ->
+ pr " args.%s = %s;\n" n n
+ | Int n ->
+ pr " args.%s = %s;\n" n n
+ | Int64 n ->
+ pr " args.%s = %s;\n" n n
+ | FileIn _ | FileOut _ -> ()
+ | 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;
+ 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 " }\n";
+ pr " args.%s.%s_val = (char *) %s;\n" n n n;
+ pr " args.%s.%s_len = %s_size;\n" n n n
+ | Pointer _ -> assert false
+ ) args;
+
+ List.iter (
+ fun argt ->
+ let n = name_of_argt argt in
+ let uc_shortname = String.uppercase shortname in
+ let uc_n = String.uppercase n in
+ pr " if ((optargs->bitmask & GUESTFS_%s_%s_BITMASK))\n"
+ uc_shortname uc_n;
+ (match argt with
+ | Bool n
+ | Int n
| Int64 n ->
- pr " args.%s = %s;\n" n n
- | FileIn _ | FileOut _ -> ()
- | 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;
- 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 " }\n";
- pr " args.%s.%s_val = (char *) %s;\n" n n n;
- pr " args.%s.%s_len = %s_size;\n" n n n
- | Pointer _ -> assert false
- ) args;
- pr " serial = guestfs___send (g, GUESTFS_PROC_%s,\n"
- (String.uppercase shortname);
- pr " (xdrproc_t) xdr_%s_args, (char *) &args);\n"
- name;
+ pr " args.%s = optargs->%s;\n" n n;
+ pr " else\n";
+ pr " args.%s = 0;\n" n
+ | String n ->
+ pr " args.%s = (char *) %s;\n" n n;
+ pr " else\n";
+ pr " args.%s = (char *) \"\";\n" n
+ | _ -> assert false
+ )
+ ) optargs;
+
+ pr " serial = guestfs___send (g, GUESTFS_PROC_%s,\n"
+ (String.uppercase shortname);
+ pr " progress_hint, %s,\n"
+ (if optargs <> [] then "optargs->bitmask" else "0");
+ pr " (xdrproc_t) xdr_%s_args, (char *) &args);\n"
+ name;
);
pr " if (serial == -1) {\n";
pr " guestfs___end_busy (g);\n";
"guestfs_safe_strdup";
"guestfs_safe_memdup";
"guestfs_tmpdir";
+ "guestfs___for_each_disk";
] in
let functions =
List.flatten (