blob: 8ae1758fe353c989e9a7d50168928c6a51d8830c [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 *
Guido van Rossum46003ff1992-05-15 11:05:24 +0000554posix_getegid(self, args)
555 object *self;
556 object *args;
557{
558 if (!getnoarg(args))
559 return NULL;
560 return newintobject((long)getegid());
561}
562
563static object *
564posix_geteuid(self, args)
565 object *self;
566 object *args;
567{
568 if (!getnoarg(args))
569 return NULL;
570 return newintobject((long)geteuid());
571}
572
573static object *
574posix_getgid(self, args)
575 object *self;
576 object *args;
577{
578 if (!getnoarg(args))
579 return NULL;
580 return newintobject((long)getgid());
581}
582
583static object *
Guido van Rossum85e3b011991-06-03 12:42:10 +0000584posix_getpid(self, args)
585 object *self;
586 object *args;
587{
Guido van Rossum04814471991-06-04 20:23:49 +0000588 if (!getnoarg(args))
Guido van Rossum85e3b011991-06-03 12:42:10 +0000589 return NULL;
590 return newintobject((long)getpid());
591}
592
593static object *
Guido van Rossum04814471991-06-04 20:23:49 +0000594posix_getpgrp(self, args)
595 object *self;
596 object *args;
597{
598 if (!getnoarg(args))
599 return NULL;
Guido van Rossum50e61dc1992-03-27 17:22:31 +0000600#ifdef SYSV
601 return newintobject((long)getpgrp());
602#else
Guido van Rossum971443b1991-06-07 13:59:29 +0000603 return newintobject((long)getpgrp(0));
Guido van Rossum50e61dc1992-03-27 17:22:31 +0000604#endif
Guido van Rossum04814471991-06-04 20:23:49 +0000605}
606
607static object *
Guido van Rossum85e3b011991-06-03 12:42:10 +0000608posix_getppid(self, args)
609 object *self;
610 object *args;
611{
Guido van Rossum04814471991-06-04 20:23:49 +0000612 if (!getnoarg(args))
Guido van Rossum85e3b011991-06-03 12:42:10 +0000613 return NULL;
614 return newintobject((long)getppid());
615}
616
617static object *
Guido van Rossum46003ff1992-05-15 11:05:24 +0000618posix_getuid(self, args)
619 object *self;
620 object *args;
621{
622 if (!getnoarg(args))
623 return NULL;
624 return newintobject((long)getuid());
625}
626
627static object *
Guido van Rossum85e3b011991-06-03 12:42:10 +0000628posix_kill(self, args)
629 object *self;
630 object *args;
631{
632 int pid, sig;
633 if (!getintintarg(args, &pid, &sig))
634 return NULL;
635 if (kill(pid, sig) == -1)
636 return posix_error();
637 INCREF(None);
638 return None;
639}
640
641static object *
Guido van Rossum3b066191991-06-04 19:40:25 +0000642posix_popen(self, args)
643 object *self;
644 object *args;
645{
646 extern int pclose PROTO((FILE *));
Guido van Rossumef0a00e1992-01-27 16:51:30 +0000647 char *name, *mode;
Guido van Rossum3b066191991-06-04 19:40:25 +0000648 FILE *fp;
Guido van Rossumef0a00e1992-01-27 16:51:30 +0000649 if (!getargs(args, "(ss)", &name, &mode))
Guido van Rossum3b066191991-06-04 19:40:25 +0000650 return NULL;
Guido van Rossumef0a00e1992-01-27 16:51:30 +0000651 fp = popen(name, mode);
Guido van Rossum3b066191991-06-04 19:40:25 +0000652 if (fp == NULL)
653 return posix_error();
Guido van Rossume0d452d1991-07-27 21:41:01 +0000654 /* From now on, ignore SIGPIPE and let the error checking
655 do the work. */
656 (void) signal(SIGPIPE, SIG_IGN);
Guido van Rossumef0a00e1992-01-27 16:51:30 +0000657 return newopenfileobject(fp, name, mode, pclose);
Guido van Rossum3b066191991-06-04 19:40:25 +0000658}
659
660static object *
Guido van Rossum85e3b011991-06-03 12:42:10 +0000661posix_wait(self, args) /* Also waitpid() */
662 object *self;
663 object *args;
664{
665 object *v;
666 int pid, sts;
667 if (args == NULL)
668 pid = wait(&sts);
669 else {
670#ifdef NO_WAITPID
Guido van Rossumc39de5f1992-02-05 11:15:54 +0000671 err_setstr(PosixError,
Guido van Rossum85e3b011991-06-03 12:42:10 +0000672 "posix.wait(pid, options) not supported on this system");
673#else
674 int options;
675 if (!getintintarg(args, &pid, &options))
676 return NULL;
677 pid = waitpid(pid, &sts, options);
678#endif
679 }
680 if (pid == -1)
681 return posix_error();
682 v = newtupleobject(2);
683 if (v != NULL) {
684 settupleitem(v, 0, newintobject((long)pid));
685 settupleitem(v, 1, newintobject((long)sts));
686 if (err_occurred()) {
687 DECREF(v);
688 v = NULL;
689 }
690 }
691 return v;
692}
693
694#endif /* MSDOS */
695
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000696static object *
697posix_lstat(self, args)
698 object *self;
699 object *args;
700{
Guido van Rossumc39de5f1992-02-05 11:15:54 +0000701#ifdef NO_LSTAT
702#define lstat stat
703#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000704 extern int lstat PROTO((const char *, struct stat *));
705 return posix_do_stat(self, args, lstat);
706}
707
708static object *
709posix_readlink(self, args)
710 object *self;
711 object *args;
712{
Guido van Rossumc39de5f1992-02-05 11:15:54 +0000713#ifdef NO_LSTAT
714 err_setstr(PosixError, "readlink not implemented on this system");
715 return NULL;
716#else
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000717 char buf[1024]; /* XXX Should use MAXPATHLEN */
Guido van Rossumef0a00e1992-01-27 16:51:30 +0000718 char *path;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000719 int n;
720 if (!getstrarg(args, &path))
721 return NULL;
Guido van Rossum50e61dc1992-03-27 17:22:31 +0000722 n = readlink(path, buf, (int) sizeof buf);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000723 if (n < 0)
724 return posix_error();
725 return newsizedstringobject(buf, n);
Guido van Rossumc39de5f1992-02-05 11:15:54 +0000726#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000727}
728
729static object *
730posix_symlink(self, args)
731 object *self;
732 object *args;
733{
Guido van Rossumc39de5f1992-02-05 11:15:54 +0000734#ifdef NO_LSTAT
735 err_setstr(PosixError, "symlink not implemented on this system");
736 return NULL;
737#else
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000738 extern int symlink PROTO((const char *, const char *));
739 return posix_2str(args, symlink);
Guido van Rossumc39de5f1992-02-05 11:15:54 +0000740#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000741}
742
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000743
Guido van Rossum22db57e1992-04-05 14:25:30 +0000744#ifdef DO_TIMES
745
746static object *
747posix_times(self, args)
748 object *self;
749 object *args;
750{
751 struct tms t;
752 clock_t c;
753 object *tuple;
754 if (!getnoarg(args))
755 return NULL;
756 errno = 0;
757 c = times(&t);
758 if (c == (clock_t) -1) {
759 err_errno(IOError);
760 return NULL;
761 }
762 tuple = newtupleobject(4);
763 if (tuple == NULL)
764 return NULL;
765 settupleitem(tuple, 0, newfloatobject((double)t.tms_utime / HZ));
766 settupleitem(tuple, 1, newfloatobject((double)t.tms_stime / HZ));
767 settupleitem(tuple, 2, newfloatobject((double)t.tms_cutime / HZ));
768 settupleitem(tuple, 3, newfloatobject((double)t.tms_cstime / HZ));
769 if (err_occurred()) {
770 DECREF(tuple);
771 return NULL;
772 }
773 return tuple;
774}
775
776#endif
777
778
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000779static struct methodlist posix_methods[] = {
780 {"chdir", posix_chdir},
781 {"chmod", posix_chmod},
782 {"getcwd", posix_getcwd},
Guido van Rossum0ee42cd1991-04-08 21:01:03 +0000783#ifndef MSDOS
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000784 {"link", posix_link},
Guido van Rossum0ee42cd1991-04-08 21:01:03 +0000785#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000786 {"listdir", posix_listdir},
Guido van Rossumc39de5f1992-02-05 11:15:54 +0000787 {"lstat", posix_lstat},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000788 {"mkdir", posix_mkdir},
Guido van Rossumc39de5f1992-02-05 11:15:54 +0000789 {"readlink", posix_readlink},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000790 {"rename", posix_rename},
791 {"rmdir", posix_rmdir},
792 {"stat", posix_stat},
Guido van Rossumc39de5f1992-02-05 11:15:54 +0000793 {"symlink", posix_symlink},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000794 {"system", posix_system},
Guido van Rossum0ee42cd1991-04-08 21:01:03 +0000795#ifndef MSDOS
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000796 {"umask", posix_umask},
Guido van Rossum0ee42cd1991-04-08 21:01:03 +0000797#endif
Guido van Rossumc39de5f1992-02-05 11:15:54 +0000798#ifndef NO_UNAME
799 {"uname", posix_uname},
800#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000801 {"unlink", posix_unlink},
Guido van Rossum1ff6cb41991-04-08 20:59:13 +0000802 {"utime", posix_utime},
Guido van Rossum22db57e1992-04-05 14:25:30 +0000803#ifdef DO_TIMES
804 {"times", posix_times},
805#endif
Guido van Rossumc39de5f1992-02-05 11:15:54 +0000806
Guido van Rossum85e3b011991-06-03 12:42:10 +0000807#ifndef MSDOS
808 {"_exit", posix__exit},
809 {"exec", posix_exec},
810 {"fork", posix_fork},
Guido van Rossum46003ff1992-05-15 11:05:24 +0000811 {"getegid", posix_getegid},
812 {"geteuid", posix_geteuid},
813 {"getgid", posix_getgid},
Guido van Rossum85e3b011991-06-03 12:42:10 +0000814 {"getpid", posix_getpid},
Guido van Rossum04814471991-06-04 20:23:49 +0000815 {"getpgrp", posix_getpgrp},
Guido van Rossum85e3b011991-06-03 12:42:10 +0000816 {"getppid", posix_getppid},
Guido van Rossum46003ff1992-05-15 11:05:24 +0000817 {"getuid", posix_getuid},
Guido van Rossum85e3b011991-06-03 12:42:10 +0000818 {"kill", posix_kill},
Guido van Rossum3b066191991-06-04 19:40:25 +0000819 {"popen", posix_popen},
Guido van Rossum85e3b011991-06-03 12:42:10 +0000820 {"wait", posix_wait},
821#endif
Guido van Rossumc39de5f1992-02-05 11:15:54 +0000822
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000823 {NULL, NULL} /* Sentinel */
824};
825
826
827void
828initposix()
829{
830 object *m, *d, *v;
831
832 m = initmodule("posix", posix_methods);
833 d = getmoduledict(m);
834
835 /* Initialize posix.environ dictionary */
836 v = convertenviron();
837 if (v == NULL || dictinsert(d, "environ", v) != 0)
838 fatal("can't define posix.environ");
839 DECREF(v);
840
841 /* Initialize posix.error exception */
842 PosixError = newstringobject("posix.error");
843 if (PosixError == NULL || dictinsert(d, "error", PosixError) != 0)
844 fatal("can't define posix.error");
845}
Guido van Rossum0ee42cd1991-04-08 21:01:03 +0000846
Guido van Rossum3b066191991-06-04 19:40:25 +0000847
848/* Function used elsewhere to get a file's modification time */
849
850long
851getmtime(path)
852 char *path;
853{
854 struct stat st;
855 if (stat(path, &st) != 0)
856 return -1;
857 else
858 return st.st_mtime;
859}
860
861
Guido van Rossum0ee42cd1991-04-08 21:01:03 +0000862#ifdef MSDOS
863
864/* A small "compatibility library" for TurboC under MS-DOS */
865
866#include <sir.h>
867#include <io.h>
868#include <dos.h>
869#include <fcntl.h>
870
871int
872chmod(path, mode)
873 char *path;
874 int mode;
875{
876 return _chmod(path, 1, mode);
877}
878
879int
880utime(path, times)
881 char *path;
882 time_t times[2];
883{
884 struct date dt;
885 struct time tm;
886 struct ftime dft;
887 int fh;
888 unixtodos(tv[0].tv_sec,&dt,&tm);
889 dft.ft_tsec = tm.ti_sec; dft.ft_min = tm.ti_min;
890 dft.ft_hour = tm.ti_hour; dft.ft_day = dt.da_day;
891 dft.ft_month = dt.da_mon;
892 dft.ft_year = (dt.da_year - 1980); /* this is for TC library */
893
Guido van Rossumef0a00e1992-01-27 16:51:30 +0000894 if ((fh = open(path,O_RDWR)) < 0)
Guido van Rossum0ee42cd1991-04-08 21:01:03 +0000895 return posix_error(); /* can't open file to set time */
896 if (setftime(fh,&dft) < 0)
897 {
898 close(fh);
899 return posix_error();
900 }
901 close(fh); /* close the temp handle */
902}
903
904#endif /* MSDOS */