#include <fcntl.h>
#include <errno.h>
#include <unistd.h>
+#include <captive/macros.h>
+#include <stdlib.h>
#include "cmd_put.h" /* self */
#include "cmd_cd.h" /* for cmdline_path_from_cwd() */
/* Config: */
-#define TRANSFER_BUFFER_SIZE (0x10000)
+#define DEFAULT_TRANSFER_BUFFER_SIZE (0x10000)
GQuark cmdline_cmd_put_error_quark(void)
}
+static gchar *optarg_transfer_buffer;
+
const struct poptOption cmd_put_table[]={
- POPT_AUTOHELP
+ CMDLINE_POPT("buffer-size",'b',POPT_ARG_STRING,&optarg_transfer_buffer,
+ N_("Transfer buffer size"),N_("size")),
+ CMDLINE_POPT_AUTOHELP
POPT_TABLEEND
};
const gchar *sourcefile,*targetfile;
guint perm=0644;
int fdsrc;
-guint8 transfer_buffer[TRANSFER_BUFFER_SIZE];
+guint8 *transfer_buffer;
+long transfer_buffer_size=DEFAULT_TRANSFER_BUFFER_SIZE;
int got;
g_return_if_fail(!errp || !*errp);
+ if (optarg_transfer_buffer) {
+const gchar *string=captive_strdup_alloca(optarg_transfer_buffer);
+char *endptr;
+
+ free(optarg_transfer_buffer);
+ optarg_transfer_buffer=NULL;
+
+ transfer_buffer_size=strtol(string,&endptr,0);
+ if (transfer_buffer_size<=0 || transfer_buffer_size>=LONG_MAX || (endptr && *endptr)) {
+ g_set_error(errp,CMDLINE_CMD_PUT_ERROR,CMDLINE_CMD_PUT_ERROR_PARSING_TRANSFER_BUFFER_SIZE,
+ _("Error parsing transfer buffer size: %s"),string);
+ return;
+ }
+ }
+
sourcefile=cmd_argv[0];
if (cmd_argv[1])
targetfile=cmdline_path_from_cwd(cmd_argv[1]);
goto err_close_fdsrc;
}
- while (0<(got=read(fdsrc,transfer_buffer,sizeof(transfer_buffer)))) {
+ transfer_buffer=g_malloc(transfer_buffer_size);
+ g_assert(transfer_buffer!=NULL); /* Should not happen. */
+
+ while (0<(got=read(fdsrc,transfer_buffer,transfer_buffer_size))) {
GnomeVFSFileSize bytes_written;
if (!errvfsresult_to_gerr(errp,captive_file_write(
err_cleanup(errp);
g_set_error(errp,CMDLINE_CMD_PUT_ERROR,CMDLINE_CMD_PUT_ERROR_WRITING_TARGET_GUESTOS_FILE,
_("Error writing target guest-os file: %s"),targetfile);
- goto err_unref_captive_file_object;
+ goto err_free_transfer_buffer;
}
if (bytes_written!=(GnomeVFSFileSize)got) {
g_set_error(errp,CMDLINE_CMD_PUT_ERROR,CMDLINE_CMD_PUT_ERROR_WRITING_TARGET_GUESTOS_FILE,
_("Error writing target guest-os file '%s': requested %d, written %Lu"),
targetfile,got,(unsigned long long)bytes_written);
- goto err_unref_captive_file_object;
+ goto err_free_transfer_buffer;
}
}
if (got==-1) {
g_set_error(errp,CMDLINE_CMD_PUT_ERROR,CMDLINE_CMD_PUT_ERROR_READING_SOURCE_FILE,
_("Error reading source host-os file '%s': %s"),sourcefile,g_strerror(errno));
- goto err_unref_captive_file_object;
+ goto err_free_transfer_buffer;
}
g_assert(got==0);
-err_unref_captive_file_object:
+err_free_transfer_buffer:
+ g_free(transfer_buffer);
+/* err_unref_captive_file_object: */
g_object_unref(captive_file_object);
err_close_fdsrc:
if (close(fdsrc)) {