Mailing-List: contact cygwin-developers-help AT sourceware DOT cygnus DOT com; run by ezmlm List-Subscribe: List-Archive: List-Post: List-Help: , Sender: cygwin-developers-owner AT sources DOT redhat DOT com Delivered-To: mailing list cygwin-developers AT sources DOT redhat DOT com Date: Sat, 28 Apr 2001 13:07:48 -0400 From: Christopher Faylor To: cygwin-developers AT cygwin DOT com Subject: difficult problem with symbolic link handling Message-ID: <20010428130748.A20706@redhat.com> Reply-To: cygwin-developers AT cygwin DOT com Mail-Followup-To: cygwin-developers AT cygwin DOT com Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline User-Agent: Mutt/1.3.11i [long explanation follows] Someone recently pointed out a problem with "1.3.1 symbolic link handling". In reality, AFAICT, this is a long-standing problem with cygwin's symbolic problem. It's at least a year old and probably older. The pathological case was the /usr/lib/terminfo link. /usr/lib/terminfo is a link to ../share/terminfo. The problem with that is that /usr/lib is a link to /lib. So Cygwin's current symbolic link handling does this: 1) Convert /usr/lib/terminfo to (for example) f:\cygwin\lib\terminfo. 2) Read f:\cygwin\link\terminfo and retrieve the value ../share/terminfo. 3) Bite off the trailing path component and change this to: f:\cygwin\lib\..\share\terminfo. 4) "Canonicalize" this path to f:\cygwin\share\terminfo. 5) Does this file exist? No. Return an error. As you can see this is an "error" in cygwin's file handling. I've "fixed" this problem by doing the following: 1) Canonicalize /usr/lib/terminfo -> /usr/lib/terminfo 2) Pass /usr/lib/terminfo to symlink lookup which converts this to the MS-DOS equivalent f:\cygwin\lib\terminfo. 3) Return "../share/terminfo" 4) Bite off trailing path component and change this to: "/usr/lib/../share/terminfo" 5) Goto 1, which converts this to "/usr/share/terminfo", eventually exiting the loop with "success" when the file is found. On the face of it, this seems to be the right thing to do, but there are some problems. One problem is that step 2 is called repeatedly in this new scenario. This is a fairly expensive scan of cygwin's mount table (which involves a gratuitous canonicalize that was already done in step 1). Another more serious problem is that there is ambiguity in the parsing. What if /usr/lib/terminfo had a mount table entry of: f:\foo\bar\blaz\terminfo and blaz was a symlink? That would not be handled in my "improved" filename scanning above because f:\foo\bar\blaz\terminfo wouldn't actually exist. That doesn't bother the current process but the "improved" process would notice that it didn't exist and start trying to find a prefix to /usr/lib/terminfo that did exist. So, it would do a: /usr/lib/terminfo doesn't exist, try: /usr/lib exists, is is a symbolic link? No, /usr/lib/terminfo doesn't exist So, basically, what this means is that symlinks won't work in the mount table, where they did before. Does anyone have any problems with this new behavior? IMO, this new way is more correct but I have a nagging feeling that I may be missing something. cgf