This issue tracker has been migrated to GitHub, and is currently read-only.
For more information, see the GitHub FAQs in the Python's Developer Guide.

classification
Title: subprocess.run(), subprocess.Popen() should accept file descriptor as cwd parameter
Type: enhancement Stage: needs patch
Components: Extension Modules Versions: Python 3.11
process
Status: open Resolution:
Dependencies: Superseder:
Assigned To: Nosy List: gregory.p.smith, ydroneaud
Priority: normal Keywords:

Created on 2022-03-15 14:55 by ydroneaud, last changed 2022-04-11 14:59 by admin.

Messages (4)
msg415249 - (view) Author: Yann Droneaud (ydroneaud) Date: 2022-03-15 14:55
subprocess.run() and subprocess.Popen() accepts a cwd= parameter to change directory before running the subprocess.

Unfortunately it's not possible to use a file descriptor to run the subprocess in a directory already opened.

For example:

    import os
    import subprocess
    with os.open('/usr/bin', os.O_RDONLY) as f:
        subprocess.run(["ls", "-l"], cwd=f, check=True)

fails with

    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
      File "/usr/lib/python3.9/subprocess.py", line 505, in run
        with Popen(*popenargs, **kwargs) as process:
      File "/usr/lib/python3.9/subprocess.py", line 951, in __init__
        self._execute_child(args, executable, preexec_fn, close_fds,
      File "/usr/lib/python3.9/subprocess.py", line 1754, in _execute_child
        self.pid = _posixsubprocess.fork_exec(

Using a file descriptor instead of path is useful to address TOCTOU issues.

Maybe a mean to convert a file descriptor to a Path-like object would do the trick.
msg415716 - (view) Author: Gregory P. Smith (gregory.p.smith) * (Python committer) Date: 2022-03-21 22:07
Basically you want it to call fchdir() instead of chdir() when passed a fd (integer) instead of a string/Path-like.  That makes sense and should be a reasonably straight forward set of changes to _posixsubprocess.c.

(A way to convert a fd into a Path-like object would _not_ work as that'd reintroduce the TOCTOU on the directory - that'd be a pathlib feature request anyways, not a subprocess one)
msg416788 - (view) Author: Yann Droneaud (ydroneaud) Date: 2022-04-05 16:24
I looked at posixmodule: os.chdir() accepts a file descriptor.
Maybe it can be possible to invoke it from _posixsubprocess.c instead of calling chdir().
msg416801 - (view) Author: Gregory P. Smith (gregory.p.smith) * (Python committer) Date: 2022-04-05 18:51
this mostly requires plumbing to accept an int as the cwd and plumb that through to the between fork and exec code to call `fchdir(cwd_fd)` on the `int` instead of chdir(cwd) on the `char*`.

the Modules/_posixsubprocess.c internals are a bit of a mess today with a bazillion parameters passed to internal functions which makes this a pain... I want to refactor things to use a struct and not need that, but adding this feature is doable regardless.
History
Date User Action Args
2022-04-11 14:59:57adminsetgithub: 91183
2022-04-05 18:51:32gregory.p.smithsetmessages: + msg416801
components: + Extension Modules, - Library (Lib)
2022-04-05 16:24:11ydroneaudsetmessages: + msg416788
2022-03-21 22:07:02gregory.p.smithsetstage: needs patch
messages: + msg415716
versions: + Python 3.11, - Python 3.9, Python 3.10
2022-03-21 20:55:03ned.deilysetnosy: + gregory.p.smith
2022-03-15 14:55:54ydroneaudcreate