blob: c2678eb5b21ade925cd2125ffea665f8eca54574 [file] [log] [blame]
Guido van Rossumf70e43a1991-02-19 12:39:46 +00001/***********************************************************
Guido van Rossumb6775db1994-08-01 11:34:53 +00002Copyright 1991, 1992, 1993, 1994 by Stichting Mathematisch Centrum,
Guido van Rossum775f4da1993-01-09 17:18:52 +00003Amsterdam, The Netherlands.
Guido van Rossumf70e43a1991-02-19 12:39:46 +00004
5 All Rights Reserved
6
7Permission to use, copy, modify, and distribute this software and its
8documentation for any purpose and without fee is hereby granted,
9provided that the above copyright notice appear in all copies and that
10both that copyright notice and this permission notice appear in
11supporting documentation, and that the names of Stichting Mathematisch
12Centrum or CWI not be used in advertising or publicity pertaining to
13distribution of the software without specific, written prior permission.
14
15STICHTING MATHEMATISCH CENTRUM DISCLAIMS ALL WARRANTIES WITH REGARD TO
16THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
17FITNESS, IN NO EVENT SHALL STICHTING MATHEMATISCH CENTRUM BE LIABLE
18FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
19WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
20ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
21OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
22
23******************************************************************/
24
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000025/* POSIX module implementation */
26
Guido van Rossum3f5da241990-12-20 15:06:42 +000027#include "allobjects.h"
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000028#include "modsupport.h"
Guido van Rossumff4949e1992-08-05 19:58:53 +000029#include "ceval.h"
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000030
Guido van Rossumb6775db1994-08-01 11:34:53 +000031#include <string.h>
32#include <errno.h>
Guido van Rossumb6775db1994-08-01 11:34:53 +000033#include <sys/types.h>
34#include <sys/stat.h>
Guido van Rossumb6775db1994-08-01 11:34:53 +000035
36#include "mytime.h" /* For clock_t on some systems */
37
38#ifdef HAVE_FCNTL_H
39#include <fcntl.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000040#endif /* HAVE_FCNTL_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +000041
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000042#ifndef NT
Guido van Rossumb6775db1994-08-01 11:34:53 +000043#ifdef HAVE_UNISTD_H
Guido van Rossum0b0db8e1993-01-21 16:07:51 +000044#include <unistd.h>
Guido van Rossumb6775db1994-08-01 11:34:53 +000045#else /* !HAVE_UNISTD_H */
Guido van Rossuma2b7f401993-01-04 09:09:59 +000046extern int mkdir PROTO((const char *, mode_t));
47extern int chdir PROTO((const char *));
Guido van Rossume22e6441993-07-09 10:51:31 +000048extern int rmdir PROTO((const char *));
49extern int chmod PROTO((const char *, mode_t));
Guido van Rossumb6775db1994-08-01 11:34:53 +000050extern int chown PROTO((const char *, uid_t, gid_t));
51extern char *getcwd PROTO((char *, int));
Guido van Rossume22e6441993-07-09 10:51:31 +000052extern char *strerror PROTO((int));
Guido van Rossuma2b7f401993-01-04 09:09:59 +000053extern int link PROTO((const char *, const char *));
54extern int rename PROTO((const char *, const char *));
Guido van Rossuma2b7f401993-01-04 09:09:59 +000055extern int stat PROTO((const char *, struct stat *));
56extern int unlink PROTO((const char *));
57extern int pclose PROTO((FILE *));
Guido van Rossumb6775db1994-08-01 11:34:53 +000058#ifdef HAVE_SYMLINK
Guido van Rossuma2b7f401993-01-04 09:09:59 +000059extern int symlink PROTO((const char *, const char *));
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000060#endif /_ HAVE_SYMLINK */
Guido van Rossumb6775db1994-08-01 11:34:53 +000061#ifdef HAVE_LSTAT
62extern int lstat PROTO((const char *, struct stat *));
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000063#endif /* HAVE_LSTAT */
Guido van Rossumb6775db1994-08-01 11:34:53 +000064#endif /* !HAVE_UNISTD_H */
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000065#endif /* !NT */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000066
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000067#ifndef NT
Guido van Rossumb6775db1994-08-01 11:34:53 +000068/* XXX These are for SunOS4.1.3 but shouldn't hurt elsewhere */
69extern int rename();
70extern int pclose();
71extern int lstat();
72extern int symlink();
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000073#endif /* !NT */
Guido van Rossumb6775db1994-08-01 11:34:53 +000074
75#ifdef HAVE_UTIME_H
76#include <utime.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000077#endif /* HAVE_UTIME_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +000078
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
100/* unistd.h defines _POSIX_VERSION on POSIX.1 systems. */
101#if defined(DIRENT) || defined(_POSIX_VERSION)
102#include <dirent.h>
103#define NLENGTH(dirent) (strlen((dirent)->d_name))
104#else /* not (DIRENT or _POSIX_VERSION) */
105#define dirent direct
106#define NLENGTH(dirent) ((dirent)->d_namlen)
107#ifdef SYSNDIR
108#include <sys/ndir.h>
109#endif /* SYSNDIR */
110#ifdef SYSDIR
111#include <sys/dir.h>
112#endif /* SYSDIR */
113#ifdef NDIR
114#include <ndir.h>
115#endif /* NDIR */
116#endif /* not (DIRENT or _POSIX_VERSION) */
117
118#ifdef NT
119#include <direct.h>
120#include <io.h>
121#include <process.h>
122#include <windows.h>
123#define popen _popen
Guido van Rossum794d8131994-08-23 13:48:48 +0000124#define pclose _pclose
Guido van Rossumb6775db1994-08-01 11:34:53 +0000125#endif /* NT */
126
127#ifdef OS2
128#include <io.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000129#endif /* OS2 */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000130
131/* Return a dictionary corresponding to the POSIX environment table */
132
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000133#ifndef NT
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000134extern char **environ;
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000135#endif /* !NT */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000136
137static object *
138convertenviron()
139{
140 object *d;
141 char **e;
142 d = newdictobject();
143 if (d == NULL)
144 return NULL;
145 if (environ == NULL)
146 return d;
147 /* XXX This part ignores errors */
148 for (e = environ; *e != NULL; e++) {
149 object *v;
150 char *p = strchr(*e, '=');
151 if (p == NULL)
152 continue;
153 v = newstringobject(p+1);
154 if (v == NULL)
155 continue;
156 *p = '\0';
157 (void) dictinsert(d, *e, v);
158 *p = '=';
159 DECREF(v);
160 }
161 return d;
162}
163
164
165static object *PosixError; /* Exception posix.error */
166
167/* Set a POSIX-specific error from errno, and return NULL */
168
Guido van Rossum687dd131993-05-17 08:34:16 +0000169static object * posix_error() { return err_errno(PosixError);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000170}
171
172
173/* POSIX generic methods */
174
175static object *
176posix_1str(args, func)
177 object *args;
178 int (*func) FPROTO((const char *));
179{
Guido van Rossumef0a00e1992-01-27 16:51:30 +0000180 char *path1;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000181 int res;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +0000182 if (!getargs(args, "s", &path1))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000183 return NULL;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000184 BGN_SAVE
185 res = (*func)(path1);
186 END_SAVE
187 if (res < 0)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000188 return posix_error();
189 INCREF(None);
190 return None;
191}
192
193static object *
194posix_2str(args, func)
195 object *args;
196 int (*func) FPROTO((const char *, const char *));
197{
Guido van Rossumef0a00e1992-01-27 16:51:30 +0000198 char *path1, *path2;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000199 int res;
Guido van Rossum234f9421993-06-17 12:35:49 +0000200 if (!getargs(args, "(ss)", &path1, &path2))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000201 return NULL;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000202 BGN_SAVE
203 res = (*func)(path1, path2);
204 END_SAVE
205 if (res < 0)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000206 return posix_error();
207 INCREF(None);
208 return None;
209}
210
211static object *
212posix_strint(args, func)
213 object *args;
214 int (*func) FPROTO((const char *, int));
215{
Guido van Rossumef0a00e1992-01-27 16:51:30 +0000216 char *path;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000217 int i;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000218 int res;
Guido van Rossum234f9421993-06-17 12:35:49 +0000219 if (!getargs(args, "(si)", &path, &i))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000220 return NULL;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000221 BGN_SAVE
222 res = (*func)(path, i);
223 END_SAVE
224 if (res < 0)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000225 return posix_error();
226 INCREF(None);
227 return None;
228}
229
230static object *
Guido van Rossumb6775db1994-08-01 11:34:53 +0000231posix_strintint(args, func)
232 object *args;
233 int (*func) FPROTO((const char *, int, int));
234{
235 char *path;
236 int i,i2;
237 int res;
238 if (!getargs(args, "(sii)", &path, &i, &i2))
239 return NULL;
240 BGN_SAVE
241 res = (*func)(path, i, i2);
242 END_SAVE
243 if (res < 0)
244 return posix_error();
245 INCREF(None);
246 return None;
247}
248
249static object *
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000250posix_do_stat(self, args, statfunc)
251 object *self;
252 object *args;
253 int (*statfunc) FPROTO((const char *, struct stat *));
254{
255 struct stat st;
Guido van Rossumef0a00e1992-01-27 16:51:30 +0000256 char *path;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000257 int res;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +0000258 if (!getargs(args, "s", &path))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000259 return NULL;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000260 BGN_SAVE
261 res = (*statfunc)(path, &st);
262 END_SAVE
263 if (res != 0)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000264 return posix_error();
Guido van Rossum687dd131993-05-17 08:34:16 +0000265 return mkvalue("(llllllllll)",
Guido van Rossume5372401993-03-16 12:15:04 +0000266 (long)st.st_mode,
267 (long)st.st_ino,
268 (long)st.st_dev,
269 (long)st.st_nlink,
270 (long)st.st_uid,
271 (long)st.st_gid,
272 (long)st.st_size,
273 (long)st.st_atime,
274 (long)st.st_mtime,
275 (long)st.st_ctime);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000276}
277
278
279/* POSIX methods */
280
281static object *
282posix_chdir(self, args)
283 object *self;
284 object *args;
285{
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000286 return posix_1str(args, chdir);
287}
288
289static object *
290posix_chmod(self, args)
291 object *self;
292 object *args;
293{
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000294 return posix_strint(args, chmod);
295}
296
Guido van Rossumb6775db1994-08-01 11:34:53 +0000297#ifdef HAVE_CHOWN
298static object *
299posix_chown(self, args)
300 object *self;
301 object *args;
302{
303 return posix_strintint(args, chown);
304}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000305#endif /* HAVE_CHOWN */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000306
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000307static object *
308posix_getcwd(self, args)
309 object *self;
310 object *args;
311{
312 char buf[1026];
Guido van Rossumff4949e1992-08-05 19:58:53 +0000313 char *res;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000314 if (!getnoarg(args))
315 return NULL;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000316 BGN_SAVE
317 res = getcwd(buf, sizeof buf);
318 END_SAVE
319 if (res == NULL)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000320 return posix_error();
321 return newstringobject(buf);
322}
323
Guido van Rossumb6775db1994-08-01 11:34:53 +0000324#ifdef HAVE_LINK
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000325static object *
326posix_link(self, args)
327 object *self;
328 object *args;
329{
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000330 return posix_2str(args, link);
331}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000332#endif /* HAVE_LINK */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000333
Guido van Rossumb6775db1994-08-01 11:34:53 +0000334static object *
335posix_listdir(self, args)
336 object *self;
337 object *args;
338{
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000339#ifdef NT
340
Guido van Rossumb6775db1994-08-01 11:34:53 +0000341 char *name;
342 int len;
343 object *d, *v;
344 HANDLE hFindFile;
345 WIN32_FIND_DATA FileData;
346 char namebuf[MAX_PATH+5];
347
348 if (!getargs(args, "s#", &name, &len))
349 return NULL;
350 if (len >= MAX_PATH) {
351 err_setstr(ValueError, "path too long");
352 return NULL;
353 }
354 strcpy(namebuf, name);
355 if (namebuf[len-1] != '/' && namebuf[len-1] != '\\')
356 namebuf[len++] = '/';
357 strcpy(namebuf + len, "*.*");
358
359 if ((d = newlistobject(0)) == NULL)
360 return NULL;
361
362 hFindFile = FindFirstFile(namebuf, &FileData);
363 if (hFindFile == INVALID_HANDLE_VALUE) {
364 errno = GetLastError();
365 return posix_error();
366 }
367 do {
368 v = newstringobject(FileData.cFileName);
369 if (v == NULL) {
370 DECREF(d);
371 d = NULL;
372 break;
373 }
374 if (addlistitem(d, v) != 0) {
375 DECREF(v);
376 DECREF(d);
377 d = NULL;
378 break;
379 }
380 DECREF(v);
381 } while (FindNextFile(hFindFile, &FileData) == TRUE);
382
383 if (FindClose(hFindFile) == FALSE) {
384 errno = GetLastError();
385 return posix_error();
386 }
387
388 return d;
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000389
390#else /* !NT */
391
Guido van Rossumef0a00e1992-01-27 16:51:30 +0000392 char *name;
393 object *d, *v;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000394 DIR *dirp;
Guido van Rossumb6775db1994-08-01 11:34:53 +0000395 struct dirent *ep;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +0000396 if (!getargs(args, "s", &name))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000397 return NULL;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000398 BGN_SAVE
399 if ((dirp = opendir(name)) == NULL) {
400 RET_SAVE
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000401 return posix_error();
Guido van Rossumff4949e1992-08-05 19:58:53 +0000402 }
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000403 if ((d = newlistobject(0)) == NULL) {
404 closedir(dirp);
Guido van Rossumff4949e1992-08-05 19:58:53 +0000405 RET_SAVE
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000406 return NULL;
407 }
408 while ((ep = readdir(dirp)) != NULL) {
409 v = newstringobject(ep->d_name);
410 if (v == NULL) {
411 DECREF(d);
412 d = NULL;
413 break;
414 }
415 if (addlistitem(d, v) != 0) {
416 DECREF(v);
417 DECREF(d);
418 d = NULL;
419 break;
420 }
421 DECREF(v);
422 }
423 closedir(dirp);
Guido van Rossumff4949e1992-08-05 19:58:53 +0000424 END_SAVE
Guido van Rossum0ee42cd1991-04-08 21:01:03 +0000425
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000426 return d;
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000427
428#endif /* !NT */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000429}
430
431static object *
432posix_mkdir(self, args)
433 object *self;
434 object *args;
435{
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000436 return posix_strint(args, mkdir);
437}
438
Guido van Rossumb6775db1994-08-01 11:34:53 +0000439#ifdef HAVE_NICE
Guido van Rossum775f4da1993-01-09 17:18:52 +0000440static object *
441posix_nice(self, args)
442 object *self;
443 object *args;
444{
445 int increment, value;
446
447 if (!getargs(args, "i", &increment))
448 return NULL;
449 value = nice(increment);
450 if (value == -1)
451 return posix_error();
452 return newintobject((long) value);
453}
Guido van Rossumb6775db1994-08-01 11:34:53 +0000454#endif /* HAVE_NICE */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +0000455
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000456static object *
457posix_rename(self, args)
458 object *self;
459 object *args;
460{
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000461 return posix_2str(args, rename);
462}
463
464static object *
465posix_rmdir(self, args)
466 object *self;
467 object *args;
468{
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000469 return posix_1str(args, rmdir);
470}
471
472static object *
473posix_stat(self, args)
474 object *self;
475 object *args;
476{
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000477 return posix_do_stat(self, args, stat);
478}
479
480static object *
481posix_system(self, args)
482 object *self;
483 object *args;
484{
Guido van Rossumef0a00e1992-01-27 16:51:30 +0000485 char *command;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000486 long sts;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +0000487 if (!getargs(args, "s", &command))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000488 return NULL;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000489 BGN_SAVE
Guido van Rossumef0a00e1992-01-27 16:51:30 +0000490 sts = system(command);
Guido van Rossumff4949e1992-08-05 19:58:53 +0000491 END_SAVE
492 return newintobject(sts);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000493}
494
495static object *
496posix_umask(self, args)
497 object *self;
498 object *args;
499{
500 int i;
501 if (!getintarg(args, &i))
502 return NULL;
503 i = umask(i);
504 if (i < 0)
505 return posix_error();
506 return newintobject((long)i);
507}
508
509static object *
510posix_unlink(self, args)
511 object *self;
512 object *args;
513{
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000514 return posix_1str(args, unlink);
515}
516
Guido van Rossumb6775db1994-08-01 11:34:53 +0000517#ifdef HAVE_UNAME
Guido van Rossumc39de5f1992-02-05 11:15:54 +0000518static object *
519posix_uname(self, args)
520 object *self;
521 object *args;
522{
Guido van Rossumc39de5f1992-02-05 11:15:54 +0000523 struct utsname u;
524 object *v;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000525 int res;
Guido van Rossum50e61dc1992-03-27 17:22:31 +0000526 if (!getnoarg(args))
527 return NULL;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000528 BGN_SAVE
529 res = uname(&u);
530 END_SAVE
531 if (res < 0)
Guido van Rossumc39de5f1992-02-05 11:15:54 +0000532 return posix_error();
Guido van Rossume5372401993-03-16 12:15:04 +0000533 return mkvalue("(sssss)",
534 u.sysname,
535 u.nodename,
536 u.release,
537 u.version,
538 u.machine);
Guido van Rossumc39de5f1992-02-05 11:15:54 +0000539}
Guido van Rossumb6775db1994-08-01 11:34:53 +0000540#endif /* HAVE_UNAME */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +0000541
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000542static object *
Guido van Rossum1ff6cb41991-04-08 20:59:13 +0000543posix_utime(self, args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000544 object *self;
545 object *args;
546{
Guido van Rossumef0a00e1992-01-27 16:51:30 +0000547 char *path;
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 Rossumef0a00e1992-01-27 16:51:30 +0000562 if (!getargs(args, "(s(ll))", &path, &ATIME, &MTIME))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000563 return NULL;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000564 BGN_SAVE
565 res = utime(path, UTIME_ARG);
566 END_SAVE
567 if (res < 0)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000568 return posix_error();
569 INCREF(None);
570 return None;
Guido van Rossum1ff6cb41991-04-08 20:59:13 +0000571#undef UTIME_ARG
572#undef ATIME
573#undef MTIME
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000574}
575
Guido van Rossum85e3b011991-06-03 12:42:10 +0000576
Guido van Rossum3b066191991-06-04 19:40:25 +0000577/* Process operations */
Guido van Rossum85e3b011991-06-03 12:42:10 +0000578
579static object *
580posix__exit(self, args)
581 object *self;
582 object *args;
583{
584 int sts;
585 if (!getintarg(args, &sts))
586 return NULL;
587 _exit(sts);
588 /* NOTREACHED */
589}
590
Guido van Rossum85e3b011991-06-03 12:42:10 +0000591static object *
Guido van Rossum89b33251993-10-22 14:26:06 +0000592posix_execv(self, args)
Guido van Rossum85e3b011991-06-03 12:42:10 +0000593 object *self;
594 object *args;
595{
Guido van Rossumef0a00e1992-01-27 16:51:30 +0000596 char *path;
597 object *argv;
Guido van Rossum85e3b011991-06-03 12:42:10 +0000598 char **argvlist;
599 int i, argc;
600 object *(*getitem) PROTO((object *, int));
601
Guido van Rossum89b33251993-10-22 14:26:06 +0000602 /* execv has two arguments: (path, argv), where
Guido van Rossum85e3b011991-06-03 12:42:10 +0000603 argv is a list or tuple of strings. */
604
Guido van Rossumef0a00e1992-01-27 16:51:30 +0000605 if (!getargs(args, "(sO)", &path, &argv))
Guido van Rossum85e3b011991-06-03 12:42:10 +0000606 return NULL;
Guido van Rossum85e3b011991-06-03 12:42:10 +0000607 if (is_listobject(argv)) {
608 argc = getlistsize(argv);
609 getitem = getlistitem;
610 }
611 else if (is_tupleobject(argv)) {
612 argc = gettuplesize(argv);
613 getitem = gettupleitem;
614 }
Guido van Rossumef0a00e1992-01-27 16:51:30 +0000615 else {
616 badarg:
617 err_badarg();
618 return NULL;
619 }
Guido van Rossum85e3b011991-06-03 12:42:10 +0000620
621 argvlist = NEW(char *, argc+1);
622 if (argvlist == NULL)
623 return NULL;
624 for (i = 0; i < argc; i++) {
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +0000625 if (!getargs((*getitem)(argv, i), "s", &argvlist[i])) {
Guido van Rossum85e3b011991-06-03 12:42:10 +0000626 DEL(argvlist);
627 goto badarg;
628 }
Guido van Rossum85e3b011991-06-03 12:42:10 +0000629 }
630 argvlist[argc] = NULL;
631
Guido van Rossumb6775db1994-08-01 11:34:53 +0000632#ifdef BAD_EXEC_PROTOTYPES
633 execv(path, (const char **) argvlist);
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000634#else /* BAD_EXEC_PROTOTYPES */
Guido van Rossumef0a00e1992-01-27 16:51:30 +0000635 execv(path, argvlist);
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000636#endif /* BAD_EXEC_PROTOTYPES */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000637
Guido van Rossum85e3b011991-06-03 12:42:10 +0000638 /* If we get here it's definitely an error */
639
640 DEL(argvlist);
641 return posix_error();
642}
643
644static object *
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +0000645posix_execve(self, args)
646 object *self;
647 object *args;
648{
649 char *path;
650 object *argv, *env;
651 char **argvlist;
652 char **envlist;
653 object *key, *val;
654 int i, pos, argc, envc;
655 object *(*getitem) PROTO((object *, int));
656
657 /* execve has three arguments: (path, argv, env), where
658 argv is a list or tuple of strings and env is a dictionary
659 like posix.environ. */
660
661 if (!getargs(args, "(sOO)", &path, &argv, &env))
662 return NULL;
663 if (is_listobject(argv)) {
664 argc = getlistsize(argv);
665 getitem = getlistitem;
666 }
667 else if (is_tupleobject(argv)) {
668 argc = gettuplesize(argv);
669 getitem = gettupleitem;
670 }
671 else {
672 err_setstr(TypeError, "argv must be tuple or list");
673 return NULL;
674 }
675 if (!is_dictobject(env)) {
676 err_setstr(TypeError, "env must be dictionary");
677 return NULL;
678 }
679
680 argvlist = NEW(char *, argc+1);
681 if (argvlist == NULL) {
682 err_nomem();
683 return NULL;
684 }
685 for (i = 0; i < argc; i++) {
686 if (!getargs((*getitem)(argv, i),
687 "s;argv must be list of strings",
688 &argvlist[i])) {
689 goto fail_1;
690 }
691 }
692 argvlist[argc] = NULL;
693
694 i = getmappingsize(env);
695 envlist = NEW(char *, i + 1);
696 if (envlist == NULL) {
697 err_nomem();
698 goto fail_1;
699 }
700 pos = 0;
701 envc = 0;
702 while (mappinggetnext(env, &pos, &key, &val)) {
703 char *p, *k, *v;
704 if (!getargs(key, "s;non-string key in env", &k) ||
705 !getargs(val, "s;non-string value in env", &v)) {
706 goto fail_2;
707 }
708 p = NEW(char, getstringsize(key) + getstringsize(val) + 2);
709 if (p == NULL) {
710 err_nomem();
711 goto fail_2;
712 }
713 sprintf(p, "%s=%s", k, v);
714 envlist[envc++] = p;
715 }
716 envlist[envc] = 0;
717
Guido van Rossumb6775db1994-08-01 11:34:53 +0000718
719#ifdef BAD_EXEC_PROTOTYPES
720 execve(path, (const char **)argvlist, envlist);
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000721#else /* BAD_EXEC_PROTOTYPES */
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +0000722 execve(path, argvlist, envlist);
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000723#endif /* BAD_EXEC_PROTOTYPES */
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +0000724
725 /* If we get here it's definitely an error */
726
727 (void) posix_error();
728
729 fail_2:
730 while (--envc >= 0)
731 DEL(envlist[envc]);
732 DEL(envlist);
733 fail_1:
734 DEL(argvlist);
735
736 return NULL;
737}
738
Guido van Rossum794d8131994-08-23 13:48:48 +0000739#ifndef NT
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +0000740static object *
Guido van Rossum85e3b011991-06-03 12:42:10 +0000741posix_fork(self, args)
742 object *self;
743 object *args;
744{
745 int pid;
Guido van Rossum50e61dc1992-03-27 17:22:31 +0000746 if (!getnoarg(args))
747 return NULL;
Guido van Rossum85e3b011991-06-03 12:42:10 +0000748 pid = fork();
749 if (pid == -1)
750 return posix_error();
751 return newintobject((long)pid);
752}
753
754static object *
Guido van Rossum46003ff1992-05-15 11:05:24 +0000755posix_getegid(self, args)
756 object *self;
757 object *args;
758{
759 if (!getnoarg(args))
760 return NULL;
761 return newintobject((long)getegid());
762}
763
764static object *
765posix_geteuid(self, args)
766 object *self;
767 object *args;
768{
769 if (!getnoarg(args))
770 return NULL;
771 return newintobject((long)geteuid());
772}
773
774static object *
775posix_getgid(self, args)
776 object *self;
777 object *args;
778{
779 if (!getnoarg(args))
780 return NULL;
781 return newintobject((long)getgid());
782}
Guido van Rossumb078ce11994-08-29 14:01:43 +0000783#endif /* !NT */
Guido van Rossum46003ff1992-05-15 11:05:24 +0000784
785static object *
Guido van Rossum85e3b011991-06-03 12:42:10 +0000786posix_getpid(self, args)
787 object *self;
788 object *args;
789{
Guido van Rossum04814471991-06-04 20:23:49 +0000790 if (!getnoarg(args))
Guido van Rossum85e3b011991-06-03 12:42:10 +0000791 return NULL;
792 return newintobject((long)getpid());
793}
794
Guido van Rossumb6775db1994-08-01 11:34:53 +0000795#ifdef HAVE_GETPGRP
Guido van Rossum85e3b011991-06-03 12:42:10 +0000796static object *
Guido van Rossum04814471991-06-04 20:23:49 +0000797posix_getpgrp(self, args)
798 object *self;
799 object *args;
800{
801 if (!getnoarg(args))
802 return NULL;
Guido van Rossumb6775db1994-08-01 11:34:53 +0000803#ifdef GETPGRP_HAVE_ARG
Guido van Rossum971443b1991-06-07 13:59:29 +0000804 return newintobject((long)getpgrp(0));
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000805#else /* GETPGRP_HAVE_ARG */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000806 return newintobject((long)getpgrp());
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000807#endif /* GETPGRP_HAVE_ARG */
Guido van Rossum04814471991-06-04 20:23:49 +0000808}
Guido van Rossumb6775db1994-08-01 11:34:53 +0000809#endif /* HAVE_GETPGRP */
Guido van Rossum04814471991-06-04 20:23:49 +0000810
Guido van Rossumb6775db1994-08-01 11:34:53 +0000811#ifdef HAVE_SETPGRP
Guido van Rossum04814471991-06-04 20:23:49 +0000812static object *
Guido van Rossumc2670a01992-09-13 20:07:29 +0000813posix_setpgrp(self, args)
814 object *self;
815 object *args;
816{
817 if (!getnoarg(args))
818 return NULL;
Guido van Rossum64933891994-10-20 21:56:42 +0000819#ifdef SETPGRP_HAVE_ARG
Guido van Rossumc2670a01992-09-13 20:07:29 +0000820 if (setpgrp(0, 0) < 0)
Guido van Rossum64933891994-10-20 21:56:42 +0000821#else /* SETPGRP_HAVE_ARG */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000822 if (setpgrp() < 0)
Guido van Rossum64933891994-10-20 21:56:42 +0000823#endif /* SETPGRP_HAVE_ARG */
Guido van Rossum687dd131993-05-17 08:34:16 +0000824 return posix_error();
Guido van Rossumc2670a01992-09-13 20:07:29 +0000825 INCREF(None);
826 return None;
827}
828
Guido van Rossumb6775db1994-08-01 11:34:53 +0000829#endif /* HAVE_SETPGRP */
830
Guido van Rossum794d8131994-08-23 13:48:48 +0000831#ifndef NT
Guido van Rossumc2670a01992-09-13 20:07:29 +0000832static object *
Guido van Rossum85e3b011991-06-03 12:42:10 +0000833posix_getppid(self, args)
834 object *self;
835 object *args;
836{
Guido van Rossum04814471991-06-04 20:23:49 +0000837 if (!getnoarg(args))
Guido van Rossum85e3b011991-06-03 12:42:10 +0000838 return NULL;
839 return newintobject((long)getppid());
840}
841
842static object *
Guido van Rossum46003ff1992-05-15 11:05:24 +0000843posix_getuid(self, args)
844 object *self;
845 object *args;
846{
847 if (!getnoarg(args))
848 return NULL;
849 return newintobject((long)getuid());
850}
851
852static object *
Guido van Rossum85e3b011991-06-03 12:42:10 +0000853posix_kill(self, args)
854 object *self;
855 object *args;
856{
857 int pid, sig;
Guido van Rossum234f9421993-06-17 12:35:49 +0000858 if (!getargs(args, "(ii)", &pid, &sig))
Guido van Rossum85e3b011991-06-03 12:42:10 +0000859 return NULL;
860 if (kill(pid, sig) == -1)
861 return posix_error();
862 INCREF(None);
863 return None;
864}
Guido van Rossum794d8131994-08-23 13:48:48 +0000865#endif /* !NT */
Guido van Rossum85e3b011991-06-03 12:42:10 +0000866
867static object *
Guido van Rossum3b066191991-06-04 19:40:25 +0000868posix_popen(self, args)
869 object *self;
870 object *args;
871{
Guido van Rossumef0a00e1992-01-27 16:51:30 +0000872 char *name, *mode;
Guido van Rossum3b066191991-06-04 19:40:25 +0000873 FILE *fp;
Guido van Rossumef0a00e1992-01-27 16:51:30 +0000874 if (!getargs(args, "(ss)", &name, &mode))
Guido van Rossum3b066191991-06-04 19:40:25 +0000875 return NULL;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000876 BGN_SAVE
Guido van Rossumef0a00e1992-01-27 16:51:30 +0000877 fp = popen(name, mode);
Guido van Rossumff4949e1992-08-05 19:58:53 +0000878 END_SAVE
Guido van Rossum3b066191991-06-04 19:40:25 +0000879 if (fp == NULL)
880 return posix_error();
Guido van Rossumef0a00e1992-01-27 16:51:30 +0000881 return newopenfileobject(fp, name, mode, pclose);
Guido van Rossum3b066191991-06-04 19:40:25 +0000882}
883
Guido van Rossumb6775db1994-08-01 11:34:53 +0000884#ifdef HAVE_SETUID
Guido van Rossum3b066191991-06-04 19:40:25 +0000885static object *
Guido van Rossuma3d78fb1993-11-10 09:23:53 +0000886posix_setuid(self, args)
887 object *self;
888 object *args;
889{
890 int uid;
891 if (!getargs(args, "i", &uid))
892 return NULL;
893 if (setuid(uid) < 0)
894 return posix_error();
895 INCREF(None);
896 return None;
897}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000898#endif /* HAVE_SETUID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +0000899
Guido van Rossumb6775db1994-08-01 11:34:53 +0000900#ifdef HAVE_SETGID
Guido van Rossuma3d78fb1993-11-10 09:23:53 +0000901static object *
902posix_setgid(self, args)
903 object *self;
904 object *args;
905{
906 int gid;
907 if (!getargs(args, "i", &gid))
908 return NULL;
909 if (setgid(gid) < 0)
910 return posix_error();
911 INCREF(None);
912 return None;
913}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000914#endif /* HAVE_SETGID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +0000915
Guido van Rossumb6775db1994-08-01 11:34:53 +0000916#ifdef HAVE_WAITPID
Guido van Rossuma3d78fb1993-11-10 09:23:53 +0000917static object *
Guido van Rossum21803b81992-08-09 12:55:27 +0000918posix_waitpid(self, args)
Guido van Rossum85e3b011991-06-03 12:42:10 +0000919 object *self;
920 object *args;
921{
Guido van Rossum21803b81992-08-09 12:55:27 +0000922 int pid, options, sts;
923 if (!getargs(args, "(ii)", &pid, &options))
924 return NULL;
925 BGN_SAVE
926 pid = waitpid(pid, &sts, options);
927 END_SAVE
Guido van Rossum85e3b011991-06-03 12:42:10 +0000928 if (pid == -1)
929 return posix_error();
Guido van Rossum21803b81992-08-09 12:55:27 +0000930 else
931 return mkvalue("ii", pid, sts);
Guido van Rossum21803b81992-08-09 12:55:27 +0000932}
Guido van Rossumb6775db1994-08-01 11:34:53 +0000933#endif /* HAVE_WAITPID */
Guido van Rossum21803b81992-08-09 12:55:27 +0000934
Guido van Rossum794d8131994-08-23 13:48:48 +0000935#ifndef NT
Guido van Rossum21803b81992-08-09 12:55:27 +0000936static object *
937posix_wait(self, args)
938 object *self;
939 object *args;
940{
941 int pid, sts;
Guido van Rossum21803b81992-08-09 12:55:27 +0000942 BGN_SAVE
943 pid = wait(&sts);
944 END_SAVE
945 if (pid == -1)
946 return posix_error();
947 else
948 return mkvalue("ii", pid, sts);
Guido van Rossum85e3b011991-06-03 12:42:10 +0000949}
Guido van Rossum794d8131994-08-23 13:48:48 +0000950#endif /* !NT */
Guido van Rossum85e3b011991-06-03 12:42:10 +0000951
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000952static object *
953posix_lstat(self, args)
954 object *self;
955 object *args;
956{
Guido van Rossumb6775db1994-08-01 11:34:53 +0000957#ifdef HAVE_LSTAT
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000958 return posix_do_stat(self, args, lstat);
Guido van Rossumb6775db1994-08-01 11:34:53 +0000959#else /* !HAVE_LSTAT */
960 return posix_do_stat(self, args, stat);
961#endif /* !HAVE_LSTAT */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000962}
963
Guido van Rossumb6775db1994-08-01 11:34:53 +0000964#ifdef HAVE_READLINK
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000965static object *
966posix_readlink(self, args)
967 object *self;
968 object *args;
969{
Guido van Rossumb6775db1994-08-01 11:34:53 +0000970 char buf[MAXPATHLEN];
Guido van Rossumef0a00e1992-01-27 16:51:30 +0000971 char *path;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000972 int n;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +0000973 if (!getargs(args, "s", &path))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000974 return NULL;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000975 BGN_SAVE
Guido van Rossum50e61dc1992-03-27 17:22:31 +0000976 n = readlink(path, buf, (int) sizeof buf);
Guido van Rossumff4949e1992-08-05 19:58:53 +0000977 END_SAVE
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000978 if (n < 0)
979 return posix_error();
980 return newsizedstringobject(buf, n);
981}
Guido van Rossumb6775db1994-08-01 11:34:53 +0000982#endif /* HAVE_READLINK */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000983
Guido van Rossumb6775db1994-08-01 11:34:53 +0000984#ifdef HAVE_SYMLINK
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000985static object *
986posix_symlink(self, args)
987 object *self;
988 object *args;
989{
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000990 return posix_2str(args, symlink);
991}
Guido van Rossumb6775db1994-08-01 11:34:53 +0000992#endif /* HAVE_SYMLINK */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000993
Guido van Rossumb6775db1994-08-01 11:34:53 +0000994#ifdef HAVE_TIMES
995#ifndef HZ
996#define HZ 60 /* Universal constant :-) */
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000997#endif /* HZ */
Guido van Rossum22db57e1992-04-05 14:25:30 +0000998static object *
999posix_times(self, args)
1000 object *self;
1001 object *args;
1002{
1003 struct tms t;
1004 clock_t c;
Guido van Rossum22db57e1992-04-05 14:25:30 +00001005 if (!getnoarg(args))
1006 return NULL;
1007 errno = 0;
1008 c = times(&t);
Guido van Rossum687dd131993-05-17 08:34:16 +00001009 if (c == (clock_t) -1)
1010 return posix_error();
Guido van Rossum0b0db8e1993-01-21 16:07:51 +00001011 return mkvalue("dddd",
1012 (double)t.tms_utime / HZ,
1013 (double)t.tms_stime / HZ,
1014 (double)t.tms_cutime / HZ,
1015 (double)t.tms_cstime / HZ);
Guido van Rossum22db57e1992-04-05 14:25:30 +00001016}
Guido van Rossumb6775db1994-08-01 11:34:53 +00001017#endif /* HAVE_TIMES */
Guido van Rossum14ed0b21994-09-29 09:50:09 +00001018#ifdef NT
1019#define HAVE_TIMES /* so the method table will pick it up */
1020static object *
1021posix_times(self, args)
1022 object *self;
1023 object *args;
1024{
1025 FILETIME create, exit, kernel, user;
1026 HANDLE hProc;
1027 if (!getnoarg(args))
1028 return NULL;
1029 hProc = GetCurrentProcess();
1030 GetProcessTimes(hProc,&create, &exit, &kernel, &user);
1031 return mkvalue("dddd",
1032 (double)(kernel.dwHighDateTime*2E32+kernel.dwLowDateTime) / 2E6,
1033 (double)(user.dwHighDateTime*2E32+user.dwLowDateTime) / 2E6,
1034 (double)0,
1035 (double)0);
1036}
1037#endif /* NT */
Guido van Rossum22db57e1992-04-05 14:25:30 +00001038
Guido van Rossumb6775db1994-08-01 11:34:53 +00001039#ifdef HAVE_SETSID
Guido van Rossumc2670a01992-09-13 20:07:29 +00001040static object *
1041posix_setsid(self, args)
1042 object *self;
1043 object *args;
1044{
1045 if (!getnoarg(args))
1046 return NULL;
Guido van Rossum687dd131993-05-17 08:34:16 +00001047 if (setsid() < 0)
1048 return posix_error();
Guido van Rossumc2670a01992-09-13 20:07:29 +00001049 INCREF(None);
1050 return None;
1051}
Guido van Rossumb6775db1994-08-01 11:34:53 +00001052#endif /* HAVE_SETSID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00001053
Guido van Rossumb6775db1994-08-01 11:34:53 +00001054#ifdef HAVE_SETPGID
Guido van Rossumc2670a01992-09-13 20:07:29 +00001055static object *
1056posix_setpgid(self, args)
1057 object *self;
1058 object *args;
1059{
1060 int pid, pgrp;
1061 if (!getargs(args, "(ii)", &pid, &pgrp))
1062 return NULL;
Guido van Rossum687dd131993-05-17 08:34:16 +00001063 if (setpgid(pid, pgrp) < 0)
1064 return posix_error();
Guido van Rossumc2670a01992-09-13 20:07:29 +00001065 INCREF(None);
1066 return None;
1067}
Guido van Rossumb6775db1994-08-01 11:34:53 +00001068#endif /* HAVE_SETPGID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00001069
Guido van Rossumb6775db1994-08-01 11:34:53 +00001070#ifdef HAVE_TCGETPGRP
Guido van Rossum7066dd71992-09-17 17:54:56 +00001071static object *
1072posix_tcgetpgrp(self, args)
1073 object *self;
1074 object *args;
1075{
1076 int fd, pgid;
1077 if (!getargs(args, "i", &fd))
1078 return NULL;
1079 pgid = tcgetpgrp(fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00001080 if (pgid < 0)
1081 return posix_error();
Guido van Rossum7066dd71992-09-17 17:54:56 +00001082 return newintobject((long)pgid);
1083}
Guido van Rossumb6775db1994-08-01 11:34:53 +00001084#endif /* HAVE_TCGETPGRP */
Guido van Rossum7066dd71992-09-17 17:54:56 +00001085
Guido van Rossumb6775db1994-08-01 11:34:53 +00001086#ifdef HAVE_TCSETPGRP
Guido van Rossum7066dd71992-09-17 17:54:56 +00001087static object *
1088posix_tcsetpgrp(self, args)
1089 object *self;
1090 object *args;
1091{
1092 int fd, pgid;
1093 if (!getargs(args, "(ii)", &fd, &pgid))
1094 return NULL;
Guido van Rossum687dd131993-05-17 08:34:16 +00001095 if (tcsetpgrp(fd, pgid) < 0)
1096 return posix_error();
Guido van Rossum7066dd71992-09-17 17:54:56 +00001097 INCREF(None);
1098 return None;
1099}
Guido van Rossumb6775db1994-08-01 11:34:53 +00001100#endif /* HAVE_TCSETPGRP */
Guido van Rossum22db57e1992-04-05 14:25:30 +00001101
Guido van Rossum687dd131993-05-17 08:34:16 +00001102/* Functions acting on file descriptors */
1103
Guido van Rossum234f9421993-06-17 12:35:49 +00001104static object *
Guido van Rossum687dd131993-05-17 08:34:16 +00001105posix_open(self, args)
1106 object *self;
1107 object *args;
1108{
1109 char *file;
1110 int flag;
1111 int mode = 0777;
1112 int fd;
1113 if (!getargs(args, "(si)", &file, &flag)) {
1114 err_clear();
1115 if (!getargs(args, "(sii)", &file, &flag, &mode))
1116 return NULL;
1117 }
1118 BGN_SAVE
1119 fd = open(file, flag, mode);
1120 END_SAVE
1121 if (fd < 0)
1122 return posix_error();
1123 return newintobject((long)fd);
1124}
1125
Guido van Rossum234f9421993-06-17 12:35:49 +00001126static object *
Guido van Rossum687dd131993-05-17 08:34:16 +00001127posix_close(self, args)
1128 object *self;
1129 object *args;
1130{
1131 int fd, res;
1132 if (!getargs(args, "i", &fd))
1133 return NULL;
1134 BGN_SAVE
1135 res = close(fd);
1136 END_SAVE
1137 if (res < 0)
1138 return posix_error();
1139 INCREF(None);
1140 return None;
1141}
1142
Guido van Rossum234f9421993-06-17 12:35:49 +00001143static object *
Guido van Rossum687dd131993-05-17 08:34:16 +00001144posix_dup(self, args)
1145 object *self;
1146 object *args;
1147{
1148 int fd;
1149 if (!getargs(args, "i", &fd))
1150 return NULL;
1151 BGN_SAVE
1152 fd = dup(fd);
1153 END_SAVE
1154 if (fd < 0)
1155 return posix_error();
1156 return newintobject((long)fd);
1157}
1158
Guido van Rossum234f9421993-06-17 12:35:49 +00001159static object *
Guido van Rossum687dd131993-05-17 08:34:16 +00001160posix_dup2(self, args)
1161 object *self;
1162 object *args;
1163{
1164 int fd, fd2, res;
1165 if (!getargs(args, "(ii)", &fd, &fd2))
1166 return NULL;
1167 BGN_SAVE
1168 res = dup2(fd, fd2);
1169 END_SAVE
1170 if (res < 0)
1171 return posix_error();
1172 INCREF(None);
1173 return None;
1174}
1175
Guido van Rossum234f9421993-06-17 12:35:49 +00001176static object *
Guido van Rossum687dd131993-05-17 08:34:16 +00001177posix_lseek(self, args)
1178 object *self;
1179 object *args;
1180{
1181 int fd, how;
1182 long pos, res;
1183 if (!getargs(args, "(ili)", &fd, &pos, &how))
1184 return NULL;
1185#ifdef SEEK_SET
1186 /* Turn 0, 1, 2 into SEEK_{SET,CUR,END} */
1187 switch (how) {
1188 case 0: how = SEEK_SET; break;
1189 case 1: how = SEEK_CUR; break;
1190 case 2: how = SEEK_END; break;
1191 }
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001192#endif /* SEEK_END */
Guido van Rossum687dd131993-05-17 08:34:16 +00001193 BGN_SAVE
1194 res = lseek(fd, pos, how);
1195 END_SAVE
1196 if (res < 0)
1197 return posix_error();
1198 return newintobject(res);
1199}
1200
Guido van Rossum234f9421993-06-17 12:35:49 +00001201static object *
Guido van Rossum687dd131993-05-17 08:34:16 +00001202posix_read(self, args)
1203 object *self;
1204 object *args;
1205{
1206 int fd, size;
1207 object *buffer;
1208 if (!getargs(args, "(ii)", &fd, &size))
1209 return NULL;
1210 buffer = newsizedstringobject((char *)NULL, size);
1211 if (buffer == NULL)
1212 return NULL;
1213 BGN_SAVE
1214 size = read(fd, getstringvalue(buffer), size);
1215 END_SAVE
1216 if (size < 0) {
1217 DECREF(buffer);
1218 return posix_error();
1219 }
1220 resizestring(&buffer, size);
1221 return buffer;
1222}
1223
Guido van Rossum234f9421993-06-17 12:35:49 +00001224static object *
Guido van Rossum687dd131993-05-17 08:34:16 +00001225posix_write(self, args)
1226 object *self;
1227 object *args;
1228{
1229 int fd, size;
1230 char *buffer;
1231 if (!getargs(args, "(is#)", &fd, &buffer, &size))
1232 return NULL;
1233 BGN_SAVE
1234 size = write(fd, buffer, size);
1235 END_SAVE
1236 if (size < 0)
1237 return posix_error();
1238 return newintobject((long)size);
1239}
1240
Guido van Rossum234f9421993-06-17 12:35:49 +00001241static object *
Guido van Rossum687dd131993-05-17 08:34:16 +00001242posix_fstat(self, args)
1243 object *self;
1244 object *args;
1245{
1246 int fd;
1247 struct stat st;
1248 int res;
1249 if (!getargs(args, "i", &fd))
1250 return NULL;
1251 BGN_SAVE
1252 res = fstat(fd, &st);
1253 END_SAVE
1254 if (res != 0)
1255 return posix_error();
1256 return mkvalue("(llllllllll)",
1257 (long)st.st_mode,
1258 (long)st.st_ino,
1259 (long)st.st_dev,
1260 (long)st.st_nlink,
1261 (long)st.st_uid,
1262 (long)st.st_gid,
1263 (long)st.st_size,
1264 (long)st.st_atime,
1265 (long)st.st_mtime,
1266 (long)st.st_ctime);
1267}
1268
1269static object *
1270posix_fdopen(self, args)
1271 object *self;
1272 object *args;
1273{
1274 extern int fclose PROTO((FILE *));
1275 int fd;
1276 char *mode;
1277 FILE *fp;
1278 if (!getargs(args, "(is)", &fd, &mode))
1279 return NULL;
1280 BGN_SAVE
1281 fp = fdopen(fd, mode);
1282 END_SAVE
1283 if (fp == NULL)
1284 return posix_error();
1285 /* From now on, ignore SIGPIPE and let the error checking
1286 do the work. */
Guido van Rossum687dd131993-05-17 08:34:16 +00001287 return newopenfileobject(fp, "(fdopen)", mode, fclose);
1288}
1289
Guido van Rossum234f9421993-06-17 12:35:49 +00001290static object *
Guido van Rossum687dd131993-05-17 08:34:16 +00001291posix_pipe(self, args)
1292 object *self;
1293 object *args;
1294{
Guido van Rossum794d8131994-08-23 13:48:48 +00001295#ifndef NT
Guido van Rossum687dd131993-05-17 08:34:16 +00001296 int fds[2];
1297 int res;
1298 if (!getargs(args, ""))
1299 return NULL;
1300 BGN_SAVE
1301 res = pipe(fds);
1302 END_SAVE
1303 if (res != 0)
1304 return posix_error();
1305 return mkvalue("(ii)", fds[0], fds[1]);
Guido van Rossum794d8131994-08-23 13:48:48 +00001306#else /* NT */
1307 HANDLE read, write;
1308 BOOL ok;
1309 if (!getargs(args, ""))
1310 return NULL;
1311 BGN_SAVE
1312 ok = CreatePipe( &read, &write, NULL, 0);
1313 END_SAVE
1314 if (!ok)
1315 return posix_error();
1316 return mkvalue("(ii)", read, write);
1317#endif /* NT */
Guido van Rossum687dd131993-05-17 08:34:16 +00001318}
Guido van Rossum22db57e1992-04-05 14:25:30 +00001319
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001320static struct methodlist posix_methods[] = {
1321 {"chdir", posix_chdir},
1322 {"chmod", posix_chmod},
Guido van Rossumb6775db1994-08-01 11:34:53 +00001323#ifdef HAVE_CHOWN
1324 {"chown", posix_chown},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001325#endif /* HAVE_CHOWN */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001326 {"getcwd", posix_getcwd},
Guido van Rossumb6775db1994-08-01 11:34:53 +00001327#ifdef HAVE_LINK
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001328 {"link", posix_link},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001329#endif /* HAVE_LINK */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001330 {"listdir", posix_listdir},
Guido van Rossumc39de5f1992-02-05 11:15:54 +00001331 {"lstat", posix_lstat},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001332 {"mkdir", posix_mkdir},
Guido van Rossumb6775db1994-08-01 11:34:53 +00001333#ifdef HAVE_NICE
Guido van Rossum775f4da1993-01-09 17:18:52 +00001334 {"nice", posix_nice},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001335#endif /* HAVE_NICE */
Guido van Rossumb6775db1994-08-01 11:34:53 +00001336#ifdef HAVE_READLINK
Guido van Rossumc39de5f1992-02-05 11:15:54 +00001337 {"readlink", posix_readlink},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001338#endif /* HAVE_READLINK */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001339 {"rename", posix_rename},
1340 {"rmdir", posix_rmdir},
1341 {"stat", posix_stat},
Guido van Rossumb6775db1994-08-01 11:34:53 +00001342#ifdef HAVE_SYMLINK
Guido van Rossumc39de5f1992-02-05 11:15:54 +00001343 {"symlink", posix_symlink},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001344#endif /* HAVE_SYMLINK */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001345 {"system", posix_system},
1346 {"umask", posix_umask},
Guido van Rossumb6775db1994-08-01 11:34:53 +00001347#ifdef HAVE_UNAME
Guido van Rossumc39de5f1992-02-05 11:15:54 +00001348 {"uname", posix_uname},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001349#endif /* HAVE_UNAME */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001350 {"unlink", posix_unlink},
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00001351 {"utime", posix_utime},
Guido van Rossumb6775db1994-08-01 11:34:53 +00001352#ifdef HAVE_TIMES
Guido van Rossum22db57e1992-04-05 14:25:30 +00001353 {"times", posix_times},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001354#endif /* HAVE_TIMES */
Guido van Rossum85e3b011991-06-03 12:42:10 +00001355 {"_exit", posix__exit},
Guido van Rossum89b33251993-10-22 14:26:06 +00001356 {"execv", posix_execv},
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001357 {"execve", posix_execve},
Guido van Rossumb6775db1994-08-01 11:34:53 +00001358#ifndef NT
Guido van Rossum85e3b011991-06-03 12:42:10 +00001359 {"fork", posix_fork},
Guido van Rossum46003ff1992-05-15 11:05:24 +00001360 {"getegid", posix_getegid},
1361 {"geteuid", posix_geteuid},
1362 {"getgid", posix_getgid},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001363#endif /* !NT */
Guido van Rossum85e3b011991-06-03 12:42:10 +00001364 {"getpid", posix_getpid},
Guido van Rossumb6775db1994-08-01 11:34:53 +00001365#ifdef HAVE_GETPGRP
Guido van Rossum04814471991-06-04 20:23:49 +00001366 {"getpgrp", posix_getpgrp},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001367#endif /* HAVE_GETPGRP */
Guido van Rossumb6775db1994-08-01 11:34:53 +00001368#ifndef NT
Guido van Rossum85e3b011991-06-03 12:42:10 +00001369 {"getppid", posix_getppid},
Guido van Rossum46003ff1992-05-15 11:05:24 +00001370 {"getuid", posix_getuid},
Guido van Rossum85e3b011991-06-03 12:42:10 +00001371 {"kill", posix_kill},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001372#endif /* !NT */
Guido van Rossum3b066191991-06-04 19:40:25 +00001373 {"popen", posix_popen},
Guido van Rossumb6775db1994-08-01 11:34:53 +00001374#ifdef HAVE_SETUID
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00001375 {"setuid", posix_setuid},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001376#endif /* HAVE_SETUID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00001377#ifdef HAVE_SETGID
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00001378 {"setgid", posix_setgid},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001379#endif /* HAVE_SETGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00001380#ifdef HAVE_SETPGRP
Guido van Rossumc2670a01992-09-13 20:07:29 +00001381 {"setpgrp", posix_setpgrp},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001382#endif /* HAVE_SETPGRP */
Guido van Rossumb6775db1994-08-01 11:34:53 +00001383#ifndef NT
Guido van Rossum85e3b011991-06-03 12:42:10 +00001384 {"wait", posix_wait},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001385#endif /* !NT */
Guido van Rossumb6775db1994-08-01 11:34:53 +00001386#ifdef HAVE_WAITPID
Guido van Rossum21803b81992-08-09 12:55:27 +00001387 {"waitpid", posix_waitpid},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001388#endif /* HAVE_WAITPID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00001389#ifdef HAVE_SETSID
Guido van Rossumc2670a01992-09-13 20:07:29 +00001390 {"setsid", posix_setsid},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001391#endif /* HAVE_SETSID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00001392#ifdef HAVE_SETPGID
Guido van Rossumc2670a01992-09-13 20:07:29 +00001393 {"setpgid", posix_setpgid},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001394#endif /* HAVE_SETPGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00001395#ifdef HAVE_TCGETPGRP
Guido van Rossum7066dd71992-09-17 17:54:56 +00001396 {"tcgetpgrp", posix_tcgetpgrp},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001397#endif /* HAVE_TCGETPGRP */
Guido van Rossumb6775db1994-08-01 11:34:53 +00001398#ifdef HAVE_TCSETPGRP
Guido van Rossum7066dd71992-09-17 17:54:56 +00001399 {"tcsetpgrp", posix_tcsetpgrp},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001400#endif /* HAVE_TCSETPGRP */
Guido van Rossum687dd131993-05-17 08:34:16 +00001401 {"open", posix_open},
1402 {"close", posix_close},
1403 {"dup", posix_dup},
1404 {"dup2", posix_dup2},
1405 {"lseek", posix_lseek},
1406 {"read", posix_read},
1407 {"write", posix_write},
1408 {"fstat", posix_fstat},
1409 {"fdopen", posix_fdopen},
Guido van Rossum687dd131993-05-17 08:34:16 +00001410 {"pipe", posix_pipe},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001411 {NULL, NULL} /* Sentinel */
1412};
1413
1414
Guido van Rossumb6775db1994-08-01 11:34:53 +00001415#ifdef NT
1416void
1417initnt()
1418{
1419 object *m, *d, *v;
1420
1421 m = initmodule("nt", posix_methods);
1422 d = getmoduledict(m);
1423
1424 /* Initialize nt.environ dictionary */
1425 v = convertenviron();
1426 if (v == NULL || dictinsert(d, "environ", v) != 0)
1427 fatal("can't define nt.environ");
1428 DECREF(v);
1429
1430 /* Initialize nt.error exception */
1431 PosixError = newstringobject("nt.error");
1432 if (PosixError == NULL || dictinsert(d, "error", PosixError) != 0)
1433 fatal("can't define nt.error");
1434}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001435#else /* !NT */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001436void
1437initposix()
1438{
1439 object *m, *d, *v;
1440
1441 m = initmodule("posix", posix_methods);
1442 d = getmoduledict(m);
1443
1444 /* Initialize posix.environ dictionary */
1445 v = convertenviron();
1446 if (v == NULL || dictinsert(d, "environ", v) != 0)
1447 fatal("can't define posix.environ");
1448 DECREF(v);
1449
1450 /* Initialize posix.error exception */
1451 PosixError = newstringobject("posix.error");
1452 if (PosixError == NULL || dictinsert(d, "error", PosixError) != 0)
1453 fatal("can't define posix.error");
1454}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001455#endif /* !NT */