summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndreas Gruenbacher <agruen@linbit.com>2012-04-17 16:13:08 +0200
committerAndreas Gruenbacher <agruen@linbit.com>2012-04-17 16:48:19 +0200
commit9a26fde226660a628d58ed7d987a71b9a4123244 (patch)
treef19871a06ea2300e4e170a383733a91715f8dac2
parentb9a1ff0cfa3144f212b4f1c3923c3b3c281e2240 (diff)
downloadpatch-9a26fde226660a628d58ed7d987a71b9a4123244.tar.gz
Only warn when trying to modify read-only files
Failing when trying to patch read-only files causes various users of patch to break. Instead, warn by default and introduce a command line option for choosing a different behavior. * patch.man: Describe the new behavior and command-line option. * src/patch.c (read_only_behavior): New variable. (main): Implement the new behavior. (longopts): Add the new --read-only option. (option_help): Describe the new behavior. (get_some_switches): Recognize the new --read-only option.
-rw-r--r--patch.man8
-rw-r--r--src/patch.c19
-rw-r--r--tests/read-only-files13
3 files changed, 34 insertions, 6 deletions
diff --git a/patch.man b/patch.man
index 02e6b90..b0ee8c1 100644
--- a/patch.man
+++ b/patch.man
@@ -314,6 +314,10 @@ and patches should be generated by
.B "diff\ \*=binary"
when line endings are significant.)
.TP
+\fB\*=read\-only=\fP\fIbehavior\fP
+Behave as requested when trying to modify a read-only file: \fBignore\fP the
+potential problem, \fBwarn\fP about it (the default), or \fBfail\fP.
+.TP
\fB\-c\fP or \fB\*=context\fP
Interpret the patch file as a ordinary context diff.
.TP
@@ -356,8 +360,8 @@ removes a file, it also attempts to remove any empty ancestor directories.
\fB\-f\fP or \fB\*=force\fP
Assume that the user knows exactly what he or she is doing, and do not
ask any questions. Skip patches whose headers
-do not say which file is to be patched; patch files even though they are
-read-only or have the wrong version for the
+do not say which file is to be patched; patch files even though they have the
+wrong version for the
.B Prereq:\&
line in the patch; and assume that
patches are not reversed even if they look like they are.
diff --git a/src/patch.c b/src/patch.c
index cc9b268..40987c1 100644
--- a/src/patch.c
+++ b/src/patch.c
@@ -76,6 +76,7 @@ static char const *version_control;
static char const *version_control_context;
static bool remove_empty_files;
static bool explicit_inname;
+static enum { RO_IGNORE, RO_WARN, RO_FAIL } read_only_behavior = RO_WARN;
/* true if -R was specified on command line. */
static bool reverse_flag_specified;
@@ -244,11 +245,12 @@ main (int argc, char **argv)
}
}
- if (! inerrno && ! S_ISLNK (instat.st_mode)
+ if (read_only_behavior != RO_IGNORE
+ && ! inerrno && ! S_ISLNK (instat.st_mode)
&& access (inname, W_OK) != 0)
{
say ("File %s is read-only; ", quotearg (inname));
- if (force || batch)
+ if (read_only_behavior == RO_WARN)
say ("trying to patch anyway\n");
else
{
@@ -682,6 +684,7 @@ static struct option const longopts[] =
{"posix", no_argument, NULL, CHAR_MAX + 7},
{"quoting-style", required_argument, NULL, CHAR_MAX + 8},
{"reject-format", required_argument, NULL, CHAR_MAX + 9},
+ {"read-only", required_argument, NULL, CHAR_MAX + 10},
{NULL, no_argument, NULL, 0}
};
@@ -747,6 +750,8 @@ static char const *const option_help[] =
" -d DIR --directory=DIR Change the working directory to DIR first.",
" --reject-format=FORMAT Create 'context' or 'unified' rejects.",
" --binary Read and write data in binary mode.",
+" --read-only=BEHAVIOR How to handle read-only input files: 'ignore' that they",
+" are read-only, 'warn' (default), or 'fail'.",
"",
" -v --version Output version info.",
" --help Output this help.",
@@ -961,6 +966,16 @@ get_some_switches (void)
else
usage (stderr, 2);
break;
+ case CHAR_MAX + 10:
+ if (strcmp (optarg, "ignore") == 0)
+ read_only_behavior = RO_IGNORE;
+ else if (strcmp (optarg, "warn") == 0)
+ read_only_behavior = RO_WARN;
+ else if (strcmp (optarg, "fail") == 0)
+ read_only_behavior = RO_FAIL;
+ else
+ usage (stderr, 2);
+ break;
default:
usage (stderr, 2);
}
diff --git a/tests/read-only-files b/tests/read-only-files
index 7db401b..918b97a 100644
--- a/tests/read-only-files
+++ b/tests/read-only-files
@@ -41,7 +41,7 @@ EOF
echo one > f
chmod a=r f
-check 'patch -p0 < f.diff || echo "Status: $?"' <<EOF
+check 'patch -p0 --read-only=fail < f.diff || echo "Status: $?"' <<EOF
File f is read-only; refusing to patch
1 out of 1 hunk ignored -- saving rejects to file f.rej
File f is read-only; refusing to patch
@@ -51,9 +51,18 @@ EOF
rm -f f.rej
-check 'patch -f -p0 < f.diff || echo "Status: $?"' <<EOF
+check 'patch -f -p0 --read-only=warn < f.diff || echo "Status: $?"' <<EOF
File f is read-only; trying to patch anyway
patching file f
File f is read-only; trying to patch anyway
patching file f
EOF
+
+rm -f f
+echo one > f
+chmod a=r f
+
+check 'patch -f -p0 --read-only=ignore < f.diff || echo "Status: $?"' <<EOF
+patching file f
+patching file f
+EOF