blob: 4e8440795f1cf2c924bebc0442540837f8b4ccfc [file] [log] [blame]
Guido van Rossumf70e43a1991-02-19 12:39:46 +00001/***********************************************************
Guido van Rossum775f4da1993-01-09 17:18:52 +00002Copyright 1991, 1992, 1993 by Stichting Mathematisch Centrum,
3Amsterdam, The Netherlands.
Guido van Rossumf70e43a1991-02-19 12:39:46 +00004
5 All Rights Reserved
6
7Permission to use, copy, modify, and distribute this software and its
8documentation for any purpose and without fee is hereby granted,
9provided that the above copyright notice appear in all copies and that
10both that copyright notice and this permission notice appear in
11supporting documentation, and that the names of Stichting Mathematisch
12Centrum or CWI not be used in advertising or publicity pertaining to
13distribution of the software without specific, written prior permission.
14
15STICHTING MATHEMATISCH CENTRUM DISCLAIMS ALL WARRANTIES WITH REGARD TO
16THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
17FITNESS, IN NO EVENT SHALL STICHTING MATHEMATISCH CENTRUM BE LIABLE
18FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
19WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
20ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
21OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
22
23******************************************************************/
24
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000025/* POSIX module implementation */
26
Guido van Rossum1ff6cb41991-04-08 20:59:13 +000027#ifdef AMOEBA
28#define NO_LSTAT
29#define SYSV
30#endif
31
Guido van Rossum0ee42cd1991-04-08 21:01:03 +000032#ifdef MSDOS
33#define NO_LSTAT
Guido van Rossumc39de5f1992-02-05 11:15:54 +000034#define NO_UNAME
Guido van Rossum0ee42cd1991-04-08 21:01:03 +000035#endif
36
Guido van Rossumc2670a01992-09-13 20:07:29 +000037#ifdef __sgi
38#define DO_PG
39#endif
40
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000041#include <signal.h>
42#include <string.h>
43#include <setjmp.h>
44#include <sys/types.h>
45#include <sys/stat.h>
Guido van Rossum0ee42cd1991-04-08 21:01:03 +000046
Guido van Rossum22db57e1992-04-05 14:25:30 +000047#ifdef DO_TIMES
48#include <sys/times.h>
49#include <sys/param.h>
50#include <errno.h>
51#endif
52
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000053#ifdef SYSV
Guido van Rossum0ee42cd1991-04-08 21:01:03 +000054
Guido van Rossum1ff6cb41991-04-08 20:59:13 +000055#define UTIME_STRUCT
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000056#include <dirent.h>
57#define direct dirent
Guido van Rossum1ff6cb41991-04-08 20:59:13 +000058#ifdef i386
59#define mode_t int
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000060#endif
Guido van Rossum0ee42cd1991-04-08 21:01:03 +000061
Guido van Rossum1ff6cb41991-04-08 20:59:13 +000062#else /* !SYSV */
Guido van Rossum0ee42cd1991-04-08 21:01:03 +000063
64#ifndef MSDOS
Guido van Rossum1ff6cb41991-04-08 20:59:13 +000065#include <sys/dir.h>
Guido van Rossum0ee42cd1991-04-08 21:01:03 +000066#endif
67
Guido van Rossum1ff6cb41991-04-08 20:59:13 +000068#endif /* !SYSV */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000069
Guido van Rossum50e61dc1992-03-27 17:22:31 +000070#ifndef NO_UNISTD
Guido van Rossum22db57e1992-04-05 14:25:30 +000071#include <unistd.h> /* Take this out and hope the best if it doesn't exist */
Guido van Rossum50e61dc1992-03-27 17:22:31 +000072#endif
73
Guido van Rossum3f5da241990-12-20 15:06:42 +000074#include "allobjects.h"
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000075#include "modsupport.h"
Guido van Rossumff4949e1992-08-05 19:58:53 +000076#include "ceval.h"
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000077
Guido van Rossum0b0db8e1993-01-21 16:07:51 +000078#ifdef _SEQUENT_
79#include <unistd.h>
80#else /* _SEQUENT_ */
Guido van Rossuma2b7f401993-01-04 09:09:59 +000081/* XXX Aren't these always declared in unistd.h? */
Guido van Rossum7f77e2d1990-10-30 13:34:38 +000082extern char *strerror PROTO((int));
Guido van Rossuma2b7f401993-01-04 09:09:59 +000083extern int chmod PROTO((const char *, mode_t));
84extern char *getcwd PROTO((char *, int)); /* XXX or size_t? */
85extern int mkdir PROTO((const char *, mode_t));
86extern int chdir PROTO((const char *));
87extern int link PROTO((const char *, const char *));
88extern int rename PROTO((const char *, const char *));
89extern int rmdir PROTO((const char *));
90extern int stat PROTO((const char *, struct stat *));
91extern int unlink PROTO((const char *));
92extern int pclose PROTO((FILE *));
Guido van Rossum0b0db8e1993-01-21 16:07:51 +000093#endif /* _SEQUENT_ */
Guido van Rossuma2b7f401993-01-04 09:09:59 +000094#ifdef NO_LSTAT
95#define lstat stat
96#else
97extern int lstat PROTO((const char *, struct stat *));
98extern int symlink PROTO((const char *, const char *));
99#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000100
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000101
102/* Return a dictionary corresponding to the POSIX environment table */
103
104extern char **environ;
105
106static object *
107convertenviron()
108{
109 object *d;
110 char **e;
111 d = newdictobject();
112 if (d == NULL)
113 return NULL;
114 if (environ == NULL)
115 return d;
116 /* XXX This part ignores errors */
117 for (e = environ; *e != NULL; e++) {
118 object *v;
119 char *p = strchr(*e, '=');
120 if (p == NULL)
121 continue;
122 v = newstringobject(p+1);
123 if (v == NULL)
124 continue;
125 *p = '\0';
126 (void) dictinsert(d, *e, v);
127 *p = '=';
128 DECREF(v);
129 }
130 return d;
131}
132
133
134static object *PosixError; /* Exception posix.error */
135
136/* Set a POSIX-specific error from errno, and return NULL */
137
Guido van Rossum9a1581c1990-10-21 13:12:47 +0000138static object *
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000139posix_error()
140{
Guido van Rossume8f305a1990-10-14 20:04:28 +0000141 return err_errno(PosixError);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000142}
143
144
145/* POSIX generic methods */
146
147static object *
148posix_1str(args, func)
149 object *args;
150 int (*func) FPROTO((const char *));
151{
Guido van Rossumef0a00e1992-01-27 16:51:30 +0000152 char *path1;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000153 int res;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000154 if (!getstrarg(args, &path1))
155 return NULL;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000156 BGN_SAVE
157 res = (*func)(path1);
158 END_SAVE
159 if (res < 0)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000160 return posix_error();
161 INCREF(None);
162 return None;
163}
164
165static object *
166posix_2str(args, func)
167 object *args;
168 int (*func) FPROTO((const char *, const char *));
169{
Guido van Rossumef0a00e1992-01-27 16:51:30 +0000170 char *path1, *path2;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000171 int res;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000172 if (!getstrstrarg(args, &path1, &path2))
173 return NULL;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000174 BGN_SAVE
175 res = (*func)(path1, path2);
176 END_SAVE
177 if (res < 0)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000178 return posix_error();
179 INCREF(None);
180 return None;
181}
182
183static object *
184posix_strint(args, func)
185 object *args;
186 int (*func) FPROTO((const char *, int));
187{
Guido van Rossumef0a00e1992-01-27 16:51:30 +0000188 char *path;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000189 int i;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000190 int res;
Guido van Rossumef0a00e1992-01-27 16:51:30 +0000191 if (!getstrintarg(args, &path, &i))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000192 return NULL;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000193 BGN_SAVE
194 res = (*func)(path, i);
195 END_SAVE
196 if (res < 0)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000197 return posix_error();
198 INCREF(None);
199 return None;
200}
201
202static object *
203posix_do_stat(self, args, statfunc)
204 object *self;
205 object *args;
206 int (*statfunc) FPROTO((const char *, struct stat *));
207{
208 struct stat st;
Guido van Rossumef0a00e1992-01-27 16:51:30 +0000209 char *path;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000210 object *v;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000211 int res;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000212 if (!getstrarg(args, &path))
213 return NULL;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000214 BGN_SAVE
215 res = (*statfunc)(path, &st);
216 END_SAVE
217 if (res != 0)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000218 return posix_error();
Guido van Rossume5372401993-03-16 12:15:04 +0000219 v = mkvalue("(llllllllll)",
220 (long)st.st_mode,
221 (long)st.st_ino,
222 (long)st.st_dev,
223 (long)st.st_nlink,
224 (long)st.st_uid,
225 (long)st.st_gid,
226 (long)st.st_size,
227 (long)st.st_atime,
228 (long)st.st_mtime,
229 (long)st.st_ctime);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000230}
231
232
233/* POSIX methods */
234
235static object *
236posix_chdir(self, args)
237 object *self;
238 object *args;
239{
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000240 return posix_1str(args, chdir);
241}
242
243static object *
244posix_chmod(self, args)
245 object *self;
246 object *args;
247{
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000248 return posix_strint(args, chmod);
249}
250
251static object *
252posix_getcwd(self, args)
253 object *self;
254 object *args;
255{
256 char buf[1026];
Guido van Rossumff4949e1992-08-05 19:58:53 +0000257 char *res;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000258 if (!getnoarg(args))
259 return NULL;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000260 BGN_SAVE
261 res = getcwd(buf, sizeof buf);
262 END_SAVE
263 if (res == NULL)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000264 return posix_error();
265 return newstringobject(buf);
266}
267
Guido van Rossum0ee42cd1991-04-08 21:01:03 +0000268#ifndef MSDOS
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000269static object *
270posix_link(self, args)
271 object *self;
272 object *args;
273{
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000274 return posix_2str(args, link);
275}
Guido van Rossum0ee42cd1991-04-08 21:01:03 +0000276#endif /* !MSDOS */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000277
278static object *
279posix_listdir(self, args)
280 object *self;
281 object *args;
282{
Guido van Rossumef0a00e1992-01-27 16:51:30 +0000283 char *name;
284 object *d, *v;
Guido van Rossum0ee42cd1991-04-08 21:01:03 +0000285
286#ifdef MSDOS
287 struct ffblk ep;
288 int rv;
289 if (!getstrarg(args, &name))
290 return NULL;
291
Guido van Rossumef0a00e1992-01-27 16:51:30 +0000292 if (findfirst(name, &ep, 0) == -1)
Guido van Rossum0ee42cd1991-04-08 21:01:03 +0000293 return posix_error();
294 if ((d = newlistobject(0)) == NULL)
295 return NULL;
296 do {
297 v = newstringobject(ep.ff_name);
298 if (v == NULL) {
299 DECREF(d);
300 d = NULL;
301 break;
302 }
303 if (addlistitem(d, v) != 0) {
304 DECREF(v);
305 DECREF(d);
306 d = NULL;
307 break;
308 }
309 DECREF(v);
310 } while ((rv = findnext(&ep)) == 0);
311#else /* !MSDOS */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000312 DIR *dirp;
313 struct direct *ep;
314 if (!getstrarg(args, &name))
315 return NULL;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000316 BGN_SAVE
317 if ((dirp = opendir(name)) == NULL) {
318 RET_SAVE
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000319 return posix_error();
Guido van Rossumff4949e1992-08-05 19:58:53 +0000320 }
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000321 if ((d = newlistobject(0)) == NULL) {
322 closedir(dirp);
Guido van Rossumff4949e1992-08-05 19:58:53 +0000323 RET_SAVE
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000324 return NULL;
325 }
326 while ((ep = readdir(dirp)) != NULL) {
327 v = newstringobject(ep->d_name);
328 if (v == NULL) {
329 DECREF(d);
330 d = NULL;
331 break;
332 }
333 if (addlistitem(d, v) != 0) {
334 DECREF(v);
335 DECREF(d);
336 d = NULL;
337 break;
338 }
339 DECREF(v);
340 }
341 closedir(dirp);
Guido van Rossumff4949e1992-08-05 19:58:53 +0000342 END_SAVE
Guido van Rossum0ee42cd1991-04-08 21:01:03 +0000343#endif /* !MSDOS */
344
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000345 return d;
346}
347
348static object *
349posix_mkdir(self, args)
350 object *self;
351 object *args;
352{
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000353 return posix_strint(args, mkdir);
354}
355
Guido van Rossum775f4da1993-01-09 17:18:52 +0000356#ifndef MSDOS
357static object *
358posix_nice(self, args)
359 object *self;
360 object *args;
361{
362 int increment, value;
363
364 if (!getargs(args, "i", &increment))
365 return NULL;
366 value = nice(increment);
367 if (value == -1)
368 return posix_error();
369 return newintobject((long) value);
370}
371#endif
372
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000373#if i386 && ! _SEQUENT_
Guido van Rossum1ff6cb41991-04-08 20:59:13 +0000374int
375rename(from, to)
376 char *from;
377 char *to;
378{
379 int status;
380 /* XXX Shouldn't this unlink the destination first? */
381 status = link(from, to);
382 if (status != 0)
383 return status;
384 return unlink(from);
385}
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000386#endif /* i386 && ! _SEQUENT_ */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +0000387
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000388static object *
389posix_rename(self, args)
390 object *self;
391 object *args;
392{
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000393 return posix_2str(args, rename);
394}
395
396static object *
397posix_rmdir(self, args)
398 object *self;
399 object *args;
400{
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000401 return posix_1str(args, rmdir);
402}
403
404static object *
405posix_stat(self, args)
406 object *self;
407 object *args;
408{
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000409 return posix_do_stat(self, args, stat);
410}
411
412static object *
413posix_system(self, args)
414 object *self;
415 object *args;
416{
Guido van Rossumef0a00e1992-01-27 16:51:30 +0000417 char *command;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000418 long sts;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000419 if (!getstrarg(args, &command))
420 return NULL;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000421 BGN_SAVE
Guido van Rossumef0a00e1992-01-27 16:51:30 +0000422 sts = system(command);
Guido van Rossumff4949e1992-08-05 19:58:53 +0000423 END_SAVE
424 return newintobject(sts);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000425}
426
Guido van Rossum0ee42cd1991-04-08 21:01:03 +0000427#ifndef MSDOS
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000428static object *
429posix_umask(self, args)
430 object *self;
431 object *args;
432{
433 int i;
434 if (!getintarg(args, &i))
435 return NULL;
436 i = umask(i);
437 if (i < 0)
438 return posix_error();
439 return newintobject((long)i);
440}
Guido van Rossum0ee42cd1991-04-08 21:01:03 +0000441#endif /* !MSDOS */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000442
443static object *
444posix_unlink(self, args)
445 object *self;
446 object *args;
447{
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000448 return posix_1str(args, unlink);
449}
450
Guido van Rossumc39de5f1992-02-05 11:15:54 +0000451#ifndef NO_UNAME
452#include <sys/utsname.h>
453
Guido van Rossuma2b7f401993-01-04 09:09:59 +0000454extern int uname PROTO((struct utsname *));
455
Guido van Rossumc39de5f1992-02-05 11:15:54 +0000456static object *
457posix_uname(self, args)
458 object *self;
459 object *args;
460{
Guido van Rossumc39de5f1992-02-05 11:15:54 +0000461 struct utsname u;
462 object *v;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000463 int res;
Guido van Rossum50e61dc1992-03-27 17:22:31 +0000464 if (!getnoarg(args))
465 return NULL;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000466 BGN_SAVE
467 res = uname(&u);
468 END_SAVE
469 if (res < 0)
Guido van Rossumc39de5f1992-02-05 11:15:54 +0000470 return posix_error();
Guido van Rossume5372401993-03-16 12:15:04 +0000471 return mkvalue("(sssss)",
472 u.sysname,
473 u.nodename,
474 u.release,
475 u.version,
476 u.machine);
Guido van Rossumc39de5f1992-02-05 11:15:54 +0000477}
478#endif /* NO_UNAME */
479
Guido van Rossum1ff6cb41991-04-08 20:59:13 +0000480#ifdef UTIME_STRUCT
481#include <utime.h>
482#endif
483
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000484static object *
Guido van Rossum1ff6cb41991-04-08 20:59:13 +0000485posix_utime(self, args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000486 object *self;
487 object *args;
488{
Guido van Rossumef0a00e1992-01-27 16:51:30 +0000489 char *path;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000490 int res;
Guido van Rossum1ff6cb41991-04-08 20:59:13 +0000491
492#ifdef UTIME_STRUCT
493 struct utimbuf buf;
494#define ATIME buf.actime
495#define MTIME buf.modtime
496#define UTIME_ARG &buf
497
498#else
499 time_t buf[2];
500#define ATIME buf[0]
501#define MTIME buf[1]
502#define UTIME_ARG buf
503#endif
504
Guido van Rossumef0a00e1992-01-27 16:51:30 +0000505 if (!getargs(args, "(s(ll))", &path, &ATIME, &MTIME))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000506 return NULL;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000507 BGN_SAVE
508 res = utime(path, UTIME_ARG);
509 END_SAVE
510 if (res < 0)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000511 return posix_error();
512 INCREF(None);
513 return None;
Guido van Rossum1ff6cb41991-04-08 20:59:13 +0000514#undef UTIME_ARG
515#undef ATIME
516#undef MTIME
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000517}
518
Guido van Rossum85e3b011991-06-03 12:42:10 +0000519
520#ifndef MSDOS
521
Guido van Rossum3b066191991-06-04 19:40:25 +0000522/* Process operations */
Guido van Rossum85e3b011991-06-03 12:42:10 +0000523
524static object *
525posix__exit(self, args)
526 object *self;
527 object *args;
528{
529 int sts;
530 if (!getintarg(args, &sts))
531 return NULL;
532 _exit(sts);
533 /* NOTREACHED */
534}
535
536/* XXX To do: exece, execp */
537
538static object *
539posix_exec(self, args)
540 object *self;
541 object *args;
542{
Guido van Rossumef0a00e1992-01-27 16:51:30 +0000543 char *path;
544 object *argv;
Guido van Rossum85e3b011991-06-03 12:42:10 +0000545 char **argvlist;
546 int i, argc;
547 object *(*getitem) PROTO((object *, int));
548
549 /* exec has two arguments: (path, argv), where
550 argv is a list or tuple of strings. */
551
Guido van Rossumef0a00e1992-01-27 16:51:30 +0000552 if (!getargs(args, "(sO)", &path, &argv))
Guido van Rossum85e3b011991-06-03 12:42:10 +0000553 return NULL;
Guido van Rossum85e3b011991-06-03 12:42:10 +0000554 if (is_listobject(argv)) {
555 argc = getlistsize(argv);
556 getitem = getlistitem;
557 }
558 else if (is_tupleobject(argv)) {
559 argc = gettuplesize(argv);
560 getitem = gettupleitem;
561 }
Guido van Rossumef0a00e1992-01-27 16:51:30 +0000562 else {
563 badarg:
564 err_badarg();
565 return NULL;
566 }
Guido van Rossum85e3b011991-06-03 12:42:10 +0000567
568 argvlist = NEW(char *, argc+1);
569 if (argvlist == NULL)
570 return NULL;
571 for (i = 0; i < argc; i++) {
Guido van Rossumef0a00e1992-01-27 16:51:30 +0000572 if (!getstrarg((*getitem)(argv, i), &argvlist[i])) {
Guido van Rossum85e3b011991-06-03 12:42:10 +0000573 DEL(argvlist);
574 goto badarg;
575 }
Guido van Rossum85e3b011991-06-03 12:42:10 +0000576 }
577 argvlist[argc] = NULL;
578
Guido van Rossumef0a00e1992-01-27 16:51:30 +0000579 execv(path, argvlist);
Guido van Rossum85e3b011991-06-03 12:42:10 +0000580
581 /* If we get here it's definitely an error */
582
583 DEL(argvlist);
584 return posix_error();
585}
586
587static object *
588posix_fork(self, args)
589 object *self;
590 object *args;
591{
592 int pid;
Guido van Rossum50e61dc1992-03-27 17:22:31 +0000593 if (!getnoarg(args))
594 return NULL;
Guido van Rossum85e3b011991-06-03 12:42:10 +0000595 pid = fork();
596 if (pid == -1)
597 return posix_error();
598 return newintobject((long)pid);
599}
600
601static object *
Guido van Rossum46003ff1992-05-15 11:05:24 +0000602posix_getegid(self, args)
603 object *self;
604 object *args;
605{
606 if (!getnoarg(args))
607 return NULL;
608 return newintobject((long)getegid());
609}
610
611static object *
612posix_geteuid(self, args)
613 object *self;
614 object *args;
615{
616 if (!getnoarg(args))
617 return NULL;
618 return newintobject((long)geteuid());
619}
620
621static object *
622posix_getgid(self, args)
623 object *self;
624 object *args;
625{
626 if (!getnoarg(args))
627 return NULL;
628 return newintobject((long)getgid());
629}
630
631static object *
Guido van Rossum85e3b011991-06-03 12:42:10 +0000632posix_getpid(self, args)
633 object *self;
634 object *args;
635{
Guido van Rossum04814471991-06-04 20:23:49 +0000636 if (!getnoarg(args))
Guido van Rossum85e3b011991-06-03 12:42:10 +0000637 return NULL;
638 return newintobject((long)getpid());
639}
640
641static object *
Guido van Rossum04814471991-06-04 20:23:49 +0000642posix_getpgrp(self, args)
643 object *self;
644 object *args;
645{
646 if (!getnoarg(args))
647 return NULL;
Guido van Rossum50e61dc1992-03-27 17:22:31 +0000648#ifdef SYSV
649 return newintobject((long)getpgrp());
650#else
Guido van Rossum971443b1991-06-07 13:59:29 +0000651 return newintobject((long)getpgrp(0));
Guido van Rossum50e61dc1992-03-27 17:22:31 +0000652#endif
Guido van Rossum04814471991-06-04 20:23:49 +0000653}
654
655static object *
Guido van Rossumc2670a01992-09-13 20:07:29 +0000656posix_setpgrp(self, args)
657 object *self;
658 object *args;
659{
660 if (!getnoarg(args))
661 return NULL;
662#ifdef SYSV
663 if (setpgrp() < 0)
664#else
665 if (setpgrp(0, 0) < 0)
666#endif
667 return err_errno(PosixError);
668 INCREF(None);
669 return None;
670}
671
672static object *
Guido van Rossum85e3b011991-06-03 12:42:10 +0000673posix_getppid(self, args)
674 object *self;
675 object *args;
676{
Guido van Rossum04814471991-06-04 20:23:49 +0000677 if (!getnoarg(args))
Guido van Rossum85e3b011991-06-03 12:42:10 +0000678 return NULL;
679 return newintobject((long)getppid());
680}
681
682static object *
Guido van Rossum46003ff1992-05-15 11:05:24 +0000683posix_getuid(self, args)
684 object *self;
685 object *args;
686{
687 if (!getnoarg(args))
688 return NULL;
689 return newintobject((long)getuid());
690}
691
692static object *
Guido van Rossum85e3b011991-06-03 12:42:10 +0000693posix_kill(self, args)
694 object *self;
695 object *args;
696{
697 int pid, sig;
698 if (!getintintarg(args, &pid, &sig))
699 return NULL;
700 if (kill(pid, sig) == -1)
701 return posix_error();
702 INCREF(None);
703 return None;
704}
705
706static object *
Guido van Rossum3b066191991-06-04 19:40:25 +0000707posix_popen(self, args)
708 object *self;
709 object *args;
710{
Guido van Rossumef0a00e1992-01-27 16:51:30 +0000711 char *name, *mode;
Guido van Rossum3b066191991-06-04 19:40:25 +0000712 FILE *fp;
Guido van Rossumef0a00e1992-01-27 16:51:30 +0000713 if (!getargs(args, "(ss)", &name, &mode))
Guido van Rossum3b066191991-06-04 19:40:25 +0000714 return NULL;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000715 BGN_SAVE
Guido van Rossumef0a00e1992-01-27 16:51:30 +0000716 fp = popen(name, mode);
Guido van Rossumff4949e1992-08-05 19:58:53 +0000717 END_SAVE
Guido van Rossum3b066191991-06-04 19:40:25 +0000718 if (fp == NULL)
719 return posix_error();
Guido van Rossume0d452d1991-07-27 21:41:01 +0000720 /* From now on, ignore SIGPIPE and let the error checking
721 do the work. */
722 (void) signal(SIGPIPE, SIG_IGN);
Guido van Rossumef0a00e1992-01-27 16:51:30 +0000723 return newopenfileobject(fp, name, mode, pclose);
Guido van Rossum3b066191991-06-04 19:40:25 +0000724}
725
726static object *
Guido van Rossum21803b81992-08-09 12:55:27 +0000727posix_waitpid(self, args)
Guido van Rossum85e3b011991-06-03 12:42:10 +0000728 object *self;
729 object *args;
730{
Guido van Rossum85e3b011991-06-03 12:42:10 +0000731#ifdef NO_WAITPID
Guido van Rossum21803b81992-08-09 12:55:27 +0000732 err_setstr(PosixError,
733 "posix.waitpid() not supported on this system");
734 return NULL;
Guido van Rossum85e3b011991-06-03 12:42:10 +0000735#else
Guido van Rossum21803b81992-08-09 12:55:27 +0000736 int pid, options, sts;
737 if (!getargs(args, "(ii)", &pid, &options))
738 return NULL;
739 BGN_SAVE
740 pid = waitpid(pid, &sts, options);
741 END_SAVE
Guido van Rossum85e3b011991-06-03 12:42:10 +0000742 if (pid == -1)
743 return posix_error();
Guido van Rossum21803b81992-08-09 12:55:27 +0000744 else
745 return mkvalue("ii", pid, sts);
746#endif
747}
748
749static object *
750posix_wait(self, args)
751 object *self;
752 object *args;
753{
754 int pid, sts;
755 if (args != NULL)
756 return posix_waitpid(self, args); /* BW compat */
757 BGN_SAVE
758 pid = wait(&sts);
759 END_SAVE
760 if (pid == -1)
761 return posix_error();
762 else
763 return mkvalue("ii", pid, sts);
Guido van Rossum85e3b011991-06-03 12:42:10 +0000764}
765
766#endif /* MSDOS */
767
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000768static object *
769posix_lstat(self, args)
770 object *self;
771 object *args;
772{
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000773 return posix_do_stat(self, args, lstat);
774}
775
776static object *
777posix_readlink(self, args)
778 object *self;
779 object *args;
780{
Guido van Rossumc39de5f1992-02-05 11:15:54 +0000781#ifdef NO_LSTAT
782 err_setstr(PosixError, "readlink not implemented on this system");
783 return NULL;
784#else
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000785 char buf[1024]; /* XXX Should use MAXPATHLEN */
Guido van Rossumef0a00e1992-01-27 16:51:30 +0000786 char *path;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000787 int n;
788 if (!getstrarg(args, &path))
789 return NULL;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000790 BGN_SAVE
Guido van Rossum50e61dc1992-03-27 17:22:31 +0000791 n = readlink(path, buf, (int) sizeof buf);
Guido van Rossumff4949e1992-08-05 19:58:53 +0000792 END_SAVE
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000793 if (n < 0)
794 return posix_error();
795 return newsizedstringobject(buf, n);
Guido van Rossumc39de5f1992-02-05 11:15:54 +0000796#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000797}
798
799static object *
800posix_symlink(self, args)
801 object *self;
802 object *args;
803{
Guido van Rossumc39de5f1992-02-05 11:15:54 +0000804#ifdef NO_LSTAT
805 err_setstr(PosixError, "symlink not implemented on this system");
806 return NULL;
807#else
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000808 return posix_2str(args, symlink);
Guido van Rossumc39de5f1992-02-05 11:15:54 +0000809#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000810}
811
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000812
Guido van Rossum22db57e1992-04-05 14:25:30 +0000813#ifdef DO_TIMES
814
815static object *
816posix_times(self, args)
817 object *self;
818 object *args;
819{
820 struct tms t;
821 clock_t c;
Guido van Rossum22db57e1992-04-05 14:25:30 +0000822 if (!getnoarg(args))
823 return NULL;
824 errno = 0;
825 c = times(&t);
826 if (c == (clock_t) -1) {
Guido van Rossum7066dd71992-09-17 17:54:56 +0000827 err_errno(PosixError);
Guido van Rossum22db57e1992-04-05 14:25:30 +0000828 return NULL;
829 }
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000830 return mkvalue("dddd",
831 (double)t.tms_utime / HZ,
832 (double)t.tms_stime / HZ,
833 (double)t.tms_cutime / HZ,
834 (double)t.tms_cstime / HZ);
Guido van Rossum22db57e1992-04-05 14:25:30 +0000835}
836
Guido van Rossumc2670a01992-09-13 20:07:29 +0000837#endif /* DO_TIMES */
838
839#ifdef DO_PG
840
841static object *
842posix_setsid(self, args)
843 object *self;
844 object *args;
845{
846 if (!getnoarg(args))
847 return NULL;
Guido van Rossum7066dd71992-09-17 17:54:56 +0000848 if (setsid() < 0) {
Guido van Rossumc2670a01992-09-13 20:07:29 +0000849 err_errno(PosixError);
Guido van Rossum7066dd71992-09-17 17:54:56 +0000850 return NULL;
851 }
Guido van Rossumc2670a01992-09-13 20:07:29 +0000852 INCREF(None);
853 return None;
854}
855
856static object *
857posix_setpgid(self, args)
858 object *self;
859 object *args;
860{
861 int pid, pgrp;
862 if (!getargs(args, "(ii)", &pid, &pgrp))
863 return NULL;
Guido van Rossum7066dd71992-09-17 17:54:56 +0000864 if (setpgid(pid, pgrp) < 0) {
Guido van Rossumc2670a01992-09-13 20:07:29 +0000865 err_errno(PosixError);
Guido van Rossum7066dd71992-09-17 17:54:56 +0000866 return NULL;
867 }
Guido van Rossumc2670a01992-09-13 20:07:29 +0000868 INCREF(None);
869 return None;
870}
871
Guido van Rossum7066dd71992-09-17 17:54:56 +0000872static object *
873posix_tcgetpgrp(self, args)
874 object *self;
875 object *args;
876{
877 int fd, pgid;
878 if (!getargs(args, "i", &fd))
879 return NULL;
880 pgid = tcgetpgrp(fd);
881 if (pgid < 0) {
882 err_errno(PosixError);
883 return NULL;
884 }
885 return newintobject((long)pgid);
886}
887
888static object *
889posix_tcsetpgrp(self, args)
890 object *self;
891 object *args;
892{
893 int fd, pgid;
894 if (!getargs(args, "(ii)", &fd, &pgid))
895 return NULL;
896 if (tcsetpgrp(fd, pgid) < 0) {
897 err_errno(PosixError);
898 return NULL;
899 }
900 INCREF(None);
901 return None;
902}
903
Guido van Rossumc2670a01992-09-13 20:07:29 +0000904#endif /* DO_PG */
Guido van Rossum22db57e1992-04-05 14:25:30 +0000905
906
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000907static struct methodlist posix_methods[] = {
908 {"chdir", posix_chdir},
909 {"chmod", posix_chmod},
910 {"getcwd", posix_getcwd},
Guido van Rossum0ee42cd1991-04-08 21:01:03 +0000911#ifndef MSDOS
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000912 {"link", posix_link},
Guido van Rossum0ee42cd1991-04-08 21:01:03 +0000913#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000914 {"listdir", posix_listdir},
Guido van Rossumc39de5f1992-02-05 11:15:54 +0000915 {"lstat", posix_lstat},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000916 {"mkdir", posix_mkdir},
Guido van Rossum775f4da1993-01-09 17:18:52 +0000917#ifndef MSDOS
918 {"nice", posix_nice},
919#endif
Guido van Rossumc39de5f1992-02-05 11:15:54 +0000920 {"readlink", posix_readlink},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000921 {"rename", posix_rename},
922 {"rmdir", posix_rmdir},
923 {"stat", posix_stat},
Guido van Rossumc39de5f1992-02-05 11:15:54 +0000924 {"symlink", posix_symlink},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000925 {"system", posix_system},
Guido van Rossum0ee42cd1991-04-08 21:01:03 +0000926#ifndef MSDOS
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000927 {"umask", posix_umask},
Guido van Rossum0ee42cd1991-04-08 21:01:03 +0000928#endif
Guido van Rossumc39de5f1992-02-05 11:15:54 +0000929#ifndef NO_UNAME
930 {"uname", posix_uname},
931#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000932 {"unlink", posix_unlink},
Guido van Rossum1ff6cb41991-04-08 20:59:13 +0000933 {"utime", posix_utime},
Guido van Rossum22db57e1992-04-05 14:25:30 +0000934#ifdef DO_TIMES
935 {"times", posix_times},
936#endif
Guido van Rossumc39de5f1992-02-05 11:15:54 +0000937
Guido van Rossum85e3b011991-06-03 12:42:10 +0000938#ifndef MSDOS
939 {"_exit", posix__exit},
940 {"exec", posix_exec},
941 {"fork", posix_fork},
Guido van Rossum46003ff1992-05-15 11:05:24 +0000942 {"getegid", posix_getegid},
943 {"geteuid", posix_geteuid},
944 {"getgid", posix_getgid},
Guido van Rossum85e3b011991-06-03 12:42:10 +0000945 {"getpid", posix_getpid},
Guido van Rossum04814471991-06-04 20:23:49 +0000946 {"getpgrp", posix_getpgrp},
Guido van Rossum85e3b011991-06-03 12:42:10 +0000947 {"getppid", posix_getppid},
Guido van Rossum46003ff1992-05-15 11:05:24 +0000948 {"getuid", posix_getuid},
Guido van Rossum85e3b011991-06-03 12:42:10 +0000949 {"kill", posix_kill},
Guido van Rossum3b066191991-06-04 19:40:25 +0000950 {"popen", posix_popen},
Guido van Rossumc2670a01992-09-13 20:07:29 +0000951 {"setpgrp", posix_setpgrp},
Guido van Rossum85e3b011991-06-03 12:42:10 +0000952 {"wait", posix_wait},
Guido van Rossum21803b81992-08-09 12:55:27 +0000953 {"waitpid", posix_waitpid},
Guido van Rossum85e3b011991-06-03 12:42:10 +0000954#endif
Guido van Rossumc39de5f1992-02-05 11:15:54 +0000955
Guido van Rossumc2670a01992-09-13 20:07:29 +0000956#ifdef DO_PG
957 {"setsid", posix_setsid},
958 {"setpgid", posix_setpgid},
Guido van Rossum7066dd71992-09-17 17:54:56 +0000959 {"tcgetpgrp", posix_tcgetpgrp},
960 {"tcsetpgrp", posix_tcsetpgrp},
Guido van Rossumc2670a01992-09-13 20:07:29 +0000961#endif
962
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000963 {NULL, NULL} /* Sentinel */
964};
965
966
967void
968initposix()
969{
970 object *m, *d, *v;
971
972 m = initmodule("posix", posix_methods);
973 d = getmoduledict(m);
974
975 /* Initialize posix.environ dictionary */
976 v = convertenviron();
977 if (v == NULL || dictinsert(d, "environ", v) != 0)
978 fatal("can't define posix.environ");
979 DECREF(v);
980
981 /* Initialize posix.error exception */
982 PosixError = newstringobject("posix.error");
983 if (PosixError == NULL || dictinsert(d, "error", PosixError) != 0)
984 fatal("can't define posix.error");
985}
Guido van Rossum0ee42cd1991-04-08 21:01:03 +0000986
Guido van Rossum3b066191991-06-04 19:40:25 +0000987
988/* Function used elsewhere to get a file's modification time */
989
990long
991getmtime(path)
992 char *path;
993{
994 struct stat st;
995 if (stat(path, &st) != 0)
996 return -1;
997 else
998 return st.st_mtime;
999}
1000
1001
Guido van Rossum0ee42cd1991-04-08 21:01:03 +00001002#ifdef MSDOS
1003
1004/* A small "compatibility library" for TurboC under MS-DOS */
1005
1006#include <sir.h>
1007#include <io.h>
1008#include <dos.h>
1009#include <fcntl.h>
1010
1011int
1012chmod(path, mode)
1013 char *path;
1014 int mode;
1015{
1016 return _chmod(path, 1, mode);
1017}
1018
1019int
1020utime(path, times)
1021 char *path;
1022 time_t times[2];
1023{
1024 struct date dt;
1025 struct time tm;
1026 struct ftime dft;
1027 int fh;
1028 unixtodos(tv[0].tv_sec,&dt,&tm);
1029 dft.ft_tsec = tm.ti_sec; dft.ft_min = tm.ti_min;
1030 dft.ft_hour = tm.ti_hour; dft.ft_day = dt.da_day;
1031 dft.ft_month = dt.da_mon;
1032 dft.ft_year = (dt.da_year - 1980); /* this is for TC library */
1033
Guido van Rossumef0a00e1992-01-27 16:51:30 +00001034 if ((fh = open(path,O_RDWR)) < 0)
Guido van Rossum0ee42cd1991-04-08 21:01:03 +00001035 return posix_error(); /* can't open file to set time */
1036 if (setftime(fh,&dft) < 0)
1037 {
1038 close(fh);
1039 return posix_error();
1040 }
1041 close(fh); /* close the temp handle */
1042}
1043
1044#endif /* MSDOS */