@@ -5179,7 +5179,8 @@ enum posix_spawn_file_actions_identifier {
5179
5179
5180
5180
static int
5181
5181
parse_file_actions (PyObject * file_actions ,
5182
- posix_spawn_file_actions_t * file_actionsp )
5182
+ posix_spawn_file_actions_t * file_actionsp ,
5183
+ PyObject * temp_buffer )
5183
5184
{
5184
5185
PyObject * seq ;
5185
5186
PyObject * file_action = NULL ;
@@ -5224,9 +5225,13 @@ parse_file_actions(PyObject *file_actions,
5224
5225
{
5225
5226
goto fail ;
5226
5227
}
5228
+ if (PyList_Append (temp_buffer , path )) {
5229
+ Py_DECREF (path );
5230
+ goto fail ;
5231
+ }
5227
5232
errno = posix_spawn_file_actions_addopen (file_actionsp ,
5228
5233
fd , PyBytes_AS_STRING (path ), oflag , (mode_t )mode );
5229
- Py_DECREF (path ); /* addopen copied it. */
5234
+ Py_DECREF (path );
5230
5235
if (errno ) {
5231
5236
posix_error ();
5232
5237
goto fail ;
@@ -5309,6 +5314,7 @@ os_posix_spawn_impl(PyObject *module, path_t *path, PyObject *argv,
5309
5314
posix_spawn_file_actions_t * file_actionsp = NULL ;
5310
5315
Py_ssize_t argc , envc ;
5311
5316
PyObject * result = NULL ;
5317
+ PyObject * temp_buffer = NULL ;
5312
5318
pid_t pid ;
5313
5319
int err_code ;
5314
5320
@@ -5349,7 +5355,19 @@ os_posix_spawn_impl(PyObject *module, path_t *path, PyObject *argv,
5349
5355
}
5350
5356
5351
5357
if (file_actions != Py_None ) {
5352
- if (parse_file_actions (file_actions , & file_actions_buf )) {
5358
+ /* There is a bug in old versions of glibc that makes some of the
5359
+ * helper functions for manipulating file actions not copy the provided
5360
+ * buffers. The problem is that posix_spawn_file_actions_addopen does not
5361
+ * copy the value of path for some old versions of glibc (<2.20).
5362
+ * The use of temp_buffer here is a workaround that keeps the
5363
+ * python objects that own the buffers alive until posix_spawn gets called.
5364
+ * Check https://bugs.python.org/issue33630 and
5365
+ * https://sourceware.org/bugzilla/show_bug.cgi?id=17048 for more info.*/
5366
+ temp_buffer = PyList_New (0 );
5367
+ if (!temp_buffer ) {
5368
+ goto exit ;
5369
+ }
5370
+ if (parse_file_actions (file_actions , & file_actions_buf , temp_buffer )) {
5353
5371
goto exit ;
5354
5372
}
5355
5373
file_actionsp = & file_actions_buf ;
@@ -5376,6 +5394,7 @@ os_posix_spawn_impl(PyObject *module, path_t *path, PyObject *argv,
5376
5394
if (argvlist ) {
5377
5395
free_string_array (argvlist , argc );
5378
5396
}
5397
+ Py_XDECREF (temp_buffer );
5379
5398
return result ;
5380
5399
}
5381
5400
#endif /* HAVE_POSIX_SPAWN */
0 commit comments