@@ -7760,7 +7760,7 @@ parse_posix_spawn_flags(PyObject *module, const char *func_name, PyObject *setpg
77607760static int
77617761parse_file_actions(PyObject *file_actions,
77627762 posix_spawn_file_actions_t *file_actionsp,
7763- PyObject *temp_buffer)
7763+ PyObject *temp_buffer, PyObject** cwd )
77647764{
77657765 PyObject *seq;
77667766 PyObject *file_action = NULL;
@@ -7884,7 +7884,8 @@ parse_file_actions(PyObject *file_actions,
78847884 Py_DECREF(path);
78857885 goto fail;
78867886 }
7887- Py_DECREF(path);
7887+ Py_XDECREF(cwd);
7888+ *cwd = path;
78887889 break;
78897890 }
78907891#endif
@@ -7924,6 +7925,7 @@ py_posix_spawn(int use_posix_spawnp, PyObject *module, path_t *path, PyObject *a
79247925 Py_ssize_t argc, envc;
79257926 PyObject *result = NULL;
79267927 PyObject *temp_buffer = NULL;
7928+ PyObject *cwd = NULL;
79277929 pid_t pid;
79287930 int err_code;
79297931
@@ -7995,7 +7997,7 @@ py_posix_spawn(int use_posix_spawnp, PyObject *module, path_t *path, PyObject *a
79957997 if (!temp_buffer) {
79967998 goto exit;
79977999 }
7998- if (parse_file_actions(file_actions, &file_actions_buf, temp_buffer)) {
8000+ if (parse_file_actions(file_actions, &file_actions_buf, temp_buffer, &cwd )) {
79998001 goto exit;
80008002 }
80018003 file_actionsp = &file_actions_buf;
@@ -8027,6 +8029,17 @@ py_posix_spawn(int use_posix_spawnp, PyObject *module, path_t *path, PyObject *a
80278029
80288030 if (err_code) {
80298031 errno = err_code;
8032+ #ifdef HAVE_POSIX_SPAWN_FILE_ACTIONS_ADDCHDIR_NP
8033+ if (errno == ENOENT && cwd != NULL) {
8034+ /* ENOENT can occur when either the path of the executable or the
8035+ * cwd given via file_actions doesn't exist. Since it's not feasible
8036+ * to determine which of those paths caused the problem, we return
8037+ * an exception with both. */
8038+ PyErr_Format(PyExc_FileNotFoundError, "Either '%S' or '%s' doesn't exist.",
8039+ path->object, PyBytes_AS_STRING(cwd));
8040+ goto exit;
8041+ }
8042+ #endif
80308043 PyErr_SetFromErrnoWithFilenameObject(PyExc_OSError, path->object);
80318044 goto exit;
80328045 }
@@ -8048,6 +8061,7 @@ py_posix_spawn(int use_posix_spawnp, PyObject *module, path_t *path, PyObject *a
80488061 if (argvlist) {
80498062 free_string_array(argvlist, argc);
80508063 }
8064+ Py_XDECREF(cwd);
80518065 Py_XDECREF(temp_buffer);
80528066 return result;
80538067}
0 commit comments