Skip to content

Commit 8a29643

Browse files
committed
use a list to capture all cwds given
1 parent 3184df2 commit 8a29643

1 file changed

Lines changed: 42 additions & 12 deletions

File tree

Modules/posixmodule.c

Lines changed: 42 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -7760,7 +7760,7 @@ parse_posix_spawn_flags(PyObject *module, const char *func_name, PyObject *setpg
77607760
static int
77617761
parse_file_actions(PyObject *file_actions,
77627762
posix_spawn_file_actions_t *file_actionsp,
7763-
PyObject *temp_buffer, PyObject** cwd)
7763+
PyObject *temp_buffer, PyObject* cwd_buffer)
77647764
{
77657765
PyObject *seq;
77667766
PyObject *file_action = NULL;
@@ -7884,8 +7884,10 @@ parse_file_actions(PyObject *file_actions,
78847884
Py_DECREF(path);
78857885
goto fail;
78867886
}
7887-
Py_XDECREF(*cwd);
7888-
*cwd = path;
7887+
if (PyList_Append(cwd_buffer, path)) {
7888+
Py_DECREF(path);
7889+
goto fail;
7890+
}
78897891
break;
78907892
}
78917893
#endif
@@ -7925,7 +7927,7 @@ py_posix_spawn(int use_posix_spawnp, PyObject *module, path_t *path, PyObject *a
79257927
Py_ssize_t argc, envc;
79267928
PyObject *result = NULL;
79277929
PyObject *temp_buffer = NULL;
7928-
PyObject *cwd = NULL;
7930+
PyObject *cwd_buffer = NULL;
79297931
pid_t pid;
79307932
int err_code;
79317933

@@ -7997,7 +7999,12 @@ py_posix_spawn(int use_posix_spawnp, PyObject *module, path_t *path, PyObject *a
79977999
if (!temp_buffer) {
79988000
goto exit;
79998001
}
8000-
if (parse_file_actions(file_actions, &file_actions_buf, temp_buffer, &cwd)) {
8002+
/* TODO there can be multiple cwd actions .... */
8003+
cwd_buffer = PyList_New(0);
8004+
if (!cwd_buffer) {
8005+
goto exit;
8006+
}
8007+
if (parse_file_actions(file_actions, &file_actions_buf, temp_buffer, cwd_buffer)) {
80018008
goto exit;
80028009
}
80038010
file_actionsp = &file_actions_buf;
@@ -8030,13 +8037,36 @@ py_posix_spawn(int use_posix_spawnp, PyObject *module, path_t *path, PyObject *a
80308037
if (err_code) {
80318038
errno = err_code;
80328039
#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.",
8040+
Py_ssize_t cwd_size = PyList_GET_SIZE(cwd_buffer);
8041+
if (errno == ENOENT && cwd_size > 0) {
8042+
/* ENOENT can occur when either the path of the executable or any of
8043+
* the cwds given via file_actions doesn't exist. Since it's not
8044+
* possible to determine which of those paths caused the problem,
8045+
* we return an exception with all of those. */
8046+
8047+
if (cwd_size == 1) {
8048+
/* the common case */
8049+
PyObject *cwd = PyList_GET_ITEM(cwd_buffer, 0);
8050+
PyErr_Format(PyExc_FileNotFoundError, "Either '%S' or '%s' doesn't exist.",
80398051
path->object, PyBytes_AS_STRING(cwd));
8052+
} else {
8053+
/* TODO ..... */
8054+
PyObject *separator = PyBytes_FromString(", ");
8055+
if (!separator) {
8056+
goto exit;
8057+
}
8058+
8059+
PyObject *joined = PyObject_CallMethod(separator, "join", "O", cwd_buffer);
8060+
Py_DECREF(separator);
8061+
if (!joined) {
8062+
goto exit;
8063+
}
8064+
PyErr_Format(PyExc_FileNotFoundError,
8065+
"Either '%S' or one of (%s) doesn't exist.",
8066+
path->object, PyBytes_AS_STRING(joined));
8067+
8068+
Py_DECREF(joined);
8069+
}
80408070
goto exit;
80418071
}
80428072
#endif
@@ -8061,7 +8091,7 @@ py_posix_spawn(int use_posix_spawnp, PyObject *module, path_t *path, PyObject *a
80618091
if (argvlist) {
80628092
free_string_array(argvlist, argc);
80638093
}
8064-
Py_XDECREF(cwd);
8094+
Py_XDECREF(cwd_buffer);
80658095
Py_XDECREF(temp_buffer);
80668096
return result;
80678097
}

0 commit comments

Comments
 (0)