Staging
v0.5.1
https://github.com/python/cpython
Revision b90c68586e1f2c45c736dd38880f182be267e2ef authored by Miss Islington (bot) on 06 February 2018, 06:51:10 UTC, committed by Gregory P. Smith on 06 February 2018, 06:51:10 UTC
Fix a rare but potential pre-exec child process deadlock in subprocess on POSIX systems when marking file descriptors inheritable on exec in the child process.  This bug appears to have been introduced in 3.4 with the inheritable file descriptors support.

This also changes Python/fileutils.c `set_inheritable` to use the "slow" two `fcntl` syscall path instead of the "fast" single `ioctl` syscall path when asked to be async signal safe (by way of being asked not to raise exceptions).  `ioctl` is not a POSIX async-signal-safe approved function.

ref: http://pubs.opengroup.org/onlinepubs/9699919799/functions/V2_chap02.html
(cherry picked from commit c1e46e94de38a92f98736af9a42d89c3975a9919)

Co-authored-by: Alexey Izbyshev <izbyshev@users.noreply.github.com>
1 parent 7bd5a75
Raw File
Tip revision: b90c68586e1f2c45c736dd38880f182be267e2ef authored by Miss Islington (bot) on 06 February 2018, 06:51:10 UTC
bpo-32777: Fix _Py_set_inheritable async-safety in subprocess (GH-5560) (GH-5563)
Tip revision: b90c685
memoryobject.h
/* Memory view object. In Python this is available as "memoryview". */

#ifndef Py_MEMORYOBJECT_H
#define Py_MEMORYOBJECT_H
#ifdef __cplusplus
extern "C" {
#endif

#ifndef Py_LIMITED_API
PyAPI_DATA(PyTypeObject) _PyManagedBuffer_Type;
#endif
PyAPI_DATA(PyTypeObject) PyMemoryView_Type;

#define PyMemoryView_Check(op) (Py_TYPE(op) == &PyMemoryView_Type)

#ifndef Py_LIMITED_API
/* Get a pointer to the memoryview's private copy of the exporter's buffer. */
#define PyMemoryView_GET_BUFFER(op) (&((PyMemoryViewObject *)(op))->view)
/* Get a pointer to the exporting object (this may be NULL!). */
#define PyMemoryView_GET_BASE(op) (((PyMemoryViewObject *)(op))->view.obj)
#endif

PyAPI_FUNC(PyObject *) PyMemoryView_FromObject(PyObject *base);
#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 >= 0x03030000
PyAPI_FUNC(PyObject *) PyMemoryView_FromMemory(char *mem, Py_ssize_t size,
                                               int flags);
#endif
#ifndef Py_LIMITED_API
PyAPI_FUNC(PyObject *) PyMemoryView_FromBuffer(Py_buffer *info);
#endif
PyAPI_FUNC(PyObject *) PyMemoryView_GetContiguous(PyObject *base,
                                                  int buffertype,
                                                  char order);


/* The structs are declared here so that macros can work, but they shouldn't
   be considered public. Don't access their fields directly, use the macros
   and functions instead! */
#ifndef Py_LIMITED_API
#define _Py_MANAGED_BUFFER_RELEASED    0x001  /* access to exporter blocked */
#define _Py_MANAGED_BUFFER_FREE_FORMAT 0x002  /* free format */
typedef struct {
    PyObject_HEAD
    int flags;          /* state flags */
    Py_ssize_t exports; /* number of direct memoryview exports */
    Py_buffer master; /* snapshot buffer obtained from the original exporter */
} _PyManagedBufferObject;


/* memoryview state flags */
#define _Py_MEMORYVIEW_RELEASED    0x001  /* access to master buffer blocked */
#define _Py_MEMORYVIEW_C           0x002  /* C-contiguous layout */
#define _Py_MEMORYVIEW_FORTRAN     0x004  /* Fortran contiguous layout */
#define _Py_MEMORYVIEW_SCALAR      0x008  /* scalar: ndim = 0 */
#define _Py_MEMORYVIEW_PIL         0x010  /* PIL-style layout */

typedef struct {
    PyObject_VAR_HEAD
    _PyManagedBufferObject *mbuf; /* managed buffer */
    Py_hash_t hash;               /* hash value for read-only views */
    int flags;                    /* state flags */
    Py_ssize_t exports;           /* number of buffer re-exports */
    Py_buffer view;               /* private copy of the exporter's view */
    PyObject *weakreflist;
    Py_ssize_t ob_array[1];       /* shape, strides, suboffsets */
} PyMemoryViewObject;
#endif

#ifdef __cplusplus
}
#endif
#endif /* !Py_MEMORYOBJECT_H */
back to top