blob: fb622865a884343f08844285df99832da0eff641 [file] [log] [blame]
Guido van Rossumce9739b1994-01-05 16:17:15 +00001/***********************************************************
Jack Jansen42218ce1997-01-31 16:15:11 +00002Copyright 1991-1997 by Stichting Mathematisch Centrum, Amsterdam,
Guido van Rossum99546991995-01-08 14:33:34 +00003The Netherlands.
Guido van Rossumce9739b1994-01-05 16:17:15 +00004
5 All Rights Reserved
6
7Permission to use, copy, modify, and distribute this software and its
8documentation for any purpose and without fee is hereby granted,
9provided that the above copyright notice appear in all copies and that
10both that copyright notice and this permission notice appear in
11supporting documentation, and that the names of Stichting Mathematisch
12Centrum or CWI not be used in advertising or publicity pertaining to
13distribution of the software without specific, written prior permission.
14
15STICHTING MATHEMATISCH CENTRUM DISCLAIMS ALL WARRANTIES WITH REGARD TO
16THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
17FITNESS, IN NO EVENT SHALL STICHTING MATHEMATISCH CENTRUM BE LIABLE
18FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
19WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
20ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
21OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
22
23******************************************************************/
24
Guido van Rossum87f223c1994-05-06 15:54:15 +000025/* Mac module implementation */
Guido van Rossumce9739b1994-01-05 16:17:15 +000026
Jack Jansenf5c20571997-01-30 15:48:07 +000027#include "Python.h"
Guido van Rossum98bf58f2001-10-18 20:34:25 +000028#include "structseq.h"
Guido van Rossum87f223c1994-05-06 15:54:15 +000029#include "ceval.h"
Guido van Rossumce9739b1994-01-05 16:17:15 +000030
Guido van Rossum87f223c1994-05-06 15:54:15 +000031#include <stdio.h>
32#include <string.h>
33#include <errno.h>
Guido van Rossum739267b1994-08-29 08:42:37 +000034
Jack Jansenc743c8d1996-02-14 16:02:30 +000035#ifdef USE_GUSI
Jack Jansen59b912a1996-10-15 16:13:33 +000036/* Remove defines from macstat.h */
37#undef S_IFMT
38#undef S_IFDIR
39#undef S_IFREG
40#undef S_IREAD
41#undef S_IWRITE
42#undef S_IEXEC
43
Jack Jansenc743c8d1996-02-14 16:02:30 +000044#include <sys/types.h>
Jack Jansen37d21e12000-04-07 09:25:06 +000045#include <sys/stat.h>
46#else /* USE_GUSI */
Jack Jansen37d21e12000-04-07 09:25:06 +000047#endif /* USE_GUSI */
Guido van Rossumce9739b1994-01-05 16:17:15 +000048
Jack Jansen37d21e12000-04-07 09:25:06 +000049#ifdef USE_GUSI2
Jack Jansen37d21e12000-04-07 09:25:06 +000050#include <unistd.h>
51#include <fcntl.h>
Jack Jansen37d21e12000-04-07 09:25:06 +000052#else
Jack Jansen12e89e42000-05-12 21:36:29 +000053#define mode_t int
Guido van Rossum87f223c1994-05-06 15:54:15 +000054#include <fcntl.h>
Jack Jansene79dc762000-06-02 21:35:07 +000055#ifdef _POSIX
56#include <unistd.h>
57#include <stat.h>
58#endif
Jack Jansen0c097ea1994-12-14 13:48:38 +000059#endif
Guido van Rossumce9739b1994-01-05 16:17:15 +000060
Jack Jansenb6971731996-02-20 16:24:37 +000061/* Optional routines, for some compiler/runtime combinations */
Jack Jansenb6971731996-02-20 16:24:37 +000062#if defined(USE_GUSI) || !defined(__MWERKS__)
63#define WEHAVE_FDOPEN
64#endif
65#if defined(MPW) || defined(USE_GUSI)
66#define WEHAVE_DUP
67#endif
Jack Jansen40bd7701998-02-20 15:56:19 +000068#if defined(USE_GUSI)
69#define WEHAVE_FSTAT
70#endif
Jack Jansen7cbf4801995-01-22 16:52:38 +000071
Guido van Rossumd4d77281994-08-19 10:51:31 +000072#include "macdefs.h"
Jack Jansenc743c8d1996-02-14 16:02:30 +000073#ifdef USE_GUSI
74#include <dirent.h>
75#else
Guido van Rossumd4d77281994-08-19 10:51:31 +000076#include "dirent.h"
Jack Jansenc743c8d1996-02-14 16:02:30 +000077#endif
Guido van Rossum87f223c1994-05-06 15:54:15 +000078
79#ifndef MAXPATHLEN
80#define MAXPATHLEN 1024
81#endif
82
83/* Prototypes for Unix simulation on Mac */
84
Jack Jansenb6971731996-02-20 16:24:37 +000085#ifndef USE_GUSI
86
Jack Jansend88296d2000-07-11 19:51:05 +000087int chdir(const char *path);
88int mkdir(const char *path, int mode);
89DIR * opendir(char *);
90void closedir(DIR *);
91struct dirent * readdir(DIR *);
92int rmdir(const char *path);
93int sync(void);
Jack Jansenb6971731996-02-20 16:24:37 +000094
Jack Jansend88296d2000-07-11 19:51:05 +000095int unlink(const char *);
Guido van Rossum87f223c1994-05-06 15:54:15 +000096
Jack Jansenb6971731996-02-20 16:24:37 +000097#endif /* USE_GUSI */
98
Jack Jansend88296d2000-07-11 19:51:05 +000099char *getwd(char *);
100char *getbootvol(void);
Guido van Rossum87f223c1994-05-06 15:54:15 +0000101
102
Guido van Rossum87f223c1994-05-06 15:54:15 +0000103/* Set a MAC-specific error from errno, and return NULL */
104
Jack Jansenf5c20571997-01-30 15:48:07 +0000105static PyObject *
Guido van Rossum87f223c1994-05-06 15:54:15 +0000106mac_error()
107{
Jack Jansenb3be2162001-11-30 14:16:36 +0000108 return PyErr_SetFromErrno(PyExc_OSError);
Guido van Rossum87f223c1994-05-06 15:54:15 +0000109}
110
111/* MAC generic methods */
112
Jack Jansenf5c20571997-01-30 15:48:07 +0000113static PyObject *
Guido van Rossum87f223c1994-05-06 15:54:15 +0000114mac_1str(args, func)
Jack Jansenf5c20571997-01-30 15:48:07 +0000115 PyObject *args;
Jack Jansend88296d2000-07-11 19:51:05 +0000116 int (*func)(const char *);
Guido van Rossum87f223c1994-05-06 15:54:15 +0000117{
118 char *path1;
119 int res;
Jack Jansenddafd2b2001-08-03 13:07:19 +0000120 if (!PyArg_ParseTuple(args, "s", &path1))
Guido van Rossum87f223c1994-05-06 15:54:15 +0000121 return NULL;
Jack Jansenf5c20571997-01-30 15:48:07 +0000122 Py_BEGIN_ALLOW_THREADS
Guido van Rossum87f223c1994-05-06 15:54:15 +0000123 res = (*func)(path1);
Jack Jansenf5c20571997-01-30 15:48:07 +0000124 Py_END_ALLOW_THREADS
Guido van Rossum87f223c1994-05-06 15:54:15 +0000125 if (res < 0)
126 return mac_error();
Jack Jansenf5c20571997-01-30 15:48:07 +0000127 Py_INCREF(Py_None);
128 return Py_None;
Guido van Rossum87f223c1994-05-06 15:54:15 +0000129}
130
Jack Jansenf5c20571997-01-30 15:48:07 +0000131static PyObject *
Guido van Rossum87f223c1994-05-06 15:54:15 +0000132mac_2str(args, func)
Jack Jansenf5c20571997-01-30 15:48:07 +0000133 PyObject *args;
Jack Jansend88296d2000-07-11 19:51:05 +0000134 int (*func)(const char *, const char *);
Guido van Rossum87f223c1994-05-06 15:54:15 +0000135{
136 char *path1, *path2;
137 int res;
Jack Jansenddafd2b2001-08-03 13:07:19 +0000138 if (!PyArg_ParseTuple(args, "ss", &path1, &path2))
Guido van Rossum87f223c1994-05-06 15:54:15 +0000139 return NULL;
Jack Jansenf5c20571997-01-30 15:48:07 +0000140 Py_BEGIN_ALLOW_THREADS
Guido van Rossum87f223c1994-05-06 15:54:15 +0000141 res = (*func)(path1, path2);
Jack Jansenf5c20571997-01-30 15:48:07 +0000142 Py_END_ALLOW_THREADS
Guido van Rossum87f223c1994-05-06 15:54:15 +0000143 if (res < 0)
144 return mac_error();
Jack Jansenf5c20571997-01-30 15:48:07 +0000145 Py_INCREF(Py_None);
146 return Py_None;
Guido van Rossum87f223c1994-05-06 15:54:15 +0000147}
148
Jack Jansenf5c20571997-01-30 15:48:07 +0000149static PyObject *
Guido van Rossum87f223c1994-05-06 15:54:15 +0000150mac_strint(args, func)
Jack Jansenf5c20571997-01-30 15:48:07 +0000151 PyObject *args;
Jack Jansend88296d2000-07-11 19:51:05 +0000152 int (*func)(const char *, int);
Guido van Rossum87f223c1994-05-06 15:54:15 +0000153{
154 char *path;
155 int i;
156 int res;
Jack Jansenddafd2b2001-08-03 13:07:19 +0000157 if (!PyArg_ParseTuple(args, "si", &path, &i))
Guido van Rossum87f223c1994-05-06 15:54:15 +0000158 return NULL;
Jack Jansenf5c20571997-01-30 15:48:07 +0000159 Py_BEGIN_ALLOW_THREADS
Guido van Rossum87f223c1994-05-06 15:54:15 +0000160 res = (*func)(path, i);
Jack Jansenf5c20571997-01-30 15:48:07 +0000161 Py_END_ALLOW_THREADS
Guido van Rossum87f223c1994-05-06 15:54:15 +0000162 if (res < 0)
163 return mac_error();
Jack Jansenf5c20571997-01-30 15:48:07 +0000164 Py_INCREF(Py_None);
165 return Py_None;
Guido van Rossum87f223c1994-05-06 15:54:15 +0000166}
167
Jack Jansenf5c20571997-01-30 15:48:07 +0000168static PyObject *
Guido van Rossumce9739b1994-01-05 16:17:15 +0000169mac_chdir(self, args)
Jack Jansenf5c20571997-01-30 15:48:07 +0000170 PyObject *self;
171 PyObject *args;
Guido van Rossumce9739b1994-01-05 16:17:15 +0000172{
Guido van Rossum87f223c1994-05-06 15:54:15 +0000173 return mac_1str(args, chdir);
174}
175
Jack Jansenf5c20571997-01-30 15:48:07 +0000176static PyObject *
Guido van Rossum87f223c1994-05-06 15:54:15 +0000177mac_close(self, args)
Jack Jansenf5c20571997-01-30 15:48:07 +0000178 PyObject *self;
179 PyObject *args;
Guido van Rossum87f223c1994-05-06 15:54:15 +0000180{
181 int fd, res;
Jack Jansenddafd2b2001-08-03 13:07:19 +0000182 if (!PyArg_ParseTuple(args, "i", &fd))
Guido van Rossumce9739b1994-01-05 16:17:15 +0000183 return NULL;
Jack Jansenf5c20571997-01-30 15:48:07 +0000184 Py_BEGIN_ALLOW_THREADS
Guido van Rossum87f223c1994-05-06 15:54:15 +0000185 res = close(fd);
Jack Jansenf5c20571997-01-30 15:48:07 +0000186 Py_END_ALLOW_THREADS
Guido van Rossum87f223c1994-05-06 15:54:15 +0000187 if (res < 0)
188 return mac_error();
Jack Jansenf5c20571997-01-30 15:48:07 +0000189 Py_INCREF(Py_None);
190 return Py_None;
Guido van Rossumce9739b1994-01-05 16:17:15 +0000191}
192
Jack Jansenb6971731996-02-20 16:24:37 +0000193#ifdef WEHAVE_DUP
Guido van Rossum921a08f1994-05-06 15:56:22 +0000194
Jack Jansenf5c20571997-01-30 15:48:07 +0000195static PyObject *
Guido van Rossum87f223c1994-05-06 15:54:15 +0000196mac_dup(self, args)
Jack Jansenf5c20571997-01-30 15:48:07 +0000197 PyObject *self;
198 PyObject *args;
Guido van Rossum87f223c1994-05-06 15:54:15 +0000199{
200 int fd;
Jack Jansenddafd2b2001-08-03 13:07:19 +0000201 if (!PyArg_ParseTuple(args, "i", &fd))
Guido van Rossum87f223c1994-05-06 15:54:15 +0000202 return NULL;
Jack Jansenf5c20571997-01-30 15:48:07 +0000203 Py_BEGIN_ALLOW_THREADS
Guido van Rossum87f223c1994-05-06 15:54:15 +0000204 fd = dup(fd);
Jack Jansenf5c20571997-01-30 15:48:07 +0000205 Py_END_ALLOW_THREADS
Guido van Rossum87f223c1994-05-06 15:54:15 +0000206 if (fd < 0)
207 return mac_error();
Jack Jansenf5c20571997-01-30 15:48:07 +0000208 return PyInt_FromLong((long)fd);
Guido van Rossum87f223c1994-05-06 15:54:15 +0000209}
210
Jack Jansenb6971731996-02-20 16:24:37 +0000211#endif
Guido van Rossume7834441994-08-26 09:09:48 +0000212
Jack Jansenb6971731996-02-20 16:24:37 +0000213#ifdef WEHAVE_FDOPEN
Jack Jansenf5c20571997-01-30 15:48:07 +0000214static PyObject *
Guido van Rossum87f223c1994-05-06 15:54:15 +0000215mac_fdopen(self, args)
Jack Jansenf5c20571997-01-30 15:48:07 +0000216 PyObject *self;
217 PyObject *args;
Guido van Rossum87f223c1994-05-06 15:54:15 +0000218{
Jack Jansend88296d2000-07-11 19:51:05 +0000219 extern int fclose(FILE *);
Guido van Rossum87f223c1994-05-06 15:54:15 +0000220 int fd;
Jack Jansen3e828722003-01-08 16:27:44 +0000221 char *mode = "r";
222 int bufsize = -1;
Guido van Rossum87f223c1994-05-06 15:54:15 +0000223 FILE *fp;
Jack Jansen3e828722003-01-08 16:27:44 +0000224 PyObject *f;
225 if (!PyArg_ParseTuple(args, "i|si", &fd, &mode, &bufsize))
Guido van Rossum87f223c1994-05-06 15:54:15 +0000226 return NULL;
Jack Jansenf5c20571997-01-30 15:48:07 +0000227 Py_BEGIN_ALLOW_THREADS
Guido van Rossum87f223c1994-05-06 15:54:15 +0000228 fp = fdopen(fd, mode);
Jack Jansenf5c20571997-01-30 15:48:07 +0000229 Py_END_ALLOW_THREADS
Guido van Rossum87f223c1994-05-06 15:54:15 +0000230 if (fp == NULL)
231 return mac_error();
Jack Jansen3e828722003-01-08 16:27:44 +0000232 f = PyFile_FromFile(fp, "<fdopen>", mode, fclose);
233 if (f != NULL)
234 PyFile_SetBufSize(f, bufsize);
235 return f;
Guido van Rossum87f223c1994-05-06 15:54:15 +0000236}
Jack Jansen0c097ea1994-12-14 13:48:38 +0000237#endif
Guido van Rossum87f223c1994-05-06 15:54:15 +0000238
Jack Jansenf5c20571997-01-30 15:48:07 +0000239static PyObject *
Guido van Rossumce9739b1994-01-05 16:17:15 +0000240mac_getcwd(self, args)
Jack Jansenf5c20571997-01-30 15:48:07 +0000241 PyObject *self;
242 PyObject *args;
Guido van Rossumce9739b1994-01-05 16:17:15 +0000243{
Guido van Rossum87f223c1994-05-06 15:54:15 +0000244 char path[MAXPATHLEN];
245 char *res;
Jack Jansenddafd2b2001-08-03 13:07:19 +0000246 if (!PyArg_ParseTuple(args, ""))
Guido van Rossumce9739b1994-01-05 16:17:15 +0000247 return NULL;
Jack Jansenf5c20571997-01-30 15:48:07 +0000248 Py_BEGIN_ALLOW_THREADS
Jack Jansenb6971731996-02-20 16:24:37 +0000249#ifdef USE_GUSI
250 res = getcwd(path, sizeof path);
251#else
Guido van Rossum87f223c1994-05-06 15:54:15 +0000252 res = getwd(path);
Jack Jansenb6971731996-02-20 16:24:37 +0000253#endif
Jack Jansenf5c20571997-01-30 15:48:07 +0000254 Py_END_ALLOW_THREADS
Guido van Rossum87f223c1994-05-06 15:54:15 +0000255 if (res == NULL) {
Jack Jansenb3be2162001-11-30 14:16:36 +0000256 return mac_error();
Guido van Rossumce9739b1994-01-05 16:17:15 +0000257 }
Jack Jansenf5c20571997-01-30 15:48:07 +0000258 return PyString_FromString(res);
Guido van Rossumce9739b1994-01-05 16:17:15 +0000259}
260
Jack Jansenf5c20571997-01-30 15:48:07 +0000261static PyObject *
Guido van Rossumce9739b1994-01-05 16:17:15 +0000262mac_listdir(self, args)
Jack Jansenf5c20571997-01-30 15:48:07 +0000263 PyObject *self;
264 PyObject *args;
Guido van Rossumce9739b1994-01-05 16:17:15 +0000265{
Guido van Rossumce9739b1994-01-05 16:17:15 +0000266 char *name;
Jack Jansenf5c20571997-01-30 15:48:07 +0000267 PyObject *d, *v;
Guido van Rossumce9739b1994-01-05 16:17:15 +0000268 DIR *dirp;
Guido van Rossumd4d77281994-08-19 10:51:31 +0000269 struct dirent *ep;
Jack Jansenddafd2b2001-08-03 13:07:19 +0000270 if (!PyArg_ParseTuple(args, "s", &name))
Guido van Rossumce9739b1994-01-05 16:17:15 +0000271 return NULL;
Jack Jansend7b568a2001-08-11 23:18:55 +0000272#ifdef USE_GUSI
273 /* Work around a bug in GUSI: if you opendir() a file it will
274 ** actually opendir() the parent directory.
275 */
276 {
277 struct stat stb;
278 int res;
279
280 res = stat(name, &stb);
281 if ( res < 0 )
282 return mac_error();
283 if (!S_ISDIR(stb.st_mode) ) {
284 errno = ENOTDIR;
285 return mac_error();
286 }
287 }
288#endif
289
Jack Jansenf5c20571997-01-30 15:48:07 +0000290 Py_BEGIN_ALLOW_THREADS
Guido van Rossum87f223c1994-05-06 15:54:15 +0000291 if ((dirp = opendir(name)) == NULL) {
Jack Jansenf5c20571997-01-30 15:48:07 +0000292 Py_BLOCK_THREADS
Guido van Rossum87f223c1994-05-06 15:54:15 +0000293 return mac_error();
294 }
Jack Jansenf5c20571997-01-30 15:48:07 +0000295 if ((d = PyList_New(0)) == NULL) {
Guido van Rossumce9739b1994-01-05 16:17:15 +0000296 closedir(dirp);
Jack Jansenf5c20571997-01-30 15:48:07 +0000297 Py_BLOCK_THREADS
Guido van Rossumce9739b1994-01-05 16:17:15 +0000298 return NULL;
299 }
300 while ((ep = readdir(dirp)) != NULL) {
Jack Jansenf5c20571997-01-30 15:48:07 +0000301 v = PyString_FromString(ep->d_name);
Guido van Rossumce9739b1994-01-05 16:17:15 +0000302 if (v == NULL) {
Jack Jansenf5c20571997-01-30 15:48:07 +0000303 Py_DECREF(d);
Guido van Rossumce9739b1994-01-05 16:17:15 +0000304 d = NULL;
305 break;
306 }
Jack Jansenf5c20571997-01-30 15:48:07 +0000307 if (PyList_Append(d, v) != 0) {
308 Py_DECREF(v);
309 Py_DECREF(d);
Guido van Rossumce9739b1994-01-05 16:17:15 +0000310 d = NULL;
311 break;
312 }
Jack Jansenf5c20571997-01-30 15:48:07 +0000313 Py_DECREF(v);
Guido van Rossumce9739b1994-01-05 16:17:15 +0000314 }
315 closedir(dirp);
Jack Jansenf5c20571997-01-30 15:48:07 +0000316 Py_END_ALLOW_THREADS
Guido van Rossum87f223c1994-05-06 15:54:15 +0000317
Guido van Rossumce9739b1994-01-05 16:17:15 +0000318 return d;
319}
320
Jack Jansenf5c20571997-01-30 15:48:07 +0000321static PyObject *
Guido van Rossum87f223c1994-05-06 15:54:15 +0000322mac_lseek(self, args)
Jack Jansenf5c20571997-01-30 15:48:07 +0000323 PyObject *self;
324 PyObject *args;
Guido van Rossum87f223c1994-05-06 15:54:15 +0000325{
326 int fd;
327 int where;
328 int how;
329 long res;
Jack Jansenddafd2b2001-08-03 13:07:19 +0000330 if (!PyArg_ParseTuple(args, "iii", &fd, &where, &how))
Guido van Rossum87f223c1994-05-06 15:54:15 +0000331 return NULL;
Jack Jansenf5c20571997-01-30 15:48:07 +0000332 Py_BEGIN_ALLOW_THREADS
Guido van Rossum87f223c1994-05-06 15:54:15 +0000333 res = lseek(fd, (long)where, how);
Jack Jansenf5c20571997-01-30 15:48:07 +0000334 Py_END_ALLOW_THREADS
Guido van Rossum87f223c1994-05-06 15:54:15 +0000335 if (res < 0)
336 return mac_error();
Jack Jansenf5c20571997-01-30 15:48:07 +0000337 return PyInt_FromLong(res);
Guido van Rossum87f223c1994-05-06 15:54:15 +0000338}
Jack Jansenc743c8d1996-02-14 16:02:30 +0000339
Jack Jansenf5c20571997-01-30 15:48:07 +0000340static PyObject *
Guido van Rossumce9739b1994-01-05 16:17:15 +0000341mac_mkdir(self, args)
Jack Jansenf5c20571997-01-30 15:48:07 +0000342 PyObject *self;
343 PyObject *args;
Guido van Rossumce9739b1994-01-05 16:17:15 +0000344{
Jack Jansen243b29b1996-02-21 12:33:50 +0000345 int res;
346 char *path;
347 int mode = 0777; /* Unused */
Jack Jansenf5c20571997-01-30 15:48:07 +0000348 if (!PyArg_ParseTuple(args, "s|i", &path, &mode))
Jack Jansen243b29b1996-02-21 12:33:50 +0000349 return NULL;
Jack Jansenf5c20571997-01-30 15:48:07 +0000350 Py_BEGIN_ALLOW_THREADS
Jack Jansen243b29b1996-02-21 12:33:50 +0000351 res = mkdir(path, mode);
Jack Jansenf5c20571997-01-30 15:48:07 +0000352 Py_END_ALLOW_THREADS
Jack Jansen243b29b1996-02-21 12:33:50 +0000353 if (res < 0)
354 return mac_error();
Jack Jansenf5c20571997-01-30 15:48:07 +0000355 Py_INCREF(Py_None);
356 return Py_None;
Guido van Rossumce9739b1994-01-05 16:17:15 +0000357}
358
Jack Jansenf5c20571997-01-30 15:48:07 +0000359static PyObject *
Guido van Rossum87f223c1994-05-06 15:54:15 +0000360mac_open(self, args)
Jack Jansenf5c20571997-01-30 15:48:07 +0000361 PyObject *self;
362 PyObject *args;
Guido van Rossum87f223c1994-05-06 15:54:15 +0000363{
364 char *path;
365 int mode;
Jack Jansenddafd2b2001-08-03 13:07:19 +0000366 int perm; /* Accepted but ignored */
Guido van Rossum87f223c1994-05-06 15:54:15 +0000367 int fd;
Jack Jansenddafd2b2001-08-03 13:07:19 +0000368 if (!PyArg_ParseTuple(args, "si|i", &path, &mode, &perm))
Guido van Rossum87f223c1994-05-06 15:54:15 +0000369 return NULL;
Jack Jansenf5c20571997-01-30 15:48:07 +0000370 Py_BEGIN_ALLOW_THREADS
Guido van Rossum87f223c1994-05-06 15:54:15 +0000371 fd = open(path, mode);
Jack Jansenf5c20571997-01-30 15:48:07 +0000372 Py_END_ALLOW_THREADS
Guido van Rossum87f223c1994-05-06 15:54:15 +0000373 if (fd < 0)
374 return mac_error();
Jack Jansenf5c20571997-01-30 15:48:07 +0000375 return PyInt_FromLong((long)fd);
Guido van Rossum87f223c1994-05-06 15:54:15 +0000376}
377
Jack Jansenf5c20571997-01-30 15:48:07 +0000378static PyObject *
Guido van Rossum87f223c1994-05-06 15:54:15 +0000379mac_read(self, args)
Jack Jansenf5c20571997-01-30 15:48:07 +0000380 PyObject *self;
381 PyObject *args;
Guido van Rossum87f223c1994-05-06 15:54:15 +0000382{
383 int fd, size;
Jack Jansenf5c20571997-01-30 15:48:07 +0000384 PyObject *buffer;
Jack Jansenddafd2b2001-08-03 13:07:19 +0000385 if (!PyArg_ParseTuple(args, "ii", &fd, &size))
Guido van Rossum87f223c1994-05-06 15:54:15 +0000386 return NULL;
Jack Jansenf5c20571997-01-30 15:48:07 +0000387 buffer = PyString_FromStringAndSize((char *)NULL, size);
Guido van Rossum87f223c1994-05-06 15:54:15 +0000388 if (buffer == NULL)
389 return NULL;
Jack Jansenf5c20571997-01-30 15:48:07 +0000390 Py_BEGIN_ALLOW_THREADS
391 size = read(fd, PyString_AsString(buffer), size);
392 Py_END_ALLOW_THREADS
Guido van Rossum87f223c1994-05-06 15:54:15 +0000393 if (size < 0) {
Jack Jansenf5c20571997-01-30 15:48:07 +0000394 Py_DECREF(buffer);
Guido van Rossum87f223c1994-05-06 15:54:15 +0000395 return mac_error();
396 }
Jack Jansenf5c20571997-01-30 15:48:07 +0000397 _PyString_Resize(&buffer, size);
Guido van Rossum87f223c1994-05-06 15:54:15 +0000398 return buffer;
399}
Guido van Rossumce9739b1994-01-05 16:17:15 +0000400
Jack Jansenf5c20571997-01-30 15:48:07 +0000401static PyObject *
Guido van Rossumce9739b1994-01-05 16:17:15 +0000402mac_rename(self, args)
Jack Jansenf5c20571997-01-30 15:48:07 +0000403 PyObject *self;
404 PyObject *args;
Guido van Rossumce9739b1994-01-05 16:17:15 +0000405{
Guido van Rossum87f223c1994-05-06 15:54:15 +0000406 return mac_2str(args, rename);
Guido van Rossumce9739b1994-01-05 16:17:15 +0000407}
408
Jack Jansenf5c20571997-01-30 15:48:07 +0000409static PyObject *
Guido van Rossumce9739b1994-01-05 16:17:15 +0000410mac_rmdir(self, args)
Jack Jansenf5c20571997-01-30 15:48:07 +0000411 PyObject *self;
412 PyObject *args;
Guido van Rossumce9739b1994-01-05 16:17:15 +0000413{
Guido van Rossum87f223c1994-05-06 15:54:15 +0000414 return mac_1str(args, rmdir);
Guido van Rossumce9739b1994-01-05 16:17:15 +0000415}
416
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000417static char stat_result__doc__[] =
418"stat_result: Result from stat or lstat.\n\n\
419This object may be accessed either as a tuple of\n\
420 (mode,ino,dev,nlink,uid,gid,size,atime,mtime,ctime)\n\
421or via the attributes st_mode, st_ino, st_dev, st_nlink, st_uid, and so on.\n\
422\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000423See os.stat for more information.\n";
424
425#define COMMON_STAT_RESULT_FIELDS \
426 { "st_mode", "protection bits" }, \
427 { "st_ino", "inode" }, \
Jack Jansene54968a2001-10-23 22:28:23 +0000428 { "st_dev", "device" }, \
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000429 { "st_nlink", "number of hard links" }, \
Jack Jansene54968a2001-10-23 22:28:23 +0000430 { "st_uid", "user ID of owner" }, \
431 { "st_gid", "group ID of owner" }, \
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000432 { "st_size", "total size, in bytes" }, \
433 { "st_atime", "time of last access" }, \
434 { "st_mtime", "time of last modification" }, \
435 { "st_ctime", "time of last change" },
436
437
438
439static PyStructSequence_Field stat_result_fields[] = {
440 COMMON_STAT_RESULT_FIELDS
441 {0}
442};
443
444static PyStructSequence_Desc stat_result_desc = {
Guido van Rossum14648392001-12-08 18:02:58 +0000445 "mac.stat_result",
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000446 stat_result__doc__,
447 stat_result_fields,
448 10
449};
450
451static PyTypeObject StatResultType;
452
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000453static PyObject *
454_pystat_from_struct_stat(struct stat st, void* _mst)
455{
456 PyObject *v;
457
Jack Jansen6c7e3262002-12-12 10:31:54 +0000458 v = PyStructSequence_New(&StatResultType);
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000459 PyStructSequence_SET_ITEM(v, 0, PyInt_FromLong((long)st.st_mode));
460 PyStructSequence_SET_ITEM(v, 1, PyInt_FromLong((long)st.st_ino));
461 PyStructSequence_SET_ITEM(v, 2, PyInt_FromLong((long)st.st_dev));
462 PyStructSequence_SET_ITEM(v, 3, PyInt_FromLong((long)st.st_nlink));
463 PyStructSequence_SET_ITEM(v, 4, PyInt_FromLong((long)st.st_uid));
464 PyStructSequence_SET_ITEM(v, 5, PyInt_FromLong((long)st.st_gid));
465 PyStructSequence_SET_ITEM(v, 6, PyInt_FromLong((long)st.st_size));
466 PyStructSequence_SET_ITEM(v, 7,
467 PyFloat_FromDouble((double)st.st_atime));
468 PyStructSequence_SET_ITEM(v, 8,
469 PyFloat_FromDouble((double)st.st_mtime));
470 PyStructSequence_SET_ITEM(v, 9,
471 PyFloat_FromDouble((double)st.st_ctime));
Jack Jansen6c7e3262002-12-12 10:31:54 +0000472 if (PyErr_Occurred()) {
473 Py_DECREF(v);
474 return NULL;
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000475 }
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000476
Jack Jansen6c7e3262002-12-12 10:31:54 +0000477 return v;
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000478}
479
480
Jack Jansenf5c20571997-01-30 15:48:07 +0000481static PyObject *
Guido van Rossumce9739b1994-01-05 16:17:15 +0000482mac_stat(self, args)
Jack Jansenf5c20571997-01-30 15:48:07 +0000483 PyObject *self;
484 PyObject *args;
Guido van Rossumce9739b1994-01-05 16:17:15 +0000485{
Jack Jansen59b912a1996-10-15 16:13:33 +0000486 struct stat st;
Guido van Rossumce9739b1994-01-05 16:17:15 +0000487 char *path;
Guido van Rossum87f223c1994-05-06 15:54:15 +0000488 int res;
Jack Jansenddafd2b2001-08-03 13:07:19 +0000489 if (!PyArg_ParseTuple(args, "s", &path))
Guido van Rossumce9739b1994-01-05 16:17:15 +0000490 return NULL;
Jack Jansenf5c20571997-01-30 15:48:07 +0000491 Py_BEGIN_ALLOW_THREADS
Jack Jansen59b912a1996-10-15 16:13:33 +0000492 res = stat(path, &st);
Jack Jansenf5c20571997-01-30 15:48:07 +0000493 Py_END_ALLOW_THREADS
Guido van Rossum87f223c1994-05-06 15:54:15 +0000494 if (res != 0)
495 return mac_error();
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000496
497 return _pystat_from_struct_stat(st, NULL);
Jack Jansen40bd7701998-02-20 15:56:19 +0000498}
499
500#ifdef WEHAVE_FSTAT
501static PyObject *
502mac_fstat(self, args)
503 PyObject *self;
504 PyObject *args;
505{
506 struct stat st;
507 long fd;
508 int res;
Jack Jansenddafd2b2001-08-03 13:07:19 +0000509 if (!PyArg_ParseTuple(args, "l", &fd))
Jack Jansen40bd7701998-02-20 15:56:19 +0000510 return NULL;
511 Py_BEGIN_ALLOW_THREADS
512 res = fstat((int)fd, &st);
513 Py_END_ALLOW_THREADS
514 if (res != 0)
515 return mac_error();
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000516
517 return _pystat_from_struct_stat(st, NULL);
Guido van Rossumce9739b1994-01-05 16:17:15 +0000518}
Jack Jansen40bd7701998-02-20 15:56:19 +0000519#endif /* WEHAVE_FSTAT */
Guido van Rossumce9739b1994-01-05 16:17:15 +0000520
Jack Jansenf5c20571997-01-30 15:48:07 +0000521static PyObject *
Guido van Rossumce9739b1994-01-05 16:17:15 +0000522mac_sync(self, args)
Jack Jansenf5c20571997-01-30 15:48:07 +0000523 PyObject *self;
524 PyObject *args;
Guido van Rossumce9739b1994-01-05 16:17:15 +0000525{
Guido van Rossum87f223c1994-05-06 15:54:15 +0000526 int res;
Jack Jansenddafd2b2001-08-03 13:07:19 +0000527 if (!PyArg_ParseTuple(args, ""))
Guido van Rossumce9739b1994-01-05 16:17:15 +0000528 return NULL;
Jack Jansenf5c20571997-01-30 15:48:07 +0000529 Py_BEGIN_ALLOW_THREADS
Jack Jansen0e5a7332002-03-21 21:09:36 +0000530#ifdef USE_GUSI2
531 sync();
532 res = 0;
533#else
Guido van Rossum87f223c1994-05-06 15:54:15 +0000534 res = sync();
Jack Jansen0e5a7332002-03-21 21:09:36 +0000535#endif
Jack Jansenf5c20571997-01-30 15:48:07 +0000536 Py_END_ALLOW_THREADS
Guido van Rossum87f223c1994-05-06 15:54:15 +0000537 if (res != 0)
538 return mac_error();
Jack Jansenf5c20571997-01-30 15:48:07 +0000539 Py_INCREF(Py_None);
540 return Py_None;
Guido van Rossumce9739b1994-01-05 16:17:15 +0000541}
542
Jack Jansenf5c20571997-01-30 15:48:07 +0000543static PyObject *
Guido van Rossumce9739b1994-01-05 16:17:15 +0000544mac_unlink(self, args)
Jack Jansenf5c20571997-01-30 15:48:07 +0000545 PyObject *self;
546 PyObject *args;
Guido van Rossumce9739b1994-01-05 16:17:15 +0000547{
Guido van Rossum739267b1994-08-29 08:42:37 +0000548 return mac_1str(args, (int (*)(const char *))unlink);
Guido van Rossumce9739b1994-01-05 16:17:15 +0000549}
550
Jack Jansenf5c20571997-01-30 15:48:07 +0000551static PyObject *
Guido van Rossum87f223c1994-05-06 15:54:15 +0000552mac_write(self, args)
Jack Jansenf5c20571997-01-30 15:48:07 +0000553 PyObject *self;
554 PyObject *args;
Guido van Rossum87f223c1994-05-06 15:54:15 +0000555{
556 int fd, size;
557 char *buffer;
Jack Jansenddafd2b2001-08-03 13:07:19 +0000558 if (!PyArg_ParseTuple(args, "is#", &fd, &buffer, &size))
Guido van Rossum87f223c1994-05-06 15:54:15 +0000559 return NULL;
Jack Jansenf5c20571997-01-30 15:48:07 +0000560 Py_BEGIN_ALLOW_THREADS
Guido van Rossum87f223c1994-05-06 15:54:15 +0000561 size = write(fd, buffer, size);
Jack Jansenf5c20571997-01-30 15:48:07 +0000562 Py_END_ALLOW_THREADS
Guido van Rossum87f223c1994-05-06 15:54:15 +0000563 if (size < 0)
564 return mac_error();
Jack Jansenf5c20571997-01-30 15:48:07 +0000565 return PyInt_FromLong((long)size);
Guido van Rossum87f223c1994-05-06 15:54:15 +0000566}
Guido van Rossumce9739b1994-01-05 16:17:15 +0000567
Jack Jansen46ed2761996-10-23 15:46:57 +0000568#ifdef USE_MALLOC_DEBUG
Jack Jansen8748a0b2000-08-25 22:18:20 +0000569void *mstats(char *);
570
Jack Jansenf5c20571997-01-30 15:48:07 +0000571static PyObject *
Jack Jansend50e4e11995-01-18 13:58:04 +0000572mac_mstats(self, args)
Jack Jansenf5c20571997-01-30 15:48:07 +0000573 PyObject*self;
574 PyObject *args;
Jack Jansend50e4e11995-01-18 13:58:04 +0000575{
576 mstats("python");
Jack Jansenf5c20571997-01-30 15:48:07 +0000577 Py_INCREF(Py_None);
578 return Py_None;
Jack Jansend50e4e11995-01-18 13:58:04 +0000579}
Jack Jansen4f27a551997-02-20 15:22:17 +0000580#endif /* USE_MALLOC_DEBUG */
Jack Jansend50e4e11995-01-18 13:58:04 +0000581
Jack Jansenf5c20571997-01-30 15:48:07 +0000582static struct PyMethodDef mac_methods[] = {
Jack Jansenddafd2b2001-08-03 13:07:19 +0000583 {"chdir", mac_chdir, 1},
584 {"close", mac_close, 1},
Jack Jansenb6971731996-02-20 16:24:37 +0000585#ifdef WEHAVE_DUP
Jack Jansenddafd2b2001-08-03 13:07:19 +0000586 {"dup", mac_dup, 1},
Guido van Rossum921a08f1994-05-06 15:56:22 +0000587#endif
Jack Jansenb6971731996-02-20 16:24:37 +0000588#ifdef WEHAVE_FDOPEN
Jack Jansenddafd2b2001-08-03 13:07:19 +0000589 {"fdopen", mac_fdopen, 1},
Jack Jansen0c097ea1994-12-14 13:48:38 +0000590#endif
Jack Jansen40bd7701998-02-20 15:56:19 +0000591#ifdef WEHAVE_FSTAT
Jack Jansenddafd2b2001-08-03 13:07:19 +0000592 {"fstat", mac_fstat, 1},
Jack Jansen40bd7701998-02-20 15:56:19 +0000593#endif
Jack Jansenddafd2b2001-08-03 13:07:19 +0000594 {"getcwd", mac_getcwd, 1},
595 {"listdir", mac_listdir, 1},
596 {"lseek", mac_lseek, 1},
Jack Jansen243b29b1996-02-21 12:33:50 +0000597 {"mkdir", mac_mkdir, 1},
Jack Jansenddafd2b2001-08-03 13:07:19 +0000598 {"open", mac_open, 1},
599 {"read", mac_read, 1},
600 {"rename", mac_rename, 1},
601 {"rmdir", mac_rmdir, 1},
602 {"stat", mac_stat, 1},
Jack Jansenddafd2b2001-08-03 13:07:19 +0000603 {"sync", mac_sync, 1},
604 {"remove", mac_unlink, 1},
605 {"unlink", mac_unlink, 1},
606 {"write", mac_write, 1},
Jack Jansen46ed2761996-10-23 15:46:57 +0000607#ifdef USE_MALLOC_DEBUG
Jack Jansenddafd2b2001-08-03 13:07:19 +0000608 {"mstats", mac_mstats, 1},
Jack Jansend50e4e11995-01-18 13:58:04 +0000609#endif
Guido van Rossum87f223c1994-05-06 15:54:15 +0000610
Guido van Rossumce9739b1994-01-05 16:17:15 +0000611 {NULL, NULL} /* Sentinel */
612};
613
Jack Jansenddafd2b2001-08-03 13:07:19 +0000614static int
615ins(PyObject *d, char *symbol, long value)
616{
617 PyObject* v = PyInt_FromLong(value);
618 if (!v || PyDict_SetItemString(d, symbol, v) < 0)
619 return -1; /* triggers fatal error */
620
621 Py_DECREF(v);
622 return 0;
623}
624
625static int
626all_ins(PyObject *d)
627{
628#ifdef F_OK
629 if (ins(d, "F_OK", (long)F_OK)) return -1;
630#endif
631#ifdef R_OK
632 if (ins(d, "R_OK", (long)R_OK)) return -1;
633#endif
634#ifdef W_OK
635 if (ins(d, "W_OK", (long)W_OK)) return -1;
636#endif
637#ifdef X_OK
638 if (ins(d, "X_OK", (long)X_OK)) return -1;
639#endif
640#ifdef NGROUPS_MAX
641 if (ins(d, "NGROUPS_MAX", (long)NGROUPS_MAX)) return -1;
642#endif
643#ifdef TMP_MAX
644 if (ins(d, "TMP_MAX", (long)TMP_MAX)) return -1;
645#endif
646#ifdef WNOHANG
647 if (ins(d, "WNOHANG", (long)WNOHANG)) return -1;
648#endif
649#ifdef O_RDONLY
650 if (ins(d, "O_RDONLY", (long)O_RDONLY)) return -1;
651#endif
652#ifdef O_WRONLY
653 if (ins(d, "O_WRONLY", (long)O_WRONLY)) return -1;
654#endif
655#ifdef O_RDWR
656 if (ins(d, "O_RDWR", (long)O_RDWR)) return -1;
657#endif
658#ifdef O_NDELAY
659 if (ins(d, "O_NDELAY", (long)O_NDELAY)) return -1;
660#endif
661#ifdef O_NONBLOCK
662 if (ins(d, "O_NONBLOCK", (long)O_NONBLOCK)) return -1;
663#endif
664#ifdef O_APPEND
665 if (ins(d, "O_APPEND", (long)O_APPEND)) return -1;
666#endif
667#ifdef O_DSYNC
668 if (ins(d, "O_DSYNC", (long)O_DSYNC)) return -1;
669#endif
670#ifdef O_RSYNC
671 if (ins(d, "O_RSYNC", (long)O_RSYNC)) return -1;
672#endif
673#ifdef O_SYNC
674 if (ins(d, "O_SYNC", (long)O_SYNC)) return -1;
675#endif
676#ifdef O_NOCTTY
677 if (ins(d, "O_NOCTTY", (long)O_NOCTTY)) return -1;
678#endif
679#ifdef O_CREAT
680 if (ins(d, "O_CREAT", (long)O_CREAT)) return -1;
681#endif
682#ifdef O_EXCL
683 if (ins(d, "O_EXCL", (long)O_EXCL)) return -1;
684#endif
685#ifdef O_TRUNC
686 if (ins(d, "O_TRUNC", (long)O_TRUNC)) return -1;
687#endif
688#ifdef O_BINARY
689 if (ins(d, "O_BINARY", (long)O_BINARY)) return -1;
690#endif
691#ifdef O_TEXT
692 if (ins(d, "O_TEXT", (long)O_TEXT)) return -1;
693#endif
694
695#ifdef HAVE_SPAWNV
696 if (ins(d, "P_WAIT", (long)_P_WAIT)) return -1;
697 if (ins(d, "P_NOWAIT", (long)_P_NOWAIT)) return -1;
698 if (ins(d, "P_OVERLAY", (long)_OLD_P_OVERLAY)) return -1;
699 if (ins(d, "P_NOWAITO", (long)_P_NOWAITO)) return -1;
700 if (ins(d, "P_DETACH", (long)_P_DETACH)) return -1;
701#endif
702
703#if defined(PYOS_OS2)
704 if (insertvalues(d)) return -1;
705#endif
706 return 0;
707}
708
Guido van Rossumce9739b1994-01-05 16:17:15 +0000709
710void
711initmac()
712{
Jack Jansenf5c20571997-01-30 15:48:07 +0000713 PyObject *m, *d;
Guido van Rossumce9739b1994-01-05 16:17:15 +0000714
Jack Jansenf5c20571997-01-30 15:48:07 +0000715 m = Py_InitModule("mac", mac_methods);
716 d = PyModule_GetDict(m);
Guido van Rossumce9739b1994-01-05 16:17:15 +0000717
Jack Jansenddafd2b2001-08-03 13:07:19 +0000718 if (all_ins(d))
719 return;
720
Guido van Rossumce9739b1994-01-05 16:17:15 +0000721 /* Initialize mac.error exception */
Jack Jansenb3be2162001-11-30 14:16:36 +0000722 PyDict_SetItemString(d, "error", PyExc_OSError);
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000723
724 PyStructSequence_InitType(&StatResultType, &stat_result_desc);
725 PyDict_SetItemString(d, "stat_result", (PyObject*) &StatResultType);
726
Guido van Rossumce9739b1994-01-05 16:17:15 +0000727}