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
====================================