blob: 7645bfda3fc5c9ba90185cba622e4f68a4bba820 [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
34#endif
35
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000036#include <signal.h>
37#include <string.h>
38#include <setjmp.h>
39#include <sys/types.h>
40#include <sys/stat.h>
Guido van Rossum0ee42cd1991-04-08 21:01:03 +000041
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000042#ifdef SYSV
Guido van Rossum0ee42cd1991-04-08 21:01:03 +000043
Guido van Rossum1ff6cb41991-04-08 20:59:13 +000044#define UTIME_STRUCT
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000045#include <dirent.h>
46#define direct dirent
Guido van Rossum1ff6cb41991-04-08 20:59:13 +000047#ifdef i386
48#define mode_t int
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000049#endif
Guido van Rossum0ee42cd1991-04-08 21:01:03 +000050
Guido van Rossum1ff6cb41991-04-08 20:59:13 +000051#else /* !SYSV */
Guido van Rossum0ee42cd1991-04-08 21:01:03 +000052
53#ifndef MSDOS
Guido van Rossum1ff6cb41991-04-08 20:59:13 +000054#include <sys/dir.h>
Guido van Rossum0ee42cd1991-04-08 21:01:03 +000055#endif
56
Guido van Rossum1ff6cb41991-04-08 20:59:13 +000057#endif /* !SYSV */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000058
Guido van Rossum3f5da241990-12-20 15:06:42 +000059#include "allobjects.h"
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000060#include "modsupport.h"
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000061
Guido van Rossum7f77e2d1990-10-30 13:34:38 +000062extern char *strerror PROTO((int));
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000063
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000064
65/* Return a dictionary corresponding to the POSIX environment table */
66
67extern char **environ;
68
69static object *
70convertenviron()
71{
72 object *d;
73 char **e;
74 d = newdictobject();
75 if (d == NULL)
76 return NULL;
77 if (environ == NULL)
78 return d;
79 /* XXX This part ignores errors */
80 for (e = environ; *e != NULL; e++) {
81 object *v;
82 char *p = strchr(*e, '=');
83 if (p == NULL)
84 continue;
85 v = newstringobject(p+1);
86 if (v == NULL)
87 continue;
88 *p = '\0';
89 (void) dictinsert(d, *e, v);
90 *p = '=';
91 DECREF(v);
92 }
93 return d;
94}
95
96
97static object *PosixError; /* Exception posix.error */
98
99/* Set a POSIX-specific error from errno, and return NULL */
100
Guido van Rossum9a1581c1990-10-21 13:12:47 +0000101static object *
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000102posix_error()
103{
Guido van Rossume8f305a1990-10-14 20:04:28 +0000104 return err_errno(PosixError);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000105}
106
107
108/* POSIX generic methods */
109
110static object *
111posix_1str(args, func)
112 object *args;
113 int (*func) FPROTO((const char *));
114{
115 object *path1;
116 if (!getstrarg(args, &path1))
117 return NULL;
118 if ((*func)(getstringvalue(path1)) < 0)
119 return posix_error();
120 INCREF(None);
121 return None;
122}
123
124static object *
125posix_2str(args, func)
126 object *args;
127 int (*func) FPROTO((const char *, const char *));
128{
129 object *path1, *path2;
130 if (!getstrstrarg(args, &path1, &path2))
131 return NULL;
132 if ((*func)(getstringvalue(path1), getstringvalue(path2)) < 0)
133 return posix_error();
134 INCREF(None);
135 return None;
136}
137
138static object *
139posix_strint(args, func)
140 object *args;
141 int (*func) FPROTO((const char *, int));
142{
143 object *path1;
144 int i;
145 if (!getstrintarg(args, &path1, &i))
146 return NULL;
147 if ((*func)(getstringvalue(path1), i) < 0)
148 return posix_error();
149 INCREF(None);
150 return None;
151}
152
153static object *
154posix_do_stat(self, args, statfunc)
155 object *self;
156 object *args;
157 int (*statfunc) FPROTO((const char *, struct stat *));
158{
159 struct stat st;
160 object *path;
161 object *v;
162 if (!getstrarg(args, &path))
163 return NULL;
164 if ((*statfunc)(getstringvalue(path), &st) != 0)
165 return posix_error();
166 v = newtupleobject(10);
167 if (v == NULL)
168 return NULL;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000169#define SET(i, st_member) settupleitem(v, i, newintobject((long)st.st_member))
170 SET(0, st_mode);
171 SET(1, st_ino);
172 SET(2, st_dev);
173 SET(3, st_nlink);
174 SET(4, st_uid);
175 SET(5, st_gid);
176 SET(6, st_size);
177 SET(7, st_atime);
178 SET(8, st_mtime);
179 SET(9, st_ctime);
180#undef SET
Guido van Rossum3f5da241990-12-20 15:06:42 +0000181 if (err_occurred()) {
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000182 DECREF(v);
Guido van Rossum3f5da241990-12-20 15:06:42 +0000183 return NULL;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000184 }
185 return v;
186}
187
188
189/* POSIX methods */
190
191static object *
192posix_chdir(self, args)
193 object *self;
194 object *args;
195{
196 extern int chdir PROTO((const char *));
197 return posix_1str(args, chdir);
198}
199
200static object *
201posix_chmod(self, args)
202 object *self;
203 object *args;
204{
205 extern int chmod PROTO((const char *, mode_t));
206 return posix_strint(args, chmod);
207}
208
209static object *
210posix_getcwd(self, args)
211 object *self;
212 object *args;
213{
214 char buf[1026];
215 extern char *getcwd PROTO((char *, int));
216 if (!getnoarg(args))
217 return NULL;
218 if (getcwd(buf, sizeof buf) == NULL)
219 return posix_error();
220 return newstringobject(buf);
221}
222
Guido van Rossum0ee42cd1991-04-08 21:01:03 +0000223#ifndef MSDOS
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000224static object *
225posix_link(self, args)
226 object *self;
227 object *args;
228{
229 extern int link PROTO((const char *, const char *));
230 return posix_2str(args, link);
231}
Guido van Rossum0ee42cd1991-04-08 21:01:03 +0000232#endif /* !MSDOS */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000233
234static object *
235posix_listdir(self, args)
236 object *self;
237 object *args;
238{
239 object *name, *d, *v;
Guido van Rossum0ee42cd1991-04-08 21:01:03 +0000240
241#ifdef MSDOS
242 struct ffblk ep;
243 int rv;
244 if (!getstrarg(args, &name))
245 return NULL;
246
247 if (findfirst((char *) getstringvalue(name), &ep, 0) == -1)
248 return posix_error();
249 if ((d = newlistobject(0)) == NULL)
250 return NULL;
251 do {
252 v = newstringobject(ep.ff_name);
253 if (v == NULL) {
254 DECREF(d);
255 d = NULL;
256 break;
257 }
258 if (addlistitem(d, v) != 0) {
259 DECREF(v);
260 DECREF(d);
261 d = NULL;
262 break;
263 }
264 DECREF(v);
265 } while ((rv = findnext(&ep)) == 0);
266#else /* !MSDOS */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000267 DIR *dirp;
268 struct direct *ep;
269 if (!getstrarg(args, &name))
270 return NULL;
271 if ((dirp = opendir(getstringvalue(name))) == NULL)
272 return posix_error();
273 if ((d = newlistobject(0)) == NULL) {
274 closedir(dirp);
275 return NULL;
276 }
277 while ((ep = readdir(dirp)) != NULL) {
278 v = newstringobject(ep->d_name);
279 if (v == NULL) {
280 DECREF(d);
281 d = NULL;
282 break;
283 }
284 if (addlistitem(d, v) != 0) {
285 DECREF(v);
286 DECREF(d);
287 d = NULL;
288 break;
289 }
290 DECREF(v);
291 }
292 closedir(dirp);
Guido van Rossum0ee42cd1991-04-08 21:01:03 +0000293#endif /* !MSDOS */
294
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000295 return d;
296}
297
298static object *
299posix_mkdir(self, args)
300 object *self;
301 object *args;
302{
303 extern int mkdir PROTO((const char *, mode_t));
304 return posix_strint(args, mkdir);
305}
306
Guido van Rossum1ff6cb41991-04-08 20:59:13 +0000307#ifdef i386
308int
309rename(from, to)
310 char *from;
311 char *to;
312{
313 int status;
314 /* XXX Shouldn't this unlink the destination first? */
315 status = link(from, to);
316 if (status != 0)
317 return status;
318 return unlink(from);
319}
Guido van Rossum0ee42cd1991-04-08 21:01:03 +0000320#endif /* i386 */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +0000321
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000322static object *
323posix_rename(self, args)
324 object *self;
325 object *args;
326{
327 extern int rename PROTO((const char *, const char *));
328 return posix_2str(args, rename);
329}
330
331static object *
332posix_rmdir(self, args)
333 object *self;
334 object *args;
335{
336 extern int rmdir PROTO((const char *));
337 return posix_1str(args, rmdir);
338}
339
340static object *
341posix_stat(self, args)
342 object *self;
343 object *args;
344{
345 extern int stat PROTO((const char *, struct stat *));
346 return posix_do_stat(self, args, stat);
347}
348
349static object *
350posix_system(self, args)
351 object *self;
352 object *args;
353{
354 object *command;
355 int sts;
356 if (!getstrarg(args, &command))
357 return NULL;
358 sts = system(getstringvalue(command));
359 return newintobject((long)sts);
360}
361
Guido van Rossum0ee42cd1991-04-08 21:01:03 +0000362#ifndef MSDOS
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000363static object *
364posix_umask(self, args)
365 object *self;
366 object *args;
367{
368 int i;
369 if (!getintarg(args, &i))
370 return NULL;
371 i = umask(i);
372 if (i < 0)
373 return posix_error();
374 return newintobject((long)i);
375}
Guido van Rossum0ee42cd1991-04-08 21:01:03 +0000376#endif /* !MSDOS */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000377
378static object *
379posix_unlink(self, args)
380 object *self;
381 object *args;
382{
383 extern int unlink PROTO((const char *));
384 return posix_1str(args, unlink);
385}
386
Guido van Rossum1ff6cb41991-04-08 20:59:13 +0000387#ifdef UTIME_STRUCT
388#include <utime.h>
389#endif
390
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000391static object *
Guido van Rossum1ff6cb41991-04-08 20:59:13 +0000392posix_utime(self, args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000393 object *self;
394 object *args;
395{
396 object *path;
Guido van Rossum1ff6cb41991-04-08 20:59:13 +0000397
398#ifdef UTIME_STRUCT
399 struct utimbuf buf;
400#define ATIME buf.actime
401#define MTIME buf.modtime
402#define UTIME_ARG &buf
403
404#else
405 time_t buf[2];
406#define ATIME buf[0]
407#define MTIME buf[1]
408#define UTIME_ARG buf
409#endif
410
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000411 if (args == NULL || !is_tupleobject(args) || gettuplesize(args) != 2) {
412 err_badarg();
413 return NULL;
414 }
415 if (!getstrarg(gettupleitem(args, 0), &path) ||
Guido van Rossum1ff6cb41991-04-08 20:59:13 +0000416 !getlonglongargs(gettupleitem(args, 1), &ATIME, &MTIME))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000417 return NULL;
Guido van Rossum1ff6cb41991-04-08 20:59:13 +0000418 if (utime(getstringvalue(path), UTIME_ARG) < 0)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000419 return posix_error();
420 INCREF(None);
421 return None;
Guido van Rossum1ff6cb41991-04-08 20:59:13 +0000422#undef UTIME_ARG
423#undef ATIME
424#undef MTIME
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000425}
426
Guido van Rossum85e3b011991-06-03 12:42:10 +0000427
428#ifndef MSDOS
429
Guido van Rossum3b066191991-06-04 19:40:25 +0000430/* Process operations */
Guido van Rossum85e3b011991-06-03 12:42:10 +0000431
432static object *
433posix__exit(self, args)
434 object *self;
435 object *args;
436{
437 int sts;
438 if (!getintarg(args, &sts))
439 return NULL;
440 _exit(sts);
441 /* NOTREACHED */
442}
443
444/* XXX To do: exece, execp */
445
446static object *
447posix_exec(self, args)
448 object *self;
449 object *args;
450{
451 object *path, *argv;
452 char **argvlist;
453 int i, argc;
454 object *(*getitem) PROTO((object *, int));
455
456 /* exec has two arguments: (path, argv), where
457 argv is a list or tuple of strings. */
458
459 if (args == NULL || !is_tupleobject(args) || gettuplesize(args) != 2) {
460 badarg:
461 err_badarg();
462 return NULL;
463 }
464 if (!getstrarg(gettupleitem(args, 0), &path))
465 return NULL;
466 argv = gettupleitem(args, 1);
467 if (argv == NULL)
468 goto badarg;
469 if (is_listobject(argv)) {
470 argc = getlistsize(argv);
471 getitem = getlistitem;
472 }
473 else if (is_tupleobject(argv)) {
474 argc = gettuplesize(argv);
475 getitem = gettupleitem;
476 }
477 else
478 goto badarg;
479
480 argvlist = NEW(char *, argc+1);
481 if (argvlist == NULL)
482 return NULL;
483 for (i = 0; i < argc; i++) {
484 object *arg;
485 if (!getstrarg((*getitem)(argv, i), &arg)) {
486 DEL(argvlist);
487 goto badarg;
488 }
489 argvlist[i] = getstringvalue(arg);
490 }
491 argvlist[argc] = NULL;
492
493 execv(getstringvalue(path), argvlist);
494
495 /* If we get here it's definitely an error */
496
497 DEL(argvlist);
498 return posix_error();
499}
500
501static object *
502posix_fork(self, args)
503 object *self;
504 object *args;
505{
506 int pid;
507 pid = fork();
508 if (pid == -1)
509 return posix_error();
510 return newintobject((long)pid);
511}
512
513static object *
514posix_getpid(self, args)
515 object *self;
516 object *args;
517{
Guido van Rossum04814471991-06-04 20:23:49 +0000518 if (!getnoarg(args))
Guido van Rossum85e3b011991-06-03 12:42:10 +0000519 return NULL;
520 return newintobject((long)getpid());
521}
522
523static object *
Guido van Rossum04814471991-06-04 20:23:49 +0000524posix_getpgrp(self, args)
525 object *self;
526 object *args;
527{
528 if (!getnoarg(args))
529 return NULL;
Guido van Rossum971443b1991-06-07 13:59:29 +0000530 return newintobject((long)getpgrp(0));
Guido van Rossum04814471991-06-04 20:23:49 +0000531}
532
533static object *
Guido van Rossum85e3b011991-06-03 12:42:10 +0000534posix_getppid(self, args)
535 object *self;
536 object *args;
537{
Guido van Rossum04814471991-06-04 20:23:49 +0000538 if (!getnoarg(args))
Guido van Rossum85e3b011991-06-03 12:42:10 +0000539 return NULL;
540 return newintobject((long)getppid());
541}
542
543static object *
544posix_kill(self, args)
545 object *self;
546 object *args;
547{
548 int pid, sig;
549 if (!getintintarg(args, &pid, &sig))
550 return NULL;
551 if (kill(pid, sig) == -1)
552 return posix_error();
553 INCREF(None);
554 return None;
555}
556
557static object *
Guido van Rossum3b066191991-06-04 19:40:25 +0000558posix_popen(self, args)
559 object *self;
560 object *args;
561{
562 extern int pclose PROTO((FILE *));
563 object *name, *mode;
564 FILE *fp;
565 if (args == NULL || !is_tupleobject(args) || gettuplesize(args) != 2 ||
566 !is_stringobject(name = gettupleitem(args, 0)) ||
567 !is_stringobject(mode = gettupleitem(args, 1))) {
Guido van Rossum9db40131991-07-01 18:48:44 +0000568 err_setstr(TypeError, "popen() requires 2 string arguments");
Guido van Rossum3b066191991-06-04 19:40:25 +0000569 return NULL;
570 }
571 fp = popen(getstringvalue(name), getstringvalue(mode));
572 if (fp == NULL)
573 return posix_error();
574 return newopenfileobject(fp, name, mode, pclose);
575}
576
577static object *
Guido van Rossum85e3b011991-06-03 12:42:10 +0000578posix_wait(self, args) /* Also waitpid() */
579 object *self;
580 object *args;
581{
582 object *v;
583 int pid, sts;
584 if (args == NULL)
585 pid = wait(&sts);
586 else {
587#ifdef NO_WAITPID
588 err_setstr(RuntimeError,
589 "posix.wait(pid, options) not supported on this system");
590#else
591 int options;
592 if (!getintintarg(args, &pid, &options))
593 return NULL;
594 pid = waitpid(pid, &sts, options);
595#endif
596 }
597 if (pid == -1)
598 return posix_error();
599 v = newtupleobject(2);
600 if (v != NULL) {
601 settupleitem(v, 0, newintobject((long)pid));
602 settupleitem(v, 1, newintobject((long)sts));
603 if (err_occurred()) {
604 DECREF(v);
605 v = NULL;
606 }
607 }
608 return v;
609}
610
611#endif /* MSDOS */
612
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000613#ifndef NO_LSTAT
614
615static object *
616posix_lstat(self, args)
617 object *self;
618 object *args;
619{
620 extern int lstat PROTO((const char *, struct stat *));
621 return posix_do_stat(self, args, lstat);
622}
623
624static object *
625posix_readlink(self, args)
626 object *self;
627 object *args;
628{
629 char buf[1024]; /* XXX Should use MAXPATHLEN */
630 object *path;
631 int n;
632 if (!getstrarg(args, &path))
633 return NULL;
634 n = readlink(getstringvalue(path), buf, sizeof buf);
635 if (n < 0)
636 return posix_error();
637 return newsizedstringobject(buf, n);
638}
639
640static object *
641posix_symlink(self, args)
642 object *self;
643 object *args;
644{
645 extern int symlink PROTO((const char *, const char *));
646 return posix_2str(args, symlink);
647}
648
649#endif /* NO_LSTAT */
650
651
652static struct methodlist posix_methods[] = {
653 {"chdir", posix_chdir},
654 {"chmod", posix_chmod},
655 {"getcwd", posix_getcwd},
Guido van Rossum0ee42cd1991-04-08 21:01:03 +0000656#ifndef MSDOS
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000657 {"link", posix_link},
Guido van Rossum0ee42cd1991-04-08 21:01:03 +0000658#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000659 {"listdir", posix_listdir},
660 {"mkdir", posix_mkdir},
661 {"rename", posix_rename},
662 {"rmdir", posix_rmdir},
663 {"stat", posix_stat},
664 {"system", posix_system},
Guido van Rossum0ee42cd1991-04-08 21:01:03 +0000665#ifndef MSDOS
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000666 {"umask", posix_umask},
Guido van Rossum0ee42cd1991-04-08 21:01:03 +0000667#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000668 {"unlink", posix_unlink},
Guido van Rossum1ff6cb41991-04-08 20:59:13 +0000669 {"utime", posix_utime},
Guido van Rossum85e3b011991-06-03 12:42:10 +0000670#ifndef MSDOS
671 {"_exit", posix__exit},
672 {"exec", posix_exec},
673 {"fork", posix_fork},
674 {"getpid", posix_getpid},
Guido van Rossum04814471991-06-04 20:23:49 +0000675 {"getpgrp", posix_getpgrp},
Guido van Rossum85e3b011991-06-03 12:42:10 +0000676 {"getppid", posix_getppid},
677 {"kill", posix_kill},
Guido van Rossum3b066191991-06-04 19:40:25 +0000678 {"popen", posix_popen},
Guido van Rossum85e3b011991-06-03 12:42:10 +0000679 {"wait", posix_wait},
680#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000681#ifndef NO_LSTAT
682 {"lstat", posix_lstat},
683 {"readlink", posix_readlink},
684 {"symlink", posix_symlink},
685#endif
686 {NULL, NULL} /* Sentinel */
687};
688
689
690void
691initposix()
692{
693 object *m, *d, *v;
694
695 m = initmodule("posix", posix_methods);
696 d = getmoduledict(m);
697
698 /* Initialize posix.environ dictionary */
699 v = convertenviron();
700 if (v == NULL || dictinsert(d, "environ", v) != 0)
701 fatal("can't define posix.environ");
702 DECREF(v);
703
704 /* Initialize posix.error exception */
705 PosixError = newstringobject("posix.error");
706 if (PosixError == NULL || dictinsert(d, "error", PosixError) != 0)
707 fatal("can't define posix.error");
708}
Guido van Rossum0ee42cd1991-04-08 21:01:03 +0000709
Guido van Rossum3b066191991-06-04 19:40:25 +0000710
711/* Function used elsewhere to get a file's modification time */
712
713long
714getmtime(path)
715 char *path;
716{
717 struct stat st;
718 if (stat(path, &st) != 0)
719 return -1;
720 else
721 return st.st_mtime;
722}
723
724
Guido van Rossum0ee42cd1991-04-08 21:01:03 +0000725#ifdef MSDOS
726
727/* A small "compatibility library" for TurboC under MS-DOS */
728
729#include <sir.h>
730#include <io.h>
731#include <dos.h>
732#include <fcntl.h>
733
734int
735chmod(path, mode)
736 char *path;
737 int mode;
738{
739 return _chmod(path, 1, mode);
740}
741
742int
743utime(path, times)
744 char *path;
745 time_t times[2];
746{
747 struct date dt;
748 struct time tm;
749 struct ftime dft;
750 int fh;
751 unixtodos(tv[0].tv_sec,&dt,&tm);
752 dft.ft_tsec = tm.ti_sec; dft.ft_min = tm.ti_min;
753 dft.ft_hour = tm.ti_hour; dft.ft_day = dt.da_day;
754 dft.ft_month = dt.da_mon;
755 dft.ft_year = (dt.da_year - 1980); /* this is for TC library */
756
757 if ((fh = open(getstringvalue(path),O_RDWR)) < 0)
758 return posix_error(); /* can't open file to set time */
759 if (setftime(fh,&dft) < 0)
760 {
761 close(fh);
762 return posix_error();
763 }
764 close(fh); /* close the temp handle */
765}
766
767#endif /* MSDOS */