[Libguestfs] [PATCH 1/2] New API calls: truncate, truncate_size, mkdir_mode, utimens.
Richard W.M. Jones
rjones at redhat.com
Fri Oct 30 16:19:56 UTC 2009
Almost every part of the FUSE API is already covered by the guestfs
API, because I looked at this before. This patch implements the four
missing API calls required to complete it.
Rich.
--
Richard Jones, Virtualization Group, Red Hat http://people.redhat.com/~rjones
virt-top is 'top' for virtual machines. Tiny program with many
powerful monitoring features, net stats, disk stats, logging, etc.
http://et.redhat.com/~rjones/virt-top
-------------- next part --------------
>From c440c92ea4b716acc99794a2363fca318c539374 Mon Sep 17 00:00:00 2001
From: Richard Jones <rjones at redhat.com>
Date: Fri, 30 Oct 2009 16:10:45 +0000
Subject: [PATCH 1/2] New API calls: truncate, truncate_size, mkdir_mode, utimens.
truncate, truncate_size: Used to truncate files to a particular
size, or to zero bytes.
mkdir_mode: Like mkdir but allows you to also specify the
initial permissions for the new directory.
utimens: Set timestamp on a file with nanosecond accuracy.
The implementation is complicated by the fact that we had to
add an Int64 parameter type to the generator.
---
TODO | 2 -
daemon/Makefile.am | 2 +
daemon/dir.c | 17 ++++++
daemon/truncate.c | 65 +++++++++++++++++++++
daemon/utimens.c | 81 ++++++++++++++++++++++++++
perl/typemap | 1 +
po/POTFILES.in | 2 +
src/MAX_PROC_NR | 2 +-
src/generator.ml | 158 +++++++++++++++++++++++++++++++++++++++++++--------
9 files changed, 302 insertions(+), 28 deletions(-)
create mode 100644 daemon/truncate.c
create mode 100644 daemon/utimens.c
diff --git a/TODO b/TODO
index 2833d46..fc14cdc 100644
--- a/TODO
+++ b/TODO
@@ -145,9 +145,7 @@ Ideas for extra commands
General glibc / core programs:
chgrp
dd (?)
- utime / utimes / futimes / futimens / l..
more mk*temp calls
- trunc[ate??]
ext2 properties:
chattr
diff --git a/daemon/Makefile.am b/daemon/Makefile.am
index dce868a..db311ab 100644
--- a/daemon/Makefile.am
+++ b/daemon/Makefile.am
@@ -74,8 +74,10 @@ guestfsd_SOURCES = \
swap.c \
sync.c \
tar.c \
+ truncate.c \
umask.c \
upload.c \
+ utimens.c \
wc.c \
xattr.c \
zero.c \
diff --git a/daemon/dir.c b/daemon/dir.c
index 1ca6286..b603cfd 100644
--- a/daemon/dir.c
+++ b/daemon/dir.c
@@ -99,6 +99,23 @@ do_mkdir (const char *path)
return 0;
}
+int
+do_mkdir_mode (const char *path, int mode)
+{
+ int r;
+
+ CHROOT_IN;
+ r = mkdir (path, mode);
+ CHROOT_OUT;
+
+ if (r == -1) {
+ reply_with_perror ("mkdir_mode: %s", path);
+ return -1;
+ }
+
+ return 0;
+}
+
static int
recursive_mkdir (const char *path)
{
diff --git a/daemon/truncate.c b/daemon/truncate.c
new file mode 100644
index 0000000..c2da382
--- /dev/null
+++ b/daemon/truncate.c
@@ -0,0 +1,65 @@
+/* libguestfs - the guestfsd daemon
+ * Copyright (C) 2009 Red Hat Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include <config.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <sys/types.h>
+
+#include "../src/guestfs_protocol.h"
+#include "daemon.h"
+#include "actions.h"
+
+int
+do_truncate_size (const char *path, int64_t size)
+{
+ int fd;
+ int r;
+
+ CHROOT_IN;
+ fd = open (path, O_WRONLY | O_NOCTTY);
+ CHROOT_OUT;
+
+ if (fd == -1) {
+ reply_with_perror ("open: %s", path);
+ return -1;
+ }
+
+ r = ftruncate (fd, (off_t) size);
+ if (r == -1) {
+ reply_with_perror ("ftruncate: %s", path);
+ close (fd);
+ return -1;
+ }
+
+ if (close (fd) == -1) {
+ reply_with_perror ("close: %s", path);
+ return -1;
+ }
+
+ return 0;
+}
+
+int
+do_truncate (const char *path)
+{
+ return do_truncate_size (path, 0);
+}
diff --git a/daemon/utimens.c b/daemon/utimens.c
new file mode 100644
index 0000000..2d0e3bf
--- /dev/null
+++ b/daemon/utimens.c
@@ -0,0 +1,81 @@
+/* libguestfs - the guestfsd daemon
+ * Copyright (C) 2009 Red Hat Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include <config.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <sys/stat.h>
+
+#include "../src/guestfs_protocol.h"
+#include "daemon.h"
+#include "actions.h"
+
+int
+do_utimens (const char *path,
+ int64_t atsecs, int64_t atnsecs,
+ int64_t mtsecs, int64_t mtnsecs)
+{
+#ifndef HAVE_FUTIMENS
+ reply_with_error ("utimens: not supported in this appliance");
+ return -1;
+#else
+ int fd;
+ int r;
+
+ CHROOT_IN;
+ fd = open (path, O_WRONLY | O_NOCTTY);
+ CHROOT_OUT;
+
+ if (fd == -1) {
+ reply_with_perror ("open: %s", path);
+ return -1;
+ }
+
+ if (atnsecs == -1)
+ atnsecs = UTIME_NOW;
+ if (atnsecs == -2)
+ atnsecs = UTIME_OMIT;
+ if (mtnsecs == -1)
+ mtnsecs = UTIME_NOW;
+ if (mtnsecs == -2)
+ mtnsecs = UTIME_OMIT;
+
+ struct timespec times[2];
+ times[0].tv_sec = atsecs;
+ times[0].tv_nsec = atnsecs;
+ times[1].tv_sec = mtsecs;
+ times[1].tv_nsec = mtnsecs;
+
+ r = futimens (fd, times);
+ if (r == -1) {
+ reply_with_perror ("futimens: %s", path);
+ close (fd);
+ return -1;
+ }
+
+ if (close (fd) == -1) {
+ reply_with_perror ("close: %s", path);
+ return -1;
+ }
+
+ return 0;
+#endif /* HAVE_FUTIMENS */
+}
diff --git a/perl/typemap b/perl/typemap
index 97788d3..752ca0d 100644
--- a/perl/typemap
+++ b/perl/typemap
@@ -2,6 +2,7 @@ TYPEMAP
char * T_PV
const char * T_PV
guestfs_h * O_OBJECT_guestfs_h
+int64_t T_IV
INPUT
O_OBJECT_guestfs_h
diff --git a/po/POTFILES.in b/po/POTFILES.in
index f6afb60..8c3c8f5 100644
--- a/po/POTFILES.in
+++ b/po/POTFILES.in
@@ -49,8 +49,10 @@ daemon/stubs.c
daemon/swap.c
daemon/sync.c
daemon/tar.c
+daemon/truncate.c
daemon/umask.c
daemon/upload.c
+daemon/utimens.c
daemon/wc.c
daemon/xattr.c
daemon/zero.c
diff --git a/src/MAX_PROC_NR b/src/MAX_PROC_NR
index ca55a6c..8f897c8 100644
--- a/src/MAX_PROC_NR
+++ b/src/MAX_PROC_NR
@@ -1 +1 @@
-198
+202
diff --git a/src/generator.ml b/src/generator.ml
index 4e056e2..bc1aa1a 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";
]
@@ -3715,6 +3717,57 @@ 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<guestfs_mount> call).");
+ ("truncate", (RErr, [Pathname "path"]), 199, [],
+ [InitBasicFS, Always, TestOutputStruct (
+ [["truncate"; "/test"];
+ ["stat"; "/test"]], [CompareWithInt ("size", 0)])],
+ "truncate a file to zero size",
+ "\
+This command truncates C<path> to a zero-length file. The
+file must exist already.");
+
+ ("truncate_size", (RErr, [Pathname "path"; Int64 "size"]), 200, [],
+ [InitBasicFS, Always, TestOutputStruct (
+ [["truncate_size"; "/test"; "1000"];
+ ["stat"; "/test"]], [CompareWithInt ("size", 1000)])],
+ "truncate a file to a particular size",
+ "\
+This command truncates C<path> to size C<size> bytes. The file
+must exist already. If the file is smaller than C<size> 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 (
+ [["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<atsecs, atnsecs> are the last access time (atime) in secs and
+nanoseconds from the epoch.
+
+C<mtsecs, mtnsecs> 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", 0o10111)])],
+ "create a directory with a particular mode",
+ "\
+This command creates a directory, setting the initial permissions
+of the directory to C<mode>. See also C<guestfs_mkdir>.");
+
]
let all_functions = non_daemon_functions @ daemon_functions
@@ -3965,6 +4018,7 @@ type callt =
| CallOptString of string option
| CallStringList of string list
| CallInt of int
+ | CallInt64 of int64
| CallBool of bool
(* Used to memoize the result of pod2text. *)
@@ -4102,7 +4156,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 =
@@ -4518,11 +4572,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"
@@ -4711,6 +4767,8 @@ and generate_client_actions () =
pr "\
#include <stdio.h>
#include <stdlib.h>
+#include <stdint.h>
+#include <inttypes.h>
#include \"guestfs.h\"
#include \"guestfs-internal-actions.h\"
@@ -4813,6 +4871,8 @@ check_state (guestfs_h *g, const char *caller)
pr " fputs (%s ? \" true\" : \" false\", stdout);\n" n
| Int n -> (* int *)
pr " printf (\" %%d\", %s);\n" n
+ | Int64 n ->
+ pr " printf (\" %%\" PRIi64, %s);\n" n
) (snd style);
pr " putchar ('\\n');\n";
pr " }\n";
@@ -4902,6 +4962,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"
@@ -5104,6 +5166,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
);
@@ -5155,6 +5218,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"
@@ -6057,6 +6121,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 ->
@@ -6115,6 +6180,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);
@@ -6379,6 +6450,7 @@ and generate_fish_cmds () =
| 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. *)
@@ -6415,6 +6487,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. *)
@@ -6429,7 +6503,7 @@ and generate_fish_cmds () =
function
| 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 ->
@@ -6648,6 +6722,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";
@@ -6720,6 +6795,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)
@@ -7002,6 +7078,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
@@ -7040,7 +7118,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);
@@ -7132,6 +7211,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 *)
@@ -7283,12 +7363,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)
@@ -7660,7 +7742,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
@@ -7927,6 +8009,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";
@@ -7940,6 +8023,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";
@@ -7950,6 +8036,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";
@@ -7959,7 +8046,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
@@ -7974,7 +8061,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);
@@ -8304,6 +8391,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";
@@ -8331,7 +8420,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);
@@ -8654,6 +8743,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";
@@ -8773,6 +8864,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";
@@ -8826,6 +8919,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 =
@@ -8867,7 +8962,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);
@@ -8896,7 +8992,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. *)
@@ -9158,7 +9255,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 =
@@ -9166,6 +9263,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
@@ -9222,6 +9320,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
);
@@ -9302,6 +9401,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";
@@ -9417,6 +9517,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
)
@@ -9450,6 +9552,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
)
@@ -9480,6 +9583,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
)
@@ -9510,6 +9614,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
)
@@ -9545,6 +9650,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
)
@@ -9587,6 +9693,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
@@ -9605,43 +9713,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. *)
--
1.6.5.rc2
More information about the Libguestfs
mailing list