summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--daemon/actions.h3
-rw-r--r--daemon/stubs.c90
-rw-r--r--fish/cmds.c104
-rw-r--r--fish/completion.c3
-rw-r--r--guestfish-actions.pod30
-rw-r--r--guestfs-actions.pod63
-rw-r--r--ocaml/guestfs.ml33
-rw-r--r--ocaml/guestfs.mli39
-rw-r--r--ocaml/guestfs_c_actions.c140
-rw-r--r--perl/Guestfs.xs76
-rw-r--r--perl/lib/Sys/Guestfs.pm24
-rw-r--r--python/guestfs-py.c144
-rw-r--r--python/guestfs.py9
-rw-r--r--src/guestfs-actions.c225
-rw-r--r--src/guestfs-actions.h3
-rw-r--r--src/guestfs-structs.h30
-rw-r--r--src/guestfs_protocol.c124
-rw-r--r--src/guestfs_protocol.h83
-rw-r--r--src/guestfs_protocol.x57
-rw-r--r--tests.c609
20 files changed, 1540 insertions, 349 deletions
diff --git a/daemon/actions.h b/daemon/actions.h
index 90aeb8d0..c0f41ce1 100644
--- a/daemon/actions.h
+++ b/daemon/actions.h
@@ -72,3 +72,6 @@ extern int do_lvm_remove_all (void);
extern char *do_file (const char *path);
extern char *do_command (char * const* const arguments);
extern char **do_command_lines (char * const* const arguments);
+extern guestfs_int_stat *do_stat (const char *path);
+extern guestfs_int_stat *do_lstat (const char *path);
+extern guestfs_int_statvfs *do_statvfs (const char *path);
diff --git a/daemon/stubs.c b/daemon/stubs.c
index 9a0dc912..9662de80 100644
--- a/daemon/stubs.c
+++ b/daemon/stubs.c
@@ -1223,6 +1223,87 @@ done:
xdr_free ((xdrproc_t) xdr_guestfs_command_lines_args, (char *) &args);
}
+static void stat_stub (XDR *xdr_in)
+{
+ guestfs_int_stat *r;
+ struct guestfs_stat_args args;
+ const char *path;
+
+ memset (&args, 0, sizeof args);
+
+ if (!xdr_guestfs_stat_args (xdr_in, &args)) {
+ reply_with_error ("%s: daemon failed to decode procedure arguments", "stat");
+ return;
+ }
+ path = args.path;
+
+ r = do_stat (path);
+ if (r == NULL)
+ /* do_stat has already called reply_with_error */
+ goto done;
+
+ struct guestfs_stat_ret ret;
+ ret.statbuf = *r;
+ reply ((xdrproc_t) xdr_guestfs_stat_ret, (char *) &ret);
+ xdr_free ((xdrproc_t) xdr_guestfs_stat_ret, (char *) &ret);
+done:
+ xdr_free ((xdrproc_t) xdr_guestfs_stat_args, (char *) &args);
+}
+
+static void lstat_stub (XDR *xdr_in)
+{
+ guestfs_int_stat *r;
+ struct guestfs_lstat_args args;
+ const char *path;
+
+ memset (&args, 0, sizeof args);
+
+ if (!xdr_guestfs_lstat_args (xdr_in, &args)) {
+ reply_with_error ("%s: daemon failed to decode procedure arguments", "lstat");
+ return;
+ }
+ path = args.path;
+
+ r = do_lstat (path);
+ if (r == NULL)
+ /* do_lstat has already called reply_with_error */
+ goto done;
+
+ struct guestfs_lstat_ret ret;
+ ret.statbuf = *r;
+ reply ((xdrproc_t) xdr_guestfs_lstat_ret, (char *) &ret);
+ xdr_free ((xdrproc_t) xdr_guestfs_lstat_ret, (char *) &ret);
+done:
+ xdr_free ((xdrproc_t) xdr_guestfs_lstat_args, (char *) &args);
+}
+
+static void statvfs_stub (XDR *xdr_in)
+{
+ guestfs_int_statvfs *r;
+ struct guestfs_statvfs_args args;
+ const char *path;
+
+ memset (&args, 0, sizeof args);
+
+ if (!xdr_guestfs_statvfs_args (xdr_in, &args)) {
+ reply_with_error ("%s: daemon failed to decode procedure arguments", "statvfs");
+ return;
+ }
+ path = args.path;
+
+ r = do_statvfs (path);
+ if (r == NULL)
+ /* do_statvfs has already called reply_with_error */
+ goto done;
+
+ struct guestfs_statvfs_ret ret;
+ ret.statbuf = *r;
+ reply ((xdrproc_t) xdr_guestfs_statvfs_ret, (char *) &ret);
+ xdr_free ((xdrproc_t) xdr_guestfs_statvfs_ret, (char *) &ret);
+done:
+ xdr_free ((xdrproc_t) xdr_guestfs_statvfs_args, (char *) &args);
+}
+
void dispatch_incoming_message (XDR *xdr_in)
{
switch (proc_nr) {
@@ -1379,6 +1460,15 @@ void dispatch_incoming_message (XDR *xdr_in)
case GUESTFS_PROC_COMMAND_LINES:
command_lines_stub (xdr_in);
break;
+ case GUESTFS_PROC_STAT:
+ stat_stub (xdr_in);
+ break;
+ case GUESTFS_PROC_LSTAT:
+ lstat_stub (xdr_in);
+ break;
+ case GUESTFS_PROC_STATVFS:
+ statvfs_stub (xdr_in);
+ break;
default:
reply_with_error ("dispatch_incoming_message: unknown procedure number %d", proc_nr);
}
diff --git a/fish/cmds.c b/fish/cmds.c
index b6586140..60aee8c1 100644
--- a/fish/cmds.c
+++ b/fish/cmds.c
@@ -65,6 +65,7 @@ void list_commands (void)
printf ("%-20s %s\n", "list-partitions", "list the partitions");
printf ("%-20s %s\n", "ll", "list the files in a directory (long format)");
printf ("%-20s %s\n", "ls", "list the files in a directory");
+ printf ("%-20s %s\n", "lstat", "get file information for a symbolic link");
printf ("%-20s %s\n", "lvcreate", "create an LVM volume group");
printf ("%-20s %s\n", "lvm-remove-all", "remove all LVM LVs, VGs and PVs");
printf ("%-20s %s\n", "lvs", "list the LVM logical volumes (LVs)");
@@ -85,6 +86,8 @@ void list_commands (void)
printf ("%-20s %s\n", "set-path", "set the search path");
printf ("%-20s %s\n", "set-verbose", "set verbose mode");
printf ("%-20s %s\n", "sfdisk", "create partitions on a block device");
+ printf ("%-20s %s\n", "stat", "get file information");
+ printf ("%-20s %s\n", "statvfs", "get file system statistics");
printf ("%-20s %s\n", "sync", "sync disks, writes are flushed through to the disk image");
printf ("%-20s %s\n", "touch", "update file timestamps or create a new file");
printf ("%-20s %s\n", "umount", "unmount a filesystem");
@@ -284,6 +287,15 @@ void display_command (const char *cmd)
if (strcasecmp (cmd, "command_lines") == 0 || strcasecmp (cmd, "command-lines") == 0)
pod2text ("command-lines - run a command, returning lines", " command-lines <arguments>\n\nThis is the same as C<command>, but splits the\nresult into a list of lines.");
else
+ if (strcasecmp (cmd, "stat") == 0)
+ pod2text ("stat - get file information", " stat <path>\n\nReturns file information for the given C<path>.\n\nThis is the same as the C<stat(2)> system call.");
+ else
+ if (strcasecmp (cmd, "lstat") == 0)
+ pod2text ("lstat - get file information for a symbolic link", " lstat <path>\n\nReturns file information for the given C<path>.\n\nThis is the same as C<stat> except that if C<path>\nis a symbolic link, then the link is stat-ed, not the file it\nrefers to.\n\nThis is the same as the C<lstat(2)> system call.");
+ else
+ if (strcasecmp (cmd, "statvfs") == 0)
+ pod2text ("statvfs - get file system statistics", " statvfs <path>\n\nReturns file system statistics for any mounted file system.\nC<path> should be a file or directory in the mounted file system\n(typically it is the mount point itself, but it doesn't need to be).\n\nThis is the same as the C<statvfs(2)> system call.");
+ else
display_builtin_command (cmd);
}
@@ -389,6 +401,38 @@ static void print_lv_list (struct guestfs_lvm_lv_list *lvs)
print_lv (&lvs->val[i]);
}
+static void print_stat (struct guestfs_stat *stat)
+{
+ printf ("dev: %" PRIi64 "\n", stat->dev);
+ printf ("ino: %" PRIi64 "\n", stat->ino);
+ printf ("mode: %" PRIi64 "\n", stat->mode);
+ printf ("nlink: %" PRIi64 "\n", stat->nlink);
+ printf ("uid: %" PRIi64 "\n", stat->uid);
+ printf ("gid: %" PRIi64 "\n", stat->gid);
+ printf ("rdev: %" PRIi64 "\n", stat->rdev);
+ printf ("size: %" PRIi64 "\n", stat->size);
+ printf ("blksize: %" PRIi64 "\n", stat->blksize);
+ printf ("blocks: %" PRIi64 "\n", stat->blocks);
+ printf ("atime: %" PRIi64 "\n", stat->atime);
+ printf ("mtime: %" PRIi64 "\n", stat->mtime);
+ printf ("ctime: %" PRIi64 "\n", stat->ctime);
+}
+
+static void print_statvfs (struct guestfs_statvfs *statvfs)
+{
+ printf ("bsize: %" PRIi64 "\n", statvfs->bsize);
+ printf ("frsize: %" PRIi64 "\n", statvfs->frsize);
+ printf ("blocks: %" PRIi64 "\n", statvfs->blocks);
+ printf ("bfree: %" PRIi64 "\n", statvfs->bfree);
+ printf ("bavail: %" PRIi64 "\n", statvfs->bavail);
+ printf ("files: %" PRIi64 "\n", statvfs->files);
+ printf ("ffree: %" PRIi64 "\n", statvfs->ffree);
+ printf ("favail: %" PRIi64 "\n", statvfs->favail);
+ printf ("fsid: %" PRIi64 "\n", statvfs->fsid);
+ printf ("flag: %" PRIi64 "\n", statvfs->flag);
+ printf ("namemax: %" PRIi64 "\n", statvfs->namemax);
+}
+
static int run_launch (const char *cmd, int argc, char *argv[])
{
int r;
@@ -1340,6 +1384,57 @@ static int run_command_lines (const char *cmd, int argc, char *argv[])
return 0;
}
+static int run_stat (const char *cmd, int argc, char *argv[])
+{
+ struct guestfs_stat *r;
+ const char *path;
+ if (argc != 1) {
+ fprintf (stderr, "%s should have 1 parameter(s)\n", cmd);
+ fprintf (stderr, "type 'help %s' for help on %s\n", cmd, cmd);
+ return -1;
+ }
+ path = argv[0];
+ r = guestfs_stat (g, path);
+ if (r == NULL) return -1;
+ print_stat (r);
+ free (r);
+ return 0;
+}
+
+static int run_lstat (const char *cmd, int argc, char *argv[])
+{
+ struct guestfs_stat *r;
+ const char *path;
+ if (argc != 1) {
+ fprintf (stderr, "%s should have 1 parameter(s)\n", cmd);
+ fprintf (stderr, "type 'help %s' for help on %s\n", cmd, cmd);
+ return -1;
+ }
+ path = argv[0];
+ r = guestfs_lstat (g, path);
+ if (r == NULL) return -1;
+ print_stat (r);
+ free (r);
+ return 0;
+}
+
+static int run_statvfs (const char *cmd, int argc, char *argv[])
+{
+ struct guestfs_statvfs *r;
+ const char *path;
+ if (argc != 1) {
+ fprintf (stderr, "%s should have 1 parameter(s)\n", cmd);
+ fprintf (stderr, "type 'help %s' for help on %s\n", cmd, cmd);
+ return -1;
+ }
+ path = argv[0];
+ r = guestfs_statvfs (g, path);
+ if (r == NULL) return -1;
+ print_statvfs (r);
+ free (r);
+ return 0;
+}
+
int run_action (const char *cmd, int argc, char *argv[])
{
if (strcasecmp (cmd, "launch") == 0 || strcasecmp (cmd, "run") == 0)
@@ -1528,6 +1623,15 @@ int run_action (const char *cmd, int argc, char *argv[])
if (strcasecmp (cmd, "command_lines") == 0 || strcasecmp (cmd, "command-lines") == 0)
return run_command_lines (cmd, argc, argv);
else
+ if (strcasecmp (cmd, "stat") == 0)
+ return run_stat (cmd, argc, argv);
+ else
+ if (strcasecmp (cmd, "lstat") == 0)
+ return run_lstat (cmd, argc, argv);
+ else
+ if (strcasecmp (cmd, "statvfs") == 0)
+ return run_statvfs (cmd, argc, argv);
+ else
{
fprintf (stderr, "%s: unknown command\n", cmd);
return -1;
diff --git a/fish/completion.c b/fish/completion.c
index 150b1aaa..7b4f818a 100644
--- a/fish/completion.c
+++ b/fish/completion.c
@@ -71,6 +71,7 @@ static const char *commands[] = {
"list-partitions",
"ll",
"ls",
+ "lstat",
"lvcreate",
"lvm-remove-all",
"lvs",
@@ -93,6 +94,8 @@ static const char *commands[] = {
"set-path",
"set-verbose",
"sfdisk",
+ "stat",
+ "statvfs",
"sync",
"touch",
"umount",
diff --git a/guestfish-actions.pod b/guestfish-actions.pod
index fbf2f97c..e240f499 100644
--- a/guestfish-actions.pod
+++ b/guestfish-actions.pod
@@ -377,6 +377,18 @@ hidden files are shown.
This command is mostly useful for interactive sessions. Programs
should probably use C<readdir> instead.
+=head2 lstat
+
+ lstat path
+
+Returns file information for the given C<path>.
+
+This is the same as C<stat> except that if C<path>
+is a symbolic link, then the link is stat-ed, not the file it
+refers to.
+
+This is the same as the C<lstat(2)> system call.
+
=head2 lvcreate
lvcreate logvol volgroup mbytes
@@ -583,6 +595,24 @@ the string C<,> (comma).
B<This command is dangerous. Without careful use you
can easily destroy all your data>.
+=head2 stat
+
+ stat path
+
+Returns file information for the given C<path>.
+
+This is the same as the C<stat(2)> system call.
+
+=head2 statvfs
+
+ statvfs path
+
+Returns file system statistics for any mounted file system.
+C<path> should be a file or directory in the mounted file system
+(typically it is the mount point itself, but it doesn't need to be).
+
+This is the same as the C<statvfs(2)> system call.
+
=head2 sync
sync
diff --git a/guestfs-actions.pod b/guestfs-actions.pod
index 5bd9628b..03378e0a 100644
--- a/guestfs-actions.pod
+++ b/guestfs-actions.pod
@@ -58,7 +58,8 @@ On success this returns a pair containing the
number of nodes in the nodeset, and a boolean flag
if a node was created.
-This function returns a C<struct guestfs_int_bool *>.
+This function returns a C<struct guestfs_int_bool *>,
+or NULL if there was an error.
I<The caller must call C<guestfs_free_int_bool> after use>.
=head2 guestfs_aug_defvar
@@ -500,6 +501,24 @@ This function returns a NULL-terminated array of strings
(like L<environ(3)>), or NULL if there was an error.
I<The caller must free the strings and the array after use>.
+=head2 guestfs_lstat
+
+ struct guestfs_stat *guestfs_lstat (guestfs_h *handle,
+ const char *path);
+
+Returns file information for the given C<path>.
+
+This is the same as C<guestfs_stat> except that if C<path>
+is a symbolic link, then the link is stat-ed, not the file it
+refers to.
+
+This is the same as the C<lstat(2)> system call.
+
+This function returns a C<struct guestfs_stat *>
+(see L<stat(2)> and E<lt>guestfs-structs.hE<gt>),
+or NULL if there was an error.
+I<The caller must call C<free> after use>.
+
=head2 guestfs_lvcreate
int guestfs_lvcreate (guestfs_h *handle,
@@ -547,7 +566,9 @@ I<The caller must free the strings and the array after use>.
List all the logical volumes detected. This is the equivalent
of the L<lvs(8)> command. The "full" version includes all fields.
-This function returns a C<struct guestfs_lvm_lv_list *>.
+This function returns a C<struct guestfs_lvm_lv_list *>
+(see E<lt>guestfs-structs.hE<gt>),
+or NULL if there was an error.
I<The caller must call C<guestfs_free_lvm_lv_list> after use>.
=head2 guestfs_mkdir
@@ -653,7 +674,9 @@ I<The caller must free the strings and the array after use>.
List all the physical volumes detected. This is the equivalent
of the L<pvs(8)> command. The "full" version includes all fields.
-This function returns a C<struct guestfs_lvm_pv_list *>.
+This function returns a C<struct guestfs_lvm_pv_list *>
+(see E<lt>guestfs-structs.hE<gt>),
+or NULL if there was an error.
I<The caller must call C<guestfs_free_lvm_pv_list> after use>.
=head2 guestfs_read_lines
@@ -778,6 +801,36 @@ This function returns 0 on success or -1 on error.
B<This command is dangerous. Without careful use you
can easily destroy all your data>.
+=head2 guestfs_stat
+
+ struct guestfs_stat *guestfs_stat (guestfs_h *handle,
+ const char *path);
+
+Returns file information for the given C<path>.
+
+This is the same as the C<stat(2)> system call.
+
+This function returns a C<struct guestfs_stat *>
+(see L<stat(2)> and E<lt>guestfs-structs.hE<gt>),
+or NULL if there was an error.
+I<The caller must call C<free> after use>.
+
+=head2 guestfs_statvfs
+
+ struct guestfs_statvfs *guestfs_statvfs (guestfs_h *handle,
+ const char *path);
+
+Returns file system statistics for any mounted file system.
+C<path> should be a file or directory in the mounted file system
+(typically it is the mount point itself, but it doesn't need to be).
+
+This is the same as the C<statvfs(2)> system call.
+
+This function returns a C<struct guestfs_statvfs *>
+(see L<statvfs(2)> and E<lt>guestfs-structs.hE<gt>),
+or NULL if there was an error.
+I<The caller must call C<free> after use>.
+
=head2 guestfs_sync
int guestfs_sync (guestfs_h *handle);
@@ -856,7 +909,9 @@ I<The caller must free the strings and the array after use>.
List all the volumes groups detected. This is the equivalent
of the L<vgs(8)> command. The "full" version includes all fields.
-This function returns a C<struct guestfs_lvm_vg_list *>.
+This function returns a C<struct guestfs_lvm_vg_list *>
+(see E<lt>guestfs-structs.hE<gt>),
+or NULL if there was an error.
I<The caller must call C<guestfs_free_lvm_vg_list> after use>.
=head2 guestfs_wait_ready
diff --git a/ocaml/guestfs.ml b/ocaml/guestfs.ml
index fa2e3418..f0344ac7 100644
--- a/ocaml/guestfs.ml
+++ b/ocaml/guestfs.ml
@@ -85,6 +85,36 @@ type lvm_lv = {
modules : string;
}
+type stat = {
+ dev : int64;
+ ino : int64;
+ mode : int64;
+ nlink : int64;
+ uid : int64;
+ gid : int64;
+ rdev : int64;
+ size : int64;
+ blksize : int64;
+ blocks : int64;
+ atime : int64;
+ mtime : int64;
+ ctime : int64;
+}
+
+type statvfs = {
+ bsize : int64;
+ frsize : int64;
+ blocks : int64;
+ bfree : int64;
+ bavail : int64;
+ files : int64;
+ ffree : int64;
+ favail : int64;
+ fsid : int64;
+ flag : int64;
+ namemax : int64;
+}
+
external launch : t -> unit = "ocaml_guestfs_launch"
external wait_ready : t -> unit = "ocaml_guestfs_wait_ready"
external kill_subprocess : t -> unit = "ocaml_guestfs_kill_subprocess"
@@ -148,3 +178,6 @@ external lvm_remove_all : t -> unit = "ocaml_guestfs_lvm_remove_all"
external file : t -> string -> string = "ocaml_guestfs_file"
external command : t -> string array -> string = "ocaml_guestfs_command"
external command_lines : t -> string array -> string array = "ocaml_guestfs_command_lines"
+external stat : t -> string -> stat = "ocaml_guestfs_stat"
+external lstat : t -> string -> stat = "ocaml_guestfs_lstat"
+external statvfs : t -> string -> statvfs = "ocaml_guestfs_statvfs"
diff --git a/ocaml/guestfs.mli b/ocaml/guestfs.mli
index 279ed4d3..30629681 100644
--- a/ocaml/guestfs.mli
+++ b/ocaml/guestfs.mli
@@ -94,6 +94,36 @@ type lvm_lv = {
modules : string;
}
+type stat = {
+ dev : int64;
+ ino : int64;
+ mode : int64;
+ nlink : int64;
+ uid : int64;
+ gid : int64;
+ rdev : int64;
+ size : int64;
+ blksize : int64;
+ blocks : int64;
+ atime : int64;
+ mtime : int64;
+ ctime : int64;
+}
+
+type statvfs = {
+ bsize : int64;
+ frsize : int64;
+ blocks : int64;
+ bfree : int64;
+ bavail : int64;
+ files : int64;
+ ffree : int64;
+ favail : int64;
+ fsid : int64;
+ flag : int64;
+ namemax : int64;
+}
+
val launch : t -> unit
(** launch the qemu subprocess *)
@@ -283,3 +313,12 @@ val command : t -> string array -> string
val command_lines : t -> string array -> string array
(** run a command, returning lines *)
+val stat : t -> string -> stat
+(** get file information *)
+
+val lstat : t -> string -> stat
+(** get file information for a symbolic link *)
+
+val statvfs : t -> string -> statvfs
+(** get file system statistics *)
+
diff --git a/ocaml/guestfs_c_actions.c b/ocaml/guestfs_c_actions.c
index 356965dc..01fbcb06 100644
--- a/ocaml/guestfs_c_actions.c
+++ b/ocaml/guestfs_c_actions.c
@@ -233,6 +233,74 @@ copy_lvm_lv_list (const struct guestfs_lvm_lv_list *lvs)
}
}
+static CAMLprim value
+copy_stat (const struct guestfs_stat *stat)
+{
+ CAMLparam0 ();
+ CAMLlocal2 (rv, v);
+
+ rv = caml_alloc (13, 0);
+ v = caml_copy_int64 (stat->dev);
+ Store_field (rv, 0, v);
+ v = caml_copy_int64 (stat->ino);
+ Store_field (rv, 1, v);
+ v = caml_copy_int64 (stat->mode);
+ Store_field (rv, 2, v);
+ v = caml_copy_int64 (stat->nlink);
+ Store_field (rv, 3, v);
+ v = caml_copy_int64 (stat->uid);
+ Store_field (rv, 4, v);
+ v = caml_copy_int64 (stat->gid);
+ Store_field (rv, 5, v);
+ v = caml_copy_int64 (stat->rdev);
+ Store_field (rv, 6, v);
+ v = caml_copy_int64 (stat->size);
+ Store_field (rv, 7, v);
+ v = caml_copy_int64 (stat->blksize);
+ Store_field (rv, 8, v);
+ v = caml_copy_int64 (stat->blocks);
+ Store_field (rv, 9, v);
+ v = caml_copy_int64 (stat->atime);
+ Store_field (rv, 10, v);
+ v = caml_copy_int64 (stat->mtime);
+ Store_field (rv, 11, v);
+ v = caml_copy_int64 (stat->ctime);
+ Store_field (rv, 12, v);
+ CAMLreturn (rv);
+}
+
+static CAMLprim value
+copy_statvfs (const struct guestfs_statvfs *statvfs)
+{
+ CAMLparam0 ();
+ CAMLlocal2 (rv, v);
+
+ rv = caml_alloc (11, 0);
+ v = caml_copy_int64 (statvfs->bsize);
+ Store_field (rv, 0, v);
+ v = caml_copy_int64 (statvfs->frsize);
+ Store_field (rv, 1, v);
+ v = caml_copy_int64 (statvfs->blocks);
+ Store_field (rv, 2, v);
+ v = caml_copy_int64 (statvfs->bfree);
+ Store_field (rv, 3, v);
+ v = caml_copy_int64 (statvfs->bavail);
+ Store_field (rv, 4, v);
+ v = caml_copy_int64 (statvfs->files);
+ Store_field (rv, 5, v);
+ v = caml_copy_int64 (statvfs->ffree);
+ Store_field (rv, 6, v);
+ v = caml_copy_int64 (statvfs->favail);
+ Store_field (rv, 7, v);
+ v = caml_copy_int64 (statvfs->fsid);
+ Store_field (rv, 8, v);
+ v = caml_copy_int64 (statvfs->flag);
+ Store_field (rv, 9, v);
+ v = caml_copy_int64 (statvfs->namemax);
+ Store_field (rv, 10, v);
+ CAMLreturn (rv);
+}
+
CAMLprim value
ocaml_guestfs_launch (value gv)
{
@@ -1741,3 +1809,75 @@ ocaml_guestfs_command_lines (value gv, value argumentsv)
CAMLreturn (rv);
}
+CAMLprim value
+ocaml_guestfs_stat (value gv, value pathv)
+{
+ CAMLparam2 (gv, pathv);
+ CAMLlocal1 (rv);
+
+ guestfs_h *g = Guestfs_val (gv);
+ if (g == NULL)
+ caml_failwith ("stat: used handle after closing it");
+
+ const char *path = String_val (pathv);
+ struct guestfs_stat *r;
+
+ caml_enter_blocking_section ();
+ r = guestfs_stat (g, path);
+ caml_leave_blocking_section ();
+ if (r == NULL)
+ ocaml_guestfs_raise_error (g, "stat");
+
+ rv = copy_stat (r);
+ free (r);
+ CAMLreturn (rv);
+}
+
+CAMLprim value
+ocaml_guestfs_lstat (value gv, value pathv)
+{
+ CAMLparam2 (gv, pathv);
+ CAMLlocal1 (rv);
+
+ guestfs_h *g = Guestfs_val (gv);
+ if (g == NULL)
+ caml_failwith ("lstat: used handle after closing it");
+
+ const char *path = String_val (pathv);
+ struct guestfs_stat *r;
+
+ caml_enter_blocking_section ();
+ r = guestfs_lstat (g, path);
+ caml_leave_blocking_section ();
+ if (r == NULL)
+ ocaml_guestfs_raise_error (g, "lstat");
+
+ rv = copy_stat (r);
+ free (r);
+ CAMLreturn (rv);
+}
+
+CAMLprim value
+ocaml_guestfs_statvfs (value gv, value pathv)
+{
+ CAMLparam2 (gv, pathv);
+ CAMLlocal1 (rv);
+
+ guestfs_h *g = Guestfs_val (gv);
+ if (g == NULL)
+ caml_failwith ("statvfs: used handle after closing it");
+
+ const char *path = String_val (pathv);
+ struct guestfs_statvfs *r;
+
+ caml_enter_blocking_section ();
+ r = guestfs_statvfs (g, path);
+ caml_leave_blocking_section ();
+ if (r == NULL)
+ ocaml_guestfs_raise_error (g, "statvfs");
+
+ rv = copy_statvfs (r);
+ free (r);
+ CAMLreturn (rv);
+}
+
diff --git a/perl/Guestfs.xs b/perl/Guestfs.xs
index c1eaa11f..37a15e09 100644
--- a/perl/Guestfs.xs
+++ b/perl/Guestfs.xs
@@ -1011,3 +1011,79 @@ PREINIT:
}
free (lines);
+void
+stat (g, path)
+ guestfs_h *g;
+ char *path;
+PREINIT:
+ struct guestfs_stat *statbuf;
+ PPCODE:
+ statbuf = guestfs_stat (g, path);
+ if (statbuf == NULL)
+ croak ("stat: %s", guestfs_last_error (g));
+ EXTEND (SP, 13);
+ PUSHs (sv_2mortal (my_newSVll (statbuf->dev)));
+ PUSHs (sv_2mortal (my_newSVll (statbuf->ino)));
+ PUSHs (sv_2mortal (my_newSVll (statbuf->mode)));
+ PUSHs (sv_2mortal (my_newSVll (statbuf->nlink)));
+ PUSHs (sv_2mortal (my_newSVll (statbuf->uid)));
+ PUSHs (sv_2mortal (my_newSVll (statbuf->gid)));
+ PUSHs (sv_2mortal (my_newSVll (statbuf->rdev)));
+ PUSHs (sv_2mortal (my_newSVll (statbuf->size)));
+ PUSHs (sv_2mortal (my_newSVll (statbuf->blksize)));
+ PUSHs (sv_2mortal (my_newSVll (statbuf->blocks)));
+ PUSHs (sv_2mortal (my_newSVll (statbuf->atime)));
+ PUSHs (sv_2mortal (my_newSVll (statbuf->mtime)));
+ PUSHs (sv_2mortal (my_newSVll (statbuf->ctime)));
+ free (statbuf);
+
+void
+lstat (g, path)
+ guestfs_h *g;
+ char *path;
+PREINIT:
+ struct guestfs_stat *statbuf;
+ PPCODE:
+ statbuf = guestfs_lstat (g, path);
+ if (statbuf == NULL)
+ croak ("lstat: %s", guestfs_last_error (g));
+ EXTEND (SP, 13);
+ PUSHs (sv_2mortal (my_newSVll (statbuf->dev)));
+ PUSHs (sv_2mortal (my_newSVll (statbuf->ino)));
+ PUSHs (sv_2mortal (my_newSVll (statbuf->mode)));
+ PUSHs (sv_2mortal (my_newSVll (statbuf->nlink)));
+ PUSHs (sv_2mortal (my_newSVll (statbuf->uid)));
+ PUSHs (sv_2mortal (my_newSVll (statbuf->gid)));
+ PUSHs (sv_2mortal (my_newSVll (statbuf->rdev)));
+ PUSHs (sv_2mortal (my_newSVll (statbuf->size)));
+ PUSHs (sv_2mortal (my_newSVll (statbuf->blksize)));
+ PUSHs (sv_2mortal (my_newSVll (statbuf->blocks)));
+ PUSHs (sv_2mortal (my_newSVll (statbuf->atime)));
+ PUSHs (sv_2mortal (my_newSVll (statbuf->mtime)));
+ PUSHs (sv_2mortal (my_newSVll (statbuf->ctime)));
+ free (statbuf);
+
+void
+statvfs (g, path)
+ guestfs_h *g;
+ char *path;
+PREINIT:
+ struct guestfs_statvfs *statbuf;
+ PPCODE:
+ statbuf = guestfs_statvfs (g, path);
+ if (statbuf == NULL)
+ croak ("statvfs: %s", guestfs_last_error (g));
+ EXTEND (SP, 11);
+ PUSHs (sv_2mortal (my_newSVll (statbuf->bsize)));
+ PUSHs (sv_2mortal (my_newSVll (statbuf->frsize)));
+ PUSHs (sv_2mortal (my_newSVll (statbuf->blocks)));
+ PUSHs (sv_2mortal (my_newSVll (statbuf->bfree)));
+ PUSHs (sv_2mortal (my_newSVll (statbuf->bavail)));
+ PUSHs (sv_2mortal (my_newSVll (statbuf->files)));
+ PUSHs (sv_2mortal (my_newSVll (statbuf->ffree)));
+ PUSHs (sv_2mortal (my_newSVll (statbuf->favail)));
+ PUSHs (sv_2mortal (my_newSVll (statbuf->fsid)));
+ PUSHs (sv_2mortal (my_newSVll (statbuf->flag)));
+ PUSHs (sv_2mortal (my_newSVll (statbuf->namemax)));
+ free (statbuf);
+
diff --git a/perl/lib/Sys/Guestfs.pm b/perl/lib/Sys/Guestfs.pm
index c9caf088..09663bc5 100644
--- a/perl/lib/Sys/Guestfs.pm
+++ b/perl/lib/Sys/Guestfs.pm
@@ -402,6 +402,16 @@ hidden files are shown.
This command is mostly useful for interactive sessions. Programs
should probably use C<$h-E<gt>readdir> instead.
+=item %statbuf = $h->lstat ($path);
+
+Returns file information for the given C<path>.
+
+This is the same as C<$h-E<gt>stat> except that if C<path>
+is a symbolic link, then the link is stat-ed, not the file it
+refers to.
+
+This is the same as the C<lstat(2)> system call.
+
=item $h->lvcreate ($logvol, $volgroup, $mbytes);
This creates an LVM volume group called C<logvol>
@@ -568,6 +578,20 @@ the string C<,> (comma).
B<This command is dangerous. Without careful use you
can easily destroy all your data>.
+=item %statbuf = $h->stat ($path);
+
+Returns file information for the given C<path>.
+
+This is the same as the C<stat(2)> system call.
+
+=item %statbuf = $h->statvfs ($path);
+
+Returns file system statistics for any mounted file system.
+C<path> should be a file or directory in the mounted file system
+(typically it is the mount point itself, but it doesn't need to be).
+
+This is the same as the C<statvfs(2)> system call.
+
=item $h->sync ();
This syncs the disk, so that any writes are flushed through to the
diff --git a/python/guestfs-py.c b/python/guestfs-py.c
index 8c7ad228..81c87982 100644
--- a/python/guestfs-py.c
+++ b/python/guestfs-py.c
@@ -303,6 +303,72 @@ put_lvm_lv_list (struct guestfs_lvm_lv_list *lvs)
};
static PyObject *
+put_stat (struct guestfs_stat *stat)
+{
+ PyObject *dict;
+
+ dict = PyDict_New ();
+ PyDict_SetItemString (dict, "dev",
+ PyLong_FromLongLong (stat->dev));
+ PyDict_SetItemString (dict, "ino",
+ PyLong_FromLongLong (stat->ino));
+ PyDict_SetItemString (dict, "mode",
+ PyLong_FromLongLong (stat->mode));
+ PyDict_SetItemString (dict, "nlink",
+ PyLong_FromLongLong (stat->nlink));
+ PyDict_SetItemString (dict, "uid",
+ PyLong_FromLongLong (stat->uid));
+ PyDict_SetItemString (dict, "gid",
+ PyLong_FromLongLong (stat->gid));
+ PyDict_SetItemString (dict, "rdev",
+ PyLong_FromLongLong (stat->rdev));
+ PyDict_SetItemString (dict, "size",
+ PyLong_FromLongLong (stat->size));
+ PyDict_SetItemString (dict, "blksize",
+ PyLong_FromLongLong (stat->blksize));
+ PyDict_SetItemString (dict, "blocks",
+ PyLong_FromLongLong (stat->blocks));
+ PyDict_SetItemString (dict, "atime",
+ PyLong_FromLongLong (stat->atime));
+ PyDict_SetItemString (dict, "mtime",
+ PyLong_FromLongLong (stat->mtime));
+ PyDict_SetItemString (dict, "ctime",
+ PyLong_FromLongLong (stat->ctime));
+ return dict;
+};
+
+static PyObject *
+put_statvfs (struct guestfs_statvfs *statvfs)
+{
+ PyObject *dict;
+
+ dict = PyDict_New ();
+ PyDict_SetItemString (dict, "bsize",
+ PyLong_FromLongLong (statvfs->bsize));
+ PyDict_SetItemString (dict, "frsize",
+ PyLong_FromLongLong (statvfs->frsize));
+ PyDict_SetItemString (dict, "blocks",
+ PyLong_FromLongLong (statvfs->blocks));
+ PyDict_SetItemString (dict, "bfree",
+ PyLong_FromLongLong (statvfs->bfree));
+ PyDict_SetItemString (dict, "bavail",
+ PyLong_FromLongLong (statvfs->bavail));
+ PyDict_SetItemString (dict, "files",
+ PyLong_FromLongLong (statvfs->files));
+ PyDict_SetItemString (dict, "ffree",
+ PyLong_FromLongLong (statvfs->ffree));
+ PyDict_SetItemString (dict, "favail",
+ PyLong_FromLongLong (statvfs->favail));
+ PyDict_SetItemString (dict, "fsid",
+ PyLong_FromLongLong (statvfs->fsid));
+ PyDict_SetItemString (dict, "flag",
+ PyLong_FromLongLong (statvfs->flag));
+ PyDict_SetItemString (dict, "namemax",
+ PyLong_FromLongLong (statvfs->namemax));
+ return dict;
+};
+
+static PyObject *
py_guestfs_launch (PyObject *self, PyObject *args)
{
PyObject *py_g;
@@ -1889,6 +1955,81 @@ py_guestfs_command_lines (PyObject *self, PyObject *args)
return py_r;
}
+static PyObject *
+py_guestfs_stat (PyObject *self, PyObject *args)
+{
+ PyObject *py_g;
+ guestfs_h *g;
+ PyObject *py_r;
+ struct guestfs_stat *r;
+ const char *path;
+
+ if (!PyArg_ParseTuple (args, (char *) "Os:guestfs_stat",
+ &py_g, &path))
+ return NULL;
+ g = get_handle (py_g);
+
+ r = guestfs_stat (g, path);
+ if (r == NULL) {
+ PyErr_SetString (PyExc_RuntimeError, guestfs_last_error (g));
+ return NULL;
+ }
+
+ py_r = put_stat (r);
+ free (r);
+ return py_r;
+}
+
+static PyObject *
+py_guestfs_lstat (PyObject *self, PyObject *args)
+{
+ PyObject *py_g;
+ guestfs_h *g;
+ PyObject *py_r;
+ struct guestfs_stat *r;
+ const char *path;
+
+ if (!PyArg_ParseTuple (args, (char *) "Os:guestfs_lstat",
+ &py_g, &path))
+ return NULL;
+ g = get_handle (py_g);
+
+ r = guestfs_lstat (g, path);
+ if (r == NULL) {
+ PyErr_SetString (PyExc_RuntimeError, guestfs_last_error (g));
+ return NULL;
+ }
+
+ py_r = put_stat (r);
+ free (r);
+ return py_r;
+}
+
+static PyObject *
+py_guestfs_statvfs (PyObject *self, PyObject *args)
+{
+ PyObject *py_g;
+ guestfs_h *g;
+ PyObject *py_r;
+ struct guestfs_statvfs *r;
+ const char *path;
+
+ if (!PyArg_ParseTuple (args, (char *) "Os:guestfs_statvfs",
+ &py_g, &path))
+ return NULL;
+ g = get_handle (py_g);
+
+ r = guestfs_statvfs (g, path);
+ if (r == NULL) {
+ PyErr_SetString (PyExc_RuntimeError, guestfs_last_error (g));
+ return NULL;
+ }
+
+ py_r = put_statvfs (r);
+ free (r);
+ return py_r;
+}
+
static PyMethodDef methods[] = {
{ (char *) "create", py_guestfs_create, METH_VARARGS, NULL },
{ (char *) "close", py_guestfs_close, METH_VARARGS, NULL },
@@ -1955,6 +2096,9 @@ static PyMethodDef methods[] = {
{ (char *) "file", py_guestfs_file, METH_VARARGS, NULL },
{ (char *) "command", py_guestfs_command, METH_VARARGS, NULL },
{ (char *) "command_lines", py_guestfs_command_lines, METH_VARARGS, NULL },
+ { (char *) "stat", py_guestfs_stat, METH_VARARGS, NULL },
+ { (char *) "lstat", py_guestfs_lstat, METH_VARARGS, NULL },
+ { (char *) "statvfs", py_guestfs_statvfs, METH_VARARGS, NULL },
{ NULL, NULL, 0, NULL }
};
diff --git a/python/guestfs.py b/python/guestfs.py
index 6cf7e19e..2e0be5c5 100644
--- a/python/guestfs.py
+++ b/python/guestfs.py
@@ -216,3 +216,12 @@ class GuestFS:
def command_lines (self, arguments):
return libguestfsmod.command_lines (self._o, arguments)
+ def stat (self, path):
+ return libguestfsmod.stat (self._o, path)
+
+ def lstat (self, path):
+ return libguestfsmod.lstat (self._o, path)
+
+ def statvfs (self, path):
+ return libguestfsmod.statvfs (self._o, path)
+
diff --git a/src/guestfs-actions.c b/src/guestfs-actions.c
index c6f574a7..8f40102e 100644
--- a/src/guestfs-actions.c
+++ b/src/guestfs-actions.c
@@ -3699,3 +3699,228 @@ char **guestfs_command_lines (guestfs_h *g,
return rv.ret.lines.lines_val;
}
+struct stat_rv {
+ int cb_done; /* flag to indicate callback was called */
+ struct guestfs_message_header hdr;
+ struct guestfs_message_error err;
+ struct guestfs_stat_ret ret;
+};
+
+static void stat_cb (guestfs_h *g, void *data, XDR *xdr)
+{
+ struct stat_rv *rv = (struct stat_rv *) data;
+
+ if (!xdr_guestfs_message_header (xdr, &rv->hdr)) {
+ error (g, "guestfs_stat: failed to parse reply header");
+ return;
+ }
+ if (rv->hdr.status == GUESTFS_STATUS_ERROR) {
+ if (!xdr_guestfs_message_error (xdr, &rv->err)) {
+ error (g, "guestfs_stat: failed to parse reply error");
+ return;
+ }
+ goto done;
+ }
+ if (!xdr_guestfs_stat_ret (xdr, &rv->ret)) {
+ error (g, "guestfs_stat: failed to parse reply");
+ return;
+ }
+ done:
+ rv->cb_done = 1;
+ main_loop.main_loop_quit (g);
+}
+
+struct guestfs_stat *guestfs_stat (guestfs_h *g,
+ const char *path)
+{
+ struct guestfs_stat_args args;
+ struct stat_rv rv;
+ int serial;
+
+ if (g->state != READY) {
+ error (g, "guestfs_stat called from the wrong state, %d != READY",
+ g->state);
+ return NULL;
+ }
+
+ memset (&rv, 0, sizeof rv);
+
+ args.path = (char *) path;
+ serial = dispatch (g, GUESTFS_PROC_STAT,
+ (xdrproc_t) xdr_guestfs_stat_args, (char *) &args);
+ if (serial == -1)
+ return NULL;
+
+ rv.cb_done = 0;
+ g->reply_cb_internal = stat_cb;
+ g->reply_cb_internal_data = &rv;
+ main_loop.main_loop_run (g);
+ g->reply_cb_internal = NULL;
+ g->reply_cb_internal_data = NULL;
+ if (!rv.cb_done) {
+ error (g, "guestfs_stat failed, see earlier error messages");
+ return NULL;
+ }
+
+ if (check_reply_header (g, &rv.hdr, GUESTFS_PROC_STAT, serial) == -1)
+ return NULL;
+
+ if (rv.hdr.status == GUESTFS_STATUS_ERROR) {
+ error (g, "%s", rv.err.error);
+ return NULL;
+ }
+
+ /* caller will free this */
+ return safe_memdup (g, &rv.ret.statbuf, sizeof (rv.ret.statbuf));
+}
+
+struct lstat_rv {
+ int cb_done; /* flag to indicate callback was called */
+ struct guestfs_message_header hdr;
+ struct guestfs_message_error err;
+ struct guestfs_lstat_ret ret;
+};
+
+static void lstat_cb (guestfs_h *g, void *data, XDR *xdr)
+{
+ struct lstat_rv *rv = (struct lstat_rv *) data;
+
+ if (!xdr_guestfs_message_header (xdr, &rv->hdr)) {
+ error (g, "guestfs_lstat: failed to parse reply header");
+ return;
+ }
+ if (rv->hdr.status == GUESTFS_STATUS_ERROR) {
+ if (!xdr_guestfs_message_error (xdr, &rv->err)) {
+ error (g, "guestfs_lstat: failed to parse reply error");
+ return;
+ }
+ goto done;
+ }
+ if (!xdr_guestfs_lstat_ret (xdr, &rv->ret)) {
+ error (g, "guestfs_lstat: failed to parse reply");
+ return;
+ }
+ done:
+ rv->cb_done = 1;
+ main_loop.main_loop_quit (g);
+}
+
+struct guestfs_stat *guestfs_lstat (guestfs_h *g,
+ const char *path)
+{
+ struct guestfs_lstat_args args;
+ struct lstat_rv rv;
+ int serial;
+
+ if (g->state != READY) {
+ error (g, "guestfs_lstat called from the wrong state, %d != READY",
+ g->state);
+ return NULL;
+ }
+
+ memset (&rv, 0, sizeof rv);
+
+ args.path = (char *) path;
+ serial = dispatch (g, GUESTFS_PROC_LSTAT,
+ (xdrproc_t) xdr_guestfs_lstat_args, (char *) &args);
+ if (serial == -1)
+ return NULL;
+
+ rv.cb_done = 0;
+ g->reply_cb_internal = lstat_cb;
+ g->reply_cb_internal_data = &rv;
+ main_loop.main_loop_run (g);
+ g->reply_cb_internal = NULL;
+ g->reply_cb_internal_data = NULL;
+ if (!rv.cb_done) {
+ error (g, "guestfs_lstat failed, see earlier error messages");
+ return NULL;
+ }
+
+ if (check_reply_header (g, &rv.hdr, GUESTFS_PROC_LSTAT, serial) == -1)
+ return NULL;
+
+ if (rv.hdr.status == GUESTFS_STATUS_ERROR) {
+ error (g, "%s", rv.err.error);
+ return NULL;
+ }
+
+ /* caller will free this */
+ return safe_memdup (g, &rv.ret.statbuf, sizeof (rv.ret.statbuf));
+}
+
+struct statvfs_rv {
+ int cb_done; /* flag to indicate callback was called */
+ struct guestfs_message_header hdr;
+ struct guestfs_message_error err;
+ struct guestfs_statvfs_ret ret;
+};
+
+static void statvfs_cb (guestfs_h *g, void *data, XDR *xdr)
+{
+ struct statvfs_rv *rv = (struct statvfs_rv *) data;
+
+ if (!xdr_guestfs_message_header (xdr, &rv->hdr)) {
+ error (g, "guestfs_statvfs: failed to parse reply header");
+ return;
+ }
+ if (rv->hdr.status == GUESTFS_STATUS_ERROR) {
+ if (!xdr_guestfs_message_error (xdr, &rv->err)) {
+ error (g, "guestfs_statvfs: failed to parse reply error");
+ return;
+ }
+ goto done;
+ }
+ if (!xdr_guestfs_statvfs_ret (xdr, &rv->ret)) {
+ error (g, "guestfs_statvfs: failed to parse reply");
+ return;
+ }
+ done:
+ rv->cb_done = 1;
+ main_loop.main_loop_quit (g);
+}
+
+struct guestfs_statvfs *guestfs_statvfs (guestfs_h *g,
+ const char *path)
+{
+ struct guestfs_statvfs_args args;
+ struct statvfs_rv rv;
+ int serial;
+
+ if (g->state != READY) {
+ error (g, "guestfs_statvfs called from the wrong state, %d != READY",
+ g->state);
+ return NULL;
+ }
+
+ memset (&rv, 0, sizeof rv);
+
+ args.path = (char *) path;
+ serial = dispatch (g, GUESTFS_PROC_STATVFS,
+ (xdrproc_t) xdr_guestfs_statvfs_args, (char *) &args);
+ if (serial == -1)
+ return NULL;
+
+ rv.cb_done = 0;
+ g->reply_cb_internal = statvfs_cb;
+ g->reply_cb_internal_data = &rv;
+ main_loop.main_loop_run (g);
+ g->reply_cb_internal = NULL;
+ g->reply_cb_internal_data = NULL;
+ if (!rv.cb_done) {
+ error (g, "guestfs_statvfs failed, see earlier error messages");
+ return NULL;
+ }
+
+ if (check_reply_header (g, &rv.hdr, GUESTFS_PROC_STATVFS, serial) == -1)
+ return NULL;
+
+ if (rv.hdr.status == GUESTFS_STATUS_ERROR) {
+ error (g, "%s", rv.err.error);
+ return NULL;
+ }
+
+ /* caller will free this */
+ return safe_memdup (g, &rv.ret.statbuf, sizeof (rv.ret.statbuf));
+}
+
diff --git a/src/guestfs-actions.h b/src/guestfs-actions.h
index 06efabf0..a838a049 100644
--- a/src/guestfs-actions.h
+++ b/src/guestfs-actions.h
@@ -82,3 +82,6 @@ extern int guestfs_lvm_remove_all (guestfs_h *handle);
extern char *guestfs_file (guestfs_h *handle, const char *path);
extern char *guestfs_command (guestfs_h *handle, char * const* const arguments);
extern char **guestfs_command_lines (guestfs_h *handle, char * const* const arguments);
+extern struct guestfs_stat *guestfs_stat (guestfs_h *handle, const char *path);
+extern struct guestfs_stat *guestfs_lstat (guestfs_h *handle, const char *path);
+extern struct guestfs_statvfs *guestfs_statvfs (guestfs_h *handle, const char *path);
diff --git a/src/guestfs-structs.h b/src/guestfs-structs.h
index b3751cd5..76ac8199 100644
--- a/src/guestfs-structs.h
+++ b/src/guestfs-structs.h
@@ -97,3 +97,33 @@ struct guestfs_lvm_lv_list {
struct guestfs_lvm_lv *val;
};
+struct guestfs_stat {
+ int64_t dev;
+ int64_t ino;
+ int64_t mode;
+ int64_t nlink;
+ int64_t uid;
+ int64_t gid;
+ int64_t rdev;
+ int64_t size;
+ int64_t blksize;
+ int64_t blocks;
+ int64_t atime;
+ int64_t mtime;
+ int64_t ctime;
+};
+
+struct guestfs_statvfs {
+ int64_t bsize;
+ int64_t frsize;
+ int64_t blocks;
+ int64_t bfree;
+ int64_t bavail;
+ int64_t files;
+ int64_t ffree;
+ int64_t favail;
+ int64_t fsid;
+ int64_t flag;
+ int64_t namemax;
+};
+
diff --git a/src/guestfs_protocol.c b/src/guestfs_protocol.c
index 0849f7ae..99377b4d 100644
--- a/src/guestfs_protocol.c
+++ b/src/guestfs_protocol.c
@@ -174,6 +174,70 @@ xdr_guestfs_lvm_int_lv_list (XDR *xdrs, guestfs_lvm_int_lv_list *objp)
}
bool_t
+xdr_guestfs_int_stat (XDR *xdrs, guestfs_int_stat *objp)
+{
+ register int32_t *buf;
+
+ if (!xdr_quad_t (xdrs, &objp->dev))
+ return FALSE;
+ if (!xdr_quad_t (xdrs, &objp->ino))
+ return FALSE;
+ if (!xdr_quad_t (xdrs, &objp->mode))
+ return FALSE;
+ if (!xdr_quad_t (xdrs, &objp->nlink))
+ return FALSE;
+ if (!xdr_quad_t (xdrs, &objp->uid))
+ return FALSE;
+ if (!xdr_quad_t (xdrs, &objp->gid))
+ return FALSE;
+ if (!xdr_quad_t (xdrs, &objp->rdev))
+ return FALSE;
+ if (!xdr_quad_t (xdrs, &objp->size))
+ return FALSE;
+ if (!xdr_quad_t (xdrs, &objp->blksize))
+ return FALSE;
+ if (!xdr_quad_t (xdrs, &objp->blocks))
+ return FALSE;
+ if (!xdr_quad_t (xdrs, &objp->atime))
+ return FALSE;
+ if (!xdr_quad_t (xdrs, &objp->mtime))
+ return FALSE;
+ if (!xdr_quad_t (xdrs, &objp->ctime))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_guestfs_int_statvfs (XDR *xdrs, guestfs_int_statvfs *objp)
+{
+ register int32_t *buf;
+
+ if (!xdr_quad_t (xdrs, &objp->bsize))
+ return FALSE;
+ if (!xdr_quad_t (xdrs, &objp->frsize))
+ return FALSE;
+ if (!xdr_quad_t (xdrs, &objp->blocks))
+ return FALSE;
+ if (!xdr_quad_t (xdrs, &objp->bfree))
+ return FALSE;
+ if (!xdr_quad_t (xdrs, &objp->bavail))
+ return FALSE;
+ if (!xdr_quad_t (xdrs, &objp->files))
+ return FALSE;
+ if (!xdr_quad_t (xdrs, &objp->ffree))
+ return FALSE;
+ if (!xdr_quad_t (xdrs, &objp->favail))
+ return FALSE;
+ if (!xdr_quad_t (xdrs, &objp->fsid))
+ return FALSE;
+ if (!xdr_quad_t (xdrs, &objp->flag))
+ return FALSE;
+ if (!xdr_quad_t (xdrs, &objp->namemax))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
xdr_guestfs_mount_args (XDR *xdrs, guestfs_mount_args *objp)
{
register int32_t *buf;
@@ -890,6 +954,66 @@ xdr_guestfs_command_lines_ret (XDR *xdrs, guestfs_command_lines_ret *objp)
}
bool_t
+xdr_guestfs_stat_args (XDR *xdrs, guestfs_stat_args *objp)
+{
+ register int32_t *buf;
+
+ if (!xdr_string (xdrs, &objp->path, ~0))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_guestfs_stat_ret (XDR *xdrs, guestfs_stat_ret *objp)
+{
+ register int32_t *buf;
+
+ if (!xdr_guestfs_int_stat (xdrs, &objp->statbuf))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_guestfs_lstat_args (XDR *xdrs, guestfs_lstat_args *objp)
+{
+ register int32_t *buf;
+
+ if (!xdr_string (xdrs, &objp->path, ~0))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_guestfs_lstat_ret (XDR *xdrs, guestfs_lstat_ret *objp)
+{
+ register int32_t *buf;
+
+ if (!xdr_guestfs_int_stat (xdrs, &objp->statbuf))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_guestfs_statvfs_args (XDR *xdrs, guestfs_statvfs_args *objp)
+{
+ register int32_t *buf;
+
+ if (!xdr_string (xdrs, &objp->path, ~0))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_guestfs_statvfs_ret (XDR *xdrs, guestfs_statvfs_ret *objp)
+{
+ register int32_t *buf;
+
+ if (!xdr_guestfs_int_statvfs (xdrs, &objp->statbuf))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
xdr_guestfs_procedure (XDR *xdrs, guestfs_procedure *objp)
{
register int32_t *buf;
diff --git a/src/guestfs_protocol.h b/src/guestfs_protocol.h
index 4b314682..07207237 100644
--- a/src/guestfs_protocol.h
+++ b/src/guestfs_protocol.h
@@ -92,6 +92,38 @@ typedef struct {
guestfs_lvm_int_lv *guestfs_lvm_int_lv_list_val;
} guestfs_lvm_int_lv_list;
+struct guestfs_int_stat {
+ quad_t dev;
+ quad_t ino;
+ quad_t mode;
+ quad_t nlink;
+ quad_t uid;
+ quad_t gid;
+ quad_t rdev;
+ quad_t size;
+ quad_t blksize;
+ quad_t blocks;
+ quad_t atime;
+ quad_t mtime;
+ quad_t ctime;
+};
+typedef struct guestfs_int_stat guestfs_int_stat;
+
+struct guestfs_int_statvfs {
+ quad_t bsize;
+ quad_t frsize;
+ quad_t blocks;
+ quad_t bfree;
+ quad_t bavail;
+ quad_t files;
+ quad_t ffree;
+ quad_t favail;
+ quad_t fsid;
+ quad_t flag;
+ quad_t namemax;
+};
+typedef struct guestfs_int_statvfs guestfs_int_statvfs;
+
struct guestfs_mount_args {
char *device;
char *mountpoint;
@@ -465,6 +497,36 @@ struct guestfs_command_lines_ret {
};
typedef struct guestfs_command_lines_ret guestfs_command_lines_ret;
+struct guestfs_stat_args {
+ char *path;
+};
+typedef struct guestfs_stat_args guestfs_stat_args;
+
+struct guestfs_stat_ret {
+ guestfs_int_stat statbuf;
+};
+typedef struct guestfs_stat_ret guestfs_stat_ret;
+
+struct guestfs_lstat_args {
+ char *path;
+};
+typedef struct guestfs_lstat_args guestfs_lstat_args;
+
+struct guestfs_lstat_ret {
+ guestfs_int_stat statbuf;
+};
+typedef struct guestfs_lstat_ret guestfs_lstat_ret;
+
+struct guestfs_statvfs_args {
+ char *path;
+};
+typedef struct guestfs_statvfs_args guestfs_statvfs_args;
+
+struct guestfs_statvfs_ret {
+ guestfs_int_statvfs statbuf;
+};
+typedef struct guestfs_statvfs_ret guestfs_statvfs_ret;
+
enum guestfs_procedure {
GUESTFS_PROC_MOUNT = 1,
GUESTFS_PROC_SYNC = 2,
@@ -517,7 +579,10 @@ enum guestfs_procedure {
GUESTFS_PROC_FILE = 49,
GUESTFS_PROC_COMMAND = 50,
GUESTFS_PROC_COMMAND_LINES = 51,
- GUESTFS_PROC_dummy = 51 + 1,
+ GUESTFS_PROC_STAT = 52,
+ GUESTFS_PROC_LSTAT = 53,
+ GUESTFS_PROC_STATVFS = 54,
+ GUESTFS_PROC_dummy = 54 + 1,
};
typedef enum guestfs_procedure guestfs_procedure;
#define GUESTFS_MESSAGE_MAX 4194304
@@ -562,6 +627,8 @@ extern bool_t xdr_guestfs_lvm_int_vg (XDR *, guestfs_lvm_int_vg*);
extern bool_t xdr_guestfs_lvm_int_vg_list (XDR *, guestfs_lvm_int_vg_list*);
extern bool_t xdr_guestfs_lvm_int_lv (XDR *, guestfs_lvm_int_lv*);
extern bool_t xdr_guestfs_lvm_int_lv_list (XDR *, guestfs_lvm_int_lv_list*);
+extern bool_t xdr_guestfs_int_stat (XDR *, guestfs_int_stat*);
+extern bool_t xdr_guestfs_int_statvfs (XDR *, guestfs_int_statvfs*);
extern bool_t xdr_guestfs_mount_args (XDR *, guestfs_mount_args*);
extern bool_t xdr_guestfs_touch_args (XDR *, guestfs_touch_args*);
extern bool_t xdr_guestfs_cat_args (XDR *, guestfs_cat_args*);
@@ -623,6 +690,12 @@ extern bool_t xdr_guestfs_command_args (XDR *, guestfs_command_args*);
extern bool_t xdr_guestfs_command_ret (XDR *, guestfs_command_ret*);
extern bool_t xdr_guestfs_command_lines_args (XDR *, guestfs_command_lines_args*);
extern bool_t xdr_guestfs_command_lines_ret (XDR *, guestfs_command_lines_ret*);
+extern bool_t xdr_guestfs_stat_args (XDR *, guestfs_stat_args*);
+extern bool_t xdr_guestfs_stat_ret (XDR *, guestfs_stat_ret*);
+extern bool_t xdr_guestfs_lstat_args (XDR *, guestfs_lstat_args*);
+extern bool_t xdr_guestfs_lstat_ret (XDR *, guestfs_lstat_ret*);
+extern bool_t xdr_guestfs_statvfs_args (XDR *, guestfs_statvfs_args*);
+extern bool_t xdr_guestfs_statvfs_ret (XDR *, guestfs_statvfs_ret*);
extern bool_t xdr_guestfs_procedure (XDR *, guestfs_procedure*);
extern bool_t xdr_guestfs_message_direction (XDR *, guestfs_message_direction*);
extern bool_t xdr_guestfs_message_status (XDR *, guestfs_message_status*);
@@ -637,6 +710,8 @@ extern bool_t xdr_guestfs_lvm_int_vg ();
extern bool_t xdr_guestfs_lvm_int_vg_list ();
extern bool_t xdr_guestfs_lvm_int_lv ();
extern bool_t xdr_guestfs_lvm_int_lv_list ();
+extern bool_t xdr_guestfs_int_stat ();
+extern bool_t xdr_guestfs_int_statvfs ();
extern bool_t xdr_guestfs_mount_args ();
extern bool_t xdr_guestfs_touch_args ();
extern bool_t xdr_guestfs_cat_args ();
@@ -698,6 +773,12 @@ extern bool_t xdr_guestfs_command_args ();
extern bool_t xdr_guestfs_command_ret ();
extern bool_t xdr_guestfs_command_lines_args ();
extern bool_t xdr_guestfs_command_lines_ret ();
+extern bool_t xdr_guestfs_stat_args ();
+extern bool_t xdr_guestfs_stat_ret ();
+extern bool_t xdr_guestfs_lstat_args ();
+extern bool_t xdr_guestfs_lstat_ret ();
+extern bool_t xdr_guestfs_statvfs_args ();
+extern bool_t xdr_guestfs_statvfs_ret ();
extern bool_t xdr_guestfs_procedure ();
extern bool_t xdr_guestfs_message_direction ();
extern bool_t xdr_guestfs_message_status ();
diff --git a/src/guestfs_protocol.x b/src/guestfs_protocol.x
index 68362d64..e03aef66 100644
--- a/src/guestfs_protocol.x
+++ b/src/guestfs_protocol.x
@@ -85,6 +85,36 @@ struct guestfs_lvm_int_lv {
typedef struct guestfs_lvm_int_lv guestfs_lvm_int_lv_list<>;
+struct guestfs_int_stat {
+ hyper dev;
+ hyper ino;
+ hyper mode;
+ hyper nlink;
+ hyper uid;
+ hyper gid;
+ hyper rdev;
+ hyper size;
+ hyper blksize;
+ hyper blocks;
+ hyper atime;
+ hyper mtime;
+ hyper ctime;
+};
+
+struct guestfs_int_statvfs {
+ hyper bsize;
+ hyper frsize;
+ hyper blocks;
+ hyper bfree;
+ hyper bavail;
+ hyper files;
+ hyper ffree;
+ hyper favail;
+ hyper fsid;
+ hyper flag;
+ hyper namemax;
+};
+
struct guestfs_mount_args {
string device<>;
string mountpoint<>;
@@ -352,6 +382,30 @@ struct guestfs_command_lines_ret {
str lines<>;
};
+struct guestfs_stat_args {
+ string path<>;
+};
+
+struct guestfs_stat_ret {
+ guestfs_int_stat statbuf;
+};
+
+struct guestfs_lstat_args {
+ string path<>;
+};
+
+struct guestfs_lstat_ret {
+ guestfs_int_stat statbuf;
+};
+
+struct guestfs_statvfs_args {
+ string path<>;
+};
+
+struct guestfs_statvfs_ret {
+ guestfs_int_statvfs statbuf;
+};
+
enum guestfs_procedure {
GUESTFS_PROC_MOUNT = 1,
GUESTFS_PROC_SYNC = 2,
@@ -404,6 +458,9 @@ enum guestfs_procedure {
GUESTFS_PROC_FILE = 49,
GUESTFS_PROC_COMMAND = 50,
GUESTFS_PROC_COMMAND_LINES = 51,
+ GUESTFS_PROC_STAT = 52,
+ GUESTFS_PROC_LSTAT = 53,
+ GUESTFS_PROC_STATVFS = 54,
GUESTFS_PROC_dummy
};
diff --git a/tests.c b/tests.c
index b59192c7..1c6676bd 100644
--- a/tests.c
+++ b/tests.c
@@ -1238,288 +1238,6 @@ static int test_lvs_1 (void)
return 0;
}
-static int test_pvs_full_0 (void)
-{
- /* InitBasicFSonLVM for pvs_full (0): create ext2 on /dev/VG/LV */
- {
- int r;
- suppress_error = 0;
- r = guestfs_umount_all (g);
- if (r == -1)
- return -1;
- }
- {
- int r;
- suppress_error = 0;
- r = guestfs_lvm_remove_all (g);
- if (r == -1)
- return -1;
- }
- {
- char *lines[] = {
- ",",
- NULL
- };
- int r;
- suppress_error = 0;
- r = guestfs_sfdisk (g, "/dev/sda", 0, 0, 0, lines);
- if (r == -1)
- return -1;
- }
- {
- int r;
- suppress_error = 0;
- r = guestfs_pvcreate (g, "/dev/sda1");
- if (r == -1)
- return -1;
- }
- {
- char *physvols[] = {
- "/dev/sda1",
- NULL
- };
- int r;
- suppress_error = 0;
- r = guestfs_vgcreate (g, "VG", physvols);
- if (r == -1)
- return -1;
- }
- {
- int r;
- suppress_error = 0;
- r = guestfs_lvcreate (g, "LV", "VG", 8);
- if (r == -1)
- return -1;
- }
- {
- int r;
- suppress_error = 0;
- r = guestfs_mkfs (g, "ext2", "/dev/VG/LV");
- if (r == -1)
- return -1;
- }
- {
- int r;
- suppress_error = 0;
- r = guestfs_mount (g, "/dev/VG/LV", "/");
- if (r == -1)
- return -1;
- }
- /* TestOutputLength for pvs_full (0) */
- {
- char **r;
- int i;
- suppress_error = 0;
- r = guestfs_pvs (g);
- if (r == NULL)
- return -1;
- int j;
- for (j = 0; j < 1; ++j)
- if (r[j] == NULL) {
- fprintf (stderr, "test_pvs_full_0: short list returned\n");
- print_strings (r);
- return -1;
- }
- if (r[j] != NULL) {
- fprintf (stderr, "test_pvs_full_0: long list returned\n");
- print_strings (r);
- return -1;
- }
- for (i = 0; r[i] != NULL; ++i)
- free (r[i]);
- free (r);
- }
- return 0;
-}
-
-static int test_vgs_full_0 (void)
-{
- /* InitBasicFSonLVM for vgs_full (0): create ext2 on /dev/VG/LV */
- {
- int r;
- suppress_error = 0;
- r = guestfs_umount_all (g);
- if (r == -1)
- return -1;
- }
- {
- int r;
- suppress_error = 0;
- r = guestfs_lvm_remove_all (g);
- if (r == -1)
- return -1;
- }
- {
- char *lines[] = {
- ",",
- NULL
- };
- int r;
- suppress_error = 0;
- r = guestfs_sfdisk (g, "/dev/sda", 0, 0, 0, lines);
- if (r == -1)
- return -1;
- }
- {
- int r;
- suppress_error = 0;
- r = guestfs_pvcreate (g, "/dev/sda1");
- if (r == -1)
- return -1;
- }
- {
- char *physvols[] = {
- "/dev/sda1",
- NULL
- };
- int r;
- suppress_error = 0;
- r = guestfs_vgcreate (g, "VG", physvols);
- if (r == -1)
- return -1;
- }
- {
- int r;
- suppress_error = 0;
- r = guestfs_lvcreate (g, "LV", "VG", 8);
- if (r == -1)
- return -1;
- }
- {
- int r;
- suppress_error = 0;
- r = guestfs_mkfs (g, "ext2", "/dev/VG/LV");
- if (r == -1)
- return -1;
- }
- {
- int r;
- suppress_error = 0;
- r = guestfs_mount (g, "/dev/VG/LV", "/");
- if (r == -1)
- return -1;
- }
- /* TestOutputLength for vgs_full (0) */
- {
- char **r;
- int i;
- suppress_error = 0;
- r = guestfs_pvs (g);
- if (r == NULL)
- return -1;
- int j;
- for (j = 0; j < 1; ++j)
- if (r[j] == NULL) {
- fprintf (stderr, "test_vgs_full_0: short list returned\n");
- print_strings (r);
- return -1;
- }
- if (r[j] != NULL) {
- fprintf (stderr, "test_vgs_full_0: long list returned\n");
- print_strings (r);
- return -1;
- }
- for (i = 0; r[i] != NULL; ++i)
- free (r[i]);
- free (r);
- }
- return 0;
-}
-
-static int test_lvs_full_0 (void)
-{
- /* InitBasicFSonLVM for lvs_full (0): create ext2 on /dev/VG/LV */
- {
- int r;
- suppress_error = 0;
- r = guestfs_umount_all (g);
- if (r == -1)
- return -1;
- }
- {
- int r;
- suppress_error = 0;
- r = guestfs_lvm_remove_all (g);
- if (r == -1)
- return -1;
- }
- {
- char *lines[] = {
- ",",
- NULL
- };
- int r;
- suppress_error = 0;
- r = guestfs_sfdisk (g, "/dev/sda", 0, 0, 0, lines);
- if (r == -1)
- return -1;
- }
- {
- int r;
- suppress_error = 0;
- r = guestfs_pvcreate (g, "/dev/sda1");
- if (r == -1)
- return -1;
- }
- {
- char *physvols[] = {
- "/dev/sda1",
- NULL
- };
- int r;
- suppress_error = 0;
- r = guestfs_vgcreate (g, "VG", physvols);
- if (r == -1)
- return -1;
- }
- {
- int r;
- suppress_error = 0;
- r = guestfs_lvcreate (g, "LV", "VG", 8);
- if (r == -1)
- return -1;
- }
- {
- int r;
- suppress_error = 0;
- r = guestfs_mkfs (g, "ext2", "/dev/VG/LV");
- if (r == -1)
- return -1;
- }
- {
- int r;
- suppress_error = 0;
- r = guestfs_mount (g, "/dev/VG/LV", "/");
- if (r == -1)
- return -1;
- }
- /* TestOutputLength for lvs_full (0) */
- {
- char **r;
- int i;
- suppress_error = 0;
- r = guestfs_pvs (g);
- if (r == NULL)
- return -1;
- int j;
- for (j = 0; j < 1; ++j)
- if (r[j] == NULL) {
- fprintf (stderr, "test_lvs_full_0: short list returned\n");
- print_strings (r);
- return -1;
- }
- if (r[j] != NULL) {
- fprintf (stderr, "test_lvs_full_0: long list returned\n");
- print_strings (r);
- return -1;
- }
- for (i = 0; r[i] != NULL; ++i)
- free (r[i]);
- free (r);
- }
- return 0;
-}
-
static int test_read_lines_0 (void)
{
/* InitBasicFS for read_lines (0): create ext2 on /dev/sda1 */
@@ -3787,6 +3505,207 @@ static int test_file_2 (void)
return 0;
}
+static int test_stat_0 (void)
+{
+ /* InitBasicFS for stat (0): create ext2 on /dev/sda1 */
+ {
+ int r;
+ suppress_error = 0;
+ r = guestfs_umount_all (g);
+ if (r == -1)
+ return -1;
+ }
+ {
+ int r;
+ suppress_error = 0;
+ r = guestfs_lvm_remove_all (g);
+ if (r == -1)
+ return -1;
+ }
+ {
+ char *lines[] = {
+ ",",
+ NULL
+ };
+ int r;
+ suppress_error = 0;
+ r = guestfs_sfdisk (g, "/dev/sda", 0, 0, 0, lines);
+ if (r == -1)
+ return -1;
+ }
+ {
+ int r;
+ suppress_error = 0;
+ r = guestfs_mkfs (g, "ext2", "/dev/sda1");
+ if (r == -1)
+ return -1;
+ }
+ {
+ int r;
+ suppress_error = 0;
+ r = guestfs_mount (g, "/dev/sda1", "/");
+ if (r == -1)
+ return -1;
+ }
+ /* TestOutputStruct for stat (0) */
+ {
+ int r;
+ suppress_error = 0;
+ r = guestfs_touch (g, "/new");
+ if (r == -1)
+ return -1;
+ }
+ {
+ struct guestfs_stat *r;
+ suppress_error = 0;
+ r = guestfs_stat (g, "/new");
+ if (r == NULL)
+ return -1;
+ if (r->size != 0) {
+ fprintf (stderr, "test_stat_0: size was %d, expected 0\n",
+ (int) r->size);
+ return -1;
+ }
+ free (r);
+ }
+ return 0;
+}
+
+static int test_lstat_0 (void)
+{
+ /* InitBasicFS for lstat (0): create ext2 on /dev/sda1 */
+ {
+ int r;
+ suppress_error = 0;
+ r = guestfs_umount_all (g);
+ if (r == -1)
+ return -1;
+ }
+ {
+ int r;
+ suppress_error = 0;
+ r = guestfs_lvm_remove_all (g);
+ if (r == -1)
+ return -1;
+ }
+ {
+ char *lines[] = {
+ ",",
+ NULL
+ };
+ int r;
+ suppress_error = 0;
+ r = guestfs_sfdisk (g, "/dev/sda", 0, 0, 0, lines);
+ if (r == -1)
+ return -1;
+ }
+ {
+ int r;
+ suppress_error = 0;
+ r = guestfs_mkfs (g, "ext2", "/dev/sda1");
+ if (r == -1)
+ return -1;
+ }
+ {
+ int r;
+ suppress_error = 0;
+ r = guestfs_mount (g, "/dev/sda1", "/");
+ if (r == -1)
+ return -1;
+ }
+ /* TestOutputStruct for lstat (0) */
+ {
+ int r;
+ suppress_error = 0;
+ r = guestfs_touch (g, "/new");
+ if (r == -1)
+ return -1;
+ }
+ {
+ struct guestfs_stat *r;
+ suppress_error = 0;
+ r = guestfs_lstat (g, "/new");
+ if (r == NULL)
+ return -1;
+ if (r->size != 0) {
+ fprintf (stderr, "test_lstat_0: size was %d, expected 0\n",
+ (int) r->size);
+ return -1;
+ }
+ free (r);
+ }
+ return 0;
+}
+
+static int test_statvfs_0 (void)
+{
+ /* InitBasicFS for statvfs (0): create ext2 on /dev/sda1 */
+ {
+ int r;
+ suppress_error = 0;
+ r = guestfs_umount_all (g);
+ if (r == -1)
+ return -1;
+ }
+ {
+ int r;
+ suppress_error = 0;
+ r = guestfs_lvm_remove_all (g);
+ if (r == -1)
+ return -1;
+ }
+ {
+ char *lines[] = {
+ ",",
+ NULL
+ };
+ int r;
+ suppress_error = 0;
+ r = guestfs_sfdisk (g, "/dev/sda", 0, 0, 0, lines);
+ if (r == -1)
+ return -1;
+ }
+ {
+ int r;
+ suppress_error = 0;
+ r = guestfs_mkfs (g, "ext2", "/dev/sda1");
+ if (r == -1)
+ return -1;
+ }
+ {
+ int r;
+ suppress_error = 0;
+ r = guestfs_mount (g, "/dev/sda1", "/");
+ if (r == -1)
+ return -1;
+ }
+ /* TestOutputStruct for statvfs (0) */
+ {
+ struct guestfs_statvfs *r;
+ suppress_error = 0;
+ r = guestfs_statvfs (g, "/");
+ if (r == NULL)
+ return -1;
+ if (r->bfree != 487702) {
+ fprintf (stderr, "test_statvfs_0: bfree was %d, expected 487702\n",
+ (int) r->bfree);
+ return -1;
+ }
+ if (r->blocks != 490020) {
+ fprintf (stderr, "test_statvfs_0: blocks was %d, expected 490020\n",
+ (int) r->blocks);
+ return -1;
+ }
+ if (r->bsize != 1024) {
+ fprintf (stderr, "test_statvfs_0: bsize was %d, expected 1024\n",
+ (int) r->bsize);
+ return -1;
+ }
+ free (r);
+ }
+ return 0;
+}
+
int main (int argc, char *argv[])
{
char c = 0;
@@ -3794,6 +3713,7 @@ int main (int argc, char *argv[])
const char *srcdir;
int fd;
char buf[256];
+ int nr_tests;
g = guestfs_create ();
if (g == NULL) {
@@ -3900,251 +3820,252 @@ int main (int argc, char *argv[])
exit (1);
}
- printf (" 1/ 49 test_mount_0\n");
+ nr_tests = 49;
+ printf (" 1/%3d test_mount_0\n", nr_tests);
if (test_mount_0 () == -1) {
printf ("test_mount_0 FAILED\n");
failed++;
}
- printf (" 2/ 49 test_sync_0\n");
+ printf (" 2/%3d test_sync_0\n", nr_tests);
if (test_sync_0 () == -1) {
printf ("test_sync_0 FAILED\n");
failed++;
}
- printf (" 3/ 49 test_touch_0\n");
+ printf (" 3/%3d test_touch_0\n", nr_tests);
if (test_touch_0 () == -1) {
printf ("test_touch_0 FAILED\n");
failed++;
}
- printf (" 4/ 49 test_cat_0\n");
+ printf (" 4/%3d test_cat_0\n", nr_tests);
if (test_cat_0 () == -1) {
printf ("test_cat_0 FAILED\n");
failed++;
}
- printf (" 5/ 49 test_ls_0\n");
+ printf (" 5/%3d test_ls_0\n", nr_tests);
if (test_ls_0 () == -1) {
printf ("test_ls_0 FAILED\n");
failed++;
}
- printf (" 6/ 49 test_list_devices_0\n");
+ printf (" 6/%3d test_list_devices_0\n", nr_tests);
if (test_list_devices_0 () == -1) {
printf ("test_list_devices_0 FAILED\n");
failed++;
}
- printf (" 7/ 49 test_list_partitions_0\n");
+ printf (" 7/%3d test_list_partitions_0\n", nr_tests);
if (test_list_partitions_0 () == -1) {
printf ("test_list_partitions_0 FAILED\n");
failed++;
}
- printf (" 8/ 49 test_list_partitions_1\n");
+ printf (" 8/%3d test_list_partitions_1\n", nr_tests);
if (test_list_partitions_1 () == -1) {
printf ("test_list_partitions_1 FAILED\n");
failed++;
}
- printf (" 9/ 49 test_pvs_0\n");
+ printf (" 9/%3d test_pvs_0\n", nr_tests);
if (test_pvs_0 () == -1) {
printf ("test_pvs_0 FAILED\n");
failed++;
}
- printf (" 10/ 49 test_pvs_1\n");
+ printf (" 10/%3d test_pvs_1\n", nr_tests);
if (test_pvs_1 () == -1) {
printf ("test_pvs_1 FAILED\n");
failed++;
}
- printf (" 11/ 49 test_vgs_0\n");
+ printf (" 11/%3d test_vgs_0\n", nr_tests);
if (test_vgs_0 () == -1) {
printf ("test_vgs_0 FAILED\n");
failed++;
}
- printf (" 12/ 49 test_vgs_1\n");
+ printf (" 12/%3d test_vgs_1\n", nr_tests);
if (test_vgs_1 () == -1) {
printf ("test_vgs_1 FAILED\n");
failed++;
}
- printf (" 13/ 49 test_lvs_0\n");
+ printf (" 13/%3d test_lvs_0\n", nr_tests);
if (test_lvs_0 () == -1) {
printf ("test_lvs_0 FAILED\n");
failed++;
}
- printf (" 14/ 49 test_lvs_1\n");
+ printf (" 14/%3d test_lvs_1\n", nr_tests);
if (test_lvs_1 () == -1) {
printf ("test_lvs_1 FAILED\n");
failed++;
}
- printf (" 15/ 49 test_pvs_full_0\n");
- if (test_pvs_full_0 () == -1) {
- printf ("test_pvs_full_0 FAILED\n");
- failed++;
- }
- printf (" 16/ 49 test_vgs_full_0\n");
- if (test_vgs_full_0 () == -1) {
- printf ("test_vgs_full_0 FAILED\n");
- failed++;
- }
- printf (" 17/ 49 test_lvs_full_0\n");
- if (test_lvs_full_0 () == -1) {
- printf ("test_lvs_full_0 FAILED\n");
- failed++;
- }
- printf (" 18/ 49 test_read_lines_0\n");
+ printf (" 15/%3d test_read_lines_0\n", nr_tests);
if (test_read_lines_0 () == -1) {
printf ("test_read_lines_0 FAILED\n");
failed++;
}
- printf (" 19/ 49 test_read_lines_1\n");
+ printf (" 16/%3d test_read_lines_1\n", nr_tests);
if (test_read_lines_1 () == -1) {
printf ("test_read_lines_1 FAILED\n");
failed++;
}
- printf (" 20/ 49 test_rm_0\n");
+ printf (" 17/%3d test_rm_0\n", nr_tests);
if (test_rm_0 () == -1) {
printf ("test_rm_0 FAILED\n");
failed++;
}
- printf (" 21/ 49 test_rm_1\n");
+ printf (" 18/%3d test_rm_1\n", nr_tests);
if (test_rm_1 () == -1) {
printf ("test_rm_1 FAILED\n");
failed++;
}
- printf (" 22/ 49 test_rm_2\n");
+ printf (" 19/%3d test_rm_2\n", nr_tests);
if (test_rm_2 () == -1) {
printf ("test_rm_2 FAILED\n");
failed++;
}
- printf (" 23/ 49 test_rmdir_0\n");
+ printf (" 20/%3d test_rmdir_0\n", nr_tests);
if (test_rmdir_0 () == -1) {
printf ("test_rmdir_0 FAILED\n");
failed++;
}
- printf (" 24/ 49 test_rmdir_1\n");
+ printf (" 21/%3d test_rmdir_1\n", nr_tests);
if (test_rmdir_1 () == -1) {
printf ("test_rmdir_1 FAILED\n");
failed++;
}
- printf (" 25/ 49 test_rmdir_2\n");
+ printf (" 22/%3d test_rmdir_2\n", nr_tests);
if (test_rmdir_2 () == -1) {
printf ("test_rmdir_2 FAILED\n");
failed++;
}
- printf (" 26/ 49 test_rm_rf_0\n");
+ printf (" 23/%3d test_rm_rf_0\n", nr_tests);
if (test_rm_rf_0 () == -1) {
printf ("test_rm_rf_0 FAILED\n");
failed++;
}
- printf (" 27/ 49 test_mkdir_0\n");
+ printf (" 24/%3d test_mkdir_0\n", nr_tests);
if (test_mkdir_0 () == -1) {
printf ("test_mkdir_0 FAILED\n");
failed++;
}
- printf (" 28/ 49 test_mkdir_1\n");
+ printf (" 25/%3d test_mkdir_1\n", nr_tests);
if (test_mkdir_1 () == -1) {
printf ("test_mkdir_1 FAILED\n");
failed++;
}
- printf (" 29/ 49 test_mkdir_p_0\n");
+ printf (" 26/%3d test_mkdir_p_0\n", nr_tests);
if (test_mkdir_p_0 () == -1) {
printf ("test_mkdir_p_0 FAILED\n");
failed++;
}
- printf (" 30/ 49 test_mkdir_p_1\n");
+ printf (" 27/%3d test_mkdir_p_1\n", nr_tests);
if (test_mkdir_p_1 () == -1) {
printf ("test_mkdir_p_1 FAILED\n");
failed++;
}
- printf (" 31/ 49 test_mkdir_p_2\n");
+ printf (" 28/%3d test_mkdir_p_2\n", nr_tests);
if (test_mkdir_p_2 () == -1) {
printf ("test_mkdir_p_2 FAILED\n");
failed++;
}
- printf (" 32/ 49 test_exists_0\n");
+ printf (" 29/%3d test_exists_0\n", nr_tests);
if (test_exists_0 () == -1) {
printf ("test_exists_0 FAILED\n");
failed++;
}
- printf (" 33/ 49 test_exists_1\n");
+ printf (" 30/%3d test_exists_1\n", nr_tests);
if (test_exists_1 () == -1) {
printf ("test_exists_1 FAILED\n");
failed++;
}
- printf (" 34/ 49 test_is_file_0\n");
+ printf (" 31/%3d test_is_file_0\n", nr_tests);
if (test_is_file_0 () == -1) {
printf ("test_is_file_0 FAILED\n");
failed++;
}
- printf (" 35/ 49 test_is_file_1\n");
+ printf (" 32/%3d test_is_file_1\n", nr_tests);
if (test_is_file_1 () == -1) {
printf ("test_is_file_1 FAILED\n");
failed++;
}
- printf (" 36/ 49 test_is_dir_0\n");
+ printf (" 33/%3d test_is_dir_0\n", nr_tests);
if (test_is_dir_0 () == -1) {
printf ("test_is_dir_0 FAILED\n");
failed++;
}
- printf (" 37/ 49 test_is_dir_1\n");
+ printf (" 34/%3d test_is_dir_1\n", nr_tests);
if (test_is_dir_1 () == -1) {
printf ("test_is_dir_1 FAILED\n");
failed++;
}
- printf (" 38/ 49 test_pvcreate_0\n");
+ printf (" 35/%3d test_pvcreate_0\n", nr_tests);
if (test_pvcreate_0 () == -1) {
printf ("test_pvcreate_0 FAILED\n");
failed++;
}
- printf (" 39/ 49 test_vgcreate_0\n");
+ printf (" 36/%3d test_vgcreate_0\n", nr_tests);
if (test_vgcreate_0 () == -1) {
printf ("test_vgcreate_0 FAILED\n");
failed++;
}
- printf (" 40/ 49 test_lvcreate_0\n");
+ printf (" 37/%3d test_lvcreate_0\n", nr_tests);
if (test_lvcreate_0 () == -1) {
printf ("test_lvcreate_0 FAILED\n");
failed++;
}
- printf (" 41/ 49 test_mkfs_0\n");
+ printf (" 38/%3d test_mkfs_0\n", nr_tests);
if (test_mkfs_0 () == -1) {
printf ("test_mkfs_0 FAILED\n");
failed++;
}
- printf (" 42/ 49 test_write_file_0\n");
+ printf (" 39/%3d test_write_file_0\n", nr_tests);
if (test_write_file_0 () == -1) {
printf ("test_write_file_0 FAILED\n");
failed++;
}
- printf (" 43/ 49 test_umount_0\n");
+ printf (" 40/%3d test_umount_0\n", nr_tests);
if (test_umount_0 () == -1) {
printf ("test_umount_0 FAILED\n");
failed++;
}
- printf (" 44/ 49 test_umount_1\n");
+ printf (" 41/%3d test_umount_1\n", nr_tests);
if (test_umount_1 () == -1) {
printf ("test_umount_1 FAILED\n");
failed++;
}
- printf (" 45/ 49 test_mounts_0\n");
+ printf (" 42/%3d test_mounts_0\n", nr_tests);
if (test_mounts_0 () == -1) {
printf ("test_mounts_0 FAILED\n");
failed++;
}
- printf (" 46/ 49 test_umount_all_0\n");
+ printf (" 43/%3d test_umount_all_0\n", nr_tests);
if (test_umount_all_0 () == -1) {
printf ("test_umount_all_0 FAILED\n");
failed++;
}
- printf (" 47/ 49 test_file_0\n");
+ printf (" 44/%3d test_file_0\n", nr_tests);
if (test_file_0 () == -1) {
printf ("test_file_0 FAILED\n");
failed++;
}
- printf (" 48/ 49 test_file_1\n");
+ printf (" 45/%3d test_file_1\n", nr_tests);
if (test_file_1 () == -1) {
printf ("test_file_1 FAILED\n");
failed++;
}
- printf (" 49/ 49 test_file_2\n");
+ printf (" 46/%3d test_file_2\n", nr_tests);
if (test_file_2 () == -1) {
printf ("test_file_2 FAILED\n");
failed++;
}
+ printf (" 47/%3d test_stat_0\n", nr_tests);
+ if (test_stat_0 () == -1) {
+ printf ("test_stat_0 FAILED\n");
+ failed++;
+ }
+ printf (" 48/%3d test_lstat_0\n", nr_tests);
+ if (test_lstat_0 () == -1) {
+ printf ("test_lstat_0 FAILED\n");
+ failed++;
+ }
+ printf (" 49/%3d test_statvfs_0\n", nr_tests);
+ if (test_statvfs_0 () == -1) {
+ printf ("test_statvfs_0 FAILED\n");
+ failed++;
+ }
guestfs_close (g);
snprintf (buf, sizeof buf, "%s/test1.img", srcdir);
@@ -4155,7 +4076,7 @@ int main (int argc, char *argv[])
unlink (buf);
if (failed > 0) {
- printf ("***** %d / 49 tests FAILED *****\n", failed);
+ printf ("***** %d / %d tests FAILED *****\n", failed, nr_tests);
exit (1);
}