path.Walk on a symlink to a directory

1,558 views
Skip to first unread message

David Symonds

unread,
Jan 21, 2011, 3:16:24 AM1/21/11
to golang-nuts, g...@golang.org
path.Walk uses os.Lstat and thus doesn't work on a symlink to a directory.
If I use os.Lstat or os.Stat to try to dereference a symlink, I don't
think I can get a full filename to pass to path.Walk without a lot of
effort.

Am I overlooking something obvious?

David Roundy

unread,
Jan 21, 2011, 9:47:29 AM1/21/11
to David Symonds, golang-nuts, g...@golang.org
Following symlinks in path.Walk seems like a bad idea, as it can lead
to confusing behavior. Perhaps path.Walk could be coded to avoid
infinite loops due to link cycles, but it also would mean that you'd
have no guarantee that the walk hasn't escaped the parent directory.
So, for instance, it wouldn't be useful for implementing "rm -rf".

Or perhaps I'm misunderstanding, and you mean to request that the root
of the walk be treated specially, and that symlinks be followed when
looking at the root, but not during the walk itself?

David

--
David Roundy

chris dollin

unread,
Jan 21, 2011, 9:54:37 AM1/21/11
to David Roundy, David Symonds, golang-nuts, g...@golang.org
On 21 January 2011 14:47, David Roundy <rou...@physics.oregonstate.edu> wrote:
> Following symlinks in path.Walk seems like a bad idea, as it can lead
> to confusing behavior.  Perhaps path.Walk could be coded to avoid
> infinite loops due to link cycles, but it also would mean that you'd
> have no guarantee that the walk hasn't escaped the parent directory.
> So, for instance, it wouldn't be useful for implementing "rm -rf".
>
> Or perhaps I'm misunderstanding, and you mean to request that the root
> of the walk be treated specially, and that symlinks be followed when
> looking at the root, but not during the walk itself?

I though the OP was saying that when they got a symlink from
Walk they were unable to construct the full path for the referred-to
file so as to be able to Walk it.

Minimal complete example would be nice.

> On Fri, Jan 21, 2011 at 12:16 AM, David Symonds <dsym...@golang.org> wrote:
>> path.Walk uses os.Lstat and thus doesn't work on a symlink to a directory.
>> If I use os.Lstat or os.Stat to try to dereference a symlink, I don't
>> think I can get a full filename to pass to path.Walk without a lot of
>> effort.
>>
>> Am I overlooking something obvious?

Chris

--
Chris "allusive" Dollin

David Symonds

unread,
Jan 21, 2011, 6:16:07 PM1/21/11
to David Roundy, golang-nuts, g...@golang.org
On Sat, Jan 22, 2011 at 1:47 AM, David Roundy
<rou...@physics.oregonstate.edu> wrote:

> Or perhaps I'm misunderstanding, and you mean to request that the root
> of the walk be treated specially, and that symlinks be followed when
> looking at the root, but not during the walk itself?

Yes, that's precisely the situation. I'm working with a build system
that creates a regular directory tree in a place that isn't practical
to locate and creates a symlink to the root of that tree in a
convenient location. I've got the path to the symlink, and I want to
walk the directory tree.

Any ideas?


Dave.

k...@xph.us

unread,
Jan 22, 2011, 12:46:59 AM1/22/11
to David Symonds, David Roundy, golang-nuts, g...@golang.org
On Fri, Jan 21, 2011 at 3:16 PM, David Symonds <dsym...@golang.org> wrote:
> Any ideas?

Are you trying to avoid writing a function such as this?

func indirect(p string) (string, os.Error) {
fi, err := os.Lstat(p)
if err != nil {
return "", err
}

for fi.IsSymlink() {
t, err := os.Readlink(p)
if err != nil {
return "", err
}

if path.IsAbs(t) {
p = t
} else {
dir, _ := path.Split(p)
p = path.Join(dir, t)
}

fi, err = os.Lstat(p)
if err != nil {
return "", err
}
}

return p, nil
}

Perhaps there is a place for this in the standard path package.

kr

k...@xph.us

unread,
Jan 22, 2011, 1:01:28 AM1/22/11
to David Symonds, David Roundy, golang-nuts, g...@golang.org
On Fri, Jan 21, 2011 at 9:46 PM, k...@xph.us <k...@xph.us> wrote:
> func indirect(p string) (string, os.Error) {
> ...
> }

Note that this particular function doesn't check for link cycles, so
it's not safe in general.

kr

David Symonds

unread,
Jan 22, 2011, 5:57:19 AM1/22/11
to k...@xph.us, David Roundy, golang-nuts, g...@golang.org
On Sat, Jan 22, 2011 at 4:46 PM, k...@xph.us <k...@xph.us> wrote:

> Are you trying to avoid writing a function such as this?

Yeah, I was trying to avoid that much effort. It seems a bit tricky to
get right, what with all the relative vs. absolute paths.
You're right, I think there should be something like this in the
standard library; path does seem like a reasonable place.


Dave.

anac...@google.com

unread,
Mar 26, 2014, 1:24:27 AM3/26/14
to golan...@googlegroups.com, k...@xph.us, David Roundy, g...@golang.org
Was something like this ever implemented?
Reply all
Reply to author
Forward
0 new messages