blob: e6ac8812c4ea1a90716f578e11e68b598a7cff5f [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;
221 char *mode;
222 FILE *fp;
Jack Jansenddafd2b2001-08-03 13:07:19 +0000223 if (!PyArg_ParseTuple(args, "is", &fd, &mode))
Guido van Rossum87f223c1994-05-06 15:54:15 +0000224 return NULL;
Jack Jansenf5c20571997-01-30 15:48:07 +0000225 Py_BEGIN_ALLOW_THREADS
Guido van Rossum87f223c1994-05-06 15:54:15 +0000226 fp = fdopen(fd, mode);
Jack Jansenf5c20571997-01-30 15:48:07 +0000227 Py_END_ALLOW_THREADS
Guido van Rossum87f223c1994-05-06 15:54:15 +0000228 if (fp == NULL)
229 return mac_error();
Jack Jansenf5c20571997-01-30 15:48:07 +0000230 return PyFile_FromFile(fp, "(fdopen)", mode, fclose);
Guido van Rossum87f223c1994-05-06 15:54:15 +0000231}
Jack Jansen0c097ea1994-12-14 13:48:38 +0000232#endif
Guido van Rossum87f223c1994-05-06 15:54:15 +0000233
Jack Jansenf5c20571997-01-30 15:48:07 +0000234static PyObject *
Guido van Rossumce9739b1994-01-05 16:17:15 +0000235mac_getcwd(self, args)
Jack Jansenf5c20571997-01-30 15:48:07 +0000236 PyObject *self;
237 PyObject *args;
Guido van Rossumce9739b1994-01-05 16:17:15 +0000238{
Guido van Rossum87f223c1994-05-06 15:54:15 +0000239 char path[MAXPATHLEN];
240 char *res;
Jack Jansenddafd2b2001-08-03 13:07:19 +0000241 if (!PyArg_ParseTuple(args, ""))
Guido van Rossumce9739b1994-01-05 16:17:15 +0000242 return NULL;
Jack Jansenf5c20571997-01-30 15:48:07 +0000243 Py_BEGIN_ALLOW_THREADS
Jack Jansenb6971731996-02-20 16:24:37 +0000244#ifdef USE_GUSI
245 res = getcwd(path, sizeof path);
246#else
Guido van Rossum87f223c1994-05-06 15:54:15 +0000247 res = getwd(path);
Jack Jansenb6971731996-02-20 16:24:37 +0000248#endif
Jack Jansenf5c20571997-01-30 15:48:07 +0000249 Py_END_ALLOW_THREADS
Guido van Rossum87f223c1994-05-06 15:54:15 +0000250 if (res == NULL) {
Jack Jansenb3be2162001-11-30 14:16:36 +0000251 return mac_error();
Guido van Rossumce9739b1994-01-05 16:17:15 +0000252 }
Jack Jansenf5c20571997-01-30 15:48:07 +0000253 return PyString_FromString(res);
Guido van Rossumce9739b1994-01-05 16:17:15 +0000254}
255
Jack Jansenf5c20571997-01-30 15:48:07 +0000256static PyObject *
Guido van Rossumce9739b1994-01-05 16:17:15 +0000257mac_listdir(self, args)
Jack Jansenf5c20571997-01-30 15:48:07 +0000258 PyObject *self;
259 PyObject *args;
Guido van Rossumce9739b1994-01-05 16:17:15 +0000260{
Guido van Rossumce9739b1994-01-05 16:17:15 +0000261 char *name;
Jack Jansenf5c20571997-01-30 15:48:07 +0000262 PyObject *d, *v;
Guido van Rossumce9739b1994-01-05 16:17:15 +0000263 DIR *dirp;
Guido van Rossumd4d77281994-08-19 10:51:31 +0000264 struct dirent *ep;
Jack Jansenddafd2b2001-08-03 13:07:19 +0000265 if (!PyArg_ParseTuple(args, "s", &name))
Guido van Rossumce9739b1994-01-05 16:17:15 +0000266 return NULL;
Jack Jansend7b568a2001-08-11 23:18:55 +0000267#ifdef USE_GUSI
268 /* Work around a bug in GUSI: if you opendir() a file it will
269 ** actually opendir() the parent directory.
270 */
271 {
272 struct stat stb;
273 int res;
274
275 res = stat(name, &stb);
276 if ( res < 0 )
277 return mac_error();
278 if (!S_ISDIR(stb.st_mode) ) {
279 errno = ENOTDIR;
280 return mac_error();
281 }
282 }
283#endif
284
Jack Jansenf5c20571997-01-30 15:48:07 +0000285 Py_BEGIN_ALLOW_THREADS
Guido van Rossum87f223c1994-05-06 15:54:15 +0000286 if ((dirp = opendir(name)) == NULL) {
Jack Jansenf5c20571997-01-30 15:48:07 +0000287 Py_BLOCK_THREADS
Guido van Rossum87f223c1994-05-06 15:54:15 +0000288 return mac_error();
289 }
Jack Jansenf5c20571997-01-30 15:48:07 +0000290 if ((d = PyList_New(0)) == NULL) {
Guido van Rossumce9739b1994-01-05 16:17:15 +0000291 closedir(dirp);
Jack Jansenf5c20571997-01-30 15:48:07 +0000292 Py_BLOCK_THREADS
Guido van Rossumce9739b1994-01-05 16:17:15 +0000293 return NULL;
294 }
295 while ((ep = readdir(dirp)) != NULL) {
Jack Jansenf5c20571997-01-30 15:48:07 +0000296 v = PyString_FromString(ep->d_name);
Guido van Rossumce9739b1994-01-05 16:17:15 +0000297 if (v == NULL) {
Jack Jansenf5c20571997-01-30 15:48:07 +0000298 Py_DECREF(d);
Guido van Rossumce9739b1994-01-05 16:17:15 +0000299 d = NULL;
300 break;
301 }
Jack Jansenf5c20571997-01-30 15:48:07 +0000302 if (PyList_Append(d, v) != 0) {
303 Py_DECREF(v);
304 Py_DECREF(d);
Guido van Rossumce9739b1994-01-05 16:17:15 +0000305 d = NULL;
306 break;
307 }
Jack Jansenf5c20571997-01-30 15:48:07 +0000308 Py_DECREF(v);
Guido van Rossumce9739b1994-01-05 16:17:15 +0000309 }
310 closedir(dirp);
Jack Jansenf5c20571997-01-30 15:48:07 +0000311 Py_END_ALLOW_THREADS
Guido van Rossum87f223c1994-05-06 15:54:15 +0000312
Guido van Rossumce9739b1994-01-05 16:17:15 +0000313 return d;
314}
315
Jack Jansenf5c20571997-01-30 15:48:07 +0000316static PyObject *
Guido van Rossum87f223c1994-05-06 15:54:15 +0000317mac_lseek(self, args)
Jack Jansenf5c20571997-01-30 15:48:07 +0000318 PyObject *self;
319 PyObject *args;
Guido van Rossum87f223c1994-05-06 15:54:15 +0000320{
321 int fd;
322 int where;
323 int how;
324 long res;
Jack Jansenddafd2b2001-08-03 13:07:19 +0000325 if (!PyArg_ParseTuple(args, "iii", &fd, &where, &how))
Guido van Rossum87f223c1994-05-06 15:54:15 +0000326 return NULL;
Jack Jansenf5c20571997-01-30 15:48:07 +0000327 Py_BEGIN_ALLOW_THREADS
Guido van Rossum87f223c1994-05-06 15:54:15 +0000328 res = lseek(fd, (long)where, how);
Jack Jansenf5c20571997-01-30 15:48:07 +0000329 Py_END_ALLOW_THREADS
Guido van Rossum87f223c1994-05-06 15:54:15 +0000330 if (res < 0)
331 return mac_error();
Jack Jansenf5c20571997-01-30 15:48:07 +0000332 return PyInt_FromLong(res);
Guido van Rossum87f223c1994-05-06 15:54:15 +0000333}
Jack Jansenc743c8d1996-02-14 16:02:30 +0000334
Jack Jansenf5c20571997-01-30 15:48:07 +0000335static PyObject *
Guido van Rossumce9739b1994-01-05 16:17:15 +0000336mac_mkdir(self, args)
Jack Jansenf5c20571997-01-30 15:48:07 +0000337 PyObject *self;
338 PyObject *args;
Guido van Rossumce9739b1994-01-05 16:17:15 +0000339{
Jack Jansen243b29b1996-02-21 12:33:50 +0000340 int res;
341 char *path;
342 int mode = 0777; /* Unused */
Jack Jansenf5c20571997-01-30 15:48:07 +0000343 if (!PyArg_ParseTuple(args, "s|i", &path, &mode))
Jack Jansen243b29b1996-02-21 12:33:50 +0000344 return NULL;
Jack Jansenf5c20571997-01-30 15:48:07 +0000345 Py_BEGIN_ALLOW_THREADS
Jack Jansen243b29b1996-02-21 12:33:50 +0000346 res = mkdir(path, mode);
Jack Jansenf5c20571997-01-30 15:48:07 +0000347 Py_END_ALLOW_THREADS
Jack Jansen243b29b1996-02-21 12:33:50 +0000348 if (res < 0)
349 return mac_error();
Jack Jansenf5c20571997-01-30 15:48:07 +0000350 Py_INCREF(Py_None);
351 return Py_None;
Guido van Rossumce9739b1994-01-05 16:17:15 +0000352}
353
Jack Jansenf5c20571997-01-30 15:48:07 +0000354static PyObject *
Guido van Rossum87f223c1994-05-06 15:54:15 +0000355mac_open(self, args)
Jack Jansenf5c20571997-01-30 15:48:07 +0000356 PyObject *self;
357 PyObject *args;
Guido van Rossum87f223c1994-05-06 15:54:15 +0000358{
359 char *path;
360 int mode;
Jack Jansenddafd2b2001-08-03 13:07:19 +0000361 int perm; /* Accepted but ignored */
Guido van Rossum87f223c1994-05-06 15:54:15 +0000362 int fd;
Jack Jansenddafd2b2001-08-03 13:07:19 +0000363 if (!PyArg_ParseTuple(args, "si|i", &path, &mode, &perm))
Guido van Rossum87f223c1994-05-06 15:54:15 +0000364 return NULL;
Jack Jansenf5c20571997-01-30 15:48:07 +0000365 Py_BEGIN_ALLOW_THREADS
Guido van Rossum87f223c1994-05-06 15:54:15 +0000366 fd = open(path, mode);
Jack Jansenf5c20571997-01-30 15:48:07 +0000367 Py_END_ALLOW_THREADS
Guido van Rossum87f223c1994-05-06 15:54:15 +0000368 if (fd < 0)
369 return mac_error();
Jack Jansenf5c20571997-01-30 15:48:07 +0000370 return PyInt_FromLong((long)fd);
Guido van Rossum87f223c1994-05-06 15:54:15 +0000371}
372
Jack Jansenf5c20571997-01-30 15:48:07 +0000373static PyObject *
Guido van Rossum87f223c1994-05-06 15:54:15 +0000374mac_read(self, args)
Jack Jansenf5c20571997-01-30 15:48:07 +0000375 PyObject *self;
376 PyObject *args;
Guido van Rossum87f223c1994-05-06 15:54:15 +0000377{
378 int fd, size;
Jack Jansenf5c20571997-01-30 15:48:07 +0000379 PyObject *buffer;
Jack Jansenddafd2b2001-08-03 13:07:19 +0000380 if (!PyArg_ParseTuple(args, "ii", &fd, &size))
Guido van Rossum87f223c1994-05-06 15:54:15 +0000381 return NULL;
Jack Jansenf5c20571997-01-30 15:48:07 +0000382 buffer = PyString_FromStringAndSize((char *)NULL, size);
Guido van Rossum87f223c1994-05-06 15:54:15 +0000383 if (buffer == NULL)
384 return NULL;
Jack Jansenf5c20571997-01-30 15:48:07 +0000385 Py_BEGIN_ALLOW_THREADS
386 size = read(fd, PyString_AsString(buffer), size);
387 Py_END_ALLOW_THREADS
Guido van Rossum87f223c1994-05-06 15:54:15 +0000388 if (size < 0) {
Jack Jansenf5c20571997-01-30 15:48:07 +0000389 Py_DECREF(buffer);
Guido van Rossum87f223c1994-05-06 15:54:15 +0000390 return mac_error();
391 }
Jack Jansenf5c20571997-01-30 15:48:07 +0000392 _PyString_Resize(&buffer, size);
Guido van Rossum87f223c1994-05-06 15:54:15 +0000393 return buffer;
394}
Guido van Rossumce9739b1994-01-05 16:17:15 +0000395
Jack Jansenf5c20571997-01-30 15:48:07 +0000396static PyObject *
Guido van Rossumce9739b1994-01-05 16:17:15 +0000397mac_rename(self, args)
Jack Jansenf5c20571997-01-30 15:48:07 +0000398 PyObject *self;
399 PyObject *args;
Guido van Rossumce9739b1994-01-05 16:17:15 +0000400{
Guido van Rossum87f223c1994-05-06 15:54:15 +0000401 return mac_2str(args, rename);
Guido van Rossumce9739b1994-01-05 16:17:15 +0000402}
403
Jack Jansenf5c20571997-01-30 15:48:07 +0000404static PyObject *
Guido van Rossumce9739b1994-01-05 16:17:15 +0000405mac_rmdir(self, args)
Jack Jansenf5c20571997-01-30 15:48:07 +0000406 PyObject *self;
407 PyObject *args;
Guido van Rossumce9739b1994-01-05 16:17:15 +0000408{
Guido van Rossum87f223c1994-05-06 15:54:15 +0000409 return mac_1str(args, rmdir);
Guido van Rossumce9739b1994-01-05 16:17:15 +0000410}
411
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000412static char stat_result__doc__[] =
413"stat_result: Result from stat or lstat.\n\n\
414This object may be accessed either as a tuple of\n\
415 (mode,ino,dev,nlink,uid,gid,size,atime,mtime,ctime)\n\
416or via the attributes st_mode, st_ino, st_dev, st_nlink, st_uid, and so on.\n\
417\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000418See os.stat for more information.\n";
419
420#define COMMON_STAT_RESULT_FIELDS \
421 { "st_mode", "protection bits" }, \
422 { "st_ino", "inode" }, \
Jack Jansene54968a2001-10-23 22:28:23 +0000423 { "st_dev", "device" }, \
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000424 { "st_nlink", "number of hard links" }, \
Jack Jansene54968a2001-10-23 22:28:23 +0000425 { "st_uid", "user ID of owner" }, \
426 { "st_gid", "group ID of owner" }, \
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000427 { "st_size", "total size, in bytes" }, \
428 { "st_atime", "time of last access" }, \
429 { "st_mtime", "time of last modification" }, \
430 { "st_ctime", "time of last change" },
431
432
433
434static PyStructSequence_Field stat_result_fields[] = {
435 COMMON_STAT_RESULT_FIELDS
436 {0}
437};
438
439static PyStructSequence_Desc stat_result_desc = {
Guido van Rossum14648392001-12-08 18:02:58 +0000440 "mac.stat_result",
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000441 stat_result__doc__,
442 stat_result_fields,
443 10
444};
445
446static PyTypeObject StatResultType;
447
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000448static PyObject *
449_pystat_from_struct_stat(struct stat st, void* _mst)
450{
451 PyObject *v;
452
Jack Jansen6c7e3262002-12-12 10:31:54 +0000453 v = PyStructSequence_New(&StatResultType);
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000454 PyStructSequence_SET_ITEM(v, 0, PyInt_FromLong((long)st.st_mode));
455 PyStructSequence_SET_ITEM(v, 1, PyInt_FromLong((long)st.st_ino));
456 PyStructSequence_SET_ITEM(v, 2, PyInt_FromLong((long)st.st_dev));
457 PyStructSequence_SET_ITEM(v, 3, PyInt_FromLong((long)st.st_nlink));
458 PyStructSequence_SET_ITEM(v, 4, PyInt_FromLong((long)st.st_uid));
459 PyStructSequence_SET_ITEM(v, 5, PyInt_FromLong((long)st.st_gid));
460 PyStructSequence_SET_ITEM(v, 6, PyInt_FromLong((long)st.st_size));
461 PyStructSequence_SET_ITEM(v, 7,
462 PyFloat_FromDouble((double)st.st_atime));
463 PyStructSequence_SET_ITEM(v, 8,
464 PyFloat_FromDouble((double)st.st_mtime));
465 PyStructSequence_SET_ITEM(v, 9,
466 PyFloat_FromDouble((double)st.st_ctime));
Jack Jansen6c7e3262002-12-12 10:31:54 +0000467 if (PyErr_Occurred()) {
468 Py_DECREF(v);
469 return NULL;
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000470 }
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000471
Jack Jansen6c7e3262002-12-12 10:31:54 +0000472 return v;
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000473}
474
475
Jack Jansenf5c20571997-01-30 15:48:07 +0000476static PyObject *
Guido van Rossumce9739b1994-01-05 16:17:15 +0000477mac_stat(self, args)
Jack Jansenf5c20571997-01-30 15:48:07 +0000478 PyObject *self;
479 PyObject *args;
Guido van Rossumce9739b1994-01-05 16:17:15 +0000480{
Jack Jansen59b912a1996-10-15 16:13:33 +0000481 struct stat st;
Guido van Rossumce9739b1994-01-05 16:17:15 +0000482 char *path;
Guido van Rossum87f223c1994-05-06 15:54:15 +0000483 int res;
Jack Jansenddafd2b2001-08-03 13:07:19 +0000484 if (!PyArg_ParseTuple(args, "s", &path))
Guido van Rossumce9739b1994-01-05 16:17:15 +0000485 return NULL;
Jack Jansenf5c20571997-01-30 15:48:07 +0000486 Py_BEGIN_ALLOW_THREADS
Jack Jansen59b912a1996-10-15 16:13:33 +0000487 res = stat(path, &st);
Jack Jansenf5c20571997-01-30 15:48:07 +0000488 Py_END_ALLOW_THREADS
Guido van Rossum87f223c1994-05-06 15:54:15 +0000489 if (res != 0)
490 return mac_error();
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000491
492 return _pystat_from_struct_stat(st, NULL);
Jack Jansen40bd7701998-02-20 15:56:19 +0000493}
494
495#ifdef WEHAVE_FSTAT
496static PyObject *
497mac_fstat(self, args)
498 PyObject *self;
499 PyObject *args;
500{
501 struct stat st;
502 long fd;
503 int res;
Jack Jansenddafd2b2001-08-03 13:07:19 +0000504 if (!PyArg_ParseTuple(args, "l", &fd))
Jack Jansen40bd7701998-02-20 15:56:19 +0000505 return NULL;
506 Py_BEGIN_ALLOW_THREADS
507 res = fstat((int)fd, &st);
508 Py_END_ALLOW_THREADS
509 if (res != 0)
510 return mac_error();
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000511
512 return _pystat_from_struct_stat(st, NULL);
Guido van Rossumce9739b1994-01-05 16:17:15 +0000513}
Jack Jansen40bd7701998-02-20 15:56:19 +0000514#endif /* WEHAVE_FSTAT */
Guido van Rossumce9739b1994-01-05 16:17:15 +0000515
Jack Jansenf5c20571997-01-30 15:48:07 +0000516static PyObject *
Guido van Rossumce9739b1994-01-05 16:17:15 +0000517mac_sync(self, args)
Jack Jansenf5c20571997-01-30 15:48:07 +0000518 PyObject *self;
519 PyObject *args;
Guido van Rossumce9739b1994-01-05 16:17:15 +0000520{
Guido van Rossum87f223c1994-05-06 15:54:15 +0000521 int res;
Jack Jansenddafd2b2001-08-03 13:07:19 +0000522 if (!PyArg_ParseTuple(args, ""))
Guido van Rossumce9739b1994-01-05 16:17:15 +0000523 return NULL;
Jack Jansenf5c20571997-01-30 15:48:07 +0000524 Py_BEGIN_ALLOW_THREADS
Jack Jansen0e5a7332002-03-21 21:09:36 +0000525#ifdef USE_GUSI2
526 sync();
527 res = 0;
528#else
Guido van Rossum87f223c1994-05-06 15:54:15 +0000529 res = sync();
Jack Jansen0e5a7332002-03-21 21:09:36 +0000530#endif
Jack Jansenf5c20571997-01-30 15:48:07 +0000531 Py_END_ALLOW_THREADS
Guido van Rossum87f223c1994-05-06 15:54:15 +0000532 if (res != 0)
533 return mac_error();
Jack Jansenf5c20571997-01-30 15:48:07 +0000534 Py_INCREF(Py_None);
535 return Py_None;
Guido van Rossumce9739b1994-01-05 16:17:15 +0000536}
537
Jack Jansenf5c20571997-01-30 15:48:07 +0000538static PyObject *
Guido van Rossumce9739b1994-01-05 16:17:15 +0000539mac_unlink(self, args)
Jack Jansenf5c20571997-01-30 15:48:07 +0000540 PyObject *self;
541 PyObject *args;
Guido van Rossumce9739b1994-01-05 16:17:15 +0000542{
Guido van Rossum739267b1994-08-29 08:42:37 +0000543 return mac_1str(args, (int (*)(const char *))unlink);
Guido van Rossumce9739b1994-01-05 16:17:15 +0000544}
545
Jack Jansenf5c20571997-01-30 15:48:07 +0000546static PyObject *
Guido van Rossum87f223c1994-05-06 15:54:15 +0000547mac_write(self, args)
Jack Jansenf5c20571997-01-30 15:48:07 +0000548 PyObject *self;
549 PyObject *args;
Guido van Rossum87f223c1994-05-06 15:54:15 +0000550{
551 int fd, size;
552 char *buffer;
Jack Jansenddafd2b2001-08-03 13:07:19 +0000553 if (!PyArg_ParseTuple(args, "is#", &fd, &buffer, &size))
Guido van Rossum87f223c1994-05-06 15:54:15 +0000554 return NULL;
Jack Jansenf5c20571997-01-30 15:48:07 +0000555 Py_BEGIN_ALLOW_THREADS
Guido van Rossum87f223c1994-05-06 15:54:15 +0000556 size = write(fd, buffer, size);
Jack Jansenf5c20571997-01-30 15:48:07 +0000557 Py_END_ALLOW_THREADS
Guido van Rossum87f223c1994-05-06 15:54:15 +0000558 if (size < 0)
559 return mac_error();
Jack Jansenf5c20571997-01-30 15:48:07 +0000560 return PyInt_FromLong((long)size);
Guido van Rossum87f223c1994-05-06 15:54:15 +0000561}
Guido van Rossumce9739b1994-01-05 16:17:15 +0000562
Jack Jansen46ed2761996-10-23 15:46:57 +0000563#ifdef USE_MALLOC_DEBUG
Jack Jansen8748a0b2000-08-25 22:18:20 +0000564void *mstats(char *);
565
Jack Jansenf5c20571997-01-30 15:48:07 +0000566static PyObject *
Jack Jansend50e4e11995-01-18 13:58:04 +0000567mac_mstats(self, args)
Jack Jansenf5c20571997-01-30 15:48:07 +0000568 PyObject*self;
569 PyObject *args;
Jack Jansend50e4e11995-01-18 13:58:04 +0000570{
571 mstats("python");
Jack Jansenf5c20571997-01-30 15:48:07 +0000572 Py_INCREF(Py_None);
573 return Py_None;
Jack Jansend50e4e11995-01-18 13:58:04 +0000574}
Jack Jansen4f27a551997-02-20 15:22:17 +0000575#endif /* USE_MALLOC_DEBUG */
Jack Jansend50e4e11995-01-18 13:58:04 +0000576
Jack Jansenf5c20571997-01-30 15:48:07 +0000577static struct PyMethodDef mac_methods[] = {
Jack Jansenddafd2b2001-08-03 13:07:19 +0000578 {"chdir", mac_chdir, 1},
579 {"close", mac_close, 1},
Jack Jansenb6971731996-02-20 16:24:37 +0000580#ifdef WEHAVE_DUP
Jack Jansenddafd2b2001-08-03 13:07:19 +0000581 {"dup", mac_dup, 1},
Guido van Rossum921a08f1994-05-06 15:56:22 +0000582#endif
Jack Jansenb6971731996-02-20 16:24:37 +0000583#ifdef WEHAVE_FDOPEN
Jack Jansenddafd2b2001-08-03 13:07:19 +0000584 {"fdopen", mac_fdopen, 1},
Jack Jansen0c097ea1994-12-14 13:48:38 +0000585#endif
Jack Jansen40bd7701998-02-20 15:56:19 +0000586#ifdef WEHAVE_FSTAT
Jack Jansenddafd2b2001-08-03 13:07:19 +0000587 {"fstat", mac_fstat, 1},
Jack Jansen40bd7701998-02-20 15:56:19 +0000588#endif
Jack Jansenddafd2b2001-08-03 13:07:19 +0000589 {"getcwd", mac_getcwd, 1},
590 {"listdir", mac_listdir, 1},
591 {"lseek", mac_lseek, 1},
Jack Jansen243b29b1996-02-21 12:33:50 +0000592 {"mkdir", mac_mkdir, 1},
Jack Jansenddafd2b2001-08-03 13:07:19 +0000593 {"open", mac_open, 1},
594 {"read", mac_read, 1},
595 {"rename", mac_rename, 1},
596 {"rmdir", mac_rmdir, 1},
597 {"stat", mac_stat, 1},
Jack Jansenddafd2b2001-08-03 13:07:19 +0000598 {"sync", mac_sync, 1},
599 {"remove", mac_unlink, 1},
600 {"unlink", mac_unlink, 1},
601 {"write", mac_write, 1},
Jack Jansen46ed2761996-10-23 15:46:57 +0000602#ifdef USE_MALLOC_DEBUG
Jack Jansenddafd2b2001-08-03 13:07:19 +0000603 {"mstats", mac_mstats, 1},
Jack Jansend50e4e11995-01-18 13:58:04 +0000604#endif
Guido van Rossum87f223c1994-05-06 15:54:15 +0000605
Guido van Rossumce9739b1994-01-05 16:17:15 +0000606 {NULL, NULL} /* Sentinel */
607};
608
Jack Jansenddafd2b2001-08-03 13:07:19 +0000609static int
610ins(PyObject *d, char *symbol, long value)
611{
612 PyObject* v = PyInt_FromLong(value);
613 if (!v || PyDict_SetItemString(d, symbol, v) < 0)
614 return -1; /* triggers fatal error */
615
616 Py_DECREF(v);
617 return 0;
618}
619
620static int
621all_ins(PyObject *d)
622{
623#ifdef F_OK
624 if (ins(d, "F_OK", (long)F_OK)) return -1;
625#endif
626#ifdef R_OK
627 if (ins(d, "R_OK", (long)R_OK)) return -1;
628#endif
629#ifdef W_OK
630 if (ins(d, "W_OK", (long)W_OK)) return -1;
631#endif
632#ifdef X_OK
633 if (ins(d, "X_OK", (long)X_OK)) return -1;
634#endif
635#ifdef NGROUPS_MAX
636 if (ins(d, "NGROUPS_MAX", (long)NGROUPS_MAX)) return -1;
637#endif
638#ifdef TMP_MAX
639 if (ins(d, "TMP_MAX", (long)TMP_MAX)) return -1;
640#endif
641#ifdef WNOHANG
642 if (ins(d, "WNOHANG", (long)WNOHANG)) return -1;
643#endif
644#ifdef O_RDONLY
645 if (ins(d, "O_RDONLY", (long)O_RDONLY)) return -1;
646#endif
647#ifdef O_WRONLY
648 if (ins(d, "O_WRONLY", (long)O_WRONLY)) return -1;
649#endif
650#ifdef O_RDWR
651 if (ins(d, "O_RDWR", (long)O_RDWR)) return -1;
652#endif
653#ifdef O_NDELAY
654 if (ins(d, "O_NDELAY", (long)O_NDELAY)) return -1;
655#endif
656#ifdef O_NONBLOCK
657 if (ins(d, "O_NONBLOCK", (long)O_NONBLOCK)) return -1;
658#endif
659#ifdef O_APPEND
660 if (ins(d, "O_APPEND", (long)O_APPEND)) return -1;
661#endif
662#ifdef O_DSYNC
663 if (ins(d, "O_DSYNC", (long)O_DSYNC)) return -1;
664#endif
665#ifdef O_RSYNC
666 if (ins(d, "O_RSYNC", (long)O_RSYNC)) return -1;
667#endif
668#ifdef O_SYNC
669 if (ins(d, "O_SYNC", (long)O_SYNC)) return -1;
670#endif
671#ifdef O_NOCTTY
672 if (ins(d, "O_NOCTTY", (long)O_NOCTTY)) return -1;
673#endif
674#ifdef O_CREAT
675 if (ins(d, "O_CREAT", (long)O_CREAT)) return -1;
676#endif
677#ifdef O_EXCL
678 if (ins(d, "O_EXCL", (long)O_EXCL)) return -1;
679#endif
680#ifdef O_TRUNC
681 if (ins(d, "O_TRUNC", (long)O_TRUNC)) return -1;
682#endif
683#ifdef O_BINARY
684 if (ins(d, "O_BINARY", (long)O_BINARY)) return -1;
685#endif
686#ifdef O_TEXT
687 if (ins(d, "O_TEXT", (long)O_TEXT)) return -1;
688#endif
689
690#ifdef HAVE_SPAWNV
691 if (ins(d, "P_WAIT", (long)_P_WAIT)) return -1;
692 if (ins(d, "P_NOWAIT", (long)_P_NOWAIT)) return -1;
693 if (ins(d, "P_OVERLAY", (long)_OLD_P_OVERLAY)) return -1;
694 if (ins(d, "P_NOWAITO", (long)_P_NOWAITO)) return -1;
695 if (ins(d, "P_DETACH", (long)_P_DETACH)) return -1;
696#endif
697
698#if defined(PYOS_OS2)
699 if (insertvalues(d)) return -1;
700#endif
701 return 0;
702}
703
Guido van Rossumce9739b1994-01-05 16:17:15 +0000704
705void
706initmac()
707{
Jack Jansenf5c20571997-01-30 15:48:07 +0000708 PyObject *m, *d;
Guido van Rossumce9739b1994-01-05 16:17:15 +0000709
Jack Jansenf5c20571997-01-30 15:48:07 +0000710 m = Py_InitModule("mac", mac_methods);
711 d = PyModule_GetDict(m);
Guido van Rossumce9739b1994-01-05 16:17:15 +0000712
Jack Jansenddafd2b2001-08-03 13:07:19 +0000713 if (all_ins(d))
714 return;
715
Guido van Rossumce9739b1994-01-05 16:17:15 +0000716 /* Initialize mac.error exception */
Jack Jansenb3be2162001-11-30 14:16:36 +0000717 PyDict_SetItemString(d, "error", PyExc_OSError);
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000718
719 PyStructSequence_InitType(&StatResultType, &stat_result_desc);
720 PyDict_SetItemString(d, "stat_result", (PyObject*) &StatResultType);
721
Guido van Rossumce9739b1994-01-05 16:17:15 +0000722}