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