summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'app-misc/mc/files/mc-4.8.13-3297-prealloc.patch')
-rw-r--r--app-misc/mc/files/mc-4.8.13-3297-prealloc.patch120
1 files changed, 120 insertions, 0 deletions
diff --git a/app-misc/mc/files/mc-4.8.13-3297-prealloc.patch b/app-misc/mc/files/mc-4.8.13-3297-prealloc.patch
new file mode 100644
index 000000000000..d84c3484ceba
--- /dev/null
+++ b/app-misc/mc/files/mc-4.8.13-3297-prealloc.patch
@@ -0,0 +1,120 @@
+commit a3486faac37680e3bcf7d0b3905f745765a823fd
+Author: Andrew Borodin <aborodin@vmail.ru>
+Date: Mon Nov 10 10:32:34 2014 +0300
+
+ Ticket #3297: don't lose file in case of preallocate space fail.
+
+ Don't remove the destination file if it was retrieved incompletely
+ but it was already exist and appended during copy/move operation.
+
+ Signed-off-by: Andrew Borodin <aborodin@vmail.ru>
+
+diff --git a/src/filemanager/file.c b/src/filemanager/file.c
+index 9fbf081..3009ccf 100644
+--- a/src/filemanager/file.c
++++ b/src/filemanager/file.c
+@@ -1497,7 +1497,6 @@ copy_file_file (file_op_total_context_t * tctx, file_op_context_t * ctx,
+ int open_flags;
+ gboolean is_first_time = TRUE;
+ vfs_path_t *src_vpath = NULL, *dst_vpath = NULL;
+- gboolean write_errno_nospace = FALSE;
+
+ /* FIXME: We should not be using global variables! */
+ ctx->do_reget = 0;
+@@ -1739,28 +1738,39 @@ copy_file_file (file_op_total_context_t * tctx, file_op_context_t * ctx,
+ goto ret;
+ }
+
+- while (TRUE)
++ /* try preallocate space; if fail, try copy anyway */
++ while (vfs_preallocate (dest_desc, file_size, ctx->do_append != 0 ? sb.st_size : 0) != 0)
+ {
+- errno = vfs_preallocate (dest_desc, file_size, (ctx->do_append != 0) ? sb.st_size : 0);
+- if (errno == 0)
++ if (ctx->skip_all)
++ {
++ /* cannot allocate, start the file copying anyway */
++ return_status = FILE_CONT;
+ break;
++ }
+
+- if (ctx->skip_all)
+- return_status = FILE_SKIPALL;
+- else
++ return_status =
++ file_error (_("Cannot preallocate space for target file \"%s\"\n%s"), dst_path);
++
++ if (return_status == FILE_SKIPALL)
++ ctx->skip_all = TRUE;
++
++ if (ctx->skip_all || return_status == FILE_SKIP)
+ {
+- return_status =
+- file_error (_("Cannot preallocate space for target file \"%s\"\n%s"), dst_path);
+- if (return_status == FILE_RETRY)
+- continue;
+- if (return_status == FILE_SKIPALL)
+- ctx->skip_all = TRUE;
++ /* skip the space allocation error, start file copying */
++ return_status = FILE_CONT;
++ break;
+ }
+- mc_close (dest_desc);
+- dest_desc = -1;
+- mc_unlink (dst_vpath);
+- dst_status = DEST_NONE;
+- goto ret;
++
++ if (return_status == FILE_ABORT)
++ {
++ mc_close (dest_desc);
++ dest_desc = -1;
++ mc_unlink (dst_vpath);
++ dst_status = DEST_NONE;
++ goto ret;
++ }
++
++ /* return_status == FILE_RETRY -- try allocate space again */
+ }
+
+ ctx->eta_secs = 0.0;
+@@ -1822,6 +1832,8 @@ copy_file_file (file_op_total_context_t * tctx, file_op_context_t * ctx,
+ /* dst_write */
+ while ((n_written = mc_write (dest_desc, t, n_read)) < n_read)
+ {
++ gboolean write_errno_nospace;
++
+ if (n_written > 0)
+ {
+ n_read -= n_written;
+@@ -1851,10 +1863,6 @@ copy_file_file (file_op_total_context_t * tctx, file_op_context_t * ctx,
+ }
+ if (return_status != FILE_RETRY)
+ goto ret;
+-
+- /* User pressed "Retry". Will the next mc_write() call be successful?
+- * Reset error flag to be ready for that. */
+- write_errno_nospace = FALSE;
+ }
+ }
+
+@@ -1933,16 +1941,9 @@ copy_file_file (file_op_total_context_t * tctx, file_op_context_t * ctx,
+
+ if (dst_status == DEST_SHORT)
+ {
+- /* Remove short file */
+- int result = 0;
+-
+- /* In case of copy/move to full partition, keep source file
+- * and remove incomplete destination one */
+- if (!write_errno_nospace)
+- result = query_dialog (Q_ ("DialogTitle|Copy"),
+- _("Incomplete file was retrieved. Keep it?"),
+- D_ERROR, 2, _("&Delete"), _("&Keep"));
+- if (result == 0)
++ /* Query to remove short file */
++ if (query_dialog (Q_ ("DialogTitle|Copy"), _("Incomplete file was retrieved. Keep it?"),
++ D_ERROR, 2, _("&Delete"), _("&Keep")) == 0)
+ mc_unlink (dst_vpath);
+ }
+ else if (dst_status == DEST_FULL)