blob: 7f20a8fc72b8e9cd597645d044591275d159b840 [file] [log] [blame]
Guido van Rossumf70e43a1991-02-19 12:39:46 +00001/***********************************************************
Guido van Rossum524b5881995-01-04 19:10:35 +00002Copyright 1991-1995 by Stichting Mathematisch Centrum, Amsterdam,
3The 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
Guido van Rossum14ed0b21994-09-29 09:50:09 +000079#ifdef HAVE_SYS_UTIME_H
80#include <sys/utime.h>
81#define HAVE_UTIME_H /* pretend we do for the rest of this file */
82#endif /* HAVE_SYS_UTIME_H */
83
Guido van Rossumb6775db1994-08-01 11:34:53 +000084#ifdef HAVE_SYS_TIMES_H
85#include <sys/times.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000086#endif /* HAVE_SYS_TIMES_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +000087
88#ifdef HAVE_SYS_PARAM_H
89#include <sys/param.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000090#endif /* HAVE_SYS_PARAM_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +000091
92#ifdef HAVE_SYS_UTSNAME_H
93#include <sys/utsname.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000094#endif /* HAVE_SYS_UTSNAME_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +000095
96#ifndef MAXPATHLEN
97#define MAXPATHLEN 1024
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000098#endif /* MAXPATHLEN */
Guido van Rossumb6775db1994-08-01 11:34:53 +000099
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000100#ifdef HAVE_DIRENT_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000101#include <dirent.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000102#define NAMLEN(dirent) strlen((dirent)->d_name)
103#else
Guido van Rossumb6775db1994-08-01 11:34:53 +0000104#define dirent direct
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000105#define NAMLEN(dirent) (dirent)->d_namlen
106#ifdef HAVE_SYS_NDIR_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000107#include <sys/ndir.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000108#endif
109#ifdef HAVE_SYS_DIR_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000110#include <sys/dir.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000111#endif
112#ifdef HAVE_NDIR_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000113#include <ndir.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000114#endif
115#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +0000116
117#ifdef NT
118#include <direct.h>
119#include <io.h>
120#include <process.h>
121#include <windows.h>
122#define popen _popen
Guido van Rossum794d8131994-08-23 13:48:48 +0000123#define pclose _pclose
Guido van Rossumb6775db1994-08-01 11:34:53 +0000124#endif /* NT */
125
126#ifdef OS2
127#include <io.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000128#endif /* OS2 */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000129
130/* Return a dictionary corresponding to the POSIX environment table */
131
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000132#ifndef NT
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000133extern char **environ;
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000134#endif /* !NT */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000135
136static object *
137convertenviron()
138{
139 object *d;
140 char **e;
141 d = newdictobject();
142 if (d == NULL)
143 return NULL;
144 if (environ == NULL)
145 return d;
146 /* XXX This part ignores errors */
147 for (e = environ; *e != NULL; e++) {
148 object *v;
149 char *p = strchr(*e, '=');
150 if (p == NULL)
151 continue;
152 v = newstringobject(p+1);
153 if (v == NULL)
154 continue;
155 *p = '\0';
156 (void) dictinsert(d, *e, v);
157 *p = '=';
158 DECREF(v);
159 }
160 return d;
161}
162
163
164static object *PosixError; /* Exception posix.error */
165
166/* Set a POSIX-specific error from errno, and return NULL */
167
Guido van Rossum687dd131993-05-17 08:34:16 +0000168static object * posix_error() { return err_errno(PosixError);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000169}
170
171
172/* POSIX generic methods */
173
174static object *
175posix_1str(args, func)
176 object *args;
177 int (*func) FPROTO((const char *));
178{
Guido van Rossumef0a00e1992-01-27 16:51:30 +0000179 char *path1;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000180 int res;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +0000181 if (!getargs(args, "s", &path1))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000182 return NULL;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000183 BGN_SAVE
184 res = (*func)(path1);
185 END_SAVE
186 if (res < 0)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000187 return posix_error();
188 INCREF(None);
189 return None;
190}
191
192static object *
193posix_2str(args, func)
194 object *args;
195 int (*func) FPROTO((const char *, const char *));
196{
Guido van Rossumef0a00e1992-01-27 16:51:30 +0000197 char *path1, *path2;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000198 int res;
Guido van Rossum234f9421993-06-17 12:35:49 +0000199 if (!getargs(args, "(ss)", &path1, &path2))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000200 return NULL;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000201 BGN_SAVE
202 res = (*func)(path1, path2);
203 END_SAVE
204 if (res < 0)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000205 return posix_error();
206 INCREF(None);
207 return None;
208}
209
210static object *
211posix_strint(args, func)
212 object *args;
213 int (*func) FPROTO((const char *, int));
214{
Guido van Rossumef0a00e1992-01-27 16:51:30 +0000215 char *path;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000216 int i;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000217 int res;
Guido van Rossum234f9421993-06-17 12:35:49 +0000218 if (!getargs(args, "(si)", &path, &i))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000219 return NULL;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000220 BGN_SAVE
221 res = (*func)(path, i);
222 END_SAVE
223 if (res < 0)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000224 return posix_error();
225 INCREF(None);
226 return None;
227}
228
229static object *
Guido van Rossumb6775db1994-08-01 11:34:53 +0000230posix_strintint(args, func)
231 object *args;
232 int (*func) FPROTO((const char *, int, int));
233{
234 char *path;
235 int i,i2;
236 int res;
237 if (!getargs(args, "(sii)", &path, &i, &i2))
238 return NULL;
239 BGN_SAVE
240 res = (*func)(path, i, i2);
241 END_SAVE
242 if (res < 0)
243 return posix_error();
244 INCREF(None);
245 return None;
246}
247
248static object *
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000249posix_do_stat(self, args, statfunc)
250 object *self;
251 object *args;
252 int (*statfunc) FPROTO((const char *, struct stat *));
253{
254 struct stat st;
Guido van Rossumef0a00e1992-01-27 16:51:30 +0000255 char *path;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000256 int res;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +0000257 if (!getargs(args, "s", &path))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000258 return NULL;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000259 BGN_SAVE
260 res = (*statfunc)(path, &st);
261 END_SAVE
262 if (res != 0)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000263 return posix_error();
Guido van Rossum687dd131993-05-17 08:34:16 +0000264 return mkvalue("(llllllllll)",
Guido van Rossume5372401993-03-16 12:15:04 +0000265 (long)st.st_mode,
266 (long)st.st_ino,
267 (long)st.st_dev,
268 (long)st.st_nlink,
269 (long)st.st_uid,
270 (long)st.st_gid,
271 (long)st.st_size,
272 (long)st.st_atime,
273 (long)st.st_mtime,
274 (long)st.st_ctime);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000275}
276
277
278/* POSIX methods */
279
280static object *
281posix_chdir(self, args)
282 object *self;
283 object *args;
284{
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000285 return posix_1str(args, chdir);
286}
287
288static object *
289posix_chmod(self, args)
290 object *self;
291 object *args;
292{
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000293 return posix_strint(args, chmod);
294}
295
Guido van Rossumb6775db1994-08-01 11:34:53 +0000296#ifdef HAVE_CHOWN
297static object *
298posix_chown(self, args)
299 object *self;
300 object *args;
301{
302 return posix_strintint(args, chown);
303}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000304#endif /* HAVE_CHOWN */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000305
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000306static object *
307posix_getcwd(self, args)
308 object *self;
309 object *args;
310{
311 char buf[1026];
Guido van Rossumff4949e1992-08-05 19:58:53 +0000312 char *res;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000313 if (!getnoarg(args))
314 return NULL;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000315 BGN_SAVE
316 res = getcwd(buf, sizeof buf);
317 END_SAVE
318 if (res == NULL)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000319 return posix_error();
320 return newstringobject(buf);
321}
322
Guido van Rossumb6775db1994-08-01 11:34:53 +0000323#ifdef HAVE_LINK
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000324static object *
325posix_link(self, args)
326 object *self;
327 object *args;
328{
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000329 return posix_2str(args, link);
330}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000331#endif /* HAVE_LINK */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000332
Guido van Rossumb6775db1994-08-01 11:34:53 +0000333static object *
334posix_listdir(self, args)
335 object *self;
336 object *args;
337{
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000338#ifdef NT
339
Guido van Rossumb6775db1994-08-01 11:34:53 +0000340 char *name;
341 int len;
342 object *d, *v;
343 HANDLE hFindFile;
344 WIN32_FIND_DATA FileData;
345 char namebuf[MAX_PATH+5];
346
347 if (!getargs(args, "s#", &name, &len))
348 return NULL;
349 if (len >= MAX_PATH) {
350 err_setstr(ValueError, "path too long");
351 return NULL;
352 }
353 strcpy(namebuf, name);
354 if (namebuf[len-1] != '/' && namebuf[len-1] != '\\')
355 namebuf[len++] = '/';
356 strcpy(namebuf + len, "*.*");
357
358 if ((d = newlistobject(0)) == NULL)
359 return NULL;
360
361 hFindFile = FindFirstFile(namebuf, &FileData);
362 if (hFindFile == INVALID_HANDLE_VALUE) {
363 errno = GetLastError();
364 return posix_error();
365 }
366 do {
367 v = newstringobject(FileData.cFileName);
368 if (v == NULL) {
369 DECREF(d);
370 d = NULL;
371 break;
372 }
373 if (addlistitem(d, v) != 0) {
374 DECREF(v);
375 DECREF(d);
376 d = NULL;
377 break;
378 }
379 DECREF(v);
380 } while (FindNextFile(hFindFile, &FileData) == TRUE);
381
382 if (FindClose(hFindFile) == FALSE) {
383 errno = GetLastError();
384 return posix_error();
385 }
386
387 return d;
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000388
389#else /* !NT */
390
Guido van Rossumef0a00e1992-01-27 16:51:30 +0000391 char *name;
392 object *d, *v;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000393 DIR *dirp;
Guido van Rossumb6775db1994-08-01 11:34:53 +0000394 struct dirent *ep;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +0000395 if (!getargs(args, "s", &name))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000396 return NULL;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000397 BGN_SAVE
398 if ((dirp = opendir(name)) == NULL) {
399 RET_SAVE
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000400 return posix_error();
Guido van Rossumff4949e1992-08-05 19:58:53 +0000401 }
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000402 if ((d = newlistobject(0)) == NULL) {
403 closedir(dirp);
Guido van Rossumff4949e1992-08-05 19:58:53 +0000404 RET_SAVE
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000405 return NULL;
406 }
407 while ((ep = readdir(dirp)) != NULL) {
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000408 v = newsizedstringobject(ep->d_name, NAMLEN(ep));
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000409 if (v == NULL) {
410 DECREF(d);
411 d = NULL;
412 break;
413 }
414 if (addlistitem(d, v) != 0) {
415 DECREF(v);
416 DECREF(d);
417 d = NULL;
418 break;
419 }
420 DECREF(v);
421 }
422 closedir(dirp);
Guido van Rossumff4949e1992-08-05 19:58:53 +0000423 END_SAVE
Guido van Rossum0ee42cd1991-04-08 21:01:03 +0000424
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000425 return d;
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000426
427#endif /* !NT */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000428}
429
430static object *
431posix_mkdir(self, args)
432 object *self;
433 object *args;
434{
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000435 return posix_strint(args, mkdir);
436}
437
Guido van Rossumb6775db1994-08-01 11:34:53 +0000438#ifdef HAVE_NICE
Guido van Rossum775f4da1993-01-09 17:18:52 +0000439static object *
440posix_nice(self, args)
441 object *self;
442 object *args;
443{
444 int increment, value;
445
446 if (!getargs(args, "i", &increment))
447 return NULL;
448 value = nice(increment);
449 if (value == -1)
450 return posix_error();
451 return newintobject((long) value);
452}
Guido van Rossumb6775db1994-08-01 11:34:53 +0000453#endif /* HAVE_NICE */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +0000454
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000455static object *
456posix_rename(self, args)
457 object *self;
458 object *args;
459{
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000460 return posix_2str(args, rename);
461}
462
463static object *
464posix_rmdir(self, args)
465 object *self;
466 object *args;
467{
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000468 return posix_1str(args, rmdir);
469}
470
471static object *
472posix_stat(self, args)
473 object *self;
474 object *args;
475{
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000476 return posix_do_stat(self, args, stat);
477}
478
479static object *
480posix_system(self, args)
481 object *self;
482 object *args;
483{
Guido van Rossumef0a00e1992-01-27 16:51:30 +0000484 char *command;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000485 long sts;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +0000486 if (!getargs(args, "s", &command))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000487 return NULL;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000488 BGN_SAVE
Guido van Rossumef0a00e1992-01-27 16:51:30 +0000489 sts = system(command);
Guido van Rossumff4949e1992-08-05 19:58:53 +0000490 END_SAVE
491 return newintobject(sts);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000492}
493
494static object *
495posix_umask(self, args)
496 object *self;
497 object *args;
498{
499 int i;
500 if (!getintarg(args, &i))
501 return NULL;
502 i = umask(i);
503 if (i < 0)
504 return posix_error();
505 return newintobject((long)i);
506}
507
508static object *
509posix_unlink(self, args)
510 object *self;
511 object *args;
512{
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000513 return posix_1str(args, unlink);
514}
515
Guido van Rossumb6775db1994-08-01 11:34:53 +0000516#ifdef HAVE_UNAME
Guido van Rossumc39de5f1992-02-05 11:15:54 +0000517static object *
518posix_uname(self, args)
519 object *self;
520 object *args;
521{
Guido van Rossumc39de5f1992-02-05 11:15:54 +0000522 struct utsname u;
523 object *v;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000524 int res;
Guido van Rossum50e61dc1992-03-27 17:22:31 +0000525 if (!getnoarg(args))
526 return NULL;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000527 BGN_SAVE
528 res = uname(&u);
529 END_SAVE
530 if (res < 0)
Guido van Rossumc39de5f1992-02-05 11:15:54 +0000531 return posix_error();
Guido van Rossume5372401993-03-16 12:15:04 +0000532 return mkvalue("(sssss)",
533 u.sysname,
534 u.nodename,
535 u.release,
536 u.version,
537 u.machine);
Guido van Rossumc39de5f1992-02-05 11:15:54 +0000538}
Guido van Rossumb6775db1994-08-01 11:34:53 +0000539#endif /* HAVE_UNAME */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +0000540
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000541static object *
Guido van Rossum1ff6cb41991-04-08 20:59:13 +0000542posix_utime(self, args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000543 object *self;
544 object *args;
545{
Guido van Rossumef0a00e1992-01-27 16:51:30 +0000546 char *path;
Guido van Rossumf8803dd1995-01-26 00:37:45 +0000547 long atime, mtime;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000548 int res;
Guido van Rossum1ff6cb41991-04-08 20:59:13 +0000549
Guido van Rossumb6775db1994-08-01 11:34:53 +0000550#ifdef HAVE_UTIME_H
Guido van Rossum1ff6cb41991-04-08 20:59:13 +0000551 struct utimbuf buf;
552#define ATIME buf.actime
553#define MTIME buf.modtime
554#define UTIME_ARG &buf
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000555#else /* HAVE_UTIME_H */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +0000556 time_t buf[2];
557#define ATIME buf[0]
558#define MTIME buf[1]
559#define UTIME_ARG buf
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000560#endif /* HAVE_UTIME_H */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +0000561
Guido van Rossumf8803dd1995-01-26 00:37:45 +0000562 if (!getargs(args, "(s(ll))", &path, &atime, &mtime))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000563 return NULL;
Guido van Rossumf8803dd1995-01-26 00:37:45 +0000564 ATIME = atime;
565 MTIME = utime;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000566 BGN_SAVE
567 res = utime(path, UTIME_ARG);
568 END_SAVE
569 if (res < 0)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000570 return posix_error();
571 INCREF(None);
572 return None;
Guido van Rossum1ff6cb41991-04-08 20:59:13 +0000573#undef UTIME_ARG
574#undef ATIME
575#undef MTIME
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000576}
577
Guido van Rossum85e3b011991-06-03 12:42:10 +0000578
Guido van Rossum3b066191991-06-04 19:40:25 +0000579/* Process operations */
Guido van Rossum85e3b011991-06-03 12:42:10 +0000580
581static object *
582posix__exit(self, args)
583 object *self;
584 object *args;
585{
586 int sts;
587 if (!getintarg(args, &sts))
588 return NULL;
589 _exit(sts);
590 /* NOTREACHED */
591}
592
Guido van Rossum85e3b011991-06-03 12:42:10 +0000593static object *
Guido van Rossum89b33251993-10-22 14:26:06 +0000594posix_execv(self, args)
Guido van Rossum85e3b011991-06-03 12:42:10 +0000595 object *self;
596 object *args;
597{
Guido van Rossumef0a00e1992-01-27 16:51:30 +0000598 char *path;
599 object *argv;
Guido van Rossum85e3b011991-06-03 12:42:10 +0000600 char **argvlist;
601 int i, argc;
602 object *(*getitem) PROTO((object *, int));
603
Guido van Rossum89b33251993-10-22 14:26:06 +0000604 /* execv has two arguments: (path, argv), where
Guido van Rossum85e3b011991-06-03 12:42:10 +0000605 argv is a list or tuple of strings. */
606
Guido van Rossumef0a00e1992-01-27 16:51:30 +0000607 if (!getargs(args, "(sO)", &path, &argv))
Guido van Rossum85e3b011991-06-03 12:42:10 +0000608 return NULL;
Guido van Rossum85e3b011991-06-03 12:42:10 +0000609 if (is_listobject(argv)) {
610 argc = getlistsize(argv);
611 getitem = getlistitem;
612 }
613 else if (is_tupleobject(argv)) {
614 argc = gettuplesize(argv);
615 getitem = gettupleitem;
616 }
Guido van Rossumef0a00e1992-01-27 16:51:30 +0000617 else {
618 badarg:
619 err_badarg();
620 return NULL;
621 }
Guido van Rossum85e3b011991-06-03 12:42:10 +0000622
623 argvlist = NEW(char *, argc+1);
624 if (argvlist == NULL)
625 return NULL;
626 for (i = 0; i < argc; i++) {
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +0000627 if (!getargs((*getitem)(argv, i), "s", &argvlist[i])) {
Guido van Rossum85e3b011991-06-03 12:42:10 +0000628 DEL(argvlist);
629 goto badarg;
630 }
Guido van Rossum85e3b011991-06-03 12:42:10 +0000631 }
632 argvlist[argc] = NULL;
633
Guido van Rossumb6775db1994-08-01 11:34:53 +0000634#ifdef BAD_EXEC_PROTOTYPES
635 execv(path, (const char **) argvlist);
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000636#else /* BAD_EXEC_PROTOTYPES */
Guido van Rossumef0a00e1992-01-27 16:51:30 +0000637 execv(path, argvlist);
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000638#endif /* BAD_EXEC_PROTOTYPES */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000639
Guido van Rossum85e3b011991-06-03 12:42:10 +0000640 /* If we get here it's definitely an error */
641
642 DEL(argvlist);
643 return posix_error();
644}
645
646static object *
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +0000647posix_execve(self, args)
648 object *self;
649 object *args;
650{
651 char *path;
652 object *argv, *env;
653 char **argvlist;
654 char **envlist;
655 object *key, *val;
656 int i, pos, argc, envc;
657 object *(*getitem) PROTO((object *, int));
658
659 /* execve has three arguments: (path, argv, env), where
660 argv is a list or tuple of strings and env is a dictionary
661 like posix.environ. */
662
663 if (!getargs(args, "(sOO)", &path, &argv, &env))
664 return NULL;
665 if (is_listobject(argv)) {
666 argc = getlistsize(argv);
667 getitem = getlistitem;
668 }
669 else if (is_tupleobject(argv)) {
670 argc = gettuplesize(argv);
671 getitem = gettupleitem;
672 }
673 else {
674 err_setstr(TypeError, "argv must be tuple or list");
675 return NULL;
676 }
677 if (!is_dictobject(env)) {
678 err_setstr(TypeError, "env must be dictionary");
679 return NULL;
680 }
681
682 argvlist = NEW(char *, argc+1);
683 if (argvlist == NULL) {
684 err_nomem();
685 return NULL;
686 }
687 for (i = 0; i < argc; i++) {
688 if (!getargs((*getitem)(argv, i),
689 "s;argv must be list of strings",
690 &argvlist[i])) {
691 goto fail_1;
692 }
693 }
694 argvlist[argc] = NULL;
695
696 i = getmappingsize(env);
697 envlist = NEW(char *, i + 1);
698 if (envlist == NULL) {
699 err_nomem();
700 goto fail_1;
701 }
702 pos = 0;
703 envc = 0;
704 while (mappinggetnext(env, &pos, &key, &val)) {
705 char *p, *k, *v;
706 if (!getargs(key, "s;non-string key in env", &k) ||
707 !getargs(val, "s;non-string value in env", &v)) {
708 goto fail_2;
709 }
710 p = NEW(char, getstringsize(key) + getstringsize(val) + 2);
711 if (p == NULL) {
712 err_nomem();
713 goto fail_2;
714 }
715 sprintf(p, "%s=%s", k, v);
716 envlist[envc++] = p;
717 }
718 envlist[envc] = 0;
719
Guido van Rossumb6775db1994-08-01 11:34:53 +0000720
721#ifdef BAD_EXEC_PROTOTYPES
722 execve(path, (const char **)argvlist, envlist);
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000723#else /* BAD_EXEC_PROTOTYPES */
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +0000724 execve(path, argvlist, envlist);
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000725#endif /* BAD_EXEC_PROTOTYPES */
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +0000726
727 /* If we get here it's definitely an error */
728
729 (void) posix_error();
730
731 fail_2:
732 while (--envc >= 0)
733 DEL(envlist[envc]);
734 DEL(envlist);
735 fail_1:
736 DEL(argvlist);
737
738 return NULL;
739}
740
Guido van Rossum794d8131994-08-23 13:48:48 +0000741#ifndef NT
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +0000742static object *
Guido van Rossum85e3b011991-06-03 12:42:10 +0000743posix_fork(self, args)
744 object *self;
745 object *args;
746{
747 int pid;
Guido van Rossum50e61dc1992-03-27 17:22:31 +0000748 if (!getnoarg(args))
749 return NULL;
Guido van Rossum85e3b011991-06-03 12:42:10 +0000750 pid = fork();
751 if (pid == -1)
752 return posix_error();
753 return newintobject((long)pid);
754}
755
756static object *
Guido van Rossum46003ff1992-05-15 11:05:24 +0000757posix_getegid(self, args)
758 object *self;
759 object *args;
760{
761 if (!getnoarg(args))
762 return NULL;
763 return newintobject((long)getegid());
764}
765
766static object *
767posix_geteuid(self, args)
768 object *self;
769 object *args;
770{
771 if (!getnoarg(args))
772 return NULL;
773 return newintobject((long)geteuid());
774}
775
776static object *
777posix_getgid(self, args)
778 object *self;
779 object *args;
780{
781 if (!getnoarg(args))
782 return NULL;
783 return newintobject((long)getgid());
784}
Guido van Rossumb078ce11994-08-29 14:01:43 +0000785#endif /* !NT */
Guido van Rossum46003ff1992-05-15 11:05:24 +0000786
787static object *
Guido van Rossum85e3b011991-06-03 12:42:10 +0000788posix_getpid(self, args)
789 object *self;
790 object *args;
791{
Guido van Rossum04814471991-06-04 20:23:49 +0000792 if (!getnoarg(args))
Guido van Rossum85e3b011991-06-03 12:42:10 +0000793 return NULL;
794 return newintobject((long)getpid());
795}
796
Guido van Rossumb6775db1994-08-01 11:34:53 +0000797#ifdef HAVE_GETPGRP
Guido van Rossum85e3b011991-06-03 12:42:10 +0000798static object *
Guido van Rossum04814471991-06-04 20:23:49 +0000799posix_getpgrp(self, args)
800 object *self;
801 object *args;
802{
803 if (!getnoarg(args))
804 return NULL;
Guido van Rossumb6775db1994-08-01 11:34:53 +0000805#ifdef GETPGRP_HAVE_ARG
Guido van Rossum971443b1991-06-07 13:59:29 +0000806 return newintobject((long)getpgrp(0));
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000807#else /* GETPGRP_HAVE_ARG */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000808 return newintobject((long)getpgrp());
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000809#endif /* GETPGRP_HAVE_ARG */
Guido van Rossum04814471991-06-04 20:23:49 +0000810}
Guido van Rossumb6775db1994-08-01 11:34:53 +0000811#endif /* HAVE_GETPGRP */
Guido van Rossum04814471991-06-04 20:23:49 +0000812
Guido van Rossumb6775db1994-08-01 11:34:53 +0000813#ifdef HAVE_SETPGRP
Guido van Rossum04814471991-06-04 20:23:49 +0000814static object *
Guido van Rossumc2670a01992-09-13 20:07:29 +0000815posix_setpgrp(self, args)
816 object *self;
817 object *args;
818{
819 if (!getnoarg(args))
820 return NULL;
Guido van Rossum64933891994-10-20 21:56:42 +0000821#ifdef SETPGRP_HAVE_ARG
Guido van Rossumc2670a01992-09-13 20:07:29 +0000822 if (setpgrp(0, 0) < 0)
Guido van Rossum64933891994-10-20 21:56:42 +0000823#else /* SETPGRP_HAVE_ARG */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000824 if (setpgrp() < 0)
Guido van Rossum64933891994-10-20 21:56:42 +0000825#endif /* SETPGRP_HAVE_ARG */
Guido van Rossum687dd131993-05-17 08:34:16 +0000826 return posix_error();
Guido van Rossumc2670a01992-09-13 20:07:29 +0000827 INCREF(None);
828 return None;
829}
830
Guido van Rossumb6775db1994-08-01 11:34:53 +0000831#endif /* HAVE_SETPGRP */
832
Guido van Rossum794d8131994-08-23 13:48:48 +0000833#ifndef NT
Guido van Rossumc2670a01992-09-13 20:07:29 +0000834static object *
Guido van Rossum85e3b011991-06-03 12:42:10 +0000835posix_getppid(self, args)
836 object *self;
837 object *args;
838{
Guido van Rossum04814471991-06-04 20:23:49 +0000839 if (!getnoarg(args))
Guido van Rossum85e3b011991-06-03 12:42:10 +0000840 return NULL;
841 return newintobject((long)getppid());
842}
843
844static object *
Guido van Rossum46003ff1992-05-15 11:05:24 +0000845posix_getuid(self, args)
846 object *self;
847 object *args;
848{
849 if (!getnoarg(args))
850 return NULL;
851 return newintobject((long)getuid());
852}
853
854static object *
Guido van Rossum85e3b011991-06-03 12:42:10 +0000855posix_kill(self, args)
856 object *self;
857 object *args;
858{
859 int pid, sig;
Guido van Rossum234f9421993-06-17 12:35:49 +0000860 if (!getargs(args, "(ii)", &pid, &sig))
Guido van Rossum85e3b011991-06-03 12:42:10 +0000861 return NULL;
862 if (kill(pid, sig) == -1)
863 return posix_error();
864 INCREF(None);
865 return None;
866}
Guido van Rossum794d8131994-08-23 13:48:48 +0000867#endif /* !NT */
Guido van Rossum85e3b011991-06-03 12:42:10 +0000868
869static object *
Guido van Rossum3b066191991-06-04 19:40:25 +0000870posix_popen(self, args)
871 object *self;
872 object *args;
873{
Guido van Rossuma6a1e531995-01-10 15:36:38 +0000874 char *name;
875 char *mode = "r";
876 int bufsize = -1;
Guido van Rossum3b066191991-06-04 19:40:25 +0000877 FILE *fp;
Guido van Rossuma6a1e531995-01-10 15:36:38 +0000878 object *f;
879 if (!newgetargs(args, "s|si", &name, &mode, &bufsize))
Guido van Rossum3b066191991-06-04 19:40:25 +0000880 return NULL;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000881 BGN_SAVE
Guido van Rossumef0a00e1992-01-27 16:51:30 +0000882 fp = popen(name, mode);
Guido van Rossumff4949e1992-08-05 19:58:53 +0000883 END_SAVE
Guido van Rossum3b066191991-06-04 19:40:25 +0000884 if (fp == NULL)
885 return posix_error();
Guido van Rossuma6a1e531995-01-10 15:36:38 +0000886 f = newopenfileobject(fp, name, mode, pclose);
887 if (f != NULL)
888 setfilebufsize(f, bufsize);
889 return f;
Guido van Rossum3b066191991-06-04 19:40:25 +0000890}
891
Guido van Rossumb6775db1994-08-01 11:34:53 +0000892#ifdef HAVE_SETUID
Guido van Rossum3b066191991-06-04 19:40:25 +0000893static object *
Guido van Rossuma3d78fb1993-11-10 09:23:53 +0000894posix_setuid(self, args)
895 object *self;
896 object *args;
897{
898 int uid;
899 if (!getargs(args, "i", &uid))
900 return NULL;
901 if (setuid(uid) < 0)
902 return posix_error();
903 INCREF(None);
904 return None;
905}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000906#endif /* HAVE_SETUID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +0000907
Guido van Rossumb6775db1994-08-01 11:34:53 +0000908#ifdef HAVE_SETGID
Guido van Rossuma3d78fb1993-11-10 09:23:53 +0000909static object *
910posix_setgid(self, args)
911 object *self;
912 object *args;
913{
914 int gid;
915 if (!getargs(args, "i", &gid))
916 return NULL;
917 if (setgid(gid) < 0)
918 return posix_error();
919 INCREF(None);
920 return None;
921}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000922#endif /* HAVE_SETGID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +0000923
Guido van Rossumb6775db1994-08-01 11:34:53 +0000924#ifdef HAVE_WAITPID
Guido van Rossuma3d78fb1993-11-10 09:23:53 +0000925static object *
Guido van Rossum21803b81992-08-09 12:55:27 +0000926posix_waitpid(self, args)
Guido van Rossum85e3b011991-06-03 12:42:10 +0000927 object *self;
928 object *args;
929{
Guido van Rossum21803b81992-08-09 12:55:27 +0000930 int pid, options, sts;
931 if (!getargs(args, "(ii)", &pid, &options))
932 return NULL;
933 BGN_SAVE
934 pid = waitpid(pid, &sts, options);
935 END_SAVE
Guido van Rossum85e3b011991-06-03 12:42:10 +0000936 if (pid == -1)
937 return posix_error();
Guido van Rossum21803b81992-08-09 12:55:27 +0000938 else
939 return mkvalue("ii", pid, sts);
Guido van Rossum21803b81992-08-09 12:55:27 +0000940}
Guido van Rossumb6775db1994-08-01 11:34:53 +0000941#endif /* HAVE_WAITPID */
Guido van Rossum21803b81992-08-09 12:55:27 +0000942
Guido van Rossum794d8131994-08-23 13:48:48 +0000943#ifndef NT
Guido van Rossum21803b81992-08-09 12:55:27 +0000944static object *
945posix_wait(self, args)
946 object *self;
947 object *args;
948{
949 int pid, sts;
Guido van Rossum21803b81992-08-09 12:55:27 +0000950 BGN_SAVE
951 pid = wait(&sts);
952 END_SAVE
953 if (pid == -1)
954 return posix_error();
955 else
956 return mkvalue("ii", pid, sts);
Guido van Rossum85e3b011991-06-03 12:42:10 +0000957}
Guido van Rossum794d8131994-08-23 13:48:48 +0000958#endif /* !NT */
Guido van Rossum85e3b011991-06-03 12:42:10 +0000959
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000960static object *
961posix_lstat(self, args)
962 object *self;
963 object *args;
964{
Guido van Rossumb6775db1994-08-01 11:34:53 +0000965#ifdef HAVE_LSTAT
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000966 return posix_do_stat(self, args, lstat);
Guido van Rossumb6775db1994-08-01 11:34:53 +0000967#else /* !HAVE_LSTAT */
968 return posix_do_stat(self, args, stat);
969#endif /* !HAVE_LSTAT */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000970}
971
Guido van Rossumb6775db1994-08-01 11:34:53 +0000972#ifdef HAVE_READLINK
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000973static object *
974posix_readlink(self, args)
975 object *self;
976 object *args;
977{
Guido van Rossumb6775db1994-08-01 11:34:53 +0000978 char buf[MAXPATHLEN];
Guido van Rossumef0a00e1992-01-27 16:51:30 +0000979 char *path;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000980 int n;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +0000981 if (!getargs(args, "s", &path))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000982 return NULL;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000983 BGN_SAVE
Guido van Rossum50e61dc1992-03-27 17:22:31 +0000984 n = readlink(path, buf, (int) sizeof buf);
Guido van Rossumff4949e1992-08-05 19:58:53 +0000985 END_SAVE
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000986 if (n < 0)
987 return posix_error();
988 return newsizedstringobject(buf, n);
989}
Guido van Rossumb6775db1994-08-01 11:34:53 +0000990#endif /* HAVE_READLINK */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000991
Guido van Rossumb6775db1994-08-01 11:34:53 +0000992#ifdef HAVE_SYMLINK
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000993static object *
994posix_symlink(self, args)
995 object *self;
996 object *args;
997{
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000998 return posix_2str(args, symlink);
999}
Guido van Rossumb6775db1994-08-01 11:34:53 +00001000#endif /* HAVE_SYMLINK */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001001
Guido van Rossumb6775db1994-08-01 11:34:53 +00001002#ifdef HAVE_TIMES
1003#ifndef HZ
1004#define HZ 60 /* Universal constant :-) */
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001005#endif /* HZ */
Guido van Rossum22db57e1992-04-05 14:25:30 +00001006static object *
1007posix_times(self, args)
1008 object *self;
1009 object *args;
1010{
1011 struct tms t;
1012 clock_t c;
Guido van Rossum22db57e1992-04-05 14:25:30 +00001013 if (!getnoarg(args))
1014 return NULL;
1015 errno = 0;
1016 c = times(&t);
Guido van Rossum687dd131993-05-17 08:34:16 +00001017 if (c == (clock_t) -1)
1018 return posix_error();
Guido van Rossum0b0db8e1993-01-21 16:07:51 +00001019 return mkvalue("dddd",
1020 (double)t.tms_utime / HZ,
1021 (double)t.tms_stime / HZ,
1022 (double)t.tms_cutime / HZ,
1023 (double)t.tms_cstime / HZ);
Guido van Rossum22db57e1992-04-05 14:25:30 +00001024}
Guido van Rossumb6775db1994-08-01 11:34:53 +00001025#endif /* HAVE_TIMES */
Guido van Rossum14ed0b21994-09-29 09:50:09 +00001026#ifdef NT
1027#define HAVE_TIMES /* so the method table will pick it up */
1028static object *
1029posix_times(self, args)
1030 object *self;
1031 object *args;
1032{
1033 FILETIME create, exit, kernel, user;
1034 HANDLE hProc;
1035 if (!getnoarg(args))
1036 return NULL;
1037 hProc = GetCurrentProcess();
1038 GetProcessTimes(hProc,&create, &exit, &kernel, &user);
1039 return mkvalue("dddd",
1040 (double)(kernel.dwHighDateTime*2E32+kernel.dwLowDateTime) / 2E6,
1041 (double)(user.dwHighDateTime*2E32+user.dwLowDateTime) / 2E6,
1042 (double)0,
1043 (double)0);
1044}
1045#endif /* NT */
Guido van Rossum22db57e1992-04-05 14:25:30 +00001046
Guido van Rossumb6775db1994-08-01 11:34:53 +00001047#ifdef HAVE_SETSID
Guido van Rossumc2670a01992-09-13 20:07:29 +00001048static object *
1049posix_setsid(self, args)
1050 object *self;
1051 object *args;
1052{
1053 if (!getnoarg(args))
1054 return NULL;
Guido van Rossum687dd131993-05-17 08:34:16 +00001055 if (setsid() < 0)
1056 return posix_error();
Guido van Rossumc2670a01992-09-13 20:07:29 +00001057 INCREF(None);
1058 return None;
1059}
Guido van Rossumb6775db1994-08-01 11:34:53 +00001060#endif /* HAVE_SETSID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00001061
Guido van Rossumb6775db1994-08-01 11:34:53 +00001062#ifdef HAVE_SETPGID
Guido van Rossumc2670a01992-09-13 20:07:29 +00001063static object *
1064posix_setpgid(self, args)
1065 object *self;
1066 object *args;
1067{
1068 int pid, pgrp;
1069 if (!getargs(args, "(ii)", &pid, &pgrp))
1070 return NULL;
Guido van Rossum687dd131993-05-17 08:34:16 +00001071 if (setpgid(pid, pgrp) < 0)
1072 return posix_error();
Guido van Rossumc2670a01992-09-13 20:07:29 +00001073 INCREF(None);
1074 return None;
1075}
Guido van Rossumb6775db1994-08-01 11:34:53 +00001076#endif /* HAVE_SETPGID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00001077
Guido van Rossumb6775db1994-08-01 11:34:53 +00001078#ifdef HAVE_TCGETPGRP
Guido van Rossum7066dd71992-09-17 17:54:56 +00001079static object *
1080posix_tcgetpgrp(self, args)
1081 object *self;
1082 object *args;
1083{
1084 int fd, pgid;
1085 if (!getargs(args, "i", &fd))
1086 return NULL;
1087 pgid = tcgetpgrp(fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00001088 if (pgid < 0)
1089 return posix_error();
Guido van Rossum7066dd71992-09-17 17:54:56 +00001090 return newintobject((long)pgid);
1091}
Guido van Rossumb6775db1994-08-01 11:34:53 +00001092#endif /* HAVE_TCGETPGRP */
Guido van Rossum7066dd71992-09-17 17:54:56 +00001093
Guido van Rossumb6775db1994-08-01 11:34:53 +00001094#ifdef HAVE_TCSETPGRP
Guido van Rossum7066dd71992-09-17 17:54:56 +00001095static object *
1096posix_tcsetpgrp(self, args)
1097 object *self;
1098 object *args;
1099{
1100 int fd, pgid;
1101 if (!getargs(args, "(ii)", &fd, &pgid))
1102 return NULL;
Guido van Rossum687dd131993-05-17 08:34:16 +00001103 if (tcsetpgrp(fd, pgid) < 0)
1104 return posix_error();
Guido van Rossum7066dd71992-09-17 17:54:56 +00001105 INCREF(None);
1106 return None;
1107}
Guido van Rossumb6775db1994-08-01 11:34:53 +00001108#endif /* HAVE_TCSETPGRP */
Guido van Rossum22db57e1992-04-05 14:25:30 +00001109
Guido van Rossum687dd131993-05-17 08:34:16 +00001110/* Functions acting on file descriptors */
1111
Guido van Rossum234f9421993-06-17 12:35:49 +00001112static object *
Guido van Rossum687dd131993-05-17 08:34:16 +00001113posix_open(self, args)
1114 object *self;
1115 object *args;
1116{
1117 char *file;
1118 int flag;
1119 int mode = 0777;
1120 int fd;
1121 if (!getargs(args, "(si)", &file, &flag)) {
1122 err_clear();
1123 if (!getargs(args, "(sii)", &file, &flag, &mode))
1124 return NULL;
1125 }
1126 BGN_SAVE
1127 fd = open(file, flag, mode);
1128 END_SAVE
1129 if (fd < 0)
1130 return posix_error();
1131 return newintobject((long)fd);
1132}
1133
Guido van Rossum234f9421993-06-17 12:35:49 +00001134static object *
Guido van Rossum687dd131993-05-17 08:34:16 +00001135posix_close(self, args)
1136 object *self;
1137 object *args;
1138{
1139 int fd, res;
1140 if (!getargs(args, "i", &fd))
1141 return NULL;
1142 BGN_SAVE
1143 res = close(fd);
1144 END_SAVE
1145 if (res < 0)
1146 return posix_error();
1147 INCREF(None);
1148 return None;
1149}
1150
Guido van Rossum234f9421993-06-17 12:35:49 +00001151static object *
Guido van Rossum687dd131993-05-17 08:34:16 +00001152posix_dup(self, args)
1153 object *self;
1154 object *args;
1155{
1156 int fd;
1157 if (!getargs(args, "i", &fd))
1158 return NULL;
1159 BGN_SAVE
1160 fd = dup(fd);
1161 END_SAVE
1162 if (fd < 0)
1163 return posix_error();
1164 return newintobject((long)fd);
1165}
1166
Guido van Rossum234f9421993-06-17 12:35:49 +00001167static object *
Guido van Rossum687dd131993-05-17 08:34:16 +00001168posix_dup2(self, args)
1169 object *self;
1170 object *args;
1171{
1172 int fd, fd2, res;
1173 if (!getargs(args, "(ii)", &fd, &fd2))
1174 return NULL;
1175 BGN_SAVE
1176 res = dup2(fd, fd2);
1177 END_SAVE
1178 if (res < 0)
1179 return posix_error();
1180 INCREF(None);
1181 return None;
1182}
1183
Guido van Rossum234f9421993-06-17 12:35:49 +00001184static object *
Guido van Rossum687dd131993-05-17 08:34:16 +00001185posix_lseek(self, args)
1186 object *self;
1187 object *args;
1188{
1189 int fd, how;
1190 long pos, res;
1191 if (!getargs(args, "(ili)", &fd, &pos, &how))
1192 return NULL;
1193#ifdef SEEK_SET
1194 /* Turn 0, 1, 2 into SEEK_{SET,CUR,END} */
1195 switch (how) {
1196 case 0: how = SEEK_SET; break;
1197 case 1: how = SEEK_CUR; break;
1198 case 2: how = SEEK_END; break;
1199 }
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001200#endif /* SEEK_END */
Guido van Rossum687dd131993-05-17 08:34:16 +00001201 BGN_SAVE
1202 res = lseek(fd, pos, how);
1203 END_SAVE
1204 if (res < 0)
1205 return posix_error();
1206 return newintobject(res);
1207}
1208
Guido van Rossum234f9421993-06-17 12:35:49 +00001209static object *
Guido van Rossum687dd131993-05-17 08:34:16 +00001210posix_read(self, args)
1211 object *self;
1212 object *args;
1213{
1214 int fd, size;
1215 object *buffer;
1216 if (!getargs(args, "(ii)", &fd, &size))
1217 return NULL;
1218 buffer = newsizedstringobject((char *)NULL, size);
1219 if (buffer == NULL)
1220 return NULL;
1221 BGN_SAVE
1222 size = read(fd, getstringvalue(buffer), size);
1223 END_SAVE
1224 if (size < 0) {
1225 DECREF(buffer);
1226 return posix_error();
1227 }
1228 resizestring(&buffer, size);
1229 return buffer;
1230}
1231
Guido van Rossum234f9421993-06-17 12:35:49 +00001232static object *
Guido van Rossum687dd131993-05-17 08:34:16 +00001233posix_write(self, args)
1234 object *self;
1235 object *args;
1236{
1237 int fd, size;
1238 char *buffer;
1239 if (!getargs(args, "(is#)", &fd, &buffer, &size))
1240 return NULL;
1241 BGN_SAVE
1242 size = write(fd, buffer, size);
1243 END_SAVE
1244 if (size < 0)
1245 return posix_error();
1246 return newintobject((long)size);
1247}
1248
Guido van Rossum234f9421993-06-17 12:35:49 +00001249static object *
Guido van Rossum687dd131993-05-17 08:34:16 +00001250posix_fstat(self, args)
1251 object *self;
1252 object *args;
1253{
1254 int fd;
1255 struct stat st;
1256 int res;
1257 if (!getargs(args, "i", &fd))
1258 return NULL;
1259 BGN_SAVE
1260 res = fstat(fd, &st);
1261 END_SAVE
1262 if (res != 0)
1263 return posix_error();
1264 return mkvalue("(llllllllll)",
1265 (long)st.st_mode,
1266 (long)st.st_ino,
1267 (long)st.st_dev,
1268 (long)st.st_nlink,
1269 (long)st.st_uid,
1270 (long)st.st_gid,
1271 (long)st.st_size,
1272 (long)st.st_atime,
1273 (long)st.st_mtime,
1274 (long)st.st_ctime);
1275}
1276
1277static object *
1278posix_fdopen(self, args)
1279 object *self;
1280 object *args;
1281{
1282 extern int fclose PROTO((FILE *));
1283 int fd;
Guido van Rossuma6a1e531995-01-10 15:36:38 +00001284 char *mode = "r";
1285 int bufsize = -1;
Guido van Rossum687dd131993-05-17 08:34:16 +00001286 FILE *fp;
Guido van Rossuma6a1e531995-01-10 15:36:38 +00001287 object *f;
1288 if (!newgetargs(args, "i|si", &fd, &mode, &bufsize))
Guido van Rossum687dd131993-05-17 08:34:16 +00001289 return NULL;
1290 BGN_SAVE
1291 fp = fdopen(fd, mode);
1292 END_SAVE
1293 if (fp == NULL)
1294 return posix_error();
Guido van Rossuma6a1e531995-01-10 15:36:38 +00001295 f = newopenfileobject(fp, "(fdopen)", mode, fclose);
1296 if (f != NULL)
1297 setfilebufsize(f, bufsize);
1298 return f;
Guido van Rossum687dd131993-05-17 08:34:16 +00001299}
1300
Guido van Rossum234f9421993-06-17 12:35:49 +00001301static object *
Guido van Rossum687dd131993-05-17 08:34:16 +00001302posix_pipe(self, args)
1303 object *self;
1304 object *args;
1305{
Guido van Rossum794d8131994-08-23 13:48:48 +00001306#ifndef NT
Guido van Rossum687dd131993-05-17 08:34:16 +00001307 int fds[2];
1308 int res;
1309 if (!getargs(args, ""))
1310 return NULL;
1311 BGN_SAVE
1312 res = pipe(fds);
1313 END_SAVE
1314 if (res != 0)
1315 return posix_error();
1316 return mkvalue("(ii)", fds[0], fds[1]);
Guido van Rossum794d8131994-08-23 13:48:48 +00001317#else /* NT */
1318 HANDLE read, write;
1319 BOOL ok;
1320 if (!getargs(args, ""))
1321 return NULL;
1322 BGN_SAVE
1323 ok = CreatePipe( &read, &write, NULL, 0);
1324 END_SAVE
1325 if (!ok)
1326 return posix_error();
1327 return mkvalue("(ii)", read, write);
1328#endif /* NT */
Guido van Rossum687dd131993-05-17 08:34:16 +00001329}
Guido van Rossum22db57e1992-04-05 14:25:30 +00001330
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001331static struct methodlist posix_methods[] = {
1332 {"chdir", posix_chdir},
1333 {"chmod", posix_chmod},
Guido van Rossumb6775db1994-08-01 11:34:53 +00001334#ifdef HAVE_CHOWN
1335 {"chown", posix_chown},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001336#endif /* HAVE_CHOWN */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001337 {"getcwd", posix_getcwd},
Guido van Rossumb6775db1994-08-01 11:34:53 +00001338#ifdef HAVE_LINK
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001339 {"link", posix_link},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001340#endif /* HAVE_LINK */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001341 {"listdir", posix_listdir},
Guido van Rossumc39de5f1992-02-05 11:15:54 +00001342 {"lstat", posix_lstat},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001343 {"mkdir", posix_mkdir},
Guido van Rossumb6775db1994-08-01 11:34:53 +00001344#ifdef HAVE_NICE
Guido van Rossum775f4da1993-01-09 17:18:52 +00001345 {"nice", posix_nice},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001346#endif /* HAVE_NICE */
Guido van Rossumb6775db1994-08-01 11:34:53 +00001347#ifdef HAVE_READLINK
Guido van Rossumc39de5f1992-02-05 11:15:54 +00001348 {"readlink", posix_readlink},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001349#endif /* HAVE_READLINK */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001350 {"rename", posix_rename},
1351 {"rmdir", posix_rmdir},
1352 {"stat", posix_stat},
Guido van Rossumb6775db1994-08-01 11:34:53 +00001353#ifdef HAVE_SYMLINK
Guido van Rossumc39de5f1992-02-05 11:15:54 +00001354 {"symlink", posix_symlink},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001355#endif /* HAVE_SYMLINK */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001356 {"system", posix_system},
1357 {"umask", posix_umask},
Guido van Rossumb6775db1994-08-01 11:34:53 +00001358#ifdef HAVE_UNAME
Guido van Rossumc39de5f1992-02-05 11:15:54 +00001359 {"uname", posix_uname},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001360#endif /* HAVE_UNAME */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001361 {"unlink", posix_unlink},
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00001362 {"utime", posix_utime},
Guido van Rossumb6775db1994-08-01 11:34:53 +00001363#ifdef HAVE_TIMES
Guido van Rossum22db57e1992-04-05 14:25:30 +00001364 {"times", posix_times},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001365#endif /* HAVE_TIMES */
Guido van Rossum85e3b011991-06-03 12:42:10 +00001366 {"_exit", posix__exit},
Guido van Rossum89b33251993-10-22 14:26:06 +00001367 {"execv", posix_execv},
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001368 {"execve", posix_execve},
Guido van Rossumb6775db1994-08-01 11:34:53 +00001369#ifndef NT
Guido van Rossum85e3b011991-06-03 12:42:10 +00001370 {"fork", posix_fork},
Guido van Rossum46003ff1992-05-15 11:05:24 +00001371 {"getegid", posix_getegid},
1372 {"geteuid", posix_geteuid},
1373 {"getgid", posix_getgid},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001374#endif /* !NT */
Guido van Rossum85e3b011991-06-03 12:42:10 +00001375 {"getpid", posix_getpid},
Guido van Rossumb6775db1994-08-01 11:34:53 +00001376#ifdef HAVE_GETPGRP
Guido van Rossum04814471991-06-04 20:23:49 +00001377 {"getpgrp", posix_getpgrp},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001378#endif /* HAVE_GETPGRP */
Guido van Rossumb6775db1994-08-01 11:34:53 +00001379#ifndef NT
Guido van Rossum85e3b011991-06-03 12:42:10 +00001380 {"getppid", posix_getppid},
Guido van Rossum46003ff1992-05-15 11:05:24 +00001381 {"getuid", posix_getuid},
Guido van Rossum85e3b011991-06-03 12:42:10 +00001382 {"kill", posix_kill},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001383#endif /* !NT */
Guido van Rossuma6a1e531995-01-10 15:36:38 +00001384 {"popen", posix_popen, 1},
Guido van Rossumb6775db1994-08-01 11:34:53 +00001385#ifdef HAVE_SETUID
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00001386 {"setuid", posix_setuid},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001387#endif /* HAVE_SETUID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00001388#ifdef HAVE_SETGID
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00001389 {"setgid", posix_setgid},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001390#endif /* HAVE_SETGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00001391#ifdef HAVE_SETPGRP
Guido van Rossumc2670a01992-09-13 20:07:29 +00001392 {"setpgrp", posix_setpgrp},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001393#endif /* HAVE_SETPGRP */
Guido van Rossumb6775db1994-08-01 11:34:53 +00001394#ifndef NT
Guido van Rossum85e3b011991-06-03 12:42:10 +00001395 {"wait", posix_wait},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001396#endif /* !NT */
Guido van Rossumb6775db1994-08-01 11:34:53 +00001397#ifdef HAVE_WAITPID
Guido van Rossum21803b81992-08-09 12:55:27 +00001398 {"waitpid", posix_waitpid},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001399#endif /* HAVE_WAITPID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00001400#ifdef HAVE_SETSID
Guido van Rossumc2670a01992-09-13 20:07:29 +00001401 {"setsid", posix_setsid},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001402#endif /* HAVE_SETSID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00001403#ifdef HAVE_SETPGID
Guido van Rossumc2670a01992-09-13 20:07:29 +00001404 {"setpgid", posix_setpgid},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001405#endif /* HAVE_SETPGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00001406#ifdef HAVE_TCGETPGRP
Guido van Rossum7066dd71992-09-17 17:54:56 +00001407 {"tcgetpgrp", posix_tcgetpgrp},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001408#endif /* HAVE_TCGETPGRP */
Guido van Rossumb6775db1994-08-01 11:34:53 +00001409#ifdef HAVE_TCSETPGRP
Guido van Rossum7066dd71992-09-17 17:54:56 +00001410 {"tcsetpgrp", posix_tcsetpgrp},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001411#endif /* HAVE_TCSETPGRP */
Guido van Rossum687dd131993-05-17 08:34:16 +00001412 {"open", posix_open},
1413 {"close", posix_close},
1414 {"dup", posix_dup},
1415 {"dup2", posix_dup2},
1416 {"lseek", posix_lseek},
1417 {"read", posix_read},
1418 {"write", posix_write},
1419 {"fstat", posix_fstat},
Guido van Rossuma6a1e531995-01-10 15:36:38 +00001420 {"fdopen", posix_fdopen, 1},
Guido van Rossum687dd131993-05-17 08:34:16 +00001421 {"pipe", posix_pipe},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001422 {NULL, NULL} /* Sentinel */
1423};
1424
1425
Guido van Rossumb6775db1994-08-01 11:34:53 +00001426#ifdef NT
1427void
1428initnt()
1429{
1430 object *m, *d, *v;
1431
1432 m = initmodule("nt", posix_methods);
1433 d = getmoduledict(m);
1434
1435 /* Initialize nt.environ dictionary */
1436 v = convertenviron();
1437 if (v == NULL || dictinsert(d, "environ", v) != 0)
1438 fatal("can't define nt.environ");
1439 DECREF(v);
1440
1441 /* Initialize nt.error exception */
1442 PosixError = newstringobject("nt.error");
1443 if (PosixError == NULL || dictinsert(d, "error", PosixError) != 0)
1444 fatal("can't define nt.error");
1445}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001446#else /* !NT */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001447void
1448initposix()
1449{
1450 object *m, *d, *v;
1451
1452 m = initmodule("posix", posix_methods);
1453 d = getmoduledict(m);
1454
1455 /* Initialize posix.environ dictionary */
1456 v = convertenviron();
1457 if (v == NULL || dictinsert(d, "environ", v) != 0)
1458 fatal("can't define posix.environ");
1459 DECREF(v);
1460
1461 /* Initialize posix.error exception */
1462 PosixError = newstringobject("posix.error");
1463 if (PosixError == NULL || dictinsert(d, "error", PosixError) != 0)
1464 fatal("can't define posix.error");
1465}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001466#endif /* !NT */