Port upstream commit, to be removed with v8.23: http://git.sv.gnu.org/cgit/coreutils.git/commit/?id=0093ac8d57 ln: with -sr, don't segfault for a TARGET of '' ln -sr '' F no longer segfaults. Now works as expected. [bug introduced with the --relative feature in coreutils-8.16] The changes in NEWS and THANKS.in in the original patch have been omitted. ----------------------------------------------- commit 0093ac8d57a0f1a16fd09d98f6a524dddb6053e7 Author: Jim Meyering Date: Thu Mar 13 17:05:04 2014 -0700 ln: with -sr, don't segfault for a TARGET of '' Prior to this change, "ln -sr '' F" would segfault, attempting to read path2[1] in relpath.c's path_common_prefix function. This problem arises whenever canonicalize_filename_mode returns NULL. * src/ln.c (convert_abs_rel): Call relpath only when both canonicalize_filename_mode calls return non-NULL. * tests/ln/relative.sh: Add a test to trigger this failure. Reported by Erik Bernstein in 739752@bugs.debian.org. Fixes http://bugs.gnu.org/17010. --- src/ln.c | 16 ++++++++++------ tests/ln/relative.sh | 5 +++++ 2 files changed, 15 insertions(+), 6 deletions(-) Index: src/ln.c =================================================================== --- src/ln.c.orig +++ src/ln.c @@ -139,13 +139,17 @@ convert_abs_rel (const char *from, const char *realdest = canonicalize_filename_mode (targetdir, CAN_MISSING); char *realfrom = canonicalize_filename_mode (from, CAN_MISSING); - /* Write to a PATH_MAX buffer. */ - char *relative_from = xmalloc (PATH_MAX); - - if (!relpath (realfrom, realdest, relative_from, PATH_MAX)) + char *relative_from = NULL; + if (realdest && realfrom) { - free (relative_from); - relative_from = NULL; + /* Write to a PATH_MAX buffer. */ + relative_from = xmalloc (PATH_MAX); + + if (!relpath (realfrom, realdest, relative_from, PATH_MAX)) + { + free (relative_from); + relative_from = NULL; + } } free (targetdir); Index: tests/ln/relative.sh =================================================================== --- tests/ln/relative.sh.orig +++ tests/ln/relative.sh @@ -45,4 +45,9 @@ mkdir web ln -sr latest web/latest test $(readlink web/latest) = '../release2' || fail=1 +# Expect this to fail with exit status 1, or to succeed quietly (freebsd). +# Prior to coreutils-8.23, it would segfault. +ln -sr '' F +case $? in [01]) ;; *) fail=1;; esac + Exit $fail