]> granicus.if.org Git - python/commitdiff
Fis issue5504: ctypes does now work with systems where mmap can't be
authorThomas Heller <theller@ctypes.org>
Sun, 8 Aug 2010 17:56:41 +0000 (17:56 +0000)
committerThomas Heller <theller@ctypes.org>
Sun, 8 Aug 2010 17:56:41 +0000 (17:56 +0000)
PROT_WRITE and PROT_EXEC.

Misc/NEWS
Modules/_ctypes/_ctypes.c
Modules/_ctypes/callbacks.c
Modules/_ctypes/ctypes.h
Modules/_ctypes/libffi/fficonfig.py.in
Modules/_ctypes/libffi_msvc/ffi.c
Modules/_ctypes/libffi_msvc/ffi.h
Modules/_ctypes/malloc_closure.c
setup.py

index 6c2c38fc17bb47c81141ff953ccc7c4f90b29bb7..cc635214119e1f553b7383c481b722aa203e7980 100644 (file)
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -26,6 +26,9 @@ Core and Builtins
 Library
 -------
 
+- Issue5504 - ctypes should now work with systems where mmap can't be
+  PROT_WRITE and PROT_EXEC.
+
 - Fix Issue8280 - urllib2's Request method will remove fragements in the url.
   This is how it is supposed to work, wget and curl do the same.  Previous
   behavior was wrong.
index af3bb5b96273a8374b42b66d76beef46dd322130..7d7d58cb6e47a2e05a71fb86fb4f3179419bde6f 100644 (file)
@@ -3463,7 +3463,7 @@ PyCFuncPtr_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
     self->callable = callable;
 
     self->thunk = thunk;
-    *(void **)self->b_ptr = (void *)thunk->pcl;
+    *(void **)self->b_ptr = (void *)thunk->pcl_exec;
 
     Py_INCREF((PyObject *)thunk); /* for KeepRef */
     if (-1 == KeepRef((CDataObject *)self, 0, (PyObject *)thunk)) {
index 8fbe6dea457e40d9f5ec802ddb4368b73f343725..deedaa369d98682ce5243a01436993de7ae56fad 100644 (file)
@@ -21,8 +21,8 @@ CThunkObject_dealloc(PyObject *_self)
     Py_XDECREF(self->converters);
     Py_XDECREF(self->callable);
     Py_XDECREF(self->restype);
-    if (self->pcl)
-        _ctypes_free_closure(self->pcl);
+    if (self->pcl_write)
+        ffi_closure_free(self->pcl_write);
     PyObject_GC_Del(self);
 }
 
@@ -391,7 +391,8 @@ static CThunkObject* CThunkObject_new(Py_ssize_t nArgs)
         return NULL;
     }
 
-    p->pcl = NULL;
+    p->pcl_exec = NULL;
+    p->pcl_write = NULL;
     memset(&p->cif, 0, sizeof(p->cif));
     p->converters = NULL;
     p->callable = NULL;
