1 /*
2 posixshmem - 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]
15 module _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
34 Open a shared memory object. Returns a file descriptor (integer).
35
36 [clinic start generated code]*/
37
38 static int
_posixshmem_shm_open_impl(PyObject * module,PyObject * path,int flags,int mode)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
70 Remove a shared memory object (similar to unlink()).
71
72 Remove a shared memory object name, and, once all processes have unmapped
73 the object, de-allocates and destroys the contents of the associated memory
74 region.
75
76 [clinic start generated code]*/
77
78 static PyObject *
_posixshmem_shm_unlink_impl(PyObject * module,PyObject * path)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
106 static PyMethodDef module_methods[ ] = {
107 _POSIXSHMEM_SHM_OPEN_METHODDEF
108 _POSIXSHMEM_SHM_UNLINK_METHODDEF
109 {NULL} /* Sentinel */
110 };
111
112
113 static struct PyModuleDef this_module = {
114 PyModuleDef_HEAD_INIT, // m_base
115 "_posixshmem", // m_name
116 "POSIX shared memory module", // m_doc
117 -1, // m_size (space allocated for module globals)
118 module_methods, // m_methods
119 };
120
121 /* Module init function */
122 PyMODINIT_FUNC
PyInit__posixshmem(void)123 PyInit__posixshmem(void) {
124 PyObject *module;
125 module = PyModule_Create(&this_module);
126 if (!module) {
127 return NULL;
128 }
129 return module;
130 }
131