blob: bab0c5976919f8e082c411471a047f6d96fd9b74 [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 Rossuma2b7f401993-01-04 09:09:59 +000078/* XXX Aren't these always declared in unistd.h? */
Guido van Rossum7f77e2d1990-10-30 13:34:38 +000079extern char *strerror PROTO((int));
Guido van Rossuma2b7f401993-01-04 09:09:59 +000080extern int chmod PROTO((const char *, mode_t));
81extern char *getcwd PROTO((char *, int)); /* XXX or size_t? */
82extern int mkdir PROTO((const char *, mode_t));
83extern int chdir PROTO((const char *));
84extern int link PROTO((const char *, const char *));
85extern int rename PROTO((const char *, const char *));
86extern int rmdir PROTO((const char *));
87extern int stat PROTO((const char *, struct stat *));
88extern int unlink PROTO((const char *));
89extern int pclose PROTO((FILE *));
90#ifdef NO_LSTAT
91#define lstat stat
92#else
93extern int lstat PROTO((const char *, struct stat *));
94extern int symlink PROTO((const char *, const char *));
95#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000096
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000097
98/* Return a dictionary corresponding to the POSIX environment table */
99
100extern char **environ;
101
102static object *
103convertenviron()
104{
105 object *d;
106 char **e;
107 d = newdictobject();
108 if (d == NULL)
109 return NULL;
110 if (environ == NULL)
111 return d;
112 /* XXX This part ignores errors */
113 for (e = environ; *e != NULL; e++) {
114 object *v;
115 char *p = strchr(*e, '=');
116 if (p == NULL)
117 continue;
118 v = newstringobject(p+1);
119 if (v == NULL)
120 continue;
121 *p = '\0';
122 (void) dictinsert(d, *e, v);
123 *p = '=';
124 DECREF(v);
125 }
126 return d;
127}
128
129
130static object *PosixError; /* Exception posix.error */
131
132/* Set a POSIX-specific error from errno, and return NULL */
133
Guido van Rossum9a1581c1990-10-21 13:12:47 +0000134static object *
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000135posix_error()
136{
Guido van Rossume8f305a1990-10-14 20:04:28 +0000137 return err_errno(PosixError);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000138}
139
140
141/* POSIX generic methods */
142
143static object *
144posix_1str(args, func)
145 object *args;
146 int (*func) FPROTO((const char *));
147{
Guido van Rossumef0a00e1992-01-27 16:51:30 +0000148 char *path1;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000149 int res;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000150 if (!getstrarg(args, &path1))
151 return NULL;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000152 BGN_SAVE
153 res = (*func)(path1);
154 END_SAVE
155 if (res < 0)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000156 return posix_error();
157 INCREF(None);
158 return None;
159}
160
161static object *
162posix_2str(args, func)
163 object *args;
164 int (*func) FPROTO((const char *, const char *));
165{
Guido van Rossumef0a00e1992-01-27 16:51:30 +0000166 char *path1, *path2;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000167 int res;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000168 if (!getstrstrarg(args, &path1, &path2))
169 return NULL;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000170 BGN_SAVE
171 res = (*func)(path1, path2);
172 END_SAVE
173 if (res < 0)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000174 return posix_error();
175 INCREF(None);
176 return None;
177}
178
179static object *
180posix_strint(args, func)
181 object *args;
182 int (*func) FPROTO((const char *, int));
183{
Guido van Rossumef0a00e1992-01-27 16:51:30 +0000184 char *path;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000185 int i;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000186 int res;
Guido van Rossumef0a00e1992-01-27 16:51:30 +0000187 if (!getstrintarg(args, &path, &i))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000188 return NULL;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000189 BGN_SAVE
190 res = (*func)(path, i);
191 END_SAVE
192 if (res < 0)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000193 return posix_error();
194 INCREF(None);
195 return None;
196}
197
198static object *
199posix_do_stat(self, args, statfunc)
200 object *self;
201 object *args;
202 int (*statfunc) FPROTO((const char *, struct stat *));
203{
204 struct stat st;
Guido van Rossumef0a00e1992-01-27 16:51:30 +0000205 char *path;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000206 object *v;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000207 int res;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000208 if (!getstrarg(args, &path))
209 return NULL;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000210 BGN_SAVE
211 res = (*statfunc)(path, &st);
212 END_SAVE
213 if (res != 0)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000214 return posix_error();
215 v = newtupleobject(10);
216 if (v == NULL)
217 return NULL;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000218#define SET(i, st_member) settupleitem(v, i, newintobject((long)st.st_member))
219 SET(0, st_mode);
220 SET(1, st_ino);
221 SET(2, st_dev);
222 SET(3, st_nlink);
223 SET(4, st_uid);
224 SET(5, st_gid);
225 SET(6, st_size);
226 SET(7, st_atime);
227 SET(8, st_mtime);
228 SET(9, st_ctime);
229#undef SET
Guido van Rossum3f5da241990-12-20 15:06:42 +0000230 if (err_occurred()) {
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000231 DECREF(v);
Guido van Rossum3f5da241990-12-20 15:06:42 +0000232 return NULL;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000233 }
234 return v;
235}
236
237
238/* POSIX methods */
239
240static object *
241posix_chdir(self, args)
242 object *self;
243 object *args;
244{
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000245 return posix_1str(args, chdir);
246}
247
248static object *
249posix_chmod(self, args)
250 object *self;
251 object *args;
252{
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000253 return posix_strint(args, chmod);
254}
255
256static object *
257posix_getcwd(self, args)
258 object *self;
259 object *args;
260{
261 char buf[1026];
Guido van Rossumff4949e1992-08-05 19:58:53 +0000262 char *res;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000263 if (!getnoarg(args))
264 return NULL;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000265 BGN_SAVE
266 res = getcwd(buf, sizeof buf);
267 END_SAVE
268 if (res == NULL)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000269 return posix_error();
270 return newstringobject(buf);
271}
272
Guido van Rossum0ee42cd1991-04-08 21:01:03 +0000273#ifndef MSDOS
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000274static object *
275posix_link(self, args)
276 object *self;
277 object *args;
278{
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000279 return posix_2str(args, link);
280}
Guido van Rossum0ee42cd1991-04-08 21:01:03 +0000281#endif /* !MSDOS */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000282
283static object *
284posix_listdir(self, args)
285 object *self;
286 object *args;
287{
Guido van Rossumef0a00e1992-01-27 16:51:30 +0000288 char *name;
289 object *d, *v;
Guido van Rossum0ee42cd1991-04-08 21:01:03 +0000290
291#ifdef MSDOS
292 struct ffblk ep;
293 int rv;
294 if (!getstrarg(args, &name))
295 return NULL;
296
Guido van Rossumef0a00e1992-01-27 16:51:30 +0000297 if (findfirst(name, &ep, 0) == -1)
Guido van Rossum0ee42cd1991-04-08 21:01:03 +0000298 return posix_error();
299 if ((d = newlistobject(0)) == NULL)
300 return NULL;
301 do {
302 v = newstringobject(ep.ff_name);
303 if (v == NULL) {
304 DECREF(d);
305 d = NULL;
306 break;
307 }
308 if (addlistitem(d, v) != 0) {
309 DECREF(v);
310 DECREF(d);
311 d = NULL;
312 break;
313 }
314 DECREF(v);
315 } while ((rv = findnext(&ep)) == 0);
316#else /* !MSDOS */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000317 DIR *dirp;
318 struct direct *ep;
319 if (!getstrarg(args, &name))
320 return NULL;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000321 BGN_SAVE
322 if ((dirp = opendir(name)) == NULL) {
323 RET_SAVE
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000324 return posix_error();
Guido van Rossumff4949e1992-08-05 19:58:53 +0000325 }
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000326 if ((d = newlistobject(0)) == NULL) {
327 closedir(dirp);
Guido van Rossumff4949e1992-08-05 19:58:53 +0000328 RET_SAVE
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000329 return NULL;
330 }
331 while ((ep = readdir(dirp)) != NULL) {
332 v = newstringobject(ep->d_name);
333 if (v == NULL) {
334 DECREF(d);
335 d = NULL;
336 break;
337 }
338 if (addlistitem(d, v) != 0) {
339 DECREF(v);
340 DECREF(d);
341 d = NULL;
342 break;
343 }
344 DECREF(v);
345 }
346 closedir(dirp);
Guido van Rossumff4949e1992-08-05 19:58:53 +0000347 END_SAVE
Guido van Rossum0ee42cd1991-04-08 21:01:03 +0000348#endif /* !MSDOS */
349
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000350 return d;
351}
352
353static object *
354posix_mkdir(self, args)
355 object *self;
356 object *args;
357{
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000358 return posix_strint(args, mkdir);
359}
360
Guido van Rossum775f4da1993-01-09 17:18:52 +0000361#ifndef MSDOS
362static object *
363posix_nice(self, args)
364 object *self;
365 object *args;
366{
367 int increment, value;
368
369 if (!getargs(args, "i", &increment))
370 return NULL;
371 value = nice(increment);
372 if (value == -1)
373 return posix_error();
374 return newintobject((long) value);
375}
376#endif
377
Guido van Rossum1ff6cb41991-04-08 20:59:13 +0000378#ifdef i386
379int
380rename(from, to)
381 char *from;
382 char *to;
383{
384 int status;
385 /* XXX Shouldn't this unlink the destination first? */
386 status = link(from, to);
387 if (status != 0)
388 return status;
389 return unlink(from);
390}
Guido van Rossum0ee42cd1991-04-08 21:01:03 +0000391#endif /* i386 */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +0000392
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000393static object *
394posix_rename(self, args)
395 object *self;
396 object *args;
397{
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000398 return posix_2str(args, rename);
399}
400
401static object *
402posix_rmdir(self, args)
403 object *self;
404 object *args;
405{
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000406 return posix_1str(args, rmdir);
407}
408
409static object *
410posix_stat(self, args)
411 object *self;
412 object *args;
413{
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000414 return posix_do_stat(self, args, stat);
415}
416
417static object *
418posix_system(self, args)
419 object *self;
420 object *args;
421{
Guido van Rossumef0a00e1992-01-27 16:51:30 +0000422 char *command;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000423 long sts;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000424 if (!getstrarg(args, &command))
425 return NULL;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000426 BGN_SAVE
Guido van Rossumef0a00e1992-01-27 16:51:30 +0000427 sts = system(command);
Guido van Rossumff4949e1992-08-05 19:58:53 +0000428 END_SAVE
429 return newintobject(sts);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000430}
431
Guido van Rossum0ee42cd1991-04-08 21:01:03 +0000432#ifndef MSDOS
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000433static object *
434posix_umask(self, args)
435 object *self;
436 object *args;
437{
438 int i;
439 if (!getintarg(args, &i))
440 return NULL;
441 i = umask(i);
442 if (i < 0)
443 return posix_error();
444 return newintobject((long)i);
445}
Guido van Rossum0ee42cd1991-04-08 21:01:03 +0000446#endif /* !MSDOS */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000447
448static object *
449posix_unlink(self, args)
450 object *self;
451 object *args;
452{
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000453 return posix_1str(args, unlink);
454}
455
Guido van Rossumc39de5f1992-02-05 11:15:54 +0000456#ifndef NO_UNAME
457#include <sys/utsname.h>
458
Guido van Rossuma2b7f401993-01-04 09:09:59 +0000459extern int uname PROTO((struct utsname *));
460
Guido van Rossumc39de5f1992-02-05 11:15:54 +0000461static object *
462posix_uname(self, args)
463 object *self;
464 object *args;
465{
Guido van Rossumc39de5f1992-02-05 11:15:54 +0000466 struct utsname u;
467 object *v;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000468 int res;
Guido van Rossum50e61dc1992-03-27 17:22:31 +0000469 if (!getnoarg(args))
470 return NULL;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000471 BGN_SAVE
472 res = uname(&u);
473 END_SAVE
474 if (res < 0)
Guido van Rossumc39de5f1992-02-05 11:15:54 +0000475 return posix_error();
476 v = newtupleobject(5);
477 if (v == NULL)
478 return NULL;
479#define SET(i, member) settupleitem(v, i, newstringobject(u.member))
480 SET(0, sysname);
481 SET(1, nodename);
482 SET(2, release);
483 SET(3, version);
484 SET(4, machine);
485#undef SET
486 if (err_occurred()) {
487 DECREF(v);
488 return NULL;
489 }
490 return v;
491}
492#endif /* NO_UNAME */
493
Guido van Rossum1ff6cb41991-04-08 20:59:13 +0000494#ifdef UTIME_STRUCT
495#include <utime.h>
496#endif
497
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000498static object *
Guido van Rossum1ff6cb41991-04-08 20:59:13 +0000499posix_utime(self, args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000500 object *self;
501 object *args;
502{
Guido van Rossumef0a00e1992-01-27 16:51:30 +0000503 char *path;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000504 int res;
Guido van Rossum1ff6cb41991-04-08 20:59:13 +0000505
506#ifdef UTIME_STRUCT
507 struct utimbuf buf;
508#define ATIME buf.actime
509#define MTIME buf.modtime
510#define UTIME_ARG &buf
511
512#else
513 time_t buf[2];
514#define ATIME buf[0]
515#define MTIME buf[1]
516#define UTIME_ARG buf
517#endif
518
Guido van Rossumef0a00e1992-01-27 16:51:30 +0000519 if (!getargs(args, "(s(ll))", &path, &ATIME, &MTIME))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000520 return NULL;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000521 BGN_SAVE
522 res = utime(path, UTIME_ARG);
523 END_SAVE
524 if (res < 0)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000525 return posix_error();
526 INCREF(None);
527 return None;
Guido van Rossum1ff6cb41991-04-08 20:59:13 +0000528#undef UTIME_ARG
529#undef ATIME
530#undef MTIME
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000531}
532
Guido van Rossum85e3b011991-06-03 12:42:10 +0000533
534#ifndef MSDOS
535
Guido van Rossum3b066191991-06-04 19:40:25 +0000536/* Process operations */
Guido van Rossum85e3b011991-06-03 12:42:10 +0000537
538static object *
539posix__exit(self, args)
540 object *self;
541 object *args;
542{
543 int sts;
544 if (!getintarg(args, &sts))
545 return NULL;
546 _exit(sts);
547 /* NOTREACHED */
548}
549
550/* XXX To do: exece, execp */
551
552static object *
553posix_exec(self, args)
554 object *self;
555 object *args;
556{
Guido van Rossumef0a00e1992-01-27 16:51:30 +0000557 char *path;
558 object *argv;
Guido van Rossum85e3b011991-06-03 12:42:10 +0000559 char **argvlist;
560 int i, argc;
561 object *(*getitem) PROTO((object *, int));
562
563 /* exec has two arguments: (path, argv), where
564 argv is a list or tuple of strings. */
565
Guido van Rossumef0a00e1992-01-27 16:51:30 +0000566 if (!getargs(args, "(sO)", &path, &argv))
Guido van Rossum85e3b011991-06-03 12:42:10 +0000567 return NULL;
Guido van Rossum85e3b011991-06-03 12:42:10 +0000568 if (is_listobject(argv)) {
569 argc = getlistsize(argv);
570 getitem = getlistitem;
571 }
572 else if (is_tupleobject(argv)) {
573 argc = gettuplesize(argv);
574 getitem = gettupleitem;
575 }
Guido van Rossumef0a00e1992-01-27 16:51:30 +0000576 else {
577 badarg:
578 err_badarg();
579 return NULL;
580 }
Guido van Rossum85e3b011991-06-03 12:42:10 +0000581
582 argvlist = NEW(char *, argc+1);
583 if (argvlist == NULL)
584 return NULL;
585 for (i = 0; i < argc; i++) {
Guido van Rossumef0a00e1992-01-27 16:51:30 +0000586 if (!getstrarg((*getitem)(argv, i), &argvlist[i])) {
Guido van Rossum85e3b011991-06-03 12:42:10 +0000587 DEL(argvlist);
588 goto badarg;
589 }
Guido van Rossum85e3b011991-06-03 12:42:10 +0000590 }
591 argvlist[argc] = NULL;
592
Guido van Rossumef0a00e1992-01-27 16:51:30 +0000593 execv(path, argvlist);
Guido van Rossum85e3b011991-06-03 12:42:10 +0000594
595 /* If we get here it's definitely an error */
596
597 DEL(argvlist);
598 return posix_error();
599}
600
601static object *
602posix_fork(self, args)
603 object *self;
604 object *args;
605{
606 int pid;
Guido van Rossum50e61dc1992-03-27 17:22:31 +0000607 if (!getnoarg(args))
608 return NULL;
Guido van Rossum85e3b011991-06-03 12:42:10 +0000609 pid = fork();
610 if (pid == -1)
611 return posix_error();
612 return newintobject((long)pid);
613}
614
615static object *
Guido van Rossum46003ff1992-05-15 11:05:24 +0000616posix_getegid(self, args)
617 object *self;
618 object *args;
619{
620 if (!getnoarg(args))
621 return NULL;
622 return newintobject((long)getegid());
623}
624
625static object *
626posix_geteuid(self, args)
627 object *self;
628 object *args;
629{
630 if (!getnoarg(args))
631 return NULL;
632 return newintobject((long)geteuid());
633}
634
635static object *
636posix_getgid(self, args)
637 object *self;
638 object *args;
639{
640 if (!getnoarg(args))
641 return NULL;
642 return newintobject((long)getgid());
643}
644
645static object *
Guido van Rossum85e3b011991-06-03 12:42:10 +0000646posix_getpid(self, args)
647 object *self;
648 object *args;
649{
Guido van Rossum04814471991-06-04 20:23:49 +0000650 if (!getnoarg(args))
Guido van Rossum85e3b011991-06-03 12:42:10 +0000651 return NULL;
652 return newintobject((long)getpid());
653}
654
655static object *
Guido van Rossum04814471991-06-04 20:23:49 +0000656posix_getpgrp(self, args)
657 object *self;
658 object *args;
659{
660 if (!getnoarg(args))
661 return NULL;
Guido van Rossum50e61dc1992-03-27 17:22:31 +0000662#ifdef SYSV
663 return newintobject((long)getpgrp());
664#else
Guido van Rossum971443b1991-06-07 13:59:29 +0000665 return newintobject((long)getpgrp(0));
Guido van Rossum50e61dc1992-03-27 17:22:31 +0000666#endif
Guido van Rossum04814471991-06-04 20:23:49 +0000667}
668
669static object *
Guido van Rossumc2670a01992-09-13 20:07:29 +0000670posix_setpgrp(self, args)
671 object *self;
672 object *args;
673{
674 if (!getnoarg(args))
675 return NULL;
676#ifdef SYSV
677 if (setpgrp() < 0)
678#else
679 if (setpgrp(0, 0) < 0)
680#endif
681 return err_errno(PosixError);
682 INCREF(None);
683 return None;
684}
685
686static object *
Guido van Rossum85e3b011991-06-03 12:42:10 +0000687posix_getppid(self, args)
688 object *self;
689 object *args;
690{
Guido van Rossum04814471991-06-04 20:23:49 +0000691 if (!getnoarg(args))
Guido van Rossum85e3b011991-06-03 12:42:10 +0000692 return NULL;
693 return newintobject((long)getppid());
694}
695
696static object *
Guido van Rossum46003ff1992-05-15 11:05:24 +0000697posix_getuid(self, args)
698 object *self;
699 object *args;
700{
701 if (!getnoarg(args))
702 return NULL;
703 return newintobject((long)getuid());
704}
705
706static object *
Guido van Rossum85e3b011991-06-03 12:42:10 +0000707posix_kill(self, args)
708 object *self;
709 object *args;
710{
711 int pid, sig;
712 if (!getintintarg(args, &pid, &sig))
713 return NULL;
714 if (kill(pid, sig) == -1)
715 return posix_error();
716 INCREF(None);
717 return None;
718}
719
720static object *
Guido van Rossum3b066191991-06-04 19:40:25 +0000721posix_popen(self, args)
722 object *self;
723 object *args;
724{
Guido van Rossumef0a00e1992-01-27 16:51:30 +0000725 char *name, *mode;
Guido van Rossum3b066191991-06-04 19:40:25 +0000726 FILE *fp;
Guido van Rossumef0a00e1992-01-27 16:51:30 +0000727 if (!getargs(args, "(ss)", &name, &mode))
Guido van Rossum3b066191991-06-04 19:40:25 +0000728 return NULL;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000729 BGN_SAVE
Guido van Rossumef0a00e1992-01-27 16:51:30 +0000730 fp = popen(name, mode);
Guido van Rossumff4949e1992-08-05 19:58:53 +0000731 END_SAVE
Guido van Rossum3b066191991-06-04 19:40:25 +0000732 if (fp == NULL)
733 return posix_error();
Guido van Rossume0d452d1991-07-27 21:41:01 +0000734 /* From now on, ignore SIGPIPE and let the error checking
735 do the work. */
736 (void) signal(SIGPIPE, SIG_IGN);
Guido van Rossumef0a00e1992-01-27 16:51:30 +0000737 return newopenfileobject(fp, name, mode, pclose);
Guido van Rossum3b066191991-06-04 19:40:25 +0000738}
739
740static object *
Guido van Rossum21803b81992-08-09 12:55:27 +0000741posix_waitpid(self, args)
Guido van Rossum85e3b011991-06-03 12:42:10 +0000742 object *self;
743 object *args;
744{
Guido van Rossum85e3b011991-06-03 12:42:10 +0000745#ifdef NO_WAITPID
Guido van Rossum21803b81992-08-09 12:55:27 +0000746 err_setstr(PosixError,
747 "posix.waitpid() not supported on this system");
748 return NULL;
Guido van Rossum85e3b011991-06-03 12:42:10 +0000749#else
Guido van Rossum21803b81992-08-09 12:55:27 +0000750 int pid, options, sts;
751 if (!getargs(args, "(ii)", &pid, &options))
752 return NULL;
753 BGN_SAVE
754 pid = waitpid(pid, &sts, options);
755 END_SAVE
Guido van Rossum85e3b011991-06-03 12:42:10 +0000756 if (pid == -1)
757 return posix_error();
Guido van Rossum21803b81992-08-09 12:55:27 +0000758 else
759 return mkvalue("ii", pid, sts);
760#endif
761}
762
763static object *
764posix_wait(self, args)
765 object *self;
766 object *args;
767{
768 int pid, sts;
769 if (args != NULL)
770 return posix_waitpid(self, args); /* BW compat */
771 BGN_SAVE
772 pid = wait(&sts);
773 END_SAVE
774 if (pid == -1)
775 return posix_error();
776 else
777 return mkvalue("ii", pid, sts);
Guido van Rossum85e3b011991-06-03 12:42:10 +0000778}
779
780#endif /* MSDOS */
781
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000782static object *
783posix_lstat(self, args)
784 object *self;
785 object *args;
786{
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000787 return posix_do_stat(self, args, lstat);
788}
789
790static object *
791posix_readlink(self, args)
792 object *self;
793 object *args;
794{
Guido van Rossumc39de5f1992-02-05 11:15:54 +0000795#ifdef NO_LSTAT
796 err_setstr(PosixError, "readlink not implemented on this system");
797 return NULL;
798#else
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000799 char buf[1024]; /* XXX Should use MAXPATHLEN */
Guido van Rossumef0a00e1992-01-27 16:51:30 +0000800 char *path;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000801 int n;
802 if (!getstrarg(args, &path))
803 return NULL;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000804 BGN_SAVE
Guido van Rossum50e61dc1992-03-27 17:22:31 +0000805 n = readlink(path, buf, (int) sizeof buf);
Guido van Rossumff4949e1992-08-05 19:58:53 +0000806 END_SAVE
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000807 if (n < 0)
808 return posix_error();
809 return newsizedstringobject(buf, n);
Guido van Rossumc39de5f1992-02-05 11:15:54 +0000810#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000811}
812
813static object *
814posix_symlink(self, args)
815 object *self;
816 object *args;
817{
Guido van Rossumc39de5f1992-02-05 11:15:54 +0000818#ifdef NO_LSTAT
819 err_setstr(PosixError, "symlink not implemented on this system");
820 return NULL;
821#else
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000822 return posix_2str(args, symlink);
Guido van Rossumc39de5f1992-02-05 11:15:54 +0000823#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000824}
825
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000826
Guido van Rossum22db57e1992-04-05 14:25:30 +0000827#ifdef DO_TIMES
828
829static object *
830posix_times(self, args)
831 object *self;
832 object *args;
833{
834 struct tms t;
835 clock_t c;
836 object *tuple;
837 if (!getnoarg(args))
838 return NULL;
839 errno = 0;
840 c = times(&t);
841 if (c == (clock_t) -1) {
Guido van Rossum7066dd71992-09-17 17:54:56 +0000842 err_errno(PosixError);
Guido van Rossum22db57e1992-04-05 14:25:30 +0000843 return NULL;
844 }
845 tuple = newtupleobject(4);
846 if (tuple == NULL)
847 return NULL;
848 settupleitem(tuple, 0, newfloatobject((double)t.tms_utime / HZ));
849 settupleitem(tuple, 1, newfloatobject((double)t.tms_stime / HZ));
850 settupleitem(tuple, 2, newfloatobject((double)t.tms_cutime / HZ));
851 settupleitem(tuple, 3, newfloatobject((double)t.tms_cstime / HZ));
852 if (err_occurred()) {
853 DECREF(tuple);
854 return NULL;
855 }
856 return tuple;
857}
858
Guido van Rossumc2670a01992-09-13 20:07:29 +0000859#endif /* DO_TIMES */
860
861#ifdef DO_PG
862
863static object *
864posix_setsid(self, args)
865 object *self;
866 object *args;
867{
868 if (!getnoarg(args))
869 return NULL;
Guido van Rossum7066dd71992-09-17 17:54:56 +0000870 if (setsid() < 0) {
Guido van Rossumc2670a01992-09-13 20:07:29 +0000871 err_errno(PosixError);
Guido van Rossum7066dd71992-09-17 17:54:56 +0000872 return NULL;
873 }
Guido van Rossumc2670a01992-09-13 20:07:29 +0000874 INCREF(None);
875 return None;
876}
877
878static object *
879posix_setpgid(self, args)
880 object *self;
881 object *args;
882{
883 int pid, pgrp;
884 if (!getargs(args, "(ii)", &pid, &pgrp))
885 return NULL;
Guido van Rossum7066dd71992-09-17 17:54:56 +0000886 if (setpgid(pid, pgrp) < 0) {
Guido van Rossumc2670a01992-09-13 20:07:29 +0000887 err_errno(PosixError);
Guido van Rossum7066dd71992-09-17 17:54:56 +0000888 return NULL;
889 }
Guido van Rossumc2670a01992-09-13 20:07:29 +0000890 INCREF(None);
891 return None;
892}
893
Guido van Rossum7066dd71992-09-17 17:54:56 +0000894static object *
895posix_tcgetpgrp(self, args)
896 object *self;
897 object *args;
898{
899 int fd, pgid;
900 if (!getargs(args, "i", &fd))
901 return NULL;
902 pgid = tcgetpgrp(fd);
903 if (pgid < 0) {
904 err_errno(PosixError);
905 return NULL;
906 }
907 return newintobject((long)pgid);
908}
909
910static object *
911posix_tcsetpgrp(self, args)
912 object *self;
913 object *args;
914{
915 int fd, pgid;
916 if (!getargs(args, "(ii)", &fd, &pgid))
917 return NULL;
918 if (tcsetpgrp(fd, pgid) < 0) {
919 err_errno(PosixError);
920 return NULL;
921 }
922 INCREF(None);
923 return None;
924}
925
Guido van Rossumc2670a01992-09-13 20:07:29 +0000926#endif /* DO_PG */
Guido van Rossum22db57e1992-04-05 14:25:30 +0000927
928
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000929static struct methodlist posix_methods[] = {
930 {"chdir", posix_chdir},
931 {"chmod", posix_chmod},
932 {"getcwd", posix_getcwd},
Guido van Rossum0ee42cd1991-04-08 21:01:03 +0000933#ifndef MSDOS
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000934 {"link", posix_link},
Guido van Rossum0ee42cd1991-04-08 21:01:03 +0000935#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000936 {"listdir", posix_listdir},
Guido van Rossumc39de5f1992-02-05 11:15:54 +0000937 {"lstat", posix_lstat},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000938 {"mkdir", posix_mkdir},
Guido van Rossum775f4da1993-01-09 17:18:52 +0000939#ifndef MSDOS
940 {"nice", posix_nice},
941#endif
Guido van Rossumc39de5f1992-02-05 11:15:54 +0000942 {"readlink", posix_readlink},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000943 {"rename", posix_rename},
944 {"rmdir", posix_rmdir},
945 {"stat", posix_stat},
Guido van Rossumc39de5f1992-02-05 11:15:54 +0000946 {"symlink", posix_symlink},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000947 {"system", posix_system},
Guido van Rossum0ee42cd1991-04-08 21:01:03 +0000948#ifndef MSDOS
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000949 {"umask", posix_umask},
Guido van Rossum0ee42cd1991-04-08 21:01:03 +0000950#endif
Guido van Rossumc39de5f1992-02-05 11:15:54 +0000951#ifndef NO_UNAME
952 {"uname", posix_uname},
953#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000954 {"unlink", posix_unlink},
Guido van Rossum1ff6cb41991-04-08 20:59:13 +0000955 {"utime", posix_utime},
Guido van Rossum22db57e1992-04-05 14:25:30 +0000956#ifdef DO_TIMES
957 {"times", posix_times},
958#endif
Guido van Rossumc39de5f1992-02-05 11:15:54 +0000959
Guido van Rossum85e3b011991-06-03 12:42:10 +0000960#ifndef MSDOS
961 {"_exit", posix__exit},
962 {"exec", posix_exec},
963 {"fork", posix_fork},
Guido van Rossum46003ff1992-05-15 11:05:24 +0000964 {"getegid", posix_getegid},
965 {"geteuid", posix_geteuid},
966 {"getgid", posix_getgid},
Guido van Rossum85e3b011991-06-03 12:42:10 +0000967 {"getpid", posix_getpid},
Guido van Rossum04814471991-06-04 20:23:49 +0000968 {"getpgrp", posix_getpgrp},
Guido van Rossum85e3b011991-06-03 12:42:10 +0000969 {"getppid", posix_getppid},
Guido van Rossum46003ff1992-05-15 11:05:24 +0000970 {"getuid", posix_getuid},
Guido van Rossum85e3b011991-06-03 12:42:10 +0000971 {"kill", posix_kill},
Guido van Rossum3b066191991-06-04 19:40:25 +0000972 {"popen", posix_popen},
Guido van Rossumc2670a01992-09-13 20:07:29 +0000973 {"setpgrp", posix_setpgrp},
Guido van Rossum85e3b011991-06-03 12:42:10 +0000974 {"wait", posix_wait},
Guido van Rossum21803b81992-08-09 12:55:27 +0000975 {"waitpid", posix_waitpid},
Guido van Rossum85e3b011991-06-03 12:42:10 +0000976#endif
Guido van Rossumc39de5f1992-02-05 11:15:54 +0000977
Guido van Rossumc2670a01992-09-13 20:07:29 +0000978#ifdef DO_PG
979 {"setsid", posix_setsid},
980 {"setpgid", posix_setpgid},
Guido van Rossum7066dd71992-09-17 17:54:56 +0000981 {"tcgetpgrp", posix_tcgetpgrp},
982 {"tcsetpgrp", posix_tcsetpgrp},
Guido van Rossumc2670a01992-09-13 20:07:29 +0000983#endif
984
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000985 {NULL, NULL} /* Sentinel */
986};
987
988
989void
990initposix()
991{
992 object *m, *d, *v;
993
994 m = initmodule("posix", posix_methods);
995 d = getmoduledict(m);
996
997 /* Initialize posix.environ dictionary */
998 v = convertenviron();
999 if (v == NULL || dictinsert(d, "environ", v) != 0)
1000 fatal("can't define posix.environ");
1001 DECREF(v);
1002
1003 /* Initialize posix.error exception */
1004 PosixError = newstringobject("posix.error");
1005 if (PosixError == NULL || dictinsert(d, "error", PosixError) != 0)
1006 fatal("can't define posix.error");
1007}
Guido van Rossum0ee42cd1991-04-08 21:01:03 +00001008
Guido van Rossum3b066191991-06-04 19:40:25 +00001009
1010/* Function used elsewhere to get a file's modification time */
1011
1012long
1013getmtime(path)
1014 char *path;
1015{
1016 struct stat st;
1017 if (stat(path, &st) != 0)
1018 return -1;
1019 else
1020 return st.st_mtime;
1021}
1022
1023
Guido van Rossum0ee42cd1991-04-08 21:01:03 +00001024#ifdef MSDOS
1025
1026/* A small "compatibility library" for TurboC under MS-DOS */
1027
1028#include <sir.h>
1029#include <io.h>
1030#include <dos.h>
1031#include <fcntl.h>
1032
1033int
1034chmod(path, mode)
1035 char *path;
1036 int mode;
1037{
1038 return _chmod(path, 1, mode);
1039}
1040
1041int
1042utime(path, times)
1043 char *path;
1044 time_t times[2];
1045{
1046 struct date dt;
1047 struct time tm;
1048 struct ftime dft;
1049 int fh;
1050 unixtodos(tv[0].tv_sec,&dt,&tm);
1051 dft.ft_tsec = tm.ti_sec; dft.ft_min = tm.ti_min;
1052 dft.ft_hour = tm.ti_hour; dft.ft_day = dt.da_day;
1053 dft.ft_month = dt.da_mon;
1054 dft.ft_year = (dt.da_year - 1980); /* this is for TC library */
1055
Guido van Rossumef0a00e1992-01-27 16:51:30 +00001056 if ((fh = open(path,O_RDWR)) < 0)
Guido van Rossum0ee42cd1991-04-08 21:01:03 +00001057 return posix_error(); /* can't open file to set time */
1058 if (setftime(fh,&dft) < 0)
1059 {
1060 close(fh);
1061 return posix_error();
1062 }
1063 close(fh); /* close the temp handle */
1064}
1065
1066#endif /* MSDOS */