X-Git-Url: http://git.annexia.org/?p=libguestfs.git;a=blobdiff_plain;f=src%2Fgenerator.ml;h=620395b7fdc1833bd70cf39a3802399caaf8d03c;hp=dfab8dcd4e9cbb5fb290fe28984a4131cc03cf03;hb=8355d3245623c106439ca5ef66f24972c8e09019;hpb=3920ad95f6b2db8fbf20aa26692877a09070cb04 diff --git a/src/generator.ml b/src/generator.ml index dfab8dc..620395b 100755 --- a/src/generator.ml +++ b/src/generator.ml @@ -575,7 +575,7 @@ The first character of C string must be a C<-> (dash). C can be NULL."); - ("set_qemu", (RErr, [String "qemu"]), -1, [FishAlias "qemu"], + ("set_qemu", (RErr, [OptString "qemu"]), -1, [FishAlias "qemu"], [], "set the qemu binary", "\ @@ -607,7 +607,7 @@ Return the current qemu binary. This is always non-NULL. If it wasn't set already, then this will return the default qemu binary name."); - ("set_path", (RErr, [String "searchpath"]), -1, [FishAlias "path"], + ("set_path", (RErr, [OptString "searchpath"]), -1, [FishAlias "path"], [], "set the search path", "\ @@ -794,8 +794,9 @@ against a completely different C library. This call was added in version C<1.0.58>. In previous versions of libguestfs there was no way to get the version -number. From C code you can use ELF weak linking tricks to find out if -this symbol exists (if it doesn't, then it's an earlier version). +number. From C code you can use dynamic linker functions +to find out if this symbol exists (if it doesn't, then +it's an earlier version). The call returns a structure with four elements. The first three (C, C and C) are numbers and @@ -806,6 +807,8 @@ used for distro-specific information. To construct the original version string: C<$major.$minor.$release$extra> +See also: L. + I Don't use this call to test for availability of features. Distro backports makes this unreliable. Use C instead."); @@ -3151,7 +3154,7 @@ Unknown file type =item '?' -The L returned a C field with an +The L call returned a C field with an unexpected value =back @@ -3474,7 +3477,7 @@ The C<-f> option removes the link (C) if it exists already."); "\ This command reads the target of a symbolic link."); - ("fallocate", (RErr, [Pathname "path"; Int "len"]), 169, [], + ("fallocate", (RErr, [Pathname "path"; Int "len"]), 169, [DeprecatedBy "fallocate64"], [InitBasicFS, Always, TestOutputStruct ( [["fallocate"; "/a"; "1000000"]; ["stat"; "/a"]], [CompareWithInt ("size", 1_000_000)])], @@ -3796,8 +3799,8 @@ was built (see C in the source)."); )], "echo arguments back to the client", "\ -This command concatenate the list of C passed with single spaces between -them and returns the resulting string. +This command concatenates the list of C passed with single spaces +between them and returns the resulting string. You can use this command to test the connection through to the daemon. @@ -3924,8 +3927,13 @@ file must exist already."); "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."); +must exist already. + +If the current file size is less than C then +the file is extended to the required size with zero bytes. +This creates a sparse file (ie. disk blocks are not allocated +for the file until you write to it). To create a non-sparse +file of zeroes, use C instead."); ("utimens", (RErr, [Pathname "path"; Int64 "atsecs"; Int64 "atnsecs"; Int64 "mtsecs"; Int64 "mtnsecs"]), 201, [], [InitBasicFS, Always, TestOutputStruct ( @@ -4035,7 +4043,7 @@ C is the list of files from this directory. On return you get a list of strings, with a one-to-one correspondence to the C list. Each string is the -value of the symbol link. +value of the symbolic link. If the C operation fails on any name, then the corresponding result string is the empty string C<\"\">. @@ -4062,7 +4070,9 @@ This command lets you read part of a file. It reads C bytes of the file, starting at C, from file C. This may read fewer bytes than requested. For further details -see the L system call."); +see the L system call. + +See also C."); ("part_init", (RErr, [Device "device"; String "parttype"]), 208, [], [InitEmpty, Always, TestRun ( @@ -4275,6 +4285,8 @@ the libguestfs appliance will be able to provide. The libguestfs groups, and the functions that those groups correspond to, are listed in L. +You can also fetch this list at runtime by calling +C. The argument C is a list of group names, eg: C<[\"inotify\", \"augeas\"]> would check for the availability of @@ -4453,7 +4465,7 @@ This command writes zeroes over the entire C. Compare with C which just zeroes the first few blocks of a device."); - ("txz_in", (RErr, [FileIn "tarball"; Pathname "directory"]), 229, [], + ("txz_in", (RErr, [FileIn "tarball"; Pathname "directory"]), 229, [Optional "xz"], [InitBasicFS, Always, TestOutput ( [["txz_in"; "../images/helloworld.tar.xz"; "/"]; ["cat"; "/hello"]], "hello\n")], @@ -4462,7 +4474,7 @@ a device."); This command uploads and unpacks local file C (an I tar file) into C."); - ("txz_out", (RErr, [Pathname "directory"; FileOut "tarball"]), 230, [], + ("txz_out", (RErr, [Pathname "directory"; FileOut "tarball"]), 230, [Optional "xz"], [], "pack directory into compressed tarball", "\ @@ -4658,6 +4670,87 @@ to ensure the length of the file is exactly C bytes."); This call creates a file called C. The content of the file is the string C (which can contain any 8 bit data)."); + ("pwrite", (RInt "nbytes", [Pathname "path"; BufferIn "content"; Int64 "offset"]), 247, [ProtocolLimitWarning], + [InitBasicFS, Always, TestOutput ( + [["write"; "/new"; "new file contents"]; + ["pwrite"; "/new"; "data"; "4"]; + ["cat"; "/new"]], "new data contents"); + InitBasicFS, Always, TestOutput ( + [["write"; "/new"; "new file contents"]; + ["pwrite"; "/new"; "is extended"; "9"]; + ["cat"; "/new"]], "new file is extended"); + InitBasicFS, Always, TestOutput ( + [["write"; "/new"; "new file contents"]; + ["pwrite"; "/new"; ""; "4"]; + ["cat"; "/new"]], "new file contents")], + "write to part of a file", + "\ +This command writes to part of a file. It writes the data +buffer C to the file C starting at offset C. + +This command implements the L system call, and like +that system call it may not write the full data requested. The +return value is the number of bytes that were actually written +to the file. This could even be 0, although short writes are +unlikely for regular files in ordinary circumstances. + +See also C."); + + ("resize2fs_size", (RErr, [Device "device"; Int64 "size"]), 248, [], + [], + "resize an ext2/ext3 filesystem (with size)", + "\ +This command is the same as C except that it +allows you to specify the new size (in bytes) explicitly."); + + ("pvresize_size", (RErr, [Device "device"; Int64 "size"]), 249, [Optional "lvm2"], + [], + "resize an LVM physical volume (with size)", + "\ +This command is the same as C except that it +allows you to specify the new size (in bytes) explicitly."); + + ("ntfsresize_size", (RErr, [Device "device"; Int64 "size"]), 250, [Optional "ntfsprogs"], + [], + "resize an NTFS filesystem (with size)", + "\ +This command is the same as C except that it +allows you to specify the new size (in bytes) explicitly."); + + ("available_all_groups", (RStringList "groups", []), 251, [], + [InitNone, Always, TestRun [["available_all_groups"]]], + "return a list of all optional groups", + "\ +This command returns a list of all optional groups that this +daemon knows about. Note this returns both supported and unsupported +groups. To find out which ones the daemon can actually support +you have to call C on each member of the +returned list. + +See also C and L."); + + ("fallocate64", (RErr, [Pathname "path"; Int64 "len"]), 252, [], + [InitBasicFS, Always, TestOutputStruct ( + [["fallocate64"; "/a"; "1000000"]; + ["stat"; "/a"]], [CompareWithInt ("size", 1_000_000)])], + "preallocate a file in the guest filesystem", + "\ +This command preallocates a file (containing zero bytes) named +C of size C bytes. If the file exists already, it +is overwritten. + +Note that this call allocates disk blocks for the file. +To create a sparse file use C instead. + +The deprecated call C does the same, +but owing to an oversight it only allowed 30 bit lengths +to be specified, effectively limiting the maximum size +of files created through that call to 1GB. + +Do not confuse this with the guestfish-specific +C and C commands which create +a file in the host and attach it as a device."); + ] let all_functions = non_daemon_functions @ daemon_functions @@ -5807,6 +5900,50 @@ check_state (guestfs_h *g, const char *caller) "; + let error_code_of = function + | RErr | RInt _ | RInt64 _ | RBool _ -> "-1" + | RConstString _ | RConstOptString _ + | RString _ | RStringList _ + | RStruct _ | RStructList _ + | RHashtable _ | RBufferOut _ -> "NULL" + in + + (* Generate code to check String-like parameters are not passed in + * as NULL (returning an error if they are). + *) + let check_null_strings shortname style = + let pr_newline = ref false in + List.iter ( + function + (* parameters which should not be NULL *) + | String n + | Device n + | Pathname n + | Dev_or_Path n + | FileIn n + | FileOut n + | BufferIn n + | StringList n + | DeviceList n -> + 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 (fst style)); + pr " }\n"; + pr_newline := true + + (* can be NULL *) + | OptString _ + + (* not applicable *) + | Bool _ + | Int _ + | Int64 _ -> () + ) (snd style); + + if !pr_newline then pr "\n"; + in + (* Generate code to generate guestfish call traces. *) let trace_call shortname style = pr " if (guestfs__get_trace (g)) {\n"; @@ -5864,6 +6001,7 @@ check_state (guestfs_h *g, const char *caller) generate_prototype ~extern:false ~semicolon:false ~newline:true ~handle:"g" name style; pr "{\n"; + check_null_strings shortname style; trace_call shortname style; pr " return guestfs__%s " shortname; generate_c_call_args ~handle:"g" style; @@ -5876,21 +6014,12 @@ check_state (guestfs_h *g, const char *caller) List.iter ( fun (shortname, style, _, _, _, _, _) -> let name = "guestfs_" ^ shortname in + let error_code = error_code_of (fst style) in (* Generate the action stub. *) generate_prototype ~extern:false ~semicolon:false ~newline:true ~handle:"g" name style; - let error_code = - match fst style with - | RErr | RInt _ | RInt64 _ | RBool _ -> "-1" - | RConstString _ | RConstOptString _ -> - failwithf "RConstString|RConstOptString cannot be used by daemon functions" - | RString _ | RStringList _ - | RStruct _ | RStructList _ - | RHashtable _ | RBufferOut _ -> - "NULL" in - pr "{\n"; (match snd style with @@ -5915,6 +6044,7 @@ check_state (guestfs_h *g, const char *caller) pr " int serial;\n"; pr " int r;\n"; pr "\n"; + check_null_strings shortname style; trace_call shortname style; pr " if (check_state (g, \"%s\") == -1) return %s;\n" shortname error_code; @@ -7391,6 +7521,9 @@ and generate_fish_cmds () = pr "#include \"xstrtol.h\"\n"; pr "#include \"fish.h\"\n"; pr "\n"; + pr "/* Valid suffixes allowed for numbers. See Gnulib xstrtol function. */\n"; + pr "static const char *xstrtol_suffixes = \"0kKMGTPEZY\";\n"; + pr "\n"; (* list_commands function, which implements guestfish -h *) pr "void list_commands (void)\n"; @@ -7609,7 +7742,7 @@ and generate_fish_cmds () = pr " strtol_error xerr;\n"; pr " %s r;\n" fntyp; pr "\n"; - pr " xerr = %s (argv[%d], NULL, 0, &r, \"\");\n" fn i; + pr " xerr = %s (argv[%d], NULL, 0, &r, xstrtol_suffixes);\n" fn i; pr " if (xerr != LONGINT_OK) {\n"; pr " fprintf (stderr,\n"; pr " _(\"%%s: %%s: invalid integer parameter (%%s returned %%d)\\n\"),\n"; @@ -9024,6 +9157,12 @@ and generate_python_c () = #define PY_SSIZE_T_CLEAN 1 #include +#if PY_VERSION_HEX < 0x02050000 +typedef int Py_ssize_t; +#define PY_SSIZE_T_MAX INT_MAX +#define PY_SSIZE_T_MIN INT_MIN +#endif + #include #include #include @@ -10946,9 +11085,12 @@ print_strings (char *const *argv) | FileIn n | FileOut n -> pr " printf (\"%%s\\n\", %s);\n" n | BufferIn n -> - pr " for (size_t i = 0; i < %s_size; ++i)\n" n; - pr " printf (\"<%%02x>\", %s[i]);\n" n; - pr " printf (\"\\n\");\n" + pr " {\n"; + pr " size_t i;\n"; + pr " for (i = 0; i < %s_size; ++i)\n" n; + pr " printf (\"<%%02x>\", %s[i]);\n" n; + pr " printf (\"\\n\");\n"; + pr " }\n"; | OptString n -> pr " printf (\"%%s\\n\", %s ? %s : \"null\");\n" n n | StringList n | DeviceList n -> pr " print_strings (%s);\n" n | Bool n -> pr " printf (\"%%s\\n\", %s ? \"true\" : \"false\");\n" n