blob: 367e21c3ddba00c5e090aca8724d9ab3749f2bfb [file] [log] [blame]
Guido van Rossumf70e43a1991-02-19 12:39:46 +00001/***********************************************************
Guido van Rossum22db57e1992-04-05 14:25:30 +00002Copyright 1991, 1992 by Stichting Mathematisch Centrum, Amsterdam, The
Guido van Rossumf70e43a1991-02-19 12:39:46 +00003Netherlands.
4
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 Rossum85a5fbb1990-10-14 12:07:46 +000025/* POSIX module implementation */
26
Guido van Rossum1ff6cb41991-04-08 20:59:13 +000027#ifdef AMOEBA
28#define NO_LSTAT
29#define SYSV
30#endif
31
Guido van Rossum0ee42cd1991-04-08 21:01:03 +000032#ifdef MSDOS
33#define NO_LSTAT
Guido van Rossumc39de5f1992-02-05 11:15:54 +000034#define NO_UNAME
Guido van Rossum0ee42cd1991-04-08 21:01:03 +000035#endif
36
Guido van Rossum22db57e1992-04-05 14:25:30 +000037#ifndef MSDOS
38#define DO_TIMES /* Comment this out if it causes trouble */
39#endif
40
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000041#include <signal.h>
42#include <string.h>
43#include <setjmp.h>
44#include <sys/types.h>
45#include <sys/stat.h>
Guido van Rossum0ee42cd1991-04-08 21:01:03 +000046
Guido van Rossum22db57e1992-04-05 14:25:30 +000047#ifdef DO_TIMES
48#include <sys/times.h>
49#include <sys/param.h>
50#include <errno.h>
51#endif
52
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000053#ifdef SYSV
Guido van Rossum0ee42cd1991-04-08 21:01:03 +000054
Guido van Rossum1ff6cb41991-04-08 20:59:13 +000055#define UTIME_STRUCT
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000056#include <dirent.h>
57#define direct dirent
Guido van Rossum1ff6cb41991-04-08 20:59:13 +000058#ifdef i386
59#define mode_t int
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000060#endif
Guido van Rossum0ee42cd1991-04-08 21:01:03 +000061
Guido van Rossum1ff6cb41991-04-08 20:59:13 +000062#else /* !SYSV */
Guido van Rossum0ee42cd1991-04-08 21:01:03 +000063
64#ifndef MSDOS
Guido van Rossum1ff6cb41991-04-08 20:59:13 +000065#include <sys/dir.h>
Guido van Rossum0ee42cd1991-04-08 21:01:03 +000066#endif
67
Guido van Rossum1ff6cb41991-04-08 20:59:13 +000068#endif /* !SYSV */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000069
Guido van Rossum50e61dc1992-03-27 17:22:31 +000070#ifndef NO_UNISTD
Guido van Rossum22db57e1992-04-05 14:25:30 +000071#include <unistd.h> /* Take this out and hope the best if it doesn't exist */
Guido van Rossum50e61dc1992-03-27 17:22:31 +000072#endif
73
Guido van Rossum3f5da241990-12-20 15:06:42 +000074#include "allobjects.h"
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000075#include "modsupport.h"
Guido van Rossumff4949e1992-08-05 19:58:53 +000076#include "ceval.h"
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000077
Guido van Rossum7f77e2d1990-10-30 13:34:38 +000078extern char *strerror PROTO((int));
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000079
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000080
81/* Return a dictionary corresponding to the POSIX environment table */
82
83extern char **environ;
84
85static object *
86convertenviron()
87{
88 object *d;
89 char **e;
90 d = newdictobject();
91 if (d == NULL)
92 return NULL;
93 if (environ == NULL)
94 return d;
95 /* XXX This part ignores errors */
96 for (e = environ; *e != NULL; e++) {
97 object *v;
98 char *p = strchr(*e, '=');
99 if (p == NULL)
100 continue;
101 v = newstringobject(p+1);
102 if (v == NULL)
103 continue;
104 *p = '\0';
105 (void) dictinsert(d, *e, v);
106 *p = '=';
107 DECREF(v);
108 }
109 return d;
110}
111
112
113static object *PosixError; /* Exception posix.error */
114
115/* Set a POSIX-specific error from errno, and return NULL */
116
Guido van Rossum9a1581c1990-10-21 13:12:47 +0000117static object *
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000118posix_error()
119{
Guido van Rossume8f305a1990-10-14 20:04:28 +0000120 return err_errno(PosixError);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000121}
122
123
124/* POSIX generic methods */
125
126static object *
127posix_1str(args, func)
128 object *args;
129 int (*func) FPROTO((const char *));
130{
Guido van Rossumef0a00e1992-01-27 16:51:30 +0000131 char *path1;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000132 int res;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000133 if (!getstrarg(args, &path1))
134 return NULL;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000135 BGN_SAVE
136 res = (*func)(path1);
137 END_SAVE
138 if (res < 0)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000139 return posix_error();
140 INCREF(None);
141 return None;
142}
143
144static object *
145posix_2str(args, func)
146 object *args;
147 int (*func) FPROTO((const char *, const char *));
148{
Guido van Rossumef0a00e1992-01-27 16:51:30 +0000149 char *path1, *path2;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000150 int res;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000151 if (!getstrstrarg(args, &path1, &path2))
152 return NULL;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000153 BGN_SAVE
154 res = (*func)(path1, path2);
155 END_SAVE
156 if (res < 0)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000157 return posix_error();
158 INCREF(None);
159 return None;
160}
161
162static object *
163posix_strint(args, func)
164 object *args;
165 int (*func) FPROTO((const char *, int));
166{
Guido van Rossumef0a00e1992-01-27 16:51:30 +0000167 char *path;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000168 int i;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000169 int res;
Guido van Rossumef0a00e1992-01-27 16:51:30 +0000170 if (!getstrintarg(args, &path, &i))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000171 return NULL;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000172 BGN_SAVE
173 res = (*func)(path, i);
174 END_SAVE
175 if (res < 0)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000176 return posix_error();
177 INCREF(None);
178 return None;
179}
180
181static object *
182posix_do_stat(self, args, statfunc)
183 object *self;
184 object *args;
185 int (*statfunc) FPROTO((const char *, struct stat *));
186{
187 struct stat st;
Guido van Rossumef0a00e1992-01-27 16:51:30 +0000188 char *path;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000189 object *v;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000190 int res;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000191 if (!getstrarg(args, &path))
192 return NULL;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000193 BGN_SAVE
194 res = (*statfunc)(path, &st);
195 END_SAVE
196 if (res != 0)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000197 return posix_error();
198 v = newtupleobject(10);
199 if (v == NULL)
200 return NULL;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000201#define SET(i, st_member) settupleitem(v, i, newintobject((long)st.st_member))
202 SET(0, st_mode);
203 SET(1, st_ino);
204 SET(2, st_dev);
205 SET(3, st_nlink);
206 SET(4, st_uid);
207 SET(5, st_gid);
208 SET(6, st_size);
209 SET(7, st_atime);
210 SET(8, st_mtime);
211 SET(9, st_ctime);
212#undef SET
Guido van Rossum3f5da241990-12-20 15:06:42 +0000213 if (err_occurred()) {
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000214 DECREF(v);
Guido van Rossum3f5da241990-12-20 15:06:42 +0000215 return NULL;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000216 }
217 return v;
218}
219
220
221/* POSIX methods */
222
223static object *
224posix_chdir(self, args)
225 object *self;
226 object *args;
227{
228 extern int chdir PROTO((const char *));
229 return posix_1str(args, chdir);
230}
231
232static object *
233posix_chmod(self, args)
234 object *self;
235 object *args;
236{
237 extern int chmod PROTO((const char *, mode_t));
238 return posix_strint(args, chmod);
239}
240
241static object *
242posix_getcwd(self, args)
243 object *self;
244 object *args;
245{
246 char buf[1026];
Guido van Rossumff4949e1992-08-05 19:58:53 +0000247 char *res;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000248 extern char *getcwd PROTO((char *, int));
249 if (!getnoarg(args))
250 return NULL;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000251 BGN_SAVE
252 res = getcwd(buf, sizeof buf);
253 END_SAVE
254 if (res == NULL)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000255 return posix_error();
256 return newstringobject(buf);
257}
258
Guido van Rossum0ee42cd1991-04-08 21:01:03 +0000259#ifndef MSDOS
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000260static object *
261posix_link(self, args)
262 object *self;
263 object *args;
264{
265 extern int link PROTO((const char *, const char *));
266 return posix_2str(args, link);
267}
Guido van Rossum0ee42cd1991-04-08 21:01:03 +0000268#endif /* !MSDOS */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000269
270static object *
271posix_listdir(self, args)
272 object *self;
273 object *args;
274{
Guido van Rossumef0a00e1992-01-27 16:51:30 +0000275 char *name;
276 object *d, *v;
Guido van Rossum0ee42cd1991-04-08 21:01:03 +0000277
278#ifdef MSDOS
279 struct ffblk ep;
280 int rv;
281 if (!getstrarg(args, &name))
282 return NULL;
283
Guido van Rossumef0a00e1992-01-27 16:51:30 +0000284 if (findfirst(name, &ep, 0) == -1)
Guido van Rossum0ee42cd1991-04-08 21:01:03 +0000285 return posix_error();
286 if ((d = newlistobject(0)) == NULL)
287 return NULL;
288 do {
289 v = newstringobject(ep.ff_name);
290 if (v == NULL) {
291 DECREF(d);
292 d = NULL;
293 break;
294 }
295 if (addlistitem(d, v) != 0) {
296 DECREF(v);
297 DECREF(d);
298 d = NULL;
299 break;
300 }
301 DECREF(v);
302 } while ((rv = findnext(&ep)) == 0);
303#else /* !MSDOS */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000304 DIR *dirp;
305 struct direct *ep;
306 if (!getstrarg(args, &name))
307 return NULL;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000308 BGN_SAVE
309 if ((dirp = opendir(name)) == NULL) {
310 RET_SAVE
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000311 return posix_error();
Guido van Rossumff4949e1992-08-05 19:58:53 +0000312 }
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000313 if ((d = newlistobject(0)) == NULL) {
314 closedir(dirp);
Guido van Rossumff4949e1992-08-05 19:58:53 +0000315 RET_SAVE
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000316 return NULL;
317 }
318 while ((ep = readdir(dirp)) != NULL) {
319 v = newstringobject(ep->d_name);
320 if (v == NULL) {
321 DECREF(d);
322 d = NULL;
323 break;
324 }
325 if (addlistitem(d, v) != 0) {
326 DECREF(v);
327 DECREF(d);
328 d = NULL;
329 break;
330 }
331 DECREF(v);
332 }
333 closedir(dirp);
Guido van Rossumff4949e1992-08-05 19:58:53 +0000334 END_SAVE
Guido van Rossum0ee42cd1991-04-08 21:01:03 +0000335#endif /* !MSDOS */
336
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000337 return d;
338}
339
340static object *
341posix_mkdir(self, args)
342 object *self;
343 object *args;
344{
345 extern int mkdir PROTO((const char *, mode_t));
346 return posix_strint(args, mkdir);
347}
348
Guido van Rossum1ff6cb41991-04-08 20:59:13 +0000349#ifdef i386
350int
351rename(from, to)
352 char *from;
353 char *to;
354{
355 int status;
356 /* XXX Shouldn't this unlink the destination first? */
357 status = link(from, to);
358 if (status != 0)
359 return status;
360 return unlink(from);
361}
Guido van Rossum0ee42cd1991-04-08 21:01:03 +0000362#endif /* i386 */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +0000363
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000364static object *
365posix_rename(self, args)
366 object *self;
367 object *args;
368{
369 extern int rename PROTO((const char *, const char *));
370 return posix_2str(args, rename);
371}
372
373static object *
374posix_rmdir(self, args)
375 object *self;
376 object *args;
377{
378 extern int rmdir PROTO((const char *));
379 return posix_1str(args, rmdir);
380}
381
382static object *
383posix_stat(self, args)
384 object *self;
385 object *args;
386{
387 extern int stat PROTO((const char *, struct stat *));
388 return posix_do_stat(self, args, stat);
389}
390
391static object *
392posix_system(self, args)
393 object *self;
394 object *args;
395{
Guido van Rossumef0a00e1992-01-27 16:51:30 +0000396 char *command;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000397 long sts;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000398 if (!getstrarg(args, &command))
399 return NULL;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000400 BGN_SAVE
Guido van Rossumef0a00e1992-01-27 16:51:30 +0000401 sts = system(command);
Guido van Rossumff4949e1992-08-05 19:58:53 +0000402 END_SAVE
403 return newintobject(sts);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000404}
405
Guido van Rossum0ee42cd1991-04-08 21:01:03 +0000406#ifndef MSDOS
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000407static object *
408posix_umask(self, args)
409 object *self;
410 object *args;
411{
412 int i;
413 if (!getintarg(args, &i))
414 return NULL;
415 i = umask(i);
416 if (i < 0)
417 return posix_error();
418 return newintobject((long)i);
419}
Guido van Rossum0ee42cd1991-04-08 21:01:03 +0000420#endif /* !MSDOS */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000421
422static object *
423posix_unlink(self, args)
424 object *self;
425 object *args;
426{
427 extern int unlink PROTO((const char *));
428 return posix_1str(args, unlink);
429}
430
Guido van Rossumc39de5f1992-02-05 11:15:54 +0000431#ifndef NO_UNAME
432#include <sys/utsname.h>
433
434static object *
435posix_uname(self, args)
436 object *self;
437 object *args;
438{
439 extern int uname PROTO((struct utsname *));
440 struct utsname u;
441 object *v;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000442 int res;
Guido van Rossum50e61dc1992-03-27 17:22:31 +0000443 if (!getnoarg(args))
444 return NULL;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000445 BGN_SAVE
446 res = uname(&u);
447 END_SAVE
448 if (res < 0)
Guido van Rossumc39de5f1992-02-05 11:15:54 +0000449 return posix_error();
450 v = newtupleobject(5);
451 if (v == NULL)
452 return NULL;
453#define SET(i, member) settupleitem(v, i, newstringobject(u.member))
454 SET(0, sysname);
455 SET(1, nodename);
456 SET(2, release);
457 SET(3, version);
458 SET(4, machine);
459#undef SET
460 if (err_occurred()) {
461 DECREF(v);
462 return NULL;
463 }
464 return v;
465}
466#endif /* NO_UNAME */
467
Guido van Rossum1ff6cb41991-04-08 20:59:13 +0000468#ifdef UTIME_STRUCT
469#include <utime.h>
470#endif
471
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000472static object *
Guido van Rossum1ff6cb41991-04-08 20:59:13 +0000473posix_utime(self, args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000474 object *self;
475 object *args;
476{
Guido van Rossumef0a00e1992-01-27 16:51:30 +0000477 char *path;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000478 int res;
Guido van Rossum1ff6cb41991-04-08 20:59:13 +0000479
480#ifdef UTIME_STRUCT
481 struct utimbuf buf;
482#define ATIME buf.actime
483#define MTIME buf.modtime
484#define UTIME_ARG &buf
485
486#else
487 time_t buf[2];
488#define ATIME buf[0]
489#define MTIME buf[1]
490#define UTIME_ARG buf
491#endif
492
Guido van Rossumef0a00e1992-01-27 16:51:30 +0000493 if (!getargs(args, "(s(ll))", &path, &ATIME, &MTIME))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000494 return NULL;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000495 BGN_SAVE
496 res = utime(path, UTIME_ARG);
497 END_SAVE
498 if (res < 0)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000499 return posix_error();
500 INCREF(None);
501 return None;
Guido van Rossum1ff6cb41991-04-08 20:59:13 +0000502#undef UTIME_ARG
503#undef ATIME
504#undef MTIME
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000505}
506
Guido van Rossum85e3b011991-06-03 12:42:10 +0000507
508#ifndef MSDOS
509
Guido van Rossum3b066191991-06-04 19:40:25 +0000510/* Process operations */
Guido van Rossum85e3b011991-06-03 12:42:10 +0000511
512static object *
513posix__exit(self, args)
514 object *self;
515 object *args;
516{
517 int sts;
518 if (!getintarg(args, &sts))
519 return NULL;
520 _exit(sts);
521 /* NOTREACHED */
522}
523
524/* XXX To do: exece, execp */
525
526static object *
527posix_exec(self, args)
528 object *self;
529 object *args;
530{
Guido van Rossumef0a00e1992-01-27 16:51:30 +0000531 char *path;
532 object *argv;
Guido van Rossum85e3b011991-06-03 12:42:10 +0000533 char **argvlist;
534 int i, argc;
535 object *(*getitem) PROTO((object *, int));
536
537 /* exec has two arguments: (path, argv), where
538 argv is a list or tuple of strings. */
539
Guido van Rossumef0a00e1992-01-27 16:51:30 +0000540 if (!getargs(args, "(sO)", &path, &argv))
Guido van Rossum85e3b011991-06-03 12:42:10 +0000541 return NULL;
Guido van Rossum85e3b011991-06-03 12:42:10 +0000542 if (is_listobject(argv)) {
543 argc = getlistsize(argv);
544 getitem = getlistitem;
545 }
546 else if (is_tupleobject(argv)) {
547 argc = gettuplesize(argv);
548 getitem = gettupleitem;
549 }
Guido van Rossumef0a00e1992-01-27 16:51:30 +0000550 else {
551 badarg:
552 err_badarg();
553 return NULL;
554 }
Guido van Rossum85e3b011991-06-03 12:42:10 +0000555
556 argvlist = NEW(char *, argc+1);
557 if (argvlist == NULL)
558 return NULL;
559 for (i = 0; i < argc; i++) {
Guido van Rossumef0a00e1992-01-27 16:51:30 +0000560 if (!getstrarg((*getitem)(argv, i), &argvlist[i])) {
Guido van Rossum85e3b011991-06-03 12:42:10 +0000561 DEL(argvlist);
562 goto badarg;
563 }
Guido van Rossum85e3b011991-06-03 12:42:10 +0000564 }
565 argvlist[argc] = NULL;
566
Guido van Rossumef0a00e1992-01-27 16:51:30 +0000567 execv(path, argvlist);
Guido van Rossum85e3b011991-06-03 12:42:10 +0000568
569 /* If we get here it's definitely an error */
570
571 DEL(argvlist);
572 return posix_error();
573}
574
575static object *
576posix_fork(self, args)
577 object *self;
578 object *args;
579{
580 int pid;
Guido van Rossum50e61dc1992-03-27 17:22:31 +0000581 if (!getnoarg(args))
582 return NULL;
Guido van Rossum85e3b011991-06-03 12:42:10 +0000583 pid = fork();
584 if (pid == -1)
585 return posix_error();
586 return newintobject((long)pid);
587}
588
589static object *
Guido van Rossum46003ff1992-05-15 11:05:24 +0000590posix_getegid(self, args)
591 object *self;
592 object *args;
593{
594 if (!getnoarg(args))
595 return NULL;
596 return newintobject((long)getegid());
597}
598
599static object *
600posix_geteuid(self, args)
601 object *self;
602 object *args;
603{
604 if (!getnoarg(args))
605 return NULL;
606 return newintobject((long)geteuid());
607}
608
609static object *
610posix_getgid(self, args)
611 object *self;
612 object *args;
613{
614 if (!getnoarg(args))
615 return NULL;
616 return newintobject((long)getgid());
617}
618
619static object *
Guido van Rossum85e3b011991-06-03 12:42:10 +0000620posix_getpid(self, args)
621 object *self;
622 object *args;
623{
Guido van Rossum04814471991-06-04 20:23:49 +0000624 if (!getnoarg(args))
Guido van Rossum85e3b011991-06-03 12:42:10 +0000625 return NULL;
626 return newintobject((long)getpid());
627}
628
629static object *
Guido van Rossum04814471991-06-04 20:23:49 +0000630posix_getpgrp(self, args)
631 object *self;
632 object *args;
633{
634 if (!getnoarg(args))
635 return NULL;
Guido van Rossum50e61dc1992-03-27 17:22:31 +0000636#ifdef SYSV
637 return newintobject((long)getpgrp());
638#else
Guido van Rossum971443b1991-06-07 13:59:29 +0000639 return newintobject((long)getpgrp(0));
Guido van Rossum50e61dc1992-03-27 17:22:31 +0000640#endif
Guido van Rossum04814471991-06-04 20:23:49 +0000641}
642
643static object *
Guido van Rossum85e3b011991-06-03 12:42:10 +0000644posix_getppid(self, args)
645 object *self;
646 object *args;
647{
Guido van Rossum04814471991-06-04 20:23:49 +0000648 if (!getnoarg(args))
Guido van Rossum85e3b011991-06-03 12:42:10 +0000649 return NULL;
650 return newintobject((long)getppid());
651}
652
653static object *
Guido van Rossum46003ff1992-05-15 11:05:24 +0000654posix_getuid(self, args)
655 object *self;
656 object *args;
657{
658 if (!getnoarg(args))
659 return NULL;
660 return newintobject((long)getuid());
661}
662
663static object *
Guido van Rossum85e3b011991-06-03 12:42:10 +0000664posix_kill(self, args)
665 object *self;
666 object *args;
667{
668 int pid, sig;
669 if (!getintintarg(args, &pid, &sig))
670 return NULL;
671 if (kill(pid, sig) == -1)
672 return posix_error();
673 INCREF(None);
674 return None;
675}
676
677static object *
Guido van Rossum3b066191991-06-04 19:40:25 +0000678posix_popen(self, args)
679 object *self;
680 object *args;
681{
682 extern int pclose PROTO((FILE *));
Guido van Rossumef0a00e1992-01-27 16:51:30 +0000683 char *name, *mode;
Guido van Rossum3b066191991-06-04 19:40:25 +0000684 FILE *fp;
Guido van Rossumef0a00e1992-01-27 16:51:30 +0000685 if (!getargs(args, "(ss)", &name, &mode))
Guido van Rossum3b066191991-06-04 19:40:25 +0000686 return NULL;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000687 BGN_SAVE
Guido van Rossumef0a00e1992-01-27 16:51:30 +0000688 fp = popen(name, mode);
Guido van Rossumff4949e1992-08-05 19:58:53 +0000689 END_SAVE
Guido van Rossum3b066191991-06-04 19:40:25 +0000690 if (fp == NULL)
691 return posix_error();
Guido van Rossume0d452d1991-07-27 21:41:01 +0000692 /* From now on, ignore SIGPIPE and let the error checking
693 do the work. */
694 (void) signal(SIGPIPE, SIG_IGN);
Guido van Rossumef0a00e1992-01-27 16:51:30 +0000695 return newopenfileobject(fp, name, mode, pclose);
Guido van Rossum3b066191991-06-04 19:40:25 +0000696}
697
698static object *
Guido van Rossum85e3b011991-06-03 12:42:10 +0000699posix_wait(self, args) /* Also waitpid() */
700 object *self;
701 object *args;
702{
703 object *v;
704 int pid, sts;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000705 if (args == NULL) {
706 BGN_SAVE
Guido van Rossum85e3b011991-06-03 12:42:10 +0000707 pid = wait(&sts);
Guido van Rossumff4949e1992-08-05 19:58:53 +0000708 END_SAVE
709 }
Guido van Rossum85e3b011991-06-03 12:42:10 +0000710 else {
711#ifdef NO_WAITPID
Guido van Rossumc39de5f1992-02-05 11:15:54 +0000712 err_setstr(PosixError,
Guido van Rossum85e3b011991-06-03 12:42:10 +0000713 "posix.wait(pid, options) not supported on this system");
714#else
715 int options;
716 if (!getintintarg(args, &pid, &options))
717 return NULL;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000718 BGN_SAVE
Guido van Rossum85e3b011991-06-03 12:42:10 +0000719 pid = waitpid(pid, &sts, options);
Guido van Rossumff4949e1992-08-05 19:58:53 +0000720 END_SAVE
Guido van Rossum85e3b011991-06-03 12:42:10 +0000721#endif
722 }
723 if (pid == -1)
724 return posix_error();
725 v = newtupleobject(2);
726 if (v != NULL) {
727 settupleitem(v, 0, newintobject((long)pid));
728 settupleitem(v, 1, newintobject((long)sts));
729 if (err_occurred()) {
730 DECREF(v);
731 v = NULL;
732 }
733 }
734 return v;
735}
736
737#endif /* MSDOS */
738
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000739static object *
740posix_lstat(self, args)
741 object *self;
742 object *args;
743{
Guido van Rossumc39de5f1992-02-05 11:15:54 +0000744#ifdef NO_LSTAT
745#define lstat stat
746#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000747 extern int lstat PROTO((const char *, struct stat *));
748 return posix_do_stat(self, args, lstat);
749}
750
751static object *
752posix_readlink(self, args)
753 object *self;
754 object *args;
755{
Guido van Rossumc39de5f1992-02-05 11:15:54 +0000756#ifdef NO_LSTAT
757 err_setstr(PosixError, "readlink not implemented on this system");
758 return NULL;
759#else
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000760 char buf[1024]; /* XXX Should use MAXPATHLEN */
Guido van Rossumef0a00e1992-01-27 16:51:30 +0000761 char *path;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000762 int n;
763 if (!getstrarg(args, &path))
764 return NULL;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000765 BGN_SAVE
Guido van Rossum50e61dc1992-03-27 17:22:31 +0000766 n = readlink(path, buf, (int) sizeof buf);
Guido van Rossumff4949e1992-08-05 19:58:53 +0000767 END_SAVE
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000768 if (n < 0)
769 return posix_error();
770 return newsizedstringobject(buf, n);
Guido van Rossumc39de5f1992-02-05 11:15:54 +0000771#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000772}
773
774static object *
775posix_symlink(self, args)
776 object *self;
777 object *args;
778{
Guido van Rossumc39de5f1992-02-05 11:15:54 +0000779#ifdef NO_LSTAT
780 err_setstr(PosixError, "symlink not implemented on this system");
781 return NULL;
782#else
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000783 extern int symlink PROTO((const char *, const char *));
784 return posix_2str(args, symlink);
Guido van Rossumc39de5f1992-02-05 11:15:54 +0000785#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000786}
787
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000788
Guido van Rossum22db57e1992-04-05 14:25:30 +0000789#ifdef DO_TIMES
790
791static object *
792posix_times(self, args)
793 object *self;
794 object *args;
795{
796 struct tms t;
797 clock_t c;
798 object *tuple;
799 if (!getnoarg(args))
800 return NULL;
801 errno = 0;
802 c = times(&t);
803 if (c == (clock_t) -1) {
804 err_errno(IOError);
805 return NULL;
806 }
807 tuple = newtupleobject(4);
808 if (tuple == NULL)
809 return NULL;
810 settupleitem(tuple, 0, newfloatobject((double)t.tms_utime / HZ));
811 settupleitem(tuple, 1, newfloatobject((double)t.tms_stime / HZ));
812 settupleitem(tuple, 2, newfloatobject((double)t.tms_cutime / HZ));
813 settupleitem(tuple, 3, newfloatobject((double)t.tms_cstime / HZ));
814 if (err_occurred()) {
815 DECREF(tuple);
816 return NULL;
817 }
818 return tuple;
819}
820
821#endif
822
823
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000824static struct methodlist posix_methods[] = {
825 {"chdir", posix_chdir},
826 {"chmod", posix_chmod},
827 {"getcwd", posix_getcwd},
Guido van Rossum0ee42cd1991-04-08 21:01:03 +0000828#ifndef MSDOS
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000829 {"link", posix_link},
Guido van Rossum0ee42cd1991-04-08 21:01:03 +0000830#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000831 {"listdir", posix_listdir},
Guido van Rossumc39de5f1992-02-05 11:15:54 +0000832 {"lstat", posix_lstat},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000833 {"mkdir", posix_mkdir},
Guido van Rossumc39de5f1992-02-05 11:15:54 +0000834 {"readlink", posix_readlink},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000835 {"rename", posix_rename},
836 {"rmdir", posix_rmdir},
837 {"stat", posix_stat},
Guido van Rossumc39de5f1992-02-05 11:15:54 +0000838 {"symlink", posix_symlink},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000839 {"system", posix_system},
Guido van Rossum0ee42cd1991-04-08 21:01:03 +0000840#ifndef MSDOS
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000841 {"umask", posix_umask},
Guido van Rossum0ee42cd1991-04-08 21:01:03 +0000842#endif
Guido van Rossumc39de5f1992-02-05 11:15:54 +0000843#ifndef NO_UNAME
844 {"uname", posix_uname},
845#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000846 {"unlink", posix_unlink},
Guido van Rossum1ff6cb41991-04-08 20:59:13 +0000847 {"utime", posix_utime},
Guido van Rossum22db57e1992-04-05 14:25:30 +0000848#ifdef DO_TIMES
849 {"times", posix_times},
850#endif
Guido van Rossumc39de5f1992-02-05 11:15:54 +0000851
Guido van Rossum85e3b011991-06-03 12:42:10 +0000852#ifndef MSDOS
853 {"_exit", posix__exit},
854 {"exec", posix_exec},
855 {"fork", posix_fork},
Guido van Rossum46003ff1992-05-15 11:05:24 +0000856 {"getegid", posix_getegid},
857 {"geteuid", posix_geteuid},
858 {"getgid", posix_getgid},
Guido van Rossum85e3b011991-06-03 12:42:10 +0000859 {"getpid", posix_getpid},
Guido van Rossum04814471991-06-04 20:23:49 +0000860 {"getpgrp", posix_getpgrp},
Guido van Rossum85e3b011991-06-03 12:42:10 +0000861 {"getppid", posix_getppid},
Guido van Rossum46003ff1992-05-15 11:05:24 +0000862 {"getuid", posix_getuid},
Guido van Rossum85e3b011991-06-03 12:42:10 +0000863 {"kill", posix_kill},
Guido van Rossum3b066191991-06-04 19:40:25 +0000864 {"popen", posix_popen},
Guido van Rossum85e3b011991-06-03 12:42:10 +0000865 {"wait", posix_wait},
866#endif
Guido van Rossumc39de5f1992-02-05 11:15:54 +0000867
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000868 {NULL, NULL} /* Sentinel */
869};
870
871
872void
873initposix()
874{
875 object *m, *d, *v;
876
877 m = initmodule("posix", posix_methods);
878 d = getmoduledict(m);
879
880 /* Initialize posix.environ dictionary */
881 v = convertenviron();
882 if (v == NULL || dictinsert(d, "environ", v) != 0)
883 fatal("can't define posix.environ");
884 DECREF(v);
885
886 /* Initialize posix.error exception */
887 PosixError = newstringobject("posix.error");
888 if (PosixError == NULL || dictinsert(d, "error", PosixError) != 0)
889 fatal("can't define posix.error");
890}
Guido van Rossum0ee42cd1991-04-08 21:01:03 +0000891
Guido van Rossum3b066191991-06-04 19:40:25 +0000892
893/* Function used elsewhere to get a file's modification time */
894
895long
896getmtime(path)
897 char *path;
898{
899 struct stat st;
900 if (stat(path, &st) != 0)
901 return -1;
902 else
903 return st.st_mtime;
904}
905
906
Guido van Rossum0ee42cd1991-04-08 21:01:03 +0000907#ifdef MSDOS
908
909/* A small "compatibility library" for TurboC under MS-DOS */
910
911#include <sir.h>
912#include <io.h>
913#include <dos.h>
914#include <fcntl.h>
915
916int
917chmod(path, mode)
918 char *path;
919 int mode;
920{
921 return _chmod(path, 1, mode);
922}
923
924int
925utime(path, times)
926 char *path;
927 time_t times[2];
928{
929 struct date dt;
930 struct time tm;
931 struct ftime dft;
932 int fh;
933 unixtodos(tv[0].tv_sec,&dt,&tm);
934 dft.ft_tsec = tm.ti_sec; dft.ft_min = tm.ti_min;
935 dft.ft_hour = tm.ti_hour; dft.ft_day = dt.da_day;
936 dft.ft_month = dt.da_mon;
937 dft.ft_year = (dt.da_year - 1980); /* this is for TC library */
938
Guido van Rossumef0a00e1992-01-27 16:51:30 +0000939 if ((fh = open(path,O_RDWR)) < 0)
Guido van Rossum0ee42cd1991-04-08 21:01:03 +0000940 return posix_error(); /* can't open file to set time */
941 if (setftime(fh,&dft) < 0)
942 {
943 close(fh);
944 return posix_error();
945 }
946 close(fh); /* close the temp handle */
947}
948
949#endif /* MSDOS */