@@ -7280,7 +7280,7 @@ parse_posix_spawn_flags(PyObject *module, const char *func_name, PyObject *setpg
72807280static  int 
72817281parse_file_actions (PyObject  * file_actions ,
72827282                   posix_spawn_file_actions_t  * file_actionsp ,
7283-                    PyObject  * temp_buffer )
7283+                    PyObject  * temp_buffer ,  PyObject * *   cwd )
72847284{
72857285    PyObject  * seq ;
72867286    PyObject  * file_action  =  NULL ;
@@ -7404,7 +7404,8 @@ parse_file_actions(PyObject *file_actions,
74047404                    Py_DECREF (path );
74057405                    goto fail ;
74067406                }
7407-                 Py_DECREF (path );
7407+                 Py_XDECREF (cwd );
7408+                 * cwd  =  path ;
74087409                break ;
74097410            }
74107411#endif 
@@ -7444,6 +7445,7 @@ py_posix_spawn(int use_posix_spawnp, PyObject *module, path_t *path, PyObject *a
74447445    Py_ssize_t  argc , envc ;
74457446    PyObject  * result  =  NULL ;
74467447    PyObject  * temp_buffer  =  NULL ;
7448+     PyObject  * cwd  =  NULL ;
74477449    pid_t  pid ;
74487450    int  err_code ;
74497451
@@ -7509,7 +7511,7 @@ py_posix_spawn(int use_posix_spawnp, PyObject *module, path_t *path, PyObject *a
75097511        if  (!temp_buffer ) {
75107512            goto exit ;
75117513        }
7512-         if  (parse_file_actions (file_actions , & file_actions_buf , temp_buffer )) {
7514+         if  (parse_file_actions (file_actions , & file_actions_buf , temp_buffer ,  & cwd )) {
75137515            goto exit ;
75147516        }
75157517        file_actionsp  =  & file_actions_buf ;
@@ -7541,6 +7543,17 @@ py_posix_spawn(int use_posix_spawnp, PyObject *module, path_t *path, PyObject *a
75417543
75427544    if  (err_code ) {
75437545        errno  =  err_code ;
7546+ #ifdef  HAVE_POSIX_SPAWN_FILE_ACTIONS_ADDCHDIR_NP 
7547+         if  (errno  ==  ENOENT  &&  cwd  !=  NULL ) {
7548+             /* ENOENT can occur when either the path of the executable or the 
7549+              * cwd given via file_actions doesn't exist. Since it's not feasible 
7550+              * to determine which of those paths caused the problem, we return 
7551+              * an exception with both. */ 
7552+             PyErr_Format (PyExc_FileNotFoundError , "Either '%S' or '%s' doesn't exist." ,
7553+                          path -> object , PyBytes_AS_STRING (cwd ));
7554+             goto exit ;
7555+         }
7556+ #endif 
75447557        PyErr_SetFromErrnoWithFilenameObject (PyExc_OSError , path -> object );
75457558        goto exit ;
75467559    }
@@ -7562,6 +7575,7 @@ py_posix_spawn(int use_posix_spawnp, PyObject *module, path_t *path, PyObject *a
75627575    if  (argvlist ) {
75637576        free_string_array (argvlist , argc );
75647577    }
7578+     Py_XDECREF (cwd );
75657579    Py_XDECREF (temp_buffer );
75667580    return  result ;
75677581}
0 commit comments