? weirdness in Find.find/lstat?

rubyists-

does this look like bug, or is this behaviour somehow correct :

~ > cd /tmp
/tmp > mkdir foo
/tmp > ln -s foo bar
/tmp > touch foo/bar

/tmp > ruby -r find -e “Find.find(‘foo’){|found| p found}”
“foo”
“foo/bar”

/tmp > ruby -r find -e “Find.find(‘bar’){|found| p found}”
“bar”

/tmp > ruby -r find -e “Find.find(‘bar/’){|found| p found}”
“bar/”
“bar//bar”

to me, this looks like Find.find does not descend into linked directories
unless the directory is demarked by a trailing slash. what might be the
reason for this? upon encountering a soft link, wouldn’t it make sense to
stat the entry linked to in order to determine the type?

in fact the find.rb module uses File.lstat(file).directory?, but in the case
of links this will never be true. why is this?

lstat itself seems to have strange behaviour :

/tmp > ruby -r find -e “p File.lstat(‘bar’).directory?”
false

/tmp > ruby -r find -e “p File.lstat(‘bar/’).directory?”
true

i checked and this is the behaviour of the underlying C calls as well. is
this a linux bug, or do all lstat/stat posix calls work that way?

following is a C program to check on another system :

--------CUT--------
#include <stdlib.h>
#include <stdio.h>
#include <sys/stat.h>
#include <unistd.h>

void
display (filestat)
struct stat *filestat;
{
mode_t m = filestat->st_mode;

if (S_ISLNK (m))
  printf ("is it a symbolic link?\n");
if (S_ISREG (m))
  printf ("regular file?\n");
if (S_ISDIR (m))
  printf ("directory?\n");
if (S_ISCHR (m))
  printf ("character device?\n");
if (S_ISBLK (m))
  printf ("block device?\n");
if (S_ISFIFO (m))
  printf ("fifo?\n");
if (S_ISSOCK (m))
  printf ("socket?\n");

}

int
main (argc, argv, env)
int argc;
char **argv;
char **env;
{
struct stat filestat;

stat (argv[1], &filestat);

display (&filestat);

lstat (argv[1], &filestat);
display (&filestat);

return 0;

}
--------CUT--------

if you compile this program and run it against a soft link linked against a
directory with, and without, a trailing slash i see the same bizarre
behaviour, at least on linux :

~ > cd /tmp
/tmp > mkdir foo
/tmp > ln -s foo bar

/tmp > ./a.out /tmp/bar
directory?
is it a symbolic link?

/tmp > ./a.out /tmp/bar/
directory?
directory?

i realize this a C question. but if the behaviour is different on different
systems it might make sense to abstract the ruby lstat/stat calls in such a
way that the behaviour is consistent on all platforms. if all platforms
behave this way then i guess the current implementation makes perfect sense.
if anyone has time to test the above program on other platforms, i’d really
appreciate it.

-a

···

====================================

Ara Howard
NOAA Forecast Systems Laboratory
Information and Technology Services
Data Systems Group
R/FST 325 Broadway
Boulder, CO 80305-3328
Email: ahoward@fsl.noaa.gov
Phone: 303-497-7238
Fax: 303-497-7259
====================================

Hi,

···

In message “?? weirdness in Find.find/lstat ??” on 02/12/07, ahoward ahoward@fsl.noaa.gov writes:

lstat itself seems to have strange behaviour :

/tmp > ruby -r find -e “p File.lstat(‘bar’).directory?”
false

/tmp > ruby -r find -e “p File.lstat(‘bar/’).directory?”
true

i checked and this is the behaviour of the underlying C calls as well. is
this a linux bug, or do all lstat/stat posix calls work that way?

“bar/” is “bar” and “”, which is considered as “bar/.”, so that it is
referring the directory itself. I’m not sure if it’s POSIX-ly defined
behavior.

						matz.

i’m not 100% positive, but i did some searching on google and ran some tests
on our irix/sun/linux/hp-ux boxes : it seems linux is the only system
exhibiting this - which is considered a bug in fileutils.

