diff options
author | Andreas Gruenbacher <agruen@linbit.com> | 2012-04-17 16:13:08 +0200 |
---|---|---|
committer | Andreas Gruenbacher <agruen@linbit.com> | 2012-04-17 16:48:19 +0200 |
commit | 9a26fde226660a628d58ed7d987a71b9a4123244 (patch) | |
tree | f19871a06ea2300e4e170a383733a91715f8dac2 | |
parent | b9a1ff0cfa3144f212b4f1c3923c3b3c281e2240 (diff) | |
download | patch-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.man | 8 | ||||
-rw-r--r-- | src/patch.c | 19 | ||||
-rw-r--r-- | tests/read-only-files | 13 |
3 files changed, 34 insertions, 6 deletions
@@ -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 |