Date: Mon, 10 Mar 2008 15:51:23 GMT From: Ighighi <ighighi@gmail.com> To: freebsd-gnats-submit@FreeBSD.org Subject: bin/121568: [patch]: wrong "ln -s" behaviour Message-ID: <200803101551.m2AFpNfP071097@www.freebsd.org> Resent-Message-ID: <200803101600.m2AG06KG020494@freefall.freebsd.org>
next in thread | raw e-mail | index | archive | help
>Number: 121568 >Category: bin >Synopsis: [patch]: wrong "ln -s" behaviour >Confidential: no >Severity: non-critical >Priority: medium >Responsible: freebsd-bugs >State: open >Quarter: >Keywords: >Date-Required: >Class: sw-bug >Submitter-Id: current-users >Arrival-Date: Mon Mar 10 16:00:01 UTC 2008 >Closed-Date: >Last-Modified: >Originator: Ighighi >Release: 6.3-STABLE >Organization: >Environment: FreeBSD orion 6.3-STABLE FreeBSD 6.3-STABLE #0: Mon Mar 3 04:45:31 VET 2008 root@orion:/usr/obj/usr/src/sys/CUSTOM i386 >Description: When running "ln -s" and the last argument is a directory, if any of the source files has a trailing slash it gives errors. To create a symlink like this: /tmp/defaults -> /etc/defaults/ $ /bin/rm -f /tmp/defaults $ /bin/ln -sv /etc/defaults/ /tmp ln: /tmp/: File exists $ /bin/ln -sv /etc/defaults /tmp /tmp/defaults -> /etc/defaults In this case, both commands should work regardless of any trailing slash, as is the case with GNU ln(1). I tend to use trailing slashes to make sure I'm hitting a directory or a symlink to one. Quoting the POSIX description of ln(1) available at: See http://www.opengroup.org/onlinepubs/009695399/utilities/ln.html "The corresponding destination path for each source_file shall be the concatenation of the target directory pathname, a slash character, and the last pathname component of the source_file. The second synopsis form shall be assumed when the final operand names an existing directory." The "last pathname component" is defined here: http://www.opengroup.org/onlinepubs/009695399/basedefs/xbd_chap03.html#tag_03_267 The bug is in ln(1) using strrchr(xxx, '/') instead of basename(). >How-To-Repeat: >Fix: Attached patch tested against the latest code in CVS Patch attached with submission follows: --- src/bin/ln/ln.c.orig 2007-11-17 17:01:22.000000000 -0400 +++ src/bin/ln/ln.c 2008-03-10 04:52:27.703080785 -0430 @@ -46,6 +46,7 @@ #include <err.h> #include <errno.h> +#include <libgen.h> #include <limits.h> #include <stdio.h> #include <stdlib.h> @@ -189,10 +190,8 @@ linkit(const char *source, const char *t if (isdir || (lstat(target, &sb) == 0 && S_ISDIR(sb.st_mode)) || (!hflag && stat(target, &sb) == 0 && S_ISDIR(sb.st_mode))) { - if ((p = strrchr(source, '/')) == NULL) - p = source; - else - ++p; + if ((p = basename(source)) == NULL) + return (1); if (snprintf(path, sizeof(path), "%s/%s", target, p) >= (ssize_t)sizeof(path)) { errno = ENAMETOOLONG; >Release-Note: >Audit-Trail: >Unformatted:
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200803101551.m2AFpNfP071097>