blob: 996ecdbe19b33153bf993c321beb239a3325a7a0 [file] [log] [blame]
Guido van Rossumf70e43a1991-02-19 12:39:46 +00001/***********************************************************
2Copyright 1991 by Stichting Mathematisch Centrum, Amsterdam, The
3Netherlands.
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 Rossum85a5fbb1990-10-14 12:07:46 +000043#ifdef SYSV
Guido van Rossum0ee42cd1991-04-08 21:01:03 +000044
Guido van Rossum1ff6cb41991-04-08 20:59:13 +000045#define UTIME_STRUCT
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000046#include <dirent.h>
47#define direct dirent
Guido van Rossum1ff6cb41991-04-08 20:59:13 +000048#ifdef i386
49#define mode_t int
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000050#endif
Guido van Rossum0ee42cd1991-04-08 21:01:03 +000051
Guido van Rossum1ff6cb41991-04-08 20:59:13 +000052#else /* !SYSV */
Guido van Rossum0ee42cd1991-04-08 21:01:03 +000053
54#ifndef MSDOS
Guido van Rossum1ff6cb41991-04-08 20:59:13 +000055#include <sys/dir.h>
Guido van Rossum0ee42cd1991-04-08 21:01:03 +000056#endif
57
Guido van Rossum1ff6cb41991-04-08 20:59:13 +000058#endif /* !SYSV */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000059
Guido van Rossum3f5da241990-12-20 15:06:42 +000060#include "allobjects.h"
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000061#include "modsupport.h"
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000062
Guido van Rossum7f77e2d1990-10-30 13:34:38 +000063extern char *strerror PROTO((int));
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000064
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000065
66/* Return a dictionary corresponding to the POSIX environment table */
67
68extern char **environ;
69
70static object *
71convertenviron()
72{
73 object *d;
74 char **e;
75 d = newdictobject();
76 if (d == NULL)
77 return NULL;
78 if (environ == NULL)
79 return d;
80 /* XXX This part ignores errors */
81 for (e = environ; *e != NULL; e++) {
82 object *v;
83 char *p = strchr(*e, '=');
84 if (p == NULL)
85 continue;
86 v = newstringobject(p+1);
87 if (v == NULL)
88 continue;
89 *p = '\0';
90 (void) dictinsert(d, *e, v);
91 *p = '=';
92 DECREF(v);
93 }
94 return d;
95}
96
97
98static object *PosixError; /* Exception posix.error */
99
100/* Set a POSIX-specific error from errno, and return NULL */
101
Guido van Rossum9a1581c1990-10-21 13:12:47 +0000102static object *
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000103posix_error()
104{
Guido van Rossume8f305a1990-10-14 20:04:28 +0000105 return err_errno(PosixError);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000106}
107
108
109/* POSIX generic methods */
110
111static object *
112posix_1str(args, func)
113 object *args;
114 int (*func) FPROTO((const char *));
115{
Guido van Rossumef0a00e1992-01-27 16:51:30 +0000116 char *path1;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000117 if (!getstrarg(args, &path1))
118 return NULL;
Guido van Rossumef0a00e1992-01-27 16:51:30 +0000119 if ((*func)(path1) < 0)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000120 return posix_error();
121 INCREF(None);
122 return None;
123}
124
125static object *
126posix_2str(args, func)
127 object *args;
128 int (*func) FPROTO((const char *, const char *));
129{
Guido van Rossumef0a00e1992-01-27 16:51:30 +0000130 char *path1, *path2;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000131 if (!getstrstrarg(args, &path1, &path2))
132 return NULL;
Guido van Rossumef0a00e1992-01-27 16:51:30 +0000133 if ((*func)(path1, path2) < 0)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000134 return posix_error();
135 INCREF(None);
136 return None;
137}
138
139static object *
140posix_strint(args, func)
141 object *args;
142 int (*func) FPROTO((const char *, int));
143{
Guido van Rossumef0a00e1992-01-27 16:51:30 +0000144 char *path;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000145 int i;
Guido van Rossumef0a00e1992-01-27 16:51:30 +0000146 if (!getstrintarg(args, &path, &i))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000147 return NULL;
Guido van Rossumef0a00e1992-01-27 16:51:30 +0000148 if ((*func)(path, i) < 0)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000149 return posix_error();
150 INCREF(None);
151 return None;
152}
153
154static object *
155posix_do_stat(self, args, statfunc)
156 object *self;
157 object *args;
158 int (*statfunc) FPROTO((const char *, struct stat *));
159{
160 struct stat st;
Guido van Rossumef0a00e1992-01-27 16:51:30 +0000161 char *path;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000162 object *v;
163 if (!getstrarg(args, &path))
164 return NULL;
Guido van Rossumef0a00e1992-01-27 16:51:30 +0000165 if ((*statfunc)(path, &st) != 0)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000166 return posix_error();
167 v = newtupleobject(10);
168 if (v == NULL)
169 return NULL;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000170#define SET(i, st_member) settupleitem(v, i, newintobject((long)st.st_member))
171 SET(0, st_mode);
172 SET(1, st_ino);
173 SET(2, st_dev);
174 SET(3, st_nlink);
175 SET(4, st_uid);
176 SET(5, st_gid);
177 SET(6, st_size);
178 SET(7, st_atime);
179 SET(8, st_mtime);
180 SET(9, st_ctime);
181#undef SET
Guido van Rossum3f5da241990-12-20 15:06:42 +0000182 if (err_occurred()) {
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000183 DECREF(v);
Guido van Rossum3f5da241990-12-20 15:06:42 +0000184 return NULL;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000185 }
186 return v;
187}
188
189
190/* POSIX methods */
191
192static object *
193posix_chdir(self, args)
194 object *self;
195 object *args;
196{
197 extern int chdir PROTO((const char *));
198 return posix_1str(args, chdir);
199}
200
201static object *
202posix_chmod(self, args)
203 object *self;
204 object *args;
205{
206 extern int chmod PROTO((const char *, mode_t));
207 return posix_strint(args, chmod);
208}
209
210static object *
211posix_getcwd(self, args)
212 object *self;
213 object *args;
214{
215 char buf[1026];
216 extern char *getcwd PROTO((char *, int));
217 if (!getnoarg(args))
218 return NULL;
219 if (getcwd(buf, sizeof buf) == NULL)
220 return posix_error();
221 return newstringobject(buf);
222}
223
Guido van Rossum0ee42cd1991-04-08 21:01:03 +0000224#ifndef MSDOS
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000225static object *
226posix_link(self, args)
227 object *self;
228 object *args;
229{
230 extern int link PROTO((const char *, const char *));
231 return posix_2str(args, link);
232}
Guido van Rossum0ee42cd1991-04-08 21:01:03 +0000233#endif /* !MSDOS */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000234
235static object *
236posix_listdir(self, args)
237 object *self;
238 object *args;
239{
Guido van Rossumef0a00e1992-01-27 16:51:30 +0000240 char *name;
241 object *d, *v;
Guido van Rossum0ee42cd1991-04-08 21:01:03 +0000242
243#ifdef MSDOS
244 struct ffblk ep;
245 int rv;
246 if (!getstrarg(args, &name))
247 return NULL;
248
Guido van Rossumef0a00e1992-01-27 16:51:30 +0000249 if (findfirst(name, &ep, 0) == -1)
Guido van Rossum0ee42cd1991-04-08 21:01:03 +0000250 return posix_error();
251 if ((d = newlistobject(0)) == NULL)
252 return NULL;
253 do {
254 v = newstringobject(ep.ff_name);
255 if (v == NULL) {
256 DECREF(d);
257 d = NULL;
258 break;
259 }
260 if (addlistitem(d, v) != 0) {
261 DECREF(v);
262 DECREF(d);
263 d = NULL;
264 break;
265 }
266 DECREF(v);
267 } while ((rv = findnext(&ep)) == 0);
268#else /* !MSDOS */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000269 DIR *dirp;
270 struct direct *ep;
271 if (!getstrarg(args, &name))
272 return NULL;
Guido van Rossumef0a00e1992-01-27 16:51:30 +0000273 if ((dirp = opendir(name)) == NULL)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000274 return posix_error();
275 if ((d = newlistobject(0)) == NULL) {
276 closedir(dirp);
277 return NULL;
278 }
279 while ((ep = readdir(dirp)) != NULL) {
280 v = newstringobject(ep->d_name);
281 if (v == NULL) {
282 DECREF(d);
283 d = NULL;
284 break;
285 }
286 if (addlistitem(d, v) != 0) {
287 DECREF(v);
288 DECREF(d);
289 d = NULL;
290 break;
291 }
292 DECREF(v);
293 }
294 closedir(dirp);
Guido van Rossum0ee42cd1991-04-08 21:01:03 +0000295#endif /* !MSDOS */
296
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000297 return d;
298}
299
300static object *
301posix_mkdir(self, args)
302 object *self;
303 object *args;
304{
305 extern int mkdir PROTO((const char *, mode_t));
306 return posix_strint(args, mkdir);
307}
308
Guido van Rossum1ff6cb41991-04-08 20:59:13 +0000309#ifdef i386
310int
311rename(from, to)
312 char *from;
313 char *to;
314{
315 int status;
316 /* XXX Shouldn't this unlink the destination first? */
317 status = link(from, to);
318 if (status != 0)
319 return status;
320 return unlink(from);
321}
Guido van Rossum0ee42cd1991-04-08 21:01:03 +0000322#endif /* i386 */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +0000323
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000324static object *
325posix_rename(self, args)
326 object *self;
327 object *args;
328{
329 extern int rename PROTO((const char *, const char *));
330 return posix_2str(args, rename);
331}
332
333static object *
334posix_rmdir(self, args)
335 object *self;
336 object *args;
337{
338 extern int rmdir PROTO((const char *));
339 return posix_1str(args, rmdir);
340}
341
342static object *
343posix_stat(self, args)
344 object *self;
345 object *args;
346{
347 extern int stat PROTO((const char *, struct stat *));
348 return posix_do_stat(self, args, stat);
349}
350
351static object *
352posix_system(self, args)
353 object *self;
354 object *args;
355{
Guido van Rossumef0a00e1992-01-27 16:51:30 +0000356 char *command;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000357 int sts;
358 if (!getstrarg(args, &command))
359 return NULL;
Guido van Rossumef0a00e1992-01-27 16:51:30 +0000360 sts = system(command);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000361 return newintobject((long)sts);
362}
363
Guido van Rossum0ee42cd1991-04-08 21:01:03 +0000364#ifndef MSDOS
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000365static object *
366posix_umask(self, args)
367 object *self;
368 object *args;
369{
370 int i;
371 if (!getintarg(args, &i))
372 return NULL;
373 i = umask(i);
374 if (i < 0)
375 return posix_error();
376 return newintobject((long)i);
377}
Guido van Rossum0ee42cd1991-04-08 21:01:03 +0000378#endif /* !MSDOS */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000379
380static object *
381posix_unlink(self, args)
382 object *self;
383 object *args;
384{
385 extern int unlink PROTO((const char *));
386 return posix_1str(args, unlink);
387}
388
Guido van Rossumc39de5f1992-02-05 11:15:54 +0000389#ifndef NO_UNAME
390#include <sys/utsname.h>
391
392static object *
393posix_uname(self, args)
394 object *self;
395 object *args;
396{
397 extern int uname PROTO((struct utsname *));
398 struct utsname u;
399 object *v;
400 if (uname(&u) < 0)
401 return posix_error();
402 v = newtupleobject(5);
403 if (v == NULL)
404 return NULL;
405#define SET(i, member) settupleitem(v, i, newstringobject(u.member))
406 SET(0, sysname);
407 SET(1, nodename);
408 SET(2, release);
409 SET(3, version);
410 SET(4, machine);
411#undef SET
412 if (err_occurred()) {
413 DECREF(v);
414 return NULL;
415 }
416 return v;
417}
418#endif /* NO_UNAME */
419
Guido van Rossum1ff6cb41991-04-08 20:59:13 +0000420#ifdef UTIME_STRUCT
421#include <utime.h>
422#endif
423
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000424static object *
Guido van Rossum1ff6cb41991-04-08 20:59:13 +0000425posix_utime(self, args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000426 object *self;
427 object *args;
428{
Guido van Rossumef0a00e1992-01-27 16:51:30 +0000429 char *path;
Guido van Rossum1ff6cb41991-04-08 20:59:13 +0000430
431#ifdef UTIME_STRUCT
432 struct utimbuf buf;
433#define ATIME buf.actime
434#define MTIME buf.modtime
435#define UTIME_ARG &buf
436
437#else
438 time_t buf[2];
439#define ATIME buf[0]
440#define MTIME buf[1]
441#define UTIME_ARG buf
442#endif
443
Guido van Rossumef0a00e1992-01-27 16:51:30 +0000444 if (!getargs(args, "(s(ll))", &path, &ATIME, &MTIME))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000445 return NULL;
Guido van Rossumef0a00e1992-01-27 16:51:30 +0000446 if (utime(path, UTIME_ARG) < 0)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000447 return posix_error();
448 INCREF(None);
449 return None;
Guido van Rossum1ff6cb41991-04-08 20:59:13 +0000450#undef UTIME_ARG
451#undef ATIME
452#undef MTIME
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000453}
454
Guido van Rossum85e3b011991-06-03 12:42:10 +0000455
456#ifndef MSDOS
457
Guido van Rossum3b066191991-06-04 19:40:25 +0000458/* Process operations */
Guido van Rossum85e3b011991-06-03 12:42:10 +0000459
460static object *
461posix__exit(self, args)
462 object *self;
463 object *args;
464{
465 int sts;
466 if (!getintarg(args, &sts))
467 return NULL;
468 _exit(sts);
469 /* NOTREACHED */
470}
471
472/* XXX To do: exece, execp */
473
474static object *
475posix_exec(self, args)
476 object *self;
477 object *args;
478{
Guido van Rossumef0a00e1992-01-27 16:51:30 +0000479 char *path;
480 object *argv;
Guido van Rossum85e3b011991-06-03 12:42:10 +0000481 char **argvlist;
482 int i, argc;
483 object *(*getitem) PROTO((object *, int));
484
485 /* exec has two arguments: (path, argv), where
486 argv is a list or tuple of strings. */
487
Guido van Rossumef0a00e1992-01-27 16:51:30 +0000488 if (!getargs(args, "(sO)", &path, &argv))
Guido van Rossum85e3b011991-06-03 12:42:10 +0000489 return NULL;
Guido van Rossum85e3b011991-06-03 12:42:10 +0000490 if (is_listobject(argv)) {
491 argc = getlistsize(argv);
492 getitem = getlistitem;
493 }
494 else if (is_tupleobject(argv)) {
495 argc = gettuplesize(argv);
496 getitem = gettupleitem;
497 }
Guido van Rossumef0a00e1992-01-27 16:51:30 +0000498 else {
499 badarg:
500 err_badarg();
501 return NULL;
502 }
Guido van Rossum85e3b011991-06-03 12:42:10 +0000503
504 argvlist = NEW(char *, argc+1);
505 if (argvlist == NULL)
506 return NULL;
507 for (i = 0; i < argc; i++) {
Guido van Rossumef0a00e1992-01-27 16:51:30 +0000508 if (!getstrarg((*getitem)(argv, i), &argvlist[i])) {
Guido van Rossum85e3b011991-06-03 12:42:10 +0000509 DEL(argvlist);
510 goto badarg;
511 }
Guido van Rossum85e3b011991-06-03 12:42:10 +0000512 }
513 argvlist[argc] = NULL;
514
Guido van Rossumef0a00e1992-01-27 16:51:30 +0000515 execv(path, argvlist);
Guido van Rossum85e3b011991-06-03 12:42:10 +0000516
517 /* If we get here it's definitely an error */
518
519 DEL(argvlist);
520 return posix_error();
521}
522
523static object *
524posix_fork(self, args)
525 object *self;
526 object *args;
527{
528 int pid;
529 pid = fork();
530 if (pid == -1)
531 return posix_error();
532 return newintobject((long)pid);
533}
534
535static object *
536posix_getpid(self, args)
537 object *self;
538 object *args;
539{
Guido van Rossum04814471991-06-04 20:23:49 +0000540 if (!getnoarg(args))
Guido van Rossum85e3b011991-06-03 12:42:10 +0000541 return NULL;
542 return newintobject((long)getpid());
543}
544
545static object *
Guido van Rossum04814471991-06-04 20:23:49 +0000546posix_getpgrp(self, args)
547 object *self;
548 object *args;
549{
550 if (!getnoarg(args))
551 return NULL;
Guido van Rossum971443b1991-06-07 13:59:29 +0000552 return newintobject((long)getpgrp(0));
Guido van Rossum04814471991-06-04 20:23:49 +0000553}
554
555static object *
Guido van Rossum85e3b011991-06-03 12:42:10 +0000556posix_getppid(self, args)
557 object *self;
558 object *args;
559{
Guido van Rossum04814471991-06-04 20:23:49 +0000560 if (!getnoarg(args))
Guido van Rossum85e3b011991-06-03 12:42:10 +0000561 return NULL;
562 return newintobject((long)getppid());
563}
564
565static object *
566posix_kill(self, args)
567 object *self;
568 object *args;
569{
570 int pid, sig;
571 if (!getintintarg(args, &pid, &sig))
572 return NULL;
573 if (kill(pid, sig) == -1)
574 return posix_error();
575 INCREF(None);
576 return None;
577}
578
579static object *
Guido van Rossum3b066191991-06-04 19:40:25 +0000580posix_popen(self, args)
581 object *self;
582 object *args;
583{
584 extern int pclose PROTO((FILE *));
Guido van Rossumef0a00e1992-01-27 16:51:30 +0000585 char *name, *mode;
Guido van Rossum3b066191991-06-04 19:40:25 +0000586 FILE *fp;
Guido van Rossumef0a00e1992-01-27 16:51:30 +0000587 if (!getargs(args, "(ss)", &name, &mode))
Guido van Rossum3b066191991-06-04 19:40:25 +0000588 return NULL;
Guido van Rossumef0a00e1992-01-27 16:51:30 +0000589 fp = popen(name, mode);
Guido van Rossum3b066191991-06-04 19:40:25 +0000590 if (fp == NULL)
591 return posix_error();
Guido van Rossume0d452d1991-07-27 21:41:01 +0000592 /* From now on, ignore SIGPIPE and let the error checking
593 do the work. */
594 (void) signal(SIGPIPE, SIG_IGN);
Guido van Rossumef0a00e1992-01-27 16:51:30 +0000595 return newopenfileobject(fp, name, mode, pclose);
Guido van Rossum3b066191991-06-04 19:40:25 +0000596}
597
598static object *
Guido van Rossum85e3b011991-06-03 12:42:10 +0000599posix_wait(self, args) /* Also waitpid() */
600 object *self;
601 object *args;
602{
603 object *v;
604 int pid, sts;
605 if (args == NULL)
606 pid = wait(&sts);
607 else {
608#ifdef NO_WAITPID
Guido van Rossumc39de5f1992-02-05 11:15:54 +0000609 err_setstr(PosixError,
Guido van Rossum85e3b011991-06-03 12:42:10 +0000610 "posix.wait(pid, options) not supported on this system");
611#else
612 int options;
613 if (!getintintarg(args, &pid, &options))
614 return NULL;
615 pid = waitpid(pid, &sts, options);
616#endif
617 }
618 if (pid == -1)
619 return posix_error();
620 v = newtupleobject(2);
621 if (v != NULL) {
622 settupleitem(v, 0, newintobject((long)pid));
623 settupleitem(v, 1, newintobject((long)sts));
624 if (err_occurred()) {
625 DECREF(v);
626 v = NULL;
627 }
628 }
629 return v;
630}
631
632#endif /* MSDOS */
633
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000634static object *
635posix_lstat(self, args)
636 object *self;
637 object *args;
638{
Guido van Rossumc39de5f1992-02-05 11:15:54 +0000639#ifdef NO_LSTAT
640#define lstat stat
641#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000642 extern int lstat PROTO((const char *, struct stat *));
643 return posix_do_stat(self, args, lstat);
644}
645
646static object *
647posix_readlink(self, args)
648 object *self;
649 object *args;
650{
Guido van Rossumc39de5f1992-02-05 11:15:54 +0000651#ifdef NO_LSTAT
652 err_setstr(PosixError, "readlink not implemented on this system");
653 return NULL;
654#else
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000655 char buf[1024]; /* XXX Should use MAXPATHLEN */
Guido van Rossumef0a00e1992-01-27 16:51:30 +0000656 char *path;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000657 int n;
658 if (!getstrarg(args, &path))
659 return NULL;
Guido van Rossumef0a00e1992-01-27 16:51:30 +0000660 n = readlink(path, buf, sizeof buf);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000661 if (n < 0)
662 return posix_error();
663 return newsizedstringobject(buf, n);
Guido van Rossumc39de5f1992-02-05 11:15:54 +0000664#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000665}
666
667static object *
668posix_symlink(self, args)
669 object *self;
670 object *args;
671{
Guido van Rossumc39de5f1992-02-05 11:15:54 +0000672#ifdef NO_LSTAT
673 err_setstr(PosixError, "symlink not implemented on this system");
674 return NULL;
675#else
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000676 extern int symlink PROTO((const char *, const char *));
677 return posix_2str(args, symlink);
Guido van Rossumc39de5f1992-02-05 11:15:54 +0000678#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000679}
680
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000681
682static struct methodlist posix_methods[] = {
683 {"chdir", posix_chdir},
684 {"chmod", posix_chmod},
685 {"getcwd", posix_getcwd},
Guido van Rossum0ee42cd1991-04-08 21:01:03 +0000686#ifndef MSDOS
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000687 {"link", posix_link},
Guido van Rossum0ee42cd1991-04-08 21:01:03 +0000688#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000689 {"listdir", posix_listdir},
Guido van Rossumc39de5f1992-02-05 11:15:54 +0000690 {"lstat", posix_lstat},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000691 {"mkdir", posix_mkdir},
Guido van Rossumc39de5f1992-02-05 11:15:54 +0000692 {"readlink", posix_readlink},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000693 {"rename", posix_rename},
694 {"rmdir", posix_rmdir},
695 {"stat", posix_stat},
Guido van Rossumc39de5f1992-02-05 11:15:54 +0000696 {"symlink", posix_symlink},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000697 {"system", posix_system},
Guido van Rossum0ee42cd1991-04-08 21:01:03 +0000698#ifndef MSDOS
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000699 {"umask", posix_umask},
Guido van Rossum0ee42cd1991-04-08 21:01:03 +0000700#endif
Guido van Rossumc39de5f1992-02-05 11:15:54 +0000701#ifndef NO_UNAME
702 {"uname", posix_uname},
703#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000704 {"unlink", posix_unlink},
Guido van Rossum1ff6cb41991-04-08 20:59:13 +0000705 {"utime", posix_utime},
Guido van Rossumc39de5f1992-02-05 11:15:54 +0000706
Guido van Rossum85e3b011991-06-03 12:42:10 +0000707#ifndef MSDOS
708 {"_exit", posix__exit},
709 {"exec", posix_exec},
710 {"fork", posix_fork},
711 {"getpid", posix_getpid},
Guido van Rossum04814471991-06-04 20:23:49 +0000712 {"getpgrp", posix_getpgrp},
Guido van Rossum85e3b011991-06-03 12:42:10 +0000713 {"getppid", posix_getppid},
714 {"kill", posix_kill},
Guido van Rossum3b066191991-06-04 19:40:25 +0000715 {"popen", posix_popen},
Guido van Rossum85e3b011991-06-03 12:42:10 +0000716 {"wait", posix_wait},
717#endif
Guido van Rossumc39de5f1992-02-05 11:15:54 +0000718
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000719 {NULL, NULL} /* Sentinel */
720};
721
722
723void
724initposix()
725{
726 object *m, *d, *v;
727
728 m = initmodule("posix", posix_methods);
729 d = getmoduledict(m);
730
731 /* Initialize posix.environ dictionary */
732 v = convertenviron();
733 if (v == NULL || dictinsert(d, "environ", v) != 0)
734 fatal("can't define posix.environ");
735 DECREF(v);
736
737 /* Initialize posix.error exception */
738 PosixError = newstringobject("posix.error");
739 if (PosixError == NULL || dictinsert(d, "error", PosixError) != 0)
740 fatal("can't define posix.error");
741}
Guido van Rossum0ee42cd1991-04-08 21:01:03 +0000742
Guido van Rossum3b066191991-06-04 19:40:25 +0000743
744/* Function used elsewhere to get a file's modification time */
745
746long
747getmtime(path)
748 char *path;
749{
750 struct stat st;
751 if (stat(path, &st) != 0)
752 return -1;
753 else
754 return st.st_mtime;
755}
756
757
Guido van Rossum0ee42cd1991-04-08 21:01:03 +0000758#ifdef MSDOS
759
760/* A small "compatibility library" for TurboC under MS-DOS */
761
762#include <sir.h>
763#include <io.h>
764#include <dos.h>
765#include <fcntl.h>
766
767int
768chmod(path, mode)
769 char *path;
770 int mode;
771{
772 return _chmod(path, 1, mode);
773}
774
775int
776utime(path, times)
777 char *path;
778 time_t times[2];
779{
780 struct date dt;
781 struct time tm;
782 struct ftime dft;
783 int fh;
784 unixtodos(tv[0].tv_sec,&dt,&tm);
785 dft.ft_tsec = tm.ti_sec; dft.ft_min = tm.ti_min;
786 dft.ft_hour = tm.ti_hour; dft.ft_day = dt.da_day;
787 dft.ft_month = dt.da_mon;
788 dft.ft_year = (dt.da_year - 1980); /* this is for TC library */
789
Guido van Rossumef0a00e1992-01-27 16:51:30 +0000790 if ((fh = open(path,O_RDWR)) < 0)
Guido van Rossum0ee42cd1991-04-08 21:01:03 +0000791 return posix_error(); /* can't open file to set time */
792 if (setftime(fh,&dft) < 0)
793 {
794 close(fh);
795 return posix_error();
796 }
797 close(fh); /* close the temp handle */
798}
799
800#endif /* MSDOS */