summaryrefslogtreecommitdiff
path: root/Modules
diff options
context:
space:
mode:
authorZackery Spytz <zspytz@gmail.com>2019-05-29 13:57:07 -0600
committerChristian Heimes <christian@python.org>2019-05-29 21:57:03 +0200
commit43fdbd2729cb7cdbb5afb5d16352f6604859e564 (patch)
tree88cddedd14a456ffef515fa70718b1cb5ec33b31 /Modules
parent0c2f9305640f7655ba0cd5f478948b2763b376b3 (diff)
downloadcpython-git-43fdbd2729cb7cdbb5afb5d16352f6604859e564.tar.gz
bpo-26836: Add os.memfd_create() (#13567)
* bpo-26836: Add os.memfd_create() * Use the glibc wrapper for memfd_create() Co-Authored-By: Christian Heimes <christian@python.org> * Fix deletions caused by autoreconf. * Use MFD_CLOEXEC as the default value for *flags*. * Add memset_s to configure.ac. * Revert memset_s changes. * Apply the requested changes. * Tweak the docs.
Diffstat (limited to 'Modules')
-rw-r--r--Modules/clinic/posixmodule.c.h61
-rw-r--r--Modules/posixmodule.c64
2 files changed, 124 insertions, 1 deletions
diff --git a/Modules/clinic/posixmodule.c.h b/Modules/clinic/posixmodule.c.h
index f2745591b2..13f25460b4 100644
--- a/Modules/clinic/posixmodule.c.h
+++ b/Modules/clinic/posixmodule.c.h
@@ -7343,6 +7343,61 @@ exit:
return return_value;
}
+#if defined(HAVE_MEMFD_CREATE)
+
+PyDoc_STRVAR(os_memfd_create__doc__,
+"memfd_create($module, /, name, flags=MFD_CLOEXEC)\n"
+"--\n"
+"\n");
+
+#define OS_MEMFD_CREATE_METHODDEF \
+ {"memfd_create", (PyCFunction)(void(*)(void))os_memfd_create, METH_FASTCALL|METH_KEYWORDS, os_memfd_create__doc__},
+
+static PyObject *
+os_memfd_create_impl(PyObject *module, PyObject *name, unsigned int flags);
+
+static PyObject *
+os_memfd_create(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames)
+{
+ PyObject *return_value = NULL;
+ static const char * const _keywords[] = {"name", "flags", NULL};
+ static _PyArg_Parser _parser = {NULL, _keywords, "memfd_create", 0};
+ PyObject *argsbuf[2];
+ Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1;
+ PyObject *name = NULL;
+ unsigned int flags = MFD_CLOEXEC;
+
+ args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 2, 0, argsbuf);
+ if (!args) {
+ goto exit;
+ }
+ if (!PyUnicode_FSConverter(args[0], &name)) {
+ goto exit;
+ }
+ if (!noptargs) {
+ goto skip_optional_pos;
+ }
+ if (PyFloat_Check(args[1])) {
+ PyErr_SetString(PyExc_TypeError,
+ "integer argument expected, got float" );
+ goto exit;
+ }
+ flags = (unsigned int)PyLong_AsUnsignedLongMask(args[1]);
+ if (flags == (unsigned int)-1 && PyErr_Occurred()) {
+ goto exit;
+ }
+skip_optional_pos:
+ return_value = os_memfd_create_impl(module, name, flags);
+
+exit:
+ /* Cleanup for name */
+ Py_XDECREF(name);
+
+ return return_value;
+}
+
+#endif /* defined(HAVE_MEMFD_CREATE) */
+
PyDoc_STRVAR(os_cpu_count__doc__,
"cpu_count($module, /)\n"
"--\n"
@@ -8549,6 +8604,10 @@ exit:
#define OS_LISTXATTR_METHODDEF
#endif /* !defined(OS_LISTXATTR_METHODDEF) */
+#ifndef OS_MEMFD_CREATE_METHODDEF
+ #define OS_MEMFD_CREATE_METHODDEF
+#endif /* !defined(OS_MEMFD_CREATE_METHODDEF) */
+
#ifndef OS_GET_HANDLE_INHERITABLE_METHODDEF
#define OS_GET_HANDLE_INHERITABLE_METHODDEF
#endif /* !defined(OS_GET_HANDLE_INHERITABLE_METHODDEF) */
@@ -8576,4 +8635,4 @@ exit:
#ifndef OS__REMOVE_DLL_DIRECTORY_METHODDEF
#define OS__REMOVE_DLL_DIRECTORY_METHODDEF
#endif /* !defined(OS__REMOVE_DLL_DIRECTORY_METHODDEF) */
-/*[clinic end generated code: output=5ee9420fb2e7aa2c input=a9049054013a1b77]*/
+/*[clinic end generated code: output=855b81aafd05beed input=a9049054013a1b77]*/
diff --git a/Modules/posixmodule.c b/Modules/posixmodule.c
index cd5b5ce082..a3d979c3bc 100644
--- a/Modules/posixmodule.c
+++ b/Modules/posixmodule.c
@@ -389,6 +389,19 @@ extern char *ctermid_r(char *);
#define HAVE_STRUCT_STAT_ST_FSTYPE 1
#endif
+/* memfd_create is either defined in sys/mman.h or sys/memfd.h
+ * linux/memfd.h defines additional flags
+ */
+#ifdef HAVE_SYS_MMAN_H
+#include <sys/mman.h>
+#endif
+#ifdef HAVE_SYS_MEMFD_H
+#include <sys/memfd.h>
+#endif
+#ifdef HAVE_LINUX_MEMFD_H
+#include <linux/memfd.h>
+#endif
+
#ifdef _Py_MEMORY_SANITIZER
# include <sanitizer/msan_interface.h>
#endif
@@ -11897,6 +11910,31 @@ os_urandom_impl(PyObject *module, Py_ssize_t size)
return bytes;
}
+#ifdef HAVE_MEMFD_CREATE
+/*[clinic input]
+os.memfd_create
+
+ name: FSConverter
+ flags: unsigned_int(bitwise=True, c_default="MFD_CLOEXEC") = MFD_CLOEXEC
+
+[clinic start generated code]*/
+
+static PyObject *
+os_memfd_create_impl(PyObject *module, PyObject *name, unsigned int flags)
+/*[clinic end generated code: output=6681ede983bdb9a6 input=a42cfc199bcd56e9]*/
+{
+ int fd;
+ const char *bytes = PyBytes_AS_STRING(name);
+ Py_BEGIN_ALLOW_THREADS
+ fd = memfd_create(bytes, flags);
+ Py_END_ALLOW_THREADS
+ if (fd == -1) {
+ return PyErr_SetFromErrno(PyExc_OSError);
+ }
+ return PyLong_FromLong(fd);
+}
+#endif
+
/* Terminal size querying */
static PyTypeObject* TerminalSizeType;
@@ -13554,6 +13592,7 @@ static PyMethodDef posix_methods[] = {
OS_SCANDIR_METHODDEF
OS_FSPATH_METHODDEF
OS_GETRANDOM_METHODDEF
+ OS_MEMFD_CREATE_METHODDEF
#ifdef MS_WINDOWS
OS__ADD_DLL_DIRECTORY_METHODDEF
OS__REMOVE_DLL_DIRECTORY_METHODDEF
@@ -14003,6 +14042,27 @@ all_ins(PyObject *m)
if (PyModule_AddIntMacro(m, GRND_RANDOM)) return -1;
if (PyModule_AddIntMacro(m, GRND_NONBLOCK)) return -1;
#endif
+#ifdef HAVE_MEMFD_CREATE
+ if (PyModule_AddIntMacro(m, MFD_CLOEXEC)) return -1;
+ if (PyModule_AddIntMacro(m, MFD_ALLOW_SEALING)) return -1;
+#ifdef MFD_HUGETLB
+ if (PyModule_AddIntMacro(m, MFD_HUGETLB)) return -1;
+ if (PyModule_AddIntMacro(m, MFD_HUGE_SHIFT)) return -1;
+ if (PyModule_AddIntMacro(m, MFD_HUGE_MASK)) return -1;
+ if (PyModule_AddIntMacro(m, MFD_HUGE_64KB)) return -1;
+ if (PyModule_AddIntMacro(m, MFD_HUGE_512KB)) return -1;
+ if (PyModule_AddIntMacro(m, MFD_HUGE_1MB)) return -1;
+ if (PyModule_AddIntMacro(m, MFD_HUGE_2MB)) return -1;
+ if (PyModule_AddIntMacro(m, MFD_HUGE_8MB)) return -1;
+ if (PyModule_AddIntMacro(m, MFD_HUGE_16MB)) return -1;
+ if (PyModule_AddIntMacro(m, MFD_HUGE_32MB)) return -1;
+ if (PyModule_AddIntMacro(m, MFD_HUGE_256MB)) return -1;
+ if (PyModule_AddIntMacro(m, MFD_HUGE_512MB)) return -1;
+ if (PyModule_AddIntMacro(m, MFD_HUGE_1GB)) return -1;
+ if (PyModule_AddIntMacro(m, MFD_HUGE_2GB)) return -1;
+ if (PyModule_AddIntMacro(m, MFD_HUGE_16GB)) return -1;
+#endif
+#endif
#if defined(__APPLE__)
if (PyModule_AddIntConstant(m, "_COPYFILE_DATA", COPYFILE_DATA)) return -1;
@@ -14119,6 +14179,10 @@ static const char * const have_functions[] = {
"HAVE_LUTIMES",
#endif
+#ifdef HAVE_MEMFD_CREATE
+ "HAVE_MEMFD_CREATE",
+#endif
+
#ifdef HAVE_MKDIRAT
"HAVE_MKDIRAT",
#endif