blob: 4b18466d280b14950d2307732454504138ee09d5 [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
Guido van Rossum09fdf072000-03-31 01:17:07 +000019#include <Python.h>
20
Andrew M. Kuchling1ed7d2d2000-03-30 21:14:30 +000021#ifndef MS_WIN32
22#define UNIX
23#endif
24
25#ifdef MS_WIN32
26#include <windows.h>
27#endif
28
29#ifdef UNIX
30#include <unistd.h>
31#include <sys/mman.h>
Andrew M. Kuchling7b9fb922000-06-17 22:41:22 +000032#include <sys/stat.h>
Andrew M. Kuchling1ed7d2d2000-03-30 21:14:30 +000033#endif
34
Andrew M. Kuchling1ed7d2d2000-03-30 21:14:30 +000035#include <string.h>
36#include <sys/types.h>
37
38static PyObject *mmap_module_error;
39
40typedef struct {
Guido van Rossum09fdf072000-03-31 01:17:07 +000041 PyObject_HEAD
42 char * data;
43 size_t size;
44 size_t pos;
Andrew M. Kuchling1ed7d2d2000-03-30 21:14:30 +000045
46#ifdef MS_WIN32
Guido van Rossum09fdf072000-03-31 01:17:07 +000047 HANDLE map_handle;
Andrew M. Kuchling70d27422000-06-18 04:45:14 +000048 INT_PTR file_handle;
Guido van Rossum09fdf072000-03-31 01:17:07 +000049 char * tagname;
Andrew M. Kuchling1ed7d2d2000-03-30 21:14:30 +000050#endif
51
52#ifdef UNIX
Andrew M. Kuchling7b9fb922000-06-17 22:41:22 +000053 int fd;
Andrew M. Kuchling1ed7d2d2000-03-30 21:14:30 +000054#endif
55} mmap_object;
56
57static void
58mmap_object_dealloc(mmap_object * m_obj)
59{
60#ifdef MS_WIN32
Guido van Rossum09fdf072000-03-31 01:17:07 +000061 UnmapViewOfFile (m_obj->data);
62 CloseHandle (m_obj->map_handle);
63 CloseHandle ((HANDLE)m_obj->file_handle);
Andrew M. Kuchling1ed7d2d2000-03-30 21:14:30 +000064#endif /* MS_WIN32 */
65
66#ifdef UNIX
Guido van Rossum09fdf072000-03-31 01:17:07 +000067 if (m_obj->data!=NULL) {
Andrew M. Kuchling9bc5f332000-06-18 04:25:08 +000068 msync(m_obj->data, m_obj->size, MS_SYNC);
Guido van Rossum09fdf072000-03-31 01:17:07 +000069 munmap(m_obj->data, m_obj->size);
70 }
Andrew M. Kuchling1ed7d2d2000-03-30 21:14:30 +000071#endif /* UNIX */
72
Guido van Rossumb18618d2000-05-03 23:44:39 +000073 PyObject_Del(m_obj);
Andrew M. Kuchling1ed7d2d2000-03-30 21:14:30 +000074}
75
76static PyObject *
77mmap_close_method (mmap_object * self, PyObject * args)
78{
Andrew M. Kuchling841b9fb2000-06-03 20:43:43 +000079 if (!PyArg_ParseTuple(args, ":close"))
Andrew M. Kuchling961fe172000-06-03 19:41:42 +000080 return NULL;
Andrew M. Kuchling1ed7d2d2000-03-30 21:14:30 +000081#ifdef MS_WIN32
Guido van Rossum09fdf072000-03-31 01:17:07 +000082 UnmapViewOfFile (self->data);
83 CloseHandle (self->map_handle);
84 CloseHandle ((HANDLE)self->file_handle);
85 self->map_handle = (HANDLE) NULL;
Andrew M. Kuchling1ed7d2d2000-03-30 21:14:30 +000086#endif /* MS_WIN32 */
87
88#ifdef UNIX
Guido van Rossum09fdf072000-03-31 01:17:07 +000089 munmap(self->data, self->size);
90 self->data = NULL;
Andrew M. Kuchling1ed7d2d2000-03-30 21:14:30 +000091#endif
92
Guido van Rossum09fdf072000-03-31 01:17:07 +000093 Py_INCREF (Py_None);
94 return (Py_None);
Andrew M. Kuchling1ed7d2d2000-03-30 21:14:30 +000095}
96
97#ifdef MS_WIN32
Guido van Rossum09fdf072000-03-31 01:17:07 +000098#define CHECK_VALID(err) \
99do { \
100 if (!self->map_handle) { \
101 PyErr_SetString (PyExc_ValueError, "mmap closed or invalid"); \
102 return err; \
103 } \
Andrew M. Kuchling1ed7d2d2000-03-30 21:14:30 +0000104} while (0)
105#endif /* MS_WIN32 */
106
107#ifdef UNIX
Guido van Rossum09fdf072000-03-31 01:17:07 +0000108#define CHECK_VALID(err) \
109do { \
110 if (self->data == NULL) { \
111 PyErr_SetString (PyExc_ValueError, "mmap closed or invalid"); \
112 return err; \
113 } \
Andrew M. Kuchling1ed7d2d2000-03-30 21:14:30 +0000114} while (0)
115#endif /* UNIX */
116
117static PyObject *
118mmap_read_byte_method (mmap_object * self,
Guido van Rossum09fdf072000-03-31 01:17:07 +0000119 PyObject * args)
Andrew M. Kuchling1ed7d2d2000-03-30 21:14:30 +0000120{
Guido van Rossum09fdf072000-03-31 01:17:07 +0000121 char value;
Guido van Rossum36d4f8b2000-04-10 21:34:37 +0000122 char * where;
Guido van Rossum09fdf072000-03-31 01:17:07 +0000123 CHECK_VALID(NULL);
Andrew M. Kuchling841b9fb2000-06-03 20:43:43 +0000124 if (!PyArg_ParseTuple(args, ":read_byte"))
Andrew M. Kuchling961fe172000-06-03 19:41:42 +0000125 return NULL;
Andrew M. Kuchling70d27422000-06-18 04:45:14 +0000126 if (self->pos < self->size) {
Guido van Rossum36d4f8b2000-04-10 21:34:37 +0000127 where = self->data + self->pos;
Guido van Rossum09fdf072000-03-31 01:17:07 +0000128 value = (char) *(where);
129 self->pos += 1;
130 return Py_BuildValue("c", (char) *(where));
131 } else {
132 PyErr_SetString (PyExc_ValueError, "read byte out of range");
133 return NULL;
134 }
Andrew M. Kuchling1ed7d2d2000-03-30 21:14:30 +0000135}
136
137static PyObject *
138mmap_read_line_method (mmap_object * self,
Andrew M. Kuchling961fe172000-06-03 19:41:42 +0000139 PyObject * args)
Andrew M. Kuchling1ed7d2d2000-03-30 21:14:30 +0000140{
Fred Drake56a87a02000-04-04 18:17:35 +0000141 char * start = self->data+self->pos;
Guido van Rossum09fdf072000-03-31 01:17:07 +0000142 char * eof = self->data+self->size;
143 char * eol;
144 PyObject * result;
Andrew M. Kuchling1ed7d2d2000-03-30 21:14:30 +0000145
Guido van Rossum09fdf072000-03-31 01:17:07 +0000146 CHECK_VALID(NULL);
Andrew M. Kuchling841b9fb2000-06-03 20:43:43 +0000147 if (!PyArg_ParseTuple(args, ":readline"))
Andrew M. Kuchling961fe172000-06-03 19:41:42 +0000148 return NULL;
Andrew M. Kuchling1ed7d2d2000-03-30 21:14:30 +0000149
Fred Drake56a87a02000-04-04 18:17:35 +0000150 eol = memchr(start, '\n', self->size - self->pos);
151 if (!eol)
152 eol = eof;
153 else
154 ++eol; /* we're interested in the position after the
155 newline. */
Andrew M. Kuchling70d27422000-06-18 04:45:14 +0000156 result = PyString_FromStringAndSize(start, (eol - start));
Guido van Rossum09fdf072000-03-31 01:17:07 +0000157 self->pos += (eol - start);
158 return (result);
Andrew M. Kuchling1ed7d2d2000-03-30 21:14:30 +0000159}
160
161static PyObject *
162mmap_read_method (mmap_object * self,
Andrew M. Kuchling961fe172000-06-03 19:41:42 +0000163 PyObject * args)
Andrew M. Kuchling1ed7d2d2000-03-30 21:14:30 +0000164{
Guido van Rossum09fdf072000-03-31 01:17:07 +0000165 long num_bytes;
166 PyObject *result;
Andrew M. Kuchling1ed7d2d2000-03-30 21:14:30 +0000167
Guido van Rossum09fdf072000-03-31 01:17:07 +0000168 CHECK_VALID(NULL);
169 if (!PyArg_ParseTuple (args, "l", &num_bytes))
170 return(NULL);
Andrew M. Kuchling1ed7d2d2000-03-30 21:14:30 +0000171
Guido van Rossum09fdf072000-03-31 01:17:07 +0000172 /* silently 'adjust' out-of-range requests */
173 if ((self->pos + num_bytes) > self->size) {
174 num_bytes -= (self->pos+num_bytes) - self->size;
175 }
176 result = Py_BuildValue("s#", self->data+self->pos, num_bytes);
177 self->pos += num_bytes;
178 return (result);
Andrew M. Kuchling1ed7d2d2000-03-30 21:14:30 +0000179}
180
181static PyObject *
182mmap_find_method (mmap_object *self,
Guido van Rossum09fdf072000-03-31 01:17:07 +0000183 PyObject *args)
Andrew M. Kuchling1ed7d2d2000-03-30 21:14:30 +0000184{
Andrew M. Kuchling70d27422000-06-18 04:45:14 +0000185 int start = self->pos;
Guido van Rossum09fdf072000-03-31 01:17:07 +0000186 char * needle;
187 int len;
Andrew M. Kuchling1ed7d2d2000-03-30 21:14:30 +0000188
Guido van Rossum09fdf072000-03-31 01:17:07 +0000189 CHECK_VALID(NULL);
Andrew M. Kuchling70d27422000-06-18 04:45:14 +0000190 if (!PyArg_ParseTuple (args, "s#|i", &needle, &len, &start)) {
Guido van Rossum09fdf072000-03-31 01:17:07 +0000191 return NULL;
192 } else {
193 char * p = self->data+self->pos;
194 char * e = self->data+self->size;
195 while (p < e) {
196 char * s = p;
197 char * n = needle;
198 while ((s<e) && (*n) && !(*s-*n)) {
199 s++, n++;
200 }
201 if (!*n) {
202 return Py_BuildValue (
Andrew M. Kuchling70d27422000-06-18 04:45:14 +0000203 "i",
204 (int) (p - (self->data + start)));
Guido van Rossum09fdf072000-03-31 01:17:07 +0000205 }
206 p++;
Andrew M. Kuchling1ed7d2d2000-03-30 21:14:30 +0000207 }
Guido van Rossum09fdf072000-03-31 01:17:07 +0000208 return Py_BuildValue ("l", (long) -1);
209 }
Andrew M. Kuchling1ed7d2d2000-03-30 21:14:30 +0000210}
211
212static PyObject *
213mmap_write_method (mmap_object * self,
Andrew M. Kuchling7b9fb922000-06-17 22:41:22 +0000214 PyObject * args)
Andrew M. Kuchling1ed7d2d2000-03-30 21:14:30 +0000215{
Guido van Rossum09fdf072000-03-31 01:17:07 +0000216 long length;
217 char * data;
Andrew M. Kuchling1ed7d2d2000-03-30 21:14:30 +0000218
Guido van Rossum09fdf072000-03-31 01:17:07 +0000219 CHECK_VALID(NULL);
220 if (!PyArg_ParseTuple (args, "s#", &data, &length))
221 return(NULL);
Andrew M. Kuchling1ed7d2d2000-03-30 21:14:30 +0000222
Guido van Rossum09fdf072000-03-31 01:17:07 +0000223 if ((self->pos + length) > self->size) {
224 PyErr_SetString (PyExc_ValueError, "data out of range");
225 return NULL;
226 }
227 memcpy (self->data+self->pos, data, length);
228 self->pos = self->pos+length;
229 Py_INCREF (Py_None);
230 return (Py_None);
Andrew M. Kuchling1ed7d2d2000-03-30 21:14:30 +0000231}
232
233static PyObject *
234mmap_write_byte_method (mmap_object * self,
Andrew M. Kuchling961fe172000-06-03 19:41:42 +0000235 PyObject * args)
Andrew M. Kuchling1ed7d2d2000-03-30 21:14:30 +0000236{
Guido van Rossum09fdf072000-03-31 01:17:07 +0000237 char value;
Andrew M. Kuchling1ed7d2d2000-03-30 21:14:30 +0000238
Guido van Rossum09fdf072000-03-31 01:17:07 +0000239 CHECK_VALID(NULL);
240 if (!PyArg_ParseTuple (args, "c", &value))
241 return(NULL);
Andrew M. Kuchling1ed7d2d2000-03-30 21:14:30 +0000242
Guido van Rossum09fdf072000-03-31 01:17:07 +0000243 *(self->data+self->pos) = value;
244 self->pos += 1;
245 Py_INCREF (Py_None);
246 return (Py_None);
Andrew M. Kuchling1ed7d2d2000-03-30 21:14:30 +0000247}
248
249static PyObject *
250mmap_size_method (mmap_object * self,
Andrew M. Kuchling961fe172000-06-03 19:41:42 +0000251 PyObject * args)
Andrew M. Kuchling1ed7d2d2000-03-30 21:14:30 +0000252{
Guido van Rossum09fdf072000-03-31 01:17:07 +0000253 CHECK_VALID(NULL);
Andrew M. Kuchling841b9fb2000-06-03 20:43:43 +0000254 if (!PyArg_ParseTuple(args, ":size"))
Andrew M. Kuchling961fe172000-06-03 19:41:42 +0000255 return NULL;
Andrew M. Kuchling1ed7d2d2000-03-30 21:14:30 +0000256
257#ifdef MS_WIN32
Andrew M. Kuchling70d27422000-06-18 04:45:14 +0000258 if (self->file_handle != (INT_PTR) -1) {
Guido van Rossum09fdf072000-03-31 01:17:07 +0000259 return (Py_BuildValue (
260 "l",
261 GetFileSize ((HANDLE)self->file_handle, NULL)));
262 } else {
263 return (Py_BuildValue ("l", self->size) );
264 }
Andrew M. Kuchling1ed7d2d2000-03-30 21:14:30 +0000265#endif /* MS_WIN32 */
266
267#ifdef UNIX
Andrew M. Kuchling7b9fb922000-06-17 22:41:22 +0000268 {
269 struct stat buf;
270 if (-1 == fstat(self->fd, &buf)) {
271 PyErr_SetFromErrno(mmap_module_error);
272 return NULL;
273 }
274 return (Py_BuildValue ("l", buf.st_size) );
275 }
Andrew M. Kuchling1ed7d2d2000-03-30 21:14:30 +0000276#endif /* UNIX */
277}
278
279/* This assumes that you want the entire file mapped,
280 / and when recreating the map will make the new file
281 / have the new size
282 /
283 / Is this really necessary? This could easily be done
284 / from python by just closing and re-opening with the
285 / new size?
286 */
287
288static PyObject *
289mmap_resize_method (mmap_object * self,
Guido van Rossum09fdf072000-03-31 01:17:07 +0000290 PyObject * args)
Andrew M. Kuchling1ed7d2d2000-03-30 21:14:30 +0000291{
Guido van Rossum09fdf072000-03-31 01:17:07 +0000292 unsigned long new_size;
293 CHECK_VALID(NULL);
294 if (!PyArg_ParseTuple (args, "l", &new_size)) {
295 return NULL;
Andrew M. Kuchling1ed7d2d2000-03-30 21:14:30 +0000296#ifdef MS_WIN32
Guido van Rossum09fdf072000-03-31 01:17:07 +0000297 } else {
298 DWORD dwErrCode = 0;
299 /* First, unmap the file view */
300 UnmapViewOfFile (self->data);
301 /* Close the mapping object */
302 CloseHandle ((HANDLE)self->map_handle);
303 /* Move to the desired EOF position */
304 SetFilePointer ((HANDLE)self->file_handle,
305 new_size, NULL, FILE_BEGIN);
306 /* Change the size of the file */
307 SetEndOfFile ((HANDLE)self->file_handle);
308 /* Create another mapping object and remap the file view */
309 self->map_handle = CreateFileMapping (
310 (HANDLE) self->file_handle,
311 NULL,
312 PAGE_READWRITE,
313 0,
314 new_size,
315 self->tagname);
316 if (self->map_handle != NULL) {
317 self->data = (char *) MapViewOfFile (self->map_handle,
318 FILE_MAP_WRITE,
319 0,
320 0,
321 0);
322 if (self->data != NULL) {
323 self->size = new_size;
324 Py_INCREF (Py_None);
325 return Py_None;
326 } else {
327 dwErrCode = GetLastError();
328 }
329 } else {
330 dwErrCode = GetLastError();
Andrew M. Kuchling1ed7d2d2000-03-30 21:14:30 +0000331 }
Guido van Rossum09fdf072000-03-31 01:17:07 +0000332 PyErr_SetFromWindowsErr(dwErrCode);
333 return (NULL);
Andrew M. Kuchling1ed7d2d2000-03-30 21:14:30 +0000334#endif /* MS_WIN32 */
335
336#ifdef UNIX
Andrew M. Kuchling6fef30e2000-06-18 14:51:21 +0000337#ifndef HAVE_MREMAP
Andrew M. Kuchling1ed7d2d2000-03-30 21:14:30 +0000338} else {
Guido van Rossum09fdf072000-03-31 01:17:07 +0000339 PyErr_SetString(PyExc_SystemError,
340 "mmap: resizing not available--no mremap()");
341 return NULL;
Andrew M. Kuchling1ed7d2d2000-03-30 21:14:30 +0000342#else
343} else {
Guido van Rossum09fdf072000-03-31 01:17:07 +0000344 void *newmap;
Andrew M. Kuchling1ed7d2d2000-03-30 21:14:30 +0000345
Andrew M. Kuchling6fef30e2000-06-18 14:51:21 +0000346#ifdef MREMAP_MAYMOVE
Guido van Rossum09fdf072000-03-31 01:17:07 +0000347 newmap = mremap(self->data, self->size, new_size, MREMAP_MAYMOVE);
Andrew M. Kuchling6fef30e2000-06-18 14:51:21 +0000348#else
349 newmap = mremap(self->data, self->size, new_size, 0);
350#endif
Guido van Rossum09fdf072000-03-31 01:17:07 +0000351 if (newmap == (void *)-1)
352 {
353 PyErr_SetFromErrno(mmap_module_error);
354 return NULL;
355 }
356 self->data = newmap;
357 self->size = new_size;
358 Py_INCREF(Py_None);
359 return Py_None;
Andrew M. Kuchling6fef30e2000-06-18 14:51:21 +0000360#endif /* HAVE_MREMAP */
Andrew M. Kuchling1ed7d2d2000-03-30 21:14:30 +0000361#endif /* UNIX */
362}
363}
364
365static PyObject *
366mmap_tell_method (mmap_object * self, PyObject * args)
367{
Guido van Rossum09fdf072000-03-31 01:17:07 +0000368 CHECK_VALID(NULL);
Andrew M. Kuchling841b9fb2000-06-03 20:43:43 +0000369 if (!PyArg_ParseTuple(args, ":tell"))
Andrew M. Kuchling961fe172000-06-03 19:41:42 +0000370 return NULL;
Guido van Rossum09fdf072000-03-31 01:17:07 +0000371 return (Py_BuildValue ("l", self->pos) );
Andrew M. Kuchling1ed7d2d2000-03-30 21:14:30 +0000372}
373
374static PyObject *
375mmap_flush_method (mmap_object * self, PyObject * args)
376{
Guido van Rossum09fdf072000-03-31 01:17:07 +0000377 size_t offset = 0;
378 size_t size = self->size;
379 CHECK_VALID(NULL);
380 if (!PyArg_ParseTuple (args, "|ll", &offset, &size)) {
381 return NULL;
382 } else if ((offset + size) > self->size) {
383 PyErr_SetString (PyExc_ValueError,
384 "flush values out of range");
385 return NULL;
386 } else {
Andrew M. Kuchling1ed7d2d2000-03-30 21:14:30 +0000387#ifdef MS_WIN32
Guido van Rossum09fdf072000-03-31 01:17:07 +0000388 return (Py_BuildValue (
389 "l", FlushViewOfFile (self->data+offset, size)));
Andrew M. Kuchling1ed7d2d2000-03-30 21:14:30 +0000390#endif /* MS_WIN32 */
391#ifdef UNIX
Guido van Rossum09fdf072000-03-31 01:17:07 +0000392 /* XXX semantics of return value? */
393 /* XXX flags for msync? */
394 if (-1 == msync(self->data + offset, size,
Andrew M. Kuchling9bc5f332000-06-18 04:25:08 +0000395 MS_SYNC))
Guido van Rossum09fdf072000-03-31 01:17:07 +0000396 {
397 PyErr_SetFromErrno(mmap_module_error);
398 return NULL;
Andrew M. Kuchling1ed7d2d2000-03-30 21:14:30 +0000399 }
Guido van Rossum09fdf072000-03-31 01:17:07 +0000400 return Py_BuildValue ("l", 0);
401#endif /* UNIX */
402 }
Andrew M. Kuchling1ed7d2d2000-03-30 21:14:30 +0000403}
404
405static PyObject *
406mmap_seek_method (mmap_object * self, PyObject * args)
407{
Andrew M. Kuchling70d27422000-06-18 04:45:14 +0000408 int dist;
Guido van Rossum09fdf072000-03-31 01:17:07 +0000409 int how=0;
410 CHECK_VALID(NULL);
Andrew M. Kuchling70d27422000-06-18 04:45:14 +0000411 if (!PyArg_ParseTuple (args, "i|i", &dist, &how)) {
Guido van Rossum09fdf072000-03-31 01:17:07 +0000412 return(NULL);
413 } else {
Andrew M. Kuchling70d27422000-06-18 04:45:14 +0000414 size_t where;
Guido van Rossum09fdf072000-03-31 01:17:07 +0000415 switch (how) {
Andrew M. Kuchling70d27422000-06-18 04:45:14 +0000416 case 0: /* relative to start */
417 if (dist < 0)
418 goto onoutofrange;
Guido van Rossum09fdf072000-03-31 01:17:07 +0000419 where = dist;
420 break;
Andrew M. Kuchling70d27422000-06-18 04:45:14 +0000421 case 1: /* relative to current position */
422 if ((int)self->pos + dist < 0)
423 goto onoutofrange;
Guido van Rossum09fdf072000-03-31 01:17:07 +0000424 where = self->pos + dist;
425 break;
Andrew M. Kuchling70d27422000-06-18 04:45:14 +0000426 case 2: /* relative to end */
427 if ((int)self->size + dist < 0)
428 goto onoutofrange;
429 where = self->size + dist;
Guido van Rossum09fdf072000-03-31 01:17:07 +0000430 break;
431 default:
432 PyErr_SetString (PyExc_ValueError,
433 "unknown seek type");
434 return NULL;
Andrew M. Kuchling1ed7d2d2000-03-30 21:14:30 +0000435 }
Andrew M. Kuchling70d27422000-06-18 04:45:14 +0000436 if (where > self->size)
437 goto onoutofrange;
438 self->pos = where;
439 Py_INCREF (Py_None);
440 return (Py_None);
Guido van Rossum09fdf072000-03-31 01:17:07 +0000441 }
Andrew M. Kuchling70d27422000-06-18 04:45:14 +0000442
443onoutofrange:
444 PyErr_SetString (PyExc_ValueError, "seek out of range");
445 return NULL;
Andrew M. Kuchling1ed7d2d2000-03-30 21:14:30 +0000446}
447
448static PyObject *
449mmap_move_method (mmap_object * self, PyObject * args)
450{
Guido van Rossum09fdf072000-03-31 01:17:07 +0000451 unsigned long dest, src, count;
452 CHECK_VALID(NULL);
453 if (!PyArg_ParseTuple (args, "iii", &dest, &src, &count)) {
454 return NULL;
455 } else {
456 /* bounds check the values */
457 if (/* end of source after end of data?? */
458 ((src+count) > self->size)
459 /* dest will fit? */
460 || (dest+count > self->size)) {
461 PyErr_SetString (PyExc_ValueError,
462 "source or destination out of range");
463 return NULL;
Andrew M. Kuchling1ed7d2d2000-03-30 21:14:30 +0000464 } else {
Guido van Rossum09fdf072000-03-31 01:17:07 +0000465 memmove (self->data+dest, self->data+src, count);
466 Py_INCREF (Py_None);
467 return Py_None;
Andrew M. Kuchling1ed7d2d2000-03-30 21:14:30 +0000468 }
Guido van Rossum09fdf072000-03-31 01:17:07 +0000469 }
Andrew M. Kuchling1ed7d2d2000-03-30 21:14:30 +0000470}
471
472static struct PyMethodDef mmap_object_methods[] = {
Guido van Rossum09fdf072000-03-31 01:17:07 +0000473 {"close", (PyCFunction) mmap_close_method, 1},
474 {"find", (PyCFunction) mmap_find_method, 1},
475 {"flush", (PyCFunction) mmap_flush_method, 1},
476 {"move", (PyCFunction) mmap_move_method, 1},
477 {"read", (PyCFunction) mmap_read_method, 1},
478 {"read_byte", (PyCFunction) mmap_read_byte_method, 1},
479 {"readline", (PyCFunction) mmap_read_line_method, 1},
480 {"resize", (PyCFunction) mmap_resize_method, 1},
481 {"seek", (PyCFunction) mmap_seek_method, 1},
482 {"size", (PyCFunction) mmap_size_method, 1},
483 {"tell", (PyCFunction) mmap_tell_method, 1},
484 {"write", (PyCFunction) mmap_write_method, 1},
485 {"write_byte", (PyCFunction) mmap_write_byte_method, 1},
486 {NULL, NULL} /* sentinel */
Andrew M. Kuchling1ed7d2d2000-03-30 21:14:30 +0000487};
488
489/* Functions for treating an mmap'ed file as a buffer */
490
491static int
Andrew M. Kuchling961fe172000-06-03 19:41:42 +0000492mmap_buffer_getreadbuf(mmap_object *self, int index, const void **ptr)
Andrew M. Kuchling1ed7d2d2000-03-30 21:14:30 +0000493{
Guido van Rossum09fdf072000-03-31 01:17:07 +0000494 CHECK_VALID(-1);
495 if ( index != 0 ) {
496 PyErr_SetString(PyExc_SystemError,
497 "Accessing non-existent mmap segment");
498 return -1;
499 }
500 *ptr = self->data;
501 return self->size;
Andrew M. Kuchling1ed7d2d2000-03-30 21:14:30 +0000502}
503
504static int
505mmap_buffer_getwritebuf(self, index, ptr)
Guido van Rossum09fdf072000-03-31 01:17:07 +0000506 mmap_object *self;
507 int index;
508 const void **ptr;
Andrew M. Kuchling1ed7d2d2000-03-30 21:14:30 +0000509{
Guido van Rossum09fdf072000-03-31 01:17:07 +0000510 CHECK_VALID(-1);
511 if ( index != 0 ) {
512 PyErr_SetString(PyExc_SystemError,
513 "Accessing non-existent mmap segment");
514 return -1;
515 }
516 *ptr = self->data;
517 return self->size;
Andrew M. Kuchling1ed7d2d2000-03-30 21:14:30 +0000518}
519
520static int
521mmap_buffer_getsegcount(self, lenp)
Guido van Rossum09fdf072000-03-31 01:17:07 +0000522 mmap_object *self;
523 int *lenp;
Andrew M. Kuchling1ed7d2d2000-03-30 21:14:30 +0000524{
Guido van Rossum09fdf072000-03-31 01:17:07 +0000525 CHECK_VALID(-1);
526 if (lenp)
527 *lenp = self->size;
528 return 1;
Andrew M. Kuchling1ed7d2d2000-03-30 21:14:30 +0000529}
530
531static int
532mmap_buffer_getcharbuffer(self, index, ptr)
Guido van Rossum09fdf072000-03-31 01:17:07 +0000533 mmap_object *self;
534 int index;
535 const void **ptr;
Andrew M. Kuchling1ed7d2d2000-03-30 21:14:30 +0000536{
Guido van Rossum09fdf072000-03-31 01:17:07 +0000537 if ( index != 0 ) {
538 PyErr_SetString(PyExc_SystemError,
539 "accessing non-existent buffer segment");
540 return -1;
541 }
542 *ptr = (const char *)self->data;
543 return self->size;
Andrew M. Kuchling1ed7d2d2000-03-30 21:14:30 +0000544}
545
546static PyObject *
547mmap_object_getattr(mmap_object * self, char * name)
548{
Guido van Rossum09fdf072000-03-31 01:17:07 +0000549 return Py_FindMethod (mmap_object_methods, (PyObject *)self, name);
Andrew M. Kuchling1ed7d2d2000-03-30 21:14:30 +0000550}
551
552static int
553mmap_length(self)
Guido van Rossum09fdf072000-03-31 01:17:07 +0000554 mmap_object *self;
Andrew M. Kuchling1ed7d2d2000-03-30 21:14:30 +0000555{
Guido van Rossum09fdf072000-03-31 01:17:07 +0000556 CHECK_VALID(-1);
557 return self->size;
Andrew M. Kuchling1ed7d2d2000-03-30 21:14:30 +0000558}
559
560static PyObject *
561mmap_item(self, i)
Guido van Rossum09fdf072000-03-31 01:17:07 +0000562 mmap_object *self;
563 int i;
Andrew M. Kuchling1ed7d2d2000-03-30 21:14:30 +0000564{
Guido van Rossum09fdf072000-03-31 01:17:07 +0000565 CHECK_VALID(NULL);
566 if (i < 0 || i >= self->size) {
567 PyErr_SetString(PyExc_IndexError, "mmap index out of range");
568 return NULL;
569 }
570 return PyString_FromStringAndSize(self->data + i, 1);
Andrew M. Kuchling1ed7d2d2000-03-30 21:14:30 +0000571}
572
573static PyObject *
574mmap_slice(self, ilow, ihigh)
Guido van Rossum09fdf072000-03-31 01:17:07 +0000575 mmap_object *self;
576 int ilow, ihigh;
Andrew M. Kuchling1ed7d2d2000-03-30 21:14:30 +0000577{
Guido van Rossum09fdf072000-03-31 01:17:07 +0000578 CHECK_VALID(NULL);
579 if (ilow < 0)
580 ilow = 0;
581 else if (ilow > self->size)
582 ilow = self->size;
583 if (ihigh < 0)
584 ihigh = 0;
585 if (ihigh < ilow)
586 ihigh = ilow;
587 else if (ihigh > self->size)
588 ihigh = self->size;
589
590 return PyString_FromStringAndSize(self->data + ilow, ihigh-ilow);
Andrew M. Kuchling1ed7d2d2000-03-30 21:14:30 +0000591}
592
593static PyObject *
594mmap_concat(self, bb)
Guido van Rossum09fdf072000-03-31 01:17:07 +0000595 mmap_object *self;
596 PyObject *bb;
Andrew M. Kuchling1ed7d2d2000-03-30 21:14:30 +0000597{
Guido van Rossum09fdf072000-03-31 01:17:07 +0000598 CHECK_VALID(NULL);
599 PyErr_SetString(PyExc_SystemError,
600 "mmaps don't support concatenation");
601 return NULL;
Andrew M. Kuchling1ed7d2d2000-03-30 21:14:30 +0000602}
603
604static PyObject *
605mmap_repeat(self, n)
Guido van Rossum09fdf072000-03-31 01:17:07 +0000606 mmap_object *self;
607 int n;
Andrew M. Kuchling1ed7d2d2000-03-30 21:14:30 +0000608{
Guido van Rossum09fdf072000-03-31 01:17:07 +0000609 CHECK_VALID(NULL);
610 PyErr_SetString(PyExc_SystemError,
611 "mmaps don't support repeat operation");
612 return NULL;
Andrew M. Kuchling1ed7d2d2000-03-30 21:14:30 +0000613}
614
615static int
616mmap_ass_slice(self, ilow, ihigh, v)
Guido van Rossum09fdf072000-03-31 01:17:07 +0000617 mmap_object *self;
618 int ilow, ihigh;
619 PyObject *v;
Andrew M. Kuchling1ed7d2d2000-03-30 21:14:30 +0000620{
Guido van Rossum36d4f8b2000-04-10 21:34:37 +0000621 const char *buf;
Andrew M. Kuchling1ed7d2d2000-03-30 21:14:30 +0000622
Guido van Rossum09fdf072000-03-31 01:17:07 +0000623 CHECK_VALID(-1);
624 if (ilow < 0)
625 ilow = 0;
626 else if (ilow > self->size)
627 ilow = self->size;
628 if (ihigh < 0)
629 ihigh = 0;
630 if (ihigh < ilow)
631 ihigh = ilow;
632 else if (ihigh > self->size)
633 ihigh = self->size;
634
635 if (! (PyString_Check(v)) ) {
636 PyErr_SetString(PyExc_IndexError,
637 "mmap slice assignment must be a string");
638 return -1;
639 }
640 if ( PyString_Size(v) != (ihigh - ilow) ) {
641 PyErr_SetString(PyExc_IndexError,
642 "mmap slice assignment is wrong size");
643 return -1;
644 }
645 buf = PyString_AsString(v);
646 memcpy(self->data + ilow, buf, ihigh-ilow);
647 return 0;
Andrew M. Kuchling1ed7d2d2000-03-30 21:14:30 +0000648}
649
650static int
651mmap_ass_item(self, i, v)
Guido van Rossum09fdf072000-03-31 01:17:07 +0000652 mmap_object *self;
653 int i;
654 PyObject *v;
Andrew M. Kuchling1ed7d2d2000-03-30 21:14:30 +0000655{
Guido van Rossum36d4f8b2000-04-10 21:34:37 +0000656 const char *buf;
Andrew M. Kuchling1ed7d2d2000-03-30 21:14:30 +0000657
Guido van Rossum09fdf072000-03-31 01:17:07 +0000658 CHECK_VALID(-1);
659 if (i < 0 || i >= self->size) {
660 PyErr_SetString(PyExc_IndexError, "mmap index out of range");
661 return -1;
662 }
663 if (! (PyString_Check(v) && PyString_Size(v)==1) ) {
664 PyErr_SetString(PyExc_IndexError,
665 "mmap assignment must be single-character string");
666 return -1;
667 }
668 buf = PyString_AsString(v);
669 self->data[i] = buf[0];
670 return 0;
Andrew M. Kuchling1ed7d2d2000-03-30 21:14:30 +0000671}
672
673static PySequenceMethods mmap_as_sequence = {
Guido van Rossum09fdf072000-03-31 01:17:07 +0000674 (inquiry)mmap_length, /*sq_length*/
675 (binaryfunc)mmap_concat, /*sq_concat*/
676 (intargfunc)mmap_repeat, /*sq_repeat*/
677 (intargfunc)mmap_item, /*sq_item*/
678 (intintargfunc)mmap_slice, /*sq_slice*/
679 (intobjargproc)mmap_ass_item, /*sq_ass_item*/
680 (intintobjargproc)mmap_ass_slice, /*sq_ass_slice*/
Andrew M. Kuchling1ed7d2d2000-03-30 21:14:30 +0000681};
682
683static PyBufferProcs mmap_as_buffer = {
Guido van Rossum09fdf072000-03-31 01:17:07 +0000684 (getreadbufferproc)mmap_buffer_getreadbuf,
685 (getwritebufferproc)mmap_buffer_getwritebuf,
686 (getsegcountproc)mmap_buffer_getsegcount,
687 (getcharbufferproc)mmap_buffer_getcharbuffer,
Andrew M. Kuchling1ed7d2d2000-03-30 21:14:30 +0000688};
689
690static PyTypeObject mmap_object_type = {
Guido van Rossum09fdf072000-03-31 01:17:07 +0000691 PyObject_HEAD_INIT(0) /* patched in module init */
692 0, /* ob_size */
693 "mmap", /* tp_name */
694 sizeof(mmap_object), /* tp_size */
695 0, /* tp_itemsize */
696 /* methods */
697 (destructor) mmap_object_dealloc, /* tp_dealloc */
698 0, /* tp_print */
699 (getattrfunc) mmap_object_getattr, /* tp_getattr */
700 0, /* tp_setattr */
701 0, /* tp_compare */
702 0, /* tp_repr */
703 0, /* tp_as_number */
704 &mmap_as_sequence, /*tp_as_sequence*/
705 0, /*tp_as_mapping*/
706 0, /*tp_hash*/
707 0, /*tp_call*/
708 0, /*tp_str*/
709 0, /*tp_getattro*/
710 0, /*tp_setattro*/
711 &mmap_as_buffer, /*tp_as_buffer*/
712 Py_TPFLAGS_HAVE_GETCHARBUFFER, /*tp_flags*/
713 0, /*tp_doc*/
Andrew M. Kuchling1ed7d2d2000-03-30 21:14:30 +0000714};
715
Andrew M. Kuchling70d27422000-06-18 04:45:14 +0000716
717/* extract the map size from the given PyObject
718
719 The map size is restricted to [0, INT_MAX] because this is the current
720 Python limitation on object sizes. Although the mmap object *could* handle
721 a larger map size, there is no point because all the useful operations
722 (len(), slicing(), sequence indexing) are limited by a C int.
723
724 Returns -1 on error, with an apprpriate Python exception raised. On
725 success, the map size is returned. */
726static int
727_GetMapSize(o)
728 PyObject *o;
729{
730 if (PyInt_Check(o)) {
731 long i = PyInt_AsLong(o);
732 if (PyErr_Occurred())
733 return -1;
734 if (i < 0)
735 goto onnegoverflow;
736 if (i > INT_MAX)
737 goto onposoverflow;
738 return (int)i;
739 }
740 else if (PyLong_Check(o)) {
741 long i = PyLong_AsLong(o);
742 if (PyErr_Occurred()) {
743 /* yes negative overflow is mistaken for positive overflow
744 but not worth the trouble to check sign of 'i' */
745 if (PyErr_ExceptionMatches(PyExc_OverflowError))
746 goto onposoverflow;
747 else
748 return -1;
749 }
750 if (i < 0)
751 goto onnegoverflow;
752 if (i > INT_MAX)
753 goto onposoverflow;
754 return (int)i;
755 }
756 else {
757 PyErr_SetString(PyExc_TypeError,
758 "map size must be an integral value");
759 return -1;
760 }
761
762onnegoverflow:
763 PyErr_SetString(PyExc_OverflowError,
764 "memory mapped size must be positive");
765 return -1;
766
767onposoverflow:
768 PyErr_SetString(PyExc_OverflowError,
769 "memory mapped size is too large (limited by C int)");
770 return -1;
771}
772
Andrew M. Kuchling1ed7d2d2000-03-30 21:14:30 +0000773#ifdef UNIX
774static PyObject *
775new_mmap_object (PyObject * self, PyObject * args, PyObject *kwdict)
776{
Guido van Rossum09fdf072000-03-31 01:17:07 +0000777 mmap_object * m_obj;
Andrew M. Kuchling70d27422000-06-18 04:45:14 +0000778 PyObject *map_size_obj = NULL;
779 int map_size;
Guido van Rossum09fdf072000-03-31 01:17:07 +0000780 int fd, flags = MAP_SHARED, prot = PROT_WRITE | PROT_READ;
Guido van Rossum09fdf072000-03-31 01:17:07 +0000781 char *keywords[] = {"file", "size", "flags", "prot", NULL};
Andrew M. Kuchling1ed7d2d2000-03-30 21:14:30 +0000782
Guido van Rossum09fdf072000-03-31 01:17:07 +0000783 if (!PyArg_ParseTupleAndKeywords(args, kwdict,
Andrew M. Kuchling70d27422000-06-18 04:45:14 +0000784 "iO|ii", keywords,
785 &fd, &map_size_obj, &flags, &prot)
Guido van Rossum09fdf072000-03-31 01:17:07 +0000786 )
787 return NULL;
Andrew M. Kuchling70d27422000-06-18 04:45:14 +0000788 map_size = _GetMapSize(map_size_obj);
789 if (map_size < 0)
790 return NULL;
791
Guido van Rossumb18618d2000-05-03 23:44:39 +0000792 m_obj = PyObject_New (mmap_object, &mmap_object_type);
Guido van Rossum09fdf072000-03-31 01:17:07 +0000793 if (m_obj == NULL) {return NULL;}
794 m_obj->size = (size_t) map_size;
795 m_obj->pos = (size_t) 0;
Andrew M. Kuchling7b9fb922000-06-17 22:41:22 +0000796 m_obj->fd = fd;
Guido van Rossum09fdf072000-03-31 01:17:07 +0000797 m_obj->data = mmap(NULL, map_size,
798 prot, flags,
799 fd, 0);
800 if (m_obj->data == (void *)-1)
801 {
802 Py_DECREF(m_obj);
803 PyErr_SetFromErrno(mmap_module_error);
804 return NULL;
805 }
806 return (PyObject *)m_obj;
Andrew M. Kuchling1ed7d2d2000-03-30 21:14:30 +0000807}
808#endif /* UNIX */
809
810#ifdef MS_WIN32
811static PyObject *
812new_mmap_object (PyObject * self, PyObject * args)
813{
Guido van Rossum09fdf072000-03-31 01:17:07 +0000814 mmap_object * m_obj;
Andrew M. Kuchling70d27422000-06-18 04:45:14 +0000815 PyObject *map_size_obj = NULL;
816 int map_size;
Guido van Rossum09fdf072000-03-31 01:17:07 +0000817 char * tagname = "";
Andrew M. Kuchling1ed7d2d2000-03-30 21:14:30 +0000818
Guido van Rossum09fdf072000-03-31 01:17:07 +0000819 DWORD dwErr = 0;
820 int fileno;
Andrew M. Kuchling70d27422000-06-18 04:45:14 +0000821 INT_PTR fh = 0;
Andrew M. Kuchling1ed7d2d2000-03-30 21:14:30 +0000822
Guido van Rossum09fdf072000-03-31 01:17:07 +0000823 /* Patch the object type */
824 mmap_object_type.ob_type = &PyType_Type;
825
826 if (!PyArg_ParseTuple(args,
Andrew M. Kuchling70d27422000-06-18 04:45:14 +0000827 "iO|z",
Guido van Rossum09fdf072000-03-31 01:17:07 +0000828 &fileno,
Andrew M. Kuchling70d27422000-06-18 04:45:14 +0000829 &map_size_obj,
Guido van Rossum09fdf072000-03-31 01:17:07 +0000830 &tagname)
831 )
832 return NULL;
Andrew M. Kuchling1ed7d2d2000-03-30 21:14:30 +0000833
Andrew M. Kuchling70d27422000-06-18 04:45:14 +0000834 map_size = _GetMapSize(map_size_obj);
835 if (map_size < 0)
836 return NULL;
837
Guido van Rossum09fdf072000-03-31 01:17:07 +0000838 /* if an actual filename has been specified */
839 if (fileno != 0) {
840 fh = _get_osfhandle(fileno);
841 if (fh==-1) {
842 PyErr_SetFromErrno(mmap_module_error);
843 return NULL;
Andrew M. Kuchling1ed7d2d2000-03-30 21:14:30 +0000844 }
Fred Drake1ef4e2d2000-04-05 14:15:31 +0000845 /* Win9x appears to need us seeked to zero */
846 fseek(&_iob[fileno], 0, SEEK_SET);
Guido van Rossum09fdf072000-03-31 01:17:07 +0000847 }
Andrew M. Kuchling1ed7d2d2000-03-30 21:14:30 +0000848
Guido van Rossumb18618d2000-05-03 23:44:39 +0000849 m_obj = PyObject_New (mmap_object, &mmap_object_type);
Guido van Rossum09fdf072000-03-31 01:17:07 +0000850
851 if (fh) {
852 m_obj->file_handle = fh;
853 if (!map_size) {
854 m_obj->size = GetFileSize ((HANDLE)fh, NULL);
Andrew M. Kuchling1ed7d2d2000-03-30 21:14:30 +0000855 } else {
Guido van Rossum09fdf072000-03-31 01:17:07 +0000856 m_obj->size = map_size;
Andrew M. Kuchling1ed7d2d2000-03-30 21:14:30 +0000857 }
Guido van Rossum09fdf072000-03-31 01:17:07 +0000858 }
859 else {
Andrew M. Kuchling70d27422000-06-18 04:45:14 +0000860 m_obj->file_handle = (INT_PTR) -1;
Guido van Rossum09fdf072000-03-31 01:17:07 +0000861 m_obj->size = map_size;
862 }
863
864 /* set the initial position */
865 m_obj->pos = (size_t) 0;
866
867 m_obj->map_handle = CreateFileMapping ((HANDLE) m_obj->file_handle,
868 NULL,
869 PAGE_READWRITE,
870 0,
871 m_obj->size,
872 tagname);
873 if (m_obj->map_handle != NULL) {
874 m_obj->data = (char *) MapViewOfFile (m_obj->map_handle,
875 FILE_MAP_WRITE,
876 0,
877 0,
878 0);
879 if (m_obj->data != NULL) {
880 return ((PyObject *) m_obj);
881 } else {
882 dwErr = GetLastError();
883 }
884 } else {
885 dwErr = GetLastError();
886 }
887 PyErr_SetFromWindowsErr(dwErr);
888 return (NULL);
Andrew M. Kuchling1ed7d2d2000-03-30 21:14:30 +0000889}
890#endif /* MS_WIN32 */
891
892/* List of functions exported by this module */
893static struct PyMethodDef mmap_functions[] = {
Guido van Rossum09fdf072000-03-31 01:17:07 +0000894 {"mmap", (PyCFunction) new_mmap_object,
895 METH_VARARGS|METH_KEYWORDS},
896 {NULL, NULL} /* Sentinel */
Andrew M. Kuchling1ed7d2d2000-03-30 21:14:30 +0000897};
898
899#ifdef MS_WIN32
Guido van Rossum09fdf072000-03-31 01:17:07 +0000900__declspec(dllexport) void
Andrew M. Kuchling1ed7d2d2000-03-30 21:14:30 +0000901#endif /* MS_WIN32 */
902#ifdef UNIX
903extern void
904#endif
905
906initmmap(void)
907{
Guido van Rossum09fdf072000-03-31 01:17:07 +0000908 PyObject *dict, *module;
909 module = Py_InitModule ("mmap", mmap_functions);
910 dict = PyModule_GetDict (module);
911 mmap_module_error = PyExc_EnvironmentError;
912 Py_INCREF(mmap_module_error);
913 PyDict_SetItemString (dict, "error", mmap_module_error);
Andrew M. Kuchling1ed7d2d2000-03-30 21:14:30 +0000914#ifdef PROT_EXEC
Guido van Rossum09fdf072000-03-31 01:17:07 +0000915 PyDict_SetItemString (dict, "PROT_EXEC", PyInt_FromLong(PROT_EXEC) );
Andrew M. Kuchling1ed7d2d2000-03-30 21:14:30 +0000916#endif
917#ifdef PROT_READ
Guido van Rossum09fdf072000-03-31 01:17:07 +0000918 PyDict_SetItemString (dict, "PROT_READ", PyInt_FromLong(PROT_READ) );
Andrew M. Kuchling1ed7d2d2000-03-30 21:14:30 +0000919#endif
920#ifdef PROT_WRITE
Guido van Rossum09fdf072000-03-31 01:17:07 +0000921 PyDict_SetItemString (dict, "PROT_WRITE", PyInt_FromLong(PROT_WRITE) );
Andrew M. Kuchling1ed7d2d2000-03-30 21:14:30 +0000922#endif
923
924#ifdef MAP_SHARED
Guido van Rossum09fdf072000-03-31 01:17:07 +0000925 PyDict_SetItemString (dict, "MAP_SHARED", PyInt_FromLong(MAP_SHARED) );
Andrew M. Kuchling1ed7d2d2000-03-30 21:14:30 +0000926#endif
927#ifdef MAP_PRIVATE
Guido van Rossum09fdf072000-03-31 01:17:07 +0000928 PyDict_SetItemString (dict, "MAP_PRIVATE",
929 PyInt_FromLong(MAP_PRIVATE) );
Andrew M. Kuchling1ed7d2d2000-03-30 21:14:30 +0000930#endif
931#ifdef MAP_DENYWRITE
Guido van Rossum09fdf072000-03-31 01:17:07 +0000932 PyDict_SetItemString (dict, "MAP_DENYWRITE",
933 PyInt_FromLong(MAP_DENYWRITE) );
Andrew M. Kuchling1ed7d2d2000-03-30 21:14:30 +0000934#endif
935#ifdef MAP_EXECUTABLE
Guido van Rossum09fdf072000-03-31 01:17:07 +0000936 PyDict_SetItemString (dict, "MAP_EXECUTABLE",
937 PyInt_FromLong(MAP_EXECUTABLE) );
Andrew M. Kuchling1ed7d2d2000-03-30 21:14:30 +0000938#endif
939#ifdef MAP_ANON
Guido van Rossum09fdf072000-03-31 01:17:07 +0000940 PyDict_SetItemString (dict, "MAP_ANON", PyInt_FromLong(MAP_ANON) );
941 PyDict_SetItemString (dict, "MAP_ANONYMOUS",
942 PyInt_FromLong(MAP_ANON) );
Andrew M. Kuchling1ed7d2d2000-03-30 21:14:30 +0000943#endif
944
945#ifdef UNIX
Guido van Rossum09fdf072000-03-31 01:17:07 +0000946 PyDict_SetItemString (dict, "PAGESIZE",
947 PyInt_FromLong( (long)getpagesize() ) );
Andrew M. Kuchling1ed7d2d2000-03-30 21:14:30 +0000948#endif
Guido van Rossum09fdf072000-03-31 01:17:07 +0000949#ifdef MS_WIN32
950 {
951 SYSTEM_INFO si;
952 GetSystemInfo(&si);
953 PyDict_SetItemString (dict, "PAGESIZE",
954 PyInt_FromLong( si.dwPageSize ) );
955 }
956#endif /* MS_WIN32 */
Andrew M. Kuchling1ed7d2d2000-03-30 21:14:30 +0000957
958}
Andrew M. Kuchling961fe172000-06-03 19:41:42 +0000959