summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRichard Jones <rjones@redhat.com>2009-10-30 16:10:45 +0000
committerRichard Jones <rjones@redhat.com>2009-11-02 16:37:51 +0000
commit2eb19f526164a978c373a760deb30854d56b62ce (patch)
tree33798414007f6d8bdf78e6cef6a354efad642f18
parent00425c073e5c0743ef425cd12108a85ac36b15f4 (diff)
downloadlibguestfs-2eb19f526164a978c373a760deb30854d56b62ce.tar.gz
libguestfs-2eb19f526164a978c373a760deb30854d56b62ce.tar.xz
libguestfs-2eb19f526164a978c373a760deb30854d56b62ce.zip
New API calls: truncate, truncate_size, mkdir_mode, utimens, lchown.
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. lchown: Corresponding to lchown(2) syscall (we already have chown). The implementation is complicated by the fact that we had to add an Int64 parameter type to the generator.
-rw-r--r--TODO2
-rw-r--r--bindtests13
-rw-r--r--daemon/Makefile.am2
-rw-r--r--daemon/dir.c17
-rw-r--r--daemon/file.c17
-rw-r--r--daemon/truncate.c65
-rw-r--r--daemon/utimens.c81
-rw-r--r--perl/typemap1
-rw-r--r--po/POTFILES.in2
-rw-r--r--src/MAX_PROC_NR2
-rwxr-xr-xsrc/generator.ml173
11 files changed, 347 insertions, 28 deletions
diff --git a/TODO b/TODO
index 2833d461..fc14cdc8 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/bindtests b/bindtests
index 6fbec995..e1772dbf 100644
--- a/bindtests
+++ b/bindtests
@@ -3,6 +3,7 @@ def
[]
false
0
+0
123
456
abc
@@ -10,6 +11,7 @@ null
[]
false
0
+0
123
456
@@ -17,6 +19,7 @@ def
[]
false
0
+0
123
456
@@ -24,6 +27,7 @@ false
[]
false
0
+0
123
456
abc
@@ -31,6 +35,7 @@ def
["1"]
false
0
+0
123
456
abc
@@ -38,6 +43,7 @@ def
["1", "2"]
false
0
+0
123
456
abc
@@ -45,6 +51,7 @@ def
["1"]
true
0
+0
123
456
abc
@@ -52,6 +59,7 @@ def
["1"]
false
-1
+-1
123
456
abc
@@ -59,6 +67,7 @@ def
["1"]
false
-2
+-2
123
456
abc
@@ -66,6 +75,7 @@ def
["1"]
false
1
+1
123
456
abc
@@ -73,6 +83,7 @@ def
["1"]
false
2
+2
123
456
abc
@@ -80,6 +91,7 @@ def
["1"]
false
4095
+4095
123
456
abc
@@ -87,6 +99,7 @@ def
["1"]
false
0
+0
EOF
diff --git a/daemon/Makefile.am b/daemon/Makefile.am
index dce868a6..db311abd 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 1ca62868..b603cfd0 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/file.c b/daemon/file.c
index 212aff28..7e2f062a 100644
--- a/daemon/file.c
+++ b/daemon/file.c
@@ -232,6 +232,23 @@ do_chown (int owner, int group, const char *path)
}
int
+do_lchown (int owner, int group, const char *path)
+{
+ int r;
+
+ CHROOT_IN;
+ r = lchown (path, owner, group);
+ CHROOT_OUT;
+
+ if (r == -1) {
+ reply_with_perror ("lchown: %s: %d.%d", path, owner, group);
+ return -1;
+ }
+
+ return 0;
+}
+
+int
do_exists (const char *path)
{
int r;
diff --git a/daemon/truncate.c b/daemon/truncate.c
new file mode 100644
index 00000000..c2da3828
--- /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 00000000..2d0e3bfc
--- /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 97788d30..752ca0d7 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 f6afb60d..8c3c8f50 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 ca55a6c5..bb2ee191 100644
--- a/src/MAX_PROC_NR
+++ b/src/MAX_PROC_NR
@@ -1 +1 @@
-198
+203
diff --git a/src/generator.ml b/src/generator.ml
index 32494592..b8add4c0 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,72 @@ 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 (
+ [["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<path> 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<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 (
+ [["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<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", 0o40111)])],
+ "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>.");
+
+ ("lchown", (RErr, [Int "owner"; Int "group"; Pathname "path"]), 203, [],
+ [], (* XXX *)
+ "change file owner and group",
+ "\
+Change the file owner to C<owner> and group to C<group>.
+This is like C<guestfs_chown> but if C<path> 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
@@ -3955,6 +4023,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. *)
@@ -4092,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 =
@@ -4508,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"
@@ -4701,6 +4772,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\"
@@ -4803,6 +4876,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";
@@ -4892,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"
@@ -5094,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
);
@@ -5145,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"
@@ -6047,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 ->
@@ -6105,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);
@@ -6369,6 +6455,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. *)
@@ -6405,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. *)
@@ -6419,7 +6508,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 ->
@@ -6638,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";
@@ -6710,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)
@@ -6992,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
@@ -7030,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);
@@ -7122,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 *)
@@ -7273,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)
@@ -7650,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
@@ -7917,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";
@@ -7930,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";
@@ -7940,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";
@@ -7949,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
@@ -7964,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);
@@ -8294,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";
@@ -8321,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);
@@ -8644,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";
@@ -8763,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";
@@ -8816,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 =
@@ -8857,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);
@@ -8886,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. *)
@@ -9148,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 =
@@ -9156,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
@@ -9212,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
);
@@ -9292,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";
@@ -9407,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
)
@@ -9440,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
)
@@ -9470,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
)
@@ -9500,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
)
@@ -9535,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
)
@@ -9577,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
@@ -9595,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. *)