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