blob: a6001151fb98a991ad3a5d57531f194a19102833 [file] [log] [blame]
Guido van Rossumf70e43a1991-02-19 12:39:46 +00001/***********************************************************
Guido van Rossum775f4da1993-01-09 17:18:52 +00002Copyright 1991, 1992, 1993 by Stichting Mathematisch Centrum,
3Amsterdam, The Netherlands.
Guido van Rossumf70e43a1991-02-19 12:39:46 +00004
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 Rossum0b0db8e1993-01-21 16:07:51 +000078#ifdef _SEQUENT_
79#include <unistd.h>
80#else /* _SEQUENT_ */
Guido van Rossuma2b7f401993-01-04 09:09:59 +000081/* XXX Aren't these always declared in unistd.h? */
Guido van Rossum7f77e2d1990-10-30 13:34:38 +000082extern char *strerror PROTO((int));
Guido van Rossuma2b7f401993-01-04 09:09:59 +000083extern int chmod PROTO((const char *, mode_t));
84extern char *getcwd PROTO((char *, int)); /* XXX or size_t? */
85extern int mkdir PROTO((const char *, mode_t));
86extern int chdir PROTO((const char *));
87extern int link PROTO((const char *, const char *));
88extern int rename PROTO((const char *, const char *));
89extern int rmdir PROTO((const char *));
90extern int stat PROTO((const char *, struct stat *));
91extern int unlink PROTO((const char *));
92extern int pclose PROTO((FILE *));
Guido van Rossum0b0db8e1993-01-21 16:07:51 +000093#endif /* _SEQUENT_ */
Guido van Rossuma2b7f401993-01-04 09:09:59 +000094#ifdef NO_LSTAT
95#define lstat stat
96#else
97extern int lstat PROTO((const char *, struct stat *));
98extern int symlink PROTO((const char *, const char *));
99#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000100
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000101
102/* Return a dictionary corresponding to the POSIX environment table */
103
104extern char **environ;
105
106static object *
107convertenviron()
108{
109 object *d;
110 char **e;
111 d = newdictobject();
112 if (d == NULL)
113 return NULL;
114 if (environ == NULL)
115 return d;
116 /* XXX This part ignores errors */
117 for (e = environ; *e != NULL; e++) {
118 object *v;
119 char *p = strchr(*e, '=');
120 if (p == NULL)
121 continue;
122 v = newstringobject(p+1);
123 if (v == NULL)
124 continue;
125 *p = '\0';
126 (void) dictinsert(d, *e, v);
127 *p = '=';
128 DECREF(v);
129 }
130 return d;
131}
132
133
134static object *PosixError; /* Exception posix.error */
135
136/* Set a POSIX-specific error from errno, and return NULL */
137
Guido van Rossum9a1581c1990-10-21 13:12:47 +0000138static object *
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000139posix_error()
140{
Guido van Rossume8f305a1990-10-14 20:04:28 +0000141 return err_errno(PosixError);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000142}
143
144
145/* POSIX generic methods */
146
147static object *
148posix_1str(args, func)
149 object *args;
150 int (*func) FPROTO((const char *));
151{
Guido van Rossumef0a00e1992-01-27 16:51:30 +0000152 char *path1;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000153 int res;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000154 if (!getstrarg(args, &path1))
155 return NULL;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000156 BGN_SAVE
157 res = (*func)(path1);
158 END_SAVE
159 if (res < 0)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000160 return posix_error();
161 INCREF(None);
162 return None;
163}
164
165static object *
166posix_2str(args, func)
167 object *args;
168 int (*func) FPROTO((const char *, const char *));
169{
Guido van Rossumef0a00e1992-01-27 16:51:30 +0000170 char *path1, *path2;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000171 int res;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000172 if (!getstrstrarg(args, &path1, &path2))
173 return NULL;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000174 BGN_SAVE
175 res = (*func)(path1, path2);
176 END_SAVE
177 if (res < 0)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000178 return posix_error();
179 INCREF(None);
180 return None;
181}
182
183static object *
184posix_strint(args, func)
185 object *args;
186 int (*func) FPROTO((const char *, int));
187{
Guido van Rossumef0a00e1992-01-27 16:51:30 +0000188 char *path;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000189 int i;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000190 int res;
Guido van Rossumef0a00e1992-01-27 16:51:30 +0000191 if (!getstrintarg(args, &path, &i))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000192 return NULL;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000193 BGN_SAVE
194 res = (*func)(path, i);
195 END_SAVE
196 if (res < 0)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000197 return posix_error();
198 INCREF(None);
199 return None;
200}
201
202static object *
203posix_do_stat(self, args, statfunc)
204 object *self;
205 object *args;
206 int (*statfunc) FPROTO((const char *, struct stat *));
207{
208 struct stat st;
Guido van Rossumef0a00e1992-01-27 16:51:30 +0000209 char *path;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000210 object *v;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000211 int res;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000212 if (!getstrarg(args, &path))
213 return NULL;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000214 BGN_SAVE
215 res = (*statfunc)(path, &st);
216 END_SAVE
217 if (res != 0)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000218 return posix_error();
219 v = newtupleobject(10);
220 if (v == NULL)
221 return NULL;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000222#define SET(i, st_member) settupleitem(v, i, newintobject((long)st.st_member))
223 SET(0, st_mode);
224 SET(1, st_ino);
225 SET(2, st_dev);
226 SET(3, st_nlink);
227 SET(4, st_uid);
228 SET(5, st_gid);
229 SET(6, st_size);
230 SET(7, st_atime);
231 SET(8, st_mtime);
232 SET(9, st_ctime);
233#undef SET
Guido van Rossum3f5da241990-12-20 15:06:42 +0000234 if (err_occurred()) {
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000235 DECREF(v);
Guido van Rossum3f5da241990-12-20 15:06:42 +0000236 return NULL;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000237 }
238 return v;
239}
240
241
242/* POSIX methods */
243
244static object *
245posix_chdir(self, args)
246 object *self;
247 object *args;
248{
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000249 return posix_1str(args, chdir);
250}
251
252static object *
253posix_chmod(self, args)
254 object *self;
255 object *args;
256{
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000257 return posix_strint(args, chmod);
258}
259
260static object *
261posix_getcwd(self, args)
262 object *self;
263 object *args;
264{
265 char buf[1026];
Guido van Rossumff4949e1992-08-05 19:58:53 +0000266 char *res;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000267 if (!getnoarg(args))
268 return NULL;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000269 BGN_SAVE
270 res = getcwd(buf, sizeof buf);
271 END_SAVE
272 if (res == NULL)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000273 return posix_error();
274 return newstringobject(buf);
275}
276
Guido van Rossum0ee42cd1991-04-08 21:01:03 +0000277#ifndef MSDOS
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000278static object *
279posix_link(self, args)
280 object *self;
281 object *args;
282{
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000283 return posix_2str(args, link);
284}
Guido van Rossum0ee42cd1991-04-08 21:01:03 +0000285#endif /* !MSDOS */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000286
287static object *
288posix_listdir(self, args)
289 object *self;
290 object *args;
291{
Guido van Rossumef0a00e1992-01-27 16:51:30 +0000292 char *name;
293 object *d, *v;
Guido van Rossum0ee42cd1991-04-08 21:01:03 +0000294
295#ifdef MSDOS
296 struct ffblk ep;
297 int rv;
298 if (!getstrarg(args, &name))
299 return NULL;
300
Guido van Rossumef0a00e1992-01-27 16:51:30 +0000301 if (findfirst(name, &ep, 0) == -1)
Guido van Rossum0ee42cd1991-04-08 21:01:03 +0000302 return posix_error();
303 if ((d = newlistobject(0)) == NULL)
304 return NULL;
305 do {
306 v = newstringobject(ep.ff_name);
307 if (v == NULL) {
308 DECREF(d);
309 d = NULL;
310 break;
311 }
312 if (addlistitem(d, v) != 0) {
313 DECREF(v);
314 DECREF(d);
315 d = NULL;
316 break;
317 }
318 DECREF(v);
319 } while ((rv = findnext(&ep)) == 0);
320#else /* !MSDOS */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000321 DIR *dirp;
322 struct direct *ep;
323 if (!getstrarg(args, &name))
324 return NULL;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000325 BGN_SAVE
326 if ((dirp = opendir(name)) == NULL) {
327 RET_SAVE
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000328 return posix_error();
Guido van Rossumff4949e1992-08-05 19:58:53 +0000329 }
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000330 if ((d = newlistobject(0)) == NULL) {
331 closedir(dirp);
Guido van Rossumff4949e1992-08-05 19:58:53 +0000332 RET_SAVE
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000333 return NULL;
334 }
335 while ((ep = readdir(dirp)) != NULL) {
336 v = newstringobject(ep->d_name);
337 if (v == NULL) {
338 DECREF(d);
339 d = NULL;
340 break;
341 }
342 if (addlistitem(d, v) != 0) {
343 DECREF(v);
344 DECREF(d);
345 d = NULL;
346 break;
347 }
348 DECREF(v);
349 }
350 closedir(dirp);
Guido van Rossumff4949e1992-08-05 19:58:53 +0000351 END_SAVE
Guido van Rossum0ee42cd1991-04-08 21:01:03 +0000352#endif /* !MSDOS */
353
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000354 return d;
355}
356
357static object *
358posix_mkdir(self, args)
359 object *self;
360 object *args;
361{
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000362 return posix_strint(args, mkdir);
363}
364
Guido van Rossum775f4da1993-01-09 17:18:52 +0000365#ifndef MSDOS
366static object *
367posix_nice(self, args)
368 object *self;
369 object *args;
370{
371 int increment, value;
372
373 if (!getargs(args, "i", &increment))
374 return NULL;
375 value = nice(increment);
376 if (value == -1)
377 return posix_error();
378 return newintobject((long) value);
379}
380#endif
381
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000382#if i386 && ! _SEQUENT_
Guido van Rossum1ff6cb41991-04-08 20:59:13 +0000383int
384rename(from, to)
385 char *from;
386 char *to;
387{
388 int status;
389 /* XXX Shouldn't this unlink the destination first? */
390 status = link(from, to);
391 if (status != 0)
392 return status;
393 return unlink(from);
394}
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000395#endif /* i386 && ! _SEQUENT_ */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +0000396
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000397static object *
398posix_rename(self, args)
399 object *self;
400 object *args;
401{
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000402 return posix_2str(args, rename);
403}
404
405static object *
406posix_rmdir(self, args)
407 object *self;
408 object *args;
409{
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000410 return posix_1str(args, rmdir);
411}
412
413static object *
414posix_stat(self, args)
415 object *self;
416 object *args;
417{
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000418 return posix_do_stat(self, args, stat);
419}
420
421static object *
422posix_system(self, args)
423 object *self;
424 object *args;
425{
Guido van Rossumef0a00e1992-01-27 16:51:30 +0000426 char *command;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000427 long sts;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000428 if (!getstrarg(args, &command))
429 return NULL;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000430 BGN_SAVE
Guido van Rossumef0a00e1992-01-27 16:51:30 +0000431 sts = system(command);
Guido van Rossumff4949e1992-08-05 19:58:53 +0000432 END_SAVE
433 return newintobject(sts);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000434}
435
Guido van Rossum0ee42cd1991-04-08 21:01:03 +0000436#ifndef MSDOS
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000437static object *
438posix_umask(self, args)
439 object *self;
440 object *args;
441{
442 int i;
443 if (!getintarg(args, &i))
444 return NULL;
445 i = umask(i);
446 if (i < 0)
447 return posix_error();
448 return newintobject((long)i);
449}
Guido van Rossum0ee42cd1991-04-08 21:01:03 +0000450#endif /* !MSDOS */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000451
452static object *
453posix_unlink(self, args)
454 object *self;
455 object *args;
456{
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000457 return posix_1str(args, unlink);
458}
459
Guido van Rossumc39de5f1992-02-05 11:15:54 +0000460#ifndef NO_UNAME
461#include <sys/utsname.h>
462
Guido van Rossuma2b7f401993-01-04 09:09:59 +0000463extern int uname PROTO((struct utsname *));
464
Guido van Rossumc39de5f1992-02-05 11:15:54 +0000465static object *
466posix_uname(self, args)
467 object *self;
468 object *args;
469{
Guido van Rossumc39de5f1992-02-05 11:15:54 +0000470 struct utsname u;
471 object *v;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000472 int res;
Guido van Rossum50e61dc1992-03-27 17:22:31 +0000473 if (!getnoarg(args))
474 return NULL;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000475 BGN_SAVE
476 res = uname(&u);
477 END_SAVE
478 if (res < 0)
Guido van Rossumc39de5f1992-02-05 11:15:54 +0000479 return posix_error();
480 v = newtupleobject(5);
481 if (v == NULL)
482 return NULL;
483#define SET(i, member) settupleitem(v, i, newstringobject(u.member))
484 SET(0, sysname);
485 SET(1, nodename);
486 SET(2, release);
487 SET(3, version);
488 SET(4, machine);
489#undef SET
490 if (err_occurred()) {
491 DECREF(v);
492 return NULL;
493 }
494 return v;
495}
496#endif /* NO_UNAME */
497
Guido van Rossum1ff6cb41991-04-08 20:59:13 +0000498#ifdef UTIME_STRUCT
499#include <utime.h>
500#endif
501
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000502static object *
Guido van Rossum1ff6cb41991-04-08 20:59:13 +0000503posix_utime(self, args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000504 object *self;
505 object *args;
506{
Guido van Rossumef0a00e1992-01-27 16:51:30 +0000507 char *path;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000508 int res;
Guido van Rossum1ff6cb41991-04-08 20:59:13 +0000509
510#ifdef UTIME_STRUCT
511 struct utimbuf buf;
512#define ATIME buf.actime
513#define MTIME buf.modtime
514#define UTIME_ARG &buf
515
516#else
517 time_t buf[2];
518#define ATIME buf[0]
519#define MTIME buf[1]
520#define UTIME_ARG buf
521#endif
522
Guido van Rossumef0a00e1992-01-27 16:51:30 +0000523 if (!getargs(args, "(s(ll))", &path, &ATIME, &MTIME))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000524 return NULL;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000525 BGN_SAVE
526 res = utime(path, UTIME_ARG);
527 END_SAVE
528 if (res < 0)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000529 return posix_error();
530 INCREF(None);
531 return None;
Guido van Rossum1ff6cb41991-04-08 20:59:13 +0000532#undef UTIME_ARG
533#undef ATIME
534#undef MTIME
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000535}
536
Guido van Rossum85e3b011991-06-03 12:42:10 +0000537
538#ifndef MSDOS
539
Guido van Rossum3b066191991-06-04 19:40:25 +0000540/* Process operations */
Guido van Rossum85e3b011991-06-03 12:42:10 +0000541
542static object *
543posix__exit(self, args)
544 object *self;
545 object *args;
546{
547 int sts;
548 if (!getintarg(args, &sts))
549 return NULL;
550 _exit(sts);
551 /* NOTREACHED */
552}
553
554/* XXX To do: exece, execp */
555
556static object *
557posix_exec(self, args)
558 object *self;
559 object *args;
560{
Guido van Rossumef0a00e1992-01-27 16:51:30 +0000561 char *path;
562 object *argv;
Guido van Rossum85e3b011991-06-03 12:42:10 +0000563 char **argvlist;
564 int i, argc;
565 object *(*getitem) PROTO((object *, int));
566
567 /* exec has two arguments: (path, argv), where
568 argv is a list or tuple of strings. */
569
Guido van Rossumef0a00e1992-01-27 16:51:30 +0000570 if (!getargs(args, "(sO)", &path, &argv))
Guido van Rossum85e3b011991-06-03 12:42:10 +0000571 return NULL;
Guido van Rossum85e3b011991-06-03 12:42:10 +0000572 if (is_listobject(argv)) {
573 argc = getlistsize(argv);
574 getitem = getlistitem;
575 }
576 else if (is_tupleobject(argv)) {
577 argc = gettuplesize(argv);
578 getitem = gettupleitem;
579 }
Guido van Rossumef0a00e1992-01-27 16:51:30 +0000580 else {
581 badarg:
582 err_badarg();
583 return NULL;
584 }
Guido van Rossum85e3b011991-06-03 12:42:10 +0000585
586 argvlist = NEW(char *, argc+1);
587 if (argvlist == NULL)
588 return NULL;
589 for (i = 0; i < argc; i++) {
Guido van Rossumef0a00e1992-01-27 16:51:30 +0000590 if (!getstrarg((*getitem)(argv, i), &argvlist[i])) {
Guido van Rossum85e3b011991-06-03 12:42:10 +0000591 DEL(argvlist);
592 goto badarg;
593 }
Guido van Rossum85e3b011991-06-03 12:42:10 +0000594 }
595 argvlist[argc] = NULL;
596
Guido van Rossumef0a00e1992-01-27 16:51:30 +0000597 execv(path, argvlist);
Guido van Rossum85e3b011991-06-03 12:42:10 +0000598
599 /* If we get here it's definitely an error */
600
601 DEL(argvlist);
602 return posix_error();
603}
604
605static object *
606posix_fork(self, args)
607 object *self;
608 object *args;
609{
610 int pid;
Guido van Rossum50e61dc1992-03-27 17:22:31 +0000611 if (!getnoarg(args))
612 return NULL;
Guido van Rossum85e3b011991-06-03 12:42:10 +0000613 pid = fork();
614 if (pid == -1)
615 return posix_error();
616 return newintobject((long)pid);
617}
618
619static object *
Guido van Rossum46003ff1992-05-15 11:05:24 +0000620posix_getegid(self, args)
621 object *self;
622 object *args;
623{
624 if (!getnoarg(args))
625 return NULL;
626 return newintobject((long)getegid());
627}
628
629static object *
630posix_geteuid(self, args)
631 object *self;
632 object *args;
633{
634 if (!getnoarg(args))
635 return NULL;
636 return newintobject((long)geteuid());
637}
638
639static object *
640posix_getgid(self, args)
641 object *self;
642 object *args;
643{
644 if (!getnoarg(args))
645 return NULL;
646 return newintobject((long)getgid());
647}
648
649static object *
Guido van Rossum85e3b011991-06-03 12:42:10 +0000650posix_getpid(self, args)
651 object *self;
652 object *args;
653{
Guido van Rossum04814471991-06-04 20:23:49 +0000654 if (!getnoarg(args))
Guido van Rossum85e3b011991-06-03 12:42:10 +0000655 return NULL;
656 return newintobject((long)getpid());
657}
658
659static object *
Guido van Rossum04814471991-06-04 20:23:49 +0000660posix_getpgrp(self, args)
661 object *self;
662 object *args;
663{
664 if (!getnoarg(args))
665 return NULL;
Guido van Rossum50e61dc1992-03-27 17:22:31 +0000666#ifdef SYSV
667 return newintobject((long)getpgrp());
668#else
Guido van Rossum971443b1991-06-07 13:59:29 +0000669 return newintobject((long)getpgrp(0));
Guido van Rossum50e61dc1992-03-27 17:22:31 +0000670#endif
Guido van Rossum04814471991-06-04 20:23:49 +0000671}
672
673static object *
Guido van Rossumc2670a01992-09-13 20:07:29 +0000674posix_setpgrp(self, args)
675 object *self;
676 object *args;
677{
678 if (!getnoarg(args))
679 return NULL;
680#ifdef SYSV
681 if (setpgrp() < 0)
682#else
683 if (setpgrp(0, 0) < 0)
684#endif
685 return err_errno(PosixError);
686 INCREF(None);
687 return None;
688}
689
690static object *
Guido van Rossum85e3b011991-06-03 12:42:10 +0000691posix_getppid(self, args)
692 object *self;
693 object *args;
694{
Guido van Rossum04814471991-06-04 20:23:49 +0000695 if (!getnoarg(args))
Guido van Rossum85e3b011991-06-03 12:42:10 +0000696 return NULL;
697 return newintobject((long)getppid());
698}
699
700static object *
Guido van Rossum46003ff1992-05-15 11:05:24 +0000701posix_getuid(self, args)
702 object *self;
703 object *args;
704{
705 if (!getnoarg(args))
706 return NULL;
707 return newintobject((long)getuid());
708}
709
710static object *
Guido van Rossum85e3b011991-06-03 12:42:10 +0000711posix_kill(self, args)
712 object *self;
713 object *args;
714{
715 int pid, sig;
716 if (!getintintarg(args, &pid, &sig))
717 return NULL;
718 if (kill(pid, sig) == -1)
719 return posix_error();
720 INCREF(None);
721 return None;
722}
723
724static object *
Guido van Rossum3b066191991-06-04 19:40:25 +0000725posix_popen(self, args)
726 object *self;
727 object *args;
728{
Guido van Rossumef0a00e1992-01-27 16:51:30 +0000729 char *name, *mode;
Guido van Rossum3b066191991-06-04 19:40:25 +0000730 FILE *fp;
Guido van Rossumef0a00e1992-01-27 16:51:30 +0000731 if (!getargs(args, "(ss)", &name, &mode))
Guido van Rossum3b066191991-06-04 19:40:25 +0000732 return NULL;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000733 BGN_SAVE
Guido van Rossumef0a00e1992-01-27 16:51:30 +0000734 fp = popen(name, mode);
Guido van Rossumff4949e1992-08-05 19:58:53 +0000735 END_SAVE
Guido van Rossum3b066191991-06-04 19:40:25 +0000736 if (fp == NULL)
737 return posix_error();
Guido van Rossume0d452d1991-07-27 21:41:01 +0000738 /* From now on, ignore SIGPIPE and let the error checking
739 do the work. */
740 (void) signal(SIGPIPE, SIG_IGN);
Guido van Rossumef0a00e1992-01-27 16:51:30 +0000741 return newopenfileobject(fp, name, mode, pclose);
Guido van Rossum3b066191991-06-04 19:40:25 +0000742}
743
744static object *
Guido van Rossum21803b81992-08-09 12:55:27 +0000745posix_waitpid(self, args)
Guido van Rossum85e3b011991-06-03 12:42:10 +0000746 object *self;
747 object *args;
748{
Guido van Rossum85e3b011991-06-03 12:42:10 +0000749#ifdef NO_WAITPID
Guido van Rossum21803b81992-08-09 12:55:27 +0000750 err_setstr(PosixError,
751 "posix.waitpid() not supported on this system");
752 return NULL;
Guido van Rossum85e3b011991-06-03 12:42:10 +0000753#else
Guido van Rossum21803b81992-08-09 12:55:27 +0000754 int pid, options, sts;
755 if (!getargs(args, "(ii)", &pid, &options))
756 return NULL;
757 BGN_SAVE
758 pid = waitpid(pid, &sts, options);
759 END_SAVE
Guido van Rossum85e3b011991-06-03 12:42:10 +0000760 if (pid == -1)
761 return posix_error();
Guido van Rossum21803b81992-08-09 12:55:27 +0000762 else
763 return mkvalue("ii", pid, sts);
764#endif
765}
766
767static object *
768posix_wait(self, args)
769 object *self;
770 object *args;
771{
772 int pid, sts;
773 if (args != NULL)
774 return posix_waitpid(self, args); /* BW compat */
775 BGN_SAVE
776 pid = wait(&sts);
777 END_SAVE
778 if (pid == -1)
779 return posix_error();
780 else
781 return mkvalue("ii", pid, sts);
Guido van Rossum85e3b011991-06-03 12:42:10 +0000782}
783
784#endif /* MSDOS */
785
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000786static object *
787posix_lstat(self, args)
788 object *self;
789 object *args;
790{
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000791 return posix_do_stat(self, args, lstat);
792}
793
794static object *
795posix_readlink(self, args)
796 object *self;
797 object *args;
798{
Guido van Rossumc39de5f1992-02-05 11:15:54 +0000799#ifdef NO_LSTAT
800 err_setstr(PosixError, "readlink not implemented on this system");
801 return NULL;
802#else
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000803 char buf[1024]; /* XXX Should use MAXPATHLEN */
Guido van Rossumef0a00e1992-01-27 16:51:30 +0000804 char *path;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000805 int n;
806 if (!getstrarg(args, &path))
807 return NULL;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000808 BGN_SAVE
Guido van Rossum50e61dc1992-03-27 17:22:31 +0000809 n = readlink(path, buf, (int) sizeof buf);
Guido van Rossumff4949e1992-08-05 19:58:53 +0000810 END_SAVE
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000811 if (n < 0)
812 return posix_error();
813 return newsizedstringobject(buf, n);
Guido van Rossumc39de5f1992-02-05 11:15:54 +0000814#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000815}
816
817static object *
818posix_symlink(self, args)
819 object *self;
820 object *args;
821{
Guido van Rossumc39de5f1992-02-05 11:15:54 +0000822#ifdef NO_LSTAT
823 err_setstr(PosixError, "symlink not implemented on this system");
824 return NULL;
825#else
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000826 return posix_2str(args, symlink);
Guido van Rossumc39de5f1992-02-05 11:15:54 +0000827#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000828}
829
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000830
Guido van Rossum22db57e1992-04-05 14:25:30 +0000831#ifdef DO_TIMES
832
833static object *
834posix_times(self, args)
835 object *self;
836 object *args;
837{
838 struct tms t;
839 clock_t c;
Guido van Rossum22db57e1992-04-05 14:25:30 +0000840 if (!getnoarg(args))
841 return NULL;
842 errno = 0;
843 c = times(&t);
844 if (c == (clock_t) -1) {
Guido van Rossum7066dd71992-09-17 17:54:56 +0000845 err_errno(PosixError);
Guido van Rossum22db57e1992-04-05 14:25:30 +0000846 return NULL;
847 }
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000848 return mkvalue("dddd",
849 (double)t.tms_utime / HZ,
850 (double)t.tms_stime / HZ,
851 (double)t.tms_cutime / HZ,
852 (double)t.tms_cstime / HZ);
Guido van Rossum22db57e1992-04-05 14:25:30 +0000853}
854
Guido van Rossumc2670a01992-09-13 20:07:29 +0000855#endif /* DO_TIMES */
856
857#ifdef DO_PG
858
859static object *
860posix_setsid(self, args)
861 object *self;
862 object *args;
863{
864 if (!getnoarg(args))
865 return NULL;
Guido van Rossum7066dd71992-09-17 17:54:56 +0000866 if (setsid() < 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
874static object *
875posix_setpgid(self, args)
876 object *self;
877 object *args;
878{
879 int pid, pgrp;
880 if (!getargs(args, "(ii)", &pid, &pgrp))
881 return NULL;
Guido van Rossum7066dd71992-09-17 17:54:56 +0000882 if (setpgid(pid, pgrp) < 0) {
Guido van Rossumc2670a01992-09-13 20:07:29 +0000883 err_errno(PosixError);
Guido van Rossum7066dd71992-09-17 17:54:56 +0000884 return NULL;
885 }
Guido van Rossumc2670a01992-09-13 20:07:29 +0000886 INCREF(None);
887 return None;
888}
889
Guido van Rossum7066dd71992-09-17 17:54:56 +0000890static object *
891posix_tcgetpgrp(self, args)
892 object *self;
893 object *args;
894{
895 int fd, pgid;
896 if (!getargs(args, "i", &fd))
897 return NULL;
898 pgid = tcgetpgrp(fd);
899 if (pgid < 0) {
900 err_errno(PosixError);
901 return NULL;
902 }
903 return newintobject((long)pgid);
904}
905
906static object *
907posix_tcsetpgrp(self, args)
908 object *self;
909 object *args;
910{
911 int fd, pgid;
912 if (!getargs(args, "(ii)", &fd, &pgid))
913 return NULL;
914 if (tcsetpgrp(fd, pgid) < 0) {
915 err_errno(PosixError);
916 return NULL;
917 }
918 INCREF(None);
919 return None;
920}
921
Guido van Rossumc2670a01992-09-13 20:07:29 +0000922#endif /* DO_PG */
Guido van Rossum22db57e1992-04-05 14:25:30 +0000923
924
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000925static struct methodlist posix_methods[] = {
926 {"chdir", posix_chdir},
927 {"chmod", posix_chmod},
928 {"getcwd", posix_getcwd},
Guido van Rossum0ee42cd1991-04-08 21:01:03 +0000929#ifndef MSDOS
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000930 {"link", posix_link},
Guido van Rossum0ee42cd1991-04-08 21:01:03 +0000931#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000932 {"listdir", posix_listdir},
Guido van Rossumc39de5f1992-02-05 11:15:54 +0000933 {"lstat", posix_lstat},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000934 {"mkdir", posix_mkdir},
Guido van Rossum775f4da1993-01-09 17:18:52 +0000935#ifndef MSDOS
936 {"nice", posix_nice},
937#endif
Guido van Rossumc39de5f1992-02-05 11:15:54 +0000938 {"readlink", posix_readlink},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000939 {"rename", posix_rename},
940 {"rmdir", posix_rmdir},
941 {"stat", posix_stat},
Guido van Rossumc39de5f1992-02-05 11:15:54 +0000942 {"symlink", posix_symlink},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000943 {"system", posix_system},
Guido van Rossum0ee42cd1991-04-08 21:01:03 +0000944#ifndef MSDOS
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000945 {"umask", posix_umask},
Guido van Rossum0ee42cd1991-04-08 21:01:03 +0000946#endif
Guido van Rossumc39de5f1992-02-05 11:15:54 +0000947#ifndef NO_UNAME
948 {"uname", posix_uname},
949#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000950 {"unlink", posix_unlink},
Guido van Rossum1ff6cb41991-04-08 20:59:13 +0000951 {"utime", posix_utime},
Guido van Rossum22db57e1992-04-05 14:25:30 +0000952#ifdef DO_TIMES
953 {"times", posix_times},
954#endif
Guido van Rossumc39de5f1992-02-05 11:15:54 +0000955
Guido van Rossum85e3b011991-06-03 12:42:10 +0000956#ifndef MSDOS
957 {"_exit", posix__exit},
958 {"exec", posix_exec},
959 {"fork", posix_fork},
Guido van Rossum46003ff1992-05-15 11:05:24 +0000960 {"getegid", posix_getegid},
961 {"geteuid", posix_geteuid},
962 {"getgid", posix_getgid},
Guido van Rossum85e3b011991-06-03 12:42:10 +0000963 {"getpid", posix_getpid},
Guido van Rossum04814471991-06-04 20:23:49 +0000964 {"getpgrp", posix_getpgrp},
Guido van Rossum85e3b011991-06-03 12:42:10 +0000965 {"getppid", posix_getppid},
Guido van Rossum46003ff1992-05-15 11:05:24 +0000966 {"getuid", posix_getuid},
Guido van Rossum85e3b011991-06-03 12:42:10 +0000967 {"kill", posix_kill},
Guido van Rossum3b066191991-06-04 19:40:25 +0000968 {"popen", posix_popen},
Guido van Rossumc2670a01992-09-13 20:07:29 +0000969 {"setpgrp", posix_setpgrp},
Guido van Rossum85e3b011991-06-03 12:42:10 +0000970 {"wait", posix_wait},
Guido van Rossum21803b81992-08-09 12:55:27 +0000971 {"waitpid", posix_waitpid},
Guido van Rossum85e3b011991-06-03 12:42:10 +0000972#endif
Guido van Rossumc39de5f1992-02-05 11:15:54 +0000973
Guido van Rossumc2670a01992-09-13 20:07:29 +0000974#ifdef DO_PG
975 {"setsid", posix_setsid},
976 {"setpgid", posix_setpgid},
Guido van Rossum7066dd71992-09-17 17:54:56 +0000977 {"tcgetpgrp", posix_tcgetpgrp},
978 {"tcsetpgrp", posix_tcsetpgrp},
Guido van Rossumc2670a01992-09-13 20:07:29 +0000979#endif
980
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000981 {NULL, NULL} /* Sentinel */
982};
983
984
985void
986initposix()
987{
988 object *m, *d, *v;
989
990 m = initmodule("posix", posix_methods);
991 d = getmoduledict(m);
992
993 /* Initialize posix.environ dictionary */
994 v = convertenviron();
995 if (v == NULL || dictinsert(d, "environ", v) != 0)
996 fatal("can't define posix.environ");
997 DECREF(v);
998
999 /* Initialize posix.error exception */
1000 PosixError = newstringobject("posix.error");
1001 if (PosixError == NULL || dictinsert(d, "error", PosixError) != 0)
1002 fatal("can't define posix.error");
1003}
Guido van Rossum0ee42cd1991-04-08 21:01:03 +00001004
Guido van Rossum3b066191991-06-04 19:40:25 +00001005
1006/* Function used elsewhere to get a file's modification time */
1007
1008long
1009getmtime(path)
1010 char *path;
1011{
1012 struct stat st;
1013 if (stat(path, &st) != 0)
1014 return -1;
1015 else
1016 return st.st_mtime;
1017}
1018
1019
Guido van Rossum0ee42cd1991-04-08 21:01:03 +00001020#ifdef MSDOS
1021
1022/* A small "compatibility library" for TurboC under MS-DOS */
1023
1024#include <sir.h>
1025#include <io.h>
1026#include <dos.h>
1027#include <fcntl.h>
1028
1029int
1030chmod(path, mode)
1031 char *path;
1032 int mode;
1033{
1034 return _chmod(path, 1, mode);
1035}
1036
1037int
1038utime(path, times)
1039 char *path;
1040 time_t times[2];
1041{
1042 struct date dt;
1043 struct time tm;
1044 struct ftime dft;
1045 int fh;
1046 unixtodos(tv[0].tv_sec,&dt,&tm);
1047 dft.ft_tsec = tm.ti_sec; dft.ft_min = tm.ti_min;
1048 dft.ft_hour = tm.ti_hour; dft.ft_day = dt.da_day;
1049 dft.ft_month = dt.da_mon;
1050 dft.ft_year = (dt.da_year - 1980); /* this is for TC library */
1051
Guido van Rossumef0a00e1992-01-27 16:51:30 +00001052 if ((fh = open(path,O_RDWR)) < 0)
Guido van Rossum0ee42cd1991-04-08 21:01:03 +00001053 return posix_error(); /* can't open file to set time */
1054 if (setftime(fh,&dft) < 0)
1055 {
1056 close(fh);
1057 return posix_error();
1058 }
1059 close(fh); /* close the temp handle */
1060}
1061
1062#endif /* MSDOS */