1/*
2posixshmem - A Python extension that provides shm_open() and shm_unlink()
3*/
4
5#define PY_SSIZE_T_CLEAN
6
7#include <Python.h>
8
9// for shm_open() and shm_unlink()
10#ifdef HAVE_SYS_MMAN_H
11#include <sys/mman.h>
12#endif
13
14/*[clinic input]
15module _posixshmem
16[clinic start generated code]*/
17/*[clinic end generated code: output=da39a3ee5e6b4b0d input=a416734e49164bf8]*/
18
19/*
20 *
21 * Module-level functions & meta stuff
22 *
23 */
24
25#ifdef HAVE_SHM_OPEN
26/*[clinic input]
27_posixshmem.shm_open -> int
28    path: unicode
29    flags: int
30    mode: int = 0o777
31
32# "shm_open(path, flags, mode=0o777)\n\n\
33
34Open a shared memory object.  Returns a file descriptor (integer).
35
36[clinic start generated code]*/
37
38static int
39_posixshmem_shm_open_impl(PyObject *module, PyObject *path, int flags,
40                          int mode)
41/*[clinic end generated code: output=8d110171a4fa20df input=e83b58fa802fac25]*/
42{
43    int fd;
44    int async_err = 0;
45    const char *name = PyUnicode_AsUTF8(path);
46    if (name == NULL) {
47        return -1;
48    }
49    do {
50        Py_BEGIN_ALLOW_THREADS
51        fd = shm_open(name, flags, mode);
52        Py_END_ALLOW_THREADS
53    } while (fd < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
54
55    if (fd < 0) {
56        if (!async_err)
57            PyErr_SetFromErrnoWithFilenameObject(PyExc_OSError, path);
58        return -1;
59    }
60
61    return fd;
62}
63#endif /* HAVE_SHM_OPEN */
64
65#ifdef HAVE_SHM_UNLINK
66/*[clinic input]
67_posixshmem.shm_unlink
68    path: unicode
69
70Remove a shared memory object (similar to unlink()).
71
72Remove a shared memory object name, and, once all processes  have  unmapped
73the object, de-allocates and destroys the contents of the associated memory
74region.
75
76[clinic start generated code]*/
77
78static PyObject *
79_posixshmem_shm_unlink_impl(PyObject *module, PyObject *path)
80/*[clinic end generated code: output=42f8b23d134b9ff5 input=8dc0f87143e3b300]*/
81{
82    int rv;
83    int async_err = 0;
84    const char *name = PyUnicode_AsUTF8(path);
85    if (name == NULL) {
86        return NULL;
87    }
88    do {
89        Py_BEGIN_ALLOW_THREADS
90        rv = shm_unlink(name);
91        Py_END_ALLOW_THREADS
92    } while (rv < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
93
94    if (rv < 0) {
95        if (!async_err)
96            PyErr_SetFromErrnoWithFilenameObject(PyExc_OSError, path);
97        return NULL;
98    }
99
100    Py_RETURN_NONE;
101}
102#endif /* HAVE_SHM_UNLINK */
103
104#include "clinic/posixshmem.c.h"
105
106static PyMethodDef module_methods[ ] = {
107    _POSIXSHMEM_SHM_OPEN_METHODDEF
108    _POSIXSHMEM_SHM_UNLINK_METHODDEF
109    {NULL} /* Sentinel */
110};
111
112
113static struct PyModuleDef _posixshmemmodule = {
114    PyModuleDef_HEAD_INIT,
115    .m_name = "_posixshmem",
116    .m_doc = "POSIX shared memory module",
117    .m_size = 0,
118    .m_methods = module_methods,
119};
120
121/* Module init function */
122PyMODINIT_FUNC
123PyInit__posixshmem(void)
124{
125    return PyModuleDef_Init(&_posixshmemmodule);
126}
127