blob: a263f1bdb8914ef47128bfbcd6ffd09c3cb16d53 [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 Rossumc2670a01992-09-13 20:07:29 +000037#ifdef __sgi
38#define DO_PG
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 Rossumc2670a01992-09-13 20:07:29 +0000644posix_setpgrp(self, args)
645 object *self;
646 object *args;
647{
648 if (!getnoarg(args))
649 return NULL;
650#ifdef SYSV
651 if (setpgrp() < 0)
652#else
653 if (setpgrp(0, 0) < 0)
654#endif
655 return err_errno(PosixError);
656 INCREF(None);
657 return None;
658}
659
660static object *
Guido van Rossum85e3b011991-06-03 12:42:10 +0000661posix_getppid(self, args)
662 object *self;
663 object *args;
664{
Guido van Rossum04814471991-06-04 20:23:49 +0000665 if (!getnoarg(args))
Guido van Rossum85e3b011991-06-03 12:42:10 +0000666 return NULL;
667 return newintobject((long)getppid());
668}
669
670static object *
Guido van Rossum46003ff1992-05-15 11:05:24 +0000671posix_getuid(self, args)
672 object *self;
673 object *args;
674{
675 if (!getnoarg(args))
676 return NULL;
677 return newintobject((long)getuid());
678}
679
680static object *
Guido van Rossum85e3b011991-06-03 12:42:10 +0000681posix_kill(self, args)
682 object *self;
683 object *args;
684{
685 int pid, sig;
686 if (!getintintarg(args, &pid, &sig))
687 return NULL;
688 if (kill(pid, sig) == -1)
689 return posix_error();
690 INCREF(None);
691 return None;
692}
693
694static object *
Guido van Rossum3b066191991-06-04 19:40:25 +0000695posix_popen(self, args)
696 object *self;
697 object *args;
698{
699 extern int pclose PROTO((FILE *));
Guido van Rossumef0a00e1992-01-27 16:51:30 +0000700 char *name, *mode;
Guido van Rossum3b066191991-06-04 19:40:25 +0000701 FILE *fp;
Guido van Rossumef0a00e1992-01-27 16:51:30 +0000702 if (!getargs(args, "(ss)", &name, &mode))
Guido van Rossum3b066191991-06-04 19:40:25 +0000703 return NULL;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000704 BGN_SAVE
Guido van Rossumef0a00e1992-01-27 16:51:30 +0000705 fp = popen(name, mode);
Guido van Rossumff4949e1992-08-05 19:58:53 +0000706 END_SAVE
Guido van Rossum3b066191991-06-04 19:40:25 +0000707 if (fp == NULL)
708 return posix_error();
Guido van Rossume0d452d1991-07-27 21:41:01 +0000709 /* From now on, ignore SIGPIPE and let the error checking
710 do the work. */
711 (void) signal(SIGPIPE, SIG_IGN);
Guido van Rossumef0a00e1992-01-27 16:51:30 +0000712 return newopenfileobject(fp, name, mode, pclose);
Guido van Rossum3b066191991-06-04 19:40:25 +0000713}
714
715static object *
Guido van Rossum21803b81992-08-09 12:55:27 +0000716posix_waitpid(self, args)
Guido van Rossum85e3b011991-06-03 12:42:10 +0000717 object *self;
718 object *args;
719{
Guido van Rossum85e3b011991-06-03 12:42:10 +0000720#ifdef NO_WAITPID
Guido van Rossum21803b81992-08-09 12:55:27 +0000721 err_setstr(PosixError,
722 "posix.waitpid() not supported on this system");
723 return NULL;
Guido van Rossum85e3b011991-06-03 12:42:10 +0000724#else
Guido van Rossum21803b81992-08-09 12:55:27 +0000725 int pid, options, sts;
726 if (!getargs(args, "(ii)", &pid, &options))
727 return NULL;
728 BGN_SAVE
729 pid = waitpid(pid, &sts, options);
730 END_SAVE
Guido van Rossum85e3b011991-06-03 12:42:10 +0000731 if (pid == -1)
732 return posix_error();
Guido van Rossum21803b81992-08-09 12:55:27 +0000733 else
734 return mkvalue("ii", pid, sts);
735#endif
736}
737
738static object *
739posix_wait(self, args)
740 object *self;
741 object *args;
742{
743 int pid, sts;
744 if (args != NULL)
745 return posix_waitpid(self, args); /* BW compat */
746 BGN_SAVE
747 pid = wait(&sts);
748 END_SAVE
749 if (pid == -1)
750 return posix_error();
751 else
752 return mkvalue("ii", pid, sts);
Guido van Rossum85e3b011991-06-03 12:42:10 +0000753}
754
755#endif /* MSDOS */
756
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000757static object *
758posix_lstat(self, args)
759 object *self;
760 object *args;
761{
Guido van Rossumc39de5f1992-02-05 11:15:54 +0000762#ifdef NO_LSTAT
763#define lstat stat
764#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000765 extern int lstat PROTO((const char *, struct stat *));
766 return posix_do_stat(self, args, lstat);
767}
768
769static object *
770posix_readlink(self, args)
771 object *self;
772 object *args;
773{
Guido van Rossumc39de5f1992-02-05 11:15:54 +0000774#ifdef NO_LSTAT
775 err_setstr(PosixError, "readlink not implemented on this system");
776 return NULL;
777#else
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000778 char buf[1024]; /* XXX Should use MAXPATHLEN */
Guido van Rossumef0a00e1992-01-27 16:51:30 +0000779 char *path;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000780 int n;
781 if (!getstrarg(args, &path))
782 return NULL;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000783 BGN_SAVE
Guido van Rossum50e61dc1992-03-27 17:22:31 +0000784 n = readlink(path, buf, (int) sizeof buf);
Guido van Rossumff4949e1992-08-05 19:58:53 +0000785 END_SAVE
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000786 if (n < 0)
787 return posix_error();
788 return newsizedstringobject(buf, n);
Guido van Rossumc39de5f1992-02-05 11:15:54 +0000789#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000790}
791
792static object *
793posix_symlink(self, args)
794 object *self;
795 object *args;
796{
Guido van Rossumc39de5f1992-02-05 11:15:54 +0000797#ifdef NO_LSTAT
798 err_setstr(PosixError, "symlink not implemented on this system");
799 return NULL;
800#else
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000801 extern int symlink PROTO((const char *, const char *));
802 return posix_2str(args, symlink);
Guido van Rossumc39de5f1992-02-05 11:15:54 +0000803#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000804}
805
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000806
Guido van Rossum22db57e1992-04-05 14:25:30 +0000807#ifdef DO_TIMES
808
809static object *
810posix_times(self, args)
811 object *self;
812 object *args;
813{
814 struct tms t;
815 clock_t c;
816 object *tuple;
817 if (!getnoarg(args))
818 return NULL;
819 errno = 0;
820 c = times(&t);
821 if (c == (clock_t) -1) {
Guido van Rossum7066dd71992-09-17 17:54:56 +0000822 err_errno(PosixError);
Guido van Rossum22db57e1992-04-05 14:25:30 +0000823 return NULL;
824 }
825 tuple = newtupleobject(4);
826 if (tuple == NULL)
827 return NULL;
828 settupleitem(tuple, 0, newfloatobject((double)t.tms_utime / HZ));
829 settupleitem(tuple, 1, newfloatobject((double)t.tms_stime / HZ));
830 settupleitem(tuple, 2, newfloatobject((double)t.tms_cutime / HZ));
831 settupleitem(tuple, 3, newfloatobject((double)t.tms_cstime / HZ));
832 if (err_occurred()) {
833 DECREF(tuple);
834 return NULL;
835 }
836 return tuple;
837}
838
Guido van Rossumc2670a01992-09-13 20:07:29 +0000839#endif /* DO_TIMES */
840
841#ifdef DO_PG
842
843static object *
844posix_setsid(self, args)
845 object *self;
846 object *args;
847{
848 if (!getnoarg(args))
849 return NULL;
Guido van Rossum7066dd71992-09-17 17:54:56 +0000850 if (setsid() < 0) {
Guido van Rossumc2670a01992-09-13 20:07:29 +0000851 err_errno(PosixError);
Guido van Rossum7066dd71992-09-17 17:54:56 +0000852 return NULL;
853 }
Guido van Rossumc2670a01992-09-13 20:07:29 +0000854 INCREF(None);
855 return None;
856}
857
858static object *
859posix_setpgid(self, args)
860 object *self;
861 object *args;
862{
863 int pid, pgrp;
864 if (!getargs(args, "(ii)", &pid, &pgrp))
865 return NULL;
Guido van Rossum7066dd71992-09-17 17:54:56 +0000866 if (setpgid(pid, pgrp) < 0) {
Guido van Rossumc2670a01992-09-13 20:07:29 +0000867 err_errno(PosixError);
Guido van Rossum7066dd71992-09-17 17:54:56 +0000868 return NULL;
869 }
Guido van Rossumc2670a01992-09-13 20:07:29 +0000870 INCREF(None);
871 return None;
872}
873
Guido van Rossum7066dd71992-09-17 17:54:56 +0000874static object *
875posix_tcgetpgrp(self, args)
876 object *self;
877 object *args;
878{
879 int fd, pgid;
880 if (!getargs(args, "i", &fd))
881 return NULL;
882 pgid = tcgetpgrp(fd);
883 if (pgid < 0) {
884 err_errno(PosixError);
885 return NULL;
886 }
887 return newintobject((long)pgid);
888}
889
890static object *
891posix_tcsetpgrp(self, args)
892 object *self;
893 object *args;
894{
895 int fd, pgid;
896 if (!getargs(args, "(ii)", &fd, &pgid))
897 return NULL;
898 if (tcsetpgrp(fd, pgid) < 0) {
899 err_errno(PosixError);
900 return NULL;
901 }
902 INCREF(None);
903 return None;
904}
905
Guido van Rossumc2670a01992-09-13 20:07:29 +0000906#endif /* DO_PG */
Guido van Rossum22db57e1992-04-05 14:25:30 +0000907
908
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000909static struct methodlist posix_methods[] = {
910 {"chdir", posix_chdir},
911 {"chmod", posix_chmod},
912 {"getcwd", posix_getcwd},
Guido van Rossum0ee42cd1991-04-08 21:01:03 +0000913#ifndef MSDOS
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000914 {"link", posix_link},
Guido van Rossum0ee42cd1991-04-08 21:01:03 +0000915#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000916 {"listdir", posix_listdir},
Guido van Rossumc39de5f1992-02-05 11:15:54 +0000917 {"lstat", posix_lstat},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000918 {"mkdir", posix_mkdir},
Guido van Rossumc39de5f1992-02-05 11:15:54 +0000919 {"readlink", posix_readlink},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000920 {"rename", posix_rename},
921 {"rmdir", posix_rmdir},
922 {"stat", posix_stat},
Guido van Rossumc39de5f1992-02-05 11:15:54 +0000923 {"symlink", posix_symlink},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000924 {"system", posix_system},
Guido van Rossum0ee42cd1991-04-08 21:01:03 +0000925#ifndef MSDOS
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000926 {"umask", posix_umask},
Guido van Rossum0ee42cd1991-04-08 21:01:03 +0000927#endif
Guido van Rossumc39de5f1992-02-05 11:15:54 +0000928#ifndef NO_UNAME
929 {"uname", posix_uname},
930#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000931 {"unlink", posix_unlink},
Guido van Rossum1ff6cb41991-04-08 20:59:13 +0000932 {"utime", posix_utime},
Guido van Rossum22db57e1992-04-05 14:25:30 +0000933#ifdef DO_TIMES
934 {"times", posix_times},
935#endif
Guido van Rossumc39de5f1992-02-05 11:15:54 +0000936
Guido van Rossum85e3b011991-06-03 12:42:10 +0000937#ifndef MSDOS
938 {"_exit", posix__exit},
939 {"exec", posix_exec},
940 {"fork", posix_fork},
Guido van Rossum46003ff1992-05-15 11:05:24 +0000941 {"getegid", posix_getegid},
942 {"geteuid", posix_geteuid},
943 {"getgid", posix_getgid},
Guido van Rossum85e3b011991-06-03 12:42:10 +0000944 {"getpid", posix_getpid},
Guido van Rossum04814471991-06-04 20:23:49 +0000945 {"getpgrp", posix_getpgrp},
Guido van Rossum85e3b011991-06-03 12:42:10 +0000946 {"getppid", posix_getppid},
Guido van Rossum46003ff1992-05-15 11:05:24 +0000947 {"getuid", posix_getuid},
Guido van Rossum85e3b011991-06-03 12:42:10 +0000948 {"kill", posix_kill},
Guido van Rossum3b066191991-06-04 19:40:25 +0000949 {"popen", posix_popen},
Guido van Rossumc2670a01992-09-13 20:07:29 +0000950 {"setpgrp", posix_setpgrp},
Guido van Rossum85e3b011991-06-03 12:42:10 +0000951 {"wait", posix_wait},
Guido van Rossum21803b81992-08-09 12:55:27 +0000952 {"waitpid", posix_waitpid},
Guido van Rossum85e3b011991-06-03 12:42:10 +0000953#endif
Guido van Rossumc39de5f1992-02-05 11:15:54 +0000954
Guido van Rossumc2670a01992-09-13 20:07:29 +0000955#ifdef DO_PG
956 {"setsid", posix_setsid},
957 {"setpgid", posix_setpgid},
Guido van Rossum7066dd71992-09-17 17:54:56 +0000958 {"tcgetpgrp", posix_tcgetpgrp},
959 {"tcsetpgrp", posix_tcsetpgrp},
Guido van Rossumc2670a01992-09-13 20:07:29 +0000960#endif
961
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000962 {NULL, NULL} /* Sentinel */
963};
964
965
966void
967initposix()
968{
969 object *m, *d, *v;
970
971 m = initmodule("posix", posix_methods);
972 d = getmoduledict(m);
973
974 /* Initialize posix.environ dictionary */
975 v = convertenviron();
976 if (v == NULL || dictinsert(d, "environ", v) != 0)
977 fatal("can't define posix.environ");
978 DECREF(v);
979
980 /* Initialize posix.error exception */
981 PosixError = newstringobject("posix.error");
982 if (PosixError == NULL || dictinsert(d, "error", PosixError) != 0)
983 fatal("can't define posix.error");
984}
Guido van Rossum0ee42cd1991-04-08 21:01:03 +0000985
Guido van Rossum3b066191991-06-04 19:40:25 +0000986
987/* Function used elsewhere to get a file's modification time */
988
989long
990getmtime(path)
991 char *path;
992{
993 struct stat st;
994 if (stat(path, &st) != 0)
995 return -1;
996 else
997 return st.st_mtime;
998}
999
1000
Guido van Rossum0ee42cd1991-04-08 21:01:03 +00001001#ifdef MSDOS
1002
1003/* A small "compatibility library" for TurboC under MS-DOS */
1004
1005#include <sir.h>
1006#include <io.h>
1007#include <dos.h>
1008#include <fcntl.h>
1009
1010int
1011chmod(path, mode)
1012 char *path;
1013 int mode;
1014{
1015 return _chmod(path, 1, mode);
1016}
1017
1018int
1019utime(path, times)
1020 char *path;
1021 time_t times[2];
1022{
1023 struct date dt;
1024 struct time tm;
1025 struct ftime dft;
1026 int fh;
1027 unixtodos(tv[0].tv_sec,&dt,&tm);
1028 dft.ft_tsec = tm.ti_sec; dft.ft_min = tm.ti_min;
1029 dft.ft_hour = tm.ti_hour; dft.ft_day = dt.da_day;
1030 dft.ft_month = dt.da_mon;
1031 dft.ft_year = (dt.da_year - 1980); /* this is for TC library */
1032
Guido van Rossumef0a00e1992-01-27 16:51:30 +00001033 if ((fh = open(path,O_RDWR)) < 0)
Guido van Rossum0ee42cd1991-04-08 21:01:03 +00001034 return posix_error(); /* can't open file to set time */
1035 if (setftime(fh,&dft) < 0)
1036 {
1037 close(fh);
1038 return posix_error();
1039 }
1040 close(fh); /* close the temp handle */
1041}
1042
1043#endif /* MSDOS */