diff --git a/Modules/mmapmodule.c b/Modules/mmapmodule.c index bff22b21028..66f0e481690 100644 --- a/Modules/mmapmodule.c +++ b/Modules/mmapmodule.c @@ -1,7 +1,7 @@ -/* -*- Mode: C++; tab-width: 4 -*- - / Author: Sam Rushing +/* + / Author: Sam Rushing / Hacked for Unix by A.M. Kuchling - / $Id$ + / $Id$ / mmapmodule.cpp -- map a view of a file into memory / @@ -16,6 +16,8 @@ / ftp://squirl.nightmare.com/pub/python/python-ext. */ +#include + #ifndef MS_WIN32 #define UNIX #endif @@ -29,23 +31,21 @@ #include #endif -#include - #include #include static PyObject *mmap_module_error; typedef struct { - PyObject_HEAD - char * data; - size_t size; - size_t pos; + PyObject_HEAD + char * data; + size_t size; + size_t pos; #ifdef MS_WIN32 - HANDLE map_handle; - HFILE file_handle; - char * tagname; + HANDLE map_handle; + HFILE file_handle; + char * tagname; #endif #ifdef UNIX @@ -57,201 +57,205 @@ static void mmap_object_dealloc(mmap_object * m_obj) { #ifdef MS_WIN32 - UnmapViewOfFile (m_obj->data); - CloseHandle (m_obj->map_handle); - CloseHandle ((HANDLE)m_obj->file_handle); + UnmapViewOfFile (m_obj->data); + CloseHandle (m_obj->map_handle); + CloseHandle ((HANDLE)m_obj->file_handle); #endif /* MS_WIN32 */ #ifdef UNIX - if (m_obj->data!=NULL) { - msync(m_obj->data, m_obj->size, MS_SYNC | MS_INVALIDATE); - munmap(m_obj->data, m_obj->size); - } + if (m_obj->data!=NULL) { + msync(m_obj->data, m_obj->size, MS_SYNC | MS_INVALIDATE); + munmap(m_obj->data, m_obj->size); + } #endif /* UNIX */ - PyMem_DEL(m_obj); + PyMem_DEL(m_obj); } static PyObject * mmap_close_method (mmap_object * self, PyObject * args) { #ifdef MS_WIN32 - UnmapViewOfFile (self->data); - CloseHandle (self->map_handle); - CloseHandle ((HANDLE)self->file_handle); - self->map_handle = (HANDLE) NULL; + UnmapViewOfFile (self->data); + CloseHandle (self->map_handle); + CloseHandle ((HANDLE)self->file_handle); + self->map_handle = (HANDLE) NULL; #endif /* MS_WIN32 */ #ifdef UNIX - munmap(self->data, self->size); - self->data = NULL; + munmap(self->data, self->size); + self->data = NULL; #endif - Py_INCREF (Py_None); - return (Py_None); + Py_INCREF (Py_None); + return (Py_None); } #ifdef MS_WIN32 -#define CHECK_VALID(err) \ -do { \ - if (!self->map_handle) { \ - PyErr_SetString (PyExc_ValueError, "mmap closed or invalid");\ - return err; \ - } \ +#define CHECK_VALID(err) \ +do { \ + if (!self->map_handle) { \ + PyErr_SetString (PyExc_ValueError, "mmap closed or invalid"); \ + return err; \ + } \ } while (0) #endif /* MS_WIN32 */ #ifdef UNIX -#define CHECK_VALID(err) \ -do { \ - if (self->data == NULL) { \ - PyErr_SetString (PyExc_ValueError, "mmap closed or invalid"); \ - return err; \ - } \ +#define CHECK_VALID(err) \ +do { \ + if (self->data == NULL) { \ + PyErr_SetString (PyExc_ValueError, "mmap closed or invalid"); \ + return err; \ + } \ } while (0) #endif /* UNIX */ static PyObject * mmap_read_byte_method (mmap_object * self, - PyObject * args) + PyObject * args) { - char value; - char * where = (self->data+self->pos); - CHECK_VALID(NULL); - if ((where >= 0) && (where < (self->data+self->size))) { - value = (char) *(where); - self->pos += 1; - return Py_BuildValue("c", (char) *(where)); - } else { - PyErr_SetString (PyExc_ValueError, "read byte out of range"); - return NULL; - } + char value; + char * where = (self->data+self->pos); + CHECK_VALID(NULL); + if ((where >= 0) && (where < (self->data+self->size))) { + value = (char) *(where); + self->pos += 1; + return Py_BuildValue("c", (char) *(where)); + } else { + PyErr_SetString (PyExc_ValueError, "read byte out of range"); + return NULL; + } } static PyObject * mmap_read_line_method (mmap_object * self, - PyObject * args) + PyObject * args) { - char * start; - char * eof = self->data+self->size; - char * eol; - PyObject * result; + char * start; + char * eof = self->data+self->size; + char * eol; + PyObject * result; - CHECK_VALID(NULL); - start = self->data+self->pos; + CHECK_VALID(NULL); + start = self->data+self->pos; - /* strchr was a bad idea here - there's no way to range - check it. there is no 'strnchr' */ - for (eol = start; (eol < eof) && (*eol != '\n') ; eol++) - { /* do nothing */ } + /* strchr was a bad idea here - there's no way to range + check it. there is no 'strnchr' */ + for (eol = start; (eol < eof) && (*eol != '\n') ; eol++) + { /* do nothing */ } - result = Py_BuildValue("s#", start, (long) (++eol - start)); - self->pos += (eol - start); - return (result); + result = Py_BuildValue("s#", start, (long) (++eol - start)); + self->pos += (eol - start); + return (result); } static PyObject * mmap_read_method (mmap_object * self, - PyObject * args) + PyObject * args) { - long num_bytes; - PyObject *result; + long num_bytes; + PyObject *result; - CHECK_VALID(NULL); - if (!PyArg_ParseTuple (args, "l", &num_bytes)) - return(NULL); + CHECK_VALID(NULL); + if (!PyArg_ParseTuple (args, "l", &num_bytes)) + return(NULL); - /* silently 'adjust' out-of-range requests */ - if ((self->pos + num_bytes) > self->size) { - num_bytes -= (self->pos+num_bytes) - self->size; - } - result = Py_BuildValue("s#", self->data+self->pos, num_bytes); - self->pos += num_bytes; - return (result); + /* silently 'adjust' out-of-range requests */ + if ((self->pos + num_bytes) > self->size) { + num_bytes -= (self->pos+num_bytes) - self->size; + } + result = Py_BuildValue("s#", self->data+self->pos, num_bytes); + self->pos += num_bytes; + return (result); } static PyObject * mmap_find_method (mmap_object *self, - PyObject *args) + PyObject *args) { - long start = self->pos; - char * needle; - int len; + long start = self->pos; + char * needle; + int len; - CHECK_VALID(NULL); - if (!PyArg_ParseTuple (args, "s#|l", &needle, &len, &start)) { - return NULL; - } else { - char * p = self->data+self->pos; - char * e = self->data+self->size; - while (p < e) { - char * s = p; - char * n = needle; - while ((sdata + start))); - } - p++; - } - return Py_BuildValue ("l", (long) -1); + CHECK_VALID(NULL); + if (!PyArg_ParseTuple (args, "s#|l", &needle, &len, &start)) { + return NULL; + } else { + char * p = self->data+self->pos; + char * e = self->data+self->size; + while (p < e) { + char * s = p; + char * n = needle; + while ((sdata + start))); + } + p++; } + return Py_BuildValue ("l", (long) -1); + } } static PyObject * mmap_write_method (mmap_object * self, - PyObject * args) + PyObject * args) { - long length; - char * data; + long length; + char * data; - CHECK_VALID(NULL); - if (!PyArg_ParseTuple (args, "s#", &data, &length)) - return(NULL); + CHECK_VALID(NULL); + if (!PyArg_ParseTuple (args, "s#", &data, &length)) + return(NULL); - if ((self->pos + length) > self->size) { - PyErr_SetString (mmap_module_error, "data out of range"); - return NULL; - } - memcpy (self->data+self->pos, data, length); - self->pos = self->pos+length; - Py_INCREF (Py_None); - return (Py_None); + if ((self->pos + length) > self->size) { + PyErr_SetString (PyExc_ValueError, "data out of range"); + return NULL; + } + memcpy (self->data+self->pos, data, length); + self->pos = self->pos+length; + Py_INCREF (Py_None); + return (Py_None); } static PyObject * mmap_write_byte_method (mmap_object * self, - PyObject * args) + PyObject * args) { - char value; + char value; - CHECK_VALID(NULL); - if (!PyArg_ParseTuple (args, "c", &value)) - return(NULL); + CHECK_VALID(NULL); + if (!PyArg_ParseTuple (args, "c", &value)) + return(NULL); - *(self->data+self->pos) = value; - self->pos += 1; - Py_INCREF (Py_None); - return (Py_None); + *(self->data+self->pos) = value; + self->pos += 1; + Py_INCREF (Py_None); + return (Py_None); } static PyObject * mmap_size_method (mmap_object * self, - PyObject * args) + PyObject * args) { - CHECK_VALID(NULL); + CHECK_VALID(NULL); #ifdef MS_WIN32 - if (self->file_handle != (HFILE) 0xFFFFFFFF) { - return (Py_BuildValue ("l", GetFileSize ((HANDLE)self->file_handle, NULL))); - } else { - return (Py_BuildValue ("l", self->size) ); - } + if (self->file_handle != (HFILE) 0xFFFFFFFF) { + return (Py_BuildValue ( + "l", + GetFileSize ((HANDLE)self->file_handle, NULL))); + } else { + return (Py_BuildValue ("l", self->size) ); + } #endif /* MS_WIN32 */ #ifdef UNIX - return (Py_BuildValue ("l", self->size) ); + return (Py_BuildValue ("l", self->size) ); #endif /* UNIX */ } @@ -266,70 +270,72 @@ mmap_size_method (mmap_object * self, static PyObject * mmap_resize_method (mmap_object * self, - PyObject * args) + PyObject * args) { - unsigned long new_size; - CHECK_VALID(NULL); - if (!PyArg_ParseTuple (args, "l", &new_size)) { - return NULL; + unsigned long new_size; + CHECK_VALID(NULL); + if (!PyArg_ParseTuple (args, "l", &new_size)) { + return NULL; #ifdef MS_WIN32 - } else { - /* First, unmap the file view */ - UnmapViewOfFile (self->data); - /* Close the mapping object */ - CloseHandle ((HANDLE)self->map_handle); - /* Move to the desired EOF position */ - SetFilePointer ((HANDLE)self->file_handle, new_size, NULL, FILE_BEGIN); - /* Change the size of the file */ - SetEndOfFile ((HANDLE)self->file_handle); - /* Create another mapping object and remap the file view */ - self->map_handle = CreateFileMapping ((HANDLE) self->file_handle, - NULL, - PAGE_READWRITE, - 0, - new_size, - self->tagname); - char complaint[256]; - if (self->map_handle != NULL) { - self->data = (char *) MapViewOfFile (self->map_handle, - FILE_MAP_WRITE, - 0, - 0, - 0); - if (self->data != NULL) { - self->size = new_size; - Py_INCREF (Py_None); - return Py_None; - } else { - sprintf (complaint, "MapViewOfFile failed: %ld", GetLastError()); - } - } else { - sprintf (complaint, "CreateFileMapping failed: %ld", GetLastError()); - } - PyErr_SetString (mmap_module_error, complaint); - return (NULL); + } else { + DWORD dwErrCode = 0; + /* First, unmap the file view */ + UnmapViewOfFile (self->data); + /* Close the mapping object */ + CloseHandle ((HANDLE)self->map_handle); + /* Move to the desired EOF position */ + SetFilePointer ((HANDLE)self->file_handle, + new_size, NULL, FILE_BEGIN); + /* Change the size of the file */ + SetEndOfFile ((HANDLE)self->file_handle); + /* Create another mapping object and remap the file view */ + self->map_handle = CreateFileMapping ( + (HANDLE) self->file_handle, + NULL, + PAGE_READWRITE, + 0, + new_size, + self->tagname); + if (self->map_handle != NULL) { + self->data = (char *) MapViewOfFile (self->map_handle, + FILE_MAP_WRITE, + 0, + 0, + 0); + if (self->data != NULL) { + self->size = new_size; + Py_INCREF (Py_None); + return Py_None; + } else { + dwErrCode = GetLastError(); + } + } else { + dwErrCode = GetLastError(); } + PyErr_SetFromWindowsErr(dwErrCode); + return (NULL); #endif /* MS_WIN32 */ #ifdef UNIX #ifndef MREMAP_MAYMOVE } else { - PyErr_SetString(PyExc_SystemError, "mmap: resizing not available--no mremap()"); - return NULL; + PyErr_SetString(PyExc_SystemError, + "mmap: resizing not available--no mremap()"); + return NULL; #else } else { - void *newmap; + void *newmap; - newmap = mremap(self->data, self->size, new_size, MREMAP_MAYMOVE); - if (newmap == (void *)-1) - { - PyErr_SetFromErrno(mmap_module_error); - return NULL; - } - self->data = newmap; - self->size = new_size; - Py_INCREF(Py_None); - return Py_None; + newmap = mremap(self->data, self->size, new_size, MREMAP_MAYMOVE); + if (newmap == (void *)-1) + { + PyErr_SetFromErrno(mmap_module_error); + return NULL; + } + self->data = newmap; + self->size = new_size; + Py_INCREF(Py_None); + return Py_None; #endif /* MREMAP_MAYMOVE */ #endif /* UNIX */ } @@ -338,372 +344,381 @@ mmap_resize_method (mmap_object * self, static PyObject * mmap_tell_method (mmap_object * self, PyObject * args) { - CHECK_VALID(NULL); - return (Py_BuildValue ("l", self->pos) ); + CHECK_VALID(NULL); + return (Py_BuildValue ("l", self->pos) ); } static PyObject * mmap_flush_method (mmap_object * self, PyObject * args) { - size_t offset = 0; - size_t size = self->size; - CHECK_VALID(NULL); - if (!PyArg_ParseTuple (args, "|ll", &offset, &size)) { - return NULL; - } else if ((offset + size) > self->size) { - PyErr_SetString (PyExc_ValueError, "flush values out of range"); - return NULL; - } else { + size_t offset = 0; + size_t size = self->size; + CHECK_VALID(NULL); + if (!PyArg_ParseTuple (args, "|ll", &offset, &size)) { + return NULL; + } else if ((offset + size) > self->size) { + PyErr_SetString (PyExc_ValueError, + "flush values out of range"); + return NULL; + } else { #ifdef MS_WIN32 - return (Py_BuildValue ("l", FlushViewOfFile (self->data+offset, size))); + return (Py_BuildValue ( + "l", FlushViewOfFile (self->data+offset, size))); #endif /* MS_WIN32 */ #ifdef UNIX - /* XXX semantics of return value? */ - /* XXX flags for msync? */ - if (-1 == msync(self->data + offset, size, MS_SYNC | MS_INVALIDATE)) - { - PyErr_SetFromErrno(mmap_module_error); - return NULL; - } - return Py_BuildValue ("l", 0); -#endif /* UNIX */ + /* XXX semantics of return value? */ + /* XXX flags for msync? */ + if (-1 == msync(self->data + offset, size, + MS_SYNC | MS_INVALIDATE)) + { + PyErr_SetFromErrno(mmap_module_error); + return NULL; } + return Py_BuildValue ("l", 0); +#endif /* UNIX */ + } } static PyObject * mmap_seek_method (mmap_object * self, PyObject * args) { - /* ptrdiff_t dist; */ - long dist; - int how=0; - CHECK_VALID(NULL); - if (!PyArg_ParseTuple (args, "l|i", &dist, &how)) { - return(NULL); - } else { - unsigned long where; - switch (how) { - case 0: - where = dist; - break; - case 1: - where = self->pos + dist; - break; - case 2: - where = self->size - dist; - break; - default: - PyErr_SetString (PyExc_ValueError, "unknown seek type"); - return NULL; - } - if ((where >= 0) && (where < (self->size))) { - self->pos = where; - Py_INCREF (Py_None); - return (Py_None); - } else { - PyErr_SetString (PyExc_ValueError, "seek out of range"); - return NULL; - } + /* ptrdiff_t dist; */ + long dist; + int how=0; + CHECK_VALID(NULL); + if (!PyArg_ParseTuple (args, "l|i", &dist, &how)) { + return(NULL); + } else { + unsigned long where; + switch (how) { + case 0: + where = dist; + break; + case 1: + where = self->pos + dist; + break; + case 2: + where = self->size - dist; + break; + default: + PyErr_SetString (PyExc_ValueError, + "unknown seek type"); + return NULL; } + if ((where >= 0) && (where < (self->size))) { + self->pos = where; + Py_INCREF (Py_None); + return (Py_None); + } else { + PyErr_SetString (PyExc_ValueError, + "seek out of range"); + return NULL; + } + } } static PyObject * mmap_move_method (mmap_object * self, PyObject * args) { - unsigned long dest, src, count; - CHECK_VALID(NULL); - if (!PyArg_ParseTuple (args, "iii", &dest, &src, &count)) { - return NULL; + unsigned long dest, src, count; + CHECK_VALID(NULL); + if (!PyArg_ParseTuple (args, "iii", &dest, &src, &count)) { + return NULL; + } else { + /* bounds check the values */ + if (/* end of source after end of data?? */ + ((src+count) > self->size) + /* dest will fit? */ + || (dest+count > self->size)) { + PyErr_SetString (PyExc_ValueError, + "source or destination out of range"); + return NULL; } else { - /* bounds check the values */ - if (/* end of source after end of data?? */ - ((src+count) > self->size) - /* dest will fit? */ - || (dest+count > self->size)) { - PyErr_SetString (PyExc_ValueError, - "source or destination out of range"); - return NULL; - } else { - memmove (self->data+dest, self->data+src, count); - Py_INCREF (Py_None); - return Py_None; - } + memmove (self->data+dest, self->data+src, count); + Py_INCREF (Py_None); + return Py_None; } + } } static struct PyMethodDef mmap_object_methods[] = { - {"close", (PyCFunction) mmap_close_method, 1}, - {"find", (PyCFunction) mmap_find_method, 1}, - {"flush", (PyCFunction) mmap_flush_method, 1}, - {"move", (PyCFunction) mmap_move_method, 1}, - {"read", (PyCFunction) mmap_read_method, 1}, - {"read_byte", (PyCFunction) mmap_read_byte_method, 1}, - {"readline", (PyCFunction) mmap_read_line_method, 1}, - {"resize", (PyCFunction) mmap_resize_method, 1}, - {"seek", (PyCFunction) mmap_seek_method, 1}, - {"size", (PyCFunction) mmap_size_method, 1}, - {"tell", (PyCFunction) mmap_tell_method, 1}, - {"write", (PyCFunction) mmap_write_method, 1}, - {"write_byte",(PyCFunction) mmap_write_byte_method, 1}, - {NULL, NULL} /* sentinel */ + {"close", (PyCFunction) mmap_close_method, 1}, + {"find", (PyCFunction) mmap_find_method, 1}, + {"flush", (PyCFunction) mmap_flush_method, 1}, + {"move", (PyCFunction) mmap_move_method, 1}, + {"read", (PyCFunction) mmap_read_method, 1}, + {"read_byte", (PyCFunction) mmap_read_byte_method, 1}, + {"readline", (PyCFunction) mmap_read_line_method, 1}, + {"resize", (PyCFunction) mmap_resize_method, 1}, + {"seek", (PyCFunction) mmap_seek_method, 1}, + {"size", (PyCFunction) mmap_size_method, 1}, + {"tell", (PyCFunction) mmap_tell_method, 1}, + {"write", (PyCFunction) mmap_write_method, 1}, + {"write_byte", (PyCFunction) mmap_write_byte_method, 1}, + {NULL, NULL} /* sentinel */ }; /* Functions for treating an mmap'ed file as a buffer */ static int mmap_buffer_getreadbuf(self, index, ptr) - mmap_object *self; + mmap_object *self; int index; const void **ptr; { - CHECK_VALID(-1); - if ( index != 0 ) { - PyErr_SetString(PyExc_SystemError, "Accessing non-existent mmap segment"); - return -1; - } - *ptr = self->data; - return self->size; + CHECK_VALID(-1); + if ( index != 0 ) { + PyErr_SetString(PyExc_SystemError, + "Accessing non-existent mmap segment"); + return -1; + } + *ptr = self->data; + return self->size; } static int mmap_buffer_getwritebuf(self, index, ptr) - mmap_object *self; -int index; -const void **ptr; + mmap_object *self; + int index; + const void **ptr; { - CHECK_VALID(-1); - if ( index != 0 ) { - PyErr_SetString(PyExc_SystemError, "Accessing non-existent mmap segment"); - return -1; - } - *ptr = self->data; - return self->size; + CHECK_VALID(-1); + if ( index != 0 ) { + PyErr_SetString(PyExc_SystemError, + "Accessing non-existent mmap segment"); + return -1; + } + *ptr = self->data; + return self->size; } static int mmap_buffer_getsegcount(self, lenp) - mmap_object *self; -int *lenp; + mmap_object *self; + int *lenp; { - CHECK_VALID(-1); - if (lenp) - *lenp = self->size; - return 1; + CHECK_VALID(-1); + if (lenp) + *lenp = self->size; + return 1; } static int mmap_buffer_getcharbuffer(self, index, ptr) - mmap_object *self; -int index; -const void **ptr; + mmap_object *self; + int index; + const void **ptr; { - if ( index != 0 ) { - PyErr_SetString(PyExc_SystemError, - "accessing non-existent buffer segment"); - return -1; - } - *ptr = (const char *)self->data; - return self->size; + if ( index != 0 ) { + PyErr_SetString(PyExc_SystemError, + "accessing non-existent buffer segment"); + return -1; + } + *ptr = (const char *)self->data; + return self->size; } static PyObject * mmap_object_getattr(mmap_object * self, char * name) { - return Py_FindMethod (mmap_object_methods, (PyObject *)self, name); + return Py_FindMethod (mmap_object_methods, (PyObject *)self, name); } static int mmap_length(self) - mmap_object *self; + mmap_object *self; { - CHECK_VALID(-1); - return self->size; + CHECK_VALID(-1); + return self->size; } static PyObject * mmap_item(self, i) - mmap_object *self; -int i; + mmap_object *self; + int i; { - CHECK_VALID(NULL); - if (i < 0 || i >= self->size) { - PyErr_SetString(PyExc_IndexError, "mmap index out of range"); - return NULL; - } - return PyString_FromStringAndSize(self->data + i, 1); + CHECK_VALID(NULL); + if (i < 0 || i >= self->size) { + PyErr_SetString(PyExc_IndexError, "mmap index out of range"); + return NULL; + } + return PyString_FromStringAndSize(self->data + i, 1); } static PyObject * mmap_slice(self, ilow, ihigh) - mmap_object *self; -int ilow, ihigh; + mmap_object *self; + int ilow, ihigh; { - CHECK_VALID(NULL); - if (ilow < 0) - ilow = 0; - else if (ilow > self->size) - ilow = self->size; - if (ihigh < 0) - ihigh = 0; - if (ihigh < ilow) - ihigh = ilow; - else if (ihigh > self->size) - ihigh = self->size; - - return PyString_FromStringAndSize(self->data + ilow, ihigh-ilow); + CHECK_VALID(NULL); + if (ilow < 0) + ilow = 0; + else if (ilow > self->size) + ilow = self->size; + if (ihigh < 0) + ihigh = 0; + if (ihigh < ilow) + ihigh = ilow; + else if (ihigh > self->size) + ihigh = self->size; + + return PyString_FromStringAndSize(self->data + ilow, ihigh-ilow); } static PyObject * mmap_concat(self, bb) - mmap_object *self; -PyObject *bb; + mmap_object *self; + PyObject *bb; { - CHECK_VALID(NULL); - PyErr_SetString(PyExc_SystemError, "mmaps don't support concatenation"); - return NULL; + CHECK_VALID(NULL); + PyErr_SetString(PyExc_SystemError, + "mmaps don't support concatenation"); + return NULL; } static PyObject * mmap_repeat(self, n) - mmap_object *self; -int n; + mmap_object *self; + int n; { - CHECK_VALID(NULL); - PyErr_SetString(PyExc_SystemError, "mmaps don't support repeat operation"); - return NULL; + CHECK_VALID(NULL); + PyErr_SetString(PyExc_SystemError, + "mmaps don't support repeat operation"); + return NULL; } static int mmap_ass_slice(self, ilow, ihigh, v) - mmap_object *self; -int ilow, ihigh; -PyObject *v; + mmap_object *self; + int ilow, ihigh; + PyObject *v; { - unsigned char *buf; + unsigned char *buf; - CHECK_VALID(-1); - if (ilow < 0) - ilow = 0; - else if (ilow > self->size) - ilow = self->size; - if (ihigh < 0) - ihigh = 0; - if (ihigh < ilow) - ihigh = ilow; - else if (ihigh > self->size) - ihigh = self->size; - - if (! (PyString_Check(v)) ) { - PyErr_SetString(PyExc_IndexError, - "mmap slice assignment must be a string"); - return -1; - } - if ( PyString_Size(v) != (ihigh - ilow) ) { - PyErr_SetString(PyExc_IndexError, - "mmap slice assignment is wrong size"); - return -1; - } - buf = PyString_AsString(v); - memcpy(self->data + ilow, buf, ihigh-ilow); - return 0; + CHECK_VALID(-1); + if (ilow < 0) + ilow = 0; + else if (ilow > self->size) + ilow = self->size; + if (ihigh < 0) + ihigh = 0; + if (ihigh < ilow) + ihigh = ilow; + else if (ihigh > self->size) + ihigh = self->size; + + if (! (PyString_Check(v)) ) { + PyErr_SetString(PyExc_IndexError, + "mmap slice assignment must be a string"); + return -1; + } + if ( PyString_Size(v) != (ihigh - ilow) ) { + PyErr_SetString(PyExc_IndexError, + "mmap slice assignment is wrong size"); + return -1; + } + buf = PyString_AsString(v); + memcpy(self->data + ilow, buf, ihigh-ilow); + return 0; } static int mmap_ass_item(self, i, v) - mmap_object *self; -int i; -PyObject *v; + mmap_object *self; + int i; + PyObject *v; { - unsigned char *buf; + unsigned char *buf; - CHECK_VALID(-1); - if (i < 0 || i >= self->size) { - PyErr_SetString(PyExc_IndexError, "mmap index out of range"); - return -1; - } - if (! (PyString_Check(v) && PyString_Size(v)==1) ) { - PyErr_SetString(PyExc_IndexError, - "mmap assignment must be single-character string"); - return -1; - } - buf = PyString_AsString(v); - self->data[i] = buf[0]; - return 0; + CHECK_VALID(-1); + if (i < 0 || i >= self->size) { + PyErr_SetString(PyExc_IndexError, "mmap index out of range"); + return -1; + } + if (! (PyString_Check(v) && PyString_Size(v)==1) ) { + PyErr_SetString(PyExc_IndexError, + "mmap assignment must be single-character string"); + return -1; + } + buf = PyString_AsString(v); + self->data[i] = buf[0]; + return 0; } static PySequenceMethods mmap_as_sequence = { - (inquiry)mmap_length, /*sq_length*/ - (binaryfunc)mmap_concat, /*sq_concat*/ - (intargfunc)mmap_repeat, /*sq_repeat*/ - (intargfunc)mmap_item, /*sq_item*/ - (intintargfunc)mmap_slice, /*sq_slice*/ - (intobjargproc)mmap_ass_item, /*sq_ass_item*/ - (intintobjargproc)mmap_ass_slice, /*sq_ass_slice*/ + (inquiry)mmap_length, /*sq_length*/ + (binaryfunc)mmap_concat, /*sq_concat*/ + (intargfunc)mmap_repeat, /*sq_repeat*/ + (intargfunc)mmap_item, /*sq_item*/ + (intintargfunc)mmap_slice, /*sq_slice*/ + (intobjargproc)mmap_ass_item, /*sq_ass_item*/ + (intintobjargproc)mmap_ass_slice, /*sq_ass_slice*/ }; static PyBufferProcs mmap_as_buffer = { - (getreadbufferproc)mmap_buffer_getreadbuf, - (getwritebufferproc)mmap_buffer_getwritebuf, - (getsegcountproc)mmap_buffer_getsegcount, - (getcharbufferproc)mmap_buffer_getcharbuffer, + (getreadbufferproc)mmap_buffer_getreadbuf, + (getwritebufferproc)mmap_buffer_getwritebuf, + (getsegcountproc)mmap_buffer_getsegcount, + (getcharbufferproc)mmap_buffer_getcharbuffer, }; static PyTypeObject mmap_object_type = { - PyObject_HEAD_INIT(&PyType_Type) - 0, /* ob_size */ - "mmap", /* tp_name */ - sizeof(mmap_object), /* tp_size */ - 0, /* tp_itemsize */ - /* methods */ - (destructor) mmap_object_dealloc, /* tp_dealloc */ - 0, /* tp_print */ - (getattrfunc) mmap_object_getattr,/* tp_getattr */ - 0, /* tp_setattr */ - 0, /* tp_compare */ - 0, /* tp_repr */ - 0, /* tp_as_number */ - &mmap_as_sequence, /*tp_as_sequence*/ - 0, /*tp_as_mapping*/ - 0, /*tp_hash*/ - 0, /*tp_call*/ - 0, /*tp_str*/ - 0, /*tp_getattro*/ - 0, /*tp_setattro*/ - &mmap_as_buffer, /*tp_as_buffer*/ - Py_TPFLAGS_HAVE_GETCHARBUFFER, /*tp_flags*/ - 0, /*tp_doc*/ + PyObject_HEAD_INIT(0) /* patched in module init */ + 0, /* ob_size */ + "mmap", /* tp_name */ + sizeof(mmap_object), /* tp_size */ + 0, /* tp_itemsize */ + /* methods */ + (destructor) mmap_object_dealloc, /* tp_dealloc */ + 0, /* tp_print */ + (getattrfunc) mmap_object_getattr, /* tp_getattr */ + 0, /* tp_setattr */ + 0, /* tp_compare */ + 0, /* tp_repr */ + 0, /* tp_as_number */ + &mmap_as_sequence, /*tp_as_sequence*/ + 0, /*tp_as_mapping*/ + 0, /*tp_hash*/ + 0, /*tp_call*/ + 0, /*tp_str*/ + 0, /*tp_getattro*/ + 0, /*tp_setattro*/ + &mmap_as_buffer, /*tp_as_buffer*/ + Py_TPFLAGS_HAVE_GETCHARBUFFER, /*tp_flags*/ + 0, /*tp_doc*/ }; #ifdef UNIX static PyObject * new_mmap_object (PyObject * self, PyObject * args, PyObject *kwdict) { - mmap_object * m_obj; - unsigned long map_size; - int fd, flags = MAP_SHARED, prot = PROT_WRITE | PROT_READ; - char * filename; - int namelen; - char *keywords[] = {"file", "size", "flags", "prot", NULL}; + mmap_object * m_obj; + unsigned long map_size; + int fd, flags = MAP_SHARED, prot = PROT_WRITE | PROT_READ; + char * filename; + int namelen; + char *keywords[] = {"file", "size", "flags", "prot", NULL}; - if (!PyArg_ParseTupleAndKeywords(args, kwdict, - "il|ii", keywords, - &fd, &map_size, &flags, &prot) - ) - return NULL; + if (!PyArg_ParseTupleAndKeywords(args, kwdict, + "il|ii", keywords, + &fd, &map_size, &flags, &prot) + ) + return NULL; - m_obj = PyObject_NEW (mmap_object, &mmap_object_type); - if (m_obj == NULL) {return NULL;} - m_obj->size = (size_t) map_size; - m_obj->pos = (size_t) 0; - m_obj->data = mmap(NULL, map_size, - prot, flags, - fd, 0); - if (m_obj->data == (void *)-1) - { - Py_DECREF(m_obj); - PyErr_SetFromErrno(mmap_module_error); - return NULL; - } - return (PyObject *)m_obj; + m_obj = PyObject_NEW (mmap_object, &mmap_object_type); + if (m_obj == NULL) {return NULL;} + m_obj->size = (size_t) map_size; + m_obj->pos = (size_t) 0; + m_obj->data = mmap(NULL, map_size, + prot, flags, + fd, 0); + if (m_obj->data == (void *)-1) + { + Py_DECREF(m_obj); + PyErr_SetFromErrno(mmap_module_error); + return NULL; + } + return (PyObject *)m_obj; } #endif /* UNIX */ @@ -711,93 +726,95 @@ new_mmap_object (PyObject * self, PyObject * args, PyObject *kwdict) static PyObject * new_mmap_object (PyObject * self, PyObject * args) { - mmap_object * m_obj; - unsigned long map_size; - char * filename; - int namelen; - char * tagname; + mmap_object * m_obj; + unsigned long map_size; + char * filename; + int namelen; + char * tagname = ""; - char complaint[256]; - HFILE fh = 0; - OFSTRUCT file_info; + DWORD dwErr = 0; + int fileno; + HFILE fh = 0; + OFSTRUCT file_info; - if (!PyArg_Parse (args, - "(s#zl)", - &filename, - &namelen, - &tagname, - &map_size) - ) - return NULL; + /* Patch the object type */ + mmap_object_type.ob_type = &PyType_Type; + + if (!PyArg_ParseTuple(args, + "il|z", + &fileno, + &map_size, + &tagname) + ) + return NULL; - /* if an actual filename has been specified */ - if (namelen != 0) { - fh = OpenFile (filename, &file_info, OF_READWRITE); - if (fh == HFILE_ERROR) { - sprintf (complaint, "OpenFile failed: %ld", GetLastError()); - PyErr_SetString(mmap_module_error, complaint); - return NULL; - } + /* if an actual filename has been specified */ + if (fileno != 0) { + fh = _get_osfhandle(fileno); + if (fh==-1) { + PyErr_SetFromErrno(mmap_module_error); + return NULL; } +// +// fh = OpenFile (filename, &file_info, OF_READWRITE); +// if (fh == HFILE_ERROR) { +// PyErr_SetFromWindowsErr(GetLastError()); +// return NULL; +// } + } - m_obj = PyObject_NEW (mmap_object, &mmap_object_type); - - if (fh) { - m_obj->file_handle = fh; - if (!map_size) { - m_obj->size = GetFileSize ((HANDLE)fh, NULL); - } else { - m_obj->size = map_size; - } - } - else { - m_obj->file_handle = (HFILE) 0xFFFFFFFF; - m_obj->size = map_size; - } - - /* set the initial position */ - m_obj->pos = (size_t) 0; - - m_obj->map_handle = CreateFileMapping ((HANDLE) m_obj->file_handle, - NULL, - PAGE_READWRITE, - 0, - m_obj->size, - tagname); - if (m_obj->map_handle != NULL) { - m_obj->data = (char *) MapViewOfFile (m_obj->map_handle, - FILE_MAP_WRITE, - 0, - 0, - 0); - if (m_obj->data != NULL) { - return ((PyObject *) m_obj); - } else { - sprintf (complaint, "MapViewOfFile failed: %ld", GetLastError()); - } + m_obj = PyObject_NEW (mmap_object, &mmap_object_type); + + if (fh) { + m_obj->file_handle = fh; + if (!map_size) { + m_obj->size = GetFileSize ((HANDLE)fh, NULL); } else { - sprintf (complaint, "CreateFileMapping failed: %ld", GetLastError()); + m_obj->size = map_size; } - PyErr_SetString (mmap_module_error, complaint); - return (NULL); + } + else { + m_obj->file_handle = (HFILE) 0xFFFFFFFF; + m_obj->size = map_size; + } + + /* set the initial position */ + m_obj->pos = (size_t) 0; + + m_obj->map_handle = CreateFileMapping ((HANDLE) m_obj->file_handle, + NULL, + PAGE_READWRITE, + 0, + m_obj->size, + tagname); + if (m_obj->map_handle != NULL) { + m_obj->data = (char *) MapViewOfFile (m_obj->map_handle, + FILE_MAP_WRITE, + 0, + 0, + 0); + if (m_obj->data != NULL) { + return ((PyObject *) m_obj); + } else { + dwErr = GetLastError(); + } + } else { + dwErr = GetLastError(); + } + PyErr_SetFromWindowsErr(dwErr); + return (NULL); } #endif /* MS_WIN32 */ /* List of functions exported by this module */ static struct PyMethodDef mmap_functions[] = { -#ifdef MS_WIN32 - {"mmap", (PyCFunction) new_mmap_object}, -#endif /* MS_WIN32 */ - -#ifdef UNIX - {"mmap", (PyCFunction) new_mmap_object, - METH_VARARGS|METH_KEYWORDS}, -#endif /* UNIX */ - {NULL, NULL} /* Sentinel */ + {"mmap", (PyCFunction) new_mmap_object, + METH_VARARGS|METH_KEYWORDS}, + {NULL, NULL} /* Sentinel */ }; #ifdef MS_WIN32 -extern"C" __declspec(dllexport) void +__declspec(dllexport) void #endif /* MS_WIN32 */ #ifdef UNIX extern void @@ -805,44 +822,54 @@ extern void initmmap(void) { - PyObject *dict, *module; - module = Py_InitModule ("mmap", mmap_functions); - dict = PyModule_GetDict (module); - mmap_module_error = PyString_FromString ("mmap error"); - PyDict_SetItemString (dict, "error", mmap_module_error); - + PyObject *dict, *module; + module = Py_InitModule ("mmap", mmap_functions); + dict = PyModule_GetDict (module); + mmap_module_error = PyExc_EnvironmentError; + Py_INCREF(mmap_module_error); + PyDict_SetItemString (dict, "error", mmap_module_error); #ifdef PROT_EXEC - PyDict_SetItemString (dict, "PROT_EXEC", PyInt_FromLong(PROT_EXEC) ); + PyDict_SetItemString (dict, "PROT_EXEC", PyInt_FromLong(PROT_EXEC) ); #endif #ifdef PROT_READ - PyDict_SetItemString (dict, "PROT_READ", PyInt_FromLong(PROT_READ) ); + PyDict_SetItemString (dict, "PROT_READ", PyInt_FromLong(PROT_READ) ); #endif #ifdef PROT_WRITE - PyDict_SetItemString (dict, "PROT_WRITE", PyInt_FromLong(PROT_WRITE) ); + PyDict_SetItemString (dict, "PROT_WRITE", PyInt_FromLong(PROT_WRITE) ); #endif #ifdef MAP_SHARED - PyDict_SetItemString (dict, "MAP_SHARED", PyInt_FromLong(MAP_SHARED) ); + PyDict_SetItemString (dict, "MAP_SHARED", PyInt_FromLong(MAP_SHARED) ); #endif #ifdef MAP_PRIVATE - PyDict_SetItemString (dict, "MAP_PRIVATE", PyInt_FromLong(MAP_PRIVATE) ); + PyDict_SetItemString (dict, "MAP_PRIVATE", + PyInt_FromLong(MAP_PRIVATE) ); #endif #ifdef MAP_DENYWRITE - PyDict_SetItemString (dict, "MAP_DENYWRITE", PyInt_FromLong(MAP_DENYWRITE) ); + PyDict_SetItemString (dict, "MAP_DENYWRITE", + PyInt_FromLong(MAP_DENYWRITE) ); #endif #ifdef MAP_EXECUTABLE - PyDict_SetItemString (dict, "MAP_EXECUTABLE", PyInt_FromLong(MAP_EXECUTABLE) ); + PyDict_SetItemString (dict, "MAP_EXECUTABLE", + PyInt_FromLong(MAP_EXECUTABLE) ); #endif #ifdef MAP_ANON - PyDict_SetItemString (dict, "MAP_ANON", PyInt_FromLong(MAP_ANON) ); - PyDict_SetItemString (dict, "MAP_ANONYMOUS", PyInt_FromLong(MAP_ANON) ); + PyDict_SetItemString (dict, "MAP_ANON", PyInt_FromLong(MAP_ANON) ); + PyDict_SetItemString (dict, "MAP_ANONYMOUS", + PyInt_FromLong(MAP_ANON) ); #endif #ifdef UNIX - PyDict_SetItemString (dict, "PAGESIZE", PyInt_FromLong( (long)getpagesize() ) ); + PyDict_SetItemString (dict, "PAGESIZE", + PyInt_FromLong( (long)getpagesize() ) ); #endif +#ifdef MS_WIN32 + { + SYSTEM_INFO si; + GetSystemInfo(&si); + PyDict_SetItemString (dict, "PAGESIZE", + PyInt_FromLong( si.dwPageSize ) ); + } +#endif /* MS_WIN32 */ } - - -