Bug 668327

Summary: ln implementation half-baked and incomplete
Product: [Fedora] Fedora Reporter: JW <ohtmvyyn>
Component: coreutilsAssignee: Ondrej Vasik <ovasik>
Status: CLOSED NOTABUG QA Contact: Fedora Extras Quality Assurance <extras-qa>
Severity: medium Docs Contact:
Priority: low    
Version: 14CC: aquini, kdudka, ovasik, p, twaugh
Target Milestone: ---   
Target Release: ---   
Hardware: Unspecified   
OS: Unspecified   
Fixed In Version: Doc Type: Bug Fix
Doc Text:
Story Points: ---
Clone Of: Environment:
Last Closed: 2011-01-10 06:28:06 EST Type: ---
Regression: --- Mount Type: ---
Documentation: --- CRM:
Verified Versions: Category: ---
oVirt Team: --- RHEL 7.3 requirements from Atomic Host:
Cloudforms Team: ---

Description JW 2011-01-09 23:12:13 EST
Description of problem:
When ln creates symbolic links with a target directory it fails to properly adjust paths in the created symbolic link.

Version-Release number of selected component (if applicable):

How reproducible:

Steps to Reproduce:
1. touch file
2. mkdir t
3. ln -s -t t file  (OR ln -s file t)
4. ls -l t
5. ls -L t
Actual results:
4. lrwxrwxrwx 1 root root    4 2011-01-10 14:54 file -> file
5. ls: cannot access t/file: Too many levels of symbolic links

Expected results:
4. lrwxrwxrwx 1 root root    4 2011-01-10 14:54 file -> ../file
5. lrwxrwxrwx 1 root root    0 2011-01-10 14:54 file

Additional info:
Let's face it: when ln is invoked it knows exactly what the current directory is, it knows exactly where the target directory is, it knows whether the target file has been specified with a relative path, so why doesn't it correctly create a symbolic link with the proper path relative to the target directory?  Doesn't matter for hard links, but one would hope that somebody would take the time to make relative symbolic links easier to create.  Or otherwise disallow the use of the -t option when -s is used with a relative target file.  Hard to believe that this fundamental utility has existed in such a broken state for such a long time.

More additional info:
The use of the terminology "target directory" is potentially confusing because the word "target" is also used in the context of "target of the symbolic link".  It is in fact the output or temporary current directory and would be better named as that (ie. -c, --current-directory). Fortunately the -c option is free for use.
Comment 1 Ondrej Vasik 2011-01-10 01:47:54 EST
Thanks for the report and a lot of additional information, JW.

Please, report this request for change(s) in behaviour to upstream - http://debbugs.gnu.org/coreutils (or bug-coreutils@gnu.org mailing list), as it requires wider audience to discuss the propper solution - and you will be better advocate as you may provide more usecases for "your way of ln use". Many "first sight" implementations could have nasty drawbacks.
Comment 2 Kamil Dudka 2011-01-10 04:43:48 EST
(In reply to comment #0)
> The use of the terminology "target directory" is potentially confusing because
> the word "target" is also used in the context of "target of the symbolic link".

I don't think it is.  Please refer to the info documentation:

info coreutils "Target directory"
Comment 3 Ondrej Vasik 2011-01-10 04:55:46 EST
As a side note, this is IMHO not a bug - as you expect ln to do different things than it does. 

`ln -s file' t creates 'file' symlink in t directory, pointing to self... so ls -l (with dircolors) shows it as ORPHAN (symlink to nonexistant or nonstatable file) and MISSING - it may be a bit unclear in docs, so feel free to propose documentation adjusting. If you don't agree with this, or you really think the new option is justified, please contact upstream - as I said in comment #1.
Comment 4 Pádraig Brady 2011-01-10 05:27:53 EST
I'd close this as not a bug as I don't think this is an issue.
The user should specify the link target exactly as they know
what it should be. ln couldn't start guessing. What if there
was a "file" in t/? Also we couldn't blindly assume ../ anyway
in the presence of symlinks and (bind) mounts.

As a solution to your issue, how about:

ln -s -t t $(readlink -f file)
Comment 5 JW 2011-01-10 05:41:23 EST
> What if there was a "file" in t/?

But we are trying to create a symbolic link named file so if there was already a file in t/ and no -f flag was used then obviously it would fail!

Surely you could figure that out?  How could you propose such a ridiculous contrivance?

> Also we couldn't blindly assume ../

Nobody was suggesting that ln should hard-code a ../ !!??!!  Only that ln should WORK OUT THE CORRECT RELATIVE PATH. Got that?

> ln -s -t t $(readlink -f file)

That creates a symbolic link with an absolute path.  This entire report was NOT ABOUT ABSOLUTE PATHS. Yes, I know how to create a symbolic link with an absolute path.  We all do.  But that is not the problem.  We want relative symbolic links that will still work when an entire file hierarchy gets moved or renamed.

Consider this:

(cd $a/$b/$c && ln -s ../../..file .)

Now under normal circumstances that is a way to get a relative symbolic link in the requisite directory.

But consider what happens should variable "b" be empty.  Very difficult then to reliably determine the correct number of ../'s to have in the path.
Comment 6 Ondrej Vasik 2011-01-10 06:28:06 EST
Thanks for upstream comment, Padraig. I'm closing this NOTABUG, JW, if you are going to discuss this topic further, I recommend to use upstream mailing list/bug tracker for wider audience (as Jim M./Paul E./Eric B. and others are not subsribed to this bugzilla).