Skip to content

os.rmdir() fails because of 'Resource busy' #53

@komh

Description

@komh

Bug description:

When setting a project up with meson with setting TMPDIR to the different drive from the current drive, setup fails due to 'Resource busy'. For example, a current dir is x:/dev/build and TMPDIR is set to y:/tmp.

Here the log:

Traceback (most recent call last):
  File "f:\lang\work\meson\meson-os2.git/mesonbuild/utils/universal.py", line 2058, in cleanup
    super().cleanup()
    ~~~~~~~~~~~~~~~^^
  File "G:/usr/lib/python3.13/tempfile.py", line 950, in cleanup
    self._rmtree(self.name, ignore_errors=self._ignore_cleanup_errors)
    ~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "G:/usr/lib/python3.13/tempfile.py", line 930, in _rmtree
    _shutil.rmtree(name, onexc=onexc)
    ~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^
  File "G:/usr/lib/python3.13/shutil.py", line 790, in rmtree
    return _rmtree_unsafe(path, onexc)
  File "G:/usr/lib/python3.13/shutil.py", line 635, in _rmtree_unsafe
    onexc(os.rmdir, path, err)
    ~~~~~^^^^^^^^^^^^^^^^^^^^^
  File "G:/usr/lib/python3.13/shutil.py", line 631, in _rmtree_unsafe
    os.rmdir(path)
    ~~~~~~~~^^^^^^
OSError: [Errno 16] Resource busy: 'P:/tmp/tmp90oh0e5u'

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "f:\lang\work\meson\meson-os2.git/mesonbuild/utils/universal.py", line 2052, in __exit__
    super().__exit__(exc, value, tb)
    ~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^
  File "G:/usr/lib/python3.13/tempfile.py", line 946, in __exit__
    self.cleanup()
    ~~~~~~~~~~~~^^
  File "f:\lang\work\meson\meson-os2.git/mesonbuild/utils/universal.py", line 2060, in cleanup
    windows_proof_rmtree(self.name)
    ~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^
  File "f:\lang\work\meson\meson-os2.git/mesonbuild/utils/universal.py", line 2025, in windows_proof_rmtree
    shutil.rmtree(f)
    ~~~~~~~~~~~~~^^^
  File "G:/usr/lib/python3.13/shutil.py", line 790, in rmtree
    return _rmtree_unsafe(path, onexc)
  File "G:/usr/lib/python3.13/shutil.py", line 635, in _rmtree_unsafe
    onexc(os.rmdir, path, err)
    ~~~~~^^^^^^^^^^^^^^^^^^^^^
  File "G:/usr/lib/python3.13/shutil.py", line 631, in _rmtree_unsafe
    os.rmdir(path)
    ~~~~~~~~^^^^^^
