blob: 95e590722bb199e00b8f73d2e1221a7f6afcd21a [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 Rossum85a5fbb1990-10-14 12:07:46 +000037#include <signal.h>
38#include <string.h>
39#include <setjmp.h>
40#include <sys/types.h>
41#include <sys/stat.h>
Guido van Rossum0ee42cd1991-04-08 21:01:03 +000042
Guido van Rossum22db57e1992-04-05 14:25:30 +000043#ifdef DO_TIMES
44#include <sys/times.h>
45#include <sys/param.h>
46#include <errno.h>
47#endif
48
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000049#ifdef SYSV
Guido van Rossum0ee42cd1991-04-08 21:01:03 +000050
Guido van Rossum1ff6cb41991-04-08 20:59:13 +000051#define UTIME_STRUCT
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000052#include <dirent.h>
53#define direct dirent
Guido van Rossum1ff6cb41991-04-08 20:59:13 +000054#ifdef i386
55#define mode_t int
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000056#endif
Guido van Rossum0ee42cd1991-04-08 21:01:03 +000057
Guido van Rossum1ff6cb41991-04-08 20:59:13 +000058#else /* !SYSV */
Guido van Rossum0ee42cd1991-04-08 21:01:03 +000059
60#ifndef MSDOS
Guido van Rossum1ff6cb41991-04-08 20:59:13 +000061#include <sys/dir.h>
Guido van Rossum0ee42cd1991-04-08 21:01:03 +000062#endif
63
Guido van Rossum1ff6cb41991-04-08 20:59:13 +000064#endif /* !SYSV */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000065
Guido van Rossum50e61dc1992-03-27 17:22:31 +000066#ifndef NO_UNISTD
Guido van Rossum22db57e1992-04-05 14:25:30 +000067#include <unistd.h> /* Take this out and hope the best if it doesn't exist */
Guido van Rossum50e61dc1992-03-27 17:22:31 +000068#endif
69
Guido van Rossum3f5da241990-12-20 15:06:42 +000070#include "allobjects.h"
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000071#include "modsupport.h"
Guido van Rossumff4949e1992-08-05 19:58:53 +000072#include "ceval.h"
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000073
Guido van Rossum7f77e2d1990-10-30 13:34:38 +000074extern char *strerror PROTO((int));
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000075
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000076
77/* Return a dictionary corresponding to the POSIX environment table */
78
79extern char **environ;
80
81static object *
82convertenviron()
83{
84 object *d;
85 char **e;
86 d = newdictobject();
87 if (d == NULL)
88 return NULL;
89 if (environ == NULL)
90 return d;
91 /* XXX This part ignores errors */
92 for (e = environ; *e != NULL; e++) {
93 object *v;
94 char *p = strchr(*e, '=');
95 if (p == NULL)
96 continue;
97 v = newstringobject(p+1);
98 if (v == NULL)
99 continue;
100 *p = '\0';
101 (void) dictinsert(d, *e, v);
102 *p = '=';
103 DECREF(v);
104 }
105 return d;
106}
107
108
109static object *PosixError; /* Exception posix.error */
110
111/* Set a POSIX-specific error from errno, and return NULL */
112
Guido van Rossum9a1581c1990-10-21 13:12:47 +0000113static object *
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000114posix_error()
115{
Guido van Rossume8f305a1990-10-14 20:04:28 +0000116 return err_errno(PosixError);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000117}
118
119
120/* POSIX generic methods */
121
122static object *
123posix_1str(args, func)
124 object *args;
125 int (*func) FPROTO((const char *));
126{
Guido van Rossumef0a00e1992-01-27 16:51:30 +0000127 char *path1;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000128 int res;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000129 if (!getstrarg(args, &path1))
130 return NULL;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000131 BGN_SAVE
132 res = (*func)(path1);
133 END_SAVE
134 if (res < 0)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000135 return posix_error();
136 INCREF(None);
137 return None;
138}
139
140static object *
141posix_2str(args, func)
142 object *args;
143 int (*func) FPROTO((const char *, const char *));
144{
Guido van Rossumef0a00e1992-01-27 16:51:30 +0000145 char *path1, *path2;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000146 int res;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000147 if (!getstrstrarg(args, &path1, &path2))
148 return NULL;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000149 BGN_SAVE
150 res = (*func)(path1, path2);
151 END_SAVE
152 if (res < 0)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000153 return posix_error();
154 INCREF(None);
155 return None;
156}
157
158static object *
159posix_strint(args, func)
160 object *args;
161 int (*func) FPROTO((const char *, int));
162{
Guido van Rossumef0a00e1992-01-27 16:51:30 +0000163 char *path;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000164 int i;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000165 int res;
Guido van Rossumef0a00e1992-01-27 16:51:30 +0000166 if (!getstrintarg(args, &path, &i))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000167 return NULL;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000168 BGN_SAVE
169 res = (*func)(path, i);
170 END_SAVE
171 if (res < 0)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000172 return posix_error();
173 INCREF(None);
174 return None;
175}
176
177static object *
178posix_do_stat(self, args, statfunc)
179 object *self;
180 object *args;
181 int (*statfunc) FPROTO((const char *, struct stat *));
182{
183 struct stat st;
Guido van Rossumef0a00e1992-01-27 16:51:30 +0000184 char *path;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000185 object *v;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000186 int res;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000187 if (!getstrarg(args, &path))
188 return NULL;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000189 BGN_SAVE
190 res = (*statfunc)(path, &st);
191 END_SAVE
192 if (res != 0)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000193 return posix_error();
194 v = newtupleobject(10);
195 if (v == NULL)
196 return NULL;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000197#define SET(i, st_member) settupleitem(v, i, newintobject((long)st.st_member))
198 SET(0, st_mode);
199 SET(1, st_ino);
200 SET(2, st_dev);
201 SET(3, st_nlink);
202 SET(4, st_uid);
203 SET(5, st_gid);
204 SET(6, st_size);
205 SET(7, st_atime);
206 SET(8, st_mtime);
207 SET(9, st_ctime);
208#undef SET
Guido van Rossum3f5da241990-12-20 15:06:42 +0000209 if (err_occurred()) {
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000210 DECREF(v);
Guido van Rossum3f5da241990-12-20 15:06:42 +0000211 return NULL;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000212 }
213 return v;
214}
215
216
217/* POSIX methods */
218
219static object *
220posix_chdir(self, args)
221 object *self;
222 object *args;
223{
224 extern int chdir PROTO((const char *));
225 return posix_1str(args, chdir);
226}
227
228static object *
229posix_chmod(self, args)
230 object *self;
231 object *args;
232{
233 extern int chmod PROTO((const char *, mode_t));
234 return posix_strint(args, chmod);
235}
236
237static object *
238posix_getcwd(self, args)
239 object *self;
240 object *args;
241{
242 char buf[1026];
Guido van Rossumff4949e1992-08-05 19:58:53 +0000243 char *res;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000244 extern char *getcwd PROTO((char *, int));
245 if (!getnoarg(args))
246 return NULL;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000247 BGN_SAVE
248 res = getcwd(buf, sizeof buf);
249 END_SAVE
250 if (res == NULL)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000251 return posix_error();
252 return newstringobject(buf);
253}
254
Guido van Rossum0ee42cd1991-04-08 21:01:03 +0000255#ifndef MSDOS
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000256static object *
257posix_link(self, args)
258 object *self;
259 object *args;
260{
261 extern int link PROTO((const char *, const char *));
262 return posix_2str(args, link);
263}
Guido van Rossum0ee42cd1991-04-08 21:01:03 +0000264#endif /* !MSDOS */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000265
266static object *
267posix_listdir(self, args)
268 object *self;
269 object *args;
270{
Guido van Rossumef0a00e1992-01-27 16:51:30 +0000271 char *name;
272 object *d, *v;
Guido van Rossum0ee42cd1991-04-08 21:01:03 +0000273
274#ifdef MSDOS
275 struct ffblk ep;
276 int rv;
277 if (!getstrarg(args, &name))
278 return NULL;
279
Guido van Rossumef0a00e1992-01-27 16:51:30 +0000280 if (findfirst(name, &ep, 0) == -1)
Guido van Rossum0ee42cd1991-04-08 21:01:03 +0000281 return posix_error();
282 if ((d = newlistobject(0)) == NULL)
283 return NULL;
284 do {
285 v = newstringobject(ep.ff_name);
286 if (v == NULL) {
287 DECREF(d);
288 d = NULL;
289 break;
290 }
291 if (addlistitem(d, v) != 0) {
292 DECREF(v);
293 DECREF(d);
294 d = NULL;
295 break;
296 }
297 DECREF(v);
298 } while ((rv = findnext(&ep)) == 0);
299#else /* !MSDOS */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000300 DIR *dirp;
301 struct direct *ep;
302 if (!getstrarg(args, &name))
303 return NULL;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000304 BGN_SAVE
305 if ((dirp = opendir(name)) == NULL) {
306 RET_SAVE
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000307 return posix_error();
Guido van Rossumff4949e1992-08-05 19:58:53 +0000308 }
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000309 if ((d = newlistobject(0)) == NULL) {
310 closedir(dirp);
Guido van Rossumff4949e1992-08-05 19:58:53 +0000311 RET_SAVE
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000312 return NULL;
313 }
314 while ((ep = readdir(dirp)) != NULL) {
315 v = newstringobject(ep->d_name);
316 if (v == NULL) {
317 DECREF(d);
318 d = NULL;
319 break;
320 }
321 if (addlistitem(d, v) != 0) {
322 DECREF(v);
323 DECREF(d);
324 d = NULL;
325 break;
326 }
327 DECREF(v);
328 }
329 closedir(dirp);
Guido van Rossumff4949e1992-08-05 19:58:53 +0000330 END_SAVE
Guido van Rossum0ee42cd1991-04-08 21:01:03 +0000331#endif /* !MSDOS */
332
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000333 return d;
334}
335
336static object *
337posix_mkdir(self, args)
338 object *self;
339 object *args;
340{
341 extern int mkdir PROTO((const char *, mode_t));
342 return posix_strint(args, mkdir);
343}
344
Guido van Rossum1ff6cb41991-04-08 20:59:13 +0000345#ifdef i386
346int
347rename(from, to)
348 char *from;
349 char *to;
350{
351 int status;
352 /* XXX Shouldn't this unlink the destination first? */
353 status = link(from, to);
354 if (status != 0)
355 return status;
356 return unlink(from);
357}
Guido van Rossum0ee42cd1991-04-08 21:01:03 +0000358#endif /* i386 */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +0000359
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000360static object *
361posix_rename(self, args)
362 object *self;
363 object *args;
364{
365 extern int rename PROTO((const char *, const char *));
366 return posix_2str(args, rename);
367}
368
369static object *
370posix_rmdir(self, args)
371 object *self;
372 object *args;
373{
374 extern int rmdir PROTO((const char *));
375 return posix_1str(args, rmdir);
376}
377
378static object *
379posix_stat(self, args)
380 object *self;
381 object *args;
382{
383 extern int stat PROTO((const char *, struct stat *));
384 return posix_do_stat(self, args, stat);
385}
386
387static object *
388posix_system(self, args)
389 object *self;
390 object *args;
391{
Guido van Rossumef0a00e1992-01-27 16:51:30 +0000392 char *command;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000393 long sts;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000394 if (!getstrarg(args, &command))
395 return NULL;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000396 BGN_SAVE
Guido van Rossumef0a00e1992-01-27 16:51:30 +0000397 sts = system(command);
Guido van Rossumff4949e1992-08-05 19:58:53 +0000398 END_SAVE
399 return newintobject(sts);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000400}
401
Guido van Rossum0ee42cd1991-04-08 21:01:03 +0000402#ifndef MSDOS
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000403static object *
404posix_umask(self, args)
405 object *self;
406 object *args;
407{
408 int i;
409 if (!getintarg(args, &i))
410 return NULL;
411 i = umask(i);
412 if (i < 0)
413 return posix_error();
414 return newintobject((long)i);
415}
Guido van Rossum0ee42cd1991-04-08 21:01:03 +0000416#endif /* !MSDOS */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000417
418static object *
419posix_unlink(self, args)
420 object *self;
421 object *args;
422{
423 extern int unlink PROTO((const char *));
424 return posix_1str(args, unlink);
425}
426
Guido van Rossumc39de5f1992-02-05 11:15:54 +0000427#ifndef NO_UNAME
428#include <sys/utsname.h>
429
430static object *
431posix_uname(self, args)
432 object *self;
433 object *args;
434{
435 extern int uname PROTO((struct utsname *));
436 struct utsname u;
437 object *v;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000438 int res;
Guido van Rossum50e61dc1992-03-27 17:22:31 +0000439 if (!getnoarg(args))
440 return NULL;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000441 BGN_SAVE
442 res = uname(&u);
443 END_SAVE
444 if (res < 0)
Guido van Rossumc39de5f1992-02-05 11:15:54 +0000445 return posix_error();
446 v = newtupleobject(5);
447 if (v == NULL)
448 return NULL;
449#define SET(i, member) settupleitem(v, i, newstringobject(u.member))
450 SET(0, sysname);
451 SET(1, nodename);
452 SET(2, release);
453 SET(3, version);
454 SET(4, machine);
455#undef SET
456 if (err_occurred()) {
457 DECREF(v);
458 return NULL;
459 }
460 return v;
461}
462#endif /* NO_UNAME */
463
Guido van Rossum1ff6cb41991-04-08 20:59:13 +0000464#ifdef UTIME_STRUCT
465#include <utime.h>
466#endif
467
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000468static object *
Guido van Rossum1ff6cb41991-04-08 20:59:13 +0000469posix_utime(self, args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000470 object *self;
471 object *args;
472{
Guido van Rossumef0a00e1992-01-27 16:51:30 +0000473 char *path;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000474 int res;
Guido van Rossum1ff6cb41991-04-08 20:59:13 +0000475
476#ifdef UTIME_STRUCT
477 struct utimbuf buf;
478#define ATIME buf.actime
479#define MTIME buf.modtime
480#define UTIME_ARG &buf
481
482#else
483 time_t buf[2];
484#define ATIME buf[0]
485#define MTIME buf[1]
486#define UTIME_ARG buf
487#endif
488
Guido van Rossumef0a00e1992-01-27 16:51:30 +0000489 if (!getargs(args, "(s(ll))", &path, &ATIME, &MTIME))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000490 return NULL;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000491 BGN_SAVE
492 res = utime(path, UTIME_ARG);
493 END_SAVE
494 if (res < 0)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000495 return posix_error();
496 INCREF(None);
497 return None;
Guido van Rossum1ff6cb41991-04-08 20:59:13 +0000498#undef UTIME_ARG
499#undef ATIME
500#undef MTIME
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000501}
502
Guido van Rossum85e3b011991-06-03 12:42:10 +0000503
504#ifndef MSDOS
505
Guido van Rossum3b066191991-06-04 19:40:25 +0000506/* Process operations */
Guido van Rossum85e3b011991-06-03 12:42:10 +0000507
508static object *
509posix__exit(self, args)
510 object *self;
511 object *args;
512{
513 int sts;
514 if (!getintarg(args, &sts))
515 return NULL;
516 _exit(sts);
517 /* NOTREACHED */
518}
519
520/* XXX To do: exece, execp */
521
522static object *
523posix_exec(self, args)
524 object *self;
525 object *args;
526{
Guido van Rossumef0a00e1992-01-27 16:51:30 +0000527 char *path;
528 object *argv;
Guido van Rossum85e3b011991-06-03 12:42:10 +0000529 char **argvlist;
530 int i, argc;
531 object *(*getitem) PROTO((object *, int));
532
533 /* exec has two arguments: (path, argv), where
534 argv is a list or tuple of strings. */
535
Guido van Rossumef0a00e1992-01-27 16:51:30 +0000536 if (!getargs(args, "(sO)", &path, &argv))
Guido van Rossum85e3b011991-06-03 12:42:10 +0000537 return NULL;
Guido van Rossum85e3b011991-06-03 12:42:10 +0000538 if (is_listobject(argv)) {
539 argc = getlistsize(argv);
540 getitem = getlistitem;
541 }
542 else if (is_tupleobject(argv)) {
543 argc = gettuplesize(argv);
544 getitem = gettupleitem;
545 }
Guido van Rossumef0a00e1992-01-27 16:51:30 +0000546 else {
547 badarg:
548 err_badarg();
549 return NULL;
550 }
Guido van Rossum85e3b011991-06-03 12:42:10 +0000551
552 argvlist = NEW(char *, argc+1);
553 if (argvlist == NULL)
554 return NULL;
555 for (i = 0; i < argc; i++) {
Guido van Rossumef0a00e1992-01-27 16:51:30 +0000556 if (!getstrarg((*getitem)(argv, i), &argvlist[i])) {
Guido van Rossum85e3b011991-06-03 12:42:10 +0000557 DEL(argvlist);
558 goto badarg;
559 }
Guido van Rossum85e3b011991-06-03 12:42:10 +0000560 }
561 argvlist[argc] = NULL;
562
Guido van Rossumef0a00e1992-01-27 16:51:30 +0000563 execv(path, argvlist);
Guido van Rossum85e3b011991-06-03 12:42:10 +0000564
565 /* If we get here it's definitely an error */
566
567 DEL(argvlist);
568 return posix_error();
569}
570
571static object *
572posix_fork(self, args)
573 object *self;
574 object *args;
575{
576 int pid;
Guido van Rossum50e61dc1992-03-27 17:22:31 +0000577 if (!getnoarg(args))
578 return NULL;
Guido van Rossum85e3b011991-06-03 12:42:10 +0000579 pid = fork();
580 if (pid == -1)
581 return posix_error();
582 return newintobject((long)pid);
583}
584
585static object *
Guido van Rossum46003ff1992-05-15 11:05:24 +0000586posix_getegid(self, args)
587 object *self;
588 object *args;
589{
590 if (!getnoarg(args))
591 return NULL;
592 return newintobject((long)getegid());
593}
594
595static object *
596posix_geteuid(self, args)
597 object *self;
598 object *args;
599{
600 if (!getnoarg(args))
601 return NULL;
602 return newintobject((long)geteuid());
603}
604
605static object *
606posix_getgid(self, args)
607 object *self;
608 object *args;
609{
610 if (!getnoarg(args))
611 return NULL;
612 return newintobject((long)getgid());
613}
614
615static object *
Guido van Rossum85e3b011991-06-03 12:42:10 +0000616posix_getpid(self, args)
617 object *self;
618 object *args;
619{
Guido van Rossum04814471991-06-04 20:23:49 +0000620 if (!getnoarg(args))
Guido van Rossum85e3b011991-06-03 12:42:10 +0000621 return NULL;
622 return newintobject((long)getpid());
623}
624
625static object *
Guido van Rossum04814471991-06-04 20:23:49 +0000626posix_getpgrp(self, args)
627 object *self;
628 object *args;
629{
630 if (!getnoarg(args))
631 return NULL;
Guido van Rossum50e61dc1992-03-27 17:22:31 +0000632#ifdef SYSV
633 return newintobject((long)getpgrp());
634#else
Guido van Rossum971443b1991-06-07 13:59:29 +0000635 return newintobject((long)getpgrp(0));
Guido van Rossum50e61dc1992-03-27 17:22:31 +0000636#endif
Guido van Rossum04814471991-06-04 20:23:49 +0000637}
638
639static object *
Guido van Rossum85e3b011991-06-03 12:42:10 +0000640posix_getppid(self, args)
641 object *self;
642 object *args;
643{
Guido van Rossum04814471991-06-04 20:23:49 +0000644 if (!getnoarg(args))
Guido van Rossum85e3b011991-06-03 12:42:10 +0000645 return NULL;
646 return newintobject((long)getppid());
647}
648
649static object *
Guido van Rossum46003ff1992-05-15 11:05:24 +0000650posix_getuid(self, args)
651 object *self;
652 object *args;
653{
654 if (!getnoarg(args))
655 return NULL;
656 return newintobject((long)getuid());
657}
658
659static object *
Guido van Rossum85e3b011991-06-03 12:42:10 +0000660posix_kill(self, args)
661 object *self;
662 object *args;
663{
664 int pid, sig;
665 if (!getintintarg(args, &pid, &sig))
666 return NULL;
667 if (kill(pid, sig) == -1)
668 return posix_error();
669 INCREF(None);
670 return None;
671}
672
673static object *
Guido van Rossum3b066191991-06-04 19:40:25 +0000674posix_popen(self, args)
675 object *self;
676 object *args;
677{
678 extern int pclose PROTO((FILE *));
Guido van Rossumef0a00e1992-01-27 16:51:30 +0000679 char *name, *mode;
Guido van Rossum3b066191991-06-04 19:40:25 +0000680 FILE *fp;
Guido van Rossumef0a00e1992-01-27 16:51:30 +0000681 if (!getargs(args, "(ss)", &name, &mode))
Guido van Rossum3b066191991-06-04 19:40:25 +0000682 return NULL;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000683 BGN_SAVE
Guido van Rossumef0a00e1992-01-27 16:51:30 +0000684 fp = popen(name, mode);
Guido van Rossumff4949e1992-08-05 19:58:53 +0000685 END_SAVE
Guido van Rossum3b066191991-06-04 19:40:25 +0000686 if (fp == NULL)
687 return posix_error();
Guido van Rossume0d452d1991-07-27 21:41:01 +0000688 /* From now on, ignore SIGPIPE and let the error checking
689 do the work. */
690 (void) signal(SIGPIPE, SIG_IGN);
Guido van Rossumef0a00e1992-01-27 16:51:30 +0000691 return newopenfileobject(fp, name, mode, pclose);
Guido van Rossum3b066191991-06-04 19:40:25 +0000692}
693
694static object *
Guido van Rossum21803b81992-08-09 12:55:27 +0000695posix_waitpid(self, args)
Guido van Rossum85e3b011991-06-03 12:42:10 +0000696 object *self;
697 object *args;
698{
Guido van Rossum85e3b011991-06-03 12:42:10 +0000699#ifdef NO_WAITPID
Guido van Rossum21803b81992-08-09 12:55:27 +0000700 err_setstr(PosixError,
701 "posix.waitpid() not supported on this system");
702 return NULL;
Guido van Rossum85e3b011991-06-03 12:42:10 +0000703#else
Guido van Rossum21803b81992-08-09 12:55:27 +0000704 int pid, options, sts;
705 if (!getargs(args, "(ii)", &pid, &options))
706 return NULL;
707 BGN_SAVE
708 pid = waitpid(pid, &sts, options);
709 END_SAVE
Guido van Rossum85e3b011991-06-03 12:42:10 +0000710 if (pid == -1)
711 return posix_error();
Guido van Rossum21803b81992-08-09 12:55:27 +0000712 else
713 return mkvalue("ii", pid, sts);
714#endif
715}
716
717static object *
718posix_wait(self, args)
719 object *self;
720 object *args;
721{
722 int pid, sts;
723 if (args != NULL)
724 return posix_waitpid(self, args); /* BW compat */
725 BGN_SAVE
726 pid = wait(&sts);
727 END_SAVE
728 if (pid == -1)
729 return posix_error();
730 else
731 return mkvalue("ii", pid, sts);
Guido van Rossum85e3b011991-06-03 12:42:10 +0000732}
733
734#endif /* MSDOS */
735
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000736static object *
737posix_lstat(self, args)
738 object *self;
739 object *args;
740{
Guido van Rossumc39de5f1992-02-05 11:15:54 +0000741#ifdef NO_LSTAT
742#define lstat stat
743#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000744 extern int lstat PROTO((const char *, struct stat *));
745 return posix_do_stat(self, args, lstat);
746}
747
748static object *
749posix_readlink(self, args)
750 object *self;
751 object *args;
752{
Guido van Rossumc39de5f1992-02-05 11:15:54 +0000753#ifdef NO_LSTAT
754 err_setstr(PosixError, "readlink not implemented on this system");
755 return NULL;
756#else
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000757 char buf[1024]; /* XXX Should use MAXPATHLEN */
Guido van Rossumef0a00e1992-01-27 16:51:30 +0000758 char *path;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000759 int n;
760 if (!getstrarg(args, &path))
761 return NULL;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000762 BGN_SAVE
Guido van Rossum50e61dc1992-03-27 17:22:31 +0000763 n = readlink(path, buf, (int) sizeof buf);
Guido van Rossumff4949e1992-08-05 19:58:53 +0000764 END_SAVE
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000765 if (n < 0)
766 return posix_error();
767 return newsizedstringobject(buf, n);
Guido van Rossumc39de5f1992-02-05 11:15:54 +0000768#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000769}
770
771static object *
772posix_symlink(self, args)
773 object *self;
774 object *args;
775{
Guido van Rossumc39de5f1992-02-05 11:15:54 +0000776#ifdef NO_LSTAT
777 err_setstr(PosixError, "symlink not implemented on this system");
778 return NULL;
779#else
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000780 extern int symlink PROTO((const char *, const char *));
781 return posix_2str(args, symlink);
Guido van Rossumc39de5f1992-02-05 11:15:54 +0000782#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000783}
784
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000785
Guido van Rossum22db57e1992-04-05 14:25:30 +0000786#ifdef DO_TIMES
787
788static object *
789posix_times(self, args)
790 object *self;
791 object *args;
792{
793 struct tms t;
794 clock_t c;
795 object *tuple;
796 if (!getnoarg(args))
797 return NULL;
798 errno = 0;
799 c = times(&t);
800 if (c == (clock_t) -1) {
801 err_errno(IOError);
802 return NULL;
803 }
804 tuple = newtupleobject(4);
805 if (tuple == NULL)
806 return NULL;
807 settupleitem(tuple, 0, newfloatobject((double)t.tms_utime / HZ));
808 settupleitem(tuple, 1, newfloatobject((double)t.tms_stime / HZ));
809 settupleitem(tuple, 2, newfloatobject((double)t.tms_cutime / HZ));
810 settupleitem(tuple, 3, newfloatobject((double)t.tms_cstime / HZ));
811 if (err_occurred()) {
812 DECREF(tuple);
813 return NULL;
814 }
815 return tuple;
816}
817
818#endif
819
820
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000821static struct methodlist posix_methods[] = {
822 {"chdir", posix_chdir},
823 {"chmod", posix_chmod},
824 {"getcwd", posix_getcwd},
Guido van Rossum0ee42cd1991-04-08 21:01:03 +0000825#ifndef MSDOS
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000826 {"link", posix_link},
Guido van Rossum0ee42cd1991-04-08 21:01:03 +0000827#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000828 {"listdir", posix_listdir},
Guido van Rossumc39de5f1992-02-05 11:15:54 +0000829 {"lstat", posix_lstat},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000830 {"mkdir", posix_mkdir},
Guido van Rossumc39de5f1992-02-05 11:15:54 +0000831 {"readlink", posix_readlink},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000832 {"rename", posix_rename},
833 {"rmdir", posix_rmdir},
834 {"stat", posix_stat},
Guido van Rossumc39de5f1992-02-05 11:15:54 +0000835 {"symlink", posix_symlink},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000836 {"system", posix_system},
Guido van Rossum0ee42cd1991-04-08 21:01:03 +0000837#ifndef MSDOS
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000838 {"umask", posix_umask},
Guido van Rossum0ee42cd1991-04-08 21:01:03 +0000839#endif
Guido van Rossumc39de5f1992-02-05 11:15:54 +0000840#ifndef NO_UNAME
841 {"uname", posix_uname},
842#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000843 {"unlink", posix_unlink},
Guido van Rossum1ff6cb41991-04-08 20:59:13 +0000844 {"utime", posix_utime},
Guido van Rossum22db57e1992-04-05 14:25:30 +0000845#ifdef DO_TIMES
846 {"times", posix_times},
847#endif
Guido van Rossumc39de5f1992-02-05 11:15:54 +0000848
Guido van Rossum85e3b011991-06-03 12:42:10 +0000849#ifndef MSDOS
850 {"_exit", posix__exit},
851 {"exec", posix_exec},
852 {"fork", posix_fork},
Guido van Rossum46003ff1992-05-15 11:05:24 +0000853 {"getegid", posix_getegid},
854 {"geteuid", posix_geteuid},
855 {"getgid", posix_getgid},
Guido van Rossum85e3b011991-06-03 12:42:10 +0000856 {"getpid", posix_getpid},
Guido van Rossum04814471991-06-04 20:23:49 +0000857 {"getpgrp", posix_getpgrp},
Guido van Rossum85e3b011991-06-03 12:42:10 +0000858 {"getppid", posix_getppid},
Guido van Rossum46003ff1992-05-15 11:05:24 +0000859 {"getuid", posix_getuid},
Guido van Rossum85e3b011991-06-03 12:42:10 +0000860 {"kill", posix_kill},
Guido van Rossum3b066191991-06-04 19:40:25 +0000861 {"popen", posix_popen},
Guido van Rossum85e3b011991-06-03 12:42:10 +0000862 {"wait", posix_wait},
Guido van Rossum21803b81992-08-09 12:55:27 +0000863 {"waitpid", posix_waitpid},
Guido van Rossum85e3b011991-06-03 12:42:10 +0000864#endif
Guido van Rossumc39de5f1992-02-05 11:15:54 +0000865
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000866 {NULL, NULL} /* Sentinel */
867};
868
869
870void
871initposix()
872{
873 object *m, *d, *v;
874
875 m = initmodule("posix", posix_methods);
876 d = getmoduledict(m);
877
878 /* Initialize posix.environ dictionary */
879 v = convertenviron();
880 if (v == NULL || dictinsert(d, "environ", v) != 0)
881 fatal("can't define posix.environ");
882 DECREF(v);
883
884 /* Initialize posix.error exception */
885 PosixError = newstringobject("posix.error");
886 if (PosixError == NULL || dictinsert(d, "error", PosixError) != 0)
887 fatal("can't define posix.error");
888}
Guido van Rossum0ee42cd1991-04-08 21:01:03 +0000889
Guido van Rossum3b066191991-06-04 19:40:25 +0000890
891/* Function used elsewhere to get a file's modification time */
892
893long
894getmtime(path)
895 char *path;
896{
897 struct stat st;
898 if (stat(path, &st) != 0)
899 return -1;
900 else
901 return st.st_mtime;
902}
903
904
Guido van Rossum0ee42cd1991-04-08 21:01:03 +0000905#ifdef MSDOS
906
907/* A small "compatibility library" for TurboC under MS-DOS */
908
909#include <sir.h>
910#include <io.h>
911#include <dos.h>
912#include <fcntl.h>
913
914int
915chmod(path, mode)
916 char *path;
917 int mode;
918{
919 return _chmod(path, 1, mode);
920}
921
922int
923utime(path, times)
924 char *path;
925 time_t times[2];
926{
927 struct date dt;
928 struct time tm;
929 struct ftime dft;
930 int fh;
931 unixtodos(tv[0].tv_sec,&dt,&tm);
932 dft.ft_tsec = tm.ti_sec; dft.ft_min = tm.ti_min;
933 dft.ft_hour = tm.ti_hour; dft.ft_day = dt.da_day;
934 dft.ft_month = dt.da_mon;
935 dft.ft_year = (dt.da_year - 1980); /* this is for TC library */
936
Guido van Rossumef0a00e1992-01-27 16:51:30 +0000937 if ((fh = open(path,O_RDWR)) < 0)
Guido van Rossum0ee42cd1991-04-08 21:01:03 +0000938 return posix_error(); /* can't open file to set time */
939 if (setftime(fh,&dft) < 0)
940 {
941 close(fh);
942 return posix_error();
943 }
944 close(fh); /* close the temp handle */
945}
946
947#endif /* MSDOS */