pytest-dev / pyfakefs

Provides a fake file system that mocks the Python file system modules.
https://pytest-pyfakefs.readthedocs.io
Apache License 2.0
627 stars 88 forks source link

Closing a duplicated fileno invalidates the previous file description #988

Closed vector-of-bool closed 3 months ago

vector-of-bool commented 3 months ago

Describe the bug If a file descriptor fd1 is duplicated to a new fd2, then fd2 is closed, the fd1 file description is deleted from the internal table, while the fd2 file description remains. It appears to be caused by the duplicated table entry using the same internal filedes value, so when the second entry is closed, it deletes the first entry based on the wrong filedes.

How To Reproduce This is the same test from #970, but the order of close() is swapped.

def read_with_dup(s: Path):
    s.write_text("heythere")
    fd1 = os.open(s, os.O_RDONLY)
    fd2 = os.dup(fd1)
    dat1 = os.read(fd1, 3)
    dat2 = os.read(fd2, 10)
    os.close(fd2)  # Okay
    os.close(fd1)  # Fails EBADF!
    assert dat1 == b"hey"
    assert dat2 == b"there"

def test_realfs():
    read_with_dup(Path("file.txt"))

def test_fakefs(fs):
    read_with_dup(Path("file.txt"))

Your environment Please run the following in the environment where the problem happened and paste the output.

$ python -c "import platform; print(platform.platform())"
Linux-6.7.6-arch1-1-x86_64-with-glibc2.39
$ python -c "import sys; print('Python', sys.version)"
Python 3.11.7 (main, Jan 29 2024, 16:03:57) [GCC 13.2.1 20230801]
$ python -c "from pyfakefs import __version__; print('pyfakefs', __version__)"
pyfakefs 5.4.dev0
$ python -c "import pytest; print('pytest', pytest.__version__)"
pytest 7.2.0