@@ -421,8 +422,9 @@ CThunkObject *_ctypes_alloc_callback(PyObject *callable,
 
     assert(CThunk_CheckExact(p));
 
-    p->pcl = _ctypes_alloc_closure();
-    if (p->pcl == NULL) {
+    p->pcl_write = ffi_closure_alloc(sizeof(ffi_closure),
+                                    &p->pcl_exec);
+    if (p->pcl_write == NULL) {
         PyErr_NoMemory();
         goto error;
     }
@@ -467,7 +469,9 @@ CThunkObject *_ctypes_alloc_callback(PyObject *callable,
                      "ffi_prep_cif failed with %d", result);
         goto error;
     }
-    result = ffi_prep_closure(p->pcl, &p->cif, closure_fcn, p);
+    result = ffi_prep_closure_loc(p->pcl_write, &p->cif, closure_fcn,
+                                 p,
+                                 p->pcl_exec);
     if (result != FFI_OK) {
         PyErr_Format(PyExc_RuntimeError,
                      "ffi_prep_closure failed with %d", result);
index 7d7ba1f37a50ed2e70016abe1110d61a7d706636..59640ccd580eb49732bb5fdb3ecfa11c8ec6ad63 100644 (file)
@@ -95,7 +95,8 @@ struct tagCDataObject {
 
 typedef struct {
     PyObject_VAR_HEAD
-    ffi_closure *pcl; /* the C callable */
+    ffi_closure *pcl_write; /* the C callable, writeable */
+    void *pcl_exec;         /* the C callable, executable */
     ffi_cif cif;
     int flags;
     PyObject *converters;
@@ -428,9 +429,6 @@ extern Py_ssize_t PyUnicode_AsWideChar_fixed(PyUnicodeObject *, wchar_t *, Py_ss
 #endif
 #endif
 
-extern void _ctypes_free_closure(void *);
-extern void *_ctypes_alloc_closure(void);
-
 extern void _ctypes_add_traceback(char *, char *, int);
 
 extern PyObject *PyCData_FromBaseObj(PyObject *type, PyObject *base, Py_ssize_t index, char *adr);
index b7bae9ccb578634d03e9b48c2584dfb681d9e602..27c971f86f2486a0f1c8587b9d5172117c482e06 100644 (file)
@@ -1,5 +1,7 @@
 ffi_sources = """
 src/prep_cif.c
+src/closures.c
+src/dlmalloc.c
 """.split()
 
 ffi_platforms = {
index 763d179c8b935f9342273161c63b3fac78f0959b..65581a773fa5a466ba81c43b30c2114f7777d692 100644 (file)
@@ -371,10 +371,11 @@ ffi_prep_incoming_args_SYSV(char *stack, void **rvalue,
 extern void ffi_closure_OUTER();
 
 ffi_status
-ffi_prep_closure (ffi_closure* closure,
-                 ffi_cif* cif,
-                 void (*fun)(ffi_cif*,void*,void**,void*),
-                 void *user_data)
+ffi_prep_closure_loc (ffi_closure* closure,
+                                         ffi_cif* cif,
+                                         void (*fun)(ffi_cif*,void*,void**,void*),
+                                         void *user_data,
+                                         void *codeloc)
 {
   short bytes;
   char *tramp;
@@ -452,6 +453,5 @@ ffi_prep_closure (ffi_closure* closure,
   closure->cif  = cif;
   closure->user_data = user_data;
   closure->fun  = fun;
-
   return FFI_OK;
 }
index a88d8744f7f240f7f7d83ce28ca22825ddda6bee..efb14c5f6f3aa11cb28616fe72aa22d979bef0ed 100644 (file)
@@ -221,11 +221,15 @@ typedef struct {
   void      *user_data;
 } ffi_closure;
 
+void ffi_closure_free(void *);
+void *ffi_closure_alloc (size_t size, void **code);
+
 ffi_status
-ffi_prep_closure (ffi_closure*,
+ffi_prep_closure_loc (ffi_closure*,
                  ffi_cif *,
                  void (*fun)(ffi_cif*,void*,void**,void*),
-                 void *user_data);
+                 void *user_data,
+                 void *codeloc);
 
 typedef struct {
   char tramp[FFI_TRAMPOLINE_SIZE];
index a691ab4f68a2b8f34e709f311d32e92dc77a209f..d0a20b567eda2e0c0f1a5583773855f977668923 100644 (file)
@@ -93,7 +93,7 @@ static void more_core(void)
 /******************************************************************/
 
 /* put the item back into the free list */
-void _ctypes_free_closure(void *p)
+void ffi_closure_free(void *p)
 {
     ITEM *item = (ITEM *)p;
     item->next = free_list;
@@ -101,7 +101,7 @@ void _ctypes_free_closure(void *p)
 }
 
 /* return one item from the free list, allocating more if needed */
-void *_ctypes_alloc_closure(void)
+void *ffi_closure_alloc(size_t ignored, void** codeloc)
 {
     ITEM *item;
     if (!free_list)
@@ -110,5 +110,7 @@ void *_ctypes_alloc_closure(void)
         return NULL;
     item = free_list;
     free_list = item->next;
-    return item;
+       *codeloc = (void *)item;
+    return (void *)item;
 }
+
index a363509fbdbc408746d0272640d01b2d24723508..7d5d30c2cbc909f6a1a96d3411187d12be9f85b5 100644 (file)
--- a/setup.py
+++ b/setup.py
@@ -1867,8 +1867,7 @@ class PyBuildExt(build_ext):
                    '_ctypes/callbacks.c',
                    '_ctypes/callproc.c',
                    '_ctypes/stgdict.c',
-                   '_ctypes/cfield.c',
-                   '_ctypes/malloc_closure.c']
+                   '_ctypes/cfield.c']
         depends = ['_ctypes/ctypes.h']
 
         if sys.platform == 'darwin':