John Garvey <jgarvey@qnx.com> wrote:
Xiaodan Tang <> xtang@qnx.com> > wrote:
In _IO_CONNECT, you should also check if connect->mode is 0, (non-read/write
open). and should accept the open(), so the next _IO_STAT will comes to you.
Well, not quite. The ‘mode’ field describes whether to follow the link or
not. S_ISLNK(msg->connect.mode) means don’t follow/resolve the link (you
are opening the symlink itself); !S_ISLNK(msg->connect.mode) means follow
the link (resolve it and do the name munging/re-direction). This is the
difference, for example, between stat() and lstat(). But I’ve already
posted this detail on a couple of other occassions (I think it was in the
‘Free Book Authoring Help’ thread > > , so that can’t be it …
“Pretend” I’m stupid
io_open ()
{
for each component of the path {
verify access permissions, and that the parent is a directory
if this component is a symlink {
if (!S_ISLNK (msg → connect.mode) || symlink is not final component in pathname) {
return (redirect_symlink (…));
}
}
}
}
John, if I’ve understood everything so far, then the above code is what you’ve
said needs to be done – I added the “|| symlink is not final component”
because if it’s not the final component, we have to follow it, right?
For example:
/comp1/comp2/symlink/comp3/comp4
I have no choice but to follow/redirect the “symlink” component in this case, right?
The case we’re discussing in this thread, though, is the case where the symlink
is in fact the last component, is a directory, and we’ve cd’d into it:
ln -s /tmp x
cd x
In this case, the test just boils down to:
if (!S_ISLNK (msg → connect.mode)) {
return (redirect_symlink (…));
}
The problem is that there’s a difference between “ls” and “ls -l”:
[columbia@ttypa] ls
…/ …/ AAA243023 elv_13c62057.1 strtok.c voyager.root/
[columbia@ttypa] ls -l
lrwxr-xr-x 1 root root 0 Dec 18 19:56 .@ → /tmp
If you’re still being nice and reading this far here’s a blow-by-blow message
trace of what happens.
First, the “ls” case:
io_open() gets called:
pathname is “x”
mode is 0xA000
IOFLAG:-R-W O_LARGEFILE
we call iofunc_open with a NULL “dattr”
we allocate an OCB and return EOK
io_stat() gets called,
io_close() gets called.
io_open() gets called:
pathname is “x”
mode is 0x0000
IOFLAG:-R-W O_LARGEFILE
we redirect the symlink to “/tmp”
io_open() gets called:
pathname is “x”
mode is 0x0000
IOFLAG:+R-W O_NONBLOCK
we redirect the symlink to “/tmp”
Looks “ok” to me – when the flag was 0xA000, we returned an OCB, and when the flag
was 0x0000, we did the symlink redirect.
In any event, the “ls” is what I would have expected, that when I’m cd’d into the
symlink’d directory, I get the contents of the directory.
However, it’s the “ls -l” case that has me worried:
io_open() gets called:
pathname is “x”
mode is 0xA000
IOFLAG:-R-W O_LARGEFILE
we call iofunc_open with a NULL “dattr”
we allocate an OCB and return EOK
io_stat() gets called,
io_close() gets called.
Then, io_readlink (“x”) is called.
That’s it – no other calls after that point, the “ls -l” has returned with
the “.@ → tmp” output.
Weird, huh?
I’m sure I’m doing something stoooopid.
Thanks again for your help and patience!
-RK
–
Robert Krten, PARSE Software Devices +1 613 599 8316.
Realtime Systems Architecture, Books, Video-based and Instructor-led
Training and Consulting at www.parse.com.
Email my initials at parse dot com.