Fix FileIn cmds losing synch if both ends send cancel messages (RHBZ#576879).
[libguestfs.git] / src / generator.ml
index 31ef313..73ab8fa 100755 (executable)
@@ -181,7 +181,6 @@ type flags =
   | ProtocolLimitWarning  (* display warning about protocol size limits *)
   | DangerWillRobinson   (* flags particularly dangerous commands *)
   | FishAlias of string          (* provide an alias for this cmd in guestfish *)
-  | FishAction of string  (* call this function in guestfish *)
   | FishOutput of fish_output_t (* how to display output in guestfish *)
   | NotInFish            (* do not export via guestfish *)
   | NotInDocs            (* do not add this function to documentation *)
@@ -2464,12 +2463,41 @@ the list of printable strings found.");
    "print the printable strings in a file",
    "\
 This is like the C<guestfs_strings> command, but allows you to
-specify the encoding.
+specify the encoding of strings that are looked for in
+the source file C<path>.
 
-See the L<strings(1)> manpage for the full list of encodings.
+Allowed encodings are:
 
-Commonly useful encodings are C<l> (lower case L) which will
-show strings inside Windows/x86 files.
+=over 4
+
+=item s
+
+Single 7-bit-byte characters like ASCII and the ASCII-compatible
+parts of ISO-8859-X (this is what C<guestfs_strings> uses).
+
+=item S
+
+Single 8-bit-byte characters.
+
+=item b
+
+16-bit big endian strings such as those encoded in
+UTF-16BE or UCS-2BE.
+
+=item l (lower case letter L)
+
+16-bit little endian such as UTF-16LE and UCS-2LE.
+This is useful for examining binaries in Windows guests.
+
+=item B
+
+32-bit big endian such as UCS-4BE.
+
+=item L
+
+32-bit little endian such as UCS-4LE.
+
+=back
 
 The returned strings are transcoded to UTF-8.");
 
@@ -4253,7 +4281,9 @@ content of the file is C<len> octets of C<c>, where C<c>
 must be a number in the range C<[0..255]>.
 
 To fill a file with zero bytes (sparsely), it is
-much more efficient to use C<guestfs_truncate_size>.");
+much more efficient to use C<guestfs_truncate_size>.
+To create a file with a pattern of repeating bytes
+use C<guestfs_fill_pattern>.");
 
   ("available", (RErr, [StringList "groups"]), 216, [],
    [InitNone, Always, TestRun [["available"; ""]]],
@@ -4613,6 +4643,17 @@ filename is not printable, coreutils uses a special
 backslash syntax.  For more information, see the GNU
 coreutils info file.");
 
+  ("fill_pattern", (RErr, [String "pattern"; Int "len"; Pathname "path"]), 245, [],
+   [InitBasicFS, Always, TestOutputBuffer (
+      [["fill_pattern"; "abcdefghijklmnopqrstuvwxyz"; "28"; "/test"];
+       ["read_file"; "/test"]], "abcdefghijklmnopqrstuvwxyzab")],
+   "fill a file with a repeating pattern of bytes",
+   "\
+This function is like C<guestfs_fill> except that it creates
+a new file of length C<len> containing the repeating pattern
+of bytes in C<pattern>.  The pattern is truncated if necessary
+to ensure the length of the file is exactly C<len> bytes.");
+
 ]
 
 let all_functions = non_daemon_functions @ daemon_functions
@@ -4624,6 +4665,16 @@ let all_functions_sorted =
   List.sort (fun (n1,_,_,_,_,_,_) (n2,_,_,_,_,_,_) ->
                compare n1 n2) all_functions
 
+(* This is used to generate the src/MAX_PROC_NR file which
+ * contains the maximum procedure number, a surrogate for the
+ * ABI version number.  See src/Makefile.am for the details.
+ *)
+let max_proc_nr =
+  let proc_nrs = List.map (
+    fun (_, _, proc_nr, _, _, _, _) -> proc_nr
+  ) daemon_functions in
+  List.fold_left max 0 proc_nrs
+
 (* Field types for structures. *)
 type field =
   | FChar                      (* C 'char' (really, a 7 bit byte). *)
@@ -6147,8 +6198,8 @@ and generate_daemon_actions () =
            pr "\n";
            pr "  if (!xdr_guestfs_%s_args (xdr_in, &args)) {\n" name;
            if is_filein then
-             pr "    cancel_receive ();\n";
-           pr "    reply_with_error (\"daemon failed to decode procedure arguments\");\n";
+             pr "    if (cancel_receive () != -2)\n";
+           pr "      reply_with_error (\"daemon failed to decode procedure arguments\");\n";
            pr "    goto done;\n";
            pr "  }\n";
            let pr_args n =
@@ -6159,8 +6210,8 @@ and generate_daemon_actions () =
              pr "                sizeof (char *) * (args.%s.%s_len+1));\n" n n;
              pr "  if (%s == NULL) {\n" n;
              if is_filein then
-               pr "    cancel_receive ();\n";
-             pr "    reply_with_perror (\"realloc\");\n";
+               pr "    if (cancel_receive () != -2)\n";
+             pr "      reply_with_perror (\"realloc\");\n";
              pr "    goto done;\n";
              pr "  }\n";
              pr "  %s[args.%s.%s_len] = NULL;\n" n n n;
@@ -6171,15 +6222,15 @@ and generate_daemon_actions () =
              | Pathname n ->
                  pr_args n;
                  pr "  ABS_PATH (%s, %s, goto done);\n"
-                   n (if is_filein then "cancel_receive ()" else "");
+                   n (if is_filein then "cancel_receive ()" else "0");
              | Device n ->
                  pr_args n;
                  pr "  RESOLVE_DEVICE (%s, %s, goto done);\n"
-                   n (if is_filein then "cancel_receive ()" else "");
+                   n (if is_filein then "cancel_receive ()" else "0");
              | Dev_or_Path n ->
                  pr_args n;
                  pr "  REQUIRE_ROOT_OR_RESOLVE_DEVICE (%s, %s, goto done);\n"
-                   n (if is_filein then "cancel_receive ()" else "");
+                   n (if is_filein then "cancel_receive ()" else "0");
              | String n -> pr_args n
              | OptString n -> pr "  %s = args.%s ? *args.%s : NULL;\n" n n n
              | StringList n ->
@@ -6190,7 +6241,7 @@ and generate_daemon_actions () =
                  pr "   * and perform device name translation. */\n";
                  pr "  { int pvi; for (pvi = 0; physvols[pvi] != NULL; ++pvi)\n";
                  pr "    RESOLVE_DEVICE (physvols[pvi], %s, goto done);\n"
-                   (if is_filein then "cancel_receive ()" else "");
+                   (if is_filein then "cancel_receive ()" else "0");
                  pr "  }\n";
              | Bool n -> pr "  %s = args.%s;\n" n n
              | Int n -> pr "  %s = args.%s;\n" n n
@@ -6206,7 +6257,7 @@ and generate_daemon_actions () =
         (* Emit NEED_ROOT just once, even when there are two or
            more Pathname args *)
         pr "  NEED_ROOT (%s, goto done);\n"
-          (if is_filein then "cancel_receive ()" else "");
+          (if is_filein then "cancel_receive ()" else "0");
       );
 
       (* Don't want to call the impl with any FileIn or FileOut
@@ -7575,10 +7626,7 @@ and generate_fish_cmds () =
       ) (snd style);
 
       (* Call C API function. *)
-      let fn =
-        try find_map (function FishAction n -> Some n | _ -> None) flags
-        with Not_found -> sprintf "guestfs_%s" name in
-      pr "  r = %s " fn;
+      pr "  r = guestfs_%s " name;
       generate_c_call_args ~handle:"g" style;
       pr ";\n";
 
@@ -8797,6 +8845,12 @@ package Sys::Guestfs;
 use strict;
 use warnings;
 
+# This version number changes whenever a new function
+# is added to the libguestfs API.  It is not directly
+# related to the libguestfs version number.
+use vars qw($VERSION);
+$VERSION = '0.%d';
+
 require XSLoader;
 XSLoader::load ('Sys::Guestfs');
 
@@ -8815,7 +8869,7 @@ sub new {
   return $self;
 }
 
-";
+" max_proc_nr;
 
   (* Actions.  We only need to print documentation for these as
    * they are pulled in from the XS code automatically.
@@ -11629,17 +11683,7 @@ let inspect ?connect ?xml names =
   parse_operatingsystems xml
 "
 
-(* This is used to generate the src/MAX_PROC_NR file which
- * contains the maximum procedure number, a surrogate for the
- * ABI version number.  See src/Makefile.am for the details.
- *)
 and generate_max_proc_nr () =
-  let proc_nrs = List.map (
-    fun (_, _, proc_nr, _, _, _, _) -> proc_nr
-  ) daemon_functions in
-
-  let max_proc_nr = List.fold_left max 0 proc_nrs in
-
   pr "%d\n" max_proc_nr
 
 let output_to filename k =