Modify the copy-in/copy-out APIs to use the new guestfs_int_cmd_pipe internal API. This new API allows us to capture the stderr from the tar subprocess if it fails, fixing RHBZ#1267032. The user will now see errors like this: $ guestfish -N fs -m /dev/sda1 copy-in '/tmp/d/*' / : ll / libguestfs: error: tar subprocess failed: tar: *: Cannot stat: No such file or directory tar: Exiting with failure status due to previous errors --- src/copy-in-out.c | 30 ++++++++++++++++++++++-------- 1 file changed, 22 insertions(+), 8 deletions(-) diff --git a/src/copy-in-out.c b/src/copy-in-out.c index 975c217..d5e7fb0 100644 --- a/src/copy-in-out.c +++ b/src/copy-in-out.c @@ -68,8 +68,10 @@ guestfs_impl_copy_in (guestfs_h *g, guestfs_int_cmd_add_arg (cmd, "-"); guestfs_int_cmd_add_arg (cmd, basename); - r = guestfs_int_cmd_run_async (cmd, NULL, NULL, &fd, NULL); - if (r == -1) + guestfs_int_cmd_clear_capture_errors (cmd); + + fd = guestfs_int_cmd_pipe_run (cmd, "r"); + if (fd == -1) return -1; snprintf (fdbuf, sizeof fdbuf, "/dev/fd/%d", fd); @@ -81,11 +83,16 @@ guestfs_impl_copy_in (guestfs_h *g, return -1; } - r = guestfs_int_cmd_wait (cmd); + r = guestfs_int_cmd_pipe_wait (cmd); if (r == -1) return -1; - if (!(WIFEXITED (r) && WEXITSTATUS (r) == 0)) + if (!WIFEXITED (r) || WEXITSTATUS (r) != 0) { + CLEANUP_FREE char *errors = guestfs_int_cmd_get_pipe_errors (cmd); + if (errors == NULL) + return -1; + error (g, "tar subprocess failed: %s", errors); return -1; + } return 0; } @@ -190,8 +197,10 @@ guestfs_impl_copy_out (guestfs_h *g, guestfs_int_cmd_add_arg (cmd, "-xf"); guestfs_int_cmd_add_arg (cmd, "-"); - r = guestfs_int_cmd_run_async (cmd, NULL, &fd, NULL, NULL); - if (r == -1) + guestfs_int_cmd_clear_capture_errors (cmd); + + fd = guestfs_int_cmd_pipe_run (cmd, "w"); + if (fd == -1) return -1; snprintf (fdbuf, sizeof fdbuf, "/dev/fd/%d", fd); @@ -203,11 +212,16 @@ guestfs_impl_copy_out (guestfs_h *g, return -1; } - r = guestfs_int_cmd_wait (cmd); + r = guestfs_int_cmd_pipe_wait (cmd); if (r == -1) return -1; - if (!(WIFEXITED (r) && WEXITSTATUS (r) == 0)) + if (!WIFEXITED (r) || WEXITSTATUS (r) != 0) { + CLEANUP_FREE char *errors = guestfs_int_cmd_get_pipe_errors (cmd); + if (errors == NULL) + return -1; + error (g, "tar subprocess failed: %s", errors); return -1; + } } return 0; -- 2.5.0