@@ -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