blob: 03960fc53392d210f97e61f93b12da508ac72609 [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
337#ifndef MREMAP_MAYMOVE
338} 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
Guido van Rossum09fdf072000-03-31 01:17:07 +0000346 newmap = mremap(self->data, self->size, new_size, MREMAP_MAYMOVE);
347 if (newmap == (void *)-1)
348 {
349 PyErr_SetFromErrno(mmap_module_error);
350 return NULL;
351 }
352 self->data = newmap;
353 self->size = new_size;
354 Py_INCREF(Py_None);
355 return Py_None;
Andrew M. Kuchling1ed7d2d2000-03-30 21:14:30 +0000356#endif /* MREMAP_MAYMOVE */
357#endif /* UNIX */
358}
359}
360
361static PyObject *
362mmap_tell_method (mmap_object * self, PyObject * args)
363{
Guido van Rossum09fdf072000-03-31 01:17:07 +0000364 CHECK_VALID(NULL);
Andrew M. Kuchling841b9fb2000-06-03 20:43:43 +0000365 if (!PyArg_ParseTuple(args, ":tell"))
Andrew M. Kuchling961fe172000-06-03 19:41:42 +0000366 return NULL;
Guido van Rossum09fdf072000-03-31 01:17:07 +0000367 return (Py_BuildValue ("l", self->pos) );
Andrew M. Kuchling1ed7d2d2000-03-30 21:14:30 +0000368}
369
370static PyObject *
371mmap_flush_method (mmap_object * self, PyObject * args)
372{
Guido van Rossum09fdf072000-03-31 01:17:07 +0000373 size_t offset = 0;
374 size_t size = self->size;
375 CHECK_VALID(NULL);
376 if (!PyArg_ParseTuple (args, "|ll", &offset, &size)) {
377 return NULL;
378 } else if ((offset + size) > self->size) {
379 PyErr_SetString (PyExc_ValueError,
380 "flush values out of range");
381 return NULL;
382 } else {
Andrew M. Kuchling1ed7d2d2000-03-30 21:14:30 +0000383#ifdef MS_WIN32
Guido van Rossum09fdf072000-03-31 01:17:07 +0000384 return (Py_BuildValue (
385 "l", FlushViewOfFile (self->data+offset, size)));
Andrew M. Kuchling1ed7d2d2000-03-30 21:14:30 +0000386#endif /* MS_WIN32 */
387#ifdef UNIX
Guido van Rossum09fdf072000-03-31 01:17:07 +0000388 /* XXX semantics of return value? */
389 /* XXX flags for msync? */
390 if (-1 == msync(self->data + offset, size,
Andrew M. Kuchling9bc5f332000-06-18 04:25:08 +0000391 MS_SYNC))
Guido van Rossum09fdf072000-03-31 01:17:07 +0000392 {
393 PyErr_SetFromErrno(mmap_module_error);
394 return NULL;
Andrew M. Kuchling1ed7d2d2000-03-30 21:14:30 +0000395 }
Guido van Rossum09fdf072000-03-31 01:17:07 +0000396 return Py_BuildValue ("l", 0);
397#endif /* UNIX */
398 }
Andrew M. Kuchling1ed7d2d2000-03-30 21:14:30 +0000399}
400
401static PyObject *
402mmap_seek_method (mmap_object * self, PyObject * args)
403{
Andrew M. Kuchling70d27422000-06-18 04:45:14 +0000404 int dist;
Guido van Rossum09fdf072000-03-31 01:17:07 +0000405 int how=0;
406 CHECK_VALID(NULL);
Andrew M. Kuchling70d27422000-06-18 04:45:14 +0000407 if (!PyArg_ParseTuple (args, "i|i", &dist, &how)) {
Guido van Rossum09fdf072000-03-31 01:17:07 +0000408 return(NULL);
409 } else {
Andrew M. Kuchling70d27422000-06-18 04:45:14 +0000410 size_t where;
Guido van Rossum09fdf072000-03-31 01:17:07 +0000411 switch (how) {
Andrew M. Kuchling70d27422000-06-18 04:45:14 +0000412 case 0: /* relative to start */
413 if (dist < 0)
414 goto onoutofrange;
Guido van Rossum09fdf072000-03-31 01:17:07 +0000415 where = dist;
416 break;
Andrew M. Kuchling70d27422000-06-18 04:45:14 +0000417 case 1: /* relative to current position */
418 if ((int)self->pos + dist < 0)
419 goto onoutofrange;
Guido van Rossum09fdf072000-03-31 01:17:07 +0000420 where = self->pos + dist;
421 break;
Andrew M. Kuchling70d27422000-06-18 04:45:14 +0000422 case 2: /* relative to end */
423 if ((int)self->size + dist < 0)
424 goto onoutofrange;
425 where = self->size + dist;
Guido van Rossum09fdf072000-03-31 01:17:07 +0000426 break;
427 default:
428 PyErr_SetString (PyExc_ValueError,
429 "unknown seek type");
430 return NULL;
Andrew M. Kuchling1ed7d2d2000-03-30 21:14:30 +0000431 }
Andrew M. Kuchling70d27422000-06-18 04:45:14 +0000432 if (where > self->size)
433 goto onoutofrange;
434 self->pos = where;
435 Py_INCREF (Py_None);
436 return (Py_None);
Guido van Rossum09fdf072000-03-31 01:17:07 +0000437 }
Andrew M. Kuchling70d27422000-06-18 04:45:14 +0000438
439onoutofrange:
440 PyErr_SetString (PyExc_ValueError, "seek out of range");
441 return NULL;
Andrew M. Kuchling1ed7d2d2000-03-30 21:14:30 +0000442}
443
444static PyObject *
445mmap_move_method (mmap_object * self, PyObject * args)
446{
Guido van Rossum09fdf072000-03-31 01:17:07 +0000447 unsigned long dest, src, count;
448 CHECK_VALID(NULL);
449 if (!PyArg_ParseTuple (args, "iii", &dest, &src, &count)) {
450 return NULL;
451 } else {
452 /* bounds check the values */
453 if (/* end of source after end of data?? */
454 ((src+count) > self->size)
455 /* dest will fit? */
456 || (dest+count > self->size)) {
457 PyErr_SetString (PyExc_ValueError,
458 "source or destination out of range");
459 return NULL;
Andrew M. Kuchling1ed7d2d2000-03-30 21:14:30 +0000460 } else {
Guido van Rossum09fdf072000-03-31 01:17:07 +0000461 memmove (self->data+dest, self->data+src, count);
462 Py_INCREF (Py_None);
463 return Py_None;
Andrew M. Kuchling1ed7d2d2000-03-30 21:14:30 +0000464 }
Guido van Rossum09fdf072000-03-31 01:17:07 +0000465 }
Andrew M. Kuchling1ed7d2d2000-03-30 21:14:30 +0000466}
467
468static struct PyMethodDef mmap_object_methods[] = {
Guido van Rossum09fdf072000-03-31 01:17:07 +0000469 {"close", (PyCFunction) mmap_close_method, 1},
470 {"find", (PyCFunction) mmap_find_method, 1},
471 {"flush", (PyCFunction) mmap_flush_method, 1},
472 {"move", (PyCFunction) mmap_move_method, 1},
473 {"read", (PyCFunction) mmap_read_method, 1},
474 {"read_byte", (PyCFunction) mmap_read_byte_method, 1},
475 {"readline", (PyCFunction) mmap_read_line_method, 1},
476 {"resize", (PyCFunction) mmap_resize_method, 1},
477 {"seek", (PyCFunction) mmap_seek_method, 1},
478 {"size", (PyCFunction) mmap_size_method, 1},
479 {"tell", (PyCFunction) mmap_tell_method, 1},
480 {"write", (PyCFunction) mmap_write_method, 1},
481 {"write_byte", (PyCFunction) mmap_write_byte_method, 1},
482 {NULL, NULL} /* sentinel */
Andrew M. Kuchling1ed7d2d2000-03-30 21:14:30 +0000483};
484
485/* Functions for treating an mmap'ed file as a buffer */
486
487static int
Andrew M. Kuchling961fe172000-06-03 19:41:42 +0000488mmap_buffer_getreadbuf(mmap_object *self, int index, const void **ptr)
Andrew M. Kuchling1ed7d2d2000-03-30 21:14:30 +0000489{
Guido van Rossum09fdf072000-03-31 01:17:07 +0000490 CHECK_VALID(-1);
491 if ( index != 0 ) {
492 PyErr_SetString(PyExc_SystemError,
493 "Accessing non-existent mmap segment");
494 return -1;
495 }
496 *ptr = self->data;
497 return self->size;
Andrew M. Kuchling1ed7d2d2000-03-30 21:14:30 +0000498}
499
500static int
501mmap_buffer_getwritebuf(self, index, ptr)
Guido van Rossum09fdf072000-03-31 01:17:07 +0000502 mmap_object *self;
503 int index;
504 const void **ptr;
Andrew M. Kuchling1ed7d2d2000-03-30 21:14:30 +0000505{
Guido van Rossum09fdf072000-03-31 01:17:07 +0000506 CHECK_VALID(-1);
507 if ( index != 0 ) {
508 PyErr_SetString(PyExc_SystemError,
509 "Accessing non-existent mmap segment");
510 return -1;
511 }
512 *ptr = self->data;
513 return self->size;
Andrew M. Kuchling1ed7d2d2000-03-30 21:14:30 +0000514}
515
516static int
517mmap_buffer_getsegcount(self, lenp)
Guido van Rossum09fdf072000-03-31 01:17:07 +0000518 mmap_object *self;
519 int *lenp;
Andrew M. Kuchling1ed7d2d2000-03-30 21:14:30 +0000520{
Guido van Rossum09fdf072000-03-31 01:17:07 +0000521 CHECK_VALID(-1);
522 if (lenp)
523 *lenp = self->size;
524 return 1;
Andrew M. Kuchling1ed7d2d2000-03-30 21:14:30 +0000525}
526
527static int
528mmap_buffer_getcharbuffer(self, index, ptr)
Guido van Rossum09fdf072000-03-31 01:17:07 +0000529 mmap_object *self;
530 int index;
531 const void **ptr;
Andrew M. Kuchling1ed7d2d2000-03-30 21:14:30 +0000532{
Guido van Rossum09fdf072000-03-31 01:17:07 +0000533 if ( index != 0 ) {
534 PyErr_SetString(PyExc_SystemError,
535 "accessing non-existent buffer segment");
536 return -1;
537 }
538 *ptr = (const char *)self->data;
539 return self->size;
Andrew M. Kuchling1ed7d2d2000-03-30 21:14:30 +0000540}
541
542static PyObject *
543mmap_object_getattr(mmap_object * self, char * name)
544{
Guido van Rossum09fdf072000-03-31 01:17:07 +0000545 return Py_FindMethod (mmap_object_methods, (PyObject *)self, name);
Andrew M. Kuchling1ed7d2d2000-03-30 21:14:30 +0000546}
547
548static int
549mmap_length(self)
Guido van Rossum09fdf072000-03-31 01:17:07 +0000550 mmap_object *self;
Andrew M. Kuchling1ed7d2d2000-03-30 21:14:30 +0000551{
Guido van Rossum09fdf072000-03-31 01:17:07 +0000552 CHECK_VALID(-1);
553 return self->size;
Andrew M. Kuchling1ed7d2d2000-03-30 21:14:30 +0000554}
555
556static PyObject *
557mmap_item(self, i)
Guido van Rossum09fdf072000-03-31 01:17:07 +0000558 mmap_object *self;
559 int i;
Andrew M. Kuchling1ed7d2d2000-03-30 21:14:30 +0000560{
Guido van Rossum09fdf072000-03-31 01:17:07 +0000561 CHECK_VALID(NULL);
562 if (i < 0 || i >= self->size) {
563 PyErr_SetString(PyExc_IndexError, "mmap index out of range");
564 return NULL;
565 }
566 return PyString_FromStringAndSize(self->data + i, 1);
Andrew M. Kuchling1ed7d2d2000-03-30 21:14:30 +0000567}
568
569static PyObject *
570mmap_slice(self, ilow, ihigh)
Guido van Rossum09fdf072000-03-31 01:17:07 +0000571 mmap_object *self;
572 int ilow, ihigh;
Andrew M. Kuchling1ed7d2d2000-03-30 21:14:30 +0000573{
Guido van Rossum09fdf072000-03-31 01:17:07 +0000574 CHECK_VALID(NULL);
575 if (ilow < 0)
576 ilow = 0;
577 else if (ilow > self->size)
578 ilow = self->size;
579 if (ihigh < 0)
580 ihigh = 0;
581 if (ihigh < ilow)
582 ihigh = ilow;
583 else if (ihigh > self->size)
584 ihigh = self->size;
585
586 return PyString_FromStringAndSize(self->data + ilow, ihigh-ilow);
Andrew M. Kuchling1ed7d2d2000-03-30 21:14:30 +0000587}
588
589static PyObject *
590mmap_concat(self, bb)
Guido van Rossum09fdf072000-03-31 01:17:07 +0000591 mmap_object *self;
592 PyObject *bb;
Andrew M. Kuchling1ed7d2d2000-03-30 21:14:30 +0000593{
Guido van Rossum09fdf072000-03-31 01:17:07 +0000594 CHECK_VALID(NULL);
595 PyErr_SetString(PyExc_SystemError,
596 "mmaps don't support concatenation");
597 return NULL;
Andrew M. Kuchling1ed7d2d2000-03-30 21:14:30 +0000598}
599
600static PyObject *
601mmap_repeat(self, n)
Guido van Rossum09fdf072000-03-31 01:17:07 +0000602 mmap_object *self;
603 int n;
Andrew M. Kuchling1ed7d2d2000-03-30 21:14:30 +0000604{
Guido van Rossum09fdf072000-03-31 01:17:07 +0000605 CHECK_VALID(NULL);
606 PyErr_SetString(PyExc_SystemError,
607 "mmaps don't support repeat operation");
608 return NULL;
Andrew M. Kuchling1ed7d2d2000-03-30 21:14:30 +0000609}
610
611static int
612mmap_ass_slice(self, ilow, ihigh, v)
Guido van Rossum09fdf072000-03-31 01:17:07 +0000613 mmap_object *self;
614 int ilow, ihigh;
615 PyObject *v;
Andrew M. Kuchling1ed7d2d2000-03-30 21:14:30 +0000616{
Guido van Rossum36d4f8b2000-04-10 21:34:37 +0000617 const char *buf;
Andrew M. Kuchling1ed7d2d2000-03-30 21:14:30 +0000618
Guido van Rossum09fdf072000-03-31 01:17:07 +0000619 CHECK_VALID(-1);
620 if (ilow < 0)
621 ilow = 0;
622 else if (ilow > self->size)
623 ilow = self->size;
624 if (ihigh < 0)
625 ihigh = 0;
626 if (ihigh < ilow)
627 ihigh = ilow;
628 else if (ihigh > self->size)
629 ihigh = self->size;
630
631 if (! (PyString_Check(v)) ) {
632 PyErr_SetString(PyExc_IndexError,
633 "mmap slice assignment must be a string");
634 return -1;
635 }
636 if ( PyString_Size(v) != (ihigh - ilow) ) {
637 PyErr_SetString(PyExc_IndexError,
638 "mmap slice assignment is wrong size");
639 return -1;
640 }
641 buf = PyString_AsString(v);
642 memcpy(self->data + ilow, buf, ihigh-ilow);
643 return 0;
Andrew M. Kuchling1ed7d2d2000-03-30 21:14:30 +0000644}
645
646static int
647mmap_ass_item(self, i, v)
Guido van Rossum09fdf072000-03-31 01:17:07 +0000648 mmap_object *self;
649 int i;
650 PyObject *v;
Andrew M. Kuchling1ed7d2d2000-03-30 21:14:30 +0000651{
Guido van Rossum36d4f8b2000-04-10 21:34:37 +0000652 const char *buf;
Andrew M. Kuchling1ed7d2d2000-03-30 21:14:30 +0000653
Guido van Rossum09fdf072000-03-31 01:17:07 +0000654 CHECK_VALID(-1);
655 if (i < 0 || i >= self->size) {
656 PyErr_SetString(PyExc_IndexError, "mmap index out of range");
657 return -1;
658 }
659 if (! (PyString_Check(v) && PyString_Size(v)==1) ) {
660 PyErr_SetString(PyExc_IndexError,
661 "mmap assignment must be single-character string");
662 return -1;
663 }
664 buf = PyString_AsString(v);
665 self->data[i] = buf[0];
666 return 0;
Andrew M. Kuchling1ed7d2d2000-03-30 21:14:30 +0000667}
668
669static PySequenceMethods mmap_as_sequence = {
Guido van Rossum09fdf072000-03-31 01:17:07 +0000670 (inquiry)mmap_length, /*sq_length*/
671 (binaryfunc)mmap_concat, /*sq_concat*/
672 (intargfunc)mmap_repeat, /*sq_repeat*/
673 (intargfunc)mmap_item, /*sq_item*/
674 (intintargfunc)mmap_slice, /*sq_slice*/
675 (intobjargproc)mmap_ass_item, /*sq_ass_item*/
676 (intintobjargproc)mmap_ass_slice, /*sq_ass_slice*/
Andrew M. Kuchling1ed7d2d2000-03-30 21:14:30 +0000677};
678
679static PyBufferProcs mmap_as_buffer = {
Guido van Rossum09fdf072000-03-31 01:17:07 +0000680 (getreadbufferproc)mmap_buffer_getreadbuf,
681 (getwritebufferproc)mmap_buffer_getwritebuf,
682 (getsegcountproc)mmap_buffer_getsegcount,
683 (getcharbufferproc)mmap_buffer_getcharbuffer,
Andrew M. Kuchling1ed7d2d2000-03-30 21:14:30 +0000684};
685
686static PyTypeObject mmap_object_type = {
Guido van Rossum09fdf072000-03-31 01:17:07 +0000687 PyObject_HEAD_INIT(0) /* patched in module init */
688 0, /* ob_size */
689 "mmap", /* tp_name */
690 sizeof(mmap_object), /* tp_size */
691 0, /* tp_itemsize */
692 /* methods */
693 (destructor) mmap_object_dealloc, /* tp_dealloc */
694 0, /* tp_print */
695 (getattrfunc) mmap_object_getattr, /* tp_getattr */
696 0, /* tp_setattr */
697 0, /* tp_compare */
698 0, /* tp_repr */
699 0, /* tp_as_number */
700 &mmap_as_sequence, /*tp_as_sequence*/
701 0, /*tp_as_mapping*/
702 0, /*tp_hash*/
703 0, /*tp_call*/
704 0, /*tp_str*/
705 0, /*tp_getattro*/
706 0, /*tp_setattro*/
707 &mmap_as_buffer, /*tp_as_buffer*/
708 Py_TPFLAGS_HAVE_GETCHARBUFFER, /*tp_flags*/
709 0, /*tp_doc*/
Andrew M. Kuchling1ed7d2d2000-03-30 21:14:30 +0000710};
711
Andrew M. Kuchling70d27422000-06-18 04:45:14 +0000712
713/* extract the map size from the given PyObject
714
715 The map size is restricted to [0, INT_MAX] because this is the current
716 Python limitation on object sizes. Although the mmap object *could* handle
717 a larger map size, there is no point because all the useful operations
718 (len(), slicing(), sequence indexing) are limited by a C int.
719
720 Returns -1 on error, with an apprpriate Python exception raised. On
721 success, the map size is returned. */
722static int
723_GetMapSize(o)
724 PyObject *o;
725{
726 if (PyInt_Check(o)) {
727 long i = PyInt_AsLong(o);
728 if (PyErr_Occurred())
729 return -1;
730 if (i < 0)
731 goto onnegoverflow;
732 if (i > INT_MAX)
733 goto onposoverflow;
734 return (int)i;
735 }
736 else if (PyLong_Check(o)) {
737 long i = PyLong_AsLong(o);
738 if (PyErr_Occurred()) {
739 /* yes negative overflow is mistaken for positive overflow
740 but not worth the trouble to check sign of 'i' */
741 if (PyErr_ExceptionMatches(PyExc_OverflowError))
742 goto onposoverflow;
743 else
744 return -1;
745 }
746 if (i < 0)
747 goto onnegoverflow;
748 if (i > INT_MAX)
749 goto onposoverflow;
750 return (int)i;
751 }
752 else {
753 PyErr_SetString(PyExc_TypeError,
754 "map size must be an integral value");
755 return -1;
756 }
757
758onnegoverflow:
759 PyErr_SetString(PyExc_OverflowError,
760 "memory mapped size must be positive");
761 return -1;
762
763onposoverflow:
764 PyErr_SetString(PyExc_OverflowError,
765 "memory mapped size is too large (limited by C int)");
766 return -1;
767}
768
Andrew M. Kuchling1ed7d2d2000-03-30 21:14:30 +0000769#ifdef UNIX
770static PyObject *
771new_mmap_object (PyObject * self, PyObject * args, PyObject *kwdict)
772{
Guido van Rossum09fdf072000-03-31 01:17:07 +0000773 mmap_object * m_obj;
Andrew M. Kuchling70d27422000-06-18 04:45:14 +0000774 PyObject *map_size_obj = NULL;
775 int map_size;
Guido van Rossum09fdf072000-03-31 01:17:07 +0000776 int fd, flags = MAP_SHARED, prot = PROT_WRITE | PROT_READ;
777 char * filename;
778 int namelen;
779 char *keywords[] = {"file", "size", "flags", "prot", NULL};
Andrew M. Kuchling1ed7d2d2000-03-30 21:14:30 +0000780
Guido van Rossum09fdf072000-03-31 01:17:07 +0000781 if (!PyArg_ParseTupleAndKeywords(args, kwdict,
Andrew M. Kuchling70d27422000-06-18 04:45:14 +0000782 "iO|ii", keywords,
783 &fd, &map_size_obj, &flags, &prot)
Guido van Rossum09fdf072000-03-31 01:17:07 +0000784 )
785 return NULL;
Andrew M. Kuchling70d27422000-06-18 04:45:14 +0000786 map_size = _GetMapSize(map_size_obj);
787 if (map_size < 0)
788 return NULL;
789
Guido van Rossumb18618d2000-05-03 23:44:39 +0000790 m_obj = PyObject_New (mmap_object, &mmap_object_type);
Guido van Rossum09fdf072000-03-31 01:17:07 +0000791 if (m_obj == NULL) {return NULL;}
792 m_obj->size = (size_t) map_size;
793 m_obj->pos = (size_t) 0;
Andrew M. Kuchling7b9fb922000-06-17 22:41:22 +0000794 m_obj->fd = fd;
Guido van Rossum09fdf072000-03-31 01:17:07 +0000795 m_obj->data = mmap(NULL, map_size,
796 prot, flags,
797 fd, 0);
798 if (m_obj->data == (void *)-1)
799 {
800 Py_DECREF(m_obj);
801 PyErr_SetFromErrno(mmap_module_error);
802 return NULL;
803 }
804 return (PyObject *)m_obj;
Andrew M. Kuchling1ed7d2d2000-03-30 21:14:30 +0000805}
806#endif /* UNIX */
807
808#ifdef MS_WIN32
809static PyObject *
810new_mmap_object (PyObject * self, PyObject * args)
811{
Guido van Rossum09fdf072000-03-31 01:17:07 +0000812 mmap_object * m_obj;
Andrew M. Kuchling70d27422000-06-18 04:45:14 +0000813 PyObject *map_size_obj = NULL;
814 int map_size;
Guido van Rossum09fdf072000-03-31 01:17:07 +0000815 char * tagname = "";
Andrew M. Kuchling1ed7d2d2000-03-30 21:14:30 +0000816
Guido van Rossum09fdf072000-03-31 01:17:07 +0000817 DWORD dwErr = 0;
818 int fileno;
Andrew M. Kuchling70d27422000-06-18 04:45:14 +0000819 INT_PTR fh = 0;
Andrew M. Kuchling1ed7d2d2000-03-30 21:14:30 +0000820
Guido van Rossum09fdf072000-03-31 01:17:07 +0000821 /* Patch the object type */
822 mmap_object_type.ob_type = &PyType_Type;
823
824 if (!PyArg_ParseTuple(args,
Andrew M. Kuchling70d27422000-06-18 04:45:14 +0000825 "iO|z",
Guido van Rossum09fdf072000-03-31 01:17:07 +0000826 &fileno,
Andrew M. Kuchling70d27422000-06-18 04:45:14 +0000827 &map_size_obj,
Guido van Rossum09fdf072000-03-31 01:17:07 +0000828 &tagname)
829 )
830 return NULL;
Andrew M. Kuchling1ed7d2d2000-03-30 21:14:30 +0000831
Andrew M. Kuchling70d27422000-06-18 04:45:14 +0000832 map_size = _GetMapSize(map_size_obj);
833 if (map_size < 0)
834 return NULL;
835
Guido van Rossum09fdf072000-03-31 01:17:07 +0000836 /* if an actual filename has been specified */
837 if (fileno != 0) {
838 fh = _get_osfhandle(fileno);
839 if (fh==-1) {
840 PyErr_SetFromErrno(mmap_module_error);
841 return NULL;
Andrew M. Kuchling1ed7d2d2000-03-30 21:14:30 +0000842 }
Fred Drake1ef4e2d2000-04-05 14:15:31 +0000843 /* Win9x appears to need us seeked to zero */
844 fseek(&_iob[fileno], 0, SEEK_SET);
Guido van Rossum09fdf072000-03-31 01:17:07 +0000845 }
Andrew M. Kuchling1ed7d2d2000-03-30 21:14:30 +0000846
Guido van Rossumb18618d2000-05-03 23:44:39 +0000847 m_obj = PyObject_New (mmap_object, &mmap_object_type);
Guido van Rossum09fdf072000-03-31 01:17:07 +0000848
849 if (fh) {
850 m_obj->file_handle = fh;
851 if (!map_size) {
852 m_obj->size = GetFileSize ((HANDLE)fh, NULL);
Andrew M. Kuchling1ed7d2d2000-03-30 21:14:30 +0000853 } else {
Guido van Rossum09fdf072000-03-31 01:17:07 +0000854 m_obj->size = map_size;
Andrew M. Kuchling1ed7d2d2000-03-30 21:14:30 +0000855 }
Guido van Rossum09fdf072000-03-31 01:17:07 +0000856 }
857 else {
Andrew M. Kuchling70d27422000-06-18 04:45:14 +0000858 m_obj->file_handle = (INT_PTR) -1;
Guido van Rossum09fdf072000-03-31 01:17:07 +0000859 m_obj->size = map_size;
860 }
861
862 /* set the initial position */
863 m_obj->pos = (size_t) 0;
864
865 m_obj->map_handle = CreateFileMapping ((HANDLE) m_obj->file_handle,
866 NULL,
867 PAGE_READWRITE,
868 0,
869 m_obj->size,
870 tagname);
871 if (m_obj->map_handle != NULL) {
872 m_obj->data = (char *) MapViewOfFile (m_obj->map_handle,
873 FILE_MAP_WRITE,
874 0,
875 0,
876 0);
877 if (m_obj->data != NULL) {
878 return ((PyObject *) m_obj);
879 } else {
880 dwErr = GetLastError();
881 }
882 } else {
883 dwErr = GetLastError();
884 }
885 PyErr_SetFromWindowsErr(dwErr);
886 return (NULL);
Andrew M. Kuchling1ed7d2d2000-03-30 21:14:30 +0000887}
888#endif /* MS_WIN32 */
889
890/* List of functions exported by this module */
891static struct PyMethodDef mmap_functions[] = {
Guido van Rossum09fdf072000-03-31 01:17:07 +0000892 {"mmap", (PyCFunction) new_mmap_object,
893 METH_VARARGS|METH_KEYWORDS},
894 {NULL, NULL} /* Sentinel */
Andrew M. Kuchling1ed7d2d2000-03-30 21:14:30 +0000895};
896
897#ifdef MS_WIN32
Guido van Rossum09fdf072000-03-31 01:17:07 +0000898__declspec(dllexport) void
Andrew M. Kuchling1ed7d2d2000-03-30 21:14:30 +0000899#endif /* MS_WIN32 */
900#ifdef UNIX
901extern void
902#endif
903
904initmmap(void)
905{
Guido van Rossum09fdf072000-03-31 01:17:07 +0000906 PyObject *dict, *module;
907 module = Py_InitModule ("mmap", mmap_functions);
908 dict = PyModule_GetDict (module);
909 mmap_module_error = PyExc_EnvironmentError;
910 Py_INCREF(mmap_module_error);
911 PyDict_SetItemString (dict, "error", mmap_module_error);
Andrew M. Kuchling1ed7d2d2000-03-30 21:14:30 +0000912#ifdef PROT_EXEC
Guido van Rossum09fdf072000-03-31 01:17:07 +0000913 PyDict_SetItemString (dict, "PROT_EXEC", PyInt_FromLong(PROT_EXEC) );
Andrew M. Kuchling1ed7d2d2000-03-30 21:14:30 +0000914#endif
915#ifdef PROT_READ
Guido van Rossum09fdf072000-03-31 01:17:07 +0000916 PyDict_SetItemString (dict, "PROT_READ", PyInt_FromLong(PROT_READ) );
Andrew M. Kuchling1ed7d2d2000-03-30 21:14:30 +0000917#endif
918#ifdef PROT_WRITE
Guido van Rossum09fdf072000-03-31 01:17:07 +0000919 PyDict_SetItemString (dict, "PROT_WRITE", PyInt_FromLong(PROT_WRITE) );
Andrew M. Kuchling1ed7d2d2000-03-30 21:14:30 +0000920#endif
921
922#ifdef MAP_SHARED
Guido van Rossum09fdf072000-03-31 01:17:07 +0000923 PyDict_SetItemString (dict, "MAP_SHARED", PyInt_FromLong(MAP_SHARED) );
Andrew M. Kuchling1ed7d2d2000-03-30 21:14:30 +0000924#endif
925#ifdef MAP_PRIVATE
Guido van Rossum09fdf072000-03-31 01:17:07 +0000926 PyDict_SetItemString (dict, "MAP_PRIVATE",
927 PyInt_FromLong(MAP_PRIVATE) );
Andrew M. Kuchling1ed7d2d2000-03-30 21:14:30 +0000928#endif
929#ifdef MAP_DENYWRITE
Guido van Rossum09fdf072000-03-31 01:17:07 +0000930 PyDict_SetItemString (dict, "MAP_DENYWRITE",
931 PyInt_FromLong(MAP_DENYWRITE) );
Andrew M. Kuchling1ed7d2d2000-03-30 21:14:30 +0000932#endif
933#ifdef MAP_EXECUTABLE
Guido van Rossum09fdf072000-03-31 01:17:07 +0000934 PyDict_SetItemString (dict, "MAP_EXECUTABLE",
935 PyInt_FromLong(MAP_EXECUTABLE) );
Andrew M. Kuchling1ed7d2d2000-03-30 21:14:30 +0000936#endif
937#ifdef MAP_ANON
Guido van Rossum09fdf072000-03-31 01:17:07 +0000938 PyDict_SetItemString (dict, "MAP_ANON", PyInt_FromLong(MAP_ANON) );
939 PyDict_SetItemString (dict, "MAP_ANONYMOUS",
940 PyInt_FromLong(MAP_ANON) );
Andrew M. Kuchling1ed7d2d2000-03-30 21:14:30 +0000941#endif
942
943#ifdef UNIX
Guido van Rossum09fdf072000-03-31 01:17:07 +0000944 PyDict_SetItemString (dict, "PAGESIZE",
945 PyInt_FromLong( (long)getpagesize() ) );
Andrew M. Kuchling1ed7d2d2000-03-30 21:14:30 +0000946#endif
Guido van Rossum09fdf072000-03-31 01:17:07 +0000947#ifdef MS_WIN32
948 {
949 SYSTEM_INFO si;
950 GetSystemInfo(&si);
951 PyDict_SetItemString (dict, "PAGESIZE",
952 PyInt_FromLong( si.dwPageSize ) );
953 }
954#endif /* MS_WIN32 */
Andrew M. Kuchling1ed7d2d2000-03-30 21:14:30 +0000955
956}
Andrew M. Kuchling961fe172000-06-03 19:41:42 +0000957