From 00ce42b82f31ea0ec9246d4941fcce3e582c7228 Mon Sep 17 00:00:00 2001 From: Zackery Spytz Date: Sat, 25 May 2019 08:18:31 -0600 Subject: [PATCH 1/8] bpo-26836: Add os.memfd_create() --- Doc/library/os.rst | 15 ++++++ Doc/whatsnew/3.8.rst | 4 ++ Lib/test/test_os.py | 12 +++++ .../2019-05-25-08-18-01.bpo-26836.rplYWW.rst | 1 + Modules/clinic/posixmodule.c.h | 52 ++++++++++++++++++- Modules/posixmodule.c | 35 +++++++++++++ configure | 47 ++++++++++++++++- configure.ac | 21 ++++++++ pyconfig.h.in | 3 ++ 9 files changed, 188 insertions(+), 2 deletions(-) create mode 100644 Misc/NEWS.d/next/Core and Builtins/2019-05-25-08-18-01.bpo-26836.rplYWW.rst diff --git a/Doc/library/os.rst b/Doc/library/os.rst index 6df2b49c5325e6..fb72bd19ab06e2 100644 --- a/Doc/library/os.rst +++ b/Doc/library/os.rst @@ -2982,6 +2982,21 @@ features: Added support for :class:`bytes` paths. +.. function:: memfd_create(name, flags) + + Create an anonymous file and return a file descriptor that refers to it. + *flags* must be one of the ``os.MFD_*`` constants available on the system + (or a bitwise ORed combination of them). + + .. availability:: Linux 3.17 and newer. + + .. versionadded:: 3.8 + + +.. data:: MFD_CLOEXEC +.. data:: MFD_ALLOW_SEALING + + Linux extended attributes ~~~~~~~~~~~~~~~~~~~~~~~~~ diff --git a/Doc/whatsnew/3.8.rst b/Doc/whatsnew/3.8.rst index a94aba6b2c987f..889a6bed513174 100644 --- a/Doc/whatsnew/3.8.rst +++ b/Doc/whatsnew/3.8.rst @@ -395,6 +395,10 @@ Added new function :func:`~os.add_dll_directory` on Windows for providing additional search paths for native dependencies when importing extension modules or loading DLLs using :mod:`ctypes`. +A new :func:`os.memfd_create` function was added to wrap the +``memfd_create()`` syscall. +(Contributed by Zackery Spytz in :issue:`26836`.) + os.path ------- diff --git a/Lib/test/test_os.py b/Lib/test/test_os.py index 353b9a50a2b7fb..dd477e20858c03 100644 --- a/Lib/test/test_os.py +++ b/Lib/test/test_os.py @@ -3122,6 +3122,18 @@ def test_stty_match(self): self.assertEqual(expected, actual) +@unittest.skipUnless(sysconfig.get_config_var( + 'HAVE_MEMFD_CREATE_SYSCALL') == 1, + 'requires os.memfd_create') +class MemfdCreateTests(unittest.TestCase): + def test_memfd_create(self): + fd = os.memfd_create("Hi", os.MFD_CLOEXEC) + self.assertNotEqual(fd, -1) + with open(fd, "wb") as f: + f.write(b'memfd_create') + self.assertEqual(f.tell(), 12) + + class OSErrorTests(unittest.TestCase): def setUp(self): class Str(str): diff --git a/Misc/NEWS.d/next/Core and Builtins/2019-05-25-08-18-01.bpo-26836.rplYWW.rst b/Misc/NEWS.d/next/Core and Builtins/2019-05-25-08-18-01.bpo-26836.rplYWW.rst new file mode 100644 index 00000000000000..bbf63ec82ca6cd --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2019-05-25-08-18-01.bpo-26836.rplYWW.rst @@ -0,0 +1 @@ +Add :func:`os.memfd_create`. diff --git a/Modules/clinic/posixmodule.c.h b/Modules/clinic/posixmodule.c.h index f2745591b2353d..30e14ab095cf6b 100644 --- a/Modules/clinic/posixmodule.c.h +++ b/Modules/clinic/posixmodule.c.h @@ -7343,6 +7343,52 @@ os_urandom(PyObject *module, PyObject *arg) return return_value; } +#if defined(HAVE_MEMFD_CREATE_SYSCALL) + +PyDoc_STRVAR(os_memfd_create__doc__, +"memfd_create($module, name, flags, /)\n" +"--\n" +"\n"); + +#define OS_MEMFD_CREATE_METHODDEF \ + {"memfd_create", (PyCFunction)(void(*)(void))os_memfd_create, METH_FASTCALL, 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 *return_value = NULL; + PyObject *name = NULL; + unsigned int flags; + + if (!_PyArg_CheckPositional("memfd_create", nargs, 2, 2)) { + goto exit; + } + if (!PyUnicode_FSConverter(args[0], &name)) { + goto exit; + } + 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; + } + return_value = os_memfd_create_impl(module, name, flags); + +exit: + /* Cleanup for name */ + Py_XDECREF(name); + + return return_value; +} + +#endif /* defined(HAVE_MEMFD_CREATE_SYSCALL) */ + PyDoc_STRVAR(os_cpu_count__doc__, "cpu_count($module, /)\n" "--\n" @@ -8549,6 +8595,10 @@ os__remove_dll_directory(PyObject *module, PyObject *const *args, Py_ssize_t nar #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 +8626,4 @@ os__remove_dll_directory(PyObject *module, PyObject *const *args, Py_ssize_t nar #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=e6a5172c69f2c30a input=a9049054013a1b77]*/ diff --git a/Modules/posixmodule.c b/Modules/posixmodule.c index cd5b5ce082ece4..14cd5e906efd16 100644 --- a/Modules/posixmodule.c +++ b/Modules/posixmodule.c @@ -376,6 +376,10 @@ extern char *ctermid_r(char *); #endif #endif +#ifdef HAVE_MEMFD_CREATE_SYSCALL +#include +#endif + #ifdef MS_WINDOWS #define INITFUNC PyInit_nt #define MODNAME "nt" @@ -11897,6 +11901,29 @@ os_urandom_impl(PyObject *module, Py_ssize_t size) return bytes; } +#ifdef HAVE_MEMFD_CREATE_SYSCALL +/*[clinic input] +os.memfd_create + + name: FSConverter + flags: unsigned_int(bitwise=True) + / + +[clinic start generated code]*/ + +static PyObject * +os_memfd_create_impl(PyObject *module, PyObject *name, unsigned int flags) +/*[clinic end generated code: output=6681ede983bdb9a6 input=5659b8bdae914e4f]*/ +{ + int fd; + if ((fd = syscall(__NR_memfd_create, PyBytes_AS_STRING(name), + flags)) == -1) { + return PyErr_SetFromErrno(PyExc_OSError); + } + return PyLong_FromLong(fd); +} +#endif + /* Terminal size querying */ static PyTypeObject* TerminalSizeType; @@ -13554,6 +13581,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 +14031,13 @@ 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_SYSCALL + 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; +#endif +#endif #if defined(__APPLE__) if (PyModule_AddIntConstant(m, "_COPYFILE_DATA", COPYFILE_DATA)) return -1; diff --git a/configure b/configure index bc276ac58362bf..a3109e4cde01fe 100755 --- a/configure +++ b/configure @@ -785,6 +785,7 @@ infodir docdir oldincludedir includedir +runstatedir localstatedir sharedstatedir sysconfdir @@ -897,6 +898,7 @@ datadir='${datarootdir}' sysconfdir='${prefix}/etc' sharedstatedir='${prefix}/com' localstatedir='${prefix}/var' +runstatedir='${localstatedir}/run' includedir='${prefix}/include' oldincludedir='/usr/include' docdir='${datarootdir}/doc/${PACKAGE_TARNAME}' @@ -1149,6 +1151,15 @@ do | -silent | --silent | --silen | --sile | --sil) silent=yes ;; + -runstatedir | --runstatedir | --runstatedi | --runstated \ + | --runstate | --runstat | --runsta | --runst | --runs \ + | --run | --ru | --r) + ac_prev=runstatedir ;; + -runstatedir=* | --runstatedir=* | --runstatedi=* | --runstated=* \ + | --runstate=* | --runstat=* | --runsta=* | --runst=* | --runs=* \ + | --run=* | --ru=* | --r=*) + runstatedir=$ac_optarg ;; + -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb) ac_prev=sbindir ;; -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \ @@ -1286,7 +1297,7 @@ fi for ac_var in exec_prefix prefix bindir sbindir libexecdir datarootdir \ datadir sysconfdir sharedstatedir localstatedir includedir \ oldincludedir docdir infodir htmldir dvidir pdfdir psdir \ - libdir localedir mandir + libdir localedir mandir runstatedir do eval ac_val=\$$ac_var # Remove trailing slashes. @@ -1439,6 +1450,7 @@ Fine tuning of the installation directories: --sysconfdir=DIR read-only single-machine data [PREFIX/etc] --sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com] --localstatedir=DIR modifiable single-machine data [PREFIX/var] + --runstatedir=DIR modifiable per-process data [LOCALSTATEDIR/run] --libdir=DIR object code libraries [EPREFIX/lib] --includedir=DIR C header files [PREFIX/include] --oldincludedir=DIR C header files for non-gcc [/usr/include] @@ -16913,6 +16925,39 @@ $as_echo "#define HAVE_GETRANDOM 1" >>confdefs.h fi +# check if the memfd_create() function is available +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for the memfd_create() function" >&5 +$as_echo_n "checking for the memfd_create() function... " >&6; } +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + + + #include + #include + + int main() { + (void)syscall(__NR_memfd_create, "", 0); + return 0; + } + + +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + have_memfd_create=yes +else + have_memfd_create=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $have_memfd_create" >&5 +$as_echo "$have_memfd_create" >&6; } + +if test "$have_memfd_create" = yes; then + +$as_echo "#define HAVE_MEMFD_CREATE_SYSCALL 1" >>confdefs.h + +fi + # checks for POSIX shared memory, used by Modules/_multiprocessing/posixshmem.c # shm_* may only be available if linking against librt save_LIBS="$LIBS" diff --git a/configure.ac b/configure.ac index 5e565191f27de1..916db2241d2eb2 100644 --- a/configure.ac +++ b/configure.ac @@ -5487,6 +5487,27 @@ if test "$have_getrandom" = yes; then [Define to 1 if the getrandom() function is available]) fi +# check if the memfd_create() function is available +AC_MSG_CHECKING(for the memfd_create() function) +AC_LINK_IFELSE( +[ + AC_LANG_SOURCE([[ + #include + #include + + int main() { + (void)syscall(__NR_memfd_create, "", 0); + return 0; + } + ]]) +],[have_memfd_create=yes],[have_memfd_create=no]) +AC_MSG_RESULT($have_memfd_create) + +if test "$have_memfd_create" = yes; then + AC_DEFINE(HAVE_MEMFD_CREATE_SYSCALL, 1, + [Define to 1 if the memfd_create() function is available]) +fi + # checks for POSIX shared memory, used by Modules/_multiprocessing/posixshmem.c # shm_* may only be available if linking against librt save_LIBS="$LIBS" diff --git a/pyconfig.h.in b/pyconfig.h.in index dd5f2e393be094..c4260884be055a 100644 --- a/pyconfig.h.in +++ b/pyconfig.h.in @@ -664,6 +664,9 @@ /* Define to 1 if you have the `mbrtowc' function. */ #undef HAVE_MBRTOWC +/* Define to 1 if the memfd_create() function is available */ +#undef HAVE_MEMFD_CREATE_SYSCALL + /* Define to 1 if you have the header file. */ #undef HAVE_MEMORY_H From e25baa5597489e044f19b1c021a67f4d71043dd5 Mon Sep 17 00:00:00 2001 From: Zackery Spytz Date: Mon, 27 May 2019 09:29:53 -0600 Subject: [PATCH 2/8] Use the glibc wrapper for memfd_create() Co-Authored-By: Christian Heimes --- Doc/whatsnew/3.8.rst | 2 +- Lib/test/test_os.py | 4 +- Modules/clinic/posixmodule.c.h | 6 +-- Modules/posixmodule.c | 46 ++++++++++++++++++---- aclocal.m4 | 10 ++--- configure | 70 +++++++++++++++++----------------- configure.ac | 37 ++++++++---------- pyconfig.h.in | 52 ++++--------------------- 8 files changed, 105 insertions(+), 122 deletions(-) diff --git a/Doc/whatsnew/3.8.rst b/Doc/whatsnew/3.8.rst index 889a6bed513174..3ae096250cfb5a 100644 --- a/Doc/whatsnew/3.8.rst +++ b/Doc/whatsnew/3.8.rst @@ -397,7 +397,7 @@ modules or loading DLLs using :mod:`ctypes`. A new :func:`os.memfd_create` function was added to wrap the ``memfd_create()`` syscall. -(Contributed by Zackery Spytz in :issue:`26836`.) +(Contributed by Zackery Spytz and Christian Heimes in :issue:`26836`.) os.path diff --git a/Lib/test/test_os.py b/Lib/test/test_os.py index dd477e20858c03..98da9e5914f4b5 100644 --- a/Lib/test/test_os.py +++ b/Lib/test/test_os.py @@ -3122,9 +3122,7 @@ def test_stty_match(self): self.assertEqual(expected, actual) -@unittest.skipUnless(sysconfig.get_config_var( - 'HAVE_MEMFD_CREATE_SYSCALL') == 1, - 'requires os.memfd_create') +@unittest.skipUnless(hasattr(os, 'memfd_create'), 'requires os.memfd_create') class MemfdCreateTests(unittest.TestCase): def test_memfd_create(self): fd = os.memfd_create("Hi", os.MFD_CLOEXEC) diff --git a/Modules/clinic/posixmodule.c.h b/Modules/clinic/posixmodule.c.h index 30e14ab095cf6b..34c4c4ff9de2c7 100644 --- a/Modules/clinic/posixmodule.c.h +++ b/Modules/clinic/posixmodule.c.h @@ -7343,7 +7343,7 @@ os_urandom(PyObject *module, PyObject *arg) return return_value; } -#if defined(HAVE_MEMFD_CREATE_SYSCALL) +#if defined(HAVE_MEMFD_CREATE) PyDoc_STRVAR(os_memfd_create__doc__, "memfd_create($module, name, flags, /)\n" @@ -7387,7 +7387,7 @@ os_memfd_create(PyObject *module, PyObject *const *args, Py_ssize_t nargs) return return_value; } -#endif /* defined(HAVE_MEMFD_CREATE_SYSCALL) */ +#endif /* defined(HAVE_MEMFD_CREATE) */ PyDoc_STRVAR(os_cpu_count__doc__, "cpu_count($module, /)\n" @@ -8626,4 +8626,4 @@ os__remove_dll_directory(PyObject *module, PyObject *const *args, Py_ssize_t nar #ifndef OS__REMOVE_DLL_DIRECTORY_METHODDEF #define OS__REMOVE_DLL_DIRECTORY_METHODDEF #endif /* !defined(OS__REMOVE_DLL_DIRECTORY_METHODDEF) */ -/*[clinic end generated code: output=e6a5172c69f2c30a input=a9049054013a1b77]*/ +/*[clinic end generated code: output=7446453677391010 input=a9049054013a1b77]*/ diff --git a/Modules/posixmodule.c b/Modules/posixmodule.c index 14cd5e906efd16..78beb2a11f792c 100644 --- a/Modules/posixmodule.c +++ b/Modules/posixmodule.c @@ -376,10 +376,6 @@ extern char *ctermid_r(char *); #endif #endif -#ifdef HAVE_MEMFD_CREATE_SYSCALL -#include -#endif - #ifdef MS_WINDOWS #define INITFUNC PyInit_nt #define MODNAME "nt" @@ -393,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 +#endif +#ifdef HAVE_SYS_MEMFD_H +#include +#endif +#ifdef HAVE_LINUX_MEMFD_H +#include +#endif + #ifdef _Py_MEMORY_SANITIZER # include #endif @@ -11901,7 +11910,7 @@ os_urandom_impl(PyObject *module, Py_ssize_t size) return bytes; } -#ifdef HAVE_MEMFD_CREATE_SYSCALL +#ifdef HAVE_MEMFD_CREATE /*[clinic input] os.memfd_create @@ -11916,8 +11925,11 @@ os_memfd_create_impl(PyObject *module, PyObject *name, unsigned int flags) /*[clinic end generated code: output=6681ede983bdb9a6 input=5659b8bdae914e4f]*/ { int fd; - if ((fd = syscall(__NR_memfd_create, PyBytes_AS_STRING(name), - flags)) == -1) { + 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); @@ -14031,11 +14043,25 @@ 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_SYSCALL +#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 @@ -14154,6 +14180,10 @@ static const char * const have_functions[] = { "HAVE_LUTIMES", #endif +#ifdef HAVE_MEMFD_CREATE + "HAVE_MEMFD_CREATE", +#endif + #ifdef HAVE_MKDIRAT "HAVE_MKDIRAT", #endif diff --git a/aclocal.m4 b/aclocal.m4 index 038bd4e2cea25d..85f00dd5fac7f2 100644 --- a/aclocal.m4 +++ b/aclocal.m4 @@ -55,7 +55,7 @@ dnl dnl See the "Since" comment for each macro you use to see what version dnl of the macros you require. m4_defun([PKG_PREREQ], -[m4_define([PKG_MACROS_VERSION], [0.29.2]) +[m4_define([PKG_MACROS_VERSION], [0.29.1]) m4_if(m4_version_compare(PKG_MACROS_VERSION, [$1]), -1, [m4_fatal([pkg.m4 version $1 or higher is required but ]PKG_MACROS_VERSION[ found])]) ])dnl PKG_PREREQ @@ -156,7 +156,7 @@ AC_ARG_VAR([$1][_CFLAGS], [C compiler flags for $1, overriding pkg-config])dnl AC_ARG_VAR([$1][_LIBS], [linker flags for $1, overriding pkg-config])dnl pkg_failed=no -AC_MSG_CHECKING([for $2]) +AC_MSG_CHECKING([for $1]) _PKG_CONFIG([$1][_CFLAGS], [cflags], [$2]) _PKG_CONFIG([$1][_LIBS], [libs], [$2]) @@ -166,11 +166,11 @@ and $1[]_LIBS to avoid the need to call pkg-config. See the pkg-config man page for more details.]) if test $pkg_failed = yes; then - AC_MSG_RESULT([no]) + AC_MSG_RESULT([no]) _PKG_SHORT_ERRORS_SUPPORTED if test $_pkg_short_errors_supported = yes; then $1[]_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "$2" 2>&1` - else + else $1[]_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "$2" 2>&1` fi # Put the nasty error message in config.log where it belongs @@ -187,7 +187,7 @@ installed software in a non-standard prefix. _PKG_TEXT])[]dnl ]) elif test $pkg_failed = untried; then - AC_MSG_RESULT([no]) + AC_MSG_RESULT([no]) m4_default([$4], [AC_MSG_FAILURE( [The pkg-config script could not be found or is too old. Make sure it is in your PATH or set the PKG_CONFIG environment variable to the full diff --git a/configure b/configure index a3109e4cde01fe..6360bbe6512344 100755 --- a/configure +++ b/configure @@ -7904,7 +7904,7 @@ sys/stat.h sys/syscall.h sys/sys_domain.h sys/termio.h sys/time.h \ sys/times.h sys/types.h sys/uio.h sys/un.h sys/utsname.h sys/wait.h pty.h \ libutil.h sys/resource.h netpacket/packet.h sysexits.h bluetooth.h \ linux/tipc.h linux/random.h spawn.h util.h alloca.h endian.h \ -sys/endian.h sys/sysmacros.h +sys/endian.h sys/sysmacros.h linux/memfd.h sys/memfd.h sys/mman.h do : as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` ac_fn_c_check_header_mongrel "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default" @@ -11483,8 +11483,6 @@ for ac_func in alarm accept4 setitimer getitimer bind_textdomain_codeset chown \ getgrouplist getgroups getlogin getloadavg getpeername getpgid getpid \ getpriority getresuid getresgid getpwent getpwnam_r getpwuid_r getspnam getspent getsid getwd \ if_nameindex \ - initgroups kill killpg lchmod lchown lockf linkat lstat lutimes mmap \ - memrchr mbrtowc mkdirat mkfifo \ mkfifoat mknod mknodat mktime mremap nice openat pathconf pause pipe2 plock poll \ posix_fallocate posix_fadvise posix_spawn posix_spawnp pread preadv preadv2 \ pthread_condattr_setclock pthread_init pthread_kill putenv pwrite pwritev pwritev2 \ @@ -11797,6 +11795,39 @@ $as_echo "no" >&6; } fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for memfd_create" >&5 +$as_echo_n "checking for memfd_create... " >&6; } +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +#ifdef HAVE_SYS_MMAN_H +#include +#endif +#ifdef HAVE_SYS_MEMFD_H +#include +#endif + +int +main () +{ +void *x=memfd_create + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + +$as_echo "#define HAVE_MEMFD_CREATE 1" >>confdefs.h + + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + # On some systems (eg. FreeBSD 5), we would find a definition of the # functions ctermid_r, setgroups in the library, but no prototype # (e.g. because we use _XOPEN_SOURCE). See whether we can take their @@ -16925,39 +16956,6 @@ $as_echo "#define HAVE_GETRANDOM 1" >>confdefs.h fi -# check if the memfd_create() function is available -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for the memfd_create() function" >&5 -$as_echo_n "checking for the memfd_create() function... " >&6; } -cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - - - #include - #include - - int main() { - (void)syscall(__NR_memfd_create, "", 0); - return 0; - } - - -_ACEOF -if ac_fn_c_try_link "$LINENO"; then : - have_memfd_create=yes -else - have_memfd_create=no -fi -rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $have_memfd_create" >&5 -$as_echo "$have_memfd_create" >&6; } - -if test "$have_memfd_create" = yes; then - -$as_echo "#define HAVE_MEMFD_CREATE_SYSCALL 1" >>confdefs.h - -fi - # checks for POSIX shared memory, used by Modules/_multiprocessing/posixshmem.c # shm_* may only be available if linking against librt save_LIBS="$LIBS" diff --git a/configure.ac b/configure.ac index 916db2241d2eb2..6c6798a2b4ce49 100644 --- a/configure.ac +++ b/configure.ac @@ -2133,7 +2133,7 @@ sys/stat.h sys/syscall.h sys/sys_domain.h sys/termio.h sys/time.h \ sys/times.h sys/types.h sys/uio.h sys/un.h sys/utsname.h sys/wait.h pty.h \ libutil.h sys/resource.h netpacket/packet.h sysexits.h bluetooth.h \ linux/tipc.h linux/random.h spawn.h util.h alloca.h endian.h \ -sys/endian.h sys/sysmacros.h) +sys/endian.h sys/sysmacros.h linux/memfd.h sys/memfd.h sys/mman.h) AC_HEADER_DIRENT AC_HEADER_MAJOR @@ -3624,6 +3624,20 @@ AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ [AC_MSG_RESULT(no) ]) +AC_MSG_CHECKING(for memfd_create) +AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ +#ifdef HAVE_SYS_MMAN_H +#include +#endif +#ifdef HAVE_SYS_MEMFD_H +#include +#endif +]], [[void *x=memfd_create]])], + [AC_DEFINE(HAVE_MEMFD_CREATE, 1, Define if you have the 'memfd_create' function.) + AC_MSG_RESULT(yes)], + [AC_MSG_RESULT(no) +]) + # On some systems (eg. FreeBSD 5), we would find a definition of the # functions ctermid_r, setgroups in the library, but no prototype # (e.g. because we use _XOPEN_SOURCE). See whether we can take their @@ -5487,27 +5501,6 @@ if test "$have_getrandom" = yes; then [Define to 1 if the getrandom() function is available]) fi -# check if the memfd_create() function is available -AC_MSG_CHECKING(for the memfd_create() function) -AC_LINK_IFELSE( -[ - AC_LANG_SOURCE([[ - #include - #include - - int main() { - (void)syscall(__NR_memfd_create, "", 0); - return 0; - } - ]]) -],[have_memfd_create=yes],[have_memfd_create=no]) -AC_MSG_RESULT($have_memfd_create) - -if test "$have_memfd_create" = yes; then - AC_DEFINE(HAVE_MEMFD_CREATE_SYSCALL, 1, - [Define to 1 if the memfd_create() function is available]) -fi - # checks for POSIX shared memory, used by Modules/_multiprocessing/posixshmem.c # shm_* may only be available if linking against librt save_LIBS="$LIBS" diff --git a/pyconfig.h.in b/pyconfig.h.in index c4260884be055a..3798c50c1e31f0 100644 --- a/pyconfig.h.in +++ b/pyconfig.h.in @@ -541,9 +541,6 @@ /* Define if you have the 'inet_pton' function. */ #undef HAVE_INET_PTON -/* Define to 1 if you have the `initgroups' function. */ -#undef HAVE_INITGROUPS - /* Define to 1 if you have the header file. */ #undef HAVE_INTTYPES_H @@ -553,12 +550,6 @@ /* Define if gcc has the ipa-pure-const bug. */ #undef HAVE_IPA_PURE_CONST_BUG -/* Define to 1 if you have the `kill' function. */ -#undef HAVE_KILL - -/* Define to 1 if you have the `killpg' function. */ -#undef HAVE_KILLPG - /* Define if you have the 'kqueue' functions. */ #undef HAVE_KQUEUE @@ -577,9 +568,6 @@ /* Define to 1 if you have the `lchmod' function. */ #undef HAVE_LCHMOD -/* Define to 1 if you have the `lchown' function. */ -#undef HAVE_LCHOWN - /* Define to 1 if you have the `lgamma' function. */ #undef HAVE_LGAMMA @@ -610,9 +598,6 @@ /* Define if you have the 'link' function. */ #undef HAVE_LINK -/* Define to 1 if you have the `linkat' function. */ -#undef HAVE_LINKAT - /* Define to 1 if you have the header file. */ #undef HAVE_LINUX_CAN_BCM_H @@ -625,6 +610,9 @@ /* Define to 1 if you have the header file. */ #undef HAVE_LINUX_CAN_RAW_H +/* Define to 1 if you have the header file. */ +#undef HAVE_LINUX_MEMFD_H + /* Define to 1 if you have the header file. */ #undef HAVE_LINUX_NETLINK_H @@ -640,9 +628,6 @@ /* Define to 1 if you have the header file. */ #undef HAVE_LINUX_VM_SOCKETS_H -/* Define to 1 if you have the `lockf' function. */ -#undef HAVE_LOCKF - /* Define to 1 if you have the `log1p' function. */ #undef HAVE_LOG1P @@ -652,36 +637,15 @@ /* Define to 1 if the system has the type `long double'. */ #undef HAVE_LONG_DOUBLE -/* Define to 1 if you have the `lstat' function. */ -#undef HAVE_LSTAT - -/* Define to 1 if you have the `lutimes' function. */ -#undef HAVE_LUTIMES - /* Define this if you have the makedev macro. */ #undef HAVE_MAKEDEV -/* Define to 1 if you have the `mbrtowc' function. */ -#undef HAVE_MBRTOWC - -/* Define to 1 if the memfd_create() function is available */ -#undef HAVE_MEMFD_CREATE_SYSCALL +/* Define if you have the 'memfd_create' function. */ +#undef HAVE_MEMFD_CREATE /* Define to 1 if you have the header file. */ #undef HAVE_MEMORY_H -/* Define to 1 if you have the `memrchr' function. */ -#undef HAVE_MEMRCHR - -/* Define to 1 if you have the `memset_s' function. */ -#undef HAVE_MEMSET_S - -/* Define to 1 if you have the `mkdirat' function. */ -#undef HAVE_MKDIRAT - -/* Define to 1 if you have the `mkfifo' function. */ -#undef HAVE_MKFIFO - /* Define to 1 if you have the `mkfifoat' function. */ #undef HAVE_MKFIFOAT @@ -694,9 +658,6 @@ /* Define to 1 if you have the `mktime' function. */ #undef HAVE_MKTIME -/* Define to 1 if you have the `mmap' function. */ -#undef HAVE_MMAP - /* Define to 1 if you have the `mremap' function. */ #undef HAVE_MREMAP @@ -1119,6 +1080,9 @@ /* Define to 1 if you have the header file. */ #undef HAVE_SYS_LOCK_H +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_MEMFD_H + /* Define to 1 if you have the header file. */ #undef HAVE_SYS_MKDEV_H From 457b9cb22eb0b7e188a514b7b01b1e3accf1272c Mon Sep 17 00:00:00 2001 From: Zackery Spytz Date: Mon, 27 May 2019 10:18:22 -0600 Subject: [PATCH 3/8] Fix deletions caused by autoreconf. --- configure | 2 ++ configure.ac | 2 ++ pyconfig.h.in | 39 +++++++++++++++++++++++++++++++++++++++ 3 files changed, 43 insertions(+) diff --git a/configure b/configure index 6360bbe6512344..f01672b2d8677f 100755 --- a/configure +++ b/configure @@ -11483,6 +11483,8 @@ for ac_func in alarm accept4 setitimer getitimer bind_textdomain_codeset chown \ getgrouplist getgroups getlogin getloadavg getpeername getpgid getpid \ getpriority getresuid getresgid getpwent getpwnam_r getpwuid_r getspnam getspent getsid getwd \ if_nameindex \ + initgroups kill killpg lchmod lchown lockf linkat lstat lutimes mmap \ + memrchr mbrtowc mkdirat mkfifo \ mkfifoat mknod mknodat mktime mremap nice openat pathconf pause pipe2 plock poll \ posix_fallocate posix_fadvise posix_spawn posix_spawnp pread preadv preadv2 \ pthread_condattr_setclock pthread_init pthread_kill putenv pwrite pwritev pwritev2 \ diff --git a/configure.ac b/configure.ac index 6c6798a2b4ce49..54b675576c0c6f 100644 --- a/configure.ac +++ b/configure.ac @@ -3527,6 +3527,8 @@ AC_CHECK_FUNCS(alarm accept4 setitimer getitimer bind_textdomain_codeset chown \ getgrouplist getgroups getlogin getloadavg getpeername getpgid getpid \ getpriority getresuid getresgid getpwent getpwnam_r getpwuid_r getspnam getspent getsid getwd \ if_nameindex \ + initgroups kill killpg lchmod lchown lockf linkat lstat lutimes mmap \ + memrchr mbrtowc mkdirat mkfifo \ mkfifoat mknod mknodat mktime mremap nice openat pathconf pause pipe2 plock poll \ posix_fallocate posix_fadvise posix_spawn posix_spawnp pread preadv preadv2 \ pthread_condattr_setclock pthread_init pthread_kill putenv pwrite pwritev pwritev2 \ diff --git a/pyconfig.h.in b/pyconfig.h.in index 3798c50c1e31f0..5206d0effdc38e 100644 --- a/pyconfig.h.in +++ b/pyconfig.h.in @@ -541,6 +541,9 @@ /* Define if you have the 'inet_pton' function. */ #undef HAVE_INET_PTON +/* Define to 1 if you have the `initgroups' function. */ +#undef HAVE_INITGROUPS + /* Define to 1 if you have the header file. */ #undef HAVE_INTTYPES_H @@ -550,6 +553,12 @@ /* Define if gcc has the ipa-pure-const bug. */ #undef HAVE_IPA_PURE_CONST_BUG +/* Define to 1 if you have the `kill' function. */ +#undef HAVE_KILL + +/* Define to 1 if you have the `killpg' function. */ +#undef HAVE_KILLPG + /* Define if you have the 'kqueue' functions. */ #undef HAVE_KQUEUE @@ -568,6 +577,9 @@ /* Define to 1 if you have the `lchmod' function. */ #undef HAVE_LCHMOD +/* Define to 1 if you have the `lchown' function. */ +#undef HAVE_LCHOWN + /* Define to 1 if you have the `lgamma' function. */ #undef HAVE_LGAMMA @@ -598,6 +610,9 @@ /* Define if you have the 'link' function. */ #undef HAVE_LINK +/* Define to 1 if you have the `linkat' function. */ +#undef HAVE_LINKAT + /* Define to 1 if you have the header file. */ #undef HAVE_LINUX_CAN_BCM_H @@ -628,6 +643,9 @@ /* Define to 1 if you have the header file. */ #undef HAVE_LINUX_VM_SOCKETS_H +/* Define to 1 if you have the `lockf' function. */ +#undef HAVE_LOCKF + /* Define to 1 if you have the `log1p' function. */ #undef HAVE_LOG1P @@ -637,15 +655,33 @@ /* Define to 1 if the system has the type `long double'. */ #undef HAVE_LONG_DOUBLE +/* Define to 1 if you have the `lstat' function. */ +#undef HAVE_LSTAT + +/* Define to 1 if you have the `lutimes' function. */ +#undef HAVE_LUTIMES + /* Define this if you have the makedev macro. */ #undef HAVE_MAKEDEV +/* Define to 1 if you have the `mbrtowc' function. */ +#undef HAVE_MBRTOWC + /* Define if you have the 'memfd_create' function. */ #undef HAVE_MEMFD_CREATE /* Define to 1 if you have the header file. */ #undef HAVE_MEMORY_H +/* Define to 1 if you have the `memrchr' function. */ +#undef HAVE_MEMRCHR + +/* Define to 1 if you have the `mkdirat' function. */ +#undef HAVE_MKDIRAT + +/* Define to 1 if you have the `mkfifo' function. */ +#undef HAVE_MKFIFO + /* Define to 1 if you have the `mkfifoat' function. */ #undef HAVE_MKFIFOAT @@ -658,6 +694,9 @@ /* Define to 1 if you have the `mktime' function. */ #undef HAVE_MKTIME +/* Define to 1 if you have the `mmap' function. */ +#undef HAVE_MMAP + /* Define to 1 if you have the `mremap' function. */ #undef HAVE_MREMAP From c2a0d159d20b7a9322427d04d07c28efd8fd105f Mon Sep 17 00:00:00 2001 From: Zackery Spytz Date: Mon, 27 May 2019 19:23:08 -0600 Subject: [PATCH 4/8] Use MFD_CLOEXEC as the default value for *flags*. --- Doc/library/os.rst | 29 ++++++++++++++++++++++++++--- Lib/test/test_os.py | 3 +++ Modules/clinic/posixmodule.c.h | 21 +++++++++++++++------ Modules/posixmodule.c | 5 ++--- 4 files changed, 46 insertions(+), 12 deletions(-) diff --git a/Doc/library/os.rst b/Doc/library/os.rst index fb72bd19ab06e2..d0b76c41c85477 100644 --- a/Doc/library/os.rst +++ b/Doc/library/os.rst @@ -2982,11 +2982,12 @@ features: Added support for :class:`bytes` paths. -.. function:: memfd_create(name, flags) +.. function:: memfd_create(name[, flags=os.MFD_CLOEXEC]) Create an anonymous file and return a file descriptor that refers to it. *flags* must be one of the ``os.MFD_*`` constants available on the system - (or a bitwise ORed combination of them). + (or a bitwise ORed combination of them). By default, the new file + descriptor is :ref:`non-inheritable `. .. availability:: Linux 3.17 and newer. @@ -2994,7 +2995,29 @@ features: .. data:: MFD_CLOEXEC -.. data:: MFD_ALLOW_SEALING + MFD_ALLOW_SEALING + MFD_HUGETLB + MFD_HUGE_SHIFT + MFD_HUGE_MASK + MFD_HUGE_64KB + MFD_HUGE_512KB + MFD_HUGE_1MB + MFD_HUGE_2MB + MFD_HUGE_8MB + MFD_HUGE_16MB + MFD_HUGE_32MB + MFD_HUGE_256MB + MFD_HUGE_512MB + MFD_HUGE_1GB + MFD_HUGE_2GB + MFD_HUGE_16GB + + These flags can be passed to :func:`memfd_create`. + + .. availability:: Linux 3.17 and newer. The ``MFD_HUGE*`` flags are only + available since Linux 4.14. + + .. versionadded:: 3.8 Linux extended attributes diff --git a/Lib/test/test_os.py b/Lib/test/test_os.py index 98da9e5914f4b5..efd8abbf4d7c08 100644 --- a/Lib/test/test_os.py +++ b/Lib/test/test_os.py @@ -3127,9 +3127,12 @@ class MemfdCreateTests(unittest.TestCase): def test_memfd_create(self): fd = os.memfd_create("Hi", os.MFD_CLOEXEC) self.assertNotEqual(fd, -1) + self.assertFalse(os.get_inheritable(fd)) with open(fd, "wb") as f: f.write(b'memfd_create') self.assertEqual(f.tell(), 12) + fd = os.memfd_create("Hi") + self.assertFalse(os.get_inheritable(fd)) class OSErrorTests(unittest.TestCase): diff --git a/Modules/clinic/posixmodule.c.h b/Modules/clinic/posixmodule.c.h index 34c4c4ff9de2c7..13f25460b4f6cf 100644 --- a/Modules/clinic/posixmodule.c.h +++ b/Modules/clinic/posixmodule.c.h @@ -7346,29 +7346,37 @@ os_urandom(PyObject *module, PyObject *arg) #if defined(HAVE_MEMFD_CREATE) PyDoc_STRVAR(os_memfd_create__doc__, -"memfd_create($module, name, flags, /)\n" +"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, os_memfd_create__doc__}, + {"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) +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; + unsigned int flags = MFD_CLOEXEC; - if (!_PyArg_CheckPositional("memfd_create", nargs, 2, 2)) { + 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" ); @@ -7378,6 +7386,7 @@ os_memfd_create(PyObject *module, PyObject *const *args, Py_ssize_t nargs) if (flags == (unsigned int)-1 && PyErr_Occurred()) { goto exit; } +skip_optional_pos: return_value = os_memfd_create_impl(module, name, flags); exit: @@ -8626,4 +8635,4 @@ os__remove_dll_directory(PyObject *module, PyObject *const *args, Py_ssize_t nar #ifndef OS__REMOVE_DLL_DIRECTORY_METHODDEF #define OS__REMOVE_DLL_DIRECTORY_METHODDEF #endif /* !defined(OS__REMOVE_DLL_DIRECTORY_METHODDEF) */ -/*[clinic end generated code: output=7446453677391010 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=855b81aafd05beed input=a9049054013a1b77]*/ diff --git a/Modules/posixmodule.c b/Modules/posixmodule.c index 78beb2a11f792c..a3d979c3bcd78d 100644 --- a/Modules/posixmodule.c +++ b/Modules/posixmodule.c @@ -11915,14 +11915,13 @@ os_urandom_impl(PyObject *module, Py_ssize_t size) os.memfd_create name: FSConverter - flags: unsigned_int(bitwise=True) - / + 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=5659b8bdae914e4f]*/ +/*[clinic end generated code: output=6681ede983bdb9a6 input=a42cfc199bcd56e9]*/ { int fd; const char *bytes = PyBytes_AS_STRING(name); From 00b221c1dc6248d5a65643bc42c9186cdb89fef1 Mon Sep 17 00:00:00 2001 From: Zackery Spytz Date: Mon, 27 May 2019 19:49:49 -0600 Subject: [PATCH 5/8] Add memset_s to configure.ac. --- configure | 2 +- configure.ac | 2 +- pyconfig.h.in | 3 +++ 3 files changed, 5 insertions(+), 2 deletions(-) diff --git a/configure b/configure index cc18322d7514c3..8a6f839c4a77df 100755 --- a/configure +++ b/configure @@ -11484,7 +11484,7 @@ for ac_func in alarm accept4 setitimer getitimer bind_textdomain_codeset chown \ getpriority getresuid getresgid getpwent getpwnam_r getpwuid_r getspnam getspent getsid getwd \ if_nameindex \ initgroups kill killpg lchmod lchown lockf linkat lstat lutimes madvise mmap \ - memrchr mbrtowc mkdirat mkfifo \ + memrchr memset_s mbrtowc mkdirat mkfifo \ mkfifoat mknod mknodat mktime mremap nice openat pathconf pause pipe2 plock poll \ posix_fallocate posix_fadvise posix_spawn posix_spawnp pread preadv preadv2 \ pthread_condattr_setclock pthread_init pthread_kill putenv pwrite pwritev pwritev2 \ diff --git a/configure.ac b/configure.ac index 6d31bc4e4cade8..f973ca532ca640 100644 --- a/configure.ac +++ b/configure.ac @@ -3528,7 +3528,7 @@ AC_CHECK_FUNCS(alarm accept4 setitimer getitimer bind_textdomain_codeset chown \ getpriority getresuid getresgid getpwent getpwnam_r getpwuid_r getspnam getspent getsid getwd \ if_nameindex \ initgroups kill killpg lchmod lchown lockf linkat lstat lutimes madvise mmap \ - memrchr mbrtowc mkdirat mkfifo \ + memrchr memset_s mbrtowc mkdirat mkfifo \ mkfifoat mknod mknodat mktime mremap nice openat pathconf pause pipe2 plock poll \ posix_fallocate posix_fadvise posix_spawn posix_spawnp pread preadv preadv2 \ pthread_condattr_setclock pthread_init pthread_kill putenv pwrite pwritev pwritev2 \ diff --git a/pyconfig.h.in b/pyconfig.h.in index b9bb3ffa6f6935..1670b07a0b5f07 100644 --- a/pyconfig.h.in +++ b/pyconfig.h.in @@ -679,6 +679,9 @@ /* Define to 1 if you have the `memrchr' function. */ #undef HAVE_MEMRCHR +/* Define to 1 if you have the `memset_s' function. */ +#undef HAVE_MEMSET_S + /* Define to 1 if you have the `mkdirat' function. */ #undef HAVE_MKDIRAT From 997eba8a1db88b754d9cb11c2f9ade1dc8594a22 Mon Sep 17 00:00:00 2001 From: Zackery Spytz Date: Mon, 27 May 2019 20:16:29 -0600 Subject: [PATCH 6/8] Revert memset_s changes. --- configure | 2 +- configure.ac | 2 +- pyconfig.h.in | 3 --- 3 files changed, 2 insertions(+), 5 deletions(-) diff --git a/configure b/configure index 8a6f839c4a77df..cc18322d7514c3 100755 --- a/configure +++ b/configure @@ -11484,7 +11484,7 @@ for ac_func in alarm accept4 setitimer getitimer bind_textdomain_codeset chown \ getpriority getresuid getresgid getpwent getpwnam_r getpwuid_r getspnam getspent getsid getwd \ if_nameindex \ initgroups kill killpg lchmod lchown lockf linkat lstat lutimes madvise mmap \ - memrchr memset_s mbrtowc mkdirat mkfifo \ + memrchr mbrtowc mkdirat mkfifo \ mkfifoat mknod mknodat mktime mremap nice openat pathconf pause pipe2 plock poll \ posix_fallocate posix_fadvise posix_spawn posix_spawnp pread preadv preadv2 \ pthread_condattr_setclock pthread_init pthread_kill putenv pwrite pwritev pwritev2 \ diff --git a/configure.ac b/configure.ac index f973ca532ca640..6d31bc4e4cade8 100644 --- a/configure.ac +++ b/configure.ac @@ -3528,7 +3528,7 @@ AC_CHECK_FUNCS(alarm accept4 setitimer getitimer bind_textdomain_codeset chown \ getpriority getresuid getresgid getpwent getpwnam_r getpwuid_r getspnam getspent getsid getwd \ if_nameindex \ initgroups kill killpg lchmod lchown lockf linkat lstat lutimes madvise mmap \ - memrchr memset_s mbrtowc mkdirat mkfifo \ + memrchr mbrtowc mkdirat mkfifo \ mkfifoat mknod mknodat mktime mremap nice openat pathconf pause pipe2 plock poll \ posix_fallocate posix_fadvise posix_spawn posix_spawnp pread preadv preadv2 \ pthread_condattr_setclock pthread_init pthread_kill putenv pwrite pwritev pwritev2 \ diff --git a/pyconfig.h.in b/pyconfig.h.in index 1670b07a0b5f07..b9bb3ffa6f6935 100644 --- a/pyconfig.h.in +++ b/pyconfig.h.in @@ -679,9 +679,6 @@ /* Define to 1 if you have the `memrchr' function. */ #undef HAVE_MEMRCHR -/* Define to 1 if you have the `memset_s' function. */ -#undef HAVE_MEMSET_S - /* Define to 1 if you have the `mkdirat' function. */ #undef HAVE_MKDIRAT From 346e5d011b40db54c0257cb92d273e028856c847 Mon Sep 17 00:00:00 2001 From: Zackery Spytz Date: Wed, 29 May 2019 07:59:24 -0600 Subject: [PATCH 7/8] Apply the requested changes. --- Doc/library/os.rst | 4 ++-- Lib/test/test_os.py | 9 ++++++--- 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/Doc/library/os.rst b/Doc/library/os.rst index d0b76c41c85477..c21e0f0fdae4e8 100644 --- a/Doc/library/os.rst +++ b/Doc/library/os.rst @@ -3014,8 +3014,8 @@ features: These flags can be passed to :func:`memfd_create`. - .. availability:: Linux 3.17 and newer. The ``MFD_HUGE*`` flags are only - available since Linux 4.14. + .. availability:: Linux 3.17 or newer with glibc 2.27 or newer. The + ``MFD_HUGE*`` flags are only available since Linux 4.14. .. versionadded:: 3.8 diff --git a/Lib/test/test_os.py b/Lib/test/test_os.py index efd8abbf4d7c08..820c99c7a07cb4 100644 --- a/Lib/test/test_os.py +++ b/Lib/test/test_os.py @@ -3127,12 +3127,15 @@ class MemfdCreateTests(unittest.TestCase): def test_memfd_create(self): fd = os.memfd_create("Hi", os.MFD_CLOEXEC) self.assertNotEqual(fd, -1) + self.addCleanup(os.close, fd) self.assertFalse(os.get_inheritable(fd)) - with open(fd, "wb") as f: + with open(fd, "wb", closefd=False) as f: f.write(b'memfd_create') self.assertEqual(f.tell(), 12) - fd = os.memfd_create("Hi") - self.assertFalse(os.get_inheritable(fd)) + + fd2 = os.memfd_create("Hi") + self.addCleanup(os.close, fd2) + self.assertFalse(os.get_inheritable(fd2)) class OSErrorTests(unittest.TestCase): From 7a2c4cc16ddd4d1958a8d6a0170bd561f4736e56 Mon Sep 17 00:00:00 2001 From: Zackery Spytz Date: Wed, 29 May 2019 08:03:06 -0600 Subject: [PATCH 8/8] Tweak the docs. --- Doc/library/os.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Doc/library/os.rst b/Doc/library/os.rst index c21e0f0fdae4e8..b53fd71e65b31a 100644 --- a/Doc/library/os.rst +++ b/Doc/library/os.rst @@ -2989,7 +2989,7 @@ features: (or a bitwise ORed combination of them). By default, the new file descriptor is :ref:`non-inheritable `. - .. availability:: Linux 3.17 and newer. + .. availability:: Linux 3.17 or newer with glibc 2.27 or newer. .. versionadded:: 3.8