X-Git-Url: http://git.annexia.org/?p=libguestfs.git;a=blobdiff_plain;f=src%2Fgenerator.ml;h=b8add4c0362244316a8628e6aafe16992bdbf162;hp=179665bc506a09002d4eb5b3bae347b6e5374c9e;hb=2eb19f526164a978c373a760deb30854d56b62ce;hpb=0a0d743ba80e33e676084f2a254c63d4188857b0 diff --git a/src/generator.ml b/src/generator.ml index 179665b..b8add4c 100755 --- a/src/generator.ml +++ b/src/generator.ml @@ -142,6 +142,7 @@ and argt = | DeviceList of string(* list of Device names (each cannot be NULL) *) | Bool of string (* boolean *) | Int of string (* int (smallish ints, signed, <= 31 bits) *) + | Int64 of string (* any 64 bit int *) (* These are treated as filenames (simple string parameters) in * the C API and bindings. But in the RPC protocol, we transfer * the actual file content up to or down from the daemon. @@ -364,6 +365,7 @@ let test_all_args = [ StringList "strlist"; Bool "b"; Int "integer"; + Int64 "integer64"; FileIn "filein"; FileOut "fileout"; ] @@ -440,13 +442,18 @@ You should call this after configuring the handle ("wait_ready", (RErr, []), -1, [NotInFish], [], - "wait until the qemu subprocess launches", + "wait until the qemu subprocess launches (no op)", "\ -Internally libguestfs is implemented by running a virtual machine -using L. +This function is a no op. -You should call this after C to wait for the launch -to complete."); +In versions of the API E 1.0.71 you had to call this function +just after calling C to wait for the launch +to complete. However this is no longer necessary because +C now does the waiting. + +If you see any calls to this function in code then you can just +remove them, unless you want to retain compatibility with older +versions of the API."); ("kill_subprocess", (RErr, []), -1, [], [], @@ -803,6 +810,31 @@ C is defined and set to C<1>."); "\ Return the command trace flag."); + ("set_direct", (RErr, [Bool "direct"]), -1, [FishAlias "direct"], + [InitNone, Always, TestOutputFalse ( + [["set_direct"; "false"]; + ["get_direct"]])], + "enable or disable direct appliance mode", + "\ +If the direct appliance mode flag is enabled, then stdin and +stdout are passed directly through to the appliance once it +is launched. + +One consequence of this is that log messages aren't caught +by the library and handled by C, +but go straight to stdout. + +You probably don't want to use this unless you know what you +are doing. + +The default is disabled."); + + ("get_direct", (RBool "direct", []), -1, [], + [], + "get direct appliance mode flag", + "\ +Return the direct appliance mode flag."); + ] (* daemon_functions are any functions which cause some action @@ -2458,7 +2490,7 @@ C sometimes gives an error about this and sometimes not. In any case, it is always safe to call C before calling this function."); - ("find", (RStringList "names", [Pathname "directory"]), 107, [], + ("find", (RStringList "names", [Pathname "directory"]), 107, [ProtocolLimitWarning], [InitBasicFS, Always, TestOutputList ( [["find"; "/"]], ["lost+found"]); InitBasicFS, Always, TestOutputList ( @@ -2495,7 +2527,9 @@ then the returned list from C C would be If C is not a directory, then this command returns an error. -The returned list is sorted."); +The returned list is sorted. + +See also C."); ("e2fsck_f", (RErr, [Device "device"]), 108, [], [], (* lvresize tests this *) @@ -3580,6 +3614,175 @@ You can use this command to test the connection through to the daemon. See also C."); + ("find0", (RErr, [Pathname "directory"; FileOut "files"]), 196, [], + [], (* There is a regression test for this. *) + "find all files and directories, returning NUL-separated list", + "\ +This command lists out all files and directories, recursively, +starting at C, placing the resulting list in the +external file called C. + +This command works the same way as C with the +following exceptions: + +=over 4 + +=item * + +The resulting list is written to an external file. + +=item * + +Items (filenames) in the result are separated +by C<\\0> characters. See L option I<-print0>. + +=item * + +This command is not limited in the number of names that it +can return. + +=item * + +The result list is not sorted. + +=back"); + + ("case_sensitive_path", (RString "rpath", [Pathname "path"]), 197, [], + [InitISOFS, Always, TestOutput ( + [["case_sensitive_path"; "/DIRECTORY"]], "/directory"); + InitISOFS, Always, TestOutput ( + [["case_sensitive_path"; "/DIRECTORY/"]], "/directory"); + InitISOFS, Always, TestOutput ( + [["case_sensitive_path"; "/Known-1"]], "/known-1"); + InitISOFS, Always, TestLastFail ( + [["case_sensitive_path"; "/Known-1/"]]); + InitBasicFS, Always, TestOutput ( + [["mkdir"; "/a"]; + ["mkdir"; "/a/bbb"]; + ["touch"; "/a/bbb/c"]; + ["case_sensitive_path"; "/A/bbB/C"]], "/a/bbb/c"); + InitBasicFS, Always, TestOutput ( + [["mkdir"; "/a"]; + ["mkdir"; "/a/bbb"]; + ["touch"; "/a/bbb/c"]; + ["case_sensitive_path"; "/A////bbB/C"]], "/a/bbb/c"); + InitBasicFS, Always, TestLastFail ( + [["mkdir"; "/a"]; + ["mkdir"; "/a/bbb"]; + ["touch"; "/a/bbb/c"]; + ["case_sensitive_path"; "/A/bbb/../bbb/C"]])], + "return true path on case-insensitive filesystem", + "\ +This can be used to resolve case insensitive paths on +a filesystem which is case sensitive. The use case is +to resolve paths which you have read from Windows configuration +files or the Windows Registry, to the true path. + +The command handles a peculiarity of the Linux ntfs-3g +filesystem driver (and probably others), which is that although +the underlying filesystem is case-insensitive, the driver +exports the filesystem to Linux as case-sensitive. + +One consequence of this is that special directories such +as C may appear as C or C +(or other things) depending on the precise details of how +they were created. In Windows itself this would not be +a problem. + +Bug or feature? You decide: +L + +This function resolves the true case of each element in the +path and returns the case-sensitive path. + +Thus C (\"/Windows/System32\") +might return C<\"/WINDOWS/system32\"> (the exact return value +would depend on details of how the directories were originally +created under Windows). + +I: +This function does not handle drive names, backslashes etc. + +See also C."); + + ("vfs_type", (RString "fstype", [Device "device"]), 198, [], + [InitBasicFS, Always, TestOutput ( + [["vfs_type"; "/dev/sda1"]], "ext2")], + "get the Linux VFS type corresponding to a mounted device", + "\ +This command gets the block device type corresponding to +a mounted device called C. + +Usually the result is the name of the Linux VFS module that +is used to mount this device (probably determined automatically +if you used the C call)."); + + ("truncate", (RErr, [Pathname "path"]), 199, [], + [InitBasicFS, Always, TestOutputStruct ( + [["write_file"; "/test"; "some stuff so size is not zero"; "0"]; + ["truncate"; "/test"]; + ["stat"; "/test"]], [CompareWithInt ("size", 0)])], + "truncate a file to zero size", + "\ +This command truncates C to a zero-length file. The +file must exist already."); + + ("truncate_size", (RErr, [Pathname "path"; Int64 "size"]), 200, [], + [InitBasicFS, Always, TestOutputStruct ( + [["touch"; "/test"]; + ["truncate_size"; "/test"; "1000"]; + ["stat"; "/test"]], [CompareWithInt ("size", 1000)])], + "truncate a file to a particular size", + "\ +This command truncates C to size C bytes. The file +must exist already. If the file is smaller than C then +the file is extended to the required size with null bytes."); + + ("utimens", (RErr, [Pathname "path"; Int64 "atsecs"; Int64 "atnsecs"; Int64 "mtsecs"; Int64 "mtnsecs"]), 201, [], + [InitBasicFS, Always, TestOutputStruct ( + [["touch"; "/test"]; + ["utimens"; "/test"; "12345"; "67890"; "9876"; "5432"]; + ["stat"; "/test"]], [CompareWithInt ("mtime", 9876)])], + "set timestamp of a file with nanosecond precision", + "\ +This command sets the timestamps of a file with nanosecond +precision. + +C are the last access time (atime) in secs and +nanoseconds from the epoch. + +C are the last modification time (mtime) in +secs and nanoseconds from the epoch. + +If the C<*nsecs> field contains the special value C<-1> then +the corresponding timestamp is set to the current time. (The +C<*secs> field is ignored in this case). + +If the C<*nsecs> field contains the special value C<-2> then +the corresponding timestamp is left unchanged. (The +C<*secs> field is ignored in this case)."); + + ("mkdir_mode", (RErr, [Pathname "path"; Int "mode"]), 202, [], + [InitBasicFS, Always, TestOutputStruct ( + [["mkdir_mode"; "/test"; "0o111"]; + ["stat"; "/test"]], [CompareWithInt ("mode", 0o40111)])], + "create a directory with a particular mode", + "\ +This command creates a directory, setting the initial permissions +of the directory to C. See also C."); + + ("lchown", (RErr, [Int "owner"; Int "group"; Pathname "path"]), 203, [], + [], (* XXX *) + "change file owner and group", + "\ +Change the file owner to C and group to C. +This is like C but if C is a symlink then +the link itself is changed, not the target. + +Only numeric uid and gid are supported. If you want to use +names, you will need to locate and parse the password file +yourself (Augeas support makes this relatively easy)."); + ] let all_functions = non_daemon_functions @ daemon_functions @@ -3780,7 +3983,7 @@ type rstructs_used_t = RStructOnly | RStructListOnly | RStructAndList * == there are functions returning both RStruct (_, structname) * and RStructList (_, structname) *) -let rstructs_used = +let rstructs_used_by functions = (* ||| is a "logical OR" for rstructs_used_t *) let (|||) a b = match a, b with @@ -3809,27 +4012,18 @@ let rstructs_used = | RStruct (_, structname) -> update structname RStructOnly | RStructList (_, structname) -> update structname RStructListOnly | _ -> () - ) all_functions; + ) functions; (* return key->values as a list of (key,value) *) Hashtbl.fold (fun key value xs -> (key, value) :: xs) h [] -(* debug: -let () = - List.iter ( - function - | sn, RStructOnly -> printf "%s RStructOnly\n" sn - | sn, RStructListOnly -> printf "%s RStructListOnly\n" sn - | sn, RStructAndList -> printf "%s RStructAndList\n" sn - ) rstructs_used -*) - (* Used for testing language bindings. *) type callt = | CallString of string | CallOptString of string option | CallStringList of string list | CallInt of int + | CallInt64 of int64 | CallBool of bool (* Used to memoize the result of pod2text. *) @@ -3967,7 +4161,7 @@ let mapi f xs = let name_of_argt = function | Pathname n | Device n | Dev_or_Path n | String n | OptString n - | StringList n | DeviceList n | Bool n | Int n + | StringList n | DeviceList n | Bool n | Int n | Int64 n | FileIn n | FileOut n -> n let java_name_of_struct typ = @@ -4383,11 +4577,13 @@ and generate_xdr () = pr "struct %s_args {\n" name; List.iter ( function - | Pathname n | Device n | Dev_or_Path n | String n -> pr " string %s<>;\n" n + | Pathname n | Device n | Dev_or_Path n | String n -> + pr " string %s<>;\n" n | OptString n -> pr " str *%s;\n" n | StringList n | DeviceList n -> pr " str %s<>;\n" n | Bool n -> pr " bool %s;\n" n | Int n -> pr " int %s;\n" n + | Int64 n -> pr " hyper %s;\n" n | FileIn _ | FileOut _ -> () ) args; pr "};\n\n" @@ -4576,6 +4772,8 @@ and generate_client_actions () = pr "\ #include #include +#include +#include #include \"guestfs.h\" #include \"guestfs-internal-actions.h\" @@ -4625,12 +4823,9 @@ static int check_state (guestfs_h *g, const char *caller) { if (!guestfs__is_ready (g)) { - if (guestfs__is_config (g)) + if (guestfs__is_config (g) || guestfs__is_launching (g)) error (g, \"%%s: call launch before using this function\\n(in guestfish, don't forget to use the 'run' command)\", caller); - else if (guestfs__is_launching (g)) - error (g, \"%%s: call wait_ready() before using this function\", - caller); else error (g, \"%%s called from the wrong state, %%d != READY\", caller, guestfs__get_state (g)); @@ -4647,8 +4842,8 @@ check_state (guestfs_h *g, const char *caller) let needs_i = List.exists (function - | StringList _ | DeviceList _ -> true - | _ -> false) (snd style) in + | StringList _ | DeviceList _ -> true + | _ -> false) (snd style) in if needs_i then ( pr " int i;\n"; pr "\n" @@ -4663,24 +4858,26 @@ check_state (guestfs_h *g, const char *caller) | Dev_or_Path n | FileIn n | FileOut n -> - (* guestfish doesn't support string escaping, so neither do we *) - pr " printf (\" \\\"%%s\\\"\", %s);\n" n + (* guestfish doesn't support string escaping, so neither do we *) + pr " printf (\" \\\"%%s\\\"\", %s);\n" n | OptString n -> (* string option *) - pr " if (%s) printf (\" \\\"%%s\\\"\", %s);\n" n n; - pr " else printf (\" null\");\n" + pr " if (%s) printf (\" \\\"%%s\\\"\", %s);\n" n n; + pr " else printf (\" null\");\n" | StringList n | DeviceList n -> (* string list *) - pr " putchar (' ');\n"; - pr " putchar ('\"');\n"; - pr " for (i = 0; %s[i]; ++i) {\n" n; - pr " if (i > 0) putchar (' ');\n"; - pr " fputs (%s[i], stdout);\n" n; - pr " }\n"; - pr " putchar ('\"');\n"; + pr " putchar (' ');\n"; + pr " putchar ('\"');\n"; + pr " for (i = 0; %s[i]; ++i) {\n" n; + pr " if (i > 0) putchar (' ');\n"; + pr " fputs (%s[i], stdout);\n" n; + pr " }\n"; + pr " putchar ('\"');\n"; | Bool n -> (* boolean *) - pr " fputs (%s ? \" true\" : \" false\", stdout);\n" n + pr " fputs (%s ? \" true\" : \" false\", stdout);\n" n | Int n -> (* int *) - pr " printf (\" %%d\", %s);\n" n + pr " printf (\" %%d\", %s);\n" n + | Int64 n -> + pr " printf (\" %%\" PRIi64, %s);\n" n ) (snd style); pr " putchar ('\\n');\n"; pr " }\n"; @@ -4732,16 +4929,16 @@ check_state (guestfs_h *g, const char *caller) pr " guestfs_message_header hdr;\n"; pr " guestfs_message_error err;\n"; let has_ret = - match fst style with - | RErr -> false - | RConstString _ | RConstOptString _ -> + match fst style with + | RErr -> false + | RConstString _ | RConstOptString _ -> failwithf "RConstString|RConstOptString cannot be used by daemon functions" - | RInt _ | RInt64 _ - | RBool _ | RString _ | RStringList _ - | RStruct _ | RStructList _ - | RHashtable _ | RBufferOut _ -> + | RInt _ | RInt64 _ + | RBool _ | RString _ | RStringList _ + | RStruct _ | RStructList _ + | RHashtable _ | RBufferOut _ -> pr " struct %s_ret ret;\n" name; - true in + true in pr " int serial;\n"; pr " int r;\n"; @@ -4770,6 +4967,8 @@ check_state (guestfs_h *g, const char *caller) 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 _ -> () ) args; pr " serial = guestfs___send (g, GUESTFS_PROC_%s,\n" @@ -4808,7 +5007,7 @@ check_state (guestfs_h *g, const char *caller) pr "\n"; pr " r = guestfs___recv (g, \"%s\", &hdr, &err,\n " shortname; if not has_ret then - pr "NULL, NULL" + pr "NULL, NULL" else pr "(xdrproc_t) xdr_guestfs_%s_ret, (char *) &ret" shortname; pr ");\n"; @@ -4929,11 +5128,11 @@ and generate_daemon_actions () = pr "#include \n"; pr "#include \n"; pr "#include \n"; - pr "#include \n"; pr "#include \n"; pr "#include \n"; pr "\n"; pr "#include \"daemon.h\"\n"; + pr "#include \"c-ctype.h\"\n"; pr "#include \"../src/guestfs_protocol.h\"\n"; pr "#include \"actions.h\"\n"; pr "\n"; @@ -4972,6 +5171,7 @@ and generate_daemon_actions () = | StringList n | DeviceList n -> pr " char **%s;\n" n | Bool n -> pr " int %s;\n" n | Int n -> pr " int %s;\n" n + | Int64 n -> pr " int64_t %s;\n" n | FileIn _ | FileOut _ -> () ) args ); @@ -5023,6 +5223,7 @@ and generate_daemon_actions () = pr " }\n"; | Bool n -> pr " %s = args.%s;\n" n n | Int n -> pr " %s = args.%s;\n" n n + | Int64 n -> pr " %s = args.%s;\n" n n | FileIn _ | FileOut _ -> () ) args; pr "\n" @@ -5159,7 +5360,7 @@ and generate_daemon_actions () = pr " fprintf (stderr, \"%%s: failed: passed a NULL string\\n\", __func__);\n"; pr " return -1;\n"; pr " }\n"; - pr " if (!*str || isspace (*str)) {\n"; + pr " if (!*str || c_isspace (*str)) {\n"; pr " fprintf (stderr, \"%%s: failed: passed a empty string or one beginning with whitespace\\n\", __func__);\n"; pr " return -1;\n"; pr " }\n"; @@ -5261,7 +5462,7 @@ and generate_daemon_actions () = pr " pend++;\n"; pr " }\n"; pr "\n"; - pr " while (*p && isspace (*p)) /* Skip any leading whitespace. */\n"; + pr " while (*p && c_isspace (*p)) /* Skip any leading whitespace. */\n"; pr " p++;\n"; pr "\n"; pr " if (!*p) { /* Empty line? Skip it. */\n"; @@ -5522,11 +5723,6 @@ int main (int argc, char *argv[]) /* Set a timeout in case qemu hangs during launch (RHBZ#505329). */ alarm (600); - if (guestfs_wait_ready (g) == -1) { - printf (\"guestfs_wait_ready FAILED\\n\"); - exit (1); - } - /* Cancel previous alarm. */ alarm (0); @@ -5930,6 +6126,7 @@ and generate_test_command_call ?(expect_error = false) ?test test_name cmd = | OptString n, arg -> pr " const char *%s = \"%s\";\n" n (c_quote arg); | Int _, _ + | Int64 _, _ | Bool _, _ | FileIn _, _ | FileOut _, _ -> () | StringList n, arg | DeviceList n, arg -> @@ -5988,6 +6185,12 @@ and generate_test_command_call ?(expect_error = false) ?test test_name cmd = with Failure "int_of_string" -> failwithf "%s: expecting an int, but got '%s'" test_name arg in pr ", %d" i + | Int64 _, arg -> + let i = + try Int64.of_string arg + with Failure "int_of_string" -> + failwithf "%s: expecting an int64, but got '%s'" test_name arg in + pr ", %Ld" i | Bool _, arg -> let b = bool_of_string arg in pr ", %d" (if b then 1 else 0) ) (List.combine (snd style) args); @@ -6051,9 +6254,9 @@ and generate_fish_cmds () = pr "#include \n"; pr "#include \n"; pr "#include \n"; - pr "#include \n"; pr "\n"; pr "#include \n"; + pr "#include \"c-ctype.h\"\n"; pr "#include \"fish.h\"\n"; pr "\n"; @@ -6164,17 +6367,17 @@ and generate_fish_cmds () = | name, FString -> pr " printf (\"%%s%s: %%s\\n\", indent, %s->%s);\n" name typ name | name, FUUID -> - pr " printf (\"%s: \");\n" name; + pr " printf (\"%%s%s: \", indent);\n" name; pr " for (i = 0; i < 32; ++i)\n"; - pr " printf (\"%%s%%c\", indent, %s->%s[i]);\n" typ name; + pr " printf (\"%%c\", %s->%s[i]);\n" typ name; pr " printf (\"\\n\");\n" | name, FBuffer -> pr " printf (\"%%s%s: \", indent);\n" name; pr " for (i = 0; i < %s->%s_len; ++i)\n" typ name; - pr " if (isprint (%s->%s[i]))\n" typ name; - pr " printf (\"%%s%%c\", indent, %s->%s[i]);\n" typ name; + pr " if (c_isprint (%s->%s[i]))\n" typ name; + pr " printf (\"%%c\", %s->%s[i]);\n" typ name; pr " else\n"; - pr " printf (\"%%s\\\\x%%02x\", indent, %s->%s[i]);\n" typ name; + pr " printf (\"\\\\x%%02x\", %s->%s[i]);\n" typ name; pr " printf (\"\\n\");\n" | name, (FUInt64|FBytes) -> pr " printf (\"%%s%s: %%\" PRIu64 \"\\n\", indent, %s->%s);\n" @@ -6207,19 +6410,19 @@ and generate_fish_cmds () = (* generate the function for typ *) emit_print_list_function typ | typ, _ -> () (* empty *) - ) rstructs_used; + ) (rstructs_used_by all_functions); (* Emit a print_TYPE function definition only if that function is used. *) List.iter ( function - | typ, RStructOnly -> + | typ, (RStructOnly | RStructAndList) -> pr "static void print_%s (struct guestfs_%s *%s)\n" typ typ typ; pr "{\n"; pr " print_%s_indent (%s, \"\");\n" typ typ; pr "}\n"; pr "\n"; | typ, _ -> () (* empty *) - ) rstructs_used; + ) (rstructs_used_by all_functions); (* run_ actions *) List.iter ( @@ -6242,15 +6445,17 @@ and generate_fish_cmds () = ); List.iter ( function - | Pathname n - | Device n | Dev_or_Path n + | Device n | String n | OptString n | FileIn n | FileOut n -> pr " const char *%s;\n" n + | Pathname n + | Dev_or_Path n -> pr " char *%s;\n" n | StringList n | DeviceList n -> pr " char **%s;\n" n | Bool n -> pr " int %s;\n" n | Int n -> pr " int %s;\n" n + | Int64 n -> pr " int64_t %s;\n" n ) (snd style); (* Check and convert parameters. *) @@ -6264,8 +6469,13 @@ and generate_fish_cmds () = iteri ( fun i -> function + | Device name + | String name -> + pr " %s = argv[%d];\n" name i | Pathname name - | Device name | Dev_or_Path name | String name -> pr " %s = argv[%d];\n" name i + | Dev_or_Path name -> + pr " %s = resolve_win_path (argv[%d]);\n" name i; + pr " if (%s == NULL) return -1;\n" name | OptString name -> pr " %s = strcmp (argv[%d], \"\") != 0 ? argv[%d] : NULL;\n" name i i @@ -6282,6 +6492,8 @@ and generate_fish_cmds () = pr " %s = is_true (argv[%d]) ? 1 : 0;\n" name i | Int name -> pr " %s = atoi (argv[%d]);\n" name i + | Int64 name -> + pr " %s = atoll (argv[%d]);\n" name i ) (snd style); (* Call C API function. *) @@ -6294,9 +6506,11 @@ and generate_fish_cmds () = List.iter ( function - | Pathname name | Device name | Dev_or_Path name | String name + | Device name | String name | OptString name | FileIn name | FileOut name | Bool name - | Int name -> () + | Int name | Int64 name -> () + | Pathname name | Dev_or_Path name -> + pr " free (%s);\n" name | StringList name | DeviceList name -> pr " free_strings (%s);\n" name ) (snd style); @@ -6513,6 +6727,7 @@ and generate_fish_actions_pod () = | StringList n | DeviceList n -> pr " '%s ...'" n | Bool _ -> pr " true|false" | Int n -> pr " %s" n + | Int64 n -> pr " %s" n | FileIn n | FileOut n -> pr " (%s|-)" n ) (snd style); pr "\n"; @@ -6585,6 +6800,7 @@ and generate_prototype ?(extern = true) ?(static = false) ?(semicolon = true) pr "char *const *%s" n | Bool n -> next (); pr "int %s" n | Int n -> next (); pr "int %s" n + | Int64 n -> next (); pr "int64_t %s" n | FileIn n | FileOut n -> if not in_daemon then (next (); pr "const char *%s" n) @@ -6807,7 +7023,7 @@ copy_table (char * const * argv) (* generate the function for typ *) emit_ocaml_copy_list_function typ | typ, _ -> () (* empty *) - ) rstructs_used; + ) (rstructs_used_by all_functions); (* The wrappers. *) List.iter ( @@ -6867,6 +7083,8 @@ copy_table (char * const * argv) pr " int %s = Bool_val (%sv);\n" n n | Int n -> pr " int %s = Int_val (%sv);\n" n n + | Int64 n -> + pr " int64_t %s = Int64_val (%sv);\n" n n ) (snd style); let error_code = match fst style with @@ -6905,7 +7123,8 @@ copy_table (char * const * argv) function | StringList n | DeviceList n -> pr " ocaml_guestfs_free_strings (%s);\n" n; - | Pathname _ | Device _ | Dev_or_Path _ | String _ | OptString _ | Bool _ | Int _ + | Pathname _ | Device _ | Dev_or_Path _ | String _ | OptString _ + | Bool _ | Int _ | Int64 _ | FileIn _ | FileOut _ -> () ) (snd style); @@ -6997,6 +7216,7 @@ and generate_ocaml_prototype ?(is_external = false) name style = | StringList _ | DeviceList _ -> pr "string array -> " | Bool _ -> pr "bool -> " | Int _ -> pr "int -> " + | Int64 _ -> pr "int64 -> " ) (snd style); (match fst style with | RErr -> pr "unit" (* all errors are turned into exceptions *) @@ -7148,12 +7368,14 @@ DESTROY (g) | StringList n | DeviceList n -> pr " char **%s;\n" n | Bool n -> pr " int %s;\n" n | Int n -> pr " int %s;\n" n + | Int64 n -> pr " int64_t %s;\n" n ) (snd style); let do_cleanups () = List.iter ( function - | Pathname _ | Device _ | Dev_or_Path _ | String _ | OptString _ | Bool _ | Int _ + | Pathname _ | Device _ | Dev_or_Path _ | String _ | OptString _ + | Bool _ | Int _ | Int64 _ | FileIn _ | FileOut _ -> () | StringList n | DeviceList n -> pr " free (%s);\n" n ) (snd style) @@ -7390,7 +7612,6 @@ Sys::Guestfs - Perl bindings for libguestfs my $h = Sys::Guestfs->new (); $h->add_drive ('guest.img'); $h->launch (); - $h->wait_ready (); $h->mount ('/dev/sda1', '/'); $h->touch ('/hello'); $h->sync (); @@ -7526,7 +7747,7 @@ and generate_perl_prototype name style = comma := true; match arg with | Pathname n | Device n | Dev_or_Path n | String n - | OptString n | Bool n | Int n | FileIn n | FileOut n -> + | OptString n | Bool n | Int n | Int64 n | FileIn n | FileOut n -> pr "$%s" n | StringList n | DeviceList n -> pr "\\@%s" n @@ -7754,7 +7975,7 @@ py_guestfs_close (PyObject *self, PyObject *args) (* generate the function for typ *) emit_put_list_function typ | typ, _ -> () (* empty *) - ) rstructs_used; + ) (rstructs_used_by all_functions); (* Python wrapper functions. *) List.iter ( @@ -7793,6 +8014,7 @@ py_guestfs_close (PyObject *self, PyObject *args) pr " char **%s;\n" n | Bool n -> pr " int %s;\n" n | Int n -> pr " int %s;\n" n + | Int64 n -> pr " long long %s;\n" n ) (snd style); pr "\n"; @@ -7806,6 +8028,9 @@ py_guestfs_close (PyObject *self, PyObject *args) | StringList _ | DeviceList _ -> pr "O" | Bool _ -> pr "i" (* XXX Python has booleans? *) | Int _ -> pr "i" + | Int64 _ -> pr "L" (* XXX Whoever thought it was a good idea to + * emulate C's int/long/long long in Python? + *) ) (snd style); pr ":guestfs_%s\",\n" name; pr " &py_g"; @@ -7816,6 +8041,7 @@ py_guestfs_close (PyObject *self, PyObject *args) | StringList n | DeviceList n -> pr ", &py_%s" n | Bool n -> pr ", &%s" n | Int n -> pr ", &%s" n + | Int64 n -> pr ", &%s" n ) (snd style); pr "))\n"; @@ -7825,7 +8051,7 @@ py_guestfs_close (PyObject *self, PyObject *args) List.iter ( function | Pathname _ | Device _ | Dev_or_Path _ | String _ - | FileIn _ | FileOut _ | OptString _ | Bool _ | Int _ -> () + | FileIn _ | FileOut _ | OptString _ | Bool _ | Int _ | Int64 _ -> () | StringList n | DeviceList n -> pr " %s = get_string_list (py_%s);\n" n n; pr " if (!%s) return NULL;\n" n @@ -7840,7 +8066,7 @@ py_guestfs_close (PyObject *self, PyObject *args) List.iter ( function | Pathname _ | Device _ | Dev_or_Path _ | String _ - | FileIn _ | FileOut _ | OptString _ | Bool _ | Int _ -> () + | FileIn _ | FileOut _ | OptString _ | Bool _ | Int _ | Int64 _ -> () | StringList n | DeviceList n -> pr " free (%s);\n" n ) (snd style); @@ -7928,7 +8154,6 @@ import guestfs g = guestfs.GuestFS () g.add_drive (\"guest.img\") g.launch () -g.wait_ready () parts = g.list_partitions () The guestfs module provides a Python binding to the libguestfs API @@ -7963,7 +8188,6 @@ g.add_drive (\"guest.img\") # Launch the qemu subprocess and wait for it to become ready: g.launch () -g.wait_ready () # Now you can issue commands, for example: logvols = g.lvs () @@ -8172,6 +8396,8 @@ static VALUE ruby_guestfs_close (VALUE gv) pr " int %s = RTEST (%sv);\n" n n | Int n -> pr " int %s = NUM2INT (%sv);\n" n n + | Int64 n -> + pr " long long %s = NUM2LL (%sv);\n" n n ) (snd style); pr "\n"; @@ -8199,7 +8425,7 @@ static VALUE ruby_guestfs_close (VALUE gv) List.iter ( function | Pathname _ | Device _ | Dev_or_Path _ | String _ - | FileIn _ | FileOut _ | OptString _ | Bool _ | Int _ -> () + | FileIn _ | FileOut _ | OptString _ | Bool _ | Int _ | Int64 _ -> () | StringList n | DeviceList n -> pr " free (%s);\n" n ) (snd style); @@ -8522,6 +8748,8 @@ and generate_java_prototype ?(public=false) ?(privat=false) ?(native=false) pr "boolean %s" n | Int n -> pr "int %s" n + | Int64 n -> + pr "long %s" n ) (snd style); pr ")\n"; @@ -8641,6 +8869,8 @@ Java_com_redhat_et_libguestfs_GuestFS__1close pr ", jboolean j%s" n | Int n -> pr ", jint j%s" n + | Int64 n -> + pr ", jlong j%s" n ) (snd style); pr ")\n"; pr "{\n"; @@ -8694,6 +8924,8 @@ Java_com_redhat_et_libguestfs_GuestFS__1close | Bool n | Int n -> pr " int %s;\n" n + | Int64 n -> + pr " int64_t %s;\n" n ) (snd style); let needs_i = @@ -8735,7 +8967,8 @@ Java_com_redhat_et_libguestfs_GuestFS__1close pr " }\n"; pr " %s[%s_len] = NULL;\n" n n; | Bool n - | Int n -> + | Int n + | Int64 n -> pr " %s = j%s;\n" n n ) (snd style); @@ -8764,7 +8997,8 @@ Java_com_redhat_et_libguestfs_GuestFS__1close pr " }\n"; pr " free (%s);\n" n | Bool n - | Int n -> () + | Int n + | Int64 n -> () ) (snd style); (* Check for errors. *) @@ -9026,7 +9260,7 @@ last_error h = do | Pathname n | Device n | Dev_or_Path n | String n -> pr "withCString %s $ \\%s -> " n n | OptString n -> pr "maybeWith withCString %s $ \\%s -> " n n | StringList n | DeviceList n -> pr "withMany withCString %s $ \\%s -> withArray0 nullPtr %s $ \\%s -> " n n n n - | Bool _ | Int _ -> () + | Bool _ | Int _ | Int64 _ -> () ) (snd style); (* Convert integer arguments. *) let args = @@ -9034,6 +9268,7 @@ last_error h = do function | Bool n -> sprintf "(fromBool %s)" n | Int n -> sprintf "(fromIntegral %s)" n + | Int64 n -> sprintf "(fromIntegral %s)" n | FileIn n | FileOut n | Pathname n | Device n | Dev_or_Path n | String n | OptString n | StringList n | DeviceList n -> n ) (snd style) in @@ -9090,6 +9325,7 @@ and generate_haskell_prototype ~handle ?(hs = false) style = | StringList _ | DeviceList _ -> if hs then pr "[String]" else pr "Ptr CString" | Bool _ -> pr "%s" bool | Int _ -> pr "%s" int + | Int64 _ -> pr "%s" int | FileIn _ -> pr "%s" string | FileOut _ -> pr "%s" string ); @@ -9170,6 +9406,7 @@ print_strings (char *const *argv) | StringList n | DeviceList n -> pr " print_strings (%s);\n" n | Bool n -> pr " printf (\"%%s\\n\", %s ? \"true\" : \"false\");\n" n | Int n -> pr " printf (\"%%d\\n\", %s);\n" n + | Int64 n -> pr " printf (\"%%\" PRIi64 \"\\n\", %s);\n" n ) (snd style); pr " /* Java changes stdout line buffering so we need this: */\n"; pr " fflush (stdout);\n"; @@ -9285,6 +9522,8 @@ let () = "[|" ^ String.concat ";" (List.map (sprintf "\"%s\"") xs) ^ "|]" | CallInt i when i >= 0 -> string_of_int i | CallInt i (* when i < 0 *) -> "(" ^ string_of_int i ^ ")" + | CallInt64 i when i >= 0L -> Int64.to_string i ^ "L" + | CallInt64 i (* when i < 0L *) -> "(" ^ Int64.to_string i ^ "L)" | CallBool b -> string_of_bool b ) args ) @@ -9318,6 +9557,7 @@ my $g = Sys::Guestfs->new (); | CallStringList xs -> "[" ^ String.concat "," (List.map (sprintf "\"%s\"") xs) ^ "]" | CallInt i -> string_of_int i + | CallInt64 i -> Int64.to_string i | CallBool b -> if b then "1" else "0" ) args ) @@ -9348,6 +9588,7 @@ g = guestfs.GuestFS () | CallStringList xs -> "[" ^ String.concat "," (List.map (sprintf "\"%s\"") xs) ^ "]" | CallInt i -> string_of_int i + | CallInt64 i -> Int64.to_string i | CallBool b -> if b then "1" else "0" ) args ) @@ -9378,6 +9619,7 @@ g = Guestfs::create() | CallStringList xs -> "[" ^ String.concat "," (List.map (sprintf "\"%s\"") xs) ^ "]" | CallInt i -> string_of_int i + | CallInt64 i -> Int64.to_string i | CallBool b -> string_of_bool b ) args ) @@ -9413,6 +9655,7 @@ public class Bindtests { "new String[]{" ^ String.concat "," (List.map (sprintf "\"%s\"") xs) ^ "}" | CallInt i -> string_of_int i + | CallInt64 i -> Int64.to_string i | CallBool b -> string_of_bool b ) args ) @@ -9455,6 +9698,8 @@ main = do "[" ^ String.concat "," (List.map (sprintf "\"%s\"") xs) ^ "]" | CallInt i when i < 0 -> "(" ^ string_of_int i ^ ")" | CallInt i -> string_of_int i + | CallInt64 i when i < 0L -> "(" ^ Int64.to_string i ^ ")" + | CallInt64 i -> Int64.to_string i | CallBool true -> "True" | CallBool false -> "False" ) args @@ -9473,43 +9718,43 @@ main = do and generate_lang_bindtests call = call "test0" [CallString "abc"; CallOptString (Some "def"); CallStringList []; CallBool false; - CallInt 0; CallString "123"; CallString "456"]; + CallInt 0; CallInt64 0L; CallString "123"; CallString "456"]; call "test0" [CallString "abc"; CallOptString None; CallStringList []; CallBool false; - CallInt 0; CallString "123"; CallString "456"]; + CallInt 0; CallInt64 0L; CallString "123"; CallString "456"]; call "test0" [CallString ""; CallOptString (Some "def"); CallStringList []; CallBool false; - CallInt 0; CallString "123"; CallString "456"]; + CallInt 0; CallInt64 0L; CallString "123"; CallString "456"]; call "test0" [CallString ""; CallOptString (Some ""); CallStringList []; CallBool false; - CallInt 0; CallString "123"; CallString "456"]; + CallInt 0; CallInt64 0L; CallString "123"; CallString "456"]; call "test0" [CallString "abc"; CallOptString (Some "def"); CallStringList ["1"]; CallBool false; - CallInt 0; CallString "123"; CallString "456"]; + CallInt 0; CallInt64 0L; CallString "123"; CallString "456"]; call "test0" [CallString "abc"; CallOptString (Some "def"); CallStringList ["1"; "2"]; CallBool false; - CallInt 0; CallString "123"; CallString "456"]; + CallInt 0; CallInt64 0L; CallString "123"; CallString "456"]; call "test0" [CallString "abc"; CallOptString (Some "def"); CallStringList ["1"]; CallBool true; - CallInt 0; CallString "123"; CallString "456"]; + CallInt 0; CallInt64 0L; CallString "123"; CallString "456"]; call "test0" [CallString "abc"; CallOptString (Some "def"); CallStringList ["1"]; CallBool false; - CallInt (-1); CallString "123"; CallString "456"]; + CallInt (-1); CallInt64 (-1L); CallString "123"; CallString "456"]; call "test0" [CallString "abc"; CallOptString (Some "def"); CallStringList ["1"]; CallBool false; - CallInt (-2); CallString "123"; CallString "456"]; + CallInt (-2); CallInt64 (-2L); CallString "123"; CallString "456"]; call "test0" [CallString "abc"; CallOptString (Some "def"); CallStringList ["1"]; CallBool false; - CallInt 1; CallString "123"; CallString "456"]; + CallInt 1; CallInt64 1L; CallString "123"; CallString "456"]; call "test0" [CallString "abc"; CallOptString (Some "def"); CallStringList ["1"]; CallBool false; - CallInt 2; CallString "123"; CallString "456"]; + CallInt 2; CallInt64 2L; CallString "123"; CallString "456"]; call "test0" [CallString "abc"; CallOptString (Some "def"); CallStringList ["1"]; CallBool false; - CallInt 4095; CallString "123"; CallString "456"]; + CallInt 4095; CallInt64 4095L; CallString "123"; CallString "456"]; call "test0" [CallString "abc"; CallOptString (Some "def"); CallStringList ["1"]; CallBool false; - CallInt 0; CallString ""; CallString ""] + CallInt 0; CallInt64 0L; CallString ""; CallString ""] (* XXX Add here tests of the return and error functions. *)