• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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