in fact, lstat bar when bar is linked to foo should tell you that bar is also
a directory - which is does not on linux unless you lstat bar/

-a

···

On Sat, 7 Dec 2002, Yukihiro Matsumoto wrote:

lstat itself seems to have strange behaviour :

/tmp > ruby -r find -e “p File.lstat(‘bar’).directory?”
false

/tmp > ruby -r find -e “p File.lstat(‘bar/’).directory?”
true

i checked and this is the behaviour of the underlying C calls as well. is
this a linux bug, or do all lstat/stat posix calls work that way?

“bar/” is “bar” and “”, which is considered as “bar/.”, so that it is
referring the directory itself. I’m not sure if it’s POSIX-ly defined
behavior.

====================================

Ara Howard
NOAA Forecast Systems Laboratory
Information and Technology Services
Data Systems Group
R/FST 325 Broadway
Boulder, CO 80305-3328
Email: ahoward@fsl.noaa.gov
Phone: 303-497-7238
Fax: 303-497-7259
====================================

Hi,

···

At Sat, 7 Dec 2002 10:33:19 +0900, Yukihiro Matsumoto wrote:

lstat itself seems to have strange behaviour :

/tmp > ruby -r find -e “p File.lstat(‘bar’).directory?”
false

/tmp > ruby -r find -e “p File.lstat(‘bar/’).directory?”
true

i checked and this is the behaviour of the underlying C calls as well. is
this a linux bug, or do all lstat/stat posix calls work that way?

“bar/” is “bar” and “”, which is considered as “bar/.”, so that it is
referring the directory itself. I’m not sure if it’s POSIX-ly defined
behavior.

While I tested on SourceForge Compile Farm, “bar/” was
equivalent to “bar” on Solaris.


Nobu Nakada

Hi,

···

In message “Re: ?? weirdness in Find.find/lstat ??” on 02/12/07, ahoward ahoward@fsl.noaa.gov writes:

i’m not 100% positive, but i did some searching on google and ran some tests
on our irix/sun/linux/hp-ux boxes : it seems linux is the only system
exhibiting this - which is considered a bug in fileutils.

in fact, lstat bar when bar is linked to foo should tell you that bar is also
a directory - which is does not on linux unless you lstat bar/

If so, it should be reported to the linux developers.

						matz.

Hi –

···

On Sat, 7 Dec 2002, ahoward wrote:

in fact, lstat bar when bar is linked to foo should tell you that bar is also
a directory - which is does not on linux unless you lstat bar/

I thought lstat differs from stat specifically in that it reports on
the link (rather than the thing the link points to). I’m not sure
about the bar vs. bar/ distinction… but if it’s just bar, I think
lstat should report on the link itself.

David


David Alan Black
home: dblack@candle.superlink.net
work: blackdav@shu.edu
Web: http://pirate.shu.edu/~blackdav

what you say in in agreement with the linux man page, but many unices seem to
disagree with you (solaris, irix, hp-ux). additionally the bar vs. bar/
issure on linux can lead to very confusing behaviour.

all i am saying is that, due to differences in the stat/lstat implementation
across unices, Find.find &block will behave differently on identically
structured filesystems where links are concerned. this is not a good thing
imho. languages like ruby, which purport some level of platform independence,
sometimes try to smooth over these blemishes. i was merely pointing out the
source of the problem so the powers that be could make the ‘right’ descision.

-a

···

On Sat, 7 Dec 2002 dblack@candle.superlink.net wrote:

I thought lstat differs from stat specifically in that it reports on
the link (rather than the thing the link points to). I’m not sure
about the bar vs. bar/ distinction… but if it’s just bar, I think
lstat should report on the link itself.

====================================

Ara Howard
NOAA Forecast Systems Laboratory
Information and Technology Services
Data Systems Group
R/FST 325 Broadway
Boulder, CO 80305-3328
Email: ahoward@fsl.noaa.gov
Phone: 303-497-7238
Fax: 303-497-7259
====================================