blob: 0bc0f91b0488d764b7d06e0ad7ea440601c69073 [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) {
822 err_errno(IOError);
823 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;
850 if (setsid() < 0)
851 err_errno(PosixError);
852 INCREF(None);
853 return None;
854}
855
856static object *
857posix_setpgid(self, args)
858 object *self;
859 object *args;
860{
861 int pid, pgrp;
862 if (!getargs(args, "(ii)", &pid, &pgrp))
863 return NULL;
864 if (setpgid(pid, pgrp) < 0)
865 err_errno(PosixError);
866 INCREF(None);
867 return None;
868}
869
870#endif /* DO_PG */
Guido van Rossum22db57e1992-04-05 14:25:30 +0000871
872
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000873static struct methodlist posix_methods[] = {
874 {"chdir", posix_chdir},
875 {"chmod", posix_chmod},
876 {"getcwd", posix_getcwd},
Guido van Rossum0ee42cd1991-04-08 21:01:03 +0000877#ifndef MSDOS
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000878 {"link", posix_link},
Guido van Rossum0ee42cd1991-04-08 21:01:03 +0000879#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000880 {"listdir", posix_listdir},
Guido van Rossumc39de5f1992-02-05 11:15:54 +0000881 {"lstat", posix_lstat},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000882 {"mkdir", posix_mkdir},
Guido van Rossumc39de5f1992-02-05 11:15:54 +0000883 {"readlink", posix_readlink},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000884 {"rename", posix_rename},
885 {"rmdir", posix_rmdir},
886 {"stat", posix_stat},
Guido van Rossumc39de5f1992-02-05 11:15:54 +0000887 {"symlink", posix_symlink},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000888 {"system", posix_system},
Guido van Rossum0ee42cd1991-04-08 21:01:03 +0000889#ifndef MSDOS
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000890 {"umask", posix_umask},
Guido van Rossum0ee42cd1991-04-08 21:01:03 +0000891#endif
Guido van Rossumc39de5f1992-02-05 11:15:54 +0000892#ifndef NO_UNAME
893 {"uname", posix_uname},
894#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000895 {"unlink", posix_unlink},
Guido van Rossum1ff6cb41991-04-08 20:59:13 +0000896 {"utime", posix_utime},
Guido van Rossum22db57e1992-04-05 14:25:30 +0000897#ifdef DO_TIMES
898 {"times", posix_times},
899#endif
Guido van Rossumc39de5f1992-02-05 11:15:54 +0000900
Guido van Rossum85e3b011991-06-03 12:42:10 +0000901#ifndef MSDOS
902 {"_exit", posix__exit},
903 {"exec", posix_exec},
904 {"fork", posix_fork},
Guido van Rossum46003ff1992-05-15 11:05:24 +0000905 {"getegid", posix_getegid},
906 {"geteuid", posix_geteuid},
907 {"getgid", posix_getgid},
Guido van Rossum85e3b011991-06-03 12:42:10 +0000908 {"getpid", posix_getpid},
Guido van Rossum04814471991-06-04 20:23:49 +0000909 {"getpgrp", posix_getpgrp},
Guido van Rossum85e3b011991-06-03 12:42:10 +0000910 {"getppid", posix_getppid},
Guido van Rossum46003ff1992-05-15 11:05:24 +0000911 {"getuid", posix_getuid},
Guido van Rossum85e3b011991-06-03 12:42:10 +0000912 {"kill", posix_kill},
Guido van Rossum3b066191991-06-04 19:40:25 +0000913 {"popen", posix_popen},
Guido van Rossumc2670a01992-09-13 20:07:29 +0000914 {"setpgrp", posix_setpgrp},
Guido van Rossum85e3b011991-06-03 12:42:10 +0000915 {"wait", posix_wait},
Guido van Rossum21803b81992-08-09 12:55:27 +0000916 {"waitpid", posix_waitpid},
Guido van Rossum85e3b011991-06-03 12:42:10 +0000917#endif
Guido van Rossumc39de5f1992-02-05 11:15:54 +0000918
Guido van Rossumc2670a01992-09-13 20:07:29 +0000919#ifdef DO_PG
920 {"setsid", posix_setsid},
921 {"setpgid", posix_setpgid},
922#endif
923
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000924 {NULL, NULL} /* Sentinel */
925};
926
927
928void
929initposix()
930{
931 object *m, *d, *v;
932
933 m = initmodule("posix", posix_methods);
934 d = getmoduledict(m);
935
936 /* Initialize posix.environ dictionary */
937 v = convertenviron();
938 if (v == NULL || dictinsert(d, "environ", v) != 0)
939 fatal("can't define posix.environ");
940 DECREF(v);
941
942 /* Initialize posix.error exception */
943 PosixError = newstringobject("posix.error");
944 if (PosixError == NULL || dictinsert(d, "error", PosixError) != 0)
945 fatal("can't define posix.error");
946}
Guido van Rossum0ee42cd1991-04-08 21:01:03 +0000947
Guido van Rossum3b066191991-06-04 19:40:25 +0000948
949/* Function used elsewhere to get a file's modification time */
950
951long
952getmtime(path)
953 char *path;
954{
955 struct stat st;
956 if (stat(path, &st) != 0)
957 return -1;
958 else
959 return st.st_mtime;
960}
961
962
Guido van Rossum0ee42cd1991-04-08 21:01:03 +0000963#ifdef MSDOS
964
965/* A small "compatibility library" for TurboC under MS-DOS */
966
967#include <sir.h>
968#include <io.h>
969#include <dos.h>
970#include <fcntl.h>
971
972int
973chmod(path, mode)
974 char *path;
975 int mode;
976{
977 return _chmod(path, 1, mode);
978}
979
980int
981utime(path, times)
982 char *path;
983 time_t times[2];
984{
985 struct date dt;
986 struct time tm;
987 struct ftime dft;
988 int fh;
989 unixtodos(tv[0].tv_sec,&dt,&tm);
990 dft.ft_tsec = tm.ti_sec; dft.ft_min = tm.ti_min;
991 dft.ft_hour = tm.ti_hour; dft.ft_day = dt.da_day;
992 dft.ft_month = dt.da_mon;
993 dft.ft_year = (dt.da_year - 1980); /* this is for TC library */
994
Guido van Rossumef0a00e1992-01-27 16:51:30 +0000995 if ((fh = open(path,O_RDWR)) < 0)
Guido van Rossum0ee42cd1991-04-08 21:01:03 +0000996 return posix_error(); /* can't open file to set time */
997 if (setftime(fh,&dft) < 0)
998 {
999 close(fh);
1000 return posix_error();
1001 }
1002 close(fh); /* close the temp handle */
1003}
1004
1005#endif /* MSDOS */