Skip to content

IterableDir does not iterate over all contents created after opening (Linux BTRFS) #17095

@ianprime0509

Description

@ianprime0509

Zig Version

0.12.0-dev.286+b0d9bb0bb

Steps to Reproduce and Observed Behavior

Caveat: this may not necessarily be a bug if this is acceptable platform-specific behavior, but it may be an opportunity for enhanced documentation if it is acceptable. Related to #17064 as the apparent underlying cause of that issue (this pattern appears within Package.zig: #17064 (comment)).

Given the following Zig code:

const std = @import("std");

pub fn main() !void {
    var dir = try std.fs.cwd().openIterableDir("test", .{});
    defer dir.close();

    try dir.dir.writeFile("1", "1");
    try dir.dir.writeFile("2", "2");

    var iter = dir.iterate();
    while (try iter.next()) |entry| {
        std.debug.print("{s}\n", .{entry.name});
    }
}

Running this code with an initially empty test directory yields the following output on my machine:

1

Subsequent runs, after test has already been populated with both files, yield the following output:

1
2

Output of uname -a:

Linux toolbox 6.4.12-200.fc38.x86_64 #1 SMP PREEMPT_DYNAMIC Wed Aug 23 17:46:49 UTC 2023 x86_64 GNU/Linux

Expected Behavior

The code should always output

1
2

even if those files were not both present when the IterableDir was opened, or a note should be added to IterableDir's documentation mentioning the platform-specific behavior.

In support of the view that this is not a bug (at least in Zig), the following C code reproduces the same behavior of excluding 2 from the output of the first run on an initially empty test directory:

#import <dirent.h>
#import <errno.h>
#import <stdio.h>

int main(void) {
  DIR *dir = opendir("test");
  if (!dir) {
    perror("open test");
    return 1;
  }

  FILE *file;
  if (!(file = fopen("test/1", "w"))) {
    perror("open 1");
    return 1;
  }
  fwrite("1", 1, 1, file);
  fclose(file);

  if (!(file = fopen("test/2", "w"))) {
    perror("open 2");
    return 1;
  }
  fwrite("2", 1, 1, file);
  fclose(file);

  errno = 0;
  struct dirent *entry;
  while ((entry = readdir(dir))) {
    printf("%s\n", entry->d_name);
    errno = 0;
  }
  if (errno != 0) {
    perror("read test");
    return 1;
  }
  return 0;
}

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugObserved behavior contradicts documented or intended behavioros-linuxstandard libraryThis issue involves writing Zig code for the standard library.upstreamAn issue with a third party project that Zig uses.

    Type

    No type

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions