blob: 0b8a6a87d9fa2941725a5b39f60f4b6117e59a4a [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 Rossumff4949e1992-08-05 19:58:53 +0000547 int res;
Guido van Rossum1ff6cb41991-04-08 20:59:13 +0000548
Guido van Rossumb6775db1994-08-01 11:34:53 +0000549#ifdef HAVE_UTIME_H
Guido van Rossum1ff6cb41991-04-08 20:59:13 +0000550 struct utimbuf buf;
551#define ATIME buf.actime
552#define MTIME buf.modtime
553#define UTIME_ARG &buf
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000554#else /* HAVE_UTIME_H */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +0000555 time_t buf[2];
556#define ATIME buf[0]
557#define MTIME buf[1]
558#define UTIME_ARG buf
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000559#endif /* HAVE_UTIME_H */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +0000560
Guido van Rossumef0a00e1992-01-27 16:51:30 +0000561 if (!getargs(args, "(s(ll))", &path, &ATIME, &MTIME))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000562 return NULL;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000563 BGN_SAVE
564 res = utime(path, UTIME_ARG);
565 END_SAVE
566 if (res < 0)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000567 return posix_error();
568 INCREF(None);
569 return None;
Guido van Rossum1ff6cb41991-04-08 20:59:13 +0000570#undef UTIME_ARG
571#undef ATIME
572#undef MTIME
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000573}
574
Guido van Rossum85e3b011991-06-03 12:42:10 +0000575
Guido van Rossum3b066191991-06-04 19:40:25 +0000576/* Process operations */
Guido van Rossum85e3b011991-06-03 12:42:10 +0000577
578static object *
579posix__exit(self, args)
580 object *self;
581 object *args;
582{
583 int sts;
584 if (!getintarg(args, &sts))
585 return NULL;
586 _exit(sts);
587 /* NOTREACHED */
588}
589
Guido van Rossum85e3b011991-06-03 12:42:10 +0000590static object *
Guido van Rossum89b33251993-10-22 14:26:06 +0000591posix_execv(self, args)
Guido van Rossum85e3b011991-06-03 12:42:10 +0000592 object *self;
593 object *args;
594{
Guido van Rossumef0a00e1992-01-27 16:51:30 +0000595 char *path;
596 object *argv;
Guido van Rossum85e3b011991-06-03 12:42:10 +0000597 char **argvlist;
598 int i, argc;
599 object *(*getitem) PROTO((object *, int));
600
Guido van Rossum89b33251993-10-22 14:26:06 +0000601 /* execv has two arguments: (path, argv), where
Guido van Rossum85e3b011991-06-03 12:42:10 +0000602 argv is a list or tuple of strings. */
603
Guido van Rossumef0a00e1992-01-27 16:51:30 +0000604 if (!getargs(args, "(sO)", &path, &argv))
Guido van Rossum85e3b011991-06-03 12:42:10 +0000605 return NULL;
Guido van Rossum85e3b011991-06-03 12:42:10 +0000606 if (is_listobject(argv)) {
607 argc = getlistsize(argv);
608 getitem = getlistitem;
609 }
610 else if (is_tupleobject(argv)) {
611 argc = gettuplesize(argv);
612 getitem = gettupleitem;
613 }
Guido van Rossumef0a00e1992-01-27 16:51:30 +0000614 else {
615 badarg:
616 err_badarg();
617 return NULL;
618 }
Guido van Rossum85e3b011991-06-03 12:42:10 +0000619
620 argvlist = NEW(char *, argc+1);
621 if (argvlist == NULL)
622 return NULL;
623 for (i = 0; i < argc; i++) {
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +0000624 if (!getargs((*getitem)(argv, i), "s", &argvlist[i])) {
Guido van Rossum85e3b011991-06-03 12:42:10 +0000625 DEL(argvlist);
626 goto badarg;
627 }
Guido van Rossum85e3b011991-06-03 12:42:10 +0000628 }
629 argvlist[argc] = NULL;
630
Guido van Rossumb6775db1994-08-01 11:34:53 +0000631#ifdef BAD_EXEC_PROTOTYPES
632 execv(path, (const char **) argvlist);
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000633#else /* BAD_EXEC_PROTOTYPES */
Guido van Rossumef0a00e1992-01-27 16:51:30 +0000634 execv(path, argvlist);
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000635#endif /* BAD_EXEC_PROTOTYPES */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000636
Guido van Rossum85e3b011991-06-03 12:42:10 +0000637 /* If we get here it's definitely an error */
638
639 DEL(argvlist);
640 return posix_error();
641}
642
643static object *
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +0000644posix_execve(self, args)
645 object *self;
646 object *args;
647{
648 char *path;
649 object *argv, *env;
650 char **argvlist;
651 char **envlist;
652 object *key, *val;
653 int i, pos, argc, envc;
654 object *(*getitem) PROTO((object *, int));
655
656 /* execve has three arguments: (path, argv, env), where
657 argv is a list or tuple of strings and env is a dictionary
658 like posix.environ. */
659
660 if (!getargs(args, "(sOO)", &path, &argv, &env))
661 return NULL;
662 if (is_listobject(argv)) {
663 argc = getlistsize(argv);
664 getitem = getlistitem;
665 }
666 else if (is_tupleobject(argv)) {
667 argc = gettuplesize(argv);
668 getitem = gettupleitem;
669 }
670 else {
671 err_setstr(TypeError, "argv must be tuple or list");
672 return NULL;
673 }
674 if (!is_dictobject(env)) {
675 err_setstr(TypeError, "env must be dictionary");
676 return NULL;
677 }
678
679 argvlist = NEW(char *, argc+1);
680 if (argvlist == NULL) {
681 err_nomem();
682 return NULL;
683 }
684 for (i = 0; i < argc; i++) {
685 if (!getargs((*getitem)(argv, i),
686 "s;argv must be list of strings",
687 &argvlist[i])) {
688 goto fail_1;
689 }
690 }
691 argvlist[argc] = NULL;
692
693 i = getmappingsize(env);
694 envlist = NEW(char *, i + 1);
695 if (envlist == NULL) {
696 err_nomem();
697 goto fail_1;
698 }
699 pos = 0;
700 envc = 0;
701 while (mappinggetnext(env, &pos, &key, &val)) {
702 char *p, *k, *v;
703 if (!getargs(key, "s;non-string key in env", &k) ||
704 !getargs(val, "s;non-string value in env", &v)) {
705 goto fail_2;
706 }
707 p = NEW(char, getstringsize(key) + getstringsize(val) + 2);
708 if (p == NULL) {
709 err_nomem();
710 goto fail_2;
711 }
712 sprintf(p, "%s=%s", k, v);
713 envlist[envc++] = p;
714 }
715 envlist[envc] = 0;
716
Guido van Rossumb6775db1994-08-01 11:34:53 +0000717
718#ifdef BAD_EXEC_PROTOTYPES
719 execve(path, (const char **)argvlist, envlist);
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000720#else /* BAD_EXEC_PROTOTYPES */
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +0000721 execve(path, argvlist, envlist);
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000722#endif /* BAD_EXEC_PROTOTYPES */
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +0000723
724 /* If we get here it's definitely an error */
725
726 (void) posix_error();
727
728 fail_2:
729 while (--envc >= 0)
730 DEL(envlist[envc]);
731 DEL(envlist);
732 fail_1:
733 DEL(argvlist);
734
735 return NULL;
736}
737
Guido van Rossum794d8131994-08-23 13:48:48 +0000738#ifndef NT
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +0000739static object *
Guido van Rossum85e3b011991-06-03 12:42:10 +0000740posix_fork(self, args)
741 object *self;
742 object *args;
743{
744 int pid;
Guido van Rossum50e61dc1992-03-27 17:22:31 +0000745 if (!getnoarg(args))
746 return NULL;
Guido van Rossum85e3b011991-06-03 12:42:10 +0000747 pid = fork();
748 if (pid == -1)
749 return posix_error();
750 return newintobject((long)pid);
751}
752
753static object *
Guido van Rossum46003ff1992-05-15 11:05:24 +0000754posix_getegid(self, args)
755 object *self;
756 object *args;
757{
758 if (!getnoarg(args))
759 return NULL;
760 return newintobject((long)getegid());
761}
762
763static object *
764posix_geteuid(self, args)
765 object *self;
766 object *args;
767{
768 if (!getnoarg(args))
769 return NULL;
770 return newintobject((long)geteuid());
771}
772
773static object *
774posix_getgid(self, args)
775 object *self;
776 object *args;
777{
778 if (!getnoarg(args))
779 return NULL;
780 return newintobject((long)getgid());
781}
Guido van Rossumb078ce11994-08-29 14:01:43 +0000782#endif /* !NT */
Guido van Rossum46003ff1992-05-15 11:05:24 +0000783
784static object *
Guido van Rossum85e3b011991-06-03 12:42:10 +0000785posix_getpid(self, args)
786 object *self;
787 object *args;
788{
Guido van Rossum04814471991-06-04 20:23:49 +0000789 if (!getnoarg(args))
Guido van Rossum85e3b011991-06-03 12:42:10 +0000790 return NULL;
791 return newintobject((long)getpid());
792}
793
Guido van Rossumb6775db1994-08-01 11:34:53 +0000794#ifdef HAVE_GETPGRP
Guido van Rossum85e3b011991-06-03 12:42:10 +0000795static object *
Guido van Rossum04814471991-06-04 20:23:49 +0000796posix_getpgrp(self, args)
797 object *self;
798 object *args;
799{
800 if (!getnoarg(args))
801 return NULL;
Guido van Rossumb6775db1994-08-01 11:34:53 +0000802#ifdef GETPGRP_HAVE_ARG
Guido van Rossum971443b1991-06-07 13:59:29 +0000803 return newintobject((long)getpgrp(0));
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000804#else /* GETPGRP_HAVE_ARG */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000805 return newintobject((long)getpgrp());
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000806#endif /* GETPGRP_HAVE_ARG */
Guido van Rossum04814471991-06-04 20:23:49 +0000807}
Guido van Rossumb6775db1994-08-01 11:34:53 +0000808#endif /* HAVE_GETPGRP */
Guido van Rossum04814471991-06-04 20:23:49 +0000809
Guido van Rossumb6775db1994-08-01 11:34:53 +0000810#ifdef HAVE_SETPGRP
Guido van Rossum04814471991-06-04 20:23:49 +0000811static object *
Guido van Rossumc2670a01992-09-13 20:07:29 +0000812posix_setpgrp(self, args)
813 object *self;
814 object *args;
815{
816 if (!getnoarg(args))
817 return NULL;
Guido van Rossum64933891994-10-20 21:56:42 +0000818#ifdef SETPGRP_HAVE_ARG
Guido van Rossumc2670a01992-09-13 20:07:29 +0000819 if (setpgrp(0, 0) < 0)
Guido van Rossum64933891994-10-20 21:56:42 +0000820#else /* SETPGRP_HAVE_ARG */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000821 if (setpgrp() < 0)
Guido van Rossum64933891994-10-20 21:56:42 +0000822#endif /* SETPGRP_HAVE_ARG */
Guido van Rossum687dd131993-05-17 08:34:16 +0000823 return posix_error();
Guido van Rossumc2670a01992-09-13 20:07:29 +0000824 INCREF(None);
825 return None;
826}
827
Guido van Rossumb6775db1994-08-01 11:34:53 +0000828#endif /* HAVE_SETPGRP */
829
Guido van Rossum794d8131994-08-23 13:48:48 +0000830#ifndef NT
Guido van Rossumc2670a01992-09-13 20:07:29 +0000831static object *
Guido van Rossum85e3b011991-06-03 12:42:10 +0000832posix_getppid(self, args)
833 object *self;
834 object *args;
835{
Guido van Rossum04814471991-06-04 20:23:49 +0000836 if (!getnoarg(args))
Guido van Rossum85e3b011991-06-03 12:42:10 +0000837 return NULL;
838 return newintobject((long)getppid());
839}
840
841static object *
Guido van Rossum46003ff1992-05-15 11:05:24 +0000842posix_getuid(self, args)
843 object *self;
844 object *args;
845{
846 if (!getnoarg(args))
847 return NULL;
848 return newintobject((long)getuid());
849}
850
851static object *
Guido van Rossum85e3b011991-06-03 12:42:10 +0000852posix_kill(self, args)
853 object *self;
854 object *args;
855{
856 int pid, sig;
Guido van Rossum234f9421993-06-17 12:35:49 +0000857 if (!getargs(args, "(ii)", &pid, &sig))
Guido van Rossum85e3b011991-06-03 12:42:10 +0000858 return NULL;
859 if (kill(pid, sig) == -1)
860 return posix_error();
861 INCREF(None);
862 return None;
863}
Guido van Rossum794d8131994-08-23 13:48:48 +0000864#endif /* !NT */
Guido van Rossum85e3b011991-06-03 12:42:10 +0000865
866static object *
Guido van Rossum3b066191991-06-04 19:40:25 +0000867posix_popen(self, args)
868 object *self;
869 object *args;
870{
Guido van Rossumef0a00e1992-01-27 16:51:30 +0000871 char *name, *mode;
Guido van Rossum3b066191991-06-04 19:40:25 +0000872 FILE *fp;
Guido van Rossumef0a00e1992-01-27 16:51:30 +0000873 if (!getargs(args, "(ss)", &name, &mode))
Guido van Rossum3b066191991-06-04 19:40:25 +0000874 return NULL;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000875 BGN_SAVE
Guido van Rossumef0a00e1992-01-27 16:51:30 +0000876 fp = popen(name, mode);
Guido van Rossumff4949e1992-08-05 19:58:53 +0000877 END_SAVE
Guido van Rossum3b066191991-06-04 19:40:25 +0000878 if (fp == NULL)
879 return posix_error();
Guido van Rossumef0a00e1992-01-27 16:51:30 +0000880 return newopenfileobject(fp, name, mode, pclose);
Guido van Rossum3b066191991-06-04 19:40:25 +0000881}
882
Guido van Rossumb6775db1994-08-01 11:34:53 +0000883#ifdef HAVE_SETUID
Guido van Rossum3b066191991-06-04 19:40:25 +0000884static object *
Guido van Rossuma3d78fb1993-11-10 09:23:53 +0000885posix_setuid(self, args)
886 object *self;
887 object *args;
888{
889 int uid;
890 if (!getargs(args, "i", &uid))
891 return NULL;
892 if (setuid(uid) < 0)
893 return posix_error();
894 INCREF(None);
895 return None;
896}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000897#endif /* HAVE_SETUID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +0000898
Guido van Rossumb6775db1994-08-01 11:34:53 +0000899#ifdef HAVE_SETGID
Guido van Rossuma3d78fb1993-11-10 09:23:53 +0000900static object *
901posix_setgid(self, args)
902 object *self;
903 object *args;
904{
905 int gid;
906 if (!getargs(args, "i", &gid))
907 return NULL;
908 if (setgid(gid) < 0)
909 return posix_error();
910 INCREF(None);
911 return None;
912}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000913#endif /* HAVE_SETGID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +0000914
Guido van Rossumb6775db1994-08-01 11:34:53 +0000915#ifdef HAVE_WAITPID
Guido van Rossuma3d78fb1993-11-10 09:23:53 +0000916static object *
Guido van Rossum21803b81992-08-09 12:55:27 +0000917posix_waitpid(self, args)
Guido van Rossum85e3b011991-06-03 12:42:10 +0000918 object *self;
919 object *args;
920{
Guido van Rossum21803b81992-08-09 12:55:27 +0000921 int pid, options, sts;
922 if (!getargs(args, "(ii)", &pid, &options))
923 return NULL;
924 BGN_SAVE
925 pid = waitpid(pid, &sts, options);
926 END_SAVE
Guido van Rossum85e3b011991-06-03 12:42:10 +0000927 if (pid == -1)
928 return posix_error();
Guido van Rossum21803b81992-08-09 12:55:27 +0000929 else
930 return mkvalue("ii", pid, sts);
Guido van Rossum21803b81992-08-09 12:55:27 +0000931}
Guido van Rossumb6775db1994-08-01 11:34:53 +0000932#endif /* HAVE_WAITPID */
Guido van Rossum21803b81992-08-09 12:55:27 +0000933
Guido van Rossum794d8131994-08-23 13:48:48 +0000934#ifndef NT
Guido van Rossum21803b81992-08-09 12:55:27 +0000935static object *
936posix_wait(self, args)
937 object *self;
938 object *args;
939{
940 int pid, sts;
Guido van Rossum21803b81992-08-09 12:55:27 +0000941 BGN_SAVE
942 pid = wait(&sts);
943 END_SAVE
944 if (pid == -1)
945 return posix_error();
946 else
947 return mkvalue("ii", pid, sts);
Guido van Rossum85e3b011991-06-03 12:42:10 +0000948}
Guido van Rossum794d8131994-08-23 13:48:48 +0000949#endif /* !NT */
Guido van Rossum85e3b011991-06-03 12:42:10 +0000950
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000951static object *
952posix_lstat(self, args)
953 object *self;
954 object *args;
955{
Guido van Rossumb6775db1994-08-01 11:34:53 +0000956#ifdef HAVE_LSTAT
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000957 return posix_do_stat(self, args, lstat);
Guido van Rossumb6775db1994-08-01 11:34:53 +0000958#else /* !HAVE_LSTAT */
959 return posix_do_stat(self, args, stat);
960#endif /* !HAVE_LSTAT */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000961}
962
Guido van Rossumb6775db1994-08-01 11:34:53 +0000963#ifdef HAVE_READLINK
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000964static object *
965posix_readlink(self, args)
966 object *self;
967 object *args;
968{
Guido van Rossumb6775db1994-08-01 11:34:53 +0000969 char buf[MAXPATHLEN];
Guido van Rossumef0a00e1992-01-27 16:51:30 +0000970 char *path;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000971 int n;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +0000972 if (!getargs(args, "s", &path))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000973 return NULL;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000974 BGN_SAVE
Guido van Rossum50e61dc1992-03-27 17:22:31 +0000975 n = readlink(path, buf, (int) sizeof buf);
Guido van Rossumff4949e1992-08-05 19:58:53 +0000976 END_SAVE
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000977 if (n < 0)
978 return posix_error();
979 return newsizedstringobject(buf, n);
980}
Guido van Rossumb6775db1994-08-01 11:34:53 +0000981#endif /* HAVE_READLINK */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000982
Guido van Rossumb6775db1994-08-01 11:34:53 +0000983#ifdef HAVE_SYMLINK
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000984static object *
985posix_symlink(self, args)
986 object *self;
987 object *args;
988{
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000989 return posix_2str(args, symlink);
990}
Guido van Rossumb6775db1994-08-01 11:34:53 +0000991#endif /* HAVE_SYMLINK */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000992
Guido van Rossumb6775db1994-08-01 11:34:53 +0000993#ifdef HAVE_TIMES
994#ifndef HZ
995#define HZ 60 /* Universal constant :-) */
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000996#endif /* HZ */
Guido van Rossum22db57e1992-04-05 14:25:30 +0000997static object *
998posix_times(self, args)
999 object *self;
1000 object *args;
1001{
1002 struct tms t;
1003 clock_t c;
Guido van Rossum22db57e1992-04-05 14:25:30 +00001004 if (!getnoarg(args))
1005 return NULL;
1006 errno = 0;
1007 c = times(&t);
Guido van Rossum687dd131993-05-17 08:34:16 +00001008 if (c == (clock_t) -1)
1009 return posix_error();
Guido van Rossum0b0db8e1993-01-21 16:07:51 +00001010 return mkvalue("dddd",
1011 (double)t.tms_utime / HZ,
1012 (double)t.tms_stime / HZ,
1013 (double)t.tms_cutime / HZ,
1014 (double)t.tms_cstime / HZ);
Guido van Rossum22db57e1992-04-05 14:25:30 +00001015}
Guido van Rossumb6775db1994-08-01 11:34:53 +00001016#endif /* HAVE_TIMES */
Guido van Rossum14ed0b21994-09-29 09:50:09 +00001017#ifdef NT
1018#define HAVE_TIMES /* so the method table will pick it up */
1019static object *
1020posix_times(self, args)
1021 object *self;
1022 object *args;
1023{
1024 FILETIME create, exit, kernel, user;
1025 HANDLE hProc;
1026 if (!getnoarg(args))
1027 return NULL;
1028 hProc = GetCurrentProcess();
1029 GetProcessTimes(hProc,&create, &exit, &kernel, &user);
1030 return mkvalue("dddd",
1031 (double)(kernel.dwHighDateTime*2E32+kernel.dwLowDateTime) / 2E6,
1032 (double)(user.dwHighDateTime*2E32+user.dwLowDateTime) / 2E6,
1033 (double)0,
1034 (double)0);
1035}
1036#endif /* NT */
Guido van Rossum22db57e1992-04-05 14:25:30 +00001037
Guido van Rossumb6775db1994-08-01 11:34:53 +00001038#ifdef HAVE_SETSID
Guido van Rossumc2670a01992-09-13 20:07:29 +00001039static object *
1040posix_setsid(self, args)
1041 object *self;
1042 object *args;
1043{
1044 if (!getnoarg(args))
1045 return NULL;
Guido van Rossum687dd131993-05-17 08:34:16 +00001046 if (setsid() < 0)
1047 return posix_error();
Guido van Rossumc2670a01992-09-13 20:07:29 +00001048 INCREF(None);
1049 return None;
1050}
Guido van Rossumb6775db1994-08-01 11:34:53 +00001051#endif /* HAVE_SETSID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00001052
Guido van Rossumb6775db1994-08-01 11:34:53 +00001053#ifdef HAVE_SETPGID
Guido van Rossumc2670a01992-09-13 20:07:29 +00001054static object *
1055posix_setpgid(self, args)
1056 object *self;
1057 object *args;
1058{
1059 int pid, pgrp;
1060 if (!getargs(args, "(ii)", &pid, &pgrp))
1061 return NULL;
Guido van Rossum687dd131993-05-17 08:34:16 +00001062 if (setpgid(pid, pgrp) < 0)
1063 return posix_error();
Guido van Rossumc2670a01992-09-13 20:07:29 +00001064 INCREF(None);
1065 return None;
1066}
Guido van Rossumb6775db1994-08-01 11:34:53 +00001067#endif /* HAVE_SETPGID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00001068
Guido van Rossumb6775db1994-08-01 11:34:53 +00001069#ifdef HAVE_TCGETPGRP
Guido van Rossum7066dd71992-09-17 17:54:56 +00001070static object *
1071posix_tcgetpgrp(self, args)
1072 object *self;
1073 object *args;
1074{
1075 int fd, pgid;
1076 if (!getargs(args, "i", &fd))
1077 return NULL;
1078 pgid = tcgetpgrp(fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00001079 if (pgid < 0)
1080 return posix_error();
Guido van Rossum7066dd71992-09-17 17:54:56 +00001081 return newintobject((long)pgid);
1082}
Guido van Rossumb6775db1994-08-01 11:34:53 +00001083#endif /* HAVE_TCGETPGRP */
Guido van Rossum7066dd71992-09-17 17:54:56 +00001084
Guido van Rossumb6775db1994-08-01 11:34:53 +00001085#ifdef HAVE_TCSETPGRP
Guido van Rossum7066dd71992-09-17 17:54:56 +00001086static object *
1087posix_tcsetpgrp(self, args)
1088 object *self;
1089 object *args;
1090{
1091 int fd, pgid;
1092 if (!getargs(args, "(ii)", &fd, &pgid))
1093 return NULL;
Guido van Rossum687dd131993-05-17 08:34:16 +00001094 if (tcsetpgrp(fd, pgid) < 0)
1095 return posix_error();
Guido van Rossum7066dd71992-09-17 17:54:56 +00001096 INCREF(None);
1097 return None;
1098}
Guido van Rossumb6775db1994-08-01 11:34:53 +00001099#endif /* HAVE_TCSETPGRP */
Guido van Rossum22db57e1992-04-05 14:25:30 +00001100
Guido van Rossum687dd131993-05-17 08:34:16 +00001101/* Functions acting on file descriptors */
1102
Guido van Rossum234f9421993-06-17 12:35:49 +00001103static object *
Guido van Rossum687dd131993-05-17 08:34:16 +00001104posix_open(self, args)
1105 object *self;
1106 object *args;
1107{
1108 char *file;
1109 int flag;
1110 int mode = 0777;
1111 int fd;
1112 if (!getargs(args, "(si)", &file, &flag)) {
1113 err_clear();
1114 if (!getargs(args, "(sii)", &file, &flag, &mode))
1115 return NULL;
1116 }
1117 BGN_SAVE
1118 fd = open(file, flag, mode);
1119 END_SAVE
1120 if (fd < 0)
1121 return posix_error();
1122 return newintobject((long)fd);
1123}
1124
Guido van Rossum234f9421993-06-17 12:35:49 +00001125static object *
Guido van Rossum687dd131993-05-17 08:34:16 +00001126posix_close(self, args)
1127 object *self;
1128 object *args;
1129{
1130 int fd, res;
1131 if (!getargs(args, "i", &fd))
1132 return NULL;
1133 BGN_SAVE
1134 res = close(fd);
1135 END_SAVE
1136 if (res < 0)
1137 return posix_error();
1138 INCREF(None);
1139 return None;
1140}
1141
Guido van Rossum234f9421993-06-17 12:35:49 +00001142static object *
Guido van Rossum687dd131993-05-17 08:34:16 +00001143posix_dup(self, args)
1144 object *self;
1145 object *args;
1146{
1147 int fd;
1148 if (!getargs(args, "i", &fd))
1149 return NULL;
1150 BGN_SAVE
1151 fd = dup(fd);
1152 END_SAVE
1153 if (fd < 0)
1154 return posix_error();
1155 return newintobject((long)fd);
1156}
1157
Guido van Rossum234f9421993-06-17 12:35:49 +00001158static object *
Guido van Rossum687dd131993-05-17 08:34:16 +00001159posix_dup2(self, args)
1160 object *self;
1161 object *args;
1162{
1163 int fd, fd2, res;
1164 if (!getargs(args, "(ii)", &fd, &fd2))
1165 return NULL;
1166 BGN_SAVE
1167 res = dup2(fd, fd2);
1168 END_SAVE
1169 if (res < 0)
1170 return posix_error();
1171 INCREF(None);
1172 return None;
1173}
1174
Guido van Rossum234f9421993-06-17 12:35:49 +00001175static object *
Guido van Rossum687dd131993-05-17 08:34:16 +00001176posix_lseek(self, args)
1177 object *self;
1178 object *args;
1179{
1180 int fd, how;
1181 long pos, res;
1182 if (!getargs(args, "(ili)", &fd, &pos, &how))
1183 return NULL;
1184#ifdef SEEK_SET
1185 /* Turn 0, 1, 2 into SEEK_{SET,CUR,END} */
1186 switch (how) {
1187 case 0: how = SEEK_SET; break;
1188 case 1: how = SEEK_CUR; break;
1189 case 2: how = SEEK_END; break;
1190 }
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001191#endif /* SEEK_END */
Guido van Rossum687dd131993-05-17 08:34:16 +00001192 BGN_SAVE
1193 res = lseek(fd, pos, how);
1194 END_SAVE
1195 if (res < 0)
1196 return posix_error();
1197 return newintobject(res);
1198}
1199
Guido van Rossum234f9421993-06-17 12:35:49 +00001200static object *
Guido van Rossum687dd131993-05-17 08:34:16 +00001201posix_read(self, args)
1202 object *self;
1203 object *args;
1204{
1205 int fd, size;
1206 object *buffer;
1207 if (!getargs(args, "(ii)", &fd, &size))
1208 return NULL;
1209 buffer = newsizedstringobject((char *)NULL, size);
1210 if (buffer == NULL)
1211 return NULL;
1212 BGN_SAVE
1213 size = read(fd, getstringvalue(buffer), size);
1214 END_SAVE
1215 if (size < 0) {
1216 DECREF(buffer);
1217 return posix_error();
1218 }
1219 resizestring(&buffer, size);
1220 return buffer;
1221}
1222
Guido van Rossum234f9421993-06-17 12:35:49 +00001223static object *
Guido van Rossum687dd131993-05-17 08:34:16 +00001224posix_write(self, args)
1225 object *self;
1226 object *args;
1227{
1228 int fd, size;
1229 char *buffer;
1230 if (!getargs(args, "(is#)", &fd, &buffer, &size))
1231 return NULL;
1232 BGN_SAVE
1233 size = write(fd, buffer, size);
1234 END_SAVE
1235 if (size < 0)
1236 return posix_error();
1237 return newintobject((long)size);
1238}
1239
Guido van Rossum234f9421993-06-17 12:35:49 +00001240static object *
Guido van Rossum687dd131993-05-17 08:34:16 +00001241posix_fstat(self, args)
1242 object *self;
1243 object *args;
1244{
1245 int fd;
1246 struct stat st;
1247 int res;
1248 if (!getargs(args, "i", &fd))
1249 return NULL;
1250 BGN_SAVE
1251 res = fstat(fd, &st);
1252 END_SAVE
1253 if (res != 0)
1254 return posix_error();
1255 return mkvalue("(llllllllll)",
1256 (long)st.st_mode,
1257 (long)st.st_ino,
1258 (long)st.st_dev,
1259 (long)st.st_nlink,
1260 (long)st.st_uid,
1261 (long)st.st_gid,
1262 (long)st.st_size,
1263 (long)st.st_atime,
1264 (long)st.st_mtime,
1265 (long)st.st_ctime);
1266}
1267
1268static object *
1269posix_fdopen(self, args)
1270 object *self;
1271 object *args;
1272{
1273 extern int fclose PROTO((FILE *));
1274 int fd;
1275 char *mode;
1276 FILE *fp;
1277 if (!getargs(args, "(is)", &fd, &mode))
1278 return NULL;
1279 BGN_SAVE
1280 fp = fdopen(fd, mode);
1281 END_SAVE
1282 if (fp == NULL)
1283 return posix_error();
1284 /* From now on, ignore SIGPIPE and let the error checking
1285 do the work. */
Guido van Rossum687dd131993-05-17 08:34:16 +00001286 return newopenfileobject(fp, "(fdopen)", mode, fclose);
1287}
1288
Guido van Rossum234f9421993-06-17 12:35:49 +00001289static object *
Guido van Rossum687dd131993-05-17 08:34:16 +00001290posix_pipe(self, args)
1291 object *self;
1292 object *args;
1293{
Guido van Rossum794d8131994-08-23 13:48:48 +00001294#ifndef NT
Guido van Rossum687dd131993-05-17 08:34:16 +00001295 int fds[2];
1296 int res;
1297 if (!getargs(args, ""))
1298 return NULL;
1299 BGN_SAVE
1300 res = pipe(fds);
1301 END_SAVE
1302 if (res != 0)
1303 return posix_error();
1304 return mkvalue("(ii)", fds[0], fds[1]);
Guido van Rossum794d8131994-08-23 13:48:48 +00001305#else /* NT */
1306 HANDLE read, write;
1307 BOOL ok;
1308 if (!getargs(args, ""))
1309 return NULL;
1310 BGN_SAVE
1311 ok = CreatePipe( &read, &write, NULL, 0);
1312 END_SAVE
1313 if (!ok)
1314 return posix_error();
1315 return mkvalue("(ii)", read, write);
1316#endif /* NT */
Guido van Rossum687dd131993-05-17 08:34:16 +00001317}
Guido van Rossum22db57e1992-04-05 14:25:30 +00001318
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001319static struct methodlist posix_methods[] = {
1320 {"chdir", posix_chdir},
1321 {"chmod", posix_chmod},
Guido van Rossumb6775db1994-08-01 11:34:53 +00001322#ifdef HAVE_CHOWN
1323 {"chown", posix_chown},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001324#endif /* HAVE_CHOWN */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001325 {"getcwd", posix_getcwd},
Guido van Rossumb6775db1994-08-01 11:34:53 +00001326#ifdef HAVE_LINK
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001327 {"link", posix_link},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001328#endif /* HAVE_LINK */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001329 {"listdir", posix_listdir},
Guido van Rossumc39de5f1992-02-05 11:15:54 +00001330 {"lstat", posix_lstat},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001331 {"mkdir", posix_mkdir},
Guido van Rossumb6775db1994-08-01 11:34:53 +00001332#ifdef HAVE_NICE
Guido van Rossum775f4da1993-01-09 17:18:52 +00001333 {"nice", posix_nice},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001334#endif /* HAVE_NICE */
Guido van Rossumb6775db1994-08-01 11:34:53 +00001335#ifdef HAVE_READLINK
Guido van Rossumc39de5f1992-02-05 11:15:54 +00001336 {"readlink", posix_readlink},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001337#endif /* HAVE_READLINK */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001338 {"rename", posix_rename},
1339 {"rmdir", posix_rmdir},
1340 {"stat", posix_stat},
Guido van Rossumb6775db1994-08-01 11:34:53 +00001341#ifdef HAVE_SYMLINK
Guido van Rossumc39de5f1992-02-05 11:15:54 +00001342 {"symlink", posix_symlink},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001343#endif /* HAVE_SYMLINK */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001344 {"system", posix_system},
1345 {"umask", posix_umask},
Guido van Rossumb6775db1994-08-01 11:34:53 +00001346#ifdef HAVE_UNAME
Guido van Rossumc39de5f1992-02-05 11:15:54 +00001347 {"uname", posix_uname},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001348#endif /* HAVE_UNAME */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001349 {"unlink", posix_unlink},
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00001350 {"utime", posix_utime},
Guido van Rossumb6775db1994-08-01 11:34:53 +00001351#ifdef HAVE_TIMES
Guido van Rossum22db57e1992-04-05 14:25:30 +00001352 {"times", posix_times},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001353#endif /* HAVE_TIMES */
Guido van Rossum85e3b011991-06-03 12:42:10 +00001354 {"_exit", posix__exit},
Guido van Rossum89b33251993-10-22 14:26:06 +00001355 {"execv", posix_execv},
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001356 {"execve", posix_execve},
Guido van Rossumb6775db1994-08-01 11:34:53 +00001357#ifndef NT
Guido van Rossum85e3b011991-06-03 12:42:10 +00001358 {"fork", posix_fork},
Guido van Rossum46003ff1992-05-15 11:05:24 +00001359 {"getegid", posix_getegid},
1360 {"geteuid", posix_geteuid},
1361 {"getgid", posix_getgid},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001362#endif /* !NT */
Guido van Rossum85e3b011991-06-03 12:42:10 +00001363 {"getpid", posix_getpid},
Guido van Rossumb6775db1994-08-01 11:34:53 +00001364#ifdef HAVE_GETPGRP
Guido van Rossum04814471991-06-04 20:23:49 +00001365 {"getpgrp", posix_getpgrp},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001366#endif /* HAVE_GETPGRP */
Guido van Rossumb6775db1994-08-01 11:34:53 +00001367#ifndef NT
Guido van Rossum85e3b011991-06-03 12:42:10 +00001368 {"getppid", posix_getppid},
Guido van Rossum46003ff1992-05-15 11:05:24 +00001369 {"getuid", posix_getuid},
Guido van Rossum85e3b011991-06-03 12:42:10 +00001370 {"kill", posix_kill},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001371#endif /* !NT */
Guido van Rossum3b066191991-06-04 19:40:25 +00001372 {"popen", posix_popen},
Guido van Rossumb6775db1994-08-01 11:34:53 +00001373#ifdef HAVE_SETUID
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00001374 {"setuid", posix_setuid},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001375#endif /* HAVE_SETUID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00001376#ifdef HAVE_SETGID
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00001377 {"setgid", posix_setgid},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001378#endif /* HAVE_SETGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00001379#ifdef HAVE_SETPGRP
Guido van Rossumc2670a01992-09-13 20:07:29 +00001380 {"setpgrp", posix_setpgrp},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001381#endif /* HAVE_SETPGRP */
Guido van Rossumb6775db1994-08-01 11:34:53 +00001382#ifndef NT
Guido van Rossum85e3b011991-06-03 12:42:10 +00001383 {"wait", posix_wait},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001384#endif /* !NT */
Guido van Rossumb6775db1994-08-01 11:34:53 +00001385#ifdef HAVE_WAITPID
Guido van Rossum21803b81992-08-09 12:55:27 +00001386 {"waitpid", posix_waitpid},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001387#endif /* HAVE_WAITPID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00001388#ifdef HAVE_SETSID
Guido van Rossumc2670a01992-09-13 20:07:29 +00001389 {"setsid", posix_setsid},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001390#endif /* HAVE_SETSID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00001391#ifdef HAVE_SETPGID
Guido van Rossumc2670a01992-09-13 20:07:29 +00001392 {"setpgid", posix_setpgid},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001393#endif /* HAVE_SETPGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00001394#ifdef HAVE_TCGETPGRP
Guido van Rossum7066dd71992-09-17 17:54:56 +00001395 {"tcgetpgrp", posix_tcgetpgrp},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001396#endif /* HAVE_TCGETPGRP */
Guido van Rossumb6775db1994-08-01 11:34:53 +00001397#ifdef HAVE_TCSETPGRP
Guido van Rossum7066dd71992-09-17 17:54:56 +00001398 {"tcsetpgrp", posix_tcsetpgrp},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001399#endif /* HAVE_TCSETPGRP */
Guido van Rossum687dd131993-05-17 08:34:16 +00001400 {"open", posix_open},
1401 {"close", posix_close},
1402 {"dup", posix_dup},
1403 {"dup2", posix_dup2},
1404 {"lseek", posix_lseek},
1405 {"read", posix_read},
1406 {"write", posix_write},
1407 {"fstat", posix_fstat},
1408 {"fdopen", posix_fdopen},
Guido van Rossum687dd131993-05-17 08:34:16 +00001409 {"pipe", posix_pipe},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001410 {NULL, NULL} /* Sentinel */
1411};
1412
1413
Guido van Rossumb6775db1994-08-01 11:34:53 +00001414#ifdef NT
1415void
1416initnt()
1417{
1418 object *m, *d, *v;
1419
1420 m = initmodule("nt", posix_methods);
1421 d = getmoduledict(m);
1422
1423 /* Initialize nt.environ dictionary */
1424 v = convertenviron();
1425 if (v == NULL || dictinsert(d, "environ", v) != 0)
1426 fatal("can't define nt.environ");
1427 DECREF(v);
1428
1429 /* Initialize nt.error exception */
1430 PosixError = newstringobject("nt.error");
1431 if (PosixError == NULL || dictinsert(d, "error", PosixError) != 0)
1432 fatal("can't define nt.error");
1433}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001434#else /* !NT */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001435void
1436initposix()
1437{
1438 object *m, *d, *v;
1439
1440 m = initmodule("posix", posix_methods);
1441 d = getmoduledict(m);
1442
1443 /* Initialize posix.environ dictionary */
1444 v = convertenviron();
1445 if (v == NULL || dictinsert(d, "environ", v) != 0)
1446 fatal("can't define posix.environ");
1447 DECREF(v);
1448
1449 /* Initialize posix.error exception */
1450 PosixError = newstringobject("posix.error");
1451 if (PosixError == NULL || dictinsert(d, "error", PosixError) != 0)
1452 fatal("can't define posix.error");
1453}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001454#endif /* !NT */