17db96d56Sopenharmony_ci/*
27db96d56Sopenharmony_ciposixshmem - A Python extension that provides shm_open() and shm_unlink()
37db96d56Sopenharmony_ci*/
47db96d56Sopenharmony_ci
57db96d56Sopenharmony_ci#define PY_SSIZE_T_CLEAN
67db96d56Sopenharmony_ci
77db96d56Sopenharmony_ci#include <Python.h>
87db96d56Sopenharmony_ci
97db96d56Sopenharmony_ci// for shm_open() and shm_unlink()
107db96d56Sopenharmony_ci#ifdef HAVE_SYS_MMAN_H
117db96d56Sopenharmony_ci#include <sys/mman.h>
127db96d56Sopenharmony_ci#endif
137db96d56Sopenharmony_ci
147db96d56Sopenharmony_ci/*[clinic input]
157db96d56Sopenharmony_cimodule _posixshmem
167db96d56Sopenharmony_ci[clinic start generated code]*/
177db96d56Sopenharmony_ci/*[clinic end generated code: output=da39a3ee5e6b4b0d input=a416734e49164bf8]*/
187db96d56Sopenharmony_ci
197db96d56Sopenharmony_ci/*
207db96d56Sopenharmony_ci *
217db96d56Sopenharmony_ci * Module-level functions & meta stuff
227db96d56Sopenharmony_ci *
237db96d56Sopenharmony_ci */
247db96d56Sopenharmony_ci
257db96d56Sopenharmony_ci#ifdef HAVE_SHM_OPEN
267db96d56Sopenharmony_ci/*[clinic input]
277db96d56Sopenharmony_ci_posixshmem.shm_open -> int
287db96d56Sopenharmony_ci    path: unicode
297db96d56Sopenharmony_ci    flags: int
307db96d56Sopenharmony_ci    mode: int = 0o777
317db96d56Sopenharmony_ci
327db96d56Sopenharmony_ci# "shm_open(path, flags, mode=0o777)\n\n\
337db96d56Sopenharmony_ci
347db96d56Sopenharmony_ciOpen a shared memory object.  Returns a file descriptor (integer).
357db96d56Sopenharmony_ci
367db96d56Sopenharmony_ci[clinic start generated code]*/
377db96d56Sopenharmony_ci
387db96d56Sopenharmony_cistatic int
397db96d56Sopenharmony_ci_posixshmem_shm_open_impl(PyObject *module, PyObject *path, int flags,
407db96d56Sopenharmony_ci                          int mode)
417db96d56Sopenharmony_ci/*[clinic end generated code: output=8d110171a4fa20df input=e83b58fa802fac25]*/
427db96d56Sopenharmony_ci{
437db96d56Sopenharmony_ci    int fd;
447db96d56Sopenharmony_ci    int async_err = 0;
457db96d56Sopenharmony_ci    const char *name = PyUnicode_AsUTF8(path);
467db96d56Sopenharmony_ci    if (name == NULL) {
477db96d56Sopenharmony_ci        return -1;
487db96d56Sopenharmony_ci    }
497db96d56Sopenharmony_ci    do {
507db96d56Sopenharmony_ci        Py_BEGIN_ALLOW_THREADS
517db96d56Sopenharmony_ci        fd = shm_open(name, flags, mode);
527db96d56Sopenharmony_ci        Py_END_ALLOW_THREADS
537db96d56Sopenharmony_ci    } while (fd < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
547db96d56Sopenharmony_ci
557db96d56Sopenharmony_ci    if (fd < 0) {
567db96d56Sopenharmony_ci        if (!async_err)
577db96d56Sopenharmony_ci            PyErr_SetFromErrnoWithFilenameObject(PyExc_OSError, path);
587db96d56Sopenharmony_ci        return -1;
597db96d56Sopenharmony_ci    }
607db96d56Sopenharmony_ci
617db96d56Sopenharmony_ci    return fd;
627db96d56Sopenharmony_ci}
637db96d56Sopenharmony_ci#endif /* HAVE_SHM_OPEN */
647db96d56Sopenharmony_ci
657db96d56Sopenharmony_ci#ifdef HAVE_SHM_UNLINK
667db96d56Sopenharmony_ci/*[clinic input]
677db96d56Sopenharmony_ci_posixshmem.shm_unlink
687db96d56Sopenharmony_ci    path: unicode
697db96d56Sopenharmony_ci
707db96d56Sopenharmony_ciRemove a shared memory object (similar to unlink()).
717db96d56Sopenharmony_ci
727db96d56Sopenharmony_ciRemove a shared memory object name, and, once all processes  have  unmapped
737db96d56Sopenharmony_cithe object, de-allocates and destroys the contents of the associated memory
747db96d56Sopenharmony_ciregion.
757db96d56Sopenharmony_ci
767db96d56Sopenharmony_ci[clinic start generated code]*/
777db96d56Sopenharmony_ci
787db96d56Sopenharmony_cistatic PyObject *
797db96d56Sopenharmony_ci_posixshmem_shm_unlink_impl(PyObject *module, PyObject *path)
807db96d56Sopenharmony_ci/*[clinic end generated code: output=42f8b23d134b9ff5 input=8dc0f87143e3b300]*/
817db96d56Sopenharmony_ci{
827db96d56Sopenharmony_ci    int rv;
837db96d56Sopenharmony_ci    int async_err = 0;
847db96d56Sopenharmony_ci    const char *name = PyUnicode_AsUTF8(path);
857db96d56Sopenharmony_ci    if (name == NULL) {
867db96d56Sopenharmony_ci        return NULL;
877db96d56Sopenharmony_ci    }
887db96d56Sopenharmony_ci    do {
897db96d56Sopenharmony_ci        Py_BEGIN_ALLOW_THREADS
907db96d56Sopenharmony_ci        rv = shm_unlink(name);
917db96d56Sopenharmony_ci        Py_END_ALLOW_THREADS
927db96d56Sopenharmony_ci    } while (rv < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
937db96d56Sopenharmony_ci
947db96d56Sopenharmony_ci    if (rv < 0) {
957db96d56Sopenharmony_ci        if (!async_err)
967db96d56Sopenharmony_ci            PyErr_SetFromErrnoWithFilenameObject(PyExc_OSError, path);
977db96d56Sopenharmony_ci        return NULL;
987db96d56Sopenharmony_ci    }
997db96d56Sopenharmony_ci
1007db96d56Sopenharmony_ci    Py_RETURN_NONE;
1017db96d56Sopenharmony_ci}
1027db96d56Sopenharmony_ci#endif /* HAVE_SHM_UNLINK */
1037db96d56Sopenharmony_ci
1047db96d56Sopenharmony_ci#include "clinic/posixshmem.c.h"
1057db96d56Sopenharmony_ci
1067db96d56Sopenharmony_cistatic PyMethodDef module_methods[ ] = {
1077db96d56Sopenharmony_ci    _POSIXSHMEM_SHM_OPEN_METHODDEF
1087db96d56Sopenharmony_ci    _POSIXSHMEM_SHM_UNLINK_METHODDEF
1097db96d56Sopenharmony_ci    {NULL} /* Sentinel */
1107db96d56Sopenharmony_ci};
1117db96d56Sopenharmony_ci
1127db96d56Sopenharmony_ci
1137db96d56Sopenharmony_cistatic struct PyModuleDef _posixshmemmodule = {
1147db96d56Sopenharmony_ci    PyModuleDef_HEAD_INIT,
1157db96d56Sopenharmony_ci    .m_name = "_posixshmem",
1167db96d56Sopenharmony_ci    .m_doc = "POSIX shared memory module",
1177db96d56Sopenharmony_ci    .m_size = 0,
1187db96d56Sopenharmony_ci    .m_methods = module_methods,
1197db96d56Sopenharmony_ci};
1207db96d56Sopenharmony_ci
1217db96d56Sopenharmony_ci/* Module init function */
1227db96d56Sopenharmony_ciPyMODINIT_FUNC
1237db96d56Sopenharmony_ciPyInit__posixshmem(void)
1247db96d56Sopenharmony_ci{
1257db96d56Sopenharmony_ci    return PyModuleDef_Init(&_posixshmemmodule);
1267db96d56Sopenharmony_ci}
127