diff options
Diffstat (limited to 'Modules/posixmodule.c')
-rw-r--r-- | Modules/posixmodule.c | 25 |
1 files changed, 22 insertions, 3 deletions
diff --git a/Modules/posixmodule.c b/Modules/posixmodule.c index 24d8be6..51fc1c5 100644 --- a/Modules/posixmodule.c +++ b/Modules/posixmodule.c @@ -5179,7 +5179,8 @@ enum posix_spawn_file_actions_identifier { static int parse_file_actions(PyObject *file_actions, - posix_spawn_file_actions_t *file_actionsp) + posix_spawn_file_actions_t *file_actionsp, + PyObject *temp_buffer) { PyObject *seq; PyObject *file_action = NULL; @@ -5224,9 +5225,13 @@ parse_file_actions(PyObject *file_actions, { goto fail; } + if (PyList_Append(temp_buffer, path)) { + Py_DECREF(path); + goto fail; + } errno = posix_spawn_file_actions_addopen(file_actionsp, fd, PyBytes_AS_STRING(path), oflag, (mode_t)mode); - Py_DECREF(path); /* addopen copied it. */ + Py_DECREF(path); if (errno) { posix_error(); goto fail; @@ -5309,6 +5314,7 @@ os_posix_spawn_impl(PyObject *module, path_t *path, PyObject *argv, posix_spawn_file_actions_t *file_actionsp = NULL; Py_ssize_t argc, envc; PyObject *result = NULL; + PyObject *temp_buffer = NULL; pid_t pid; int err_code; @@ -5349,7 +5355,19 @@ os_posix_spawn_impl(PyObject *module, path_t *path, PyObject *argv, } if (file_actions != Py_None) { - if (parse_file_actions(file_actions, &file_actions_buf)) { + /* There is a bug in old versions of glibc that makes some of the + * helper functions for manipulating file actions not copy the provided + * buffers. The problem is that posix_spawn_file_actions_addopen does not + * copy the value of path for some old versions of glibc (<2.20). + * The use of temp_buffer here is a workaround that keeps the + * python objects that own the buffers alive until posix_spawn gets called. + * Check https://bugs.python.org/issue33630 and + * https://sourceware.org/bugzilla/show_bug.cgi?id=17048 for more info.*/ + temp_buffer = PyList_New(0); + if (!temp_buffer) { + goto exit; + } + if (parse_file_actions(file_actions, &file_actions_buf, temp_buffer)) { goto exit; } file_actionsp = &file_actions_buf; @@ -5376,6 +5394,7 @@ exit: if (argvlist) { free_string_array(argvlist, argc); } + Py_XDECREF(temp_buffer); return result; } #endif /* HAVE_POSIX_SPAWN */ |