Bug#336560: vim loops forever in readlink on startup when
opening symlinked file with two parent directories of the same name
James Vega
jamessan at jamessan.com
Tue Nov 1 18:32:18 UTC 2005
On Tue, Nov 01, 2005 at 05:08:57PM +0100, Stefano Zacchiroli wrote:
> On Mon, Oct 31, 2005 at 09:29:23PM -0500, James Vega wrote:
> > The attached patch fixes the bug.
Actually, I think I was this is incorrect. It looks like the problem is
more complex than I thought. You were on the right path, but were
missing one thing. Here is a breakdown of the problem:
# Using the bug reporter's situation:
# /tmp/vim-bug/vim-bug/subdir/testfile
# /tmp/vim-bug/subdir/testfile -> ../vim-bug/subdir/testfile
# cwd = "/tmp/vim-bug"
void
resolvesymlink(fname, buf, bufsiz)
char_u *fname, *buf;
size_t bufsiz;
{
# fname = "subdir/testfile" ("/tmp/vim-bug/subdir/testfile")
char_u tmp[PATH_MAX];
if (fname == NULL)
return;
# I haven't taken a deep look at the code that uses buf after
# resolvesymlink is called, but we may want to have resolvesymlink
# return readlink's return code so we know how long the string in buf
# is.
# readlink call returns 26
# buf = "../vim-bug/subdir/testfile" ("/tmp/vim-bug/../vim-bug/subdir/testfile")
if (readlink((char *) fname, (char *) buf, bufsiz) == -1)
STRCPY(buf, fname); /* not a symlink: return fname unmodified */
else
{ /* symlink: recursively expand */
# Before we recursively expand, we need to check whether buf is an
# absolute or relative path. If it is a relative path, we should
# convert it to an absolute path. This would probable be better as
# (possibly modified to retain the readlink return value):
#
# do {
# STRCPY(tmp, buf);
# some_convert_to_absolute_path_function(fname, tmp);
# } while (readlink((char *) tmp, (char *) buf, bufsiz) != -1);
STRCPY(tmp, buf);
# tmp = "../vim-bug/subdir/testfile" ("/tmp/vim-bug/../vim-bug/subdir/testfile")
# buf = "../vim-bug/subdir/testfile" ("/tmp/vim-bug/../vim-bug/subdir/testfile")
#
# buf should be adjusted for the fact that it is a relative link based
# on being in "/tmp/vim-bug/subdir" when you dereference it. We're
# instead dereferencing it from "/tmp/vim-bug" which means we perform
# readlink on the same file.
# Since it isn't, we get stuck dereferencing the same symlink.
while (readlink((char *) tmp, (char *) buf, bufsiz) != -1)
STRCPY(tmp, buf);
}
}
> > My only concern is what we should do
> > if EINVAL isn't what errno is set to[1]. Is that possible in the way
> > the code is called?
>
> I would say that an "assertion failed" like exit would be appropriate in
> any of the cases errno != EINVAL. Nonetheless one of them is the one
> that should happen in the case described by the bugreport, isn't it?
> Which one does actually happen in that case?
Yes, we should get an EINVAL when we finally call readlink on an actual
file instead of a symlink.
I can work on a patch that does what I outlined above. I'll post it
here when I'm finished, as my C skills are a little rusty. Peer review
would be good. :)
James
--
GPG Key: 1024D/61326D40 2003-09-02 James Vega <jamessan at jamessan.com>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 197 bytes
Desc: not available
Url : http://lists.alioth.debian.org/pipermail/pkg-vim-maintainers/attachments/20051101/c9cfd44b/attachment-0001.pgp
More information about the pkg-vim-maintainers
mailing list