On Fri, Dec 18, 2009 at 8:01 AM, Robert Dodier <robert.dodier@gmail.com> wrote:
On 12/17/09, Juan Jose Garcia-Ripoll
<juanjose.garciaripoll@googlemail.com> wrote:
> On Wed, Dec 16, 2009 at 6:14 AM, Robert Dodier

> An unfortunate mistake: DIRECTORY used stat() on all entries in a directory,
> not only those that matched the mask. It was just a matter of switching
> lines. Now things are better. Thanks a lot for reporting.

> $ echo '(directory "/Users/jjgarcia/tmp/")(quit)' > foo.lsp; sudo dtrace -n
> 'pid$target::safe_stat:entry  { printf("%s\n", copyinstr((uintptr_t)arg0));
> }' -c "ecl -norc -load foo"
> dtrace: description 'pid$target::safe_stat:entry  ' matched 1 probe
> ;;; Loading #P"/Users/jjgarcia/foo.lsp"
> dtrace: pid 39532 has exited
> CPU     ID                    FUNCTION:NAME
>   0  19180                  safe_stat:entry jjgarcia
>   0  19180                  safe_stat:entry tmp

Hmm. I updated from CVS and I got r1.100 src/d/unixfsys.d
which has the modified code. I did a clean build,
but I get the same behavior as before.

No, you are not seeing the same behavior as before. Before, if ECL wanted to list a directory of /var/tmp/foo/a.txt it would run through the directory chain "stat-ing" the content of /var, /tmp and /foo Now it only does what is expected: it lists the content of each directory, and only inspect those that match the masks "var", "tmp", "foo" and "a.txt" There are thus only a few calls to "stat" which HAVE to be done: "var", "tmp", "foo" have to be verified not to be files, and for "a.txt" we have to verify it is not a symbolic link or return its true name.

Before thet patch

$ trace ecl -eval '(directory "/home/jjgarcia/mtp/foo")' -eval '(quit)' 2>&1 |tee ~/log
$ grep stat log |wc -l
162

After the patch

$ trace ecl -eval '(directory "/home/jjgarcia/mtp/foo")' -eval '(quit)' 2>&1 |tee ~/log2
$ grep stat log2 |wc -l
64

More precisely

[... stat due to system loading libraries ...]
fstat(4, {st_mode=S_IFREG|0755, st_size=411898, ...}) = 0
lstat("/home/jjgarcia/", {st_mode=S_IFDIR|0755, st_size=4096, ...}) = 0
stat("home", {st_mode=S_IFDIR|0755, st_size=4096, ...}) = 0
stat("jjgarcia", {st_mode=S_IFDIR|0755, st_size=4096, ...}) = 0
stat("mtp", {st_mode=S_IFDIR|0755, st_size=4096, ...}) = 0
stat("foo", {st_mode=S_IFREG|0644, st_size=0, ...}) = 0
lstat("foo", {st_mode=S_IFREG|0644, st_size=0, ...}) = 0

 
For the record, I'm looking at the output of strace,
not dtrace, which appears to be something else.

There is no strace in OS X. dtrace does the same and more: it allows you to select which calls to log. But I used "strace" in another box to show this works.
 
I don't know what safe_stat is; I'm guessing it is a library
function instead of a system call and, therefore,
not immediately relevant. (I'm interested in the calls to stat64.)

Please do not assume I am a fool by default. safe_stat() is a wrapper around stat() that captures any error condition, similarly there is safe_lstat() and other wrappers.

Juanjo

--
Instituto de Física Fundamental, CSIC
c/ Serrano, 113b, Madrid 28006 (Spain)
http://juanjose.garciaripoll.googlepages.com