blob: 8cd993e40f8a2fcb2bb79e0e48972647f8b95a16 [file] [log] [blame]
Guido van Rossum09fdf072000-03-31 01:17:07 +00001/*
2 / Author: Sam Rushing <rushing@nightmare.com>
Andrew M. Kuchling1ed7d2d2000-03-30 21:14:30 +00003 / Hacked for Unix by A.M. Kuchling <amk1@bigfoot.com>
Guido van Rossum09fdf072000-03-31 01:17:07 +00004 / $Id$
Andrew M. Kuchling1ed7d2d2000-03-30 21:14:30 +00005
6 / mmapmodule.cpp -- map a view of a file into memory
7 /
8 / todo: need permission flags, perhaps a 'chsize' analog
9 / not all functions check range yet!!!
10 /
11 /
12 / Note: This module currently only deals with 32-bit file
13 / sizes.
14 /
15 / The latest version of mmapfile is maintained by Sam at
16 / ftp://squirl.nightmare.com/pub/python/python-ext.
17*/
18
Andrew M. Kuchlingea34a842000-06-18 19:06:49 +000019#ifdef __linux__
20#define _GNU_SOURCE /* So we can get MREMAP_MAYMOVE defined when
21 sys/mman.h is included */
22#endif
23
Guido van Rossum09fdf072000-03-31 01:17:07 +000024#include <Python.h>
25
Andrew M. Kuchling1ed7d2d2000-03-30 21:14:30 +000026#ifndef MS_WIN32
27#define UNIX
28#endif
29
30#ifdef MS_WIN32
31#include <windows.h>
32#endif
33
34#ifdef UNIX
35#include <unistd.h>
36#include <sys/mman.h>
Andrew M. Kuchling7b9fb922000-06-17 22:41:22 +000037#include <sys/stat.h>
Andrew M. Kuchling1ed7d2d2000-03-30 21:14:30 +000038#endif
39
Andrew M. Kuchling1ed7d2d2000-03-30 21:14:30 +000040#include <string.h>
41#include <sys/types.h>
42
43static PyObject *mmap_module_error;
44
45typedef struct {
Guido van Rossum09fdf072000-03-31 01:17:07 +000046 PyObject_HEAD
47 char * data;
48 size_t size;
49 size_t pos;
Andrew M. Kuchling1ed7d2d2000-03-30 21:14:30 +000050
51#ifdef MS_WIN32
Guido van Rossum09fdf072000-03-31 01:17:07 +000052 HANDLE map_handle;
Andrew M. Kuchling70d27422000-06-18 04:45:14 +000053 INT_PTR file_handle;
Guido van Rossum09fdf072000-03-31 01:17:07 +000054 char * tagname;
Andrew M. Kuchling1ed7d2d2000-03-30 21:14:30 +000055#endif
56
57#ifdef UNIX
Andrew M. Kuchling7b9fb922000-06-17 22:41:22 +000058 int fd;
Andrew M. Kuchling1ed7d2d2000-03-30 21:14:30 +000059#endif
60} mmap_object;
61
62static void
63mmap_object_dealloc(mmap_object * m_obj)
64{
65#ifdef MS_WIN32
Guido van Rossum09fdf072000-03-31 01:17:07 +000066 UnmapViewOfFile (m_obj->data);
67 CloseHandle (m_obj->map_handle);
68 CloseHandle ((HANDLE)m_obj->file_handle);
Andrew M. Kuchling1ed7d2d2000-03-30 21:14:30 +000069#endif /* MS_WIN32 */
70
71#ifdef UNIX
Guido van Rossum09fdf072000-03-31 01:17:07 +000072 if (m_obj->data!=NULL) {
Andrew M. Kuchling9bc5f332000-06-18 04:25:08 +000073 msync(m_obj->data, m_obj->size, MS_SYNC);
Guido van Rossum09fdf072000-03-31 01:17:07 +000074 munmap(m_obj->data, m_obj->size);
75 }
Andrew M. Kuchling1ed7d2d2000-03-30 21:14:30 +000076#endif /* UNIX */
77
Guido van Rossumb18618d2000-05-03 23:44:39 +000078 PyObject_Del(m_obj);
Andrew M. Kuchling1ed7d2d2000-03-30 21:14:30 +000079}
80
81static PyObject *
82mmap_close_method (mmap_object * self, PyObject * args)
83{
Andrew M. Kuchling841b9fb2000-06-03 20:43:43 +000084 if (!PyArg_ParseTuple(args, ":close"))
Andrew M. Kuchling961fe172000-06-03 19:41:42 +000085 return NULL;
Andrew M. Kuchling1ed7d2d2000-03-30 21:14:30 +000086#ifdef MS_WIN32
Guido van Rossum09fdf072000-03-31 01:17:07 +000087 UnmapViewOfFile (self->data);
88 CloseHandle (self->map_handle);
89 CloseHandle ((HANDLE)self->file_handle);
90 self->map_handle = (HANDLE) NULL;
Andrew M. Kuchling1ed7d2d2000-03-30 21:14:30 +000091#endif /* MS_WIN32 */
92
93#ifdef UNIX
Guido van Rossum09fdf072000-03-31 01:17:07 +000094 munmap(self->data, self->size);
95 self->data = NULL;
Andrew M. Kuchling1ed7d2d2000-03-30 21:14:30 +000096#endif
97
Guido van Rossum09fdf072000-03-31 01:17:07 +000098 Py_INCREF (Py_None);
99 return (Py_None);
Andrew M. Kuchling1ed7d2d2000-03-30 21:14:30 +0000100}
101
102#ifdef MS_WIN32
Guido van Rossum09fdf072000-03-31 01:17:07 +0000103#define CHECK_VALID(err) \
104do { \
105 if (!self->map_handle) { \
106 PyErr_SetString (PyExc_ValueError, "mmap closed or invalid"); \
107 return err; \
108 } \
Andrew M. Kuchling1ed7d2d2000-03-30 21:14:30 +0000109} while (0)
110#endif /* MS_WIN32 */
111
112#ifdef UNIX
Guido van Rossum09fdf072000-03-31 01:17:07 +0000113#define CHECK_VALID(err) \
114do { \
115 if (self->data == NULL) { \
116 PyErr_SetString (PyExc_ValueError, "mmap closed or invalid"); \
117 return err; \
118 } \
Andrew M. Kuchling1ed7d2d2000-03-30 21:14:30 +0000119} while (0)
120#endif /* UNIX */
121
122static PyObject *
123mmap_read_byte_method (mmap_object * self,
Guido van Rossum09fdf072000-03-31 01:17:07 +0000124 PyObject * args)
Andrew M. Kuchling1ed7d2d2000-03-30 21:14:30 +0000125{
Guido van Rossum09fdf072000-03-31 01:17:07 +0000126 char value;
Guido van Rossum36d4f8b2000-04-10 21:34:37 +0000127 char * where;
Guido van Rossum09fdf072000-03-31 01:17:07 +0000128 CHECK_VALID(NULL);
Andrew M. Kuchling841b9fb2000-06-03 20:43:43 +0000129 if (!PyArg_ParseTuple(args, ":read_byte"))
Andrew M. Kuchling961fe172000-06-03 19:41:42 +0000130 return NULL;
Andrew M. Kuchling70d27422000-06-18 04:45:14 +0000131 if (self->pos < self->size) {
Guido van Rossum36d4f8b2000-04-10 21:34:37 +0000132 where = self->data + self->pos;
Guido van Rossum09fdf072000-03-31 01:17:07 +0000133 value = (char) *(where);
134 self->pos += 1;
135 return Py_BuildValue("c", (char) *(where));
136 } else {
137 PyErr_SetString (PyExc_ValueError, "read byte out of range");
138 return NULL;
139 }
Andrew M. Kuchling1ed7d2d2000-03-30 21:14:30 +0000140}
141
142static PyObject *
143mmap_read_line_method (mmap_object * self,
Andrew M. Kuchling961fe172000-06-03 19:41:42 +0000144 PyObject * args)
Andrew M. Kuchling1ed7d2d2000-03-30 21:14:30 +0000145{
Fred Drake56a87a02000-04-04 18:17:35 +0000146 char * start = self->data+self->pos;
Guido van Rossum09fdf072000-03-31 01:17:07 +0000147 char * eof = self->data+self->size;
148 char * eol;
149 PyObject * result;
Andrew M. Kuchling1ed7d2d2000-03-30 21:14:30 +0000150
Guido van Rossum09fdf072000-03-31 01:17:07 +0000151 CHECK_VALID(NULL);
Andrew M. Kuchling841b9fb2000-06-03 20:43:43 +0000152 if (!PyArg_ParseTuple(args, ":readline"))
Andrew M. Kuchling961fe172000-06-03 19:41:42 +0000153 return NULL;
Andrew M. Kuchling1ed7d2d2000-03-30 21:14:30 +0000154
Fred Drake56a87a02000-04-04 18:17:35 +0000155 eol = memchr(start, '\n', self->size - self->pos);
156 if (!eol)
157 eol = eof;
158 else
159 ++eol; /* we're interested in the position after the
160 newline. */
Andrew M. Kuchling70d27422000-06-18 04:45:14 +0000161 result = PyString_FromStringAndSize(start, (eol - start));
Guido van Rossum09fdf072000-03-31 01:17:07 +0000162 self->pos += (eol - start);
163 return (result);
Andrew M. Kuchling1ed7d2d2000-03-30 21:14:30 +0000164}
165
166static PyObject *
167mmap_read_method (mmap_object * self,
Andrew M. Kuchling961fe172000-06-03 19:41:42 +0000168 PyObject * args)
Andrew M. Kuchling1ed7d2d2000-03-30 21:14:30 +0000169{
Guido van Rossum09fdf072000-03-31 01:17:07 +0000170 long num_bytes;
171 PyObject *result;
Andrew M. Kuchling1ed7d2d2000-03-30 21:14:30 +0000172
Guido van Rossum09fdf072000-03-31 01:17:07 +0000173 CHECK_VALID(NULL);
174 if (!PyArg_ParseTuple (args, "l", &num_bytes))
175 return(NULL);
Andrew M. Kuchling1ed7d2d2000-03-30 21:14:30 +0000176
Guido van Rossum09fdf072000-03-31 01:17:07 +0000177 /* silently 'adjust' out-of-range requests */
178 if ((self->pos + num_bytes) > self->size) {
179 num_bytes -= (self->pos+num_bytes) - self->size;
180 }
181 result = Py_BuildValue("s#", self->data+self->pos, num_bytes);
182 self->pos += num_bytes;
183 return (result);
Andrew M. Kuchling1ed7d2d2000-03-30 21:14:30 +0000184}
185
186static PyObject *
187mmap_find_method (mmap_object *self,
Guido van Rossum09fdf072000-03-31 01:17:07 +0000188 PyObject *args)
Andrew M. Kuchling1ed7d2d2000-03-30 21:14:30 +0000189{
Andrew M. Kuchling70d27422000-06-18 04:45:14 +0000190 int start = self->pos;
Guido van Rossum09fdf072000-03-31 01:17:07 +0000191 char * needle;
192 int len;
Andrew M. Kuchling1ed7d2d2000-03-30 21:14:30 +0000193
Guido van Rossum09fdf072000-03-31 01:17:07 +0000194 CHECK_VALID(NULL);
Andrew M. Kuchling70d27422000-06-18 04:45:14 +0000195 if (!PyArg_ParseTuple (args, "s#|i", &needle, &len, &start)) {
Guido van Rossum09fdf072000-03-31 01:17:07 +0000196 return NULL;
197 } else {
198 char * p = self->data+self->pos;
199 char * e = self->data+self->size;
200 while (p < e) {
201 char * s = p;
202 char * n = needle;
203 while ((s<e) && (*n) && !(*s-*n)) {
204 s++, n++;
205 }
206 if (!*n) {
207 return Py_BuildValue (
Andrew M. Kuchling70d27422000-06-18 04:45:14 +0000208 "i",
209 (int) (p - (self->data + start)));
Guido van Rossum09fdf072000-03-31 01:17:07 +0000210 }
211 p++;
Andrew M. Kuchling1ed7d2d2000-03-30 21:14:30 +0000212 }
Guido van Rossum09fdf072000-03-31 01:17:07 +0000213 return Py_BuildValue ("l", (long) -1);
214 }
Andrew M. Kuchling1ed7d2d2000-03-30 21:14:30 +0000215}
216
217static PyObject *
218mmap_write_method (mmap_object * self,
Andrew M. Kuchling7b9fb922000-06-17 22:41:22 +0000219 PyObject * args)
Andrew M. Kuchling1ed7d2d2000-03-30 21:14:30 +0000220{
Guido van Rossum09fdf072000-03-31 01:17:07 +0000221 long length;
222 char * data;
Andrew M. Kuchling1ed7d2d2000-03-30 21:14:30 +0000223
Guido van Rossum09fdf072000-03-31 01:17:07 +0000224 CHECK_VALID(NULL);
225 if (!PyArg_ParseTuple (args, "s#", &data, &length))
226 return(NULL);
Andrew M. Kuchling1ed7d2d2000-03-30 21:14:30 +0000227
Guido van Rossum09fdf072000-03-31 01:17:07 +0000228 if ((self->pos + length) > self->size) {
229 PyErr_SetString (PyExc_ValueError, "data out of range");
230 return NULL;
231 }
232 memcpy (self->data+self->pos, data, length);
233 self->pos = self->pos+length;
234 Py_INCREF (Py_None);
235 return (Py_None);
Andrew M. Kuchling1ed7d2d2000-03-30 21:14:30 +0000236}
237
238static PyObject *
239mmap_write_byte_method (mmap_object * self,
Andrew M. Kuchling961fe172000-06-03 19:41:42 +0000240 PyObject * args)
Andrew M. Kuchling1ed7d2d2000-03-30 21:14:30 +0000241{
Guido van Rossum09fdf072000-03-31 01:17:07 +0000242 char value;
Andrew M. Kuchling1ed7d2d2000-03-30 21:14:30 +0000243
Guido van Rossum09fdf072000-03-31 01:17:07 +0000244 CHECK_VALID(NULL);
245 if (!PyArg_ParseTuple (args, "c", &value))
246 return(NULL);
Andrew M. Kuchling1ed7d2d2000-03-30 21:14:30 +0000247
Guido van Rossum09fdf072000-03-31 01:17:07 +0000248 *(self->data+self->pos) = value;
249 self->pos += 1;
250 Py_INCREF (Py_None);
251 return (Py_None);
Andrew M. Kuchling1ed7d2d2000-03-30 21:14:30 +0000252}
253
254static PyObject *
255mmap_size_method (mmap_object * self,
Andrew M. Kuchling961fe172000-06-03 19:41:42 +0000256 PyObject * args)
Andrew M. Kuchling1ed7d2d2000-03-30 21:14:30 +0000257{
Guido van Rossum09fdf072000-03-31 01:17:07 +0000258 CHECK_VALID(NULL);
Andrew M. Kuchling841b9fb2000-06-03 20:43:43 +0000259 if (!PyArg_ParseTuple(args, ":size"))
Andrew M. Kuchling961fe172000-06-03 19:41:42 +0000260 return NULL;
Andrew M. Kuchling1ed7d2d2000-03-30 21:14:30 +0000261
262#ifdef MS_WIN32
Andrew M. Kuchling70d27422000-06-18 04:45:14 +0000263 if (self->file_handle != (INT_PTR) -1) {
Guido van Rossum09fdf072000-03-31 01:17:07 +0000264 return (Py_BuildValue (
265 "l",
266 GetFileSize ((HANDLE)self->file_handle, NULL)));
267 } else {
268 return (Py_BuildValue ("l", self->size) );
269 }
Andrew M. Kuchling1ed7d2d2000-03-30 21:14:30 +0000270#endif /* MS_WIN32 */
271
272#ifdef UNIX
Andrew M. Kuchling7b9fb922000-06-17 22:41:22 +0000273 {
274 struct stat buf;
275 if (-1 == fstat(self->fd, &buf)) {
276 PyErr_SetFromErrno(mmap_module_error);
277 return NULL;
278 }
279 return (Py_BuildValue ("l", buf.st_size) );
280 }
Andrew M. Kuchling1ed7d2d2000-03-30 21:14:30 +0000281#endif /* UNIX */
282}
283
284/* This assumes that you want the entire file mapped,
285 / and when recreating the map will make the new file
286 / have the new size
287 /
288 / Is this really necessary? This could easily be done
289 / from python by just closing and re-opening with the
290 / new size?
291 */
292
293static PyObject *
294mmap_resize_method (mmap_object * self,
Guido van Rossum09fdf072000-03-31 01:17:07 +0000295 PyObject * args)
Andrew M. Kuchling1ed7d2d2000-03-30 21:14:30 +0000296{
Guido van Rossum09fdf072000-03-31 01:17:07 +0000297 unsigned long new_size;
298 CHECK_VALID(NULL);
299 if (!PyArg_ParseTuple (args, "l", &new_size)) {
300 return NULL;
Andrew M. Kuchling1ed7d2d2000-03-30 21:14:30 +0000301#ifdef MS_WIN32
Guido van Rossum09fdf072000-03-31 01:17:07 +0000302 } else {
303 DWORD dwErrCode = 0;
304 /* First, unmap the file view */
305 UnmapViewOfFile (self->data);
306 /* Close the mapping object */
307 CloseHandle ((HANDLE)self->map_handle);
308 /* Move to the desired EOF position */
309 SetFilePointer ((HANDLE)self->file_handle,
310 new_size, NULL, FILE_BEGIN);
311 /* Change the size of the file */
312 SetEndOfFile ((HANDLE)self->file_handle);
313 /* Create another mapping object and remap the file view */
314 self->map_handle = CreateFileMapping (
315 (HANDLE) self->file_handle,
316 NULL,
317 PAGE_READWRITE,
318 0,
319 new_size,
320 self->tagname);
321 if (self->map_handle != NULL) {
322 self->data = (char *) MapViewOfFile (self->map_handle,
323 FILE_MAP_WRITE,
324 0,
325 0,
326 0);
327 if (self->data != NULL) {
328 self->size = new_size;
329 Py_INCREF (Py_None);
330 return Py_None;
331 } else {
332 dwErrCode = GetLastError();
333 }
334 } else {
335 dwErrCode = GetLastError();
Andrew M. Kuchling1ed7d2d2000-03-30 21:14:30 +0000336 }
Guido van Rossum09fdf072000-03-31 01:17:07 +0000337 PyErr_SetFromWindowsErr(dwErrCode);
338 return (NULL);
Andrew M. Kuchling1ed7d2d2000-03-30 21:14:30 +0000339#endif /* MS_WIN32 */
340
341#ifdef UNIX
Andrew M. Kuchling6fef30e2000-06-18 14:51:21 +0000342#ifndef HAVE_MREMAP
Andrew M. Kuchling1ed7d2d2000-03-30 21:14:30 +0000343} else {
Guido van Rossum09fdf072000-03-31 01:17:07 +0000344 PyErr_SetString(PyExc_SystemError,
345 "mmap: resizing not available--no mremap()");
346 return NULL;
Andrew M. Kuchling1ed7d2d2000-03-30 21:14:30 +0000347#else
348} else {
Guido van Rossum09fdf072000-03-31 01:17:07 +0000349 void *newmap;
Andrew M. Kuchling1ed7d2d2000-03-30 21:14:30 +0000350
Andrew M. Kuchling6fef30e2000-06-18 14:51:21 +0000351#ifdef MREMAP_MAYMOVE
Guido van Rossum09fdf072000-03-31 01:17:07 +0000352 newmap = mremap(self->data, self->size, new_size, MREMAP_MAYMOVE);
Andrew M. Kuchling6fef30e2000-06-18 14:51:21 +0000353#else
354 newmap = mremap(self->data, self->size, new_size, 0);
355#endif
Guido van Rossum09fdf072000-03-31 01:17:07 +0000356 if (newmap == (void *)-1)
357 {
358 PyErr_SetFromErrno(mmap_module_error);
359 return NULL;
360 }
361 self->data = newmap;
362 self->size = new_size;
363 Py_INCREF(Py_None);
364 return Py_None;
Andrew M. Kuchling6fef30e2000-06-18 14:51:21 +0000365#endif /* HAVE_MREMAP */
Andrew M. Kuchling1ed7d2d2000-03-30 21:14:30 +0000366#endif /* UNIX */
367}
368}
369
370static PyObject *
371mmap_tell_method (mmap_object * self, PyObject * args)
372{
Guido van Rossum09fdf072000-03-31 01:17:07 +0000373 CHECK_VALID(NULL);
Andrew M. Kuchling841b9fb2000-06-03 20:43:43 +0000374 if (!PyArg_ParseTuple(args, ":tell"))
Andrew M. Kuchling961fe172000-06-03 19:41:42 +0000375 return NULL;
Guido van Rossum09fdf072000-03-31 01:17:07 +0000376 return (Py_BuildValue ("l", self->pos) );
Andrew M. Kuchling1ed7d2d2000-03-30 21:14:30 +0000377}
378
379static PyObject *
380mmap_flush_method (mmap_object * self, PyObject * args)
381{
Guido van Rossum09fdf072000-03-31 01:17:07 +0000382 size_t offset = 0;
383 size_t size = self->size;
384 CHECK_VALID(NULL);
385 if (!PyArg_ParseTuple (args, "|ll", &offset, &size)) {
386 return NULL;
387 } else if ((offset + size) > self->size) {
388 PyErr_SetString (PyExc_ValueError,
389 "flush values out of range");
390 return NULL;
391 } else {
Andrew M. Kuchling1ed7d2d2000-03-30 21:14:30 +0000392#ifdef MS_WIN32
Guido van Rossum09fdf072000-03-31 01:17:07 +0000393 return (Py_BuildValue (
394 "l", FlushViewOfFile (self->data+offset, size)));
Andrew M. Kuchling1ed7d2d2000-03-30 21:14:30 +0000395#endif /* MS_WIN32 */
396#ifdef UNIX
Guido van Rossum09fdf072000-03-31 01:17:07 +0000397 /* XXX semantics of return value? */
398 /* XXX flags for msync? */
399 if (-1 == msync(self->data + offset, size,
Andrew M. Kuchling9bc5f332000-06-18 04:25:08 +0000400 MS_SYNC))
Guido van Rossum09fdf072000-03-31 01:17:07 +0000401 {
402 PyErr_SetFromErrno(mmap_module_error);
403 return NULL;
Andrew M. Kuchling1ed7d2d2000-03-30 21:14:30 +0000404 }
Guido van Rossum09fdf072000-03-31 01:17:07 +0000405 return Py_BuildValue ("l", 0);
406#endif /* UNIX */
407 }
Andrew M. Kuchling1ed7d2d2000-03-30 21:14:30 +0000408}
409
410static PyObject *
411mmap_seek_method (mmap_object * self, PyObject * args)
412{
Andrew M. Kuchling70d27422000-06-18 04:45:14 +0000413 int dist;
Guido van Rossum09fdf072000-03-31 01:17:07 +0000414 int how=0;
415 CHECK_VALID(NULL);
Andrew M. Kuchling70d27422000-06-18 04:45:14 +0000416 if (!PyArg_ParseTuple (args, "i|i", &dist, &how)) {
Guido van Rossum09fdf072000-03-31 01:17:07 +0000417 return(NULL);
418 } else {
Andrew M. Kuchling70d27422000-06-18 04:45:14 +0000419 size_t where;
Guido van Rossum09fdf072000-03-31 01:17:07 +0000420 switch (how) {
Andrew M. Kuchling70d27422000-06-18 04:45:14 +0000421 case 0: /* relative to start */
422 if (dist < 0)
423 goto onoutofrange;
Guido van Rossum09fdf072000-03-31 01:17:07 +0000424 where = dist;
425 break;
Andrew M. Kuchling70d27422000-06-18 04:45:14 +0000426 case 1: /* relative to current position */
427 if ((int)self->pos + dist < 0)
428 goto onoutofrange;
Guido van Rossum09fdf072000-03-31 01:17:07 +0000429 where = self->pos + dist;
430 break;
Andrew M. Kuchling70d27422000-06-18 04:45:14 +0000431 case 2: /* relative to end */
432 if ((int)self->size + dist < 0)
433 goto onoutofrange;
434 where = self->size + dist;
Guido van Rossum09fdf072000-03-31 01:17:07 +0000435 break;
436 default:
437 PyErr_SetString (PyExc_ValueError,
438 "unknown seek type");
439 return NULL;
Andrew M. Kuchling1ed7d2d2000-03-30 21:14:30 +0000440 }
Andrew M. Kuchling70d27422000-06-18 04:45:14 +0000441 if (where > self->size)
442 goto onoutofrange;
443 self->pos = where;
444 Py_INCREF (Py_None);
445 return (Py_None);
Guido van Rossum09fdf072000-03-31 01:17:07 +0000446 }
Andrew M. Kuchling70d27422000-06-18 04:45:14 +0000447
448onoutofrange:
449 PyErr_SetString (PyExc_ValueError, "seek out of range");
450 return NULL;
Andrew M. Kuchling1ed7d2d2000-03-30 21:14:30 +0000451}
452
453static PyObject *
454mmap_move_method (mmap_object * self, PyObject * args)
455{
Guido van Rossum09fdf072000-03-31 01:17:07 +0000456 unsigned long dest, src, count;
457 CHECK_VALID(NULL);
458 if (!PyArg_ParseTuple (args, "iii", &dest, &src, &count)) {
459 return NULL;
460 } else {
461 /* bounds check the values */
462 if (/* end of source after end of data?? */
463 ((src+count) > self->size)
464 /* dest will fit? */
465 || (dest+count > self->size)) {
466 PyErr_SetString (PyExc_ValueError,
467 "source or destination out of range");
468 return NULL;
Andrew M. Kuchling1ed7d2d2000-03-30 21:14:30 +0000469 } else {
Guido van Rossum09fdf072000-03-31 01:17:07 +0000470 memmove (self->data+dest, self->data+src, count);
471 Py_INCREF (Py_None);
472 return Py_None;
Andrew M. Kuchling1ed7d2d2000-03-30 21:14:30 +0000473 }
Guido van Rossum09fdf072000-03-31 01:17:07 +0000474 }
Andrew M. Kuchling1ed7d2d2000-03-30 21:14:30 +0000475}
476
477static struct PyMethodDef mmap_object_methods[] = {
Guido van Rossum09fdf072000-03-31 01:17:07 +0000478 {"close", (PyCFunction) mmap_close_method, 1},
479 {"find", (PyCFunction) mmap_find_method, 1},
480 {"flush", (PyCFunction) mmap_flush_method, 1},
481 {"move", (PyCFunction) mmap_move_method, 1},
482 {"read", (PyCFunction) mmap_read_method, 1},
483 {"read_byte", (PyCFunction) mmap_read_byte_method, 1},
484 {"readline", (PyCFunction) mmap_read_line_method, 1},
485 {"resize", (PyCFunction) mmap_resize_method, 1},
486 {"seek", (PyCFunction) mmap_seek_method, 1},
487 {"size", (PyCFunction) mmap_size_method, 1},
488 {"tell", (PyCFunction) mmap_tell_method, 1},
489 {"write", (PyCFunction) mmap_write_method, 1},
490 {"write_byte", (PyCFunction) mmap_write_byte_method, 1},
491 {NULL, NULL} /* sentinel */
Andrew M. Kuchling1ed7d2d2000-03-30 21:14:30 +0000492};
493
494/* Functions for treating an mmap'ed file as a buffer */
495
496static int
Andrew M. Kuchling961fe172000-06-03 19:41:42 +0000497mmap_buffer_getreadbuf(mmap_object *self, int index, const void **ptr)
Andrew M. Kuchling1ed7d2d2000-03-30 21:14:30 +0000498{
Guido van Rossum09fdf072000-03-31 01:17:07 +0000499 CHECK_VALID(-1);
500 if ( index != 0 ) {
501 PyErr_SetString(PyExc_SystemError,
502 "Accessing non-existent mmap segment");
503 return -1;
504 }
505 *ptr = self->data;
506 return self->size;
Andrew M. Kuchling1ed7d2d2000-03-30 21:14:30 +0000507}
508
509static int
510mmap_buffer_getwritebuf(self, index, ptr)
Guido van Rossum09fdf072000-03-31 01:17:07 +0000511 mmap_object *self;
512 int index;
513 const void **ptr;
Andrew M. Kuchling1ed7d2d2000-03-30 21:14:30 +0000514{
Guido van Rossum09fdf072000-03-31 01:17:07 +0000515 CHECK_VALID(-1);
516 if ( index != 0 ) {
517 PyErr_SetString(PyExc_SystemError,
518 "Accessing non-existent mmap segment");
519 return -1;
520 }
521 *ptr = self->data;
522 return self->size;
Andrew M. Kuchling1ed7d2d2000-03-30 21:14:30 +0000523}
524
525static int
526mmap_buffer_getsegcount(self, lenp)
Guido van Rossum09fdf072000-03-31 01:17:07 +0000527 mmap_object *self;
528 int *lenp;
Andrew M. Kuchling1ed7d2d2000-03-30 21:14:30 +0000529{
Guido van Rossum09fdf072000-03-31 01:17:07 +0000530 CHECK_VALID(-1);
531 if (lenp)
532 *lenp = self->size;
533 return 1;
Andrew M. Kuchling1ed7d2d2000-03-30 21:14:30 +0000534}
535
536static int
537mmap_buffer_getcharbuffer(self, index, ptr)
Guido van Rossum09fdf072000-03-31 01:17:07 +0000538 mmap_object *self;
539 int index;
540 const void **ptr;
Andrew M. Kuchling1ed7d2d2000-03-30 21:14:30 +0000541{
Guido van Rossum09fdf072000-03-31 01:17:07 +0000542 if ( index != 0 ) {
543 PyErr_SetString(PyExc_SystemError,
544 "accessing non-existent buffer segment");
545 return -1;
546 }
547 *ptr = (const char *)self->data;
548 return self->size;
Andrew M. Kuchling1ed7d2d2000-03-30 21:14:30 +0000549}
550
551static PyObject *
552mmap_object_getattr(mmap_object * self, char * name)
553{
Guido van Rossum09fdf072000-03-31 01:17:07 +0000554 return Py_FindMethod (mmap_object_methods, (PyObject *)self, name);
Andrew M. Kuchling1ed7d2d2000-03-30 21:14:30 +0000555}
556
557static int
558mmap_length(self)
Guido van Rossum09fdf072000-03-31 01:17:07 +0000559 mmap_object *self;
Andrew M. Kuchling1ed7d2d2000-03-30 21:14:30 +0000560{
Guido van Rossum09fdf072000-03-31 01:17:07 +0000561 CHECK_VALID(-1);
562 return self->size;
Andrew M. Kuchling1ed7d2d2000-03-30 21:14:30 +0000563}
564
565static PyObject *
566mmap_item(self, i)
Guido van Rossum09fdf072000-03-31 01:17:07 +0000567 mmap_object *self;
568 int i;
Andrew M. Kuchling1ed7d2d2000-03-30 21:14:30 +0000569{
Guido van Rossum09fdf072000-03-31 01:17:07 +0000570 CHECK_VALID(NULL);
Guido van Rossumce8e1dc2000-07-01 00:51:51 +0000571 if (i < 0 || (size_t)i >= self->size) {
Guido van Rossum09fdf072000-03-31 01:17:07 +0000572 PyErr_SetString(PyExc_IndexError, "mmap index out of range");
573 return NULL;
574 }
575 return PyString_FromStringAndSize(self->data + i, 1);
Andrew M. Kuchling1ed7d2d2000-03-30 21:14:30 +0000576}
577
578static PyObject *
579mmap_slice(self, ilow, ihigh)
Guido van Rossum09fdf072000-03-31 01:17:07 +0000580 mmap_object *self;
581 int ilow, ihigh;
Andrew M. Kuchling1ed7d2d2000-03-30 21:14:30 +0000582{
Guido van Rossum09fdf072000-03-31 01:17:07 +0000583 CHECK_VALID(NULL);
584 if (ilow < 0)
585 ilow = 0;
Guido van Rossumce8e1dc2000-07-01 00:51:51 +0000586 else if ((size_t)ilow > self->size)
Guido van Rossum09fdf072000-03-31 01:17:07 +0000587 ilow = self->size;
588 if (ihigh < 0)
589 ihigh = 0;
590 if (ihigh < ilow)
591 ihigh = ilow;
Guido van Rossumce8e1dc2000-07-01 00:51:51 +0000592 else if ((size_t)ihigh > self->size)
Guido van Rossum09fdf072000-03-31 01:17:07 +0000593 ihigh = self->size;
594
595 return PyString_FromStringAndSize(self->data + ilow, ihigh-ilow);
Andrew M. Kuchling1ed7d2d2000-03-30 21:14:30 +0000596}
597
598static PyObject *
599mmap_concat(self, bb)
Guido van Rossum09fdf072000-03-31 01:17:07 +0000600 mmap_object *self;
601 PyObject *bb;
Andrew M. Kuchling1ed7d2d2000-03-30 21:14:30 +0000602{
Guido van Rossum09fdf072000-03-31 01:17:07 +0000603 CHECK_VALID(NULL);
604 PyErr_SetString(PyExc_SystemError,
605 "mmaps don't support concatenation");
606 return NULL;
Andrew M. Kuchling1ed7d2d2000-03-30 21:14:30 +0000607}
608
609static PyObject *
610mmap_repeat(self, n)
Guido van Rossum09fdf072000-03-31 01:17:07 +0000611 mmap_object *self;
612 int n;
Andrew M. Kuchling1ed7d2d2000-03-30 21:14:30 +0000613{
Guido van Rossum09fdf072000-03-31 01:17:07 +0000614 CHECK_VALID(NULL);
615 PyErr_SetString(PyExc_SystemError,
616 "mmaps don't support repeat operation");
617 return NULL;
Andrew M. Kuchling1ed7d2d2000-03-30 21:14:30 +0000618}
619
620static int
621mmap_ass_slice(self, ilow, ihigh, v)
Guido van Rossum09fdf072000-03-31 01:17:07 +0000622 mmap_object *self;
623 int ilow, ihigh;
624 PyObject *v;
Andrew M. Kuchling1ed7d2d2000-03-30 21:14:30 +0000625{
Guido van Rossum36d4f8b2000-04-10 21:34:37 +0000626 const char *buf;
Andrew M. Kuchling1ed7d2d2000-03-30 21:14:30 +0000627
Guido van Rossum09fdf072000-03-31 01:17:07 +0000628 CHECK_VALID(-1);
629 if (ilow < 0)
630 ilow = 0;
Guido van Rossumce8e1dc2000-07-01 00:51:51 +0000631 else if ((size_t)ilow > self->size)
Guido van Rossum09fdf072000-03-31 01:17:07 +0000632 ilow = self->size;
633 if (ihigh < 0)
634 ihigh = 0;
635 if (ihigh < ilow)
636 ihigh = ilow;
Guido van Rossumce8e1dc2000-07-01 00:51:51 +0000637 else if ((size_t)ihigh > self->size)
Guido van Rossum09fdf072000-03-31 01:17:07 +0000638 ihigh = self->size;
639
640 if (! (PyString_Check(v)) ) {
641 PyErr_SetString(PyExc_IndexError,
642 "mmap slice assignment must be a string");
643 return -1;
644 }
645 if ( PyString_Size(v) != (ihigh - ilow) ) {
646 PyErr_SetString(PyExc_IndexError,
647 "mmap slice assignment is wrong size");
648 return -1;
649 }
650 buf = PyString_AsString(v);
651 memcpy(self->data + ilow, buf, ihigh-ilow);
652 return 0;
Andrew M. Kuchling1ed7d2d2000-03-30 21:14:30 +0000653}
654
655static int
656mmap_ass_item(self, i, v)
Guido van Rossum09fdf072000-03-31 01:17:07 +0000657 mmap_object *self;
658 int i;
659 PyObject *v;
Andrew M. Kuchling1ed7d2d2000-03-30 21:14:30 +0000660{
Guido van Rossum36d4f8b2000-04-10 21:34:37 +0000661 const char *buf;
Andrew M. Kuchling1ed7d2d2000-03-30 21:14:30 +0000662
Guido van Rossum09fdf072000-03-31 01:17:07 +0000663 CHECK_VALID(-1);
Guido van Rossumce8e1dc2000-07-01 00:51:51 +0000664 if (i < 0 || (size_t)i >= self->size) {
Guido van Rossum09fdf072000-03-31 01:17:07 +0000665 PyErr_SetString(PyExc_IndexError, "mmap index out of range");
666 return -1;
667 }
668 if (! (PyString_Check(v) && PyString_Size(v)==1) ) {
669 PyErr_SetString(PyExc_IndexError,
670 "mmap assignment must be single-character string");
671 return -1;
672 }
673 buf = PyString_AsString(v);
674 self->data[i] = buf[0];
675 return 0;
Andrew M. Kuchling1ed7d2d2000-03-30 21:14:30 +0000676}
677
678static PySequenceMethods mmap_as_sequence = {
Guido van Rossum09fdf072000-03-31 01:17:07 +0000679 (inquiry)mmap_length, /*sq_length*/
680 (binaryfunc)mmap_concat, /*sq_concat*/
681 (intargfunc)mmap_repeat, /*sq_repeat*/
682 (intargfunc)mmap_item, /*sq_item*/
683 (intintargfunc)mmap_slice, /*sq_slice*/
684 (intobjargproc)mmap_ass_item, /*sq_ass_item*/
685 (intintobjargproc)mmap_ass_slice, /*sq_ass_slice*/
Andrew M. Kuchling1ed7d2d2000-03-30 21:14:30 +0000686};
687
688static PyBufferProcs mmap_as_buffer = {
Guido van Rossum09fdf072000-03-31 01:17:07 +0000689 (getreadbufferproc)mmap_buffer_getreadbuf,
690 (getwritebufferproc)mmap_buffer_getwritebuf,
691 (getsegcountproc)mmap_buffer_getsegcount,
692 (getcharbufferproc)mmap_buffer_getcharbuffer,
Andrew M. Kuchling1ed7d2d2000-03-30 21:14:30 +0000693};
694
695static PyTypeObject mmap_object_type = {
Guido van Rossum09fdf072000-03-31 01:17:07 +0000696 PyObject_HEAD_INIT(0) /* patched in module init */
697 0, /* ob_size */
698 "mmap", /* tp_name */
699 sizeof(mmap_object), /* tp_size */
700 0, /* tp_itemsize */
701 /* methods */
702 (destructor) mmap_object_dealloc, /* tp_dealloc */
703 0, /* tp_print */
704 (getattrfunc) mmap_object_getattr, /* tp_getattr */
705 0, /* tp_setattr */
706 0, /* tp_compare */
707 0, /* tp_repr */
708 0, /* tp_as_number */
709 &mmap_as_sequence, /*tp_as_sequence*/
710 0, /*tp_as_mapping*/
711 0, /*tp_hash*/
712 0, /*tp_call*/
713 0, /*tp_str*/
714 0, /*tp_getattro*/
715 0, /*tp_setattro*/
716 &mmap_as_buffer, /*tp_as_buffer*/
717 Py_TPFLAGS_HAVE_GETCHARBUFFER, /*tp_flags*/
718 0, /*tp_doc*/
Andrew M. Kuchling1ed7d2d2000-03-30 21:14:30 +0000719};
720
Andrew M. Kuchling70d27422000-06-18 04:45:14 +0000721
722/* extract the map size from the given PyObject
723
724 The map size is restricted to [0, INT_MAX] because this is the current
725 Python limitation on object sizes. Although the mmap object *could* handle
726 a larger map size, there is no point because all the useful operations
727 (len(), slicing(), sequence indexing) are limited by a C int.
728
729 Returns -1 on error, with an apprpriate Python exception raised. On
730 success, the map size is returned. */
731static int
732_GetMapSize(o)
733 PyObject *o;
734{
735 if (PyInt_Check(o)) {
736 long i = PyInt_AsLong(o);
737 if (PyErr_Occurred())
738 return -1;
739 if (i < 0)
740 goto onnegoverflow;
741 if (i > INT_MAX)
742 goto onposoverflow;
743 return (int)i;
744 }
745 else if (PyLong_Check(o)) {
746 long i = PyLong_AsLong(o);
747 if (PyErr_Occurred()) {
748 /* yes negative overflow is mistaken for positive overflow
749 but not worth the trouble to check sign of 'i' */
750 if (PyErr_ExceptionMatches(PyExc_OverflowError))
751 goto onposoverflow;
752 else
753 return -1;
754 }
755 if (i < 0)
756 goto onnegoverflow;
757 if (i > INT_MAX)
758 goto onposoverflow;
759 return (int)i;
760 }
761 else {
762 PyErr_SetString(PyExc_TypeError,
763 "map size must be an integral value");
764 return -1;
765 }
766
767onnegoverflow:
768 PyErr_SetString(PyExc_OverflowError,
769 "memory mapped size must be positive");
770 return -1;
771
772onposoverflow:
773 PyErr_SetString(PyExc_OverflowError,
774 "memory mapped size is too large (limited by C int)");
775 return -1;
776}
777
Andrew M. Kuchling1ed7d2d2000-03-30 21:14:30 +0000778#ifdef UNIX
779static PyObject *
780new_mmap_object (PyObject * self, PyObject * args, PyObject *kwdict)
781{
Guido van Rossum09fdf072000-03-31 01:17:07 +0000782 mmap_object * m_obj;
Andrew M. Kuchling70d27422000-06-18 04:45:14 +0000783 PyObject *map_size_obj = NULL;
784 int map_size;
Guido van Rossum09fdf072000-03-31 01:17:07 +0000785 int fd, flags = MAP_SHARED, prot = PROT_WRITE | PROT_READ;
Guido van Rossum09fdf072000-03-31 01:17:07 +0000786 char *keywords[] = {"file", "size", "flags", "prot", NULL};
Andrew M. Kuchling1ed7d2d2000-03-30 21:14:30 +0000787
Guido van Rossum09fdf072000-03-31 01:17:07 +0000788 if (!PyArg_ParseTupleAndKeywords(args, kwdict,
Andrew M. Kuchling70d27422000-06-18 04:45:14 +0000789 "iO|ii", keywords,
790 &fd, &map_size_obj, &flags, &prot)
Guido van Rossum09fdf072000-03-31 01:17:07 +0000791 )
792 return NULL;
Andrew M. Kuchling70d27422000-06-18 04:45:14 +0000793 map_size = _GetMapSize(map_size_obj);
794 if (map_size < 0)
795 return NULL;
796
Guido van Rossumb18618d2000-05-03 23:44:39 +0000797 m_obj = PyObject_New (mmap_object, &mmap_object_type);
Guido van Rossum09fdf072000-03-31 01:17:07 +0000798 if (m_obj == NULL) {return NULL;}
799 m_obj->size = (size_t) map_size;
800 m_obj->pos = (size_t) 0;
Andrew M. Kuchling7b9fb922000-06-17 22:41:22 +0000801 m_obj->fd = fd;
Guido van Rossum09fdf072000-03-31 01:17:07 +0000802 m_obj->data = mmap(NULL, map_size,
803 prot, flags,
804 fd, 0);
805 if (m_obj->data == (void *)-1)
806 {
807 Py_DECREF(m_obj);
808 PyErr_SetFromErrno(mmap_module_error);
809 return NULL;
810 }
811 return (PyObject *)m_obj;
Andrew M. Kuchling1ed7d2d2000-03-30 21:14:30 +0000812}
813#endif /* UNIX */
814
815#ifdef MS_WIN32
816static PyObject *
817new_mmap_object (PyObject * self, PyObject * args)
818{
Guido van Rossum09fdf072000-03-31 01:17:07 +0000819 mmap_object * m_obj;
Andrew M. Kuchling70d27422000-06-18 04:45:14 +0000820 PyObject *map_size_obj = NULL;
821 int map_size;
Guido van Rossum09fdf072000-03-31 01:17:07 +0000822 char * tagname = "";
Andrew M. Kuchling1ed7d2d2000-03-30 21:14:30 +0000823
Guido van Rossum09fdf072000-03-31 01:17:07 +0000824 DWORD dwErr = 0;
825 int fileno;
Andrew M. Kuchling70d27422000-06-18 04:45:14 +0000826 INT_PTR fh = 0;
Andrew M. Kuchling1ed7d2d2000-03-30 21:14:30 +0000827
Guido van Rossum09fdf072000-03-31 01:17:07 +0000828 /* Patch the object type */
829 mmap_object_type.ob_type = &PyType_Type;
830
831 if (!PyArg_ParseTuple(args,
Andrew M. Kuchling70d27422000-06-18 04:45:14 +0000832 "iO|z",
Guido van Rossum09fdf072000-03-31 01:17:07 +0000833 &fileno,
Andrew M. Kuchling70d27422000-06-18 04:45:14 +0000834 &map_size_obj,
Guido van Rossum09fdf072000-03-31 01:17:07 +0000835 &tagname)
836 )
837 return NULL;
Andrew M. Kuchling1ed7d2d2000-03-30 21:14:30 +0000838
Andrew M. Kuchling70d27422000-06-18 04:45:14 +0000839 map_size = _GetMapSize(map_size_obj);
840 if (map_size < 0)
841 return NULL;
842
Guido van Rossum09fdf072000-03-31 01:17:07 +0000843 /* if an actual filename has been specified */
844 if (fileno != 0) {
845 fh = _get_osfhandle(fileno);
846 if (fh==-1) {
847 PyErr_SetFromErrno(mmap_module_error);
848 return NULL;
Andrew M. Kuchling1ed7d2d2000-03-30 21:14:30 +0000849 }
Fred Drake1ef4e2d2000-04-05 14:15:31 +0000850 /* Win9x appears to need us seeked to zero */
851 fseek(&_iob[fileno], 0, SEEK_SET);
Guido van Rossum09fdf072000-03-31 01:17:07 +0000852 }
Andrew M. Kuchling1ed7d2d2000-03-30 21:14:30 +0000853
Guido van Rossumb18618d2000-05-03 23:44:39 +0000854 m_obj = PyObject_New (mmap_object, &mmap_object_type);
Guido van Rossum09fdf072000-03-31 01:17:07 +0000855
856 if (fh) {
857 m_obj->file_handle = fh;
858 if (!map_size) {
859 m_obj->size = GetFileSize ((HANDLE)fh, NULL);
Andrew M. Kuchling1ed7d2d2000-03-30 21:14:30 +0000860 } else {
Guido van Rossum09fdf072000-03-31 01:17:07 +0000861 m_obj->size = map_size;
Andrew M. Kuchling1ed7d2d2000-03-30 21:14:30 +0000862 }
Guido van Rossum09fdf072000-03-31 01:17:07 +0000863 }
864 else {
Andrew M. Kuchling70d27422000-06-18 04:45:14 +0000865 m_obj->file_handle = (INT_PTR) -1;
Guido van Rossum09fdf072000-03-31 01:17:07 +0000866 m_obj->size = map_size;
867 }
868
869 /* set the initial position */
870 m_obj->pos = (size_t) 0;
871
872 m_obj->map_handle = CreateFileMapping ((HANDLE) m_obj->file_handle,
873 NULL,
874 PAGE_READWRITE,
875 0,
876 m_obj->size,
877 tagname);
878 if (m_obj->map_handle != NULL) {
879 m_obj->data = (char *) MapViewOfFile (m_obj->map_handle,
880 FILE_MAP_WRITE,
881 0,
882 0,
883 0);
884 if (m_obj->data != NULL) {
885 return ((PyObject *) m_obj);
886 } else {
887 dwErr = GetLastError();
888 }
889 } else {
890 dwErr = GetLastError();
891 }
892 PyErr_SetFromWindowsErr(dwErr);
893 return (NULL);
Andrew M. Kuchling1ed7d2d2000-03-30 21:14:30 +0000894}
895#endif /* MS_WIN32 */
896
897/* List of functions exported by this module */
898static struct PyMethodDef mmap_functions[] = {
Guido van Rossum09fdf072000-03-31 01:17:07 +0000899 {"mmap", (PyCFunction) new_mmap_object,
900 METH_VARARGS|METH_KEYWORDS},
901 {NULL, NULL} /* Sentinel */
Andrew M. Kuchling1ed7d2d2000-03-30 21:14:30 +0000902};
903
904#ifdef MS_WIN32
Guido van Rossum09fdf072000-03-31 01:17:07 +0000905__declspec(dllexport) void
Andrew M. Kuchling1ed7d2d2000-03-30 21:14:30 +0000906#endif /* MS_WIN32 */
907#ifdef UNIX
908extern void
909#endif
910
911initmmap(void)
912{
Guido van Rossum09fdf072000-03-31 01:17:07 +0000913 PyObject *dict, *module;
914 module = Py_InitModule ("mmap", mmap_functions);
915 dict = PyModule_GetDict (module);
916 mmap_module_error = PyExc_EnvironmentError;
917 Py_INCREF(mmap_module_error);
918 PyDict_SetItemString (dict, "error", mmap_module_error);
Andrew M. Kuchling1ed7d2d2000-03-30 21:14:30 +0000919#ifdef PROT_EXEC
Guido van Rossum09fdf072000-03-31 01:17:07 +0000920 PyDict_SetItemString (dict, "PROT_EXEC", PyInt_FromLong(PROT_EXEC) );
Andrew M. Kuchling1ed7d2d2000-03-30 21:14:30 +0000921#endif
922#ifdef PROT_READ
Guido van Rossum09fdf072000-03-31 01:17:07 +0000923 PyDict_SetItemString (dict, "PROT_READ", PyInt_FromLong(PROT_READ) );
Andrew M. Kuchling1ed7d2d2000-03-30 21:14:30 +0000924#endif
925#ifdef PROT_WRITE
Guido van Rossum09fdf072000-03-31 01:17:07 +0000926 PyDict_SetItemString (dict, "PROT_WRITE", PyInt_FromLong(PROT_WRITE) );
Andrew M. Kuchling1ed7d2d2000-03-30 21:14:30 +0000927#endif
928
929#ifdef MAP_SHARED
Guido van Rossum09fdf072000-03-31 01:17:07 +0000930 PyDict_SetItemString (dict, "MAP_SHARED", PyInt_FromLong(MAP_SHARED) );
Andrew M. Kuchling1ed7d2d2000-03-30 21:14:30 +0000931#endif
932#ifdef MAP_PRIVATE
Guido van Rossum09fdf072000-03-31 01:17:07 +0000933 PyDict_SetItemString (dict, "MAP_PRIVATE",
934 PyInt_FromLong(MAP_PRIVATE) );
Andrew M. Kuchling1ed7d2d2000-03-30 21:14:30 +0000935#endif
936#ifdef MAP_DENYWRITE
Guido van Rossum09fdf072000-03-31 01:17:07 +0000937 PyDict_SetItemString (dict, "MAP_DENYWRITE",
938 PyInt_FromLong(MAP_DENYWRITE) );
Andrew M. Kuchling1ed7d2d2000-03-30 21:14:30 +0000939#endif
940#ifdef MAP_EXECUTABLE
Guido van Rossum09fdf072000-03-31 01:17:07 +0000941 PyDict_SetItemString (dict, "MAP_EXECUTABLE",
942 PyInt_FromLong(MAP_EXECUTABLE) );
Andrew M. Kuchling1ed7d2d2000-03-30 21:14:30 +0000943#endif
944#ifdef MAP_ANON
Guido van Rossum09fdf072000-03-31 01:17:07 +0000945 PyDict_SetItemString (dict, "MAP_ANON", PyInt_FromLong(MAP_ANON) );
946 PyDict_SetItemString (dict, "MAP_ANONYMOUS",
947 PyInt_FromLong(MAP_ANON) );
Andrew M. Kuchling1ed7d2d2000-03-30 21:14:30 +0000948#endif
949
950#ifdef UNIX
Guido van Rossum09fdf072000-03-31 01:17:07 +0000951 PyDict_SetItemString (dict, "PAGESIZE",
952 PyInt_FromLong( (long)getpagesize() ) );
Andrew M. Kuchling1ed7d2d2000-03-30 21:14:30 +0000953#endif
Guido van Rossum09fdf072000-03-31 01:17:07 +0000954#ifdef MS_WIN32
955 {
956 SYSTEM_INFO si;
957 GetSystemInfo(&si);
958 PyDict_SetItemString (dict, "PAGESIZE",
959 PyInt_FromLong( si.dwPageSize ) );
960 }
961#endif /* MS_WIN32 */
Andrew M. Kuchling1ed7d2d2000-03-30 21:14:30 +0000962
963}
Andrew M. Kuchling961fe172000-06-03 19:41:42 +0000964