summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndreas Gruenbacher <agruen@linbit.com>2012-09-19 02:01:25 +0200
committerAndreas Gruenbacher <agruen@linbit.com>2012-09-19 03:16:07 +0200
commit293415dbcf8c621c8aecb4347abd32fd60935a8b (patch)
treec36aa40734ac2be8ad5c6a956d7dc0d20359953d
parent59609b50c538db1805161cb8afe9986f82b9759a (diff)
downloadpatch-293415dbcf8c621c8aecb4347abd32fd60935a8b.tar.gz
Add --follow-symlinks option for backwards compatibility
* src/common.h (follow_symlinks): New variable. * src/patch.c (longopts): Add new --follow-symlinks option. (get_some_switches): Recognize the new option. * src/util.c (stat_file): Follow symlinks if requested. * patch.man: Document the new option. * tests/symlinks: Add test case.
-rw-r--r--patch.man7
-rw-r--r--src/common.h1
-rw-r--r--src/patch.c4
-rw-r--r--src/util.c5
-rw-r--r--tests/symlinks5
5 files changed, 21 insertions, 1 deletions
diff --git a/patch.man b/patch.man
index 0433145..c5cc5c4 100644
--- a/patch.man
+++ b/patch.man
@@ -600,6 +600,13 @@ diff form.
\fB\-s\fP or \fB\*=silent\fP or \fB\*=quiet\fP
Work silently, unless an error occurs.
.TP
+\fB\*=follow\-symlinks\fP
+When looking for input files, follow symbolic links. Replaces the symbolic
+links, instead of modifying the files the symbolic links point to. Git-style
+patches to symbolic links will no longer apply. This option exists for
+backwards compatibility with previous versions of patch; its use is
+discouraged.
+.TP
\fB\-t\fP or \fB\*=batch\fP
Suppress questions like
.BR \-f ,
diff --git a/src/common.h b/src/common.h
index 23a4091..a66e55f 100644
--- a/src/common.h
+++ b/src/common.h
@@ -111,6 +111,7 @@ XTERN bool canonicalize;
XTERN int patch_get;
XTERN bool set_time;
XTERN bool set_utc;
+XTERN bool follow_symlinks;
enum diff
{
diff --git a/src/patch.c b/src/patch.c
index 2055cb9..8b2f8c0 100644
--- a/src/patch.c
+++ b/src/patch.c
@@ -726,6 +726,7 @@ static struct option const longopts[] =
{"quoting-style", required_argument, NULL, CHAR_MAX + 8},
{"reject-format", required_argument, NULL, CHAR_MAX + 9},
{"read-only", required_argument, NULL, CHAR_MAX + 10},
+ {"follow-symlinks", no_argument, NULL, CHAR_MAX + 11},
{NULL, no_argument, NULL, 0}
};
@@ -1017,6 +1018,9 @@ get_some_switches (void)
else
usage (stderr, 2);
break;
+ case CHAR_MAX + 11:
+ follow_symlinks = true;
+ break;
default:
usage (stderr, 2);
}
diff --git a/src/util.c b/src/util.c
index 271f79f..b86109d 100644
--- a/src/util.c
+++ b/src/util.c
@@ -1652,5 +1652,8 @@ make_tempfile (char const **name, char letter, char const *real_name,
int stat_file (char const *filename, struct stat *st)
{
- return lstat (filename, st) == 0 ? 0 : errno;
+ int (*xstat)(char const *, struct stat *) =
+ follow_symlinks ? stat : lstat;
+
+ return xstat (filename, st) == 0 ? 0 : errno;
}
diff --git a/tests/symlinks b/tests/symlinks
index 5f7595d..96626b3 100644
--- a/tests/symlinks
+++ b/tests/symlinks
@@ -54,6 +54,11 @@ File l is not a regular file -- refusing to patch
1 out of 1 hunk ignored -- saving rejects to file l.rej
Status: 1
EOF
+
+check 'patch --follow-symlinks < modify.diff || echo "Status: $?"' <<EOF
+patching file l
+EOF
+
# --------------------------------------------------------------
rm -f f l