Another batch of updates...
[python/dscho.git] / Mac / Modules / macmodule.c
blob3d5c0ccd5f7810ac71f0607b43fffdfb4f9127fb
1 /***********************************************************
2 Copyright 1991-1995 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 "allobjects.h"
28 #include "modsupport.h"
29 #include "ceval.h"
31 #include <stdio.h>
32 #include <string.h>
33 #include <errno.h>
35 #ifdef THINK_C
36 #include "unix.h"
37 #undef S_IFMT
38 #undef S_IFDIR
39 #undef S_IFCHR
40 #undef S_IFBLK
41 #undef S_IFREG
42 #undef S_ISDIR
43 #undef S_ISREG
44 #endif
46 #ifdef USE_GUSI
47 #include <GUSI.h>
48 #include <sys/types.h>
49 #include <stat.h>
50 #define macstat stat
51 #else
52 #include "macstat.h"
53 #endif
55 #ifdef __MWERKS__
56 #include <unix.h>
57 #else
58 #include <fcntl.h>
59 #endif
61 /* Optional routines, for some compiler/runtime combinations */
62 #if defined(__MWERKS__) && defined(__powerc)
63 #define MALLOC_DEBUG
64 #endif
65 #if defined(USE_GUSI) || !defined(__MWERKS__)
66 #define WEHAVE_FDOPEN
67 #endif
68 #if defined(MPW) || defined(USE_GUSI)
69 #define WEHAVE_DUP
70 #endif
72 #include "macdefs.h"
73 #ifdef USE_GUSI
74 #include <dirent.h>
75 #else
76 #include "dirent.h"
77 #endif
79 #ifndef MAXPATHLEN
80 #define MAXPATHLEN 1024
81 #endif
83 /* Prototypes for Unix simulation on Mac */
85 #ifndef USE_GUSI
87 int chdir PROTO((const char *path));
88 int mkdir PROTO((const char *path, int mode));
89 DIR * opendir PROTO((char *));
90 void closedir PROTO((DIR *));
91 struct dirent * readdir PROTO((DIR *));
92 int rmdir PROTO((const char *path));
93 int sync PROTO((void));
95 #if defined(THINK_C) || defined(__SC__)
96 int unlink PROTO((char *));
97 #else
98 int unlink PROTO((const char *));
99 #endif
101 #endif /* USE_GUSI */
103 char *getwd PROTO((char *));
104 char *getbootvol PROTO((void));
107 static object *MacError; /* Exception mac.error */
109 /* Set a MAC-specific error from errno, and return NULL */
111 static object *
112 mac_error()
114 return err_errno(MacError);
117 /* MAC generic methods */
119 static object *
120 mac_1str(args, func)
121 object *args;
122 int (*func) FPROTO((const char *));
124 char *path1;
125 int res;
126 if (!getargs(args, "s", &path1))
127 return NULL;
128 BGN_SAVE
129 res = (*func)(path1);
130 END_SAVE
131 if (res < 0)
132 return mac_error();
133 INCREF(None);
134 return None;
137 static object *
138 mac_2str(args, func)
139 object *args;
140 int (*func) FPROTO((const char *, const char *));
142 char *path1, *path2;
143 int res;
144 if (!getargs(args, "(ss)", &path1, &path2))
145 return NULL;
146 BGN_SAVE
147 res = (*func)(path1, path2);
148 END_SAVE
149 if (res < 0)
150 return mac_error();
151 INCREF(None);
152 return None;
155 static object *
156 mac_strint(args, func)
157 object *args;
158 int (*func) FPROTO((const char *, int));
160 char *path;
161 int i;
162 int res;
163 if (!getargs(args, "(si)", &path, &i))
164 return NULL;
165 BGN_SAVE
166 res = (*func)(path, i);
167 END_SAVE
168 if (res < 0)
169 return mac_error();
170 INCREF(None);
171 return None;
174 static object *
175 mac_chdir(self, args)
176 object *self;
177 object *args;
179 #ifdef USE_GUSI
180 object *rv;
182 /* Change MacOS's idea of wd too */
183 rv = mac_1str(args, chdir);
184 PyMac_FixGUSIcd();
185 return rv;
186 #else
187 return mac_1str(args, chdir);
188 #endif
192 static object *
193 mac_close(self, args)
194 object *self;
195 object *args;
197 int fd, res;
198 if (!getargs(args, "i", &fd))
199 return NULL;
200 BGN_SAVE
201 res = close(fd);
202 END_SAVE
203 #ifndef USE_GUSI
204 /* GUSI gives surious errors here? */
205 if (res < 0)
206 return mac_error();
207 #endif
208 INCREF(None);
209 return None;
212 #ifdef WEHAVE_DUP
214 static object *
215 mac_dup(self, args)
216 object *self;
217 object *args;
219 int fd;
220 if (!getargs(args, "i", &fd))
221 return NULL;
222 BGN_SAVE
223 fd = dup(fd);
224 END_SAVE
225 if (fd < 0)
226 return mac_error();
227 return newintobject((long)fd);
230 #endif
232 #ifdef WEHAVE_FDOPEN
233 static object *
234 mac_fdopen(self, args)
235 object *self;
236 object *args;
238 extern int fclose PROTO((FILE *));
239 int fd;
240 char *mode;
241 FILE *fp;
242 if (!getargs(args, "(is)", &fd, &mode))
243 return NULL;
244 BGN_SAVE
245 fp = fdopen(fd, mode);
246 END_SAVE
247 if (fp == NULL)
248 return mac_error();
249 return newopenfileobject(fp, "(fdopen)", mode, fclose);
251 #endif
253 static object *
254 mac_getbootvol(self, args)
255 object *self;
256 object *args;
258 char *res;
259 if (!getnoarg(args))
260 return NULL;
261 BGN_SAVE
262 res = getbootvol();
263 END_SAVE
264 if (res == NULL)
265 return mac_error();
266 return newstringobject(res);
269 static object *
270 mac_getcwd(self, args)
271 object *self;
272 object *args;
274 char path[MAXPATHLEN];
275 char *res;
276 if (!getnoarg(args))
277 return NULL;
278 BGN_SAVE
279 #ifdef USE_GUSI
280 res = getcwd(path, sizeof path);
281 #else
282 res = getwd(path);
283 #endif
284 END_SAVE
285 if (res == NULL) {
286 err_setstr(MacError, path);
287 return NULL;
289 return newstringobject(res);
292 static object *
293 mac_listdir(self, args)
294 object *self;
295 object *args;
297 char *name;
298 object *d, *v;
299 DIR *dirp;
300 struct dirent *ep;
301 if (!getargs(args, "s", &name))
302 return NULL;
303 BGN_SAVE
304 if ((dirp = opendir(name)) == NULL) {
305 RET_SAVE
306 return mac_error();
308 if ((d = newlistobject(0)) == NULL) {
309 closedir(dirp);
310 RET_SAVE
311 return NULL;
313 while ((ep = readdir(dirp)) != NULL) {
314 v = newstringobject(ep->d_name);
315 if (v == NULL) {
316 DECREF(d);
317 d = NULL;
318 break;
320 if (addlistitem(d, v) != 0) {
321 DECREF(v);
322 DECREF(d);
323 d = NULL;
324 break;
326 DECREF(v);
328 closedir(dirp);
329 END_SAVE
331 return d;
334 static object *
335 mac_lseek(self, args)
336 object *self;
337 object *args;
339 int fd;
340 int where;
341 int how;
342 long res;
343 if (!getargs(args, "(iii)", &fd, &where, &how))
344 return NULL;
345 BGN_SAVE
346 res = lseek(fd, (long)where, how);
347 END_SAVE
348 if (res < 0)
349 return mac_error();
350 return newintobject(res);
353 static object *
354 mac_mkdir(self, args)
355 object *self;
356 object *args;
358 int res;
359 char *path;
360 int mode = 0777; /* Unused */
361 if (!newgetargs(args, "s|i", &path, &mode))
362 return NULL;
363 BGN_SAVE
364 #ifdef USE_GUSI
365 res = mkdir(path);
366 #else
367 res = mkdir(path, mode);
368 #endif
369 END_SAVE
370 if (res < 0)
371 return mac_error();
372 INCREF(None);
373 return None;
376 static object *
377 mac_open(self, args)
378 object *self;
379 object *args;
381 char *path;
382 int mode;
383 int fd;
384 if (!getargs(args, "(si)", &path, &mode))
385 return NULL;
386 BGN_SAVE
387 fd = open(path, mode);
388 END_SAVE
389 if (fd < 0)
390 return mac_error();
391 return newintobject((long)fd);
394 static object *
395 mac_read(self, args)
396 object *self;
397 object *args;
399 int fd, size;
400 object *buffer;
401 if (!getargs(args, "(ii)", &fd, &size))
402 return NULL;
403 buffer = newsizedstringobject((char *)NULL, size);
404 if (buffer == NULL)
405 return NULL;
406 BGN_SAVE
407 size = read(fd, getstringvalue(buffer), size);
408 END_SAVE
409 if (size < 0) {
410 DECREF(buffer);
411 return mac_error();
413 resizestring(&buffer, size);
414 return buffer;
417 static object *
418 mac_rename(self, args)
419 object *self;
420 object *args;
422 return mac_2str(args, rename);
425 static object *
426 mac_rmdir(self, args)
427 object *self;
428 object *args;
430 return mac_1str(args, rmdir);
433 static object *
434 mac_stat(self, args)
435 object *self;
436 object *args;
438 struct macstat st;
439 char *path;
440 int res;
441 if (!getargs(args, "s", &path))
442 return NULL;
443 BGN_SAVE
444 res = macstat(path, &st);
445 END_SAVE
446 if (res != 0)
447 return mac_error();
448 return mkvalue("(llllllllll)",
449 (long)st.st_mode,
450 (long)st.st_ino,
451 (long)st.st_dev,
452 (long)st.st_nlink,
453 (long)st.st_uid,
454 (long)st.st_gid,
455 (long)st.st_size,
456 (long)st.st_atime,
457 (long)st.st_mtime,
458 (long)st.st_ctime);
461 static object *
462 mac_xstat(self, args)
463 object *self;
464 object *args;
466 struct macstat st;
467 char *path;
468 int res;
469 if (!getargs(args, "s", &path))
470 return NULL;
471 BGN_SAVE
472 res = macstat(path, &st);
473 END_SAVE
474 if (res != 0)
475 return mac_error();
476 #ifdef USE_GUSI
477 return mkvalue("(llllllllll)",
478 (long)st.st_mode,
479 (long)st.st_ino,
480 (long)st.st_dev,
481 (long)st.st_nlink,
482 (long)st.st_uid,
483 (long)st.st_gid,
484 (long)st.st_size,
485 (long)st.st_atime,
486 (long)st.st_mtime,
487 (long)st.st_ctime);
488 #else
489 return mkvalue("(llllllllllls#s#)",
490 (long)st.st_mode,
491 (long)st.st_ino,
492 (long)st.st_dev,
493 (long)st.st_nlink,
494 (long)st.st_uid,
495 (long)st.st_gid,
496 (long)st.st_size,
497 (long)st.st_atime,
498 (long)st.st_mtime,
499 (long)st.st_ctime,
500 (long)st.st_rsize,
501 st.st_creator, 4,
502 st.st_type, 4);
503 #endif
506 static object *
507 mac_sync(self, args)
508 object *self;
509 object *args;
511 int res;
512 if (!getnoarg(args))
513 return NULL;
514 BGN_SAVE
515 res = sync();
516 END_SAVE
517 if (res != 0)
518 return mac_error();
519 INCREF(None);
520 return None;
523 static object *
524 mac_unlink(self, args)
525 object *self;
526 object *args;
528 return mac_1str(args, (int (*)(const char *))unlink);
531 static object *
532 mac_write(self, args)
533 object *self;
534 object *args;
536 int fd, size;
537 char *buffer;
538 if (!getargs(args, "(is#)", &fd, &buffer, &size))
539 return NULL;
540 BGN_SAVE
541 size = write(fd, buffer, size);
542 END_SAVE
543 if (size < 0)
544 return mac_error();
545 return newintobject((long)size);
548 #ifdef MALLOC_DEBUG
549 static object *
550 mac_mstats(self, args)
551 object*self;
552 object *args;
554 mstats("python");
555 INCREF(None);
556 return None;
558 #endif MALLOC_DEBUG
560 static struct methodlist mac_methods[] = {
561 {"chdir", mac_chdir},
562 {"close", mac_close},
563 #ifdef WEHAVE_DUP
564 {"dup", mac_dup},
565 #endif
566 #ifdef WEHAVE_FDOPEN
567 {"fdopen", mac_fdopen},
568 #endif
569 {"getbootvol", mac_getbootvol}, /* non-standard */
570 {"getcwd", mac_getcwd},
571 {"listdir", mac_listdir, 0},
572 {"lseek", mac_lseek},
573 {"mkdir", mac_mkdir, 1},
574 {"open", mac_open},
575 {"read", mac_read},
576 {"rename", mac_rename},
577 {"rmdir", mac_rmdir},
578 {"stat", mac_stat},
579 {"xstat", mac_xstat},
580 {"sync", mac_sync},
581 {"remove", mac_unlink},
582 {"unlink", mac_unlink},
583 {"write", mac_write},
584 #ifdef MALLOC_DEBUG
585 {"mstats", mac_mstats},
586 #endif
588 {NULL, NULL} /* Sentinel */
592 void
593 initmac()
595 object *m, *d;
597 m = initmodule("mac", mac_methods);
598 d = getmoduledict(m);
600 /* Initialize mac.error exception */
601 MacError = newstringobject("mac.error");
602 if (MacError == NULL || dictinsert(d, "error", MacError) != 0)
603 fatal("can't define mac.error");