blob: 5f26b621484c3c8d089e3f41a29d0f01291459a2 [file] [log] [blame]
Guido van Rossumf70e43a1991-02-19 12:39:46 +00001/***********************************************************
Guido van Rossumb6775db1994-08-01 11:34:53 +00002Copyright 1991, 1992, 1993, 1994 by Stichting Mathematisch Centrum,
Guido van Rossum775f4da1993-01-09 17:18:52 +00003Amsterdam, 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 Rossum3f5da241990-12-20 15:06:42 +000027#include "allobjects.h"
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000028#include "modsupport.h"
Guido van Rossumff4949e1992-08-05 19:58:53 +000029#include "ceval.h"
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000030
Guido van Rossumb6775db1994-08-01 11:34:53 +000031#include <string.h>
32#include <errno.h>
Guido van Rossumb6775db1994-08-01 11:34:53 +000033#include <sys/types.h>
34#include <sys/stat.h>
Guido van Rossumb6775db1994-08-01 11:34:53 +000035
36#include "mytime.h" /* For clock_t on some systems */
37
38#ifdef HAVE_FCNTL_H
39#include <fcntl.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000040#endif /* HAVE_FCNTL_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +000041
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000042#ifndef NT
Guido van Rossumb6775db1994-08-01 11:34:53 +000043#ifdef HAVE_UNISTD_H
Guido van Rossum0b0db8e1993-01-21 16:07:51 +000044#include <unistd.h>
Guido van Rossumb6775db1994-08-01 11:34:53 +000045#else /* !HAVE_UNISTD_H */
Guido van Rossuma2b7f401993-01-04 09:09:59 +000046extern int mkdir PROTO((const char *, mode_t));
47extern int chdir PROTO((const char *));
Guido van Rossume22e6441993-07-09 10:51:31 +000048extern int rmdir PROTO((const char *));
49extern int chmod PROTO((const char *, mode_t));
Guido van Rossumb6775db1994-08-01 11:34:53 +000050extern int chown PROTO((const char *, uid_t, gid_t));
51extern char *getcwd PROTO((char *, int));
Guido van Rossume22e6441993-07-09 10:51:31 +000052extern char *strerror PROTO((int));
Guido van Rossuma2b7f401993-01-04 09:09:59 +000053extern int link PROTO((const char *, const char *));
54extern int rename PROTO((const char *, const char *));
Guido van Rossuma2b7f401993-01-04 09:09:59 +000055extern int stat PROTO((const char *, struct stat *));
56extern int unlink PROTO((const char *));
57extern int pclose PROTO((FILE *));
Guido van Rossumb6775db1994-08-01 11:34:53 +000058#ifdef HAVE_SYMLINK
Guido van Rossuma2b7f401993-01-04 09:09:59 +000059extern int symlink PROTO((const char *, const char *));
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000060#endif /_ HAVE_SYMLINK */
Guido van Rossumb6775db1994-08-01 11:34:53 +000061#ifdef HAVE_LSTAT
62extern int lstat PROTO((const char *, struct stat *));
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000063#endif /* HAVE_LSTAT */
Guido van Rossumb6775db1994-08-01 11:34:53 +000064#endif /* !HAVE_UNISTD_H */
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000065#endif /* !NT */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000066
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000067#ifndef NT
Guido van Rossumb6775db1994-08-01 11:34:53 +000068/* XXX These are for SunOS4.1.3 but shouldn't hurt elsewhere */
69extern int rename();
70extern int pclose();
71extern int lstat();
72extern int symlink();
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000073#endif /* !NT */
Guido van Rossumb6775db1994-08-01 11:34:53 +000074
75#ifdef HAVE_UTIME_H
76#include <utime.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000077#endif /* HAVE_UTIME_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +000078
79#ifdef HAVE_SYS_TIMES_H
80#include <sys/times.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000081#endif /* HAVE_SYS_TIMES_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +000082
83#ifdef HAVE_SYS_PARAM_H
84#include <sys/param.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000085#endif /* HAVE_SYS_PARAM_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +000086
87#ifdef HAVE_SYS_UTSNAME_H
88#include <sys/utsname.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000089#endif /* HAVE_SYS_UTSNAME_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +000090
91#ifndef MAXPATHLEN
92#define MAXPATHLEN 1024
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000093#endif /* MAXPATHLEN */
Guido van Rossumb6775db1994-08-01 11:34:53 +000094
95/* unistd.h defines _POSIX_VERSION on POSIX.1 systems. */
96#if defined(DIRENT) || defined(_POSIX_VERSION)
97#include <dirent.h>
98#define NLENGTH(dirent) (strlen((dirent)->d_name))
99#else /* not (DIRENT or _POSIX_VERSION) */
100#define dirent direct
101#define NLENGTH(dirent) ((dirent)->d_namlen)
102#ifdef SYSNDIR
103#include <sys/ndir.h>
104#endif /* SYSNDIR */
105#ifdef SYSDIR
106#include <sys/dir.h>
107#endif /* SYSDIR */
108#ifdef NDIR
109#include <ndir.h>
110#endif /* NDIR */
111#endif /* not (DIRENT or _POSIX_VERSION) */
112
113#ifdef NT
114#include <direct.h>
115#include <io.h>
116#include <process.h>
117#include <windows.h>
118#define popen _popen
119#endif /* NT */
120
121#ifdef OS2
122#include <io.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000123#endif /* OS2 */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000124
125/* Return a dictionary corresponding to the POSIX environment table */
126
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000127#ifndef NT
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000128extern char **environ;
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000129#endif /* !NT */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000130
131static object *
132convertenviron()
133{
134 object *d;
135 char **e;
136 d = newdictobject();
137 if (d == NULL)
138 return NULL;
139 if (environ == NULL)
140 return d;
141 /* XXX This part ignores errors */
142 for (e = environ; *e != NULL; e++) {
143 object *v;
144 char *p = strchr(*e, '=');
145 if (p == NULL)
146 continue;
147 v = newstringobject(p+1);
148 if (v == NULL)
149 continue;
150 *p = '\0';
151 (void) dictinsert(d, *e, v);
152 *p = '=';
153 DECREF(v);
154 }
155 return d;
156}
157
158
159static object *PosixError; /* Exception posix.error */
160
161/* Set a POSIX-specific error from errno, and return NULL */
162
Guido van Rossum687dd131993-05-17 08:34:16 +0000163static object * posix_error() { return err_errno(PosixError);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000164}
165
166
167/* POSIX generic methods */
168
169static object *
170posix_1str(args, func)
171 object *args;
172 int (*func) FPROTO((const char *));
173{
Guido van Rossumef0a00e1992-01-27 16:51:30 +0000174 char *path1;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000175 int res;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +0000176 if (!getargs(args, "s", &path1))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000177 return NULL;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000178 BGN_SAVE
179 res = (*func)(path1);
180 END_SAVE
181 if (res < 0)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000182 return posix_error();
183 INCREF(None);
184 return None;
185}
186
187static object *
188posix_2str(args, func)
189 object *args;
190 int (*func) FPROTO((const char *, const char *));
191{
Guido van Rossumef0a00e1992-01-27 16:51:30 +0000192 char *path1, *path2;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000193 int res;
Guido van Rossum234f9421993-06-17 12:35:49 +0000194 if (!getargs(args, "(ss)", &path1, &path2))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000195 return NULL;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000196 BGN_SAVE
197 res = (*func)(path1, path2);
198 END_SAVE
199 if (res < 0)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000200 return posix_error();
201 INCREF(None);
202 return None;
203}
204
205static object *
206posix_strint(args, func)
207 object *args;
208 int (*func) FPROTO((const char *, int));
209{
Guido van Rossumef0a00e1992-01-27 16:51:30 +0000210 char *path;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000211 int i;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000212 int res;
Guido van Rossum234f9421993-06-17 12:35:49 +0000213 if (!getargs(args, "(si)", &path, &i))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000214 return NULL;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000215 BGN_SAVE
216 res = (*func)(path, i);
217 END_SAVE
218 if (res < 0)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000219 return posix_error();
220 INCREF(None);
221 return None;
222}
223
224static object *
Guido van Rossumb6775db1994-08-01 11:34:53 +0000225posix_strintint(args, func)
226 object *args;
227 int (*func) FPROTO((const char *, int, int));
228{
229 char *path;
230 int i,i2;
231 int res;
232 if (!getargs(args, "(sii)", &path, &i, &i2))
233 return NULL;
234 BGN_SAVE
235 res = (*func)(path, i, i2);
236 END_SAVE
237 if (res < 0)
238 return posix_error();
239 INCREF(None);
240 return None;
241}
242
243static object *
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000244posix_do_stat(self, args, statfunc)
245 object *self;
246 object *args;
247 int (*statfunc) FPROTO((const char *, struct stat *));
248{
249 struct stat st;
Guido van Rossumef0a00e1992-01-27 16:51:30 +0000250 char *path;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000251 int res;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +0000252 if (!getargs(args, "s", &path))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000253 return NULL;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000254 BGN_SAVE
255 res = (*statfunc)(path, &st);
256 END_SAVE
257 if (res != 0)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000258 return posix_error();
Guido van Rossum687dd131993-05-17 08:34:16 +0000259 return mkvalue("(llllllllll)",
Guido van Rossume5372401993-03-16 12:15:04 +0000260 (long)st.st_mode,
261 (long)st.st_ino,
262 (long)st.st_dev,
263 (long)st.st_nlink,
264 (long)st.st_uid,
265 (long)st.st_gid,
266 (long)st.st_size,
267 (long)st.st_atime,
268 (long)st.st_mtime,
269 (long)st.st_ctime);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000270}
271
272
273/* POSIX methods */
274
275static object *
276posix_chdir(self, args)
277 object *self;
278 object *args;
279{
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000280 return posix_1str(args, chdir);
281}
282
283static object *
284posix_chmod(self, args)
285 object *self;
286 object *args;
287{
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000288 return posix_strint(args, chmod);
289}
290
Guido van Rossumb6775db1994-08-01 11:34:53 +0000291#ifdef HAVE_CHOWN
292static object *
293posix_chown(self, args)
294 object *self;
295 object *args;
296{
297 return posix_strintint(args, chown);
298}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000299#endif /* HAVE_CHOWN */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000300
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000301static object *
302posix_getcwd(self, args)
303 object *self;
304 object *args;
305{
306 char buf[1026];
Guido van Rossumff4949e1992-08-05 19:58:53 +0000307 char *res;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000308 if (!getnoarg(args))
309 return NULL;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000310 BGN_SAVE
311 res = getcwd(buf, sizeof buf);
312 END_SAVE
313 if (res == NULL)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000314 return posix_error();
315 return newstringobject(buf);
316}
317
Guido van Rossumb6775db1994-08-01 11:34:53 +0000318#ifdef HAVE_LINK
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000319static object *
320posix_link(self, args)
321 object *self;
322 object *args;
323{
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000324 return posix_2str(args, link);
325}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000326#endif /* HAVE_LINK */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000327
Guido van Rossumb6775db1994-08-01 11:34:53 +0000328static object *
329posix_listdir(self, args)
330 object *self;
331 object *args;
332{
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000333#ifdef NT
334
Guido van Rossumb6775db1994-08-01 11:34:53 +0000335 char *name;
336 int len;
337 object *d, *v;
338 HANDLE hFindFile;
339 WIN32_FIND_DATA FileData;
340 char namebuf[MAX_PATH+5];
341
342 if (!getargs(args, "s#", &name, &len))
343 return NULL;
344 if (len >= MAX_PATH) {
345 err_setstr(ValueError, "path too long");
346 return NULL;
347 }
348 strcpy(namebuf, name);
349 if (namebuf[len-1] != '/' && namebuf[len-1] != '\\')
350 namebuf[len++] = '/';
351 strcpy(namebuf + len, "*.*");
352
353 if ((d = newlistobject(0)) == NULL)
354 return NULL;
355
356 hFindFile = FindFirstFile(namebuf, &FileData);
357 if (hFindFile == INVALID_HANDLE_VALUE) {
358 errno = GetLastError();
359 return posix_error();
360 }
361 do {
362 v = newstringobject(FileData.cFileName);
363 if (v == NULL) {
364 DECREF(d);
365 d = NULL;
366 break;
367 }
368 if (addlistitem(d, v) != 0) {
369 DECREF(v);
370 DECREF(d);
371 d = NULL;
372 break;
373 }
374 DECREF(v);
375 } while (FindNextFile(hFindFile, &FileData) == TRUE);
376
377 if (FindClose(hFindFile) == FALSE) {
378 errno = GetLastError();
379 return posix_error();
380 }
381
382 return d;
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000383
384#else /* !NT */
385
Guido van Rossumef0a00e1992-01-27 16:51:30 +0000386 char *name;
387 object *d, *v;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000388 DIR *dirp;
Guido van Rossumb6775db1994-08-01 11:34:53 +0000389 struct dirent *ep;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +0000390 if (!getargs(args, "s", &name))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000391 return NULL;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000392 BGN_SAVE
393 if ((dirp = opendir(name)) == NULL) {
394 RET_SAVE
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000395 return posix_error();
Guido van Rossumff4949e1992-08-05 19:58:53 +0000396 }
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000397 if ((d = newlistobject(0)) == NULL) {
398 closedir(dirp);
Guido van Rossumff4949e1992-08-05 19:58:53 +0000399 RET_SAVE
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000400 return NULL;
401 }
402 while ((ep = readdir(dirp)) != NULL) {
403 v = newstringobject(ep->d_name);
404 if (v == NULL) {
405 DECREF(d);
406 d = NULL;
407 break;
408 }
409 if (addlistitem(d, v) != 0) {
410 DECREF(v);
411 DECREF(d);
412 d = NULL;
413 break;
414 }
415 DECREF(v);
416 }
417 closedir(dirp);
Guido van Rossumff4949e1992-08-05 19:58:53 +0000418 END_SAVE
Guido van Rossum0ee42cd1991-04-08 21:01:03 +0000419
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000420 return d;
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000421
422#endif /* !NT */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000423}
424
425static object *
426posix_mkdir(self, args)
427 object *self;
428 object *args;
429{
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000430 return posix_strint(args, mkdir);
431}
432
Guido van Rossumb6775db1994-08-01 11:34:53 +0000433#ifdef HAVE_NICE
Guido van Rossum775f4da1993-01-09 17:18:52 +0000434static object *
435posix_nice(self, args)
436 object *self;
437 object *args;
438{
439 int increment, value;
440
441 if (!getargs(args, "i", &increment))
442 return NULL;
443 value = nice(increment);
444 if (value == -1)
445 return posix_error();
446 return newintobject((long) value);
447}
Guido van Rossumb6775db1994-08-01 11:34:53 +0000448#endif /* HAVE_NICE */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +0000449
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000450static object *
451posix_rename(self, args)
452 object *self;
453 object *args;
454{
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000455 return posix_2str(args, rename);
456}
457
458static object *
459posix_rmdir(self, args)
460 object *self;
461 object *args;
462{
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000463 return posix_1str(args, rmdir);
464}
465
466static object *
467posix_stat(self, args)
468 object *self;
469 object *args;
470{
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000471 return posix_do_stat(self, args, stat);
472}
473
474static object *
475posix_system(self, args)
476 object *self;
477 object *args;
478{
Guido van Rossumef0a00e1992-01-27 16:51:30 +0000479 char *command;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000480 long sts;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +0000481 if (!getargs(args, "s", &command))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000482 return NULL;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000483 BGN_SAVE
Guido van Rossumef0a00e1992-01-27 16:51:30 +0000484 sts = system(command);
Guido van Rossumff4949e1992-08-05 19:58:53 +0000485 END_SAVE
486 return newintobject(sts);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000487}
488
489static object *
490posix_umask(self, args)
491 object *self;
492 object *args;
493{
494 int i;
495 if (!getintarg(args, &i))
496 return NULL;
497 i = umask(i);
498 if (i < 0)
499 return posix_error();
500 return newintobject((long)i);
501}
502
503static object *
504posix_unlink(self, args)
505 object *self;
506 object *args;
507{
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000508 return posix_1str(args, unlink);
509}
510
Guido van Rossumb6775db1994-08-01 11:34:53 +0000511#ifdef HAVE_UNAME
Guido van Rossumc39de5f1992-02-05 11:15:54 +0000512static object *
513posix_uname(self, args)
514 object *self;
515 object *args;
516{
Guido van Rossumc39de5f1992-02-05 11:15:54 +0000517 struct utsname u;
518 object *v;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000519 int res;
Guido van Rossum50e61dc1992-03-27 17:22:31 +0000520 if (!getnoarg(args))
521 return NULL;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000522 BGN_SAVE
523 res = uname(&u);
524 END_SAVE
525 if (res < 0)
Guido van Rossumc39de5f1992-02-05 11:15:54 +0000526 return posix_error();
Guido van Rossume5372401993-03-16 12:15:04 +0000527 return mkvalue("(sssss)",
528 u.sysname,
529 u.nodename,
530 u.release,
531 u.version,
532 u.machine);
Guido van Rossumc39de5f1992-02-05 11:15:54 +0000533}
Guido van Rossumb6775db1994-08-01 11:34:53 +0000534#endif /* HAVE_UNAME */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +0000535
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000536static object *
Guido van Rossum1ff6cb41991-04-08 20:59:13 +0000537posix_utime(self, args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000538 object *self;
539 object *args;
540{
Guido van Rossumef0a00e1992-01-27 16:51:30 +0000541 char *path;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000542 int res;
Guido van Rossum1ff6cb41991-04-08 20:59:13 +0000543
Guido van Rossumb6775db1994-08-01 11:34:53 +0000544#ifdef HAVE_UTIME_H
Guido van Rossum1ff6cb41991-04-08 20:59:13 +0000545 struct utimbuf buf;
546#define ATIME buf.actime
547#define MTIME buf.modtime
548#define UTIME_ARG &buf
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000549#else /* HAVE_UTIME_H */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +0000550 time_t buf[2];
551#define ATIME buf[0]
552#define MTIME buf[1]
553#define UTIME_ARG buf
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000554#endif /* HAVE_UTIME_H */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +0000555
Guido van Rossumef0a00e1992-01-27 16:51:30 +0000556 if (!getargs(args, "(s(ll))", &path, &ATIME, &MTIME))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000557 return NULL;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000558 BGN_SAVE
559 res = utime(path, UTIME_ARG);
560 END_SAVE
561 if (res < 0)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000562 return posix_error();
563 INCREF(None);
564 return None;
Guido van Rossum1ff6cb41991-04-08 20:59:13 +0000565#undef UTIME_ARG
566#undef ATIME
567#undef MTIME
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000568}
569
Guido van Rossum85e3b011991-06-03 12:42:10 +0000570
Guido van Rossum3b066191991-06-04 19:40:25 +0000571/* Process operations */
Guido van Rossum85e3b011991-06-03 12:42:10 +0000572
573static object *
574posix__exit(self, args)
575 object *self;
576 object *args;
577{
578 int sts;
579 if (!getintarg(args, &sts))
580 return NULL;
581 _exit(sts);
582 /* NOTREACHED */
583}
584
Guido van Rossum85e3b011991-06-03 12:42:10 +0000585static object *
Guido van Rossum89b33251993-10-22 14:26:06 +0000586posix_execv(self, args)
Guido van Rossum85e3b011991-06-03 12:42:10 +0000587 object *self;
588 object *args;
589{
Guido van Rossumef0a00e1992-01-27 16:51:30 +0000590 char *path;
591 object *argv;
Guido van Rossum85e3b011991-06-03 12:42:10 +0000592 char **argvlist;
593 int i, argc;
594 object *(*getitem) PROTO((object *, int));
595
Guido van Rossum89b33251993-10-22 14:26:06 +0000596 /* execv has two arguments: (path, argv), where
Guido van Rossum85e3b011991-06-03 12:42:10 +0000597 argv is a list or tuple of strings. */
598
Guido van Rossumef0a00e1992-01-27 16:51:30 +0000599 if (!getargs(args, "(sO)", &path, &argv))
Guido van Rossum85e3b011991-06-03 12:42:10 +0000600 return NULL;
Guido van Rossum85e3b011991-06-03 12:42:10 +0000601 if (is_listobject(argv)) {
602 argc = getlistsize(argv);
603 getitem = getlistitem;
604 }
605 else if (is_tupleobject(argv)) {
606 argc = gettuplesize(argv);
607 getitem = gettupleitem;
608 }
Guido van Rossumef0a00e1992-01-27 16:51:30 +0000609 else {
610 badarg:
611 err_badarg();
612 return NULL;
613 }
Guido van Rossum85e3b011991-06-03 12:42:10 +0000614
615 argvlist = NEW(char *, argc+1);
616 if (argvlist == NULL)
617 return NULL;
618 for (i = 0; i < argc; i++) {
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +0000619 if (!getargs((*getitem)(argv, i), "s", &argvlist[i])) {
Guido van Rossum85e3b011991-06-03 12:42:10 +0000620 DEL(argvlist);
621 goto badarg;
622 }
Guido van Rossum85e3b011991-06-03 12:42:10 +0000623 }
624 argvlist[argc] = NULL;
625
Guido van Rossumb6775db1994-08-01 11:34:53 +0000626#ifdef BAD_EXEC_PROTOTYPES
627 execv(path, (const char **) argvlist);
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000628#else /* BAD_EXEC_PROTOTYPES */
Guido van Rossumef0a00e1992-01-27 16:51:30 +0000629 execv(path, argvlist);
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000630#endif /* BAD_EXEC_PROTOTYPES */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000631
Guido van Rossum85e3b011991-06-03 12:42:10 +0000632 /* If we get here it's definitely an error */
633
634 DEL(argvlist);
635 return posix_error();
636}
637
638static object *
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +0000639posix_execve(self, args)
640 object *self;
641 object *args;
642{
643 char *path;
644 object *argv, *env;
645 char **argvlist;
646 char **envlist;
647 object *key, *val;
648 int i, pos, argc, envc;
649 object *(*getitem) PROTO((object *, int));
650
651 /* execve has three arguments: (path, argv, env), where
652 argv is a list or tuple of strings and env is a dictionary
653 like posix.environ. */
654
655 if (!getargs(args, "(sOO)", &path, &argv, &env))
656 return NULL;
657 if (is_listobject(argv)) {
658 argc = getlistsize(argv);
659 getitem = getlistitem;
660 }
661 else if (is_tupleobject(argv)) {
662 argc = gettuplesize(argv);
663 getitem = gettupleitem;
664 }
665 else {
666 err_setstr(TypeError, "argv must be tuple or list");
667 return NULL;
668 }
669 if (!is_dictobject(env)) {
670 err_setstr(TypeError, "env must be dictionary");
671 return NULL;
672 }
673
674 argvlist = NEW(char *, argc+1);
675 if (argvlist == NULL) {
676 err_nomem();
677 return NULL;
678 }
679 for (i = 0; i < argc; i++) {
680 if (!getargs((*getitem)(argv, i),
681 "s;argv must be list of strings",
682 &argvlist[i])) {
683 goto fail_1;
684 }
685 }
686 argvlist[argc] = NULL;
687
688 i = getmappingsize(env);
689 envlist = NEW(char *, i + 1);
690 if (envlist == NULL) {
691 err_nomem();
692 goto fail_1;
693 }
694 pos = 0;
695 envc = 0;
696 while (mappinggetnext(env, &pos, &key, &val)) {
697 char *p, *k, *v;
698 if (!getargs(key, "s;non-string key in env", &k) ||
699 !getargs(val, "s;non-string value in env", &v)) {
700 goto fail_2;
701 }
702 p = NEW(char, getstringsize(key) + getstringsize(val) + 2);
703 if (p == NULL) {
704 err_nomem();
705 goto fail_2;
706 }
707 sprintf(p, "%s=%s", k, v);
708 envlist[envc++] = p;
709 }
710 envlist[envc] = 0;
711
Guido van Rossumb6775db1994-08-01 11:34:53 +0000712
713#ifdef BAD_EXEC_PROTOTYPES
714 execve(path, (const char **)argvlist, envlist);
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000715#else /* BAD_EXEC_PROTOTYPES */
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +0000716 execve(path, argvlist, envlist);
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000717#endif /* BAD_EXEC_PROTOTYPES */
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +0000718
719 /* If we get here it's definitely an error */
720
721 (void) posix_error();
722
723 fail_2:
724 while (--envc >= 0)
725 DEL(envlist[envc]);
726 DEL(envlist);
727 fail_1:
728 DEL(argvlist);
729
730 return NULL;
731}
732
733static object *
Guido van Rossum85e3b011991-06-03 12:42:10 +0000734posix_fork(self, args)
735 object *self;
736 object *args;
737{
738 int pid;
Guido van Rossum50e61dc1992-03-27 17:22:31 +0000739 if (!getnoarg(args))
740 return NULL;
Guido van Rossum85e3b011991-06-03 12:42:10 +0000741 pid = fork();
742 if (pid == -1)
743 return posix_error();
744 return newintobject((long)pid);
745}
746
747static object *
Guido van Rossum46003ff1992-05-15 11:05:24 +0000748posix_getegid(self, args)
749 object *self;
750 object *args;
751{
752 if (!getnoarg(args))
753 return NULL;
754 return newintobject((long)getegid());
755}
756
757static object *
758posix_geteuid(self, args)
759 object *self;
760 object *args;
761{
762 if (!getnoarg(args))
763 return NULL;
764 return newintobject((long)geteuid());
765}
766
767static object *
768posix_getgid(self, args)
769 object *self;
770 object *args;
771{
772 if (!getnoarg(args))
773 return NULL;
774 return newintobject((long)getgid());
775}
776
777static object *
Guido van Rossum85e3b011991-06-03 12:42:10 +0000778posix_getpid(self, args)
779 object *self;
780 object *args;
781{
Guido van Rossum04814471991-06-04 20:23:49 +0000782 if (!getnoarg(args))
Guido van Rossum85e3b011991-06-03 12:42:10 +0000783 return NULL;
784 return newintobject((long)getpid());
785}
786
Guido van Rossumb6775db1994-08-01 11:34:53 +0000787#ifdef HAVE_GETPGRP
Guido van Rossum85e3b011991-06-03 12:42:10 +0000788static object *
Guido van Rossum04814471991-06-04 20:23:49 +0000789posix_getpgrp(self, args)
790 object *self;
791 object *args;
792{
793 if (!getnoarg(args))
794 return NULL;
Guido van Rossumb6775db1994-08-01 11:34:53 +0000795#ifdef GETPGRP_HAVE_ARG
Guido van Rossum971443b1991-06-07 13:59:29 +0000796 return newintobject((long)getpgrp(0));
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000797#else /* GETPGRP_HAVE_ARG */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000798 return newintobject((long)getpgrp());
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000799#endif /* GETPGRP_HAVE_ARG */
Guido van Rossum04814471991-06-04 20:23:49 +0000800}
Guido van Rossumb6775db1994-08-01 11:34:53 +0000801#endif /* HAVE_GETPGRP */
Guido van Rossum04814471991-06-04 20:23:49 +0000802
Guido van Rossumb6775db1994-08-01 11:34:53 +0000803#ifdef HAVE_SETPGRP
Guido van Rossum04814471991-06-04 20:23:49 +0000804static object *
Guido van Rossumc2670a01992-09-13 20:07:29 +0000805posix_setpgrp(self, args)
806 object *self;
807 object *args;
808{
809 if (!getnoarg(args))
810 return NULL;
Guido van Rossumb6775db1994-08-01 11:34:53 +0000811#ifdef GETPGRP_HAVE_ARG
Guido van Rossumc2670a01992-09-13 20:07:29 +0000812 if (setpgrp(0, 0) < 0)
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000813#else /* GETPGRP_HAVE_ARG */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000814 if (setpgrp() < 0)
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000815#endif /* GETPGRP_HAVE_ARG */
Guido van Rossum687dd131993-05-17 08:34:16 +0000816 return posix_error();
Guido van Rossumc2670a01992-09-13 20:07:29 +0000817 INCREF(None);
818 return None;
819}
820
Guido van Rossumb6775db1994-08-01 11:34:53 +0000821#endif /* HAVE_SETPGRP */
822
Guido van Rossumc2670a01992-09-13 20:07:29 +0000823static object *
Guido van Rossum85e3b011991-06-03 12:42:10 +0000824posix_getppid(self, args)
825 object *self;
826 object *args;
827{
Guido van Rossum04814471991-06-04 20:23:49 +0000828 if (!getnoarg(args))
Guido van Rossum85e3b011991-06-03 12:42:10 +0000829 return NULL;
830 return newintobject((long)getppid());
831}
832
833static object *
Guido van Rossum46003ff1992-05-15 11:05:24 +0000834posix_getuid(self, args)
835 object *self;
836 object *args;
837{
838 if (!getnoarg(args))
839 return NULL;
840 return newintobject((long)getuid());
841}
842
843static object *
Guido van Rossum85e3b011991-06-03 12:42:10 +0000844posix_kill(self, args)
845 object *self;
846 object *args;
847{
848 int pid, sig;
Guido van Rossum234f9421993-06-17 12:35:49 +0000849 if (!getargs(args, "(ii)", &pid, &sig))
Guido van Rossum85e3b011991-06-03 12:42:10 +0000850 return NULL;
851 if (kill(pid, sig) == -1)
852 return posix_error();
853 INCREF(None);
854 return None;
855}
856
857static object *
Guido van Rossum3b066191991-06-04 19:40:25 +0000858posix_popen(self, args)
859 object *self;
860 object *args;
861{
Guido van Rossumef0a00e1992-01-27 16:51:30 +0000862 char *name, *mode;
Guido van Rossum3b066191991-06-04 19:40:25 +0000863 FILE *fp;
Guido van Rossumef0a00e1992-01-27 16:51:30 +0000864 if (!getargs(args, "(ss)", &name, &mode))
Guido van Rossum3b066191991-06-04 19:40:25 +0000865 return NULL;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000866 BGN_SAVE
Guido van Rossumef0a00e1992-01-27 16:51:30 +0000867 fp = popen(name, mode);
Guido van Rossumff4949e1992-08-05 19:58:53 +0000868 END_SAVE
Guido van Rossum3b066191991-06-04 19:40:25 +0000869 if (fp == NULL)
870 return posix_error();
Guido van Rossumef0a00e1992-01-27 16:51:30 +0000871 return newopenfileobject(fp, name, mode, pclose);
Guido van Rossum3b066191991-06-04 19:40:25 +0000872}
873
Guido van Rossumb6775db1994-08-01 11:34:53 +0000874#ifdef HAVE_SETUID
Guido van Rossum3b066191991-06-04 19:40:25 +0000875static object *
Guido van Rossuma3d78fb1993-11-10 09:23:53 +0000876posix_setuid(self, args)
877 object *self;
878 object *args;
879{
880 int uid;
881 if (!getargs(args, "i", &uid))
882 return NULL;
883 if (setuid(uid) < 0)
884 return posix_error();
885 INCREF(None);
886 return None;
887}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000888#endif /* HAVE_SETUID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +0000889
Guido van Rossumb6775db1994-08-01 11:34:53 +0000890#ifdef HAVE_SETGID
Guido van Rossuma3d78fb1993-11-10 09:23:53 +0000891static object *
892posix_setgid(self, args)
893 object *self;
894 object *args;
895{
896 int gid;
897 if (!getargs(args, "i", &gid))
898 return NULL;
899 if (setgid(gid) < 0)
900 return posix_error();
901 INCREF(None);
902 return None;
903}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000904#endif /* HAVE_SETGID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +0000905
Guido van Rossumb6775db1994-08-01 11:34:53 +0000906#ifdef HAVE_WAITPID
Guido van Rossuma3d78fb1993-11-10 09:23:53 +0000907static object *
Guido van Rossum21803b81992-08-09 12:55:27 +0000908posix_waitpid(self, args)
Guido van Rossum85e3b011991-06-03 12:42:10 +0000909 object *self;
910 object *args;
911{
Guido van Rossum21803b81992-08-09 12:55:27 +0000912 int pid, options, sts;
913 if (!getargs(args, "(ii)", &pid, &options))
914 return NULL;
915 BGN_SAVE
916 pid = waitpid(pid, &sts, options);
917 END_SAVE
Guido van Rossum85e3b011991-06-03 12:42:10 +0000918 if (pid == -1)
919 return posix_error();
Guido van Rossum21803b81992-08-09 12:55:27 +0000920 else
921 return mkvalue("ii", pid, sts);
Guido van Rossum21803b81992-08-09 12:55:27 +0000922}
Guido van Rossumb6775db1994-08-01 11:34:53 +0000923#endif /* HAVE_WAITPID */
Guido van Rossum21803b81992-08-09 12:55:27 +0000924
925static object *
926posix_wait(self, args)
927 object *self;
928 object *args;
929{
930 int pid, sts;
Guido van Rossum21803b81992-08-09 12:55:27 +0000931 BGN_SAVE
932 pid = wait(&sts);
933 END_SAVE
934 if (pid == -1)
935 return posix_error();
936 else
937 return mkvalue("ii", pid, sts);
Guido van Rossum85e3b011991-06-03 12:42:10 +0000938}
939
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000940static object *
941posix_lstat(self, args)
942 object *self;
943 object *args;
944{
Guido van Rossumb6775db1994-08-01 11:34:53 +0000945#ifdef HAVE_LSTAT
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000946 return posix_do_stat(self, args, lstat);
Guido van Rossumb6775db1994-08-01 11:34:53 +0000947#else /* !HAVE_LSTAT */
948 return posix_do_stat(self, args, stat);
949#endif /* !HAVE_LSTAT */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000950}
951
Guido van Rossumb6775db1994-08-01 11:34:53 +0000952#ifdef HAVE_READLINK
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000953static object *
954posix_readlink(self, args)
955 object *self;
956 object *args;
957{
Guido van Rossumb6775db1994-08-01 11:34:53 +0000958 char buf[MAXPATHLEN];
Guido van Rossumef0a00e1992-01-27 16:51:30 +0000959 char *path;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000960 int n;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +0000961 if (!getargs(args, "s", &path))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000962 return NULL;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000963 BGN_SAVE
Guido van Rossum50e61dc1992-03-27 17:22:31 +0000964 n = readlink(path, buf, (int) sizeof buf);
Guido van Rossumff4949e1992-08-05 19:58:53 +0000965 END_SAVE
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000966 if (n < 0)
967 return posix_error();
968 return newsizedstringobject(buf, n);
969}
Guido van Rossumb6775db1994-08-01 11:34:53 +0000970#endif /* HAVE_READLINK */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000971
Guido van Rossumb6775db1994-08-01 11:34:53 +0000972#ifdef HAVE_SYMLINK
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000973static object *
974posix_symlink(self, args)
975 object *self;
976 object *args;
977{
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000978 return posix_2str(args, symlink);
979}
Guido van Rossumb6775db1994-08-01 11:34:53 +0000980#endif /* HAVE_SYMLINK */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000981
Guido van Rossumb6775db1994-08-01 11:34:53 +0000982#ifdef HAVE_TIMES
983#ifndef HZ
984#define HZ 60 /* Universal constant :-) */
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000985#endif /* HZ */
Guido van Rossum22db57e1992-04-05 14:25:30 +0000986static object *
987posix_times(self, args)
988 object *self;
989 object *args;
990{
991 struct tms t;
992 clock_t c;
Guido van Rossum22db57e1992-04-05 14:25:30 +0000993 if (!getnoarg(args))
994 return NULL;
995 errno = 0;
996 c = times(&t);
Guido van Rossum687dd131993-05-17 08:34:16 +0000997 if (c == (clock_t) -1)
998 return posix_error();
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000999 return mkvalue("dddd",
1000 (double)t.tms_utime / HZ,
1001 (double)t.tms_stime / HZ,
1002 (double)t.tms_cutime / HZ,
1003 (double)t.tms_cstime / HZ);
Guido van Rossum22db57e1992-04-05 14:25:30 +00001004}
Guido van Rossumb6775db1994-08-01 11:34:53 +00001005#endif /* HAVE_TIMES */
Guido van Rossum22db57e1992-04-05 14:25:30 +00001006
Guido van Rossumb6775db1994-08-01 11:34:53 +00001007#ifdef HAVE_SETSID
Guido van Rossumc2670a01992-09-13 20:07:29 +00001008static object *
1009posix_setsid(self, args)
1010 object *self;
1011 object *args;
1012{
1013 if (!getnoarg(args))
1014 return NULL;
Guido van Rossum687dd131993-05-17 08:34:16 +00001015 if (setsid() < 0)
1016 return posix_error();
Guido van Rossumc2670a01992-09-13 20:07:29 +00001017 INCREF(None);
1018 return None;
1019}
Guido van Rossumb6775db1994-08-01 11:34:53 +00001020#endif /* HAVE_SETSID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00001021
Guido van Rossumb6775db1994-08-01 11:34:53 +00001022#ifdef HAVE_SETPGID
Guido van Rossumc2670a01992-09-13 20:07:29 +00001023static object *
1024posix_setpgid(self, args)
1025 object *self;
1026 object *args;
1027{
1028 int pid, pgrp;
1029 if (!getargs(args, "(ii)", &pid, &pgrp))
1030 return NULL;
Guido van Rossum687dd131993-05-17 08:34:16 +00001031 if (setpgid(pid, pgrp) < 0)
1032 return posix_error();
Guido van Rossumc2670a01992-09-13 20:07:29 +00001033 INCREF(None);
1034 return None;
1035}
Guido van Rossumb6775db1994-08-01 11:34:53 +00001036#endif /* HAVE_SETPGID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00001037
Guido van Rossumb6775db1994-08-01 11:34:53 +00001038#ifdef HAVE_TCGETPGRP
Guido van Rossum7066dd71992-09-17 17:54:56 +00001039static object *
1040posix_tcgetpgrp(self, args)
1041 object *self;
1042 object *args;
1043{
1044 int fd, pgid;
1045 if (!getargs(args, "i", &fd))
1046 return NULL;
1047 pgid = tcgetpgrp(fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00001048 if (pgid < 0)
1049 return posix_error();
Guido van Rossum7066dd71992-09-17 17:54:56 +00001050 return newintobject((long)pgid);
1051}
Guido van Rossumb6775db1994-08-01 11:34:53 +00001052#endif /* HAVE_TCGETPGRP */
Guido van Rossum7066dd71992-09-17 17:54:56 +00001053
Guido van Rossumb6775db1994-08-01 11:34:53 +00001054#ifdef HAVE_TCSETPGRP
Guido van Rossum7066dd71992-09-17 17:54:56 +00001055static object *
1056posix_tcsetpgrp(self, args)
1057 object *self;
1058 object *args;
1059{
1060 int fd, pgid;
1061 if (!getargs(args, "(ii)", &fd, &pgid))
1062 return NULL;
Guido van Rossum687dd131993-05-17 08:34:16 +00001063 if (tcsetpgrp(fd, pgid) < 0)
1064 return posix_error();
Guido van Rossum7066dd71992-09-17 17:54:56 +00001065 INCREF(None);
1066 return None;
1067}
Guido van Rossumb6775db1994-08-01 11:34:53 +00001068#endif /* HAVE_TCSETPGRP */
Guido van Rossum22db57e1992-04-05 14:25:30 +00001069
Guido van Rossum687dd131993-05-17 08:34:16 +00001070/* Functions acting on file descriptors */
1071
Guido van Rossum234f9421993-06-17 12:35:49 +00001072static object *
Guido van Rossum687dd131993-05-17 08:34:16 +00001073posix_open(self, args)
1074 object *self;
1075 object *args;
1076{
1077 char *file;
1078 int flag;
1079 int mode = 0777;
1080 int fd;
1081 if (!getargs(args, "(si)", &file, &flag)) {
1082 err_clear();
1083 if (!getargs(args, "(sii)", &file, &flag, &mode))
1084 return NULL;
1085 }
1086 BGN_SAVE
1087 fd = open(file, flag, mode);
1088 END_SAVE
1089 if (fd < 0)
1090 return posix_error();
1091 return newintobject((long)fd);
1092}
1093
Guido van Rossum234f9421993-06-17 12:35:49 +00001094static object *
Guido van Rossum687dd131993-05-17 08:34:16 +00001095posix_close(self, args)
1096 object *self;
1097 object *args;
1098{
1099 int fd, res;
1100 if (!getargs(args, "i", &fd))
1101 return NULL;
1102 BGN_SAVE
1103 res = close(fd);
1104 END_SAVE
1105 if (res < 0)
1106 return posix_error();
1107 INCREF(None);
1108 return None;
1109}
1110
Guido van Rossum234f9421993-06-17 12:35:49 +00001111static object *
Guido van Rossum687dd131993-05-17 08:34:16 +00001112posix_dup(self, args)
1113 object *self;
1114 object *args;
1115{
1116 int fd;
1117 if (!getargs(args, "i", &fd))
1118 return NULL;
1119 BGN_SAVE
1120 fd = dup(fd);
1121 END_SAVE
1122 if (fd < 0)
1123 return posix_error();
1124 return newintobject((long)fd);
1125}
1126
Guido van Rossum234f9421993-06-17 12:35:49 +00001127static object *
Guido van Rossum687dd131993-05-17 08:34:16 +00001128posix_dup2(self, args)
1129 object *self;
1130 object *args;
1131{
1132 int fd, fd2, res;
1133 if (!getargs(args, "(ii)", &fd, &fd2))
1134 return NULL;
1135 BGN_SAVE
1136 res = dup2(fd, fd2);
1137 END_SAVE
1138 if (res < 0)
1139 return posix_error();
1140 INCREF(None);
1141 return None;
1142}
1143
Guido van Rossum234f9421993-06-17 12:35:49 +00001144static object *
Guido van Rossum687dd131993-05-17 08:34:16 +00001145posix_lseek(self, args)
1146 object *self;
1147 object *args;
1148{
1149 int fd, how;
1150 long pos, res;
1151 if (!getargs(args, "(ili)", &fd, &pos, &how))
1152 return NULL;
1153#ifdef SEEK_SET
1154 /* Turn 0, 1, 2 into SEEK_{SET,CUR,END} */
1155 switch (how) {
1156 case 0: how = SEEK_SET; break;
1157 case 1: how = SEEK_CUR; break;
1158 case 2: how = SEEK_END; break;
1159 }
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001160#endif /* SEEK_END */
Guido van Rossum687dd131993-05-17 08:34:16 +00001161 BGN_SAVE
1162 res = lseek(fd, pos, how);
1163 END_SAVE
1164 if (res < 0)
1165 return posix_error();
1166 return newintobject(res);
1167}
1168
Guido van Rossum234f9421993-06-17 12:35:49 +00001169static object *
Guido van Rossum687dd131993-05-17 08:34:16 +00001170posix_read(self, args)
1171 object *self;
1172 object *args;
1173{
1174 int fd, size;
1175 object *buffer;
1176 if (!getargs(args, "(ii)", &fd, &size))
1177 return NULL;
1178 buffer = newsizedstringobject((char *)NULL, size);
1179 if (buffer == NULL)
1180 return NULL;
1181 BGN_SAVE
1182 size = read(fd, getstringvalue(buffer), size);
1183 END_SAVE
1184 if (size < 0) {
1185 DECREF(buffer);
1186 return posix_error();
1187 }
1188 resizestring(&buffer, size);
1189 return buffer;
1190}
1191
Guido van Rossum234f9421993-06-17 12:35:49 +00001192static object *
Guido van Rossum687dd131993-05-17 08:34:16 +00001193posix_write(self, args)
1194 object *self;
1195 object *args;
1196{
1197 int fd, size;
1198 char *buffer;
1199 if (!getargs(args, "(is#)", &fd, &buffer, &size))
1200 return NULL;
1201 BGN_SAVE
1202 size = write(fd, buffer, size);
1203 END_SAVE
1204 if (size < 0)
1205 return posix_error();
1206 return newintobject((long)size);
1207}
1208
Guido van Rossum234f9421993-06-17 12:35:49 +00001209static object *
Guido van Rossum687dd131993-05-17 08:34:16 +00001210posix_fstat(self, args)
1211 object *self;
1212 object *args;
1213{
1214 int fd;
1215 struct stat st;
1216 int res;
1217 if (!getargs(args, "i", &fd))
1218 return NULL;
1219 BGN_SAVE
1220 res = fstat(fd, &st);
1221 END_SAVE
1222 if (res != 0)
1223 return posix_error();
1224 return mkvalue("(llllllllll)",
1225 (long)st.st_mode,
1226 (long)st.st_ino,
1227 (long)st.st_dev,
1228 (long)st.st_nlink,
1229 (long)st.st_uid,
1230 (long)st.st_gid,
1231 (long)st.st_size,
1232 (long)st.st_atime,
1233 (long)st.st_mtime,
1234 (long)st.st_ctime);
1235}
1236
1237static object *
1238posix_fdopen(self, args)
1239 object *self;
1240 object *args;
1241{
1242 extern int fclose PROTO((FILE *));
1243 int fd;
1244 char *mode;
1245 FILE *fp;
1246 if (!getargs(args, "(is)", &fd, &mode))
1247 return NULL;
1248 BGN_SAVE
1249 fp = fdopen(fd, mode);
1250 END_SAVE
1251 if (fp == NULL)
1252 return posix_error();
1253 /* From now on, ignore SIGPIPE and let the error checking
1254 do the work. */
Guido van Rossum687dd131993-05-17 08:34:16 +00001255 return newopenfileobject(fp, "(fdopen)", mode, fclose);
1256}
1257
Guido van Rossum234f9421993-06-17 12:35:49 +00001258static object *
Guido van Rossum687dd131993-05-17 08:34:16 +00001259posix_pipe(self, args)
1260 object *self;
1261 object *args;
1262{
1263 int fds[2];
1264 int res;
1265 if (!getargs(args, ""))
1266 return NULL;
1267 BGN_SAVE
1268 res = pipe(fds);
1269 END_SAVE
1270 if (res != 0)
1271 return posix_error();
1272 return mkvalue("(ii)", fds[0], fds[1]);
1273}
Guido van Rossum22db57e1992-04-05 14:25:30 +00001274
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001275static struct methodlist posix_methods[] = {
1276 {"chdir", posix_chdir},
1277 {"chmod", posix_chmod},
Guido van Rossumb6775db1994-08-01 11:34:53 +00001278#ifdef HAVE_CHOWN
1279 {"chown", posix_chown},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001280#endif /* HAVE_CHOWN */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001281 {"getcwd", posix_getcwd},
Guido van Rossumb6775db1994-08-01 11:34:53 +00001282#ifdef HAVE_LINK
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001283 {"link", posix_link},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001284#endif /* HAVE_LINK */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001285 {"listdir", posix_listdir},
Guido van Rossumc39de5f1992-02-05 11:15:54 +00001286 {"lstat", posix_lstat},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001287 {"mkdir", posix_mkdir},
Guido van Rossumb6775db1994-08-01 11:34:53 +00001288#ifdef HAVE_NICE
Guido van Rossum775f4da1993-01-09 17:18:52 +00001289 {"nice", posix_nice},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001290#endif /* HAVE_NICE */
Guido van Rossumb6775db1994-08-01 11:34:53 +00001291#ifdef HAVE_READLINK
Guido van Rossumc39de5f1992-02-05 11:15:54 +00001292 {"readlink", posix_readlink},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001293#endif /* HAVE_READLINK */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001294 {"rename", posix_rename},
1295 {"rmdir", posix_rmdir},
1296 {"stat", posix_stat},
Guido van Rossumb6775db1994-08-01 11:34:53 +00001297#ifdef HAVE_SYMLINK
Guido van Rossumc39de5f1992-02-05 11:15:54 +00001298 {"symlink", posix_symlink},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001299#endif /* HAVE_SYMLINK */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001300 {"system", posix_system},
1301 {"umask", posix_umask},
Guido van Rossumb6775db1994-08-01 11:34:53 +00001302#ifdef HAVE_UNAME
Guido van Rossumc39de5f1992-02-05 11:15:54 +00001303 {"uname", posix_uname},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001304#endif /* HAVE_UNAME */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001305 {"unlink", posix_unlink},
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00001306 {"utime", posix_utime},
Guido van Rossumb6775db1994-08-01 11:34:53 +00001307#ifdef HAVE_TIMES
Guido van Rossum22db57e1992-04-05 14:25:30 +00001308 {"times", posix_times},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001309#endif /* HAVE_TIMES */
Guido van Rossum85e3b011991-06-03 12:42:10 +00001310 {"_exit", posix__exit},
Guido van Rossum89b33251993-10-22 14:26:06 +00001311 {"execv", posix_execv},
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001312 {"execve", posix_execve},
Guido van Rossumb6775db1994-08-01 11:34:53 +00001313#ifndef NT
Guido van Rossum85e3b011991-06-03 12:42:10 +00001314 {"fork", posix_fork},
Guido van Rossum46003ff1992-05-15 11:05:24 +00001315 {"getegid", posix_getegid},
1316 {"geteuid", posix_geteuid},
1317 {"getgid", posix_getgid},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001318#endif /* !NT */
Guido van Rossum85e3b011991-06-03 12:42:10 +00001319 {"getpid", posix_getpid},
Guido van Rossumb6775db1994-08-01 11:34:53 +00001320#ifdef HAVE_GETPGRP
Guido van Rossum04814471991-06-04 20:23:49 +00001321 {"getpgrp", posix_getpgrp},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001322#endif /* HAVE_GETPGRP */
Guido van Rossumb6775db1994-08-01 11:34:53 +00001323#ifndef NT
Guido van Rossum85e3b011991-06-03 12:42:10 +00001324 {"getppid", posix_getppid},
Guido van Rossum46003ff1992-05-15 11:05:24 +00001325 {"getuid", posix_getuid},
Guido van Rossum85e3b011991-06-03 12:42:10 +00001326 {"kill", posix_kill},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001327#endif /* !NT */
Guido van Rossum3b066191991-06-04 19:40:25 +00001328 {"popen", posix_popen},
Guido van Rossumb6775db1994-08-01 11:34:53 +00001329#ifdef HAVE_SETUID
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00001330 {"setuid", posix_setuid},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001331#endif /* HAVE_SETUID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00001332#ifdef HAVE_SETGID
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00001333 {"setgid", posix_setgid},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001334#endif /* HAVE_SETGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00001335#ifdef HAVE_SETPGRP
Guido van Rossumc2670a01992-09-13 20:07:29 +00001336 {"setpgrp", posix_setpgrp},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001337#endif /* HAVE_SETPGRP */
Guido van Rossumb6775db1994-08-01 11:34:53 +00001338#ifndef NT
Guido van Rossum85e3b011991-06-03 12:42:10 +00001339 {"wait", posix_wait},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001340#endif /* !NT */
Guido van Rossumb6775db1994-08-01 11:34:53 +00001341#ifdef HAVE_WAITPID
Guido van Rossum21803b81992-08-09 12:55:27 +00001342 {"waitpid", posix_waitpid},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001343#endif /* HAVE_WAITPID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00001344#ifdef HAVE_SETSID
Guido van Rossumc2670a01992-09-13 20:07:29 +00001345 {"setsid", posix_setsid},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001346#endif /* HAVE_SETSID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00001347#ifdef HAVE_SETPGID
Guido van Rossumc2670a01992-09-13 20:07:29 +00001348 {"setpgid", posix_setpgid},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001349#endif /* HAVE_SETPGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00001350#ifdef HAVE_TCGETPGRP
Guido van Rossum7066dd71992-09-17 17:54:56 +00001351 {"tcgetpgrp", posix_tcgetpgrp},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001352#endif /* HAVE_TCGETPGRP */
Guido van Rossumb6775db1994-08-01 11:34:53 +00001353#ifdef HAVE_TCSETPGRP
Guido van Rossum7066dd71992-09-17 17:54:56 +00001354 {"tcsetpgrp", posix_tcsetpgrp},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001355#endif /* HAVE_TCSETPGRP */
Guido van Rossum687dd131993-05-17 08:34:16 +00001356 {"open", posix_open},
1357 {"close", posix_close},
1358 {"dup", posix_dup},
1359 {"dup2", posix_dup2},
1360 {"lseek", posix_lseek},
1361 {"read", posix_read},
1362 {"write", posix_write},
1363 {"fstat", posix_fstat},
1364 {"fdopen", posix_fdopen},
Guido van Rossumb6775db1994-08-01 11:34:53 +00001365#ifndef NT
Guido van Rossum687dd131993-05-17 08:34:16 +00001366 {"pipe", posix_pipe},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001367#endif /* !NT */
Guido van Rossum687dd131993-05-17 08:34:16 +00001368
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001369 {NULL, NULL} /* Sentinel */
1370};
1371
1372
Guido van Rossumb6775db1994-08-01 11:34:53 +00001373#ifdef NT
1374void
1375initnt()
1376{
1377 object *m, *d, *v;
1378
1379 m = initmodule("nt", posix_methods);
1380 d = getmoduledict(m);
1381
1382 /* Initialize nt.environ dictionary */
1383 v = convertenviron();
1384 if (v == NULL || dictinsert(d, "environ", v) != 0)
1385 fatal("can't define nt.environ");
1386 DECREF(v);
1387
1388 /* Initialize nt.error exception */
1389 PosixError = newstringobject("nt.error");
1390 if (PosixError == NULL || dictinsert(d, "error", PosixError) != 0)
1391 fatal("can't define nt.error");
1392}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001393#else /* !NT */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001394void
1395initposix()
1396{
1397 object *m, *d, *v;
1398
1399 m = initmodule("posix", posix_methods);
1400 d = getmoduledict(m);
1401
1402 /* Initialize posix.environ dictionary */
1403 v = convertenviron();
1404 if (v == NULL || dictinsert(d, "environ", v) != 0)
1405 fatal("can't define posix.environ");
1406 DECREF(v);
1407
1408 /* Initialize posix.error exception */
1409 PosixError = newstringobject("posix.error");
1410 if (PosixError == NULL || dictinsert(d, "error", PosixError) != 0)
1411 fatal("can't define posix.error");
1412}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001413#endif /* !NT */