From 6f076a6cc7c4ebd16e4999580b155fc59eba37cf Mon Sep 17 00:00:00 2001
From: Oleksii Shevchuk
Date: Thu, 2 Mar 2017 13:37:30 +0200
Subject: [PATCH] Add memfd support to python based pupyimporter/memimporter
---
pupy/packages/all/pupyimporter.py | 43 ++++++++++++++++++++++++++-----
1 file changed, 37 insertions(+), 6 deletions(-)
diff --git a/pupy/packages/all/pupyimporter.py b/pupy/packages/all/pupyimporter.py
index d2c313d9..267d7e9b 100644
--- a/pupy/packages/all/pupyimporter.py
+++ b/pupy/packages/all/pupyimporter.py
@@ -32,13 +32,34 @@ try:
except ImportError:
builtin_memimporter = False
allow_system_packages = True
+ import ctypes
+ import platform
import pkg_resources
+ libc = ctypes.CDLL(None)
+ syscall = libc.syscall
from tempfile import mkstemp
from os import chmod, unlink, close, write
class MemImporter(object):
def __init__(self):
self.dir = None
+ self.memfd = None
+ self.ready = False
+
+ if platform.system() == 'Linux':
+ maj, min = platform.release().split('.')[:2]
+ if maj >= 3 and min >= 13:
+ __NR_memfd_create = None
+ machine = platform.machine()
+ if machine == 'x86_64':
+ __NR_memfd_create = 319
+ elif machine == '__i386__':
+ __NR_memfd_create = 356
+
+ if __NR_memfd_create:
+ self.memfd = lambda: syscall(__NR_memfd_create, 'heap', 0x1)
+ self.ready = True
+ return
for dir in ['/dev/shm', '/tmp', '/var/tmp', '/run']:
try:
@@ -49,6 +70,7 @@ except ImportError:
try:
chmod(name, 0777)
self.dir = dir
+ self.ready = True
break
finally:
@@ -56,7 +78,17 @@ except ImportError:
unlink(name)
def import_module(self, data, initfuncname, fullname, path):
- fd, name = mkstemp(dir=self.dir)
+ fd = -1
+ closefd = True
+ if self.memfd:
+ fd = self.memfd()
+ if fd != -1:
+ name = '/proc/self/fd/{}'.format(fd)
+ closefd = False
+
+ if fd == -1:
+ fd, name = mkstemp(dir=self.dir)
+
try:
write(fd, data)
imp.load_dynamic(fullname, name)
@@ -65,13 +97,12 @@ except ImportError:
self.dir = None
finally:
- close(fd)
- unlink(name)
+ if closefd:
+ close(fd)
+ unlink(name)
_memimporter = MemImporter()
- if _memimporter.dir:
- print 'TMP DIR: {}'.format(_memimporter.dir)
- builtin_memimporter = True
+ builtin_memimporter = _memimporter.ready
modules = {}