blob: 992147fc74c8ba955e4e60d6430bd9d53e648b83 [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 Rossum85a5fbb1990-10-14 12:07:46 +000076
Guido van Rossum7f77e2d1990-10-30 13:34:38 +000077extern char *strerror PROTO((int));
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000078
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000079
80/* Return a dictionary corresponding to the POSIX environment table */
81
82extern char **environ;
83
84static object *
85convertenviron()
86{
87 object *d;
88 char **e;
89 d = newdictobject();
90 if (d == NULL)
91 return NULL;
92 if (environ == NULL)
93 return d;
94 /* XXX This part ignores errors */
95 for (e = environ; *e != NULL; e++) {
96 object *v;
97 char *p = strchr(*e, '=');
98 if (p == NULL)
99 continue;
100 v = newstringobject(p+1);
101 if (v == NULL)
102 continue;
103 *p = '\0';
104 (void) dictinsert(d, *e, v);
105 *p = '=';
106 DECREF(v);
107 }
108 return d;
109}
110
111
112static object *PosixError; /* Exception posix.error */
113
114/* Set a POSIX-specific error from errno, and return NULL */
115
Guido van Rossum9a1581c1990-10-21 13:12:47 +0000116static object *
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000117posix_error()
118{
Guido van Rossume8f305a1990-10-14 20:04:28 +0000119 return err_errno(PosixError);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000120}
121
122
123/* POSIX generic methods */
124
125static object *
126posix_1str(args, func)
127 object *args;
128 int (*func) FPROTO((const char *));
129{
Guido van Rossumef0a00e1992-01-27 16:51:30 +0000130 char *path1;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000131 if (!getstrarg(args, &path1))
132 return NULL;
Guido van Rossumef0a00e1992-01-27 16:51:30 +0000133 if ((*func)(path1) < 0)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000134 return posix_error();
135 INCREF(None);
136 return None;
137}
138
139static object *
140posix_2str(args, func)
141 object *args;
142 int (*func) FPROTO((const char *, const char *));
143{
Guido van Rossumef0a00e1992-01-27 16:51:30 +0000144 char *path1, *path2;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000145 if (!getstrstrarg(args, &path1, &path2))
146 return NULL;
Guido van Rossumef0a00e1992-01-27 16:51:30 +0000147 if ((*func)(path1, path2) < 0)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000148 return posix_error();
149 INCREF(None);
150 return None;
151}
152
153static object *
154posix_strint(args, func)
155 object *args;
156 int (*func) FPROTO((const char *, int));
157{
Guido van Rossumef0a00e1992-01-27 16:51:30 +0000158 char *path;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000159 int i;
Guido van Rossumef0a00e1992-01-27 16:51:30 +0000160 if (!getstrintarg(args, &path, &i))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000161 return NULL;
Guido van Rossumef0a00e1992-01-27 16:51:30 +0000162 if ((*func)(path, i) < 0)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000163 return posix_error();
164 INCREF(None);
165 return None;
166}
167
168static object *
169posix_do_stat(self, args, statfunc)
170 object *self;
171 object *args;
172 int (*statfunc) FPROTO((const char *, struct stat *));
173{
174 struct stat st;
Guido van Rossumef0a00e1992-01-27 16:51:30 +0000175 char *path;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000176 object *v;
177 if (!getstrarg(args, &path))
178 return NULL;
Guido van Rossumef0a00e1992-01-27 16:51:30 +0000179 if ((*statfunc)(path, &st) != 0)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000180 return posix_error();
181 v = newtupleobject(10);
182 if (v == NULL)
183 return NULL;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000184#define SET(i, st_member) settupleitem(v, i, newintobject((long)st.st_member))
185 SET(0, st_mode);
186 SET(1, st_ino);
187 SET(2, st_dev);
188 SET(3, st_nlink);
189 SET(4, st_uid);
190 SET(5, st_gid);
191 SET(6, st_size);
192 SET(7, st_atime);
193 SET(8, st_mtime);
194 SET(9, st_ctime);
195#undef SET
Guido van Rossum3f5da241990-12-20 15:06:42 +0000196 if (err_occurred()) {
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000197 DECREF(v);
Guido van Rossum3f5da241990-12-20 15:06:42 +0000198 return NULL;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000199 }
200 return v;
201}
202
203
204/* POSIX methods */
205
206static object *
207posix_chdir(self, args)
208 object *self;
209 object *args;
210{
211 extern int chdir PROTO((const char *));
212 return posix_1str(args, chdir);
213}
214
215static object *
216posix_chmod(self, args)
217 object *self;
218 object *args;
219{
220 extern int chmod PROTO((const char *, mode_t));
221 return posix_strint(args, chmod);
222}
223
224static object *
225posix_getcwd(self, args)
226 object *self;
227 object *args;
228{
229 char buf[1026];
230 extern char *getcwd PROTO((char *, int));
231 if (!getnoarg(args))
232 return NULL;
233 if (getcwd(buf, sizeof buf) == NULL)
234 return posix_error();
235 return newstringobject(buf);
236}
237
Guido van Rossum0ee42cd1991-04-08 21:01:03 +0000238#ifndef MSDOS
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000239static object *
240posix_link(self, args)
241 object *self;
242 object *args;
243{
244 extern int link PROTO((const char *, const char *));
245 return posix_2str(args, link);
246}
Guido van Rossum0ee42cd1991-04-08 21:01:03 +0000247#endif /* !MSDOS */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000248
249static object *
250posix_listdir(self, args)
251 object *self;
252 object *args;
253{
Guido van Rossumef0a00e1992-01-27 16:51:30 +0000254 char *name;
255 object *d, *v;
Guido van Rossum0ee42cd1991-04-08 21:01:03 +0000256
257#ifdef MSDOS
258 struct ffblk ep;
259 int rv;
260 if (!getstrarg(args, &name))
261 return NULL;
262
Guido van Rossumef0a00e1992-01-27 16:51:30 +0000263 if (findfirst(name, &ep, 0) == -1)
Guido van Rossum0ee42cd1991-04-08 21:01:03 +0000264 return posix_error();
265 if ((d = newlistobject(0)) == NULL)
266 return NULL;
267 do {
268 v = newstringobject(ep.ff_name);
269 if (v == NULL) {
270 DECREF(d);
271 d = NULL;
272 break;
273 }
274 if (addlistitem(d, v) != 0) {
275 DECREF(v);
276 DECREF(d);
277 d = NULL;
278 break;
279 }
280 DECREF(v);
281 } while ((rv = findnext(&ep)) == 0);
282#else /* !MSDOS */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000283 DIR *dirp;
284 struct direct *ep;
285 if (!getstrarg(args, &name))
286 return NULL;
Guido van Rossumef0a00e1992-01-27 16:51:30 +0000287 if ((dirp = opendir(name)) == NULL)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000288 return posix_error();
289 if ((d = newlistobject(0)) == NULL) {
290 closedir(dirp);
291 return NULL;
292 }
293 while ((ep = readdir(dirp)) != NULL) {
294 v = newstringobject(ep->d_name);
295 if (v == NULL) {
296 DECREF(d);
297 d = NULL;
298 break;
299 }
300 if (addlistitem(d, v) != 0) {
301 DECREF(v);
302 DECREF(d);
303 d = NULL;
304 break;
305 }
306 DECREF(v);
307 }
308 closedir(dirp);
Guido van Rossum0ee42cd1991-04-08 21:01:03 +0000309#endif /* !MSDOS */
310
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000311 return d;
312}
313
314static object *
315posix_mkdir(self, args)
316 object *self;
317 object *args;
318{
319 extern int mkdir PROTO((const char *, mode_t));
320 return posix_strint(args, mkdir);
321}
322
Guido van Rossum1ff6cb41991-04-08 20:59:13 +0000323#ifdef i386
324int
325rename(from, to)
326 char *from;
327 char *to;
328{
329 int status;
330 /* XXX Shouldn't this unlink the destination first? */
331 status = link(from, to);
332 if (status != 0)
333 return status;
334 return unlink(from);
335}
Guido van Rossum0ee42cd1991-04-08 21:01:03 +0000336#endif /* i386 */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +0000337
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000338static object *
339posix_rename(self, args)
340 object *self;
341 object *args;
342{
343 extern int rename PROTO((const char *, const char *));
344 return posix_2str(args, rename);
345}
346
347static object *
348posix_rmdir(self, args)
349 object *self;
350 object *args;
351{
352 extern int rmdir PROTO((const char *));
353 return posix_1str(args, rmdir);
354}
355
356static object *
357posix_stat(self, args)
358 object *self;
359 object *args;
360{
361 extern int stat PROTO((const char *, struct stat *));
362 return posix_do_stat(self, args, stat);
363}
364
365static object *
366posix_system(self, args)
367 object *self;
368 object *args;
369{
Guido van Rossumef0a00e1992-01-27 16:51:30 +0000370 char *command;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000371 int sts;
372 if (!getstrarg(args, &command))
373 return NULL;
Guido van Rossumef0a00e1992-01-27 16:51:30 +0000374 sts = system(command);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000375 return newintobject((long)sts);
376}
377
Guido van Rossum0ee42cd1991-04-08 21:01:03 +0000378#ifndef MSDOS
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000379static object *
380posix_umask(self, args)
381 object *self;
382 object *args;
383{
384 int i;
385 if (!getintarg(args, &i))
386 return NULL;
387 i = umask(i);
388 if (i < 0)
389 return posix_error();
390 return newintobject((long)i);
391}
Guido van Rossum0ee42cd1991-04-08 21:01:03 +0000392#endif /* !MSDOS */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000393
394static object *
395posix_unlink(self, args)
396 object *self;
397 object *args;
398{
399 extern int unlink PROTO((const char *));
400 return posix_1str(args, unlink);
401}
402
Guido van Rossumc39de5f1992-02-05 11:15:54 +0000403#ifndef NO_UNAME
404#include <sys/utsname.h>
405
406static object *
407posix_uname(self, args)
408 object *self;
409 object *args;
410{
411 extern int uname PROTO((struct utsname *));
412 struct utsname u;
413 object *v;
Guido van Rossum50e61dc1992-03-27 17:22:31 +0000414 if (!getnoarg(args))
415 return NULL;
Guido van Rossumc39de5f1992-02-05 11:15:54 +0000416 if (uname(&u) < 0)
417 return posix_error();
418 v = newtupleobject(5);
419 if (v == NULL)
420 return NULL;
421#define SET(i, member) settupleitem(v, i, newstringobject(u.member))
422 SET(0, sysname);
423 SET(1, nodename);
424 SET(2, release);
425 SET(3, version);
426 SET(4, machine);
427#undef SET
428 if (err_occurred()) {
429 DECREF(v);
430 return NULL;
431 }
432 return v;
433}
434#endif /* NO_UNAME */
435
Guido van Rossum1ff6cb41991-04-08 20:59:13 +0000436#ifdef UTIME_STRUCT
437#include <utime.h>
438#endif
439
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000440static object *
Guido van Rossum1ff6cb41991-04-08 20:59:13 +0000441posix_utime(self, args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000442 object *self;
443 object *args;
444{
Guido van Rossumef0a00e1992-01-27 16:51:30 +0000445 char *path;
Guido van Rossum1ff6cb41991-04-08 20:59:13 +0000446
447#ifdef UTIME_STRUCT
448 struct utimbuf buf;
449#define ATIME buf.actime
450#define MTIME buf.modtime
451#define UTIME_ARG &buf
452
453#else
454 time_t buf[2];
455#define ATIME buf[0]
456#define MTIME buf[1]
457#define UTIME_ARG buf
458#endif
459
Guido van Rossumef0a00e1992-01-27 16:51:30 +0000460 if (!getargs(args, "(s(ll))", &path, &ATIME, &MTIME))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000461 return NULL;
Guido van Rossumef0a00e1992-01-27 16:51:30 +0000462 if (utime(path, UTIME_ARG) < 0)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000463 return posix_error();
464 INCREF(None);
465 return None;
Guido van Rossum1ff6cb41991-04-08 20:59:13 +0000466#undef UTIME_ARG
467#undef ATIME
468#undef MTIME
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000469}
470
Guido van Rossum85e3b011991-06-03 12:42:10 +0000471
472#ifndef MSDOS
473
Guido van Rossum3b066191991-06-04 19:40:25 +0000474/* Process operations */
Guido van Rossum85e3b011991-06-03 12:42:10 +0000475
476static object *
477posix__exit(self, args)
478 object *self;
479 object *args;
480{
481 int sts;
482 if (!getintarg(args, &sts))
483 return NULL;
484 _exit(sts);
485 /* NOTREACHED */
486}
487
488/* XXX To do: exece, execp */
489
490static object *
491posix_exec(self, args)
492 object *self;
493 object *args;
494{
Guido van Rossumef0a00e1992-01-27 16:51:30 +0000495 char *path;
496 object *argv;
Guido van Rossum85e3b011991-06-03 12:42:10 +0000497 char **argvlist;
498 int i, argc;
499 object *(*getitem) PROTO((object *, int));
500
501 /* exec has two arguments: (path, argv), where
502 argv is a list or tuple of strings. */
503
Guido van Rossumef0a00e1992-01-27 16:51:30 +0000504 if (!getargs(args, "(sO)", &path, &argv))
Guido van Rossum85e3b011991-06-03 12:42:10 +0000505 return NULL;
Guido van Rossum85e3b011991-06-03 12:42:10 +0000506 if (is_listobject(argv)) {
507 argc = getlistsize(argv);
508 getitem = getlistitem;
509 }
510 else if (is_tupleobject(argv)) {
511 argc = gettuplesize(argv);
512 getitem = gettupleitem;
513 }
Guido van Rossumef0a00e1992-01-27 16:51:30 +0000514 else {
515 badarg:
516 err_badarg();
517 return NULL;
518 }
Guido van Rossum85e3b011991-06-03 12:42:10 +0000519
520 argvlist = NEW(char *, argc+1);
521 if (argvlist == NULL)
522 return NULL;
523 for (i = 0; i < argc; i++) {
Guido van Rossumef0a00e1992-01-27 16:51:30 +0000524 if (!getstrarg((*getitem)(argv, i), &argvlist[i])) {
Guido van Rossum85e3b011991-06-03 12:42:10 +0000525 DEL(argvlist);
526 goto badarg;
527 }
Guido van Rossum85e3b011991-06-03 12:42:10 +0000528 }
529 argvlist[argc] = NULL;
530
Guido van Rossumef0a00e1992-01-27 16:51:30 +0000531 execv(path, argvlist);
Guido van Rossum85e3b011991-06-03 12:42:10 +0000532
533 /* If we get here it's definitely an error */
534
535 DEL(argvlist);
536 return posix_error();
537}
538
539static object *
540posix_fork(self, args)
541 object *self;
542 object *args;
543{
544 int pid;
Guido van Rossum50e61dc1992-03-27 17:22:31 +0000545 if (!getnoarg(args))
546 return NULL;
Guido van Rossum85e3b011991-06-03 12:42:10 +0000547 pid = fork();
548 if (pid == -1)
549 return posix_error();
550 return newintobject((long)pid);
551}
552
553static object *
554posix_getpid(self, args)
555 object *self;
556 object *args;
557{
Guido van Rossum04814471991-06-04 20:23:49 +0000558 if (!getnoarg(args))
Guido van Rossum85e3b011991-06-03 12:42:10 +0000559 return NULL;
560 return newintobject((long)getpid());
561}
562
563static object *
Guido van Rossum04814471991-06-04 20:23:49 +0000564posix_getpgrp(self, args)
565 object *self;
566 object *args;
567{
568 if (!getnoarg(args))
569 return NULL;
Guido van Rossum50e61dc1992-03-27 17:22:31 +0000570#ifdef SYSV
571 return newintobject((long)getpgrp());
572#else
Guido van Rossum971443b1991-06-07 13:59:29 +0000573 return newintobject((long)getpgrp(0));
Guido van Rossum50e61dc1992-03-27 17:22:31 +0000574#endif
Guido van Rossum04814471991-06-04 20:23:49 +0000575}
576
577static object *
Guido van Rossum85e3b011991-06-03 12:42:10 +0000578posix_getppid(self, args)
579 object *self;
580 object *args;
581{
Guido van Rossum04814471991-06-04 20:23:49 +0000582 if (!getnoarg(args))
Guido van Rossum85e3b011991-06-03 12:42:10 +0000583 return NULL;
584 return newintobject((long)getppid());
585}
586
587static object *
588posix_kill(self, args)
589 object *self;
590 object *args;
591{
592 int pid, sig;
593 if (!getintintarg(args, &pid, &sig))
594 return NULL;
595 if (kill(pid, sig) == -1)
596 return posix_error();
597 INCREF(None);
598 return None;
599}
600
601static object *
Guido van Rossum3b066191991-06-04 19:40:25 +0000602posix_popen(self, args)
603 object *self;
604 object *args;
605{
606 extern int pclose PROTO((FILE *));
Guido van Rossumef0a00e1992-01-27 16:51:30 +0000607 char *name, *mode;
Guido van Rossum3b066191991-06-04 19:40:25 +0000608 FILE *fp;
Guido van Rossumef0a00e1992-01-27 16:51:30 +0000609 if (!getargs(args, "(ss)", &name, &mode))
Guido van Rossum3b066191991-06-04 19:40:25 +0000610 return NULL;
Guido van Rossumef0a00e1992-01-27 16:51:30 +0000611 fp = popen(name, mode);
Guido van Rossum3b066191991-06-04 19:40:25 +0000612 if (fp == NULL)
613 return posix_error();
Guido van Rossume0d452d1991-07-27 21:41:01 +0000614 /* From now on, ignore SIGPIPE and let the error checking
615 do the work. */
616 (void) signal(SIGPIPE, SIG_IGN);
Guido van Rossumef0a00e1992-01-27 16:51:30 +0000617 return newopenfileobject(fp, name, mode, pclose);
Guido van Rossum3b066191991-06-04 19:40:25 +0000618}
619
620static object *
Guido van Rossum85e3b011991-06-03 12:42:10 +0000621posix_wait(self, args) /* Also waitpid() */
622 object *self;
623 object *args;
624{
625 object *v;
626 int pid, sts;
627 if (args == NULL)
628 pid = wait(&sts);
629 else {
630#ifdef NO_WAITPID
Guido van Rossumc39de5f1992-02-05 11:15:54 +0000631 err_setstr(PosixError,
Guido van Rossum85e3b011991-06-03 12:42:10 +0000632 "posix.wait(pid, options) not supported on this system");
633#else
634 int options;
635 if (!getintintarg(args, &pid, &options))
636 return NULL;
637 pid = waitpid(pid, &sts, options);
638#endif
639 }
640 if (pid == -1)
641 return posix_error();
642 v = newtupleobject(2);
643 if (v != NULL) {
644 settupleitem(v, 0, newintobject((long)pid));
645 settupleitem(v, 1, newintobject((long)sts));
646 if (err_occurred()) {
647 DECREF(v);
648 v = NULL;
649 }
650 }
651 return v;
652}
653
654#endif /* MSDOS */
655
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000656static object *
657posix_lstat(self, args)
658 object *self;
659 object *args;
660{
Guido van Rossumc39de5f1992-02-05 11:15:54 +0000661#ifdef NO_LSTAT
662#define lstat stat
663#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000664 extern int lstat PROTO((const char *, struct stat *));
665 return posix_do_stat(self, args, lstat);
666}
667
668static object *
669posix_readlink(self, args)
670 object *self;
671 object *args;
672{
Guido van Rossumc39de5f1992-02-05 11:15:54 +0000673#ifdef NO_LSTAT
674 err_setstr(PosixError, "readlink not implemented on this system");
675 return NULL;
676#else
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000677 char buf[1024]; /* XXX Should use MAXPATHLEN */
Guido van Rossumef0a00e1992-01-27 16:51:30 +0000678 char *path;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000679 int n;
680 if (!getstrarg(args, &path))
681 return NULL;
Guido van Rossum50e61dc1992-03-27 17:22:31 +0000682 n = readlink(path, buf, (int) sizeof buf);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000683 if (n < 0)
684 return posix_error();
685 return newsizedstringobject(buf, n);
Guido van Rossumc39de5f1992-02-05 11:15:54 +0000686#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000687}
688
689static object *
690posix_symlink(self, args)
691 object *self;
692 object *args;
693{
Guido van Rossumc39de5f1992-02-05 11:15:54 +0000694#ifdef NO_LSTAT
695 err_setstr(PosixError, "symlink not implemented on this system");
696 return NULL;
697#else
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000698 extern int symlink PROTO((const char *, const char *));
699 return posix_2str(args, symlink);
Guido van Rossumc39de5f1992-02-05 11:15:54 +0000700#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000701}
702
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000703
Guido van Rossum22db57e1992-04-05 14:25:30 +0000704#ifdef DO_TIMES
705
706static object *
707posix_times(self, args)
708 object *self;
709 object *args;
710{
711 struct tms t;
712 clock_t c;
713 object *tuple;
714 if (!getnoarg(args))
715 return NULL;
716 errno = 0;
717 c = times(&t);
718 if (c == (clock_t) -1) {
719 err_errno(IOError);
720 return NULL;
721 }
722 tuple = newtupleobject(4);
723 if (tuple == NULL)
724 return NULL;
725 settupleitem(tuple, 0, newfloatobject((double)t.tms_utime / HZ));
726 settupleitem(tuple, 1, newfloatobject((double)t.tms_stime / HZ));
727 settupleitem(tuple, 2, newfloatobject((double)t.tms_cutime / HZ));
728 settupleitem(tuple, 3, newfloatobject((double)t.tms_cstime / HZ));
729 if (err_occurred()) {
730 DECREF(tuple);
731 return NULL;
732 }
733 return tuple;
734}
735
736#endif
737
738
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000739static struct methodlist posix_methods[] = {
740 {"chdir", posix_chdir},
741 {"chmod", posix_chmod},
742 {"getcwd", posix_getcwd},
Guido van Rossum0ee42cd1991-04-08 21:01:03 +0000743#ifndef MSDOS
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000744 {"link", posix_link},
Guido van Rossum0ee42cd1991-04-08 21:01:03 +0000745#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000746 {"listdir", posix_listdir},
Guido van Rossumc39de5f1992-02-05 11:15:54 +0000747 {"lstat", posix_lstat},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000748 {"mkdir", posix_mkdir},
Guido van Rossumc39de5f1992-02-05 11:15:54 +0000749 {"readlink", posix_readlink},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000750 {"rename", posix_rename},
751 {"rmdir", posix_rmdir},
752 {"stat", posix_stat},
Guido van Rossumc39de5f1992-02-05 11:15:54 +0000753 {"symlink", posix_symlink},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000754 {"system", posix_system},
Guido van Rossum0ee42cd1991-04-08 21:01:03 +0000755#ifndef MSDOS
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000756 {"umask", posix_umask},
Guido van Rossum0ee42cd1991-04-08 21:01:03 +0000757#endif
Guido van Rossumc39de5f1992-02-05 11:15:54 +0000758#ifndef NO_UNAME
759 {"uname", posix_uname},
760#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000761 {"unlink", posix_unlink},
Guido van Rossum1ff6cb41991-04-08 20:59:13 +0000762 {"utime", posix_utime},
Guido van Rossum22db57e1992-04-05 14:25:30 +0000763#ifdef DO_TIMES
764 {"times", posix_times},
765#endif
Guido van Rossumc39de5f1992-02-05 11:15:54 +0000766
Guido van Rossum85e3b011991-06-03 12:42:10 +0000767#ifndef MSDOS
768 {"_exit", posix__exit},
769 {"exec", posix_exec},
770 {"fork", posix_fork},
771 {"getpid", posix_getpid},
Guido van Rossum04814471991-06-04 20:23:49 +0000772 {"getpgrp", posix_getpgrp},
Guido van Rossum85e3b011991-06-03 12:42:10 +0000773 {"getppid", posix_getppid},
774 {"kill", posix_kill},
Guido van Rossum3b066191991-06-04 19:40:25 +0000775 {"popen", posix_popen},
Guido van Rossum85e3b011991-06-03 12:42:10 +0000776 {"wait", posix_wait},
777#endif
Guido van Rossumc39de5f1992-02-05 11:15:54 +0000778
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000779 {NULL, NULL} /* Sentinel */
780};
781
782
783void
784initposix()
785{
786 object *m, *d, *v;
787
788 m = initmodule("posix", posix_methods);
789 d = getmoduledict(m);
790
791 /* Initialize posix.environ dictionary */
792 v = convertenviron();
793 if (v == NULL || dictinsert(d, "environ", v) != 0)
794 fatal("can't define posix.environ");
795 DECREF(v);
796
797 /* Initialize posix.error exception */
798 PosixError = newstringobject("posix.error");
799 if (PosixError == NULL || dictinsert(d, "error", PosixError) != 0)
800 fatal("can't define posix.error");
801}
Guido van Rossum0ee42cd1991-04-08 21:01:03 +0000802
Guido van Rossum3b066191991-06-04 19:40:25 +0000803
804/* Function used elsewhere to get a file's modification time */
805
806long
807getmtime(path)
808 char *path;
809{
810 struct stat st;
811 if (stat(path, &st) != 0)
812 return -1;
813 else
814 return st.st_mtime;
815}
816
817
Guido van Rossum0ee42cd1991-04-08 21:01:03 +0000818#ifdef MSDOS
819
820/* A small "compatibility library" for TurboC under MS-DOS */
821
822#include <sir.h>
823#include <io.h>
824#include <dos.h>
825#include <fcntl.h>
826
827int
828chmod(path, mode)
829 char *path;
830 int mode;
831{
832 return _chmod(path, 1, mode);
833}
834
835int
836utime(path, times)
837 char *path;
838 time_t times[2];
839{
840 struct date dt;
841 struct time tm;
842 struct ftime dft;
843 int fh;
844 unixtodos(tv[0].tv_sec,&dt,&tm);
845 dft.ft_tsec = tm.ti_sec; dft.ft_min = tm.ti_min;
846 dft.ft_hour = tm.ti_hour; dft.ft_day = dt.da_day;
847 dft.ft_month = dt.da_mon;
848 dft.ft_year = (dt.da_year - 1980); /* this is for TC library */
849
Guido van Rossumef0a00e1992-01-27 16:51:30 +0000850 if ((fh = open(path,O_RDWR)) < 0)
Guido van Rossum0ee42cd1991-04-08 21:01:03 +0000851 return posix_error(); /* can't open file to set time */
852 if (setftime(fh,&dft) < 0)
853 {
854 close(fh);
855 return posix_error();
856 }
857 close(fh); /* close the temp handle */
858}
859
860#endif /* MSDOS */