• 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 #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