blob: b82e492f12836c30fb6fa51118aab51b611fae7e [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 Rossume22e6441993-07-09 10:51:31 +000035#include <dos.h>
Guido van Rossum0ee42cd1991-04-08 21:01:03 +000036#endif
37
Guido van Rossumc2670a01992-09-13 20:07:29 +000038#ifdef __sgi
39#define DO_PG
40#endif
41
Guido van Rossumc70b61f1993-11-01 16:23:18 +000042#ifdef _NEXT_SOURCE
43#define mode_t int
44#define NO_UNAME
45#endif
46
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000047#include <signal.h>
48#include <string.h>
49#include <setjmp.h>
50#include <sys/types.h>
51#include <sys/stat.h>
Guido van Rossum0ee42cd1991-04-08 21:01:03 +000052
Guido van Rossum22db57e1992-04-05 14:25:30 +000053#ifdef DO_TIMES
54#include <sys/times.h>
55#include <sys/param.h>
56#include <errno.h>
57#endif
58
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000059#ifdef SYSV
Guido van Rossum0ee42cd1991-04-08 21:01:03 +000060
Guido van Rossumb376a4a1993-11-23 17:53:17 +000061#define UTIME_STRUCT 1
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000062#include <dirent.h>
63#define direct dirent
Guido van Rossum1ff6cb41991-04-08 20:59:13 +000064#ifdef i386
65#define mode_t int
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000066#endif
Guido van Rossum0ee42cd1991-04-08 21:01:03 +000067
Guido van Rossum1ff6cb41991-04-08 20:59:13 +000068#else /* !SYSV */
Guido van Rossum0ee42cd1991-04-08 21:01:03 +000069
70#ifndef MSDOS
Guido van Rossum1ff6cb41991-04-08 20:59:13 +000071#include <sys/dir.h>
Guido van Rossum0ee42cd1991-04-08 21:01:03 +000072#endif
73
Guido van Rossum1ff6cb41991-04-08 20:59:13 +000074#endif /* !SYSV */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000075
Guido van Rossum50e61dc1992-03-27 17:22:31 +000076#ifndef NO_UNISTD
Guido van Rossum22db57e1992-04-05 14:25:30 +000077#include <unistd.h> /* Take this out and hope the best if it doesn't exist */
Guido van Rossum50e61dc1992-03-27 17:22:31 +000078#endif
79
Guido van Rossum3f5da241990-12-20 15:06:42 +000080#include "allobjects.h"
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000081#include "modsupport.h"
Guido van Rossumff4949e1992-08-05 19:58:53 +000082#include "ceval.h"
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000083
Guido van Rossum0b0db8e1993-01-21 16:07:51 +000084#ifdef _SEQUENT_
85#include <unistd.h>
86#else /* _SEQUENT_ */
Guido van Rossuma2b7f401993-01-04 09:09:59 +000087/* XXX Aren't these always declared in unistd.h? */
Guido van Rossuma2b7f401993-01-04 09:09:59 +000088extern int mkdir PROTO((const char *, mode_t));
89extern int chdir PROTO((const char *));
Guido van Rossume22e6441993-07-09 10:51:31 +000090extern int rmdir PROTO((const char *));
91extern int chmod PROTO((const char *, mode_t));
Guido van Rossumb376a4a1993-11-23 17:53:17 +000092extern char *getcwd(); /* No PROTO((char *, int)) -- non portable */
Guido van Rossuma3309961993-07-28 09:05:47 +000093#ifndef MSDOS
Guido van Rossume22e6441993-07-09 10:51:31 +000094extern char *strerror PROTO((int));
Guido van Rossuma2b7f401993-01-04 09:09:59 +000095extern int link PROTO((const char *, const char *));
96extern int rename PROTO((const char *, const char *));
Guido van Rossuma2b7f401993-01-04 09:09:59 +000097extern int stat PROTO((const char *, struct stat *));
98extern int unlink PROTO((const char *));
99extern int pclose PROTO((FILE *));
Guido van Rossuma3309961993-07-28 09:05:47 +0000100#endif /* !MSDOS */
101#endif /* !_SEQUENT_ */
Guido van Rossuma2b7f401993-01-04 09:09:59 +0000102#ifdef NO_LSTAT
103#define lstat stat
104#else
105extern int lstat PROTO((const char *, struct stat *));
106extern int symlink PROTO((const char *, const char *));
107#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000108
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000109
110/* Return a dictionary corresponding to the POSIX environment table */
111
112extern char **environ;
113
114static object *
115convertenviron()
116{
117 object *d;
118 char **e;
119 d = newdictobject();
120 if (d == NULL)
121 return NULL;
122 if (environ == NULL)
123 return d;
124 /* XXX This part ignores errors */
125 for (e = environ; *e != NULL; e++) {
126 object *v;
127 char *p = strchr(*e, '=');
128 if (p == NULL)
129 continue;
130 v = newstringobject(p+1);
131 if (v == NULL)
132 continue;
133 *p = '\0';
134 (void) dictinsert(d, *e, v);
135 *p = '=';
136 DECREF(v);
137 }
138 return d;
139}
140
141
142static object *PosixError; /* Exception posix.error */
143
144/* Set a POSIX-specific error from errno, and return NULL */
145
Guido van Rossum687dd131993-05-17 08:34:16 +0000146static object * posix_error() { return err_errno(PosixError);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000147}
148
149
150/* POSIX generic methods */
151
152static object *
153posix_1str(args, func)
154 object *args;
155 int (*func) FPROTO((const char *));
156{
Guido van Rossumef0a00e1992-01-27 16:51:30 +0000157 char *path1;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000158 int res;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +0000159 if (!getargs(args, "s", &path1))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000160 return NULL;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000161 BGN_SAVE
162 res = (*func)(path1);
163 END_SAVE
164 if (res < 0)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000165 return posix_error();
166 INCREF(None);
167 return None;
168}
169
170static object *
171posix_2str(args, func)
172 object *args;
173 int (*func) FPROTO((const char *, const char *));
174{
Guido van Rossumef0a00e1992-01-27 16:51:30 +0000175 char *path1, *path2;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000176 int res;
Guido van Rossum234f9421993-06-17 12:35:49 +0000177 if (!getargs(args, "(ss)", &path1, &path2))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000178 return NULL;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000179 BGN_SAVE
180 res = (*func)(path1, path2);
181 END_SAVE
182 if (res < 0)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000183 return posix_error();
184 INCREF(None);
185 return None;
186}
187
188static object *
189posix_strint(args, func)
190 object *args;
191 int (*func) FPROTO((const char *, int));
192{
Guido van Rossumef0a00e1992-01-27 16:51:30 +0000193 char *path;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000194 int i;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000195 int res;
Guido van Rossum234f9421993-06-17 12:35:49 +0000196 if (!getargs(args, "(si)", &path, &i))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000197 return NULL;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000198 BGN_SAVE
199 res = (*func)(path, i);
200 END_SAVE
201 if (res < 0)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000202 return posix_error();
203 INCREF(None);
204 return None;
205}
206
207static object *
208posix_do_stat(self, args, statfunc)
209 object *self;
210 object *args;
211 int (*statfunc) FPROTO((const char *, struct stat *));
212{
213 struct stat st;
Guido van Rossumef0a00e1992-01-27 16:51:30 +0000214 char *path;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000215 int res;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +0000216 if (!getargs(args, "s", &path))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000217 return NULL;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000218 BGN_SAVE
219 res = (*statfunc)(path, &st);
220 END_SAVE
221 if (res != 0)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000222 return posix_error();
Guido van Rossum687dd131993-05-17 08:34:16 +0000223 return mkvalue("(llllllllll)",
Guido van Rossume5372401993-03-16 12:15:04 +0000224 (long)st.st_mode,
225 (long)st.st_ino,
226 (long)st.st_dev,
227 (long)st.st_nlink,
228 (long)st.st_uid,
229 (long)st.st_gid,
230 (long)st.st_size,
231 (long)st.st_atime,
232 (long)st.st_mtime,
233 (long)st.st_ctime);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000234}
235
236
237/* POSIX methods */
238
239static object *
240posix_chdir(self, args)
241 object *self;
242 object *args;
243{
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000244 return posix_1str(args, chdir);
245}
246
247static object *
248posix_chmod(self, args)
249 object *self;
250 object *args;
251{
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000252 return posix_strint(args, chmod);
253}
254
255static object *
256posix_getcwd(self, args)
257 object *self;
258 object *args;
259{
260 char buf[1026];
Guido van Rossumff4949e1992-08-05 19:58:53 +0000261 char *res;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000262 if (!getnoarg(args))
263 return NULL;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000264 BGN_SAVE
265 res = getcwd(buf, sizeof buf);
266 END_SAVE
267 if (res == NULL)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000268 return posix_error();
269 return newstringobject(buf);
270}
271
Guido van Rossum0ee42cd1991-04-08 21:01:03 +0000272#ifndef MSDOS
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000273static object *
274posix_link(self, args)
275 object *self;
276 object *args;
277{
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000278 return posix_2str(args, link);
279}
Guido van Rossum0ee42cd1991-04-08 21:01:03 +0000280#endif /* !MSDOS */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000281
282static object *
283posix_listdir(self, args)
284 object *self;
285 object *args;
286{
Guido van Rossumef0a00e1992-01-27 16:51:30 +0000287 char *name;
288 object *d, *v;
Guido van Rossum0ee42cd1991-04-08 21:01:03 +0000289
Guido van Rossume22e6441993-07-09 10:51:31 +0000290#ifdef TURBO_C
Guido van Rossum0ee42cd1991-04-08 21:01:03 +0000291 struct ffblk ep;
292 int rv;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +0000293 if (!getargs(args, "s", &name))
Guido van Rossum0ee42cd1991-04-08 21:01:03 +0000294 return NULL;
295
Guido van Rossumef0a00e1992-01-27 16:51:30 +0000296 if (findfirst(name, &ep, 0) == -1)
Guido van Rossum0ee42cd1991-04-08 21:01:03 +0000297 return posix_error();
298 if ((d = newlistobject(0)) == NULL)
299 return NULL;
300 do {
301 v = newstringobject(ep.ff_name);
302 if (v == NULL) {
303 DECREF(d);
304 d = NULL;
305 break;
306 }
307 if (addlistitem(d, v) != 0) {
308 DECREF(v);
309 DECREF(d);
310 d = NULL;
311 break;
312 }
313 DECREF(v);
314 } while ((rv = findnext(&ep)) == 0);
Guido van Rossume22e6441993-07-09 10:51:31 +0000315#endif /* TURBO_C */
316#ifdef MSDOS
317 struct find_t ep;
318 int rv;
319 char _name[100];
320 int attrib;
321 int num= 0;
322
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +0000323 if (!getargs(args, "s", &name))
Guido van Rossume22e6441993-07-09 10:51:31 +0000324 return NULL;
325 strcpy( _name, name );
326
327again:
328 if ((d = newlistobject(0)) == NULL)
329 return NULL;
330
331 if( _name[strlen( _name )-1]=='/' )
332 strcat( _name, "*.*" );
333
334 if (_dos_findfirst(_name, _A_NORMAL|_A_SUBDIR, &ep) == -1)
335 return posix_error();
336 attrib= ep.attrib;
337 do {
338 v = newstringobject(ep.name);
339 if (v == NULL) {
340 DECREF(d);
341 d = NULL;
342 break;
343 }
344 if (addlistitem(d, v) != 0) {
345 DECREF(v);
346 DECREF(d);
347 d = NULL;
348 break;
349 }
350 num++;
351 DECREF(v);
352 } while ((rv = _dos_findnext(&ep)) == 0);
353
354 if( attrib&_A_SUBDIR && num==1 )
355 {
356 DECREF( d );
357 strcat( _name, "/*.*" );
Guido van Rossum06191531993-10-26 15:22:37 +0000358 /* This comment is here to help the DEC alpha OSF/1 cpp
359 (which scans for comments but not for strings in
360 code that is #ifdef'ed out...) */
Guido van Rossume22e6441993-07-09 10:51:31 +0000361 goto again;
362 }
363
364#endif /* MSDOS */
365#ifdef unix
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000366 DIR *dirp;
367 struct direct *ep;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +0000368 if (!getargs(args, "s", &name))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000369 return NULL;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000370 BGN_SAVE
371 if ((dirp = opendir(name)) == NULL) {
372 RET_SAVE
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000373 return posix_error();
Guido van Rossumff4949e1992-08-05 19:58:53 +0000374 }
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000375 if ((d = newlistobject(0)) == NULL) {
376 closedir(dirp);
Guido van Rossumff4949e1992-08-05 19:58:53 +0000377 RET_SAVE
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000378 return NULL;
379 }
380 while ((ep = readdir(dirp)) != NULL) {
381 v = newstringobject(ep->d_name);
382 if (v == NULL) {
383 DECREF(d);
384 d = NULL;
385 break;
386 }
387 if (addlistitem(d, v) != 0) {
388 DECREF(v);
389 DECREF(d);
390 d = NULL;
391 break;
392 }
393 DECREF(v);
394 }
395 closedir(dirp);
Guido van Rossumff4949e1992-08-05 19:58:53 +0000396 END_SAVE
Guido van Rossume22e6441993-07-09 10:51:31 +0000397#endif /* unix */
Guido van Rossum0ee42cd1991-04-08 21:01:03 +0000398
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000399 return d;
400}
401
402static object *
403posix_mkdir(self, args)
404 object *self;
405 object *args;
406{
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000407 return posix_strint(args, mkdir);
408}
409
Guido van Rossum775f4da1993-01-09 17:18:52 +0000410#ifndef MSDOS
411static object *
412posix_nice(self, args)
413 object *self;
414 object *args;
415{
416 int increment, value;
417
418 if (!getargs(args, "i", &increment))
419 return NULL;
420 value = nice(increment);
421 if (value == -1)
422 return posix_error();
423 return newintobject((long) value);
424}
425#endif
426
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000427#if i386 && ! _SEQUENT_
Guido van Rossum1ff6cb41991-04-08 20:59:13 +0000428int
429rename(from, to)
430 char *from;
431 char *to;
432{
433 int status;
434 /* XXX Shouldn't this unlink the destination first? */
435 status = link(from, to);
436 if (status != 0)
437 return status;
438 return unlink(from);
439}
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000440#endif /* i386 && ! _SEQUENT_ */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +0000441
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000442static object *
443posix_rename(self, args)
444 object *self;
445 object *args;
446{
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000447 return posix_2str(args, rename);
448}
449
450static object *
451posix_rmdir(self, args)
452 object *self;
453 object *args;
454{
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000455 return posix_1str(args, rmdir);
456}
457
458static object *
459posix_stat(self, args)
460 object *self;
461 object *args;
462{
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000463 return posix_do_stat(self, args, stat);
464}
465
466static object *
467posix_system(self, args)
468 object *self;
469 object *args;
470{
Guido van Rossumef0a00e1992-01-27 16:51:30 +0000471 char *command;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000472 long sts;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +0000473 if (!getargs(args, "s", &command))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000474 return NULL;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000475 BGN_SAVE
Guido van Rossumef0a00e1992-01-27 16:51:30 +0000476 sts = system(command);
Guido van Rossumff4949e1992-08-05 19:58:53 +0000477 END_SAVE
478 return newintobject(sts);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000479}
480
Guido van Rossum0ee42cd1991-04-08 21:01:03 +0000481#ifndef MSDOS
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000482static object *
483posix_umask(self, args)
484 object *self;
485 object *args;
486{
487 int i;
488 if (!getintarg(args, &i))
489 return NULL;
490 i = umask(i);
491 if (i < 0)
492 return posix_error();
493 return newintobject((long)i);
494}
Guido van Rossum0ee42cd1991-04-08 21:01:03 +0000495#endif /* !MSDOS */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000496
497static object *
498posix_unlink(self, args)
499 object *self;
500 object *args;
501{
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000502 return posix_1str(args, unlink);
503}
504
Guido van Rossumc39de5f1992-02-05 11:15:54 +0000505#ifndef NO_UNAME
506#include <sys/utsname.h>
507
Guido van Rossuma2b7f401993-01-04 09:09:59 +0000508extern int uname PROTO((struct utsname *));
509
Guido van Rossumc39de5f1992-02-05 11:15:54 +0000510static object *
511posix_uname(self, args)
512 object *self;
513 object *args;
514{
Guido van Rossumc39de5f1992-02-05 11:15:54 +0000515 struct utsname u;
516 object *v;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000517 int res;
Guido van Rossum50e61dc1992-03-27 17:22:31 +0000518 if (!getnoarg(args))
519 return NULL;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000520 BGN_SAVE
521 res = uname(&u);
522 END_SAVE
523 if (res < 0)
Guido van Rossumc39de5f1992-02-05 11:15:54 +0000524 return posix_error();
Guido van Rossume5372401993-03-16 12:15:04 +0000525 return mkvalue("(sssss)",
526 u.sysname,
527 u.nodename,
528 u.release,
529 u.version,
530 u.machine);
Guido van Rossumc39de5f1992-02-05 11:15:54 +0000531}
532#endif /* NO_UNAME */
533
Guido van Rossum1ff6cb41991-04-08 20:59:13 +0000534#ifdef UTIME_STRUCT
535#include <utime.h>
536#endif
537
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000538static object *
Guido van Rossum1ff6cb41991-04-08 20:59:13 +0000539posix_utime(self, args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000540 object *self;
541 object *args;
542{
Guido van Rossumef0a00e1992-01-27 16:51:30 +0000543 char *path;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000544 int res;
Guido van Rossum1ff6cb41991-04-08 20:59:13 +0000545
546#ifdef UTIME_STRUCT
547 struct utimbuf buf;
548#define ATIME buf.actime
549#define MTIME buf.modtime
550#define UTIME_ARG &buf
551
552#else
553 time_t buf[2];
554#define ATIME buf[0]
555#define MTIME buf[1]
556#define UTIME_ARG buf
557#endif
558
Guido van Rossumef0a00e1992-01-27 16:51:30 +0000559 if (!getargs(args, "(s(ll))", &path, &ATIME, &MTIME))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000560 return NULL;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000561 BGN_SAVE
562 res = utime(path, UTIME_ARG);
563 END_SAVE
564 if (res < 0)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000565 return posix_error();
566 INCREF(None);
567 return None;
Guido van Rossum1ff6cb41991-04-08 20:59:13 +0000568#undef UTIME_ARG
569#undef ATIME
570#undef MTIME
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000571}
572
Guido van Rossum85e3b011991-06-03 12:42:10 +0000573
574#ifndef MSDOS
575
Guido van Rossum3b066191991-06-04 19:40:25 +0000576/* Process operations */
Guido van Rossum85e3b011991-06-03 12:42:10 +0000577
578static object *
579posix__exit(self, args)
580 object *self;
581 object *args;
582{
583 int sts;
584 if (!getintarg(args, &sts))
585 return NULL;
586 _exit(sts);
587 /* NOTREACHED */
588}
589
Guido van Rossum85e3b011991-06-03 12:42:10 +0000590static object *
Guido van Rossum89b33251993-10-22 14:26:06 +0000591posix_execv(self, args)
Guido van Rossum85e3b011991-06-03 12:42:10 +0000592 object *self;
593 object *args;
594{
Guido van Rossumef0a00e1992-01-27 16:51:30 +0000595 char *path;
596 object *argv;
Guido van Rossum85e3b011991-06-03 12:42:10 +0000597 char **argvlist;
598 int i, argc;
599 object *(*getitem) PROTO((object *, int));
600
Guido van Rossum89b33251993-10-22 14:26:06 +0000601 /* execv has two arguments: (path, argv), where
Guido van Rossum85e3b011991-06-03 12:42:10 +0000602 argv is a list or tuple of strings. */
603
Guido van Rossumef0a00e1992-01-27 16:51:30 +0000604 if (!getargs(args, "(sO)", &path, &argv))
Guido van Rossum85e3b011991-06-03 12:42:10 +0000605 return NULL;
Guido van Rossum85e3b011991-06-03 12:42:10 +0000606 if (is_listobject(argv)) {
607 argc = getlistsize(argv);
608 getitem = getlistitem;
609 }
610 else if (is_tupleobject(argv)) {
611 argc = gettuplesize(argv);
612 getitem = gettupleitem;
613 }
Guido van Rossumef0a00e1992-01-27 16:51:30 +0000614 else {
615 badarg:
616 err_badarg();
617 return NULL;
618 }
Guido van Rossum85e3b011991-06-03 12:42:10 +0000619
620 argvlist = NEW(char *, argc+1);
621 if (argvlist == NULL)
622 return NULL;
623 for (i = 0; i < argc; i++) {
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +0000624 if (!getargs((*getitem)(argv, i), "s", &argvlist[i])) {
Guido van Rossum85e3b011991-06-03 12:42:10 +0000625 DEL(argvlist);
626 goto badarg;
627 }
Guido van Rossum85e3b011991-06-03 12:42:10 +0000628 }
629 argvlist[argc] = NULL;
630
Guido van Rossumef0a00e1992-01-27 16:51:30 +0000631 execv(path, argvlist);
Guido van Rossum85e3b011991-06-03 12:42:10 +0000632
633 /* If we get here it's definitely an error */
634
635 DEL(argvlist);
636 return posix_error();
637}
638
639static object *
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +0000640posix_execve(self, args)
641 object *self;
642 object *args;
643{
644 char *path;
645 object *argv, *env;
646 char **argvlist;
647 char **envlist;
648 object *key, *val;
649 int i, pos, argc, envc;
650 object *(*getitem) PROTO((object *, int));
651
652 /* execve has three arguments: (path, argv, env), where
653 argv is a list or tuple of strings and env is a dictionary
654 like posix.environ. */
655
656 if (!getargs(args, "(sOO)", &path, &argv, &env))
657 return NULL;
658 if (is_listobject(argv)) {
659 argc = getlistsize(argv);
660 getitem = getlistitem;
661 }
662 else if (is_tupleobject(argv)) {
663 argc = gettuplesize(argv);
664 getitem = gettupleitem;
665 }
666 else {
667 err_setstr(TypeError, "argv must be tuple or list");
668 return NULL;
669 }
670 if (!is_dictobject(env)) {
671 err_setstr(TypeError, "env must be dictionary");
672 return NULL;
673 }
674
675 argvlist = NEW(char *, argc+1);
676 if (argvlist == NULL) {
677 err_nomem();
678 return NULL;
679 }
680 for (i = 0; i < argc; i++) {
681 if (!getargs((*getitem)(argv, i),
682 "s;argv must be list of strings",
683 &argvlist[i])) {
684 goto fail_1;
685 }
686 }
687 argvlist[argc] = NULL;
688
689 i = getmappingsize(env);
690 envlist = NEW(char *, i + 1);
691 if (envlist == NULL) {
692 err_nomem();
693 goto fail_1;
694 }
695 pos = 0;
696 envc = 0;
697 while (mappinggetnext(env, &pos, &key, &val)) {
698 char *p, *k, *v;
699 if (!getargs(key, "s;non-string key in env", &k) ||
700 !getargs(val, "s;non-string value in env", &v)) {
701 goto fail_2;
702 }
703 p = NEW(char, getstringsize(key) + getstringsize(val) + 2);
704 if (p == NULL) {
705 err_nomem();
706 goto fail_2;
707 }
708 sprintf(p, "%s=%s", k, v);
709 envlist[envc++] = p;
710 }
711 envlist[envc] = 0;
712
713 execve(path, argvlist, envlist);
714
715 /* If we get here it's definitely an error */
716
717 (void) posix_error();
718
719 fail_2:
720 while (--envc >= 0)
721 DEL(envlist[envc]);
722 DEL(envlist);
723 fail_1:
724 DEL(argvlist);
725
726 return NULL;
727}
728
729static object *
Guido van Rossum85e3b011991-06-03 12:42:10 +0000730posix_fork(self, args)
731 object *self;
732 object *args;
733{
734 int pid;
Guido van Rossum50e61dc1992-03-27 17:22:31 +0000735 if (!getnoarg(args))
736 return NULL;
Guido van Rossum85e3b011991-06-03 12:42:10 +0000737 pid = fork();
738 if (pid == -1)
739 return posix_error();
740 return newintobject((long)pid);
741}
742
743static object *
Guido van Rossum46003ff1992-05-15 11:05:24 +0000744posix_getegid(self, args)
745 object *self;
746 object *args;
747{
748 if (!getnoarg(args))
749 return NULL;
750 return newintobject((long)getegid());
751}
752
753static object *
754posix_geteuid(self, args)
755 object *self;
756 object *args;
757{
758 if (!getnoarg(args))
759 return NULL;
760 return newintobject((long)geteuid());
761}
762
763static object *
764posix_getgid(self, args)
765 object *self;
766 object *args;
767{
768 if (!getnoarg(args))
769 return NULL;
770 return newintobject((long)getgid());
771}
772
773static object *
Guido van Rossum85e3b011991-06-03 12:42:10 +0000774posix_getpid(self, args)
775 object *self;
776 object *args;
777{
Guido van Rossum04814471991-06-04 20:23:49 +0000778 if (!getnoarg(args))
Guido van Rossum85e3b011991-06-03 12:42:10 +0000779 return NULL;
780 return newintobject((long)getpid());
781}
782
783static object *
Guido van Rossum04814471991-06-04 20:23:49 +0000784posix_getpgrp(self, args)
785 object *self;
786 object *args;
787{
788 if (!getnoarg(args))
789 return NULL;
Guido van Rossum50e61dc1992-03-27 17:22:31 +0000790#ifdef SYSV
791 return newintobject((long)getpgrp());
792#else
Guido van Rossum971443b1991-06-07 13:59:29 +0000793 return newintobject((long)getpgrp(0));
Guido van Rossum50e61dc1992-03-27 17:22:31 +0000794#endif
Guido van Rossum04814471991-06-04 20:23:49 +0000795}
796
797static object *
Guido van Rossumc2670a01992-09-13 20:07:29 +0000798posix_setpgrp(self, args)
799 object *self;
800 object *args;
801{
802 if (!getnoarg(args))
803 return NULL;
804#ifdef SYSV
805 if (setpgrp() < 0)
806#else
807 if (setpgrp(0, 0) < 0)
808#endif
Guido van Rossum687dd131993-05-17 08:34:16 +0000809 return posix_error();
Guido van Rossumc2670a01992-09-13 20:07:29 +0000810 INCREF(None);
811 return None;
812}
813
814static object *
Guido van Rossum85e3b011991-06-03 12:42:10 +0000815posix_getppid(self, args)
816 object *self;
817 object *args;
818{
Guido van Rossum04814471991-06-04 20:23:49 +0000819 if (!getnoarg(args))
Guido van Rossum85e3b011991-06-03 12:42:10 +0000820 return NULL;
821 return newintobject((long)getppid());
822}
823
824static object *
Guido van Rossum46003ff1992-05-15 11:05:24 +0000825posix_getuid(self, args)
826 object *self;
827 object *args;
828{
829 if (!getnoarg(args))
830 return NULL;
831 return newintobject((long)getuid());
832}
833
834static object *
Guido van Rossum85e3b011991-06-03 12:42:10 +0000835posix_kill(self, args)
836 object *self;
837 object *args;
838{
839 int pid, sig;
Guido van Rossum234f9421993-06-17 12:35:49 +0000840 if (!getargs(args, "(ii)", &pid, &sig))
Guido van Rossum85e3b011991-06-03 12:42:10 +0000841 return NULL;
842 if (kill(pid, sig) == -1)
843 return posix_error();
844 INCREF(None);
845 return None;
846}
847
848static object *
Guido van Rossum3b066191991-06-04 19:40:25 +0000849posix_popen(self, args)
850 object *self;
851 object *args;
852{
Guido van Rossumef0a00e1992-01-27 16:51:30 +0000853 char *name, *mode;
Guido van Rossum3b066191991-06-04 19:40:25 +0000854 FILE *fp;
Guido van Rossumef0a00e1992-01-27 16:51:30 +0000855 if (!getargs(args, "(ss)", &name, &mode))
Guido van Rossum3b066191991-06-04 19:40:25 +0000856 return NULL;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000857 BGN_SAVE
Guido van Rossumef0a00e1992-01-27 16:51:30 +0000858 fp = popen(name, mode);
Guido van Rossumff4949e1992-08-05 19:58:53 +0000859 END_SAVE
Guido van Rossum3b066191991-06-04 19:40:25 +0000860 if (fp == NULL)
861 return posix_error();
Guido van Rossume0d452d1991-07-27 21:41:01 +0000862 /* From now on, ignore SIGPIPE and let the error checking
863 do the work. */
864 (void) signal(SIGPIPE, SIG_IGN);
Guido van Rossumef0a00e1992-01-27 16:51:30 +0000865 return newopenfileobject(fp, name, mode, pclose);
Guido van Rossum3b066191991-06-04 19:40:25 +0000866}
867
868static object *
Guido van Rossuma3d78fb1993-11-10 09:23:53 +0000869posix_setuid(self, args)
870 object *self;
871 object *args;
872{
873 int uid;
874 if (!getargs(args, "i", &uid))
875 return NULL;
876 if (setuid(uid) < 0)
877 return posix_error();
878 INCREF(None);
879 return None;
880}
881
882static object *
883posix_setgid(self, args)
884 object *self;
885 object *args;
886{
887 int gid;
888 if (!getargs(args, "i", &gid))
889 return NULL;
890 if (setgid(gid) < 0)
891 return posix_error();
892 INCREF(None);
893 return None;
894}
895
896static object *
Guido van Rossum21803b81992-08-09 12:55:27 +0000897posix_waitpid(self, args)
Guido van Rossum85e3b011991-06-03 12:42:10 +0000898 object *self;
899 object *args;
900{
Guido van Rossum85e3b011991-06-03 12:42:10 +0000901#ifdef NO_WAITPID
Guido van Rossum21803b81992-08-09 12:55:27 +0000902 err_setstr(PosixError,
903 "posix.waitpid() not supported on this system");
904 return NULL;
Guido van Rossum85e3b011991-06-03 12:42:10 +0000905#else
Guido van Rossum21803b81992-08-09 12:55:27 +0000906 int pid, options, sts;
907 if (!getargs(args, "(ii)", &pid, &options))
908 return NULL;
909 BGN_SAVE
910 pid = waitpid(pid, &sts, options);
911 END_SAVE
Guido van Rossum85e3b011991-06-03 12:42:10 +0000912 if (pid == -1)
913 return posix_error();
Guido van Rossum21803b81992-08-09 12:55:27 +0000914 else
915 return mkvalue("ii", pid, sts);
916#endif
917}
918
919static object *
920posix_wait(self, args)
921 object *self;
922 object *args;
923{
924 int pid, sts;
925 if (args != NULL)
926 return posix_waitpid(self, args); /* BW compat */
927 BGN_SAVE
928 pid = wait(&sts);
929 END_SAVE
930 if (pid == -1)
931 return posix_error();
932 else
933 return mkvalue("ii", pid, sts);
Guido van Rossum85e3b011991-06-03 12:42:10 +0000934}
935
936#endif /* MSDOS */
937
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000938static object *
939posix_lstat(self, args)
940 object *self;
941 object *args;
942{
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000943 return posix_do_stat(self, args, lstat);
944}
945
946static object *
947posix_readlink(self, args)
948 object *self;
949 object *args;
950{
Guido van Rossumc39de5f1992-02-05 11:15:54 +0000951#ifdef NO_LSTAT
952 err_setstr(PosixError, "readlink not implemented on this system");
953 return NULL;
954#else
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000955 char buf[1024]; /* XXX Should use MAXPATHLEN */
Guido van Rossumef0a00e1992-01-27 16:51:30 +0000956 char *path;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000957 int n;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +0000958 if (!getargs(args, "s", &path))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000959 return NULL;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000960 BGN_SAVE
Guido van Rossum50e61dc1992-03-27 17:22:31 +0000961 n = readlink(path, buf, (int) sizeof buf);
Guido van Rossumff4949e1992-08-05 19:58:53 +0000962 END_SAVE
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000963 if (n < 0)
964 return posix_error();
965 return newsizedstringobject(buf, n);
Guido van Rossumc39de5f1992-02-05 11:15:54 +0000966#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000967}
968
969static object *
970posix_symlink(self, args)
971 object *self;
972 object *args;
973{
Guido van Rossumc39de5f1992-02-05 11:15:54 +0000974#ifdef NO_LSTAT
975 err_setstr(PosixError, "symlink not implemented on this system");
976 return NULL;
977#else
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000978 return posix_2str(args, symlink);
Guido van Rossumc39de5f1992-02-05 11:15:54 +0000979#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000980}
981
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000982
Guido van Rossum22db57e1992-04-05 14:25:30 +0000983#ifdef DO_TIMES
984
985static object *
986posix_times(self, args)
987 object *self;
988 object *args;
989{
990 struct tms t;
991 clock_t c;
Guido van Rossum22db57e1992-04-05 14:25:30 +0000992 if (!getnoarg(args))
993 return NULL;
994 errno = 0;
995 c = times(&t);
Guido van Rossum687dd131993-05-17 08:34:16 +0000996 if (c == (clock_t) -1)
997 return posix_error();
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000998 return mkvalue("dddd",
999 (double)t.tms_utime / HZ,
1000 (double)t.tms_stime / HZ,
1001 (double)t.tms_cutime / HZ,
1002 (double)t.tms_cstime / HZ);
Guido van Rossum22db57e1992-04-05 14:25:30 +00001003}
1004
Guido van Rossumc2670a01992-09-13 20:07:29 +00001005#endif /* DO_TIMES */
1006
1007#ifdef DO_PG
1008
1009static object *
1010posix_setsid(self, args)
1011 object *self;
1012 object *args;
1013{
1014 if (!getnoarg(args))
1015 return NULL;
Guido van Rossum687dd131993-05-17 08:34:16 +00001016 if (setsid() < 0)
1017 return posix_error();
Guido van Rossumc2670a01992-09-13 20:07:29 +00001018 INCREF(None);
1019 return None;
1020}
1021
1022static object *
1023posix_setpgid(self, args)
1024 object *self;
1025 object *args;
1026{
1027 int pid, pgrp;
1028 if (!getargs(args, "(ii)", &pid, &pgrp))
1029 return NULL;
Guido van Rossum687dd131993-05-17 08:34:16 +00001030 if (setpgid(pid, pgrp) < 0)
1031 return posix_error();
Guido van Rossumc2670a01992-09-13 20:07:29 +00001032 INCREF(None);
1033 return None;
1034}
1035
Guido van Rossum7066dd71992-09-17 17:54:56 +00001036static object *
1037posix_tcgetpgrp(self, args)
1038 object *self;
1039 object *args;
1040{
1041 int fd, pgid;
1042 if (!getargs(args, "i", &fd))
1043 return NULL;
1044 pgid = tcgetpgrp(fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00001045 if (pgid < 0)
1046 return posix_error();
Guido van Rossum7066dd71992-09-17 17:54:56 +00001047 return newintobject((long)pgid);
1048}
1049
1050static object *
1051posix_tcsetpgrp(self, args)
1052 object *self;
1053 object *args;
1054{
1055 int fd, pgid;
1056 if (!getargs(args, "(ii)", &fd, &pgid))
1057 return NULL;
Guido van Rossum687dd131993-05-17 08:34:16 +00001058 if (tcsetpgrp(fd, pgid) < 0)
1059 return posix_error();
Guido van Rossum7066dd71992-09-17 17:54:56 +00001060 INCREF(None);
1061 return None;
1062}
1063
Guido van Rossumc2670a01992-09-13 20:07:29 +00001064#endif /* DO_PG */
Guido van Rossum22db57e1992-04-05 14:25:30 +00001065
Guido van Rossum687dd131993-05-17 08:34:16 +00001066/* Functions acting on file descriptors */
1067
Guido van Rossum234f9421993-06-17 12:35:49 +00001068static object *
Guido van Rossum687dd131993-05-17 08:34:16 +00001069posix_open(self, args)
1070 object *self;
1071 object *args;
1072{
1073 char *file;
1074 int flag;
1075 int mode = 0777;
1076 int fd;
1077 if (!getargs(args, "(si)", &file, &flag)) {
1078 err_clear();
1079 if (!getargs(args, "(sii)", &file, &flag, &mode))
1080 return NULL;
1081 }
1082 BGN_SAVE
1083 fd = open(file, flag, mode);
1084 END_SAVE
1085 if (fd < 0)
1086 return posix_error();
1087 return newintobject((long)fd);
1088}
1089
Guido van Rossum234f9421993-06-17 12:35:49 +00001090static object *
Guido van Rossum687dd131993-05-17 08:34:16 +00001091posix_close(self, args)
1092 object *self;
1093 object *args;
1094{
1095 int fd, res;
1096 if (!getargs(args, "i", &fd))
1097 return NULL;
1098 BGN_SAVE
1099 res = close(fd);
1100 END_SAVE
1101 if (res < 0)
1102 return posix_error();
1103 INCREF(None);
1104 return None;
1105}
1106
Guido van Rossum234f9421993-06-17 12:35:49 +00001107static object *
Guido van Rossum687dd131993-05-17 08:34:16 +00001108posix_dup(self, args)
1109 object *self;
1110 object *args;
1111{
1112 int fd;
1113 if (!getargs(args, "i", &fd))
1114 return NULL;
1115 BGN_SAVE
1116 fd = dup(fd);
1117 END_SAVE
1118 if (fd < 0)
1119 return posix_error();
1120 return newintobject((long)fd);
1121}
1122
Guido van Rossum234f9421993-06-17 12:35:49 +00001123static object *
Guido van Rossum687dd131993-05-17 08:34:16 +00001124posix_dup2(self, args)
1125 object *self;
1126 object *args;
1127{
1128 int fd, fd2, res;
1129 if (!getargs(args, "(ii)", &fd, &fd2))
1130 return NULL;
1131 BGN_SAVE
1132 res = dup2(fd, fd2);
1133 END_SAVE
1134 if (res < 0)
1135 return posix_error();
1136 INCREF(None);
1137 return None;
1138}
1139
Guido van Rossum234f9421993-06-17 12:35:49 +00001140static object *
Guido van Rossum687dd131993-05-17 08:34:16 +00001141posix_lseek(self, args)
1142 object *self;
1143 object *args;
1144{
1145 int fd, how;
1146 long pos, res;
1147 if (!getargs(args, "(ili)", &fd, &pos, &how))
1148 return NULL;
1149#ifdef SEEK_SET
1150 /* Turn 0, 1, 2 into SEEK_{SET,CUR,END} */
1151 switch (how) {
1152 case 0: how = SEEK_SET; break;
1153 case 1: how = SEEK_CUR; break;
1154 case 2: how = SEEK_END; break;
1155 }
1156#endif
1157 BGN_SAVE
1158 res = lseek(fd, pos, how);
1159 END_SAVE
1160 if (res < 0)
1161 return posix_error();
1162 return newintobject(res);
1163}
1164
Guido van Rossum234f9421993-06-17 12:35:49 +00001165static object *
Guido van Rossum687dd131993-05-17 08:34:16 +00001166posix_read(self, args)
1167 object *self;
1168 object *args;
1169{
1170 int fd, size;
1171 object *buffer;
1172 if (!getargs(args, "(ii)", &fd, &size))
1173 return NULL;
1174 buffer = newsizedstringobject((char *)NULL, size);
1175 if (buffer == NULL)
1176 return NULL;
1177 BGN_SAVE
1178 size = read(fd, getstringvalue(buffer), size);
1179 END_SAVE
1180 if (size < 0) {
1181 DECREF(buffer);
1182 return posix_error();
1183 }
1184 resizestring(&buffer, size);
1185 return buffer;
1186}
1187
Guido van Rossum234f9421993-06-17 12:35:49 +00001188static object *
Guido van Rossum687dd131993-05-17 08:34:16 +00001189posix_write(self, args)
1190 object *self;
1191 object *args;
1192{
1193 int fd, size;
1194 char *buffer;
1195 if (!getargs(args, "(is#)", &fd, &buffer, &size))
1196 return NULL;
1197 BGN_SAVE
1198 size = write(fd, buffer, size);
1199 END_SAVE
1200 if (size < 0)
1201 return posix_error();
1202 return newintobject((long)size);
1203}
1204
Guido van Rossum234f9421993-06-17 12:35:49 +00001205static object *
Guido van Rossum687dd131993-05-17 08:34:16 +00001206posix_fstat(self, args)
1207 object *self;
1208 object *args;
1209{
1210 int fd;
1211 struct stat st;
1212 int res;
1213 if (!getargs(args, "i", &fd))
1214 return NULL;
1215 BGN_SAVE
1216 res = fstat(fd, &st);
1217 END_SAVE
1218 if (res != 0)
1219 return posix_error();
1220 return mkvalue("(llllllllll)",
1221 (long)st.st_mode,
1222 (long)st.st_ino,
1223 (long)st.st_dev,
1224 (long)st.st_nlink,
1225 (long)st.st_uid,
1226 (long)st.st_gid,
1227 (long)st.st_size,
1228 (long)st.st_atime,
1229 (long)st.st_mtime,
1230 (long)st.st_ctime);
1231}
1232
1233static object *
1234posix_fdopen(self, args)
1235 object *self;
1236 object *args;
1237{
1238 extern int fclose PROTO((FILE *));
1239 int fd;
1240 char *mode;
1241 FILE *fp;
1242 if (!getargs(args, "(is)", &fd, &mode))
1243 return NULL;
1244 BGN_SAVE
1245 fp = fdopen(fd, mode);
1246 END_SAVE
1247 if (fp == NULL)
1248 return posix_error();
1249 /* From now on, ignore SIGPIPE and let the error checking
1250 do the work. */
1251 (void) signal(SIGPIPE, SIG_IGN);
1252 return newopenfileobject(fp, "(fdopen)", mode, fclose);
1253}
1254
1255#ifndef MSDOS
Guido van Rossum234f9421993-06-17 12:35:49 +00001256static object *
Guido van Rossum687dd131993-05-17 08:34:16 +00001257posix_pipe(self, args)
1258 object *self;
1259 object *args;
1260{
1261 int fds[2];
1262 int res;
1263 if (!getargs(args, ""))
1264 return NULL;
1265 BGN_SAVE
1266 res = pipe(fds);
1267 END_SAVE
1268 if (res != 0)
1269 return posix_error();
1270 return mkvalue("(ii)", fds[0], fds[1]);
1271}
1272#endif /* MSDOS */
Guido van Rossum22db57e1992-04-05 14:25:30 +00001273
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001274static struct methodlist posix_methods[] = {
1275 {"chdir", posix_chdir},
1276 {"chmod", posix_chmod},
1277 {"getcwd", posix_getcwd},
Guido van Rossum0ee42cd1991-04-08 21:01:03 +00001278#ifndef MSDOS
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001279 {"link", posix_link},
Guido van Rossum0ee42cd1991-04-08 21:01:03 +00001280#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001281 {"listdir", posix_listdir},
Guido van Rossumc39de5f1992-02-05 11:15:54 +00001282 {"lstat", posix_lstat},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001283 {"mkdir", posix_mkdir},
Guido van Rossum775f4da1993-01-09 17:18:52 +00001284#ifndef MSDOS
1285 {"nice", posix_nice},
1286#endif
Guido van Rossumc39de5f1992-02-05 11:15:54 +00001287 {"readlink", posix_readlink},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001288 {"rename", posix_rename},
1289 {"rmdir", posix_rmdir},
1290 {"stat", posix_stat},
Guido van Rossumc39de5f1992-02-05 11:15:54 +00001291 {"symlink", posix_symlink},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001292 {"system", posix_system},
Guido van Rossum0ee42cd1991-04-08 21:01:03 +00001293#ifndef MSDOS
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001294 {"umask", posix_umask},
Guido van Rossum0ee42cd1991-04-08 21:01:03 +00001295#endif
Guido van Rossumc39de5f1992-02-05 11:15:54 +00001296#ifndef NO_UNAME
1297 {"uname", posix_uname},
1298#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001299 {"unlink", posix_unlink},
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00001300 {"utime", posix_utime},
Guido van Rossum22db57e1992-04-05 14:25:30 +00001301#ifdef DO_TIMES
1302 {"times", posix_times},
1303#endif
Guido van Rossumc39de5f1992-02-05 11:15:54 +00001304
Guido van Rossum85e3b011991-06-03 12:42:10 +00001305#ifndef MSDOS
1306 {"_exit", posix__exit},
Guido van Rossum89b33251993-10-22 14:26:06 +00001307 {"execv", posix_execv},
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001308 {"execve", posix_execve},
Guido van Rossum85e3b011991-06-03 12:42:10 +00001309 {"fork", posix_fork},
Guido van Rossum46003ff1992-05-15 11:05:24 +00001310 {"getegid", posix_getegid},
1311 {"geteuid", posix_geteuid},
1312 {"getgid", posix_getgid},
Guido van Rossum85e3b011991-06-03 12:42:10 +00001313 {"getpid", posix_getpid},
Guido van Rossum04814471991-06-04 20:23:49 +00001314 {"getpgrp", posix_getpgrp},
Guido van Rossum85e3b011991-06-03 12:42:10 +00001315 {"getppid", posix_getppid},
Guido van Rossum46003ff1992-05-15 11:05:24 +00001316 {"getuid", posix_getuid},
Guido van Rossum85e3b011991-06-03 12:42:10 +00001317 {"kill", posix_kill},
Guido van Rossum3b066191991-06-04 19:40:25 +00001318 {"popen", posix_popen},
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00001319 {"setuid", posix_setuid},
1320 {"setgid", posix_setgid},
Guido van Rossumc2670a01992-09-13 20:07:29 +00001321 {"setpgrp", posix_setpgrp},
Guido van Rossum85e3b011991-06-03 12:42:10 +00001322 {"wait", posix_wait},
Guido van Rossum21803b81992-08-09 12:55:27 +00001323 {"waitpid", posix_waitpid},
Guido van Rossum85e3b011991-06-03 12:42:10 +00001324#endif
Guido van Rossumc39de5f1992-02-05 11:15:54 +00001325
Guido van Rossumc2670a01992-09-13 20:07:29 +00001326#ifdef DO_PG
1327 {"setsid", posix_setsid},
1328 {"setpgid", posix_setpgid},
Guido van Rossum7066dd71992-09-17 17:54:56 +00001329 {"tcgetpgrp", posix_tcgetpgrp},
1330 {"tcsetpgrp", posix_tcsetpgrp},
Guido van Rossumc2670a01992-09-13 20:07:29 +00001331#endif
1332
Guido van Rossum687dd131993-05-17 08:34:16 +00001333 {"open", posix_open},
1334 {"close", posix_close},
1335 {"dup", posix_dup},
1336 {"dup2", posix_dup2},
1337 {"lseek", posix_lseek},
1338 {"read", posix_read},
1339 {"write", posix_write},
1340 {"fstat", posix_fstat},
1341 {"fdopen", posix_fdopen},
1342#ifndef MSDOS
1343 {"pipe", posix_pipe},
1344#endif
1345
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001346 {NULL, NULL} /* Sentinel */
1347};
1348
1349
1350void
1351initposix()
1352{
1353 object *m, *d, *v;
1354
1355 m = initmodule("posix", posix_methods);
1356 d = getmoduledict(m);
1357
1358 /* Initialize posix.environ dictionary */
1359 v = convertenviron();
1360 if (v == NULL || dictinsert(d, "environ", v) != 0)
1361 fatal("can't define posix.environ");
1362 DECREF(v);
1363
1364 /* Initialize posix.error exception */
1365 PosixError = newstringobject("posix.error");
1366 if (PosixError == NULL || dictinsert(d, "error", PosixError) != 0)
1367 fatal("can't define posix.error");
1368}
Guido van Rossum0ee42cd1991-04-08 21:01:03 +00001369
Guido van Rossum3b066191991-06-04 19:40:25 +00001370
1371/* Function used elsewhere to get a file's modification time */
1372
1373long
1374getmtime(path)
1375 char *path;
1376{
1377 struct stat st;
1378 if (stat(path, &st) != 0)
1379 return -1;
1380 else
1381 return st.st_mtime;
1382}
1383
1384
Guido van Rossume22e6441993-07-09 10:51:31 +00001385#ifdef TURBO_C
Guido van Rossum0ee42cd1991-04-08 21:01:03 +00001386
1387/* A small "compatibility library" for TurboC under MS-DOS */
1388
Guido van Rossume22e6441993-07-09 10:51:31 +00001389//#include <sir.h>
Guido van Rossum0ee42cd1991-04-08 21:01:03 +00001390#include <io.h>
1391#include <dos.h>
1392#include <fcntl.h>
1393
1394int
1395chmod(path, mode)
1396 char *path;
1397 int mode;
1398{
1399 return _chmod(path, 1, mode);
1400}
1401
1402int
1403utime(path, times)
1404 char *path;
1405 time_t times[2];
1406{
1407 struct date dt;
1408 struct time tm;
1409 struct ftime dft;
1410 int fh;
1411 unixtodos(tv[0].tv_sec,&dt,&tm);
1412 dft.ft_tsec = tm.ti_sec; dft.ft_min = tm.ti_min;
1413 dft.ft_hour = tm.ti_hour; dft.ft_day = dt.da_day;
1414 dft.ft_month = dt.da_mon;
1415 dft.ft_year = (dt.da_year - 1980); /* this is for TC library */
1416
Guido van Rossumef0a00e1992-01-27 16:51:30 +00001417 if ((fh = open(path,O_RDWR)) < 0)
Guido van Rossum0ee42cd1991-04-08 21:01:03 +00001418 return posix_error(); /* can't open file to set time */
1419 if (setftime(fh,&dft) < 0)
1420 {
1421 close(fh);
1422 return posix_error();
1423 }
1424 close(fh); /* close the temp handle */
1425}
1426
Guido van Rossume22e6441993-07-09 10:51:31 +00001427#endif /* TURBO_C */