summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndreas Gruenbacher <agruen@linbit.com>2012-04-12 22:54:19 +0200
committerAndreas Gruenbacher <agruen@linbit.com>2012-04-17 16:48:19 +0200
commit73184a17e237f0004b41a3bf1492a7f0ef8f1a7a (patch)
tree42b696f430f7d48535c5c0a5821869e27149ef3f
parent02548c154916d8811c1e38dff75fa9f6e1b7fb55 (diff)
downloadpatch-73184a17e237f0004b41a3bf1492a7f0ef8f1a7a.tar.gz
Create and delete output files in a single function
* src/patch.c (output_file): New function for creating or deleting an output file and backing the old file up as needed. (main): Use the new function. * src/util.c (move_file): Allow FROM_NEEDS_REMOVAL to be NULL.
-rw-r--r--src/patch.c57
-rw-r--r--src/util.c5
2 files changed, 40 insertions, 22 deletions
diff --git a/src/patch.c b/src/patch.c
index dd8b336..3bd7472 100644
--- a/src/patch.c
+++ b/src/patch.c
@@ -53,6 +53,9 @@ static void abort_hunk (char const *, bool, bool);
static void abort_hunk_context (bool, bool);
static void abort_hunk_unified (bool, bool);
+static void output_file (char const *, int *, const struct stat *, char const *,
+ mode_t, bool);
+
#ifdef ENABLE_MERGE
static bool merge;
#else
@@ -438,16 +441,8 @@ main (int argc, char **argv)
&& ! posixly_correct)
|| S_ISLNK (file_type)))
{
- if (verbosity == VERBOSE)
- say ("Removing %s %s%s\n",
- S_ISLNK (file_type) ? "symbolic link" : "file",
- quotearg (outname),
- dry_run ? " and any empty ancestor directories" : "");
if (! dry_run)
- {
- move_file (0, 0, 0, outname, file_type | 0, backup);
- removedirs (outname);
- }
+ output_file (NULL, NULL, NULL, outname, file_type | 0, backup);
}
else
{
@@ -506,20 +501,14 @@ main (int argc, char **argv)
mode, &new_time);
}
- assert (outst.st_size != -1);
- move_file (TMPOUTNAME, &TMPOUTNAME_needs_removal, &outst,
- outname, mode, backup);
+ output_file (TMPOUTNAME, &TMPOUTNAME_needs_removal,
+ &outst, outname, mode, backup);
if (pch_rename ())
- {
- if (backup)
- create_backup (inname, 0, 0, false, true);
- else if (unlink (inname))
- pfatal ("Can't remove file %s", quotearg (inname));
- }
+ output_file (NULL, NULL, NULL, inname, mode, backup);
}
- else if (backup)
- create_backup (outname, 0, 0, true, false);
+ else
+ output_file (outname, NULL, &outst, NULL, file_type | 0, backup);
}
}
}
@@ -1619,6 +1608,34 @@ similar (char const *a, size_t alen, char const *b, size_t blen)
}
}
+/* Putting output files into place and removing them. */
+
+static void
+output_file (char const *from, int *from_needs_removal,
+ const struct stat *from_st, char const *to,
+ mode_t mode, bool backup)
+{
+ if (from == NULL)
+ {
+ if (verbosity == VERBOSE)
+ say ("Removing %s %s\n",
+ S_ISLNK (mode) ? "symbolic link" : "file",
+ quotearg (to));
+ move_file (0, 0, 0, to, mode, backup);
+ removedirs (to);
+ }
+ else if (to == NULL)
+ {
+ if (backup)
+ create_backup (from, 0, 0, true, false);
+ }
+ else
+ {
+ assert (from_st->st_size != -1);
+ move_file (from, from_needs_removal, from_st, to, mode, backup);
+ }
+}
+
/* Fatal exit with cleanup. */
void
diff --git a/src/util.c b/src/util.c
index 2985c9c..acd8d1b 100644
--- a/src/util.c
+++ b/src/util.c
@@ -519,8 +519,9 @@ move_file (char const *from, int *from_needs_removal,
/* Do not clear *FROM_NEEDS_REMOVAL if it's possible that the
rename returned zero because FROM and TO are hard links to
the same file. */
- if (0 < to_errno
- || (to_errno == 0 && to_st.st_nlink <= 1))
+ if ((0 < to_errno
+ || (to_errno == 0 && to_st.st_nlink <= 1))
+ && from_needs_removal)
*from_needs_removal = 0;
}
}