*
* Between each test we blockdev-setrw, umount-all, lvm-remove-all.
*
- * If the appliance is running an older Linux kernel (eg. RHEL 5) then
- * devices are named /dev/hda etc. To cope with this, the test suite
- * adds some hairly logic to detect this case, and then automagically
- * replaces all strings which match "/dev/sd.*" with "/dev/hd.*".
- * When writing test cases you shouldn't have to worry about this
- * difference.
- *
* Don't assume anything about the previous contents of the block
* devices. Use 'Init*' to create some initial scenarios.
*
The single parameter is an argv-style list of arguments.
The first element is the name of the program to run.
Subsequent elements are parameters. The list must be
-non-empty (ie. must contain a program name).
+non-empty (ie. must contain a program name). Note that
+the command runs directly, and is I<not> invoked via
+the shell (see C<guestfs_sh>).
The return value is anything printed to I<stdout> by
the command.
"run a command, returning lines",
"\
This is the same as C<guestfs_command>, but splits the
-result into a list of lines.");
+result into a list of lines.
+
+See also: C<guestfs_sh_lines>");
("stat", (RStat "statbuf", [String "path"]), 52, [],
[InitBasicFS, Always, TestOutputStruct (
would succeed, or some non-zero value documented in the
L<ntfs-3g.probe(8)> manual page.");
+ ("sh", (RString "output", [String "command"]), 111, [],
+ [], (* XXX needs tests *)
+ "run a command via the shell",
+ "\
+This call runs a command from the guest filesystem via the
+guest's C</bin/sh>.
+
+This is like C<guestfs_command>, but passes the command to:
+
+ /bin/sh -c \"command\"
+
+Depending on the guest's shell, this usually results in
+wildcards being expanded, shell expressions being interpolated
+and so on.
+
+All the provisos about C<guestfs_command> apply to this call.");
+
+ ("sh_lines", (RStringList "lines", [String "command"]), 112, [],
+ [], (* XXX needs tests *)
+ "run a command via the shell returning lines",
+ "\
+This is the same as C<guestfs_sh>, but splits the result
+into a list of lines.
+
+See also: C<guestfs_command_lines>");
+
+ ("glob_expand", (RStringList "paths", [String "pattern"]), 113, [],
+ [InitBasicFS, Always, TestOutputList (
+ [["mkdir_p"; "/a/b/c"];
+ ["touch"; "/a/b/c/d"];
+ ["touch"; "/a/b/c/e"];
+ ["glob_expand"; "/a/b/c/*"]], ["/a/b/c/d"; "/a/b/c/e"]);
+ InitBasicFS, Always, TestOutputList (
+ [["mkdir_p"; "/a/b/c"];
+ ["touch"; "/a/b/c/d"];
+ ["touch"; "/a/b/c/e"];
+ ["glob_expand"; "/a/*/c/*"]], ["/a/b/c/d"; "/a/b/c/e"]);
+ InitBasicFS, Always, TestOutputList (
+ [["mkdir_p"; "/a/b/c"];
+ ["touch"; "/a/b/c/d"];
+ ["touch"; "/a/b/c/e"];
+ ["glob_expand"; "/a/*/x/*"]], [])],
+ "expand a wildcard path",
+ "\
+This command searches for all the pathnames matching
+C<pattern> according to the wildcard expansion rules
+used by the shell.
+
+If no paths match, then this returns an empty list
+(note: not an error).
+
+It is just a wrapper around the C L<glob(3)> function
+with flags C<GLOB_MARK|GLOB_BRACE>.
+See that manual page for more details.");
+
]
let all_functions = non_daemon_functions @ daemon_functions
) daemon_functions;
pr " default:\n";
- pr " reply_with_error (\"dispatch_incoming_message: unknown procedure number %%d\", proc_nr);\n";
+ pr " reply_with_error (\"dispatch_incoming_message: unknown procedure number %%d, set LIBGUESTFS_PATH to point to the matching libguestfs appliance directory\", proc_nr);\n";
pr " }\n";
pr "}\n";
pr "\n";
printf (\"guestfs_launch FAILED\\n\");
exit (1);
}
+
+ /* 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);
+
nr_tests = %d;
" (500 * 1024 * 1024) (50 * 1024 * 1024) (10 * 1024 * 1024) nr_tests;
len = strlen (text);
}
+ rl_attempted_completion_over = 1;
+
while ((name = commands[index]) != NULL) {
index++;
if (strncasecmp (name, text, len) == 0)
char **matches = NULL;
#ifdef HAVE_LIBREADLINE
+ rl_completion_append_character = ' ';
+
if (start == 0)
matches = rl_completion_matches (text, generator);
+ else if (complete_dest_paths)
+ matches = rl_completion_matches (text, complete_dest_paths_generator);
#endif
return matches;
List.iter (
function
| String n | FileIn n | FileOut n ->
+ pr " Check_Type (%sv, T_STRING);\n" n;
pr " const char *%s = StringValueCStr (%sv);\n" n n;
pr " if (!%s)\n" n;
pr " rb_raise (rb_eTypeError, \"expected string for parameter %%s of %%s\",\n";
| OptString n ->
pr " const char *%s = !NIL_P (%sv) ? StringValueCStr (%sv) : NULL;\n" n n n
| StringList n ->
- pr " char **%s;" n;
+ pr " char **%s;\n" n;
+ pr " Check_Type (%sv, T_ARRAY);\n" n;
pr " {\n";
pr " int i, len;\n";
pr " len = RARRAY_LEN (%sv);\n" n;