This commit was manufactured by cvs2svn to create tag 'r22b2-mac'.
[python/dscho.git] / Mac / Modules / macmodule.c
blobc71d8a9bb86aa996e3be1df1245af37ecd9620fd
1 /***********************************************************
2 Copyright 1991-1997 by Stichting Mathematisch Centrum, Amsterdam,
3 The Netherlands.
5 All Rights Reserved
7 Permission to use, copy, modify, and distribute this software and its
8 documentation for any purpose and without fee is hereby granted,
9 provided that the above copyright notice appear in all copies and that
10 both that copyright notice and this permission notice appear in
11 supporting documentation, and that the names of Stichting Mathematisch
12 Centrum or CWI not be used in advertising or publicity pertaining to
13 distribution of the software without specific, written prior permission.
15 STICHTING MATHEMATISCH CENTRUM DISCLAIMS ALL WARRANTIES WITH REGARD TO
16 THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
17 FITNESS, IN NO EVENT SHALL STICHTING MATHEMATISCH CENTRUM BE LIABLE
18 FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
19 WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
20 ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
21 OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
23 ******************************************************************/
25 /* Mac module implementation */
27 #include "Python.h"
28 #include "structseq.h"
29 #include "ceval.h"
31 #include <stdio.h>
32 #include <string.h>
33 #include <errno.h>
35 #if TARGET_API_MAC_OS8
36 /* Skip for Carbon */
37 #include "macstat.h"
38 #endif
40 #ifdef USE_GUSI
41 /* Remove defines from macstat.h */
42 #undef S_IFMT
43 #undef S_IFDIR
44 #undef S_IFREG
45 #undef S_IREAD
46 #undef S_IWRITE
47 #undef S_IEXEC
49 #ifdef USE_GUSI1
50 #include <GUSI.h>
51 #endif /* USE_GUSI1 */
52 #include <sys/types.h>
53 #include <sys/stat.h>
54 #else /* USE_GUSI */
55 #if TARGET_API_MAC_OS8
56 #define stat macstat
57 #endif
58 #endif /* USE_GUSI */
60 #ifdef USE_GUSI2
61 #define sync bad_sync
62 #include <unistd.h>
63 #include <fcntl.h>
64 #undef sync
65 int sync(void);
66 #else
67 #define mode_t int
68 #include <fcntl.h>
69 #ifdef _POSIX
70 #include <unistd.h>
71 #include <stat.h>
72 #endif
73 #endif
75 /* Optional routines, for some compiler/runtime combinations */
76 #if defined(USE_GUSI) || !defined(__MWERKS__)
77 #define WEHAVE_FDOPEN
78 #endif
79 #if defined(MPW) || defined(USE_GUSI)
80 #define WEHAVE_DUP
81 #endif
82 #if defined(USE_GUSI)
83 #define WEHAVE_FSTAT
84 #endif
86 #include "macdefs.h"
87 #ifdef USE_GUSI
88 #include <dirent.h>
89 #else
90 #include "dirent.h"
91 #endif
93 #ifndef MAXPATHLEN
94 #define MAXPATHLEN 1024
95 #endif
97 /* Prototypes for Unix simulation on Mac */
99 #ifndef USE_GUSI
101 int chdir(const char *path);
102 int mkdir(const char *path, int mode);
103 DIR * opendir(char *);
104 void closedir(DIR *);
105 struct dirent * readdir(DIR *);
106 int rmdir(const char *path);
107 int sync(void);
109 int unlink(const char *);
111 #endif /* USE_GUSI */
113 char *getwd(char *);
114 char *getbootvol(void);
117 /* Set a MAC-specific error from errno, and return NULL */
119 static PyObject *
120 mac_error()
122 return PyErr_SetFromErrno(PyExc_OSError);
125 /* MAC generic methods */
127 static PyObject *
128 mac_1str(args, func)
129 PyObject *args;
130 int (*func)(const char *);
132 char *path1;
133 int res;
134 if (!PyArg_ParseTuple(args, "s", &path1))
135 return NULL;
136 Py_BEGIN_ALLOW_THREADS
137 res = (*func)(path1);
138 Py_END_ALLOW_THREADS
139 if (res < 0)
140 return mac_error();
141 Py_INCREF(Py_None);
142 return Py_None;
145 static PyObject *
146 mac_2str(args, func)
147 PyObject *args;
148 int (*func)(const char *, const char *);
150 char *path1, *path2;
151 int res;
152 if (!PyArg_ParseTuple(args, "ss", &path1, &path2))
153 return NULL;
154 Py_BEGIN_ALLOW_THREADS
155 res = (*func)(path1, path2);
156 Py_END_ALLOW_THREADS
157 if (res < 0)
158 return mac_error();
159 Py_INCREF(Py_None);
160 return Py_None;
163 static PyObject *
164 mac_strint(args, func)
165 PyObject *args;
166 int (*func)(const char *, int);
168 char *path;
169 int i;
170 int res;
171 if (!PyArg_ParseTuple(args, "si", &path, &i))
172 return NULL;
173 Py_BEGIN_ALLOW_THREADS
174 res = (*func)(path, i);
175 Py_END_ALLOW_THREADS
176 if (res < 0)
177 return mac_error();
178 Py_INCREF(Py_None);
179 return Py_None;
182 static PyObject *
183 mac_chdir(self, args)
184 PyObject *self;
185 PyObject *args;
187 #ifdef USE_GUSI1
188 PyObject *rv;
190 /* Change MacOS's idea of wd too */
191 rv = mac_1str(args, chdir);
192 PyMac_FixGUSIcd();
193 return rv;
194 #else
195 return mac_1str(args, chdir);
196 #endif
200 static PyObject *
201 mac_close(self, args)
202 PyObject *self;
203 PyObject *args;
205 int fd, res;
206 if (!PyArg_ParseTuple(args, "i", &fd))
207 return NULL;
208 Py_BEGIN_ALLOW_THREADS
209 res = close(fd);
210 Py_END_ALLOW_THREADS
211 #ifndef USE_GUSI1
212 /* GUSI gives surious errors here? */
213 if (res < 0)
214 return mac_error();
215 #endif
216 Py_INCREF(Py_None);
217 return Py_None;
220 #ifdef WEHAVE_DUP
222 static PyObject *
223 mac_dup(self, args)
224 PyObject *self;
225 PyObject *args;
227 int fd;
228 if (!PyArg_ParseTuple(args, "i", &fd))
229 return NULL;
230 Py_BEGIN_ALLOW_THREADS
231 fd = dup(fd);
232 Py_END_ALLOW_THREADS
233 if (fd < 0)
234 return mac_error();
235 return PyInt_FromLong((long)fd);
238 #endif
240 #ifdef WEHAVE_FDOPEN
241 static PyObject *
242 mac_fdopen(self, args)
243 PyObject *self;
244 PyObject *args;
246 extern int fclose(FILE *);
247 int fd;
248 char *mode;
249 FILE *fp;
250 if (!PyArg_ParseTuple(args, "is", &fd, &mode))
251 return NULL;
252 Py_BEGIN_ALLOW_THREADS
253 fp = fdopen(fd, mode);
254 Py_END_ALLOW_THREADS
255 if (fp == NULL)
256 return mac_error();
257 return PyFile_FromFile(fp, "(fdopen)", mode, fclose);
259 #endif
261 #if TARGET_API_MAC_OS8
262 static PyObject *
263 mac_getbootvol(self, args)
264 PyObject *self;
265 PyObject *args;
267 char *res;
268 if (!PyArg_ParseTuple(args, ""))
269 return NULL;
270 Py_BEGIN_ALLOW_THREADS
271 res = getbootvol();
272 Py_END_ALLOW_THREADS
273 if (res == NULL)
274 return mac_error();
275 return PyString_FromString(res);
277 #endif
279 static PyObject *
280 mac_getcwd(self, args)
281 PyObject *self;
282 PyObject *args;
284 char path[MAXPATHLEN];
285 char *res;
286 if (!PyArg_ParseTuple(args, ""))
287 return NULL;
288 Py_BEGIN_ALLOW_THREADS
289 #ifdef USE_GUSI
290 res = getcwd(path, sizeof path);
291 #else
292 res = getwd(path);
293 #endif
294 Py_END_ALLOW_THREADS
295 if (res == NULL) {
296 return mac_error();
298 return PyString_FromString(res);
301 static PyObject *
302 mac_listdir(self, args)
303 PyObject *self;
304 PyObject *args;
306 char *name;
307 PyObject *d, *v;
308 DIR *dirp;
309 struct dirent *ep;
310 if (!PyArg_ParseTuple(args, "s", &name))
311 return NULL;
312 #ifdef USE_GUSI
313 /* Work around a bug in GUSI: if you opendir() a file it will
314 ** actually opendir() the parent directory.
317 struct stat stb;
318 int res;
320 res = stat(name, &stb);
321 if ( res < 0 )
322 return mac_error();
323 if (!S_ISDIR(stb.st_mode) ) {
324 errno = ENOTDIR;
325 return mac_error();
328 #endif
330 Py_BEGIN_ALLOW_THREADS
331 if ((dirp = opendir(name)) == NULL) {
332 Py_BLOCK_THREADS
333 return mac_error();
335 if ((d = PyList_New(0)) == NULL) {
336 closedir(dirp);
337 Py_BLOCK_THREADS
338 return NULL;
340 while ((ep = readdir(dirp)) != NULL) {
341 v = PyString_FromString(ep->d_name);
342 if (v == NULL) {
343 Py_DECREF(d);
344 d = NULL;
345 break;
347 if (PyList_Append(d, v) != 0) {
348 Py_DECREF(v);
349 Py_DECREF(d);
350 d = NULL;
351 break;
353 Py_DECREF(v);
355 closedir(dirp);
356 Py_END_ALLOW_THREADS
358 return d;
361 static PyObject *
362 mac_lseek(self, args)
363 PyObject *self;
364 PyObject *args;
366 int fd;
367 int where;
368 int how;
369 long res;
370 if (!PyArg_ParseTuple(args, "iii", &fd, &where, &how))
371 return NULL;
372 Py_BEGIN_ALLOW_THREADS
373 res = lseek(fd, (long)where, how);
374 Py_END_ALLOW_THREADS
375 if (res < 0)
376 return mac_error();
377 return PyInt_FromLong(res);
380 static PyObject *
381 mac_mkdir(self, args)
382 PyObject *self;
383 PyObject *args;
385 int res;
386 char *path;
387 int mode = 0777; /* Unused */
388 if (!PyArg_ParseTuple(args, "s|i", &path, &mode))
389 return NULL;
390 Py_BEGIN_ALLOW_THREADS
391 #ifdef USE_GUSI1
392 res = mkdir(path);
393 #else
394 res = mkdir(path, mode);
395 #endif
396 Py_END_ALLOW_THREADS
397 if (res < 0)
398 return mac_error();
399 Py_INCREF(Py_None);
400 return Py_None;
403 static PyObject *
404 mac_open(self, args)
405 PyObject *self;
406 PyObject *args;
408 char *path;
409 int mode;
410 int perm; /* Accepted but ignored */
411 int fd;
412 if (!PyArg_ParseTuple(args, "si|i", &path, &mode, &perm))
413 return NULL;
414 Py_BEGIN_ALLOW_THREADS
415 fd = open(path, mode);
416 Py_END_ALLOW_THREADS
417 if (fd < 0)
418 return mac_error();
419 return PyInt_FromLong((long)fd);
422 static PyObject *
423 mac_read(self, args)
424 PyObject *self;
425 PyObject *args;
427 int fd, size;
428 PyObject *buffer;
429 if (!PyArg_ParseTuple(args, "ii", &fd, &size))
430 return NULL;
431 buffer = PyString_FromStringAndSize((char *)NULL, size);
432 if (buffer == NULL)
433 return NULL;
434 Py_BEGIN_ALLOW_THREADS
435 size = read(fd, PyString_AsString(buffer), size);
436 Py_END_ALLOW_THREADS
437 if (size < 0) {
438 Py_DECREF(buffer);
439 return mac_error();
441 _PyString_Resize(&buffer, size);
442 return buffer;
445 static PyObject *
446 mac_rename(self, args)
447 PyObject *self;
448 PyObject *args;
450 return mac_2str(args, rename);
453 static PyObject *
454 mac_rmdir(self, args)
455 PyObject *self;
456 PyObject *args;
458 return mac_1str(args, rmdir);
461 static char stat_result__doc__[] =
462 "stat_result: Result from stat or lstat.\n\n\
463 This object may be accessed either as a tuple of\n\
464 (mode,ino,dev,nlink,uid,gid,size,atime,mtime,ctime)\n\
465 or via the attributes st_mode, st_ino, st_dev, st_nlink, st_uid, and so on.\n\
467 See os.stat for more information.\n";
469 #define COMMON_STAT_RESULT_FIELDS \
470 { "st_mode", "protection bits" }, \
471 { "st_ino", "inode" }, \
472 { "st_dev", "device" }, \
473 { "st_nlink", "number of hard links" }, \
474 { "st_uid", "user ID of owner" }, \
475 { "st_gid", "group ID of owner" }, \
476 { "st_size", "total size, in bytes" }, \
477 { "st_atime", "time of last access" }, \
478 { "st_mtime", "time of last modification" }, \
479 { "st_ctime", "time of last change" },
483 static PyStructSequence_Field stat_result_fields[] = {
484 COMMON_STAT_RESULT_FIELDS
488 static PyStructSequence_Desc stat_result_desc = {
489 "stat_result",
490 stat_result__doc__,
491 stat_result_fields,
495 static PyTypeObject StatResultType;
497 #ifdef TARGET_API_MAC_OS8
498 static PyStructSequence_Field xstat_result_fields[] = {
499 COMMON_STAT_RESULT_FIELDS
500 { "st_rsize" },
501 { "st_creator" },
502 { "st_type "},
506 static PyStructSequence_Desc xstat_result_desc = {
507 "xstat_result",
508 stat_result__doc__,
509 xstat_result_fields,
513 static PyTypeObject XStatResultType;
514 #endif
516 static PyObject *
517 _pystat_from_struct_stat(struct stat st, void* _mst)
519 PyObject *v;
521 #if TARGET_API_MAC_OS8
522 struct macstat *mst;
524 if (_mst != NULL)
525 v = PyStructSequence_New(&XStatResultType);
526 else
527 #endif
528 v = PyStructSequence_New(&StatResultType);
529 PyStructSequence_SET_ITEM(v, 0, PyInt_FromLong((long)st.st_mode));
530 PyStructSequence_SET_ITEM(v, 1, PyInt_FromLong((long)st.st_ino));
531 PyStructSequence_SET_ITEM(v, 2, PyInt_FromLong((long)st.st_dev));
532 PyStructSequence_SET_ITEM(v, 3, PyInt_FromLong((long)st.st_nlink));
533 PyStructSequence_SET_ITEM(v, 4, PyInt_FromLong((long)st.st_uid));
534 PyStructSequence_SET_ITEM(v, 5, PyInt_FromLong((long)st.st_gid));
535 PyStructSequence_SET_ITEM(v, 6, PyInt_FromLong((long)st.st_size));
536 PyStructSequence_SET_ITEM(v, 7,
537 PyFloat_FromDouble((double)st.st_atime));
538 PyStructSequence_SET_ITEM(v, 8,
539 PyFloat_FromDouble((double)st.st_mtime));
540 PyStructSequence_SET_ITEM(v, 9,
541 PyFloat_FromDouble((double)st.st_ctime));
542 #if TARGET_API_MAC_OS8
543 if (_mst != NULL) {
544 mst = (struct macstat *) _mst;
545 PyStructSequence_SET_ITEM(v, 10,
546 PyInt_FromLong((long)mst->st_rsize));
547 PyStructSequence_SET_ITEM(v, 11,
548 PyString_FromStringAndSize(mst->st_creator,
549 4));
550 PyStructSequence_SET_ITEM(v, 12,
551 PyString_FromStringAndSize(mst->st_type,
552 4));
554 #endif
556 if (PyErr_Occurred()) {
557 Py_DECREF(v);
558 return NULL;
561 return v;
565 static PyObject *
566 mac_stat(self, args)
567 PyObject *self;
568 PyObject *args;
570 struct stat st;
571 char *path;
572 int res;
573 if (!PyArg_ParseTuple(args, "s", &path))
574 return NULL;
575 Py_BEGIN_ALLOW_THREADS
576 res = stat(path, &st);
577 Py_END_ALLOW_THREADS
578 if (res != 0)
579 return mac_error();
581 return _pystat_from_struct_stat(st, NULL);
584 #ifdef WEHAVE_FSTAT
585 static PyObject *
586 mac_fstat(self, args)
587 PyObject *self;
588 PyObject *args;
590 struct stat st;
591 long fd;
592 int res;
593 if (!PyArg_ParseTuple(args, "l", &fd))
594 return NULL;
595 Py_BEGIN_ALLOW_THREADS
596 res = fstat((int)fd, &st);
597 Py_END_ALLOW_THREADS
598 if (res != 0)
599 return mac_error();
601 return _pystat_from_struct_stat(st, NULL);
603 #endif /* WEHAVE_FSTAT */
605 #if TARGET_API_MAC_OS8
606 static PyObject *
607 mac_xstat(self, args)
608 PyObject *self;
609 PyObject *args;
611 struct macstat mst;
612 struct stat st;
613 char *path;
614 int res;
615 if (!PyArg_ParseTuple(args, "s", &path))
616 return NULL;
618 ** Convoluted: we want stat() and xstat() to agree, so we call both
619 ** stat and macstat, and use the latter only for values not provided by
620 ** the former.
622 Py_BEGIN_ALLOW_THREADS
623 res = macstat(path, &mst);
624 Py_END_ALLOW_THREADS
625 if (res != 0)
626 return mac_error();
627 Py_BEGIN_ALLOW_THREADS
628 res = stat(path, &st);
629 Py_END_ALLOW_THREADS
630 if (res != 0)
631 return mac_error();
633 return _pystat_from_struct_stat(st, (void*) &mst);
635 #endif
637 static PyObject *
638 mac_sync(self, args)
639 PyObject *self;
640 PyObject *args;
642 int res;
643 if (!PyArg_ParseTuple(args, ""))
644 return NULL;
645 Py_BEGIN_ALLOW_THREADS
646 res = sync();
647 Py_END_ALLOW_THREADS
648 if (res != 0)
649 return mac_error();
650 Py_INCREF(Py_None);
651 return Py_None;
654 static PyObject *
655 mac_unlink(self, args)
656 PyObject *self;
657 PyObject *args;
659 return mac_1str(args, (int (*)(const char *))unlink);
662 static PyObject *
663 mac_write(self, args)
664 PyObject *self;
665 PyObject *args;
667 int fd, size;
668 char *buffer;
669 if (!PyArg_ParseTuple(args, "is#", &fd, &buffer, &size))
670 return NULL;
671 Py_BEGIN_ALLOW_THREADS
672 size = write(fd, buffer, size);
673 Py_END_ALLOW_THREADS
674 if (size < 0)
675 return mac_error();
676 return PyInt_FromLong((long)size);
679 #ifdef USE_MALLOC_DEBUG
680 void *mstats(char *);
682 static PyObject *
683 mac_mstats(self, args)
684 PyObject*self;
685 PyObject *args;
687 mstats("python");
688 Py_INCREF(Py_None);
689 return Py_None;
691 #endif /* USE_MALLOC_DEBUG */
693 static struct PyMethodDef mac_methods[] = {
694 {"chdir", mac_chdir, 1},
695 {"close", mac_close, 1},
696 #ifdef WEHAVE_DUP
697 {"dup", mac_dup, 1},
698 #endif
699 #ifdef WEHAVE_FDOPEN
700 {"fdopen", mac_fdopen, 1},
701 #endif
702 #ifdef WEHAVE_FSTAT
703 {"fstat", mac_fstat, 1},
704 #endif
705 #if TARGET_API_MAC_OS8
706 {"getbootvol", mac_getbootvol, 1}, /* non-standard */
707 #endif
708 {"getcwd", mac_getcwd, 1},
709 {"listdir", mac_listdir, 1},
710 {"lseek", mac_lseek, 1},
711 {"mkdir", mac_mkdir, 1},
712 {"open", mac_open, 1},
713 {"read", mac_read, 1},
714 {"rename", mac_rename, 1},
715 {"rmdir", mac_rmdir, 1},
716 {"stat", mac_stat, 1},
717 #if TARGET_API_MAC_OS8
718 {"xstat", mac_xstat, 1},
719 #endif
720 {"sync", mac_sync, 1},
721 {"remove", mac_unlink, 1},
722 {"unlink", mac_unlink, 1},
723 {"write", mac_write, 1},
724 #ifdef USE_MALLOC_DEBUG
725 {"mstats", mac_mstats, 1},
726 #endif
728 {NULL, NULL} /* Sentinel */
731 static int
732 ins(PyObject *d, char *symbol, long value)
734 PyObject* v = PyInt_FromLong(value);
735 if (!v || PyDict_SetItemString(d, symbol, v) < 0)
736 return -1; /* triggers fatal error */
738 Py_DECREF(v);
739 return 0;
742 static int
743 all_ins(PyObject *d)
745 #ifdef F_OK
746 if (ins(d, "F_OK", (long)F_OK)) return -1;
747 #endif
748 #ifdef R_OK
749 if (ins(d, "R_OK", (long)R_OK)) return -1;
750 #endif
751 #ifdef W_OK
752 if (ins(d, "W_OK", (long)W_OK)) return -1;
753 #endif
754 #ifdef X_OK
755 if (ins(d, "X_OK", (long)X_OK)) return -1;
756 #endif
757 #ifdef NGROUPS_MAX
758 if (ins(d, "NGROUPS_MAX", (long)NGROUPS_MAX)) return -1;
759 #endif
760 #ifdef TMP_MAX
761 if (ins(d, "TMP_MAX", (long)TMP_MAX)) return -1;
762 #endif
763 #ifdef WNOHANG
764 if (ins(d, "WNOHANG", (long)WNOHANG)) return -1;
765 #endif
766 #ifdef O_RDONLY
767 if (ins(d, "O_RDONLY", (long)O_RDONLY)) return -1;
768 #endif
769 #ifdef O_WRONLY
770 if (ins(d, "O_WRONLY", (long)O_WRONLY)) return -1;
771 #endif
772 #ifdef O_RDWR
773 if (ins(d, "O_RDWR", (long)O_RDWR)) return -1;
774 #endif
775 #ifdef O_NDELAY
776 if (ins(d, "O_NDELAY", (long)O_NDELAY)) return -1;
777 #endif
778 #ifdef O_NONBLOCK
779 if (ins(d, "O_NONBLOCK", (long)O_NONBLOCK)) return -1;
780 #endif
781 #ifdef O_APPEND
782 if (ins(d, "O_APPEND", (long)O_APPEND)) return -1;
783 #endif
784 #ifdef O_DSYNC
785 if (ins(d, "O_DSYNC", (long)O_DSYNC)) return -1;
786 #endif
787 #ifdef O_RSYNC
788 if (ins(d, "O_RSYNC", (long)O_RSYNC)) return -1;
789 #endif
790 #ifdef O_SYNC
791 if (ins(d, "O_SYNC", (long)O_SYNC)) return -1;
792 #endif
793 #ifdef O_NOCTTY
794 if (ins(d, "O_NOCTTY", (long)O_NOCTTY)) return -1;
795 #endif
796 #ifdef O_CREAT
797 if (ins(d, "O_CREAT", (long)O_CREAT)) return -1;
798 #endif
799 #ifdef O_EXCL
800 if (ins(d, "O_EXCL", (long)O_EXCL)) return -1;
801 #endif
802 #ifdef O_TRUNC
803 if (ins(d, "O_TRUNC", (long)O_TRUNC)) return -1;
804 #endif
805 #ifdef O_BINARY
806 if (ins(d, "O_BINARY", (long)O_BINARY)) return -1;
807 #endif
808 #ifdef O_TEXT
809 if (ins(d, "O_TEXT", (long)O_TEXT)) return -1;
810 #endif
812 #ifdef HAVE_SPAWNV
813 if (ins(d, "P_WAIT", (long)_P_WAIT)) return -1;
814 if (ins(d, "P_NOWAIT", (long)_P_NOWAIT)) return -1;
815 if (ins(d, "P_OVERLAY", (long)_OLD_P_OVERLAY)) return -1;
816 if (ins(d, "P_NOWAITO", (long)_P_NOWAITO)) return -1;
817 if (ins(d, "P_DETACH", (long)_P_DETACH)) return -1;
818 #endif
820 #if defined(PYOS_OS2)
821 if (insertvalues(d)) return -1;
822 #endif
823 return 0;
827 void
828 initmac()
830 PyObject *m, *d;
832 m = Py_InitModule("mac", mac_methods);
833 d = PyModule_GetDict(m);
835 if (all_ins(d))
836 return;
838 /* Initialize mac.error exception */
839 PyDict_SetItemString(d, "error", PyExc_OSError);
841 PyStructSequence_InitType(&StatResultType, &stat_result_desc);
842 PyDict_SetItemString(d, "stat_result", (PyObject*) &StatResultType);
844 #if TARGET_API_MAC_OS8
845 PyStructSequence_InitType(&XStatResultType, &xstat_result_desc);
846 PyDict_SetItemString(d, "xstat_result", (PyObject*) &XStatResultType);
847 #endif