Jump to page: 1 2
Thread overview
dirEntries removes entire branches of empty directories
Nov 09, 2022
Ali Çehreli
Nov 09, 2022
Vladimir Panteleev
Nov 10, 2022
Ali Çehreli
Nov 10, 2022
Imperatorn
Nov 10, 2022
H. S. Teoh
Nov 09, 2022
kdevel
Nov 09, 2022
Imperatorn
Nov 09, 2022
Ali Çehreli
Nov 09, 2022
Imperatorn
Nov 09, 2022
Ali Çehreli
Nov 09, 2022
Imperatorn
Nov 10, 2022
Ali Çehreli
Nov 11, 2022
kdevel
Nov 11, 2022
Ali Çehreli
Nov 11, 2022
Ali Çehreli
Nov 14, 2022
kdevel
Nov 14, 2022
kdevel
Nov 26, 2022
Ali Çehreli
Nov 30, 2022
Vladimir Panteleev
November 09, 2022
In case it matters, the file system is ext4.

1) Create a directory:

  mkdir deleteme

and then run the following program:

import std;

void main() {
    foreach (e; dirEntries(absolutePath("./deleteme"), SpanMode.breadth)) {
        writeln(e.name);
    }
}

Understandably, the top level directory 'deleteme' will not be printed.

2) Make a sub-directory:

  mkdir deleteme/a

Running the program shows no output; 'a' is not visited as a directory entry.

3) Create a file inside the sub-directory:

  touch deleteme/a/x

Now the program will show 2 entries; the branch is accessible:

/home/ali/d/./deleteme/a
/home/ali/d/./deleteme/a/x

Imagine a program that wants to make sure the directory structure is intact, even the empty directories should exist. Can you think of a workaround to achieve that?

Do you think this is buggy behavior for dirEntries?

Ali
November 09, 2022

On Wednesday, 9 November 2022 at 19:05:58 UTC, Ali Çehreli wrote:

>

Running the program shows no output; 'a' is not visited as a directory entry.

That's not what happens for me:

import std.exception;
import std.file;
import std.path;
import std.stdio;

void ls()
{
    foreach (e; dirEntries(absolutePath("./deleteme"), SpanMode.breadth)) {
        writeln(e.name);
    }	
}

void main()
{
	"./deleteme".rmdirRecurse.collectException;
	"./deleteme".mkdir();

	writeln("empty");
	ls();

	writeln("only a directory");
	mkdir("./deleteme/a");
	ls();

	writeln("directory and file");
	std.file.write("./deleteme/a/x", "");
	ls();
}

Locally and on run.dlang.io I get:

empty
only a directory
/sandbox/./deleteme/a
directory and file
/sandbox/./deleteme/a
/sandbox/./deleteme/a/x
November 09, 2022
On Wednesday, 9 November 2022 at 19:05:58 UTC, Ali Çehreli wrote:
> In case it matters, the file system is ext4.

My code runs in tmp (tmpfs).

> 2) Make a sub-directory:
>
>   mkdir deleteme/a
>
> Running the program shows no output; 'a' is not visited as a directory entry.

Was say strace/ltrace?

```didi.d
import std.stdio;
import std.file;

void main (string [] args)
{
   auto de = dirEntries (args[1], SpanMode.breadth);
   foreach (e; de)
      writeln(e.name);
}
```

```
$ mkdir -p deleteme/a
$ dmd didi
$ ./didi deleteme
deleteme/a

> Do you think this is buggy behavior for dirEntries?

Sure.
November 09, 2022
On Wednesday, 9 November 2022 at 19:05:58 UTC, Ali Çehreli wrote:
> In case it matters, the file system is ext4.
>
> 1) Create a directory:
>
> [...]

That's not the behaviour I get in Windows.

When I create the subdirectory, I see it even if it's empty
November 09, 2022
On 11/9/22 11:48, Imperatorn wrote:

> That's not the behaviour I get in Windows.

Windows users deserve it! :p (At least it is better in this case. :) )

> When I create the subdirectory, I see it even if it's empty

struct DirIteratorImpl has different implementations for Windows, etc.

Ali

November 09, 2022
On 11/9/22 11:05, Ali Çehreli wrote:

> Can you think of a workaround to achieve that?

Me, me, me! :) I've learned about the Posix function 'nftw' (but I am using its sibling 'ftw').

It was pretty easy to use but there is a quality issue there: They failed to support a 'void*' context for the user! You can walk the tree but can't put the results into your local context! Boo!

I guess it was designed by someone who is happy with global variables. :) At least D makes it easy to guard access to module variables with 'synchronized', shared, etc.

Ali

November 09, 2022
On Wednesday, 9 November 2022 at 20:06:15 UTC, Ali Çehreli wrote:
> On 11/9/22 11:05, Ali Çehreli wrote:
>
> It was pretty easy to use but there is a quality issue there: They failed to support a 'void*' context for the user! You can walk the tree but can't put the results into your local context! Boo!

👻

November 09, 2022
On Wednesday, 9 November 2022 at 19:59:57 UTC, Ali Çehreli wrote:
> On 11/9/22 11:48, Imperatorn wrote:
>
> > That's not the behaviour I get in Windows.
>
> Windows users deserve it! :p (At least it is better in this case. :) )
>
> > When I create the subdirectory, I see it even if it's empty
>
> struct DirIteratorImpl has different implementations for Windows, etc.
>
> Ali

Anyway, it's definitely a bug in that implementation
November 10, 2022
On 11/9/22 11:30, Vladimir Panteleev wrote:
> On Wednesday, 9 November 2022 at 19:05:58 UTC, Ali Çehreli wrote:
>> Running the program shows no output; 'a' is not visited as a directory
>> entry.
>
> That's not what happens for me:

Does not happen for me today either. (?) I must have confused myself both with my actual program and with a trivial isolated program that I had written to test it.

Unless others have seen the same behavior yesterday there is no bug here today. :p

Ali
"walks away with a confused look on his face"

November 10, 2022
On Thursday, 10 November 2022 at 16:34:53 UTC, Ali Çehreli wrote:
> On 11/9/22 11:30, Vladimir Panteleev wrote:
> > On Wednesday, 9 November 2022 at 19:05:58 UTC, Ali Çehreli
> wrote:
> >> Running the program shows no output; 'a' is not visited as a
> directory
> >> entry.
> >
> > That's not what happens for me:
>
> Does not happen for me today either. (?) I must have confused myself both with my actual program and with a trivial isolated program that I had written to test it.
>
> Unless others have seen the same behavior yesterday there is no bug here today. :p
>
> Ali
> "walks away with a confused look on his face"

Oh, did you run the program on Wednesday? Fool!
« First   ‹ Prev
1 2