OSError: [Errno 16] Resource busy: 'P:/tmp/tmp90oh0e5u'

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "f:\lang\work\meson\meson-os2.git/mesonbuild/mesonmain.py", line 193, in run
    return options.run_func(options)
           ~~~~~~~~~~~~~~~~^^^^^^^^^
  File "f:\lang\work\meson\meson-os2.git/mesonbuild/msetup.py", line 404, in run
    app.generate()
    ~~~~~~~~~~~~^^
  File "f:\lang\work\meson\meson-os2.git/mesonbuild/msetup.py", line 196, in generate
    return self._generate(env, capture, vslite_ctx)
           ~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "f:\lang\work\meson\meson-os2.git/mesonbuild/msetup.py", line 255, in _generate
    intr.run()
    ~~~~~~~~^^
  File "f:\lang\work\meson\meson-os2.git/mesonbuild/interpreter/interpreter.py", line 3063, in run
    super().run()
    ~~~~~~~~~~~^^
  File "f:\lang\work\meson\meson-os2.git/mesonbuild/interpreterbase/interpreterbase.py", line 178, in run
    self.evaluate_codeblock(self.ast, start=1)
    ~~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^
  File "f:\lang\work\meson\meson-os2.git/mesonbuild/interpreterbase/interpreterbase.py", line 203, in evaluate_codeblock
    raise e
  File "f:\lang\work\meson\meson-os2.git/mesonbuild/interpreterbase/interpreterbase.py", line 195, in evaluate_codeblock
    self.evaluate_statement(cur)
    ~~~~~~~~~~~~~~~~~~~~~~~^^^^^
  File "f:\lang\work\meson\meson-os2.git/mesonbuild/interpreterbase/interpreterbase.py", line 213, in evaluate_statement
    self.assignment(cur)
    ~~~~~~~~~~~~~~~^^^^^
  File "f:\lang\work\meson\meson-os2.git/mesonbuild/interpreterbase/interpreterbase.py", line 644, in assignment
    value = self.evaluate_statement(node.value)
  File "f:\lang\work\meson\meson-os2.git/mesonbuild/interpreterbase/interpreterbase.py", line 215, in evaluate_statement
    return self.method_call(cur)
           ~~~~~~~~~~~~~~~~^^^^^
  File "f:\lang\work\meson\meson-os2.git/mesonbuild/interpreterbase/interpreterbase.py", line 550, in method_call
    obj = self.evaluate_statement(invocable)
  File "f:\lang\work\meson\meson-os2.git/mesonbuild/interpreterbase/interpreterbase.py", line 215, in evaluate_statement
    return self.method_call(cur)
           ~~~~~~~~~~~~~~~~^^^^^
  File "f:\lang\work\meson\meson-os2.git/mesonbuild/interpreterbase/interpreterbase.py", line 559, in method_call
    res = obj.method_call(method_name, args, kwargs)
  File "f:\lang\work\meson\meson-os2.git/mesonbuild/interpreterbase/baseobjects.py", line 127, in method_call
    return method(self, args, kwargs)
  File "f:\lang\work\meson\meson-os2.git/mesonbuild/interpreterbase/decorators.py", line 659, in wrapped
    return f(*wrapped_args, **wrapped_kwargs)
  File "f:\lang\work\meson\meson-os2.git/mesonbuild/interpreterbase/decorators.py", line 237, in wrapper
    return f(*nargs, **wrapped_kwargs)
  File "f:\lang\work\meson\meson-os2.git/mesonbuild/interpreterbase/decorators.py", line 565, in wrapper
    return f(*wrapped_args, **wrapped_kwargs)
  File "f:\lang\work\meson\meson-os2.git/mesonbuild/interpreter/compiler.py", line 463, in get_define_method
    value, cached = self.compiler.get_define(element, kwargs['prefix'],
                    ~~~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^
                                             extra_args=extra_args, dependencies=deps)
                                             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "f:\lang\work\meson\meson-os2.git/mesonbuild/compilers/mixins/clike.py", line 656, in get_define
    with func() as p:
         ~~~~^^
  File "G:/usr/lib/python3.13/contextlib.py", line 148, in __exit__
    next(self.gen)
    ~~~~^^^^^^^^^^
  File "f:\lang\work\meson\meson-os2.git/mesonbuild/compilers/compilers.py", line 908, in cached_compile
    with self.compile(code, extra_args=extra_args, mode=mode, want_output=False, temp_dir=temp_dir) as p:
         ~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "G:/usr/lib/python3.13/contextlib.py", line 148, in __exit__
    next(self.gen)
    ~~~~^^^^^^^^^^
  File "f:\lang\work\meson\meson-os2.git/mesonbuild/compilers/compilers.py", line 838, in compile
    with TemporaryDirectoryWinProof(dir=temp_dir if temp_dir else None) as tmpdirname:
         ~~~~~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "f:\lang\work\meson\meson-os2.git/mesonbuild/utils/universal.py", line 2054, in __exit__
    windows_proof_rmtree(self.name)
    ~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^
  File "f:\lang\work\meson\meson-os2.git/mesonbuild/utils/universal.py", line 2025, in windows_proof_rmtree
    shutil.rmtree(f)
    ~~~~~~~~~~~~~^^^
  File "G:/usr/lib/python3.13/shutil.py", line 790, in rmtree
    return _rmtree_unsafe(path, onexc)
  File "G:/usr/lib/python3.13/shutil.py", line 635, in _rmtree_unsafe
    onexc(os.rmdir, path, err)
    ~~~~~^^^^^^^^^^^^^^^^^^^^^
  File "G:/usr/lib/python3.13/shutil.py", line 631, in _rmtree_unsafe
    os.rmdir(path)
    ~~~~~~~~^^^^^^
OSError: [Errno 16] Resource busy: 'P:/tmp/tmp90oh0e5u'

And here is the patch:

diff -uNr  subprocess.py.org subprocess.py
--- subprocess.py.org	2025-05-13 23:00:18.000000000 +0000
+++ subprocess.py	2026-01-08 15:09:28.000000000 +0000
@@ -1862,7 +1862,7 @@
 
                 if close_fds:
                   mode |= os.P_2_NOINHERIT
-                if threadsafe:
+                if threadsafe or cwd is not None:
                   mode |= os.P_2_THREADSAFE
                 stdfds = [ p2cread, c2pwrite, errwrite ]
 

CPython versions tested on:

3.13

Operating systems tested on:

Other

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions