blob: e861d08ea8b87e208e2d217f0321663cb414fcc8 [file] [log] [blame]
Guido van Rossumf70e43a1991-02-19 12:39:46 +00001/***********************************************************
Guido van Rossum22db57e1992-04-05 14:25:30 +00002Copyright 1991, 1992 by Stichting Mathematisch Centrum, Amsterdam, The
Guido van Rossumf70e43a1991-02-19 12:39:46 +00003Netherlands.
4
5 All Rights Reserved
6
7Permission to use, copy, modify, and distribute this software and its
8documentation for any purpose and without fee is hereby granted,
9provided that the above copyright notice appear in all copies and that
10both that copyright notice and this permission notice appear in
11supporting documentation, and that the names of Stichting Mathematisch
12Centrum or CWI not be used in advertising or publicity pertaining to
13distribution of the software without specific, written prior permission.
14
15STICHTING MATHEMATISCH CENTRUM DISCLAIMS ALL WARRANTIES WITH REGARD TO
16THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
17FITNESS, IN NO EVENT SHALL STICHTING MATHEMATISCH CENTRUM BE LIABLE
18FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
19WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
20ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
21OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
22
23******************************************************************/
24
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000025/* POSIX module implementation */
26
Guido van Rossum1ff6cb41991-04-08 20:59:13 +000027#ifdef AMOEBA
28#define NO_LSTAT
29#define SYSV
30#endif
31
Guido van Rossum0ee42cd1991-04-08 21:01:03 +000032#ifdef MSDOS
33#define NO_LSTAT
Guido van Rossumc39de5f1992-02-05 11:15:54 +000034#define NO_UNAME
Guido van Rossum0ee42cd1991-04-08 21:01:03 +000035#endif
36
Guido van Rossumc2670a01992-09-13 20:07:29 +000037#ifdef __sgi
38#define DO_PG
39#endif
40
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000041#include <signal.h>
42#include <string.h>
43#include <setjmp.h>
44#include <sys/types.h>
45#include <sys/stat.h>
Guido van Rossum0ee42cd1991-04-08 21:01:03 +000046
Guido van Rossum22db57e1992-04-05 14:25:30 +000047#ifdef DO_TIMES
48#include <sys/times.h>
49#include <sys/param.h>
50#include <errno.h>
51#endif
52
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000053#ifdef SYSV
Guido van Rossum0ee42cd1991-04-08 21:01:03 +000054
Guido van Rossum1ff6cb41991-04-08 20:59:13 +000055#define UTIME_STRUCT
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000056#include <dirent.h>
57#define direct dirent
Guido van Rossum1ff6cb41991-04-08 20:59:13 +000058#ifdef i386
59#define mode_t int
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000060#endif
Guido van Rossum0ee42cd1991-04-08 21:01:03 +000061
Guido van Rossum1ff6cb41991-04-08 20:59:13 +000062#else /* !SYSV */
Guido van Rossum0ee42cd1991-04-08 21:01:03 +000063
64#ifndef MSDOS
Guido van Rossum1ff6cb41991-04-08 20:59:13 +000065#include <sys/dir.h>
Guido van Rossum0ee42cd1991-04-08 21:01:03 +000066#endif
67
Guido van Rossum1ff6cb41991-04-08 20:59:13 +000068#endif /* !SYSV */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000069
Guido van Rossum50e61dc1992-03-27 17:22:31 +000070#ifndef NO_UNISTD
Guido van Rossum22db57e1992-04-05 14:25:30 +000071#include <unistd.h> /* Take this out and hope the best if it doesn't exist */
Guido van Rossum50e61dc1992-03-27 17:22:31 +000072#endif
73
Guido van Rossum3f5da241990-12-20 15:06:42 +000074#include "allobjects.h"
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000075#include "modsupport.h"
Guido van Rossumff4949e1992-08-05 19:58:53 +000076#include "ceval.h"
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000077
Guido van 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 Rossum1ff6cb41991-04-08 20:59:13 +0000361#ifdef i386
362int
363rename(from, to)
364 char *from;
365 char *to;
366{
367 int status;
368 /* XXX Shouldn't this unlink the destination first? */
369 status = link(from, to);
370 if (status != 0)
371 return status;
372 return unlink(from);
373}
Guido van Rossum0ee42cd1991-04-08 21:01:03 +0000374#endif /* i386 */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +0000375
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000376static object *
377posix_rename(self, args)
378 object *self;
379 object *args;
380{
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000381 return posix_2str(args, rename);
382}
383
384static object *
385posix_rmdir(self, args)
386 object *self;
387 object *args;
388{
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000389 return posix_1str(args, rmdir);
390}
391
392static object *
393posix_stat(self, args)
394 object *self;
395 object *args;
396{
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000397 return posix_do_stat(self, args, stat);
398}
399
400static object *
401posix_system(self, args)
402 object *self;
403 object *args;
404{
Guido van Rossumef0a00e1992-01-27 16:51:30 +0000405 char *command;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000406 long sts;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000407 if (!getstrarg(args, &command))
408 return NULL;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000409 BGN_SAVE
Guido van Rossumef0a00e1992-01-27 16:51:30 +0000410 sts = system(command);
Guido van Rossumff4949e1992-08-05 19:58:53 +0000411 END_SAVE
412 return newintobject(sts);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000413}
414
Guido van Rossum0ee42cd1991-04-08 21:01:03 +0000415#ifndef MSDOS
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000416static object *
417posix_umask(self, args)
418 object *self;
419 object *args;
420{
421 int i;
422 if (!getintarg(args, &i))
423 return NULL;
424 i = umask(i);
425 if (i < 0)
426 return posix_error();
427 return newintobject((long)i);
428}
Guido van Rossum0ee42cd1991-04-08 21:01:03 +0000429#endif /* !MSDOS */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000430
431static object *
432posix_unlink(self, args)
433 object *self;
434 object *args;
435{
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000436 return posix_1str(args, unlink);
437}
438
Guido van Rossumc39de5f1992-02-05 11:15:54 +0000439#ifndef NO_UNAME
440#include <sys/utsname.h>
441
Guido van Rossuma2b7f401993-01-04 09:09:59 +0000442extern int uname PROTO((struct utsname *));
443
Guido van Rossumc39de5f1992-02-05 11:15:54 +0000444static object *
445posix_uname(self, args)
446 object *self;
447 object *args;
448{
Guido van Rossumc39de5f1992-02-05 11:15:54 +0000449 struct utsname u;
450 object *v;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000451 int res;
Guido van Rossum50e61dc1992-03-27 17:22:31 +0000452 if (!getnoarg(args))
453 return NULL;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000454 BGN_SAVE
455 res = uname(&u);
456 END_SAVE
457 if (res < 0)
Guido van Rossumc39de5f1992-02-05 11:15:54 +0000458 return posix_error();
459 v = newtupleobject(5);
460 if (v == NULL)
461 return NULL;
462#define SET(i, member) settupleitem(v, i, newstringobject(u.member))
463 SET(0, sysname);
464 SET(1, nodename);
465 SET(2, release);
466 SET(3, version);
467 SET(4, machine);
468#undef SET
469 if (err_occurred()) {
470 DECREF(v);
471 return NULL;
472 }
473 return v;
474}
475#endif /* NO_UNAME */
476
Guido van Rossum1ff6cb41991-04-08 20:59:13 +0000477#ifdef UTIME_STRUCT
478#include <utime.h>
479#endif
480
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000481static object *
Guido van Rossum1ff6cb41991-04-08 20:59:13 +0000482posix_utime(self, args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000483 object *self;
484 object *args;
485{
Guido van Rossumef0a00e1992-01-27 16:51:30 +0000486 char *path;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000487 int res;
Guido van Rossum1ff6cb41991-04-08 20:59:13 +0000488
489#ifdef UTIME_STRUCT
490 struct utimbuf buf;
491#define ATIME buf.actime
492#define MTIME buf.modtime
493#define UTIME_ARG &buf
494
495#else
496 time_t buf[2];
497#define ATIME buf[0]
498#define MTIME buf[1]
499#define UTIME_ARG buf
500#endif
501
Guido van Rossumef0a00e1992-01-27 16:51:30 +0000502 if (!getargs(args, "(s(ll))", &path, &ATIME, &MTIME))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000503 return NULL;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000504 BGN_SAVE
505 res = utime(path, UTIME_ARG);
506 END_SAVE
507 if (res < 0)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000508 return posix_error();
509 INCREF(None);
510 return None;
Guido van Rossum1ff6cb41991-04-08 20:59:13 +0000511#undef UTIME_ARG
512#undef ATIME
513#undef MTIME
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000514}
515
Guido van Rossum85e3b011991-06-03 12:42:10 +0000516
517#ifndef MSDOS
518
Guido van Rossum3b066191991-06-04 19:40:25 +0000519/* Process operations */
Guido van Rossum85e3b011991-06-03 12:42:10 +0000520
521static object *
522posix__exit(self, args)
523 object *self;
524 object *args;
525{
526 int sts;
527 if (!getintarg(args, &sts))
528 return NULL;
529 _exit(sts);
530 /* NOTREACHED */
531}
532
533/* XXX To do: exece, execp */
534
535static object *
536posix_exec(self, args)
537 object *self;
538 object *args;
539{
Guido van Rossumef0a00e1992-01-27 16:51:30 +0000540 char *path;
541 object *argv;
Guido van Rossum85e3b011991-06-03 12:42:10 +0000542 char **argvlist;
543 int i, argc;
544 object *(*getitem) PROTO((object *, int));
545
546 /* exec has two arguments: (path, argv), where
547 argv is a list or tuple of strings. */
548
Guido van Rossumef0a00e1992-01-27 16:51:30 +0000549 if (!getargs(args, "(sO)", &path, &argv))
Guido van Rossum85e3b011991-06-03 12:42:10 +0000550 return NULL;
Guido van Rossum85e3b011991-06-03 12:42:10 +0000551 if (is_listobject(argv)) {
552 argc = getlistsize(argv);
553 getitem = getlistitem;
554 }
555 else if (is_tupleobject(argv)) {
556 argc = gettuplesize(argv);
557 getitem = gettupleitem;
558 }
Guido van Rossumef0a00e1992-01-27 16:51:30 +0000559 else {
560 badarg:
561 err_badarg();
562 return NULL;
563 }
Guido van Rossum85e3b011991-06-03 12:42:10 +0000564
565 argvlist = NEW(char *, argc+1);
566 if (argvlist == NULL)
567 return NULL;
568 for (i = 0; i < argc; i++) {
Guido van Rossumef0a00e1992-01-27 16:51:30 +0000569 if (!getstrarg((*getitem)(argv, i), &argvlist[i])) {
Guido van Rossum85e3b011991-06-03 12:42:10 +0000570 DEL(argvlist);
571 goto badarg;
572 }
Guido van Rossum85e3b011991-06-03 12:42:10 +0000573 }
574 argvlist[argc] = NULL;
575
Guido van Rossumef0a00e1992-01-27 16:51:30 +0000576 execv(path, argvlist);
Guido van Rossum85e3b011991-06-03 12:42:10 +0000577
578 /* If we get here it's definitely an error */
579
580 DEL(argvlist);
581 return posix_error();
582}
583
584static object *
585posix_fork(self, args)
586 object *self;
587 object *args;
588{
589 int pid;
Guido van Rossum50e61dc1992-03-27 17:22:31 +0000590 if (!getnoarg(args))
591 return NULL;
Guido van Rossum85e3b011991-06-03 12:42:10 +0000592 pid = fork();
593 if (pid == -1)
594 return posix_error();
595 return newintobject((long)pid);
596}
597
598static object *
Guido van Rossum46003ff1992-05-15 11:05:24 +0000599posix_getegid(self, args)
600 object *self;
601 object *args;
602{
603 if (!getnoarg(args))
604 return NULL;
605 return newintobject((long)getegid());
606}
607
608static object *
609posix_geteuid(self, args)
610 object *self;
611 object *args;
612{
613 if (!getnoarg(args))
614 return NULL;
615 return newintobject((long)geteuid());
616}
617
618static object *
619posix_getgid(self, args)
620 object *self;
621 object *args;
622{
623 if (!getnoarg(args))
624 return NULL;
625 return newintobject((long)getgid());
626}
627
628static object *
Guido van Rossum85e3b011991-06-03 12:42:10 +0000629posix_getpid(self, args)
630 object *self;
631 object *args;
632{
Guido van Rossum04814471991-06-04 20:23:49 +0000633 if (!getnoarg(args))
Guido van Rossum85e3b011991-06-03 12:42:10 +0000634 return NULL;
635 return newintobject((long)getpid());
636}
637
638static object *
Guido van Rossum04814471991-06-04 20:23:49 +0000639posix_getpgrp(self, args)
640 object *self;
641 object *args;
642{
643 if (!getnoarg(args))
644 return NULL;
Guido van Rossum50e61dc1992-03-27 17:22:31 +0000645#ifdef SYSV
646 return newintobject((long)getpgrp());
647#else
Guido van Rossum971443b1991-06-07 13:59:29 +0000648 return newintobject((long)getpgrp(0));
Guido van Rossum50e61dc1992-03-27 17:22:31 +0000649#endif
Guido van Rossum04814471991-06-04 20:23:49 +0000650}
651
652static object *
Guido van Rossumc2670a01992-09-13 20:07:29 +0000653posix_setpgrp(self, args)
654 object *self;
655 object *args;
656{
657 if (!getnoarg(args))
658 return NULL;
659#ifdef SYSV
660 if (setpgrp() < 0)
661#else
662 if (setpgrp(0, 0) < 0)
663#endif
664 return err_errno(PosixError);
665 INCREF(None);
666 return None;
667}
668
669static object *
Guido van Rossum85e3b011991-06-03 12:42:10 +0000670posix_getppid(self, args)
671 object *self;
672 object *args;
673{
Guido van Rossum04814471991-06-04 20:23:49 +0000674 if (!getnoarg(args))
Guido van Rossum85e3b011991-06-03 12:42:10 +0000675 return NULL;
676 return newintobject((long)getppid());
677}
678
679static object *
Guido van Rossum46003ff1992-05-15 11:05:24 +0000680posix_getuid(self, args)
681 object *self;
682 object *args;
683{
684 if (!getnoarg(args))
685 return NULL;
686 return newintobject((long)getuid());
687}
688
689static object *
Guido van Rossum85e3b011991-06-03 12:42:10 +0000690posix_kill(self, args)
691 object *self;
692 object *args;
693{
694 int pid, sig;
695 if (!getintintarg(args, &pid, &sig))
696 return NULL;
697 if (kill(pid, sig) == -1)
698 return posix_error();
699 INCREF(None);
700 return None;
701}
702
703static object *
Guido van Rossum3b066191991-06-04 19:40:25 +0000704posix_popen(self, args)
705 object *self;
706 object *args;
707{
Guido van Rossumef0a00e1992-01-27 16:51:30 +0000708 char *name, *mode;
Guido van Rossum3b066191991-06-04 19:40:25 +0000709 FILE *fp;
Guido van Rossumef0a00e1992-01-27 16:51:30 +0000710 if (!getargs(args, "(ss)", &name, &mode))
Guido van Rossum3b066191991-06-04 19:40:25 +0000711 return NULL;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000712 BGN_SAVE
Guido van Rossumef0a00e1992-01-27 16:51:30 +0000713 fp = popen(name, mode);
Guido van Rossumff4949e1992-08-05 19:58:53 +0000714 END_SAVE
Guido van Rossum3b066191991-06-04 19:40:25 +0000715 if (fp == NULL)
716 return posix_error();
Guido van Rossume0d452d1991-07-27 21:41:01 +0000717 /* From now on, ignore SIGPIPE and let the error checking
718 do the work. */
719 (void) signal(SIGPIPE, SIG_IGN);
Guido van Rossumef0a00e1992-01-27 16:51:30 +0000720 return newopenfileobject(fp, name, mode, pclose);
Guido van Rossum3b066191991-06-04 19:40:25 +0000721}
722
723static object *
Guido van Rossum21803b81992-08-09 12:55:27 +0000724posix_waitpid(self, args)
Guido van Rossum85e3b011991-06-03 12:42:10 +0000725 object *self;
726 object *args;
727{
Guido van Rossum85e3b011991-06-03 12:42:10 +0000728#ifdef NO_WAITPID
Guido van Rossum21803b81992-08-09 12:55:27 +0000729 err_setstr(PosixError,
730 "posix.waitpid() not supported on this system");
731 return NULL;
Guido van Rossum85e3b011991-06-03 12:42:10 +0000732#else
Guido van Rossum21803b81992-08-09 12:55:27 +0000733 int pid, options, sts;
734 if (!getargs(args, "(ii)", &pid, &options))
735 return NULL;
736 BGN_SAVE
737 pid = waitpid(pid, &sts, options);
738 END_SAVE
Guido van Rossum85e3b011991-06-03 12:42:10 +0000739 if (pid == -1)
740 return posix_error();
Guido van Rossum21803b81992-08-09 12:55:27 +0000741 else
742 return mkvalue("ii", pid, sts);
743#endif
744}
745
746static object *
747posix_wait(self, args)
748 object *self;
749 object *args;
750{
751 int pid, sts;
752 if (args != NULL)
753 return posix_waitpid(self, args); /* BW compat */
754 BGN_SAVE
755 pid = wait(&sts);
756 END_SAVE
757 if (pid == -1)
758 return posix_error();
759 else
760 return mkvalue("ii", pid, sts);
Guido van Rossum85e3b011991-06-03 12:42:10 +0000761}
762
763#endif /* MSDOS */
764
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000765static object *
766posix_lstat(self, args)
767 object *self;
768 object *args;
769{
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000770 return posix_do_stat(self, args, lstat);
771}
772
773static object *
774posix_readlink(self, args)
775 object *self;
776 object *args;
777{
Guido van Rossumc39de5f1992-02-05 11:15:54 +0000778#ifdef NO_LSTAT
779 err_setstr(PosixError, "readlink not implemented on this system");
780 return NULL;
781#else
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000782 char buf[1024]; /* XXX Should use MAXPATHLEN */
Guido van Rossumef0a00e1992-01-27 16:51:30 +0000783 char *path;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000784 int n;
785 if (!getstrarg(args, &path))
786 return NULL;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000787 BGN_SAVE
Guido van Rossum50e61dc1992-03-27 17:22:31 +0000788 n = readlink(path, buf, (int) sizeof buf);
Guido van Rossumff4949e1992-08-05 19:58:53 +0000789 END_SAVE
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000790 if (n < 0)
791 return posix_error();
792 return newsizedstringobject(buf, n);
Guido van Rossumc39de5f1992-02-05 11:15:54 +0000793#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000794}
795
796static object *
797posix_symlink(self, args)
798 object *self;
799 object *args;
800{
Guido van Rossumc39de5f1992-02-05 11:15:54 +0000801#ifdef NO_LSTAT
802 err_setstr(PosixError, "symlink not implemented on this system");
803 return NULL;
804#else
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000805 return posix_2str(args, symlink);
Guido van Rossumc39de5f1992-02-05 11:15:54 +0000806#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000807}
808
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000809
Guido van Rossum22db57e1992-04-05 14:25:30 +0000810#ifdef DO_TIMES
811
812static object *
813posix_times(self, args)
814 object *self;
815 object *args;
816{
817 struct tms t;
818 clock_t c;
819 object *tuple;
820 if (!getnoarg(args))
821 return NULL;
822 errno = 0;
823 c = times(&t);
824 if (c == (clock_t) -1) {
Guido van Rossum7066dd71992-09-17 17:54:56 +0000825 err_errno(PosixError);
Guido van Rossum22db57e1992-04-05 14:25:30 +0000826 return NULL;
827 }
828 tuple = newtupleobject(4);
829 if (tuple == NULL)
830 return NULL;
831 settupleitem(tuple, 0, newfloatobject((double)t.tms_utime / HZ));
832 settupleitem(tuple, 1, newfloatobject((double)t.tms_stime / HZ));
833 settupleitem(tuple, 2, newfloatobject((double)t.tms_cutime / HZ));
834 settupleitem(tuple, 3, newfloatobject((double)t.tms_cstime / HZ));
835 if (err_occurred()) {
836 DECREF(tuple);
837 return NULL;
838 }
839 return tuple;
840}
841
Guido van Rossumc2670a01992-09-13 20:07:29 +0000842#endif /* DO_TIMES */
843
844#ifdef DO_PG
845
846static object *
847posix_setsid(self, args)
848 object *self;
849 object *args;
850{
851 if (!getnoarg(args))
852 return NULL;
Guido van Rossum7066dd71992-09-17 17:54:56 +0000853 if (setsid() < 0) {
Guido van Rossumc2670a01992-09-13 20:07:29 +0000854 err_errno(PosixError);
Guido van Rossum7066dd71992-09-17 17:54:56 +0000855 return NULL;
856 }
Guido van Rossumc2670a01992-09-13 20:07:29 +0000857 INCREF(None);
858 return None;
859}
860
861static object *
862posix_setpgid(self, args)
863 object *self;
864 object *args;
865{
866 int pid, pgrp;
867 if (!getargs(args, "(ii)", &pid, &pgrp))
868 return NULL;
Guido van Rossum7066dd71992-09-17 17:54:56 +0000869 if (setpgid(pid, pgrp) < 0) {
Guido van Rossumc2670a01992-09-13 20:07:29 +0000870 err_errno(PosixError);
Guido van Rossum7066dd71992-09-17 17:54:56 +0000871 return NULL;
872 }
Guido van Rossumc2670a01992-09-13 20:07:29 +0000873 INCREF(None);
874 return None;
875}
876
Guido van Rossum7066dd71992-09-17 17:54:56 +0000877static object *
878posix_tcgetpgrp(self, args)
879 object *self;
880 object *args;
881{
882 int fd, pgid;
883 if (!getargs(args, "i", &fd))
884 return NULL;
885 pgid = tcgetpgrp(fd);
886 if (pgid < 0) {
887 err_errno(PosixError);
888 return NULL;
889 }
890 return newintobject((long)pgid);
891}
892
893static object *
894posix_tcsetpgrp(self, args)
895 object *self;
896 object *args;
897{
898 int fd, pgid;
899 if (!getargs(args, "(ii)", &fd, &pgid))
900 return NULL;
901 if (tcsetpgrp(fd, pgid) < 0) {
902 err_errno(PosixError);
903 return NULL;
904 }
905 INCREF(None);
906 return None;
907}
908
Guido van Rossumc2670a01992-09-13 20:07:29 +0000909#endif /* DO_PG */
Guido van Rossum22db57e1992-04-05 14:25:30 +0000910
911
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000912static struct methodlist posix_methods[] = {
913 {"chdir", posix_chdir},
914 {"chmod", posix_chmod},
915 {"getcwd", posix_getcwd},
Guido van Rossum0ee42cd1991-04-08 21:01:03 +0000916#ifndef MSDOS
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000917 {"link", posix_link},
Guido van Rossum0ee42cd1991-04-08 21:01:03 +0000918#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000919 {"listdir", posix_listdir},
Guido van Rossumc39de5f1992-02-05 11:15:54 +0000920 {"lstat", posix_lstat},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000921 {"mkdir", posix_mkdir},
Guido van Rossumc39de5f1992-02-05 11:15:54 +0000922 {"readlink", posix_readlink},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000923 {"rename", posix_rename},
924 {"rmdir", posix_rmdir},
925 {"stat", posix_stat},
Guido van Rossumc39de5f1992-02-05 11:15:54 +0000926 {"symlink", posix_symlink},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000927 {"system", posix_system},
Guido van Rossum0ee42cd1991-04-08 21:01:03 +0000928#ifndef MSDOS
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000929 {"umask", posix_umask},
Guido van Rossum0ee42cd1991-04-08 21:01:03 +0000930#endif
Guido van Rossumc39de5f1992-02-05 11:15:54 +0000931#ifndef NO_UNAME
932 {"uname", posix_uname},
933#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000934 {"unlink", posix_unlink},
Guido van Rossum1ff6cb41991-04-08 20:59:13 +0000935 {"utime", posix_utime},
Guido van Rossum22db57e1992-04-05 14:25:30 +0000936#ifdef DO_TIMES
937 {"times", posix_times},
938#endif
Guido van Rossumc39de5f1992-02-05 11:15:54 +0000939
Guido van Rossum85e3b011991-06-03 12:42:10 +0000940#ifndef MSDOS
941 {"_exit", posix__exit},
942 {"exec", posix_exec},
943 {"fork", posix_fork},
Guido van Rossum46003ff1992-05-15 11:05:24 +0000944 {"getegid", posix_getegid},
945 {"geteuid", posix_geteuid},
946 {"getgid", posix_getgid},
Guido van Rossum85e3b011991-06-03 12:42:10 +0000947 {"getpid", posix_getpid},
Guido van Rossum04814471991-06-04 20:23:49 +0000948 {"getpgrp", posix_getpgrp},
Guido van Rossum85e3b011991-06-03 12:42:10 +0000949 {"getppid", posix_getppid},
Guido van Rossum46003ff1992-05-15 11:05:24 +0000950 {"getuid", posix_getuid},
Guido van Rossum85e3b011991-06-03 12:42:10 +0000951 {"kill", posix_kill},
Guido van Rossum3b066191991-06-04 19:40:25 +0000952 {"popen", posix_popen},
Guido van Rossumc2670a01992-09-13 20:07:29 +0000953 {"setpgrp", posix_setpgrp},
Guido van Rossum85e3b011991-06-03 12:42:10 +0000954 {"wait", posix_wait},
Guido van Rossum21803b81992-08-09 12:55:27 +0000955 {"waitpid", posix_waitpid},
Guido van Rossum85e3b011991-06-03 12:42:10 +0000956#endif
Guido van Rossumc39de5f1992-02-05 11:15:54 +0000957
Guido van Rossumc2670a01992-09-13 20:07:29 +0000958#ifdef DO_PG
959 {"setsid", posix_setsid},
960 {"setpgid", posix_setpgid},
Guido van Rossum7066dd71992-09-17 17:54:56 +0000961 {"tcgetpgrp", posix_tcgetpgrp},
962 {"tcsetpgrp", posix_tcsetpgrp},
Guido van Rossumc2670a01992-09-13 20:07:29 +0000963#endif
964
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000965 {NULL, NULL} /* Sentinel */
966};
967
968
969void
970initposix()
971{
972 object *m, *d, *v;
973
974 m = initmodule("posix", posix_methods);
975 d = getmoduledict(m);
976
977 /* Initialize posix.environ dictionary */
978 v = convertenviron();
979 if (v == NULL || dictinsert(d, "environ", v) != 0)
980 fatal("can't define posix.environ");
981 DECREF(v);
982
983 /* Initialize posix.error exception */
984 PosixError = newstringobject("posix.error");
985 if (PosixError == NULL || dictinsert(d, "error", PosixError) != 0)
986 fatal("can't define posix.error");
987}
Guido van Rossum0ee42cd1991-04-08 21:01:03 +0000988
Guido van Rossum3b066191991-06-04 19:40:25 +0000989
990/* Function used elsewhere to get a file's modification time */
991
992long
993getmtime(path)
994 char *path;
995{
996 struct stat st;
997 if (stat(path, &st) != 0)
998 return -1;
999 else
1000 return st.st_mtime;
1001}
1002
1003
Guido van Rossum0ee42cd1991-04-08 21:01:03 +00001004#ifdef MSDOS
1005
1006/* A small "compatibility library" for TurboC under MS-DOS */
1007
1008#include <sir.h>
1009#include <io.h>
1010#include <dos.h>
1011#include <fcntl.h>
1012
1013int
1014chmod(path, mode)
1015 char *path;
1016 int mode;
1017{
1018 return _chmod(path, 1, mode);
1019}
1020
1021int
1022utime(path, times)
1023 char *path;
1024 time_t times[2];
1025{
1026 struct date dt;
1027 struct time tm;
1028 struct ftime dft;
1029 int fh;
1030 unixtodos(tv[0].tv_sec,&dt,&tm);
1031 dft.ft_tsec = tm.ti_sec; dft.ft_min = tm.ti_min;
1032 dft.ft_hour = tm.ti_hour; dft.ft_day = dt.da_day;
1033 dft.ft_month = dt.da_mon;
1034 dft.ft_year = (dt.da_year - 1980); /* this is for TC library */
1035
Guido van Rossumef0a00e1992-01-27 16:51:30 +00001036 if ((fh = open(path,O_RDWR)) < 0)
Guido van Rossum0ee42cd1991-04-08 21:01:03 +00001037 return posix_error(); /* can't open file to set time */
1038 if (setftime(fh,&dft) < 0)
1039 {
1040 close(fh);
1041 return posix_error();
1042 }
1043 close(fh); /* close the temp handle */
1044}
1045
1046#endif /* MSDOS */