Skip to content

MockFileSystem incorrectly allows shared access to same file #1356

Closed

Description

@maltebp

Describe the bug
According to C#'s filesystem API, if you open a file with FileShare.None then it should not be possible to create other file streams to that file. If you do this using the "real" file system on Windows, it will throw an IOException with the message: "The process cannot access the file '-local file path-' because it is being used by another process.". But using the MockFileSystem this does not produce any error, which seems wrong.

To Reproduce
Run this code:

 MockFileSystem mockFileSystem = new();
 mockFileSystem.FileStream.New("SomeFile.txt", FileMode.Create, FileAccess.ReadWrite, FileShare.None); // Should cause open to fail
 // mockFileSystem.File.Create("SomeFile.txt"); // Does not fail either

 mockFileSystem.FileStream.New("SomeFile.txt", FileMode.Open, FileAccess.Read);


 FileSystem realFileSystem = new();
 realFileSystem.FileStream.New("SomeFile.txt", FileMode.Create, FileAccess.ReadWrite, FileShare.None); // Causes open to fail
 // realFileSystem.File.Create("SomeFile.txt"); Also fails

 realFileSystem.FileStream.New("SomeFile.txt", FileMode.Open, FileAccess.Read);

Expected behavior
It should fail when creating the "open" stream on the MockFileSystem, but it does not.

Additional context

  • TestableIO version: 22.0.16
  • .NET: net8.0-windows
  • Windows version: Microsoft Windows 11 Enterprise (10.0.22631 Build 22631)

Activity

  1. vbreuss commented on Oct 18, 2025

    @vbreuss
    Member

    Thanks for reporting, @maltebp. Do you want to take over this issue?

  2. added
    flag: good-first-issueIssues that are good for first time contributors
    and removed on Oct 18, 2025
  3. HarrisonTCodes commented on Oct 18, 2025

    @HarrisonTCodes
    Contributor

    I was messing around with potential solutions to this, thought I would share one that might be useful and I got working. I pushed it up on my fork, on this branch.

    I added proper handling/parsing of the share args in the file stream factory methods,
    Then created a static hash set of opened and unshared file streams' paths (ie those that are currently open and were opened with FileShare.None),
    Handled adding to this set on stream creation, and removing from it on disposal,
    Then added a check in the constructor which throws a like-for-like exception with the real filesystem if a second stream is opened.

    Haven't extensively tested this, and not sure if its the desired approach here - its a bit of a hack I put together quickly for experimentation in its current form. But might be useful in solving this!

  4. maltebp commented on Oct 24, 2025

    @maltebp
    Author

    @vbreuss I won't have time to fix it in the near future unfortunately. But if it hasn't been fixed until when I'll get the time to look at it, I might take a peek.

  5. vbreuss commented on Oct 25, 2025

    @vbreuss
    Member

    Thanks for letting me know, @maltebp 👍
    I leave the issue open, maybe someone wants to pick it up...

  6. HarrisonTCodes commented on Oct 25, 2025

    @HarrisonTCodes
    Contributor

    @vbreuss If the approach in my above comment is how we want to tackle this, I'd be happy to pick this up and refine my implementation. Unsure if I'm overlooking something and open to feedback on it - I'm quite new to this package!

  7. vbreuss commented on Oct 30, 2025

    @vbreuss
    Member

    @vbreuss If the approach in my above comment is how we want to tackle this, I'd be happy to pick this up and refine my implementation. Unsure if I'm overlooking something and open to feedback on it - I'm quite new to this package!

    I just had a quick glance over it and it does indeed look promising. Please ensure that it also works with concurrent access (so you should probably replace the HashSet with a ConcurrentDictionary, as suggested in this answer on StackOverflow).
    I will assign this issue to you, @HarrisonTCodes

  8. HarrisonTCodes commented on Oct 30, 2025

    @HarrisonTCodes
    Contributor

    Thanks @vbreuss, I will look into concurrency (thanks for the pointer) and get a PR up for this.

  9. github-actions commented on Nov 22, 2025

    @github-actions

    This is addressed in release v22.1.0.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Labels

flag: good-first-issueIssues that are good for first time contributorsstate: releasedIssues that are releasedtype: bugIssues that describe misbehaving functionality

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions