Skip to content

rigfs.Fsys return fs.ErrNotExist on empty directories (v0.21.6) #354

@i-prudnikov

Description

@i-prudnikov

rig’s ReadDir uses find … -print0 and then strings.Split(out, "\x00"). -print0 always ends the stream with a NUL. For a directory that only contains itself (i.e. no children), the output is roughly:
dirname + \0
In Go that string splits as two segments: []string{"dirname", ""} — a non‑nil trailing empty element.
The code assumes “only the directory line” means exactly one segment:
github.com/k0sproject/rig/pkg/rigfs/posixfsys.go lines 613-625

  items := strings.Split(out, "\\x00")
  if len(items) == 0 || (len(items) == 1 && items[0] == "") {
      return nil, &fs.PathError{Op: "read dir", Path: name, Err: fs.ErrNotExist}
  }
  if items[0] != name {
      return nil, &fs.PathError{Op: "read dir", Path: name, Err: fs.ErrNotExist}
  }
  if len(items) == 1 {
      return nil, nil
  }
  res := make([]fs.DirEntry, 0, len(items)-1)
  infos, err := fsys.multiStat(items[1:]...)

For dirname\x00 you get len(items) == 2, so you do not take the len(items) == 1 { return nil, nil } branch (the “empty directory” branch).

Then it calls multiStat(items[1:]...) → multiStat(""). For a single empty name, multiStat ends up running stat with an empty argument list and maps that to “not exist” with Path: names[0] (the empty string):
github.com/k0sproject/rig/pkg/rigfs/posixfsys.go lines 385-391

  func (fsys *PosixFsys) multiStat(names ...string) ([]fs.FileInfo, error) {
      // ...
          out, err := fsys.conn.ExecOutput(fmt.Sprintf(*fsys.statCmd, batch.String()), fsys.opts...)
          if err != nil {
              if len(names) == 1 {
                  return nil, &fs.PathError{Op: OpStat, Path: names[0], Err: fs.ErrNotExist}
              }

That matches the case : Op: "stat", Path: "", Err: file does not exist.

Rig’s version used: github.com/k0sproject/rig v0.21.6

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions