blob: 7ffcd660a75994aae3f7eae6c1639bb342588dc0 [file] [log] [blame]
Guido van Rossumf70e43a1991-02-19 12:39:46 +00001/***********************************************************
Guido van Rossumb6775db1994-08-01 11:34:53 +00002Copyright 1991, 1992, 1993, 1994 by Stichting Mathematisch Centrum,
Guido van Rossum775f4da1993-01-09 17:18:52 +00003Amsterdam, The Netherlands.
Guido van Rossumf70e43a1991-02-19 12:39:46 +00004
5 All Rights Reserved
6
7Permission to use, copy, modify, and distribute this software and its
8documentation for any purpose and without fee is hereby granted,
9provided that the above copyright notice appear in all copies and that
10both that copyright notice and this permission notice appear in
11supporting documentation, and that the names of Stichting Mathematisch
12Centrum or CWI not be used in advertising or publicity pertaining to
13distribution of the software without specific, written prior permission.
14
15STICHTING MATHEMATISCH CENTRUM DISCLAIMS ALL WARRANTIES WITH REGARD TO
16THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
17FITNESS, IN NO EVENT SHALL STICHTING MATHEMATISCH CENTRUM BE LIABLE
18FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
19WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
20ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
21OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
22
23******************************************************************/
24
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000025/* POSIX module implementation */
26
Guido van Rossum3f5da241990-12-20 15:06:42 +000027#include "allobjects.h"
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000028#include "modsupport.h"
Guido van Rossumff4949e1992-08-05 19:58:53 +000029#include "ceval.h"
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000030
Guido van Rossumb6775db1994-08-01 11:34:53 +000031#include <string.h>
32#include <errno.h>
Guido van Rossumb6775db1994-08-01 11:34:53 +000033#include <sys/types.h>
34#include <sys/stat.h>
Guido van Rossumb6775db1994-08-01 11:34:53 +000035
36#include "mytime.h" /* For clock_t on some systems */
37
38#ifdef HAVE_FCNTL_H
39#include <fcntl.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000040#endif /* HAVE_FCNTL_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +000041
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000042#ifndef NT
Guido van Rossumb6775db1994-08-01 11:34:53 +000043#ifdef HAVE_UNISTD_H
Guido van Rossum0b0db8e1993-01-21 16:07:51 +000044#include <unistd.h>
Guido van Rossumb6775db1994-08-01 11:34:53 +000045#else /* !HAVE_UNISTD_H */
Guido van Rossuma2b7f401993-01-04 09:09:59 +000046extern int mkdir PROTO((const char *, mode_t));
47extern int chdir PROTO((const char *));
Guido van Rossume22e6441993-07-09 10:51:31 +000048extern int rmdir PROTO((const char *));
49extern int chmod PROTO((const char *, mode_t));
Guido van Rossumb6775db1994-08-01 11:34:53 +000050extern int chown PROTO((const char *, uid_t, gid_t));
51extern char *getcwd PROTO((char *, int));
Guido van Rossume22e6441993-07-09 10:51:31 +000052extern char *strerror PROTO((int));
Guido van Rossuma2b7f401993-01-04 09:09:59 +000053extern int link PROTO((const char *, const char *));
54extern int rename PROTO((const char *, const char *));
Guido van Rossuma2b7f401993-01-04 09:09:59 +000055extern int stat PROTO((const char *, struct stat *));
56extern int unlink PROTO((const char *));
57extern int pclose PROTO((FILE *));
Guido van Rossumb6775db1994-08-01 11:34:53 +000058#ifdef HAVE_SYMLINK
Guido van Rossuma2b7f401993-01-04 09:09:59 +000059extern int symlink PROTO((const char *, const char *));
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000060#endif /_ HAVE_SYMLINK */
Guido van Rossumb6775db1994-08-01 11:34:53 +000061#ifdef HAVE_LSTAT
62extern int lstat PROTO((const char *, struct stat *));
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000063#endif /* HAVE_LSTAT */
Guido van Rossumb6775db1994-08-01 11:34:53 +000064#endif /* !HAVE_UNISTD_H */
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000065#endif /* !NT */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000066
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000067#ifndef NT
Guido van Rossumb6775db1994-08-01 11:34:53 +000068/* XXX These are for SunOS4.1.3 but shouldn't hurt elsewhere */
69extern int rename();
70extern int pclose();
71extern int lstat();
72extern int symlink();
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000073#endif /* !NT */
Guido van Rossumb6775db1994-08-01 11:34:53 +000074
75#ifdef HAVE_UTIME_H
76#include <utime.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000077#endif /* HAVE_UTIME_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +000078
79#ifdef HAVE_SYS_TIMES_H
80#include <sys/times.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000081#endif /* HAVE_SYS_TIMES_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +000082
83#ifdef HAVE_SYS_PARAM_H
84#include <sys/param.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000085#endif /* HAVE_SYS_PARAM_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +000086
87#ifdef HAVE_SYS_UTSNAME_H
88#include <sys/utsname.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000089#endif /* HAVE_SYS_UTSNAME_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +000090
91#ifndef MAXPATHLEN
92#define MAXPATHLEN 1024
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000093#endif /* MAXPATHLEN */
Guido van Rossumb6775db1994-08-01 11:34:53 +000094
95/* unistd.h defines _POSIX_VERSION on POSIX.1 systems. */
96#if defined(DIRENT) || defined(_POSIX_VERSION)
97#include <dirent.h>
98#define NLENGTH(dirent) (strlen((dirent)->d_name))
99#else /* not (DIRENT or _POSIX_VERSION) */
100#define dirent direct
101#define NLENGTH(dirent) ((dirent)->d_namlen)
102#ifdef SYSNDIR
103#include <sys/ndir.h>
104#endif /* SYSNDIR */
105#ifdef SYSDIR
106#include <sys/dir.h>
107#endif /* SYSDIR */
108#ifdef NDIR
109#include <ndir.h>
110#endif /* NDIR */
111#endif /* not (DIRENT or _POSIX_VERSION) */
112
113#ifdef NT
114#include <direct.h>
115#include <io.h>
116#include <process.h>
117#include <windows.h>
118#define popen _popen
Guido van Rossum794d8131994-08-23 13:48:48 +0000119#define pclose _pclose
Guido van Rossumb6775db1994-08-01 11:34:53 +0000120#endif /* NT */
121
122#ifdef OS2
123#include <io.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000124#endif /* OS2 */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000125
126/* Return a dictionary corresponding to the POSIX environment table */
127
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000128#ifndef NT
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000129extern char **environ;
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000130#endif /* !NT */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000131
132static object *
133convertenviron()
134{
135 object *d;
136 char **e;
137 d = newdictobject();
138 if (d == NULL)
139 return NULL;
140 if (environ == NULL)
141 return d;
142 /* XXX This part ignores errors */
143 for (e = environ; *e != NULL; e++) {
144 object *v;
145 char *p = strchr(*e, '=');
146 if (p == NULL)
147 continue;
148 v = newstringobject(p+1);
149 if (v == NULL)
150 continue;
151 *p = '\0';
152 (void) dictinsert(d, *e, v);
153 *p = '=';
154 DECREF(v);
155 }
156 return d;
157}
158
159
160static object *PosixError; /* Exception posix.error */
161
162/* Set a POSIX-specific error from errno, and return NULL */
163
Guido van Rossum687dd131993-05-17 08:34:16 +0000164static object * posix_error() { return err_errno(PosixError);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000165}
166
167
168/* POSIX generic methods */
169
170static object *
171posix_1str(args, func)
172 object *args;
173 int (*func) FPROTO((const char *));
174{
Guido van Rossumef0a00e1992-01-27 16:51:30 +0000175 char *path1;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000176 int res;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +0000177 if (!getargs(args, "s", &path1))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000178 return NULL;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000179 BGN_SAVE
180 res = (*func)(path1);
181 END_SAVE
182 if (res < 0)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000183 return posix_error();
184 INCREF(None);
185 return None;
186}
187
188static object *
189posix_2str(args, func)
190 object *args;
191 int (*func) FPROTO((const char *, const char *));
192{
Guido van Rossumef0a00e1992-01-27 16:51:30 +0000193 char *path1, *path2;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000194 int res;
Guido van Rossum234f9421993-06-17 12:35:49 +0000195 if (!getargs(args, "(ss)", &path1, &path2))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000196 return NULL;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000197 BGN_SAVE
198 res = (*func)(path1, path2);
199 END_SAVE
200 if (res < 0)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000201 return posix_error();
202 INCREF(None);
203 return None;
204}
205
206static object *
207posix_strint(args, func)
208 object *args;
209 int (*func) FPROTO((const char *, int));
210{
Guido van Rossumef0a00e1992-01-27 16:51:30 +0000211 char *path;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000212 int i;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000213 int res;
Guido van Rossum234f9421993-06-17 12:35:49 +0000214 if (!getargs(args, "(si)", &path, &i))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000215 return NULL;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000216 BGN_SAVE
217 res = (*func)(path, i);
218 END_SAVE
219 if (res < 0)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000220 return posix_error();
221 INCREF(None);
222 return None;
223}
224
225static object *
Guido van Rossumb6775db1994-08-01 11:34:53 +0000226posix_strintint(args, func)
227 object *args;
228 int (*func) FPROTO((const char *, int, int));
229{
230 char *path;
231 int i,i2;
232 int res;
233 if (!getargs(args, "(sii)", &path, &i, &i2))
234 return NULL;
235 BGN_SAVE
236 res = (*func)(path, i, i2);
237 END_SAVE
238 if (res < 0)
239 return posix_error();
240 INCREF(None);
241 return None;
242}
243
244static object *
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000245posix_do_stat(self, args, statfunc)
246 object *self;
247 object *args;
248 int (*statfunc) FPROTO((const char *, struct stat *));
249{
250 struct stat st;
Guido van Rossumef0a00e1992-01-27 16:51:30 +0000251 char *path;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000252 int res;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +0000253 if (!getargs(args, "s", &path))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000254 return NULL;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000255 BGN_SAVE
256 res = (*statfunc)(path, &st);
257 END_SAVE
258 if (res != 0)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000259 return posix_error();
Guido van Rossum687dd131993-05-17 08:34:16 +0000260 return mkvalue("(llllllllll)",
Guido van Rossume5372401993-03-16 12:15:04 +0000261 (long)st.st_mode,
262 (long)st.st_ino,
263 (long)st.st_dev,
264 (long)st.st_nlink,
265 (long)st.st_uid,
266 (long)st.st_gid,
267 (long)st.st_size,
268 (long)st.st_atime,
269 (long)st.st_mtime,
270 (long)st.st_ctime);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000271}
272
273
274/* POSIX methods */
275
276static object *
277posix_chdir(self, args)
278 object *self;
279 object *args;
280{
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000281 return posix_1str(args, chdir);
282}
283
284static object *
285posix_chmod(self, args)
286 object *self;
287 object *args;
288{
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000289 return posix_strint(args, chmod);
290}
291
Guido van Rossumb6775db1994-08-01 11:34:53 +0000292#ifdef HAVE_CHOWN
293static object *
294posix_chown(self, args)
295 object *self;
296 object *args;
297{
298 return posix_strintint(args, chown);
299}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000300#endif /* HAVE_CHOWN */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000301
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000302static object *
303posix_getcwd(self, args)
304 object *self;
305 object *args;
306{
307 char buf[1026];
Guido van Rossumff4949e1992-08-05 19:58:53 +0000308 char *res;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000309 if (!getnoarg(args))
310 return NULL;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000311 BGN_SAVE
312 res = getcwd(buf, sizeof buf);
313 END_SAVE
314 if (res == NULL)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000315 return posix_error();
316 return newstringobject(buf);
317}
318
Guido van Rossumb6775db1994-08-01 11:34:53 +0000319#ifdef HAVE_LINK
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000320static object *
321posix_link(self, args)
322 object *self;
323 object *args;
324{
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000325 return posix_2str(args, link);
326}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000327#endif /* HAVE_LINK */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000328
Guido van Rossumb6775db1994-08-01 11:34:53 +0000329static object *
330posix_listdir(self, args)
331 object *self;
332 object *args;
333{
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000334#ifdef NT
335
Guido van Rossumb6775db1994-08-01 11:34:53 +0000336 char *name;
337 int len;
338 object *d, *v;
339 HANDLE hFindFile;
340 WIN32_FIND_DATA FileData;
341 char namebuf[MAX_PATH+5];
342
343 if (!getargs(args, "s#", &name, &len))
344 return NULL;
345 if (len >= MAX_PATH) {
346 err_setstr(ValueError, "path too long");
347 return NULL;
348 }
349 strcpy(namebuf, name);
350 if (namebuf[len-1] != '/' && namebuf[len-1] != '\\')
351 namebuf[len++] = '/';
352 strcpy(namebuf + len, "*.*");
353
354 if ((d = newlistobject(0)) == NULL)
355 return NULL;
356
357 hFindFile = FindFirstFile(namebuf, &FileData);
358 if (hFindFile == INVALID_HANDLE_VALUE) {
359 errno = GetLastError();
360 return posix_error();
361 }
362 do {
363 v = newstringobject(FileData.cFileName);
364 if (v == NULL) {
365 DECREF(d);
366 d = NULL;
367 break;
368 }
369 if (addlistitem(d, v) != 0) {
370 DECREF(v);
371 DECREF(d);
372 d = NULL;
373 break;
374 }
375 DECREF(v);
376 } while (FindNextFile(hFindFile, &FileData) == TRUE);
377
378 if (FindClose(hFindFile) == FALSE) {
379 errno = GetLastError();
380 return posix_error();
381 }
382
383 return d;
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000384
385#else /* !NT */
386
Guido van Rossumef0a00e1992-01-27 16:51:30 +0000387 char *name;
388 object *d, *v;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000389 DIR *dirp;
Guido van Rossumb6775db1994-08-01 11:34:53 +0000390 struct dirent *ep;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +0000391 if (!getargs(args, "s", &name))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000392 return NULL;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000393 BGN_SAVE
394 if ((dirp = opendir(name)) == NULL) {
395 RET_SAVE
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000396 return posix_error();
Guido van Rossumff4949e1992-08-05 19:58:53 +0000397 }
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000398 if ((d = newlistobject(0)) == NULL) {
399 closedir(dirp);
Guido van Rossumff4949e1992-08-05 19:58:53 +0000400 RET_SAVE
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000401 return NULL;
402 }
403 while ((ep = readdir(dirp)) != NULL) {
404 v = newstringobject(ep->d_name);
405 if (v == NULL) {
406 DECREF(d);
407 d = NULL;
408 break;
409 }
410 if (addlistitem(d, v) != 0) {
411 DECREF(v);
412 DECREF(d);
413 d = NULL;
414 break;
415 }
416 DECREF(v);
417 }
418 closedir(dirp);
Guido van Rossumff4949e1992-08-05 19:58:53 +0000419 END_SAVE
Guido van Rossum0ee42cd1991-04-08 21:01:03 +0000420
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000421 return d;
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000422
423#endif /* !NT */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000424}
425
426static object *
427posix_mkdir(self, args)
428 object *self;
429 object *args;
430{
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000431 return posix_strint(args, mkdir);
432}
433
Guido van Rossumb6775db1994-08-01 11:34:53 +0000434#ifdef HAVE_NICE
Guido van Rossum775f4da1993-01-09 17:18:52 +0000435static object *
436posix_nice(self, args)
437 object *self;
438 object *args;
439{
440 int increment, value;
441
442 if (!getargs(args, "i", &increment))
443 return NULL;
444 value = nice(increment);
445 if (value == -1)
446 return posix_error();
447 return newintobject((long) value);
448}
Guido van Rossumb6775db1994-08-01 11:34:53 +0000449#endif /* HAVE_NICE */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +0000450
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000451static object *
452posix_rename(self, args)
453 object *self;
454 object *args;
455{
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000456 return posix_2str(args, rename);
457}
458
459static object *
460posix_rmdir(self, args)
461 object *self;
462 object *args;
463{
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000464 return posix_1str(args, rmdir);
465}
466
467static object *
468posix_stat(self, args)
469 object *self;
470 object *args;
471{
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000472 return posix_do_stat(self, args, stat);
473}
474
475static object *
476posix_system(self, args)
477 object *self;
478 object *args;
479{
Guido van Rossumef0a00e1992-01-27 16:51:30 +0000480 char *command;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000481 long sts;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +0000482 if (!getargs(args, "s", &command))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000483 return NULL;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000484 BGN_SAVE
Guido van Rossumef0a00e1992-01-27 16:51:30 +0000485 sts = system(command);
Guido van Rossumff4949e1992-08-05 19:58:53 +0000486 END_SAVE
487 return newintobject(sts);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000488}
489
490static object *
491posix_umask(self, args)
492 object *self;
493 object *args;
494{
495 int i;
496 if (!getintarg(args, &i))
497 return NULL;
498 i = umask(i);
499 if (i < 0)
500 return posix_error();
501 return newintobject((long)i);
502}
503
504static object *
505posix_unlink(self, args)
506 object *self;
507 object *args;
508{
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000509 return posix_1str(args, unlink);
510}
511
Guido van Rossumb6775db1994-08-01 11:34:53 +0000512#ifdef HAVE_UNAME
Guido van Rossumc39de5f1992-02-05 11:15:54 +0000513static object *
514posix_uname(self, args)
515 object *self;
516 object *args;
517{
Guido van Rossumc39de5f1992-02-05 11:15:54 +0000518 struct utsname u;
519 object *v;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000520 int res;
Guido van Rossum50e61dc1992-03-27 17:22:31 +0000521 if (!getnoarg(args))
522 return NULL;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000523 BGN_SAVE
524 res = uname(&u);
525 END_SAVE
526 if (res < 0)
Guido van Rossumc39de5f1992-02-05 11:15:54 +0000527 return posix_error();
Guido van Rossume5372401993-03-16 12:15:04 +0000528 return mkvalue("(sssss)",
529 u.sysname,
530 u.nodename,
531 u.release,
532 u.version,
533 u.machine);
Guido van Rossumc39de5f1992-02-05 11:15:54 +0000534}
Guido van Rossumb6775db1994-08-01 11:34:53 +0000535#endif /* HAVE_UNAME */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +0000536
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000537static object *
Guido van Rossum1ff6cb41991-04-08 20:59:13 +0000538posix_utime(self, args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000539 object *self;
540 object *args;
541{
Guido van Rossumef0a00e1992-01-27 16:51:30 +0000542 char *path;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000543 int res;
Guido van Rossum1ff6cb41991-04-08 20:59:13 +0000544
Guido van Rossumb6775db1994-08-01 11:34:53 +0000545#ifdef HAVE_UTIME_H
Guido van Rossum1ff6cb41991-04-08 20:59:13 +0000546 struct utimbuf buf;
547#define ATIME buf.actime
548#define MTIME buf.modtime
549#define UTIME_ARG &buf
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000550#else /* HAVE_UTIME_H */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +0000551 time_t buf[2];
552#define ATIME buf[0]
553#define MTIME buf[1]
554#define UTIME_ARG buf
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000555#endif /* HAVE_UTIME_H */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +0000556
Guido van Rossumef0a00e1992-01-27 16:51:30 +0000557 if (!getargs(args, "(s(ll))", &path, &ATIME, &MTIME))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000558 return NULL;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000559 BGN_SAVE
560 res = utime(path, UTIME_ARG);
561 END_SAVE
562 if (res < 0)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000563 return posix_error();
564 INCREF(None);
565 return None;
Guido van Rossum1ff6cb41991-04-08 20:59:13 +0000566#undef UTIME_ARG
567#undef ATIME
568#undef MTIME
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000569}
570
Guido van Rossum85e3b011991-06-03 12:42:10 +0000571
Guido van Rossum3b066191991-06-04 19:40:25 +0000572/* Process operations */
Guido van Rossum85e3b011991-06-03 12:42:10 +0000573
574static object *
575posix__exit(self, args)
576 object *self;
577 object *args;
578{
579 int sts;
580 if (!getintarg(args, &sts))
581 return NULL;
582 _exit(sts);
583 /* NOTREACHED */
584}
585
Guido van Rossum85e3b011991-06-03 12:42:10 +0000586static object *
Guido van Rossum89b33251993-10-22 14:26:06 +0000587posix_execv(self, args)
Guido van Rossum85e3b011991-06-03 12:42:10 +0000588 object *self;
589 object *args;
590{
Guido van Rossumef0a00e1992-01-27 16:51:30 +0000591 char *path;
592 object *argv;
Guido van Rossum85e3b011991-06-03 12:42:10 +0000593 char **argvlist;
594 int i, argc;
595 object *(*getitem) PROTO((object *, int));
596
Guido van Rossum89b33251993-10-22 14:26:06 +0000597 /* execv has two arguments: (path, argv), where
Guido van Rossum85e3b011991-06-03 12:42:10 +0000598 argv is a list or tuple of strings. */
599
Guido van Rossumef0a00e1992-01-27 16:51:30 +0000600 if (!getargs(args, "(sO)", &path, &argv))
Guido van Rossum85e3b011991-06-03 12:42:10 +0000601 return NULL;
Guido van Rossum85e3b011991-06-03 12:42:10 +0000602 if (is_listobject(argv)) {
603 argc = getlistsize(argv);
604 getitem = getlistitem;
605 }
606 else if (is_tupleobject(argv)) {
607 argc = gettuplesize(argv);
608 getitem = gettupleitem;
609 }
Guido van Rossumef0a00e1992-01-27 16:51:30 +0000610 else {
611 badarg:
612 err_badarg();
613 return NULL;
614 }
Guido van Rossum85e3b011991-06-03 12:42:10 +0000615
616 argvlist = NEW(char *, argc+1);
617 if (argvlist == NULL)
618 return NULL;
619 for (i = 0; i < argc; i++) {
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +0000620 if (!getargs((*getitem)(argv, i), "s", &argvlist[i])) {
Guido van Rossum85e3b011991-06-03 12:42:10 +0000621 DEL(argvlist);
622 goto badarg;
623 }
Guido van Rossum85e3b011991-06-03 12:42:10 +0000624 }
625 argvlist[argc] = NULL;
626
Guido van Rossumb6775db1994-08-01 11:34:53 +0000627#ifdef BAD_EXEC_PROTOTYPES
628 execv(path, (const char **) argvlist);
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000629#else /* BAD_EXEC_PROTOTYPES */
Guido van Rossumef0a00e1992-01-27 16:51:30 +0000630 execv(path, argvlist);
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000631#endif /* BAD_EXEC_PROTOTYPES */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000632
Guido van Rossum85e3b011991-06-03 12:42:10 +0000633 /* If we get here it's definitely an error */
634
635 DEL(argvlist);
636 return posix_error();
637}
638
639static object *
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +0000640posix_execve(self, args)
641 object *self;
642 object *args;
643{
644 char *path;
645 object *argv, *env;
646 char **argvlist;
647 char **envlist;
648 object *key, *val;
649 int i, pos, argc, envc;
650 object *(*getitem) PROTO((object *, int));
651
652 /* execve has three arguments: (path, argv, env), where
653 argv is a list or tuple of strings and env is a dictionary
654 like posix.environ. */
655
656 if (!getargs(args, "(sOO)", &path, &argv, &env))
657 return NULL;
658 if (is_listobject(argv)) {
659 argc = getlistsize(argv);
660 getitem = getlistitem;
661 }
662 else if (is_tupleobject(argv)) {
663 argc = gettuplesize(argv);
664 getitem = gettupleitem;
665 }
666 else {
667 err_setstr(TypeError, "argv must be tuple or list");
668 return NULL;
669 }
670 if (!is_dictobject(env)) {
671 err_setstr(TypeError, "env must be dictionary");
672 return NULL;
673 }
674
675 argvlist = NEW(char *, argc+1);
676 if (argvlist == NULL) {
677 err_nomem();
678 return NULL;
679 }
680 for (i = 0; i < argc; i++) {
681 if (!getargs((*getitem)(argv, i),
682 "s;argv must be list of strings",
683 &argvlist[i])) {
684 goto fail_1;
685 }
686 }
687 argvlist[argc] = NULL;
688
689 i = getmappingsize(env);
690 envlist = NEW(char *, i + 1);
691 if (envlist == NULL) {
692 err_nomem();
693 goto fail_1;
694 }
695 pos = 0;
696 envc = 0;
697 while (mappinggetnext(env, &pos, &key, &val)) {
698 char *p, *k, *v;
699 if (!getargs(key, "s;non-string key in env", &k) ||
700 !getargs(val, "s;non-string value in env", &v)) {
701 goto fail_2;
702 }
703 p = NEW(char, getstringsize(key) + getstringsize(val) + 2);
704 if (p == NULL) {
705 err_nomem();
706 goto fail_2;
707 }
708 sprintf(p, "%s=%s", k, v);
709 envlist[envc++] = p;
710 }
711 envlist[envc] = 0;
712
Guido van Rossumb6775db1994-08-01 11:34:53 +0000713
714#ifdef BAD_EXEC_PROTOTYPES
715 execve(path, (const char **)argvlist, envlist);
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000716#else /* BAD_EXEC_PROTOTYPES */
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +0000717 execve(path, argvlist, envlist);
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000718#endif /* BAD_EXEC_PROTOTYPES */
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +0000719
720 /* If we get here it's definitely an error */
721
722 (void) posix_error();
723
724 fail_2:
725 while (--envc >= 0)
726 DEL(envlist[envc]);
727 DEL(envlist);
728 fail_1:
729 DEL(argvlist);
730
731 return NULL;
732}
733
Guido van Rossum794d8131994-08-23 13:48:48 +0000734#ifndef NT
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +0000735static object *
Guido van Rossum85e3b011991-06-03 12:42:10 +0000736posix_fork(self, args)
737 object *self;
738 object *args;
739{
740 int pid;
Guido van Rossum50e61dc1992-03-27 17:22:31 +0000741 if (!getnoarg(args))
742 return NULL;
Guido van Rossum85e3b011991-06-03 12:42:10 +0000743 pid = fork();
744 if (pid == -1)
745 return posix_error();
746 return newintobject((long)pid);
747}
748
749static object *
Guido van Rossum46003ff1992-05-15 11:05:24 +0000750posix_getegid(self, args)
751 object *self;
752 object *args;
753{
754 if (!getnoarg(args))
755 return NULL;
756 return newintobject((long)getegid());
757}
758
759static object *
760posix_geteuid(self, args)
761 object *self;
762 object *args;
763{
764 if (!getnoarg(args))
765 return NULL;
766 return newintobject((long)geteuid());
767}
768
769static object *
770posix_getgid(self, args)
771 object *self;
772 object *args;
773{
774 if (!getnoarg(args))
775 return NULL;
776 return newintobject((long)getgid());
777}
Guido van Rossumb078ce11994-08-29 14:01:43 +0000778#endif /* !NT */
Guido van Rossum46003ff1992-05-15 11:05:24 +0000779
780static object *
Guido van Rossum85e3b011991-06-03 12:42:10 +0000781posix_getpid(self, args)
782 object *self;
783 object *args;
784{
Guido van Rossum04814471991-06-04 20:23:49 +0000785 if (!getnoarg(args))
Guido van Rossum85e3b011991-06-03 12:42:10 +0000786 return NULL;
787 return newintobject((long)getpid());
788}
789
Guido van Rossumb6775db1994-08-01 11:34:53 +0000790#ifdef HAVE_GETPGRP
Guido van Rossum85e3b011991-06-03 12:42:10 +0000791static object *
Guido van Rossum04814471991-06-04 20:23:49 +0000792posix_getpgrp(self, args)
793 object *self;
794 object *args;
795{
796 if (!getnoarg(args))
797 return NULL;
Guido van Rossumb6775db1994-08-01 11:34:53 +0000798#ifdef GETPGRP_HAVE_ARG
Guido van Rossum971443b1991-06-07 13:59:29 +0000799 return newintobject((long)getpgrp(0));
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000800#else /* GETPGRP_HAVE_ARG */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000801 return newintobject((long)getpgrp());
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000802#endif /* GETPGRP_HAVE_ARG */
Guido van Rossum04814471991-06-04 20:23:49 +0000803}
Guido van Rossumb6775db1994-08-01 11:34:53 +0000804#endif /* HAVE_GETPGRP */
Guido van Rossum04814471991-06-04 20:23:49 +0000805
Guido van Rossumb6775db1994-08-01 11:34:53 +0000806#ifdef HAVE_SETPGRP
Guido van Rossum04814471991-06-04 20:23:49 +0000807static object *
Guido van Rossumc2670a01992-09-13 20:07:29 +0000808posix_setpgrp(self, args)
809 object *self;
810 object *args;
811{
812 if (!getnoarg(args))
813 return NULL;
Guido van Rossumb6775db1994-08-01 11:34:53 +0000814#ifdef GETPGRP_HAVE_ARG
Guido van Rossumc2670a01992-09-13 20:07:29 +0000815 if (setpgrp(0, 0) < 0)
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000816#else /* GETPGRP_HAVE_ARG */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000817 if (setpgrp() < 0)
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000818#endif /* GETPGRP_HAVE_ARG */
Guido van Rossum687dd131993-05-17 08:34:16 +0000819 return posix_error();
Guido van Rossumc2670a01992-09-13 20:07:29 +0000820 INCREF(None);
821 return None;
822}
823
Guido van Rossumb6775db1994-08-01 11:34:53 +0000824#endif /* HAVE_SETPGRP */
825
Guido van Rossum794d8131994-08-23 13:48:48 +0000826#ifndef NT
Guido van Rossumc2670a01992-09-13 20:07:29 +0000827static object *
Guido van Rossum85e3b011991-06-03 12:42:10 +0000828posix_getppid(self, args)
829 object *self;
830 object *args;
831{
Guido van Rossum04814471991-06-04 20:23:49 +0000832 if (!getnoarg(args))
Guido van Rossum85e3b011991-06-03 12:42:10 +0000833 return NULL;
834 return newintobject((long)getppid());
835}
836
837static object *
Guido van Rossum46003ff1992-05-15 11:05:24 +0000838posix_getuid(self, args)
839 object *self;
840 object *args;
841{
842 if (!getnoarg(args))
843 return NULL;
844 return newintobject((long)getuid());
845}
846
847static object *
Guido van Rossum85e3b011991-06-03 12:42:10 +0000848posix_kill(self, args)
849 object *self;
850 object *args;
851{
852 int pid, sig;
Guido van Rossum234f9421993-06-17 12:35:49 +0000853 if (!getargs(args, "(ii)", &pid, &sig))
Guido van Rossum85e3b011991-06-03 12:42:10 +0000854 return NULL;
855 if (kill(pid, sig) == -1)
856 return posix_error();
857 INCREF(None);
858 return None;
859}
Guido van Rossum794d8131994-08-23 13:48:48 +0000860#endif /* !NT */
Guido van Rossum85e3b011991-06-03 12:42:10 +0000861
862static object *
Guido van Rossum3b066191991-06-04 19:40:25 +0000863posix_popen(self, args)
864 object *self;
865 object *args;
866{
Guido van Rossumef0a00e1992-01-27 16:51:30 +0000867 char *name, *mode;
Guido van Rossum3b066191991-06-04 19:40:25 +0000868 FILE *fp;
Guido van Rossumef0a00e1992-01-27 16:51:30 +0000869 if (!getargs(args, "(ss)", &name, &mode))
Guido van Rossum3b066191991-06-04 19:40:25 +0000870 return NULL;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000871 BGN_SAVE
Guido van Rossumef0a00e1992-01-27 16:51:30 +0000872 fp = popen(name, mode);
Guido van Rossumff4949e1992-08-05 19:58:53 +0000873 END_SAVE
Guido van Rossum3b066191991-06-04 19:40:25 +0000874 if (fp == NULL)
875 return posix_error();
Guido van Rossumef0a00e1992-01-27 16:51:30 +0000876 return newopenfileobject(fp, name, mode, pclose);
Guido van Rossum3b066191991-06-04 19:40:25 +0000877}
878
Guido van Rossumb6775db1994-08-01 11:34:53 +0000879#ifdef HAVE_SETUID
Guido van Rossum3b066191991-06-04 19:40:25 +0000880static object *
Guido van Rossuma3d78fb1993-11-10 09:23:53 +0000881posix_setuid(self, args)
882 object *self;
883 object *args;
884{
885 int uid;
886 if (!getargs(args, "i", &uid))
887 return NULL;
888 if (setuid(uid) < 0)
889 return posix_error();
890 INCREF(None);
891 return None;
892}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000893#endif /* HAVE_SETUID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +0000894
Guido van Rossumb6775db1994-08-01 11:34:53 +0000895#ifdef HAVE_SETGID
Guido van Rossuma3d78fb1993-11-10 09:23:53 +0000896static object *
897posix_setgid(self, args)
898 object *self;
899 object *args;
900{
901 int gid;
902 if (!getargs(args, "i", &gid))
903 return NULL;
904 if (setgid(gid) < 0)
905 return posix_error();
906 INCREF(None);
907 return None;
908}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000909#endif /* HAVE_SETGID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +0000910
Guido van Rossumb6775db1994-08-01 11:34:53 +0000911#ifdef HAVE_WAITPID
Guido van Rossuma3d78fb1993-11-10 09:23:53 +0000912static object *
Guido van Rossum21803b81992-08-09 12:55:27 +0000913posix_waitpid(self, args)
Guido van Rossum85e3b011991-06-03 12:42:10 +0000914 object *self;
915 object *args;
916{
Guido van Rossum21803b81992-08-09 12:55:27 +0000917 int pid, options, sts;
918 if (!getargs(args, "(ii)", &pid, &options))
919 return NULL;
920 BGN_SAVE
921 pid = waitpid(pid, &sts, options);
922 END_SAVE
Guido van Rossum85e3b011991-06-03 12:42:10 +0000923 if (pid == -1)
924 return posix_error();
Guido van Rossum21803b81992-08-09 12:55:27 +0000925 else
926 return mkvalue("ii", pid, sts);
Guido van Rossum21803b81992-08-09 12:55:27 +0000927}
Guido van Rossumb6775db1994-08-01 11:34:53 +0000928#endif /* HAVE_WAITPID */
Guido van Rossum21803b81992-08-09 12:55:27 +0000929
Guido van Rossum794d8131994-08-23 13:48:48 +0000930#ifndef NT
Guido van Rossum21803b81992-08-09 12:55:27 +0000931static object *
932posix_wait(self, args)
933 object *self;
934 object *args;
935{
936 int pid, sts;
Guido van Rossum21803b81992-08-09 12:55:27 +0000937 BGN_SAVE
938 pid = wait(&sts);
939 END_SAVE
940 if (pid == -1)
941 return posix_error();
942 else
943 return mkvalue("ii", pid, sts);
Guido van Rossum85e3b011991-06-03 12:42:10 +0000944}
Guido van Rossum794d8131994-08-23 13:48:48 +0000945#endif /* !NT */
Guido van Rossum85e3b011991-06-03 12:42:10 +0000946
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000947static object *
948posix_lstat(self, args)
949 object *self;
950 object *args;
951{
Guido van Rossumb6775db1994-08-01 11:34:53 +0000952#ifdef HAVE_LSTAT
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000953 return posix_do_stat(self, args, lstat);
Guido van Rossumb6775db1994-08-01 11:34:53 +0000954#else /* !HAVE_LSTAT */
955 return posix_do_stat(self, args, stat);
956#endif /* !HAVE_LSTAT */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000957}
958
Guido van Rossumb6775db1994-08-01 11:34:53 +0000959#ifdef HAVE_READLINK
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000960static object *
961posix_readlink(self, args)
962 object *self;
963 object *args;
964{
Guido van Rossumb6775db1994-08-01 11:34:53 +0000965 char buf[MAXPATHLEN];
Guido van Rossumef0a00e1992-01-27 16:51:30 +0000966 char *path;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000967 int n;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +0000968 if (!getargs(args, "s", &path))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000969 return NULL;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000970 BGN_SAVE
Guido van Rossum50e61dc1992-03-27 17:22:31 +0000971 n = readlink(path, buf, (int) sizeof buf);
Guido van Rossumff4949e1992-08-05 19:58:53 +0000972 END_SAVE
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000973 if (n < 0)
974 return posix_error();
975 return newsizedstringobject(buf, n);
976}
Guido van Rossumb6775db1994-08-01 11:34:53 +0000977#endif /* HAVE_READLINK */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000978
Guido van Rossumb6775db1994-08-01 11:34:53 +0000979#ifdef HAVE_SYMLINK
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000980static object *
981posix_symlink(self, args)
982 object *self;
983 object *args;
984{
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000985 return posix_2str(args, symlink);
986}
Guido van Rossumb6775db1994-08-01 11:34:53 +0000987#endif /* HAVE_SYMLINK */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000988
Guido van Rossumb6775db1994-08-01 11:34:53 +0000989#ifdef HAVE_TIMES
990#ifndef HZ
991#define HZ 60 /* Universal constant :-) */
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000992#endif /* HZ */
Guido van Rossum22db57e1992-04-05 14:25:30 +0000993static object *
994posix_times(self, args)
995 object *self;
996 object *args;
997{
998 struct tms t;
999 clock_t c;
Guido van Rossum22db57e1992-04-05 14:25:30 +00001000 if (!getnoarg(args))
1001 return NULL;
1002 errno = 0;
1003 c = times(&t);
Guido van Rossum687dd131993-05-17 08:34:16 +00001004 if (c == (clock_t) -1)
1005 return posix_error();
Guido van Rossum0b0db8e1993-01-21 16:07:51 +00001006 return mkvalue("dddd",
1007 (double)t.tms_utime / HZ,
1008 (double)t.tms_stime / HZ,
1009 (double)t.tms_cutime / HZ,
1010 (double)t.tms_cstime / HZ);
Guido van Rossum22db57e1992-04-05 14:25:30 +00001011}
Guido van Rossumb6775db1994-08-01 11:34:53 +00001012#endif /* HAVE_TIMES */
Guido van Rossum22db57e1992-04-05 14:25:30 +00001013
Guido van Rossumb6775db1994-08-01 11:34:53 +00001014#ifdef HAVE_SETSID
Guido van Rossumc2670a01992-09-13 20:07:29 +00001015static object *
1016posix_setsid(self, args)
1017 object *self;
1018 object *args;
1019{
1020 if (!getnoarg(args))
1021 return NULL;
Guido van Rossum687dd131993-05-17 08:34:16 +00001022 if (setsid() < 0)
1023 return posix_error();
Guido van Rossumc2670a01992-09-13 20:07:29 +00001024 INCREF(None);
1025 return None;
1026}
Guido van Rossumb6775db1994-08-01 11:34:53 +00001027#endif /* HAVE_SETSID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00001028
Guido van Rossumb6775db1994-08-01 11:34:53 +00001029#ifdef HAVE_SETPGID
Guido van Rossumc2670a01992-09-13 20:07:29 +00001030static object *
1031posix_setpgid(self, args)
1032 object *self;
1033 object *args;
1034{
1035 int pid, pgrp;
1036 if (!getargs(args, "(ii)", &pid, &pgrp))
1037 return NULL;
Guido van Rossum687dd131993-05-17 08:34:16 +00001038 if (setpgid(pid, pgrp) < 0)
1039 return posix_error();
Guido van Rossumc2670a01992-09-13 20:07:29 +00001040 INCREF(None);
1041 return None;
1042}
Guido van Rossumb6775db1994-08-01 11:34:53 +00001043#endif /* HAVE_SETPGID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00001044
Guido van Rossumb6775db1994-08-01 11:34:53 +00001045#ifdef HAVE_TCGETPGRP
Guido van Rossum7066dd71992-09-17 17:54:56 +00001046static object *
1047posix_tcgetpgrp(self, args)
1048 object *self;
1049 object *args;
1050{
1051 int fd, pgid;
1052 if (!getargs(args, "i", &fd))
1053 return NULL;
1054 pgid = tcgetpgrp(fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00001055 if (pgid < 0)
1056 return posix_error();
Guido van Rossum7066dd71992-09-17 17:54:56 +00001057 return newintobject((long)pgid);
1058}
Guido van Rossumb6775db1994-08-01 11:34:53 +00001059#endif /* HAVE_TCGETPGRP */
Guido van Rossum7066dd71992-09-17 17:54:56 +00001060
Guido van Rossumb6775db1994-08-01 11:34:53 +00001061#ifdef HAVE_TCSETPGRP
Guido van Rossum7066dd71992-09-17 17:54:56 +00001062static object *
1063posix_tcsetpgrp(self, args)
1064 object *self;
1065 object *args;
1066{
1067 int fd, pgid;
1068 if (!getargs(args, "(ii)", &fd, &pgid))
1069 return NULL;
Guido van Rossum687dd131993-05-17 08:34:16 +00001070 if (tcsetpgrp(fd, pgid) < 0)
1071 return posix_error();
Guido van Rossum7066dd71992-09-17 17:54:56 +00001072 INCREF(None);
1073 return None;
1074}
Guido van Rossumb6775db1994-08-01 11:34:53 +00001075#endif /* HAVE_TCSETPGRP */
Guido van Rossum22db57e1992-04-05 14:25:30 +00001076
Guido van Rossum687dd131993-05-17 08:34:16 +00001077/* Functions acting on file descriptors */
1078
Guido van Rossum234f9421993-06-17 12:35:49 +00001079static object *
Guido van Rossum687dd131993-05-17 08:34:16 +00001080posix_open(self, args)
1081 object *self;
1082 object *args;
1083{
1084 char *file;
1085 int flag;
1086 int mode = 0777;
1087 int fd;
1088 if (!getargs(args, "(si)", &file, &flag)) {
1089 err_clear();
1090 if (!getargs(args, "(sii)", &file, &flag, &mode))
1091 return NULL;
1092 }
1093 BGN_SAVE
1094 fd = open(file, flag, mode);
1095 END_SAVE
1096 if (fd < 0)
1097 return posix_error();
1098 return newintobject((long)fd);
1099}
1100
Guido van Rossum234f9421993-06-17 12:35:49 +00001101static object *
Guido van Rossum687dd131993-05-17 08:34:16 +00001102posix_close(self, args)
1103 object *self;
1104 object *args;
1105{
1106 int fd, res;
1107 if (!getargs(args, "i", &fd))
1108 return NULL;
1109 BGN_SAVE
1110 res = close(fd);
1111 END_SAVE
1112 if (res < 0)
1113 return posix_error();
1114 INCREF(None);
1115 return None;
1116}
1117
Guido van Rossum234f9421993-06-17 12:35:49 +00001118static object *
Guido van Rossum687dd131993-05-17 08:34:16 +00001119posix_dup(self, args)
1120 object *self;
1121 object *args;
1122{
1123 int fd;
1124 if (!getargs(args, "i", &fd))
1125 return NULL;
1126 BGN_SAVE
1127 fd = dup(fd);
1128 END_SAVE
1129 if (fd < 0)
1130 return posix_error();
1131 return newintobject((long)fd);
1132}
1133
Guido van Rossum234f9421993-06-17 12:35:49 +00001134static object *
Guido van Rossum687dd131993-05-17 08:34:16 +00001135posix_dup2(self, args)
1136 object *self;
1137 object *args;
1138{
1139 int fd, fd2, res;
1140 if (!getargs(args, "(ii)", &fd, &fd2))
1141 return NULL;
1142 BGN_SAVE
1143 res = dup2(fd, fd2);
1144 END_SAVE
1145 if (res < 0)
1146 return posix_error();
1147 INCREF(None);
1148 return None;
1149}
1150
Guido van Rossum234f9421993-06-17 12:35:49 +00001151static object *
Guido van Rossum687dd131993-05-17 08:34:16 +00001152posix_lseek(self, args)
1153 object *self;
1154 object *args;
1155{
1156 int fd, how;
1157 long pos, res;
1158 if (!getargs(args, "(ili)", &fd, &pos, &how))
1159 return NULL;
1160#ifdef SEEK_SET
1161 /* Turn 0, 1, 2 into SEEK_{SET,CUR,END} */
1162 switch (how) {
1163 case 0: how = SEEK_SET; break;
1164 case 1: how = SEEK_CUR; break;
1165 case 2: how = SEEK_END; break;
1166 }
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001167#endif /* SEEK_END */
Guido van Rossum687dd131993-05-17 08:34:16 +00001168 BGN_SAVE
1169 res = lseek(fd, pos, how);
1170 END_SAVE
1171 if (res < 0)
1172 return posix_error();
1173 return newintobject(res);
1174}
1175
Guido van Rossum234f9421993-06-17 12:35:49 +00001176static object *
Guido van Rossum687dd131993-05-17 08:34:16 +00001177posix_read(self, args)
1178 object *self;
1179 object *args;
1180{
1181 int fd, size;
1182 object *buffer;
1183 if (!getargs(args, "(ii)", &fd, &size))
1184 return NULL;
1185 buffer = newsizedstringobject((char *)NULL, size);
1186 if (buffer == NULL)
1187 return NULL;
1188 BGN_SAVE
1189 size = read(fd, getstringvalue(buffer), size);
1190 END_SAVE
1191 if (size < 0) {
1192 DECREF(buffer);
1193 return posix_error();
1194 }
1195 resizestring(&buffer, size);
1196 return buffer;
1197}
1198
Guido van Rossum234f9421993-06-17 12:35:49 +00001199static object *
Guido van Rossum687dd131993-05-17 08:34:16 +00001200posix_write(self, args)
1201 object *self;
1202 object *args;
1203{
1204 int fd, size;
1205 char *buffer;
1206 if (!getargs(args, "(is#)", &fd, &buffer, &size))
1207 return NULL;
1208 BGN_SAVE
1209 size = write(fd, buffer, size);
1210 END_SAVE
1211 if (size < 0)
1212 return posix_error();
1213 return newintobject((long)size);
1214}
1215
Guido van Rossum234f9421993-06-17 12:35:49 +00001216static object *
Guido van Rossum687dd131993-05-17 08:34:16 +00001217posix_fstat(self, args)
1218 object *self;
1219 object *args;
1220{
1221 int fd;
1222 struct stat st;
1223 int res;
1224 if (!getargs(args, "i", &fd))
1225 return NULL;
1226 BGN_SAVE
1227 res = fstat(fd, &st);
1228 END_SAVE
1229 if (res != 0)
1230 return posix_error();
1231 return mkvalue("(llllllllll)",
1232 (long)st.st_mode,
1233 (long)st.st_ino,
1234 (long)st.st_dev,
1235 (long)st.st_nlink,
1236 (long)st.st_uid,
1237 (long)st.st_gid,
1238 (long)st.st_size,
1239 (long)st.st_atime,
1240 (long)st.st_mtime,
1241 (long)st.st_ctime);
1242}
1243
1244static object *
1245posix_fdopen(self, args)
1246 object *self;
1247 object *args;
1248{
1249 extern int fclose PROTO((FILE *));
1250 int fd;
1251 char *mode;
1252 FILE *fp;
1253 if (!getargs(args, "(is)", &fd, &mode))
1254 return NULL;
1255 BGN_SAVE
1256 fp = fdopen(fd, mode);
1257 END_SAVE
1258 if (fp == NULL)
1259 return posix_error();
1260 /* From now on, ignore SIGPIPE and let the error checking
1261 do the work. */
Guido van Rossum687dd131993-05-17 08:34:16 +00001262 return newopenfileobject(fp, "(fdopen)", mode, fclose);
1263}
1264
Guido van Rossum234f9421993-06-17 12:35:49 +00001265static object *
Guido van Rossum687dd131993-05-17 08:34:16 +00001266posix_pipe(self, args)
1267 object *self;
1268 object *args;
1269{
Guido van Rossum794d8131994-08-23 13:48:48 +00001270#ifndef NT
Guido van Rossum687dd131993-05-17 08:34:16 +00001271 int fds[2];
1272 int res;
1273 if (!getargs(args, ""))
1274 return NULL;
1275 BGN_SAVE
1276 res = pipe(fds);
1277 END_SAVE
1278 if (res != 0)
1279 return posix_error();
1280 return mkvalue("(ii)", fds[0], fds[1]);
Guido van Rossum794d8131994-08-23 13:48:48 +00001281#else /* NT */
1282 HANDLE read, write;
1283 BOOL ok;
1284 if (!getargs(args, ""))
1285 return NULL;
1286 BGN_SAVE
1287 ok = CreatePipe( &read, &write, NULL, 0);
1288 END_SAVE
1289 if (!ok)
1290 return posix_error();
1291 return mkvalue("(ii)", read, write);
1292#endif /* NT */
Guido van Rossum687dd131993-05-17 08:34:16 +00001293}
Guido van Rossum22db57e1992-04-05 14:25:30 +00001294
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001295static struct methodlist posix_methods[] = {
1296 {"chdir", posix_chdir},
1297 {"chmod", posix_chmod},
Guido van Rossumb6775db1994-08-01 11:34:53 +00001298#ifdef HAVE_CHOWN
1299 {"chown", posix_chown},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001300#endif /* HAVE_CHOWN */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001301 {"getcwd", posix_getcwd},
Guido van Rossumb6775db1994-08-01 11:34:53 +00001302#ifdef HAVE_LINK
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001303 {"link", posix_link},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001304#endif /* HAVE_LINK */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001305 {"listdir", posix_listdir},
Guido van Rossumc39de5f1992-02-05 11:15:54 +00001306 {"lstat", posix_lstat},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001307 {"mkdir", posix_mkdir},
Guido van Rossumb6775db1994-08-01 11:34:53 +00001308#ifdef HAVE_NICE
Guido van Rossum775f4da1993-01-09 17:18:52 +00001309 {"nice", posix_nice},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001310#endif /* HAVE_NICE */
Guido van Rossumb6775db1994-08-01 11:34:53 +00001311#ifdef HAVE_READLINK
Guido van Rossumc39de5f1992-02-05 11:15:54 +00001312 {"readlink", posix_readlink},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001313#endif /* HAVE_READLINK */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001314 {"rename", posix_rename},
1315 {"rmdir", posix_rmdir},
1316 {"stat", posix_stat},
Guido van Rossumb6775db1994-08-01 11:34:53 +00001317#ifdef HAVE_SYMLINK
Guido van Rossumc39de5f1992-02-05 11:15:54 +00001318 {"symlink", posix_symlink},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001319#endif /* HAVE_SYMLINK */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001320 {"system", posix_system},
1321 {"umask", posix_umask},
Guido van Rossumb6775db1994-08-01 11:34:53 +00001322#ifdef HAVE_UNAME
Guido van Rossumc39de5f1992-02-05 11:15:54 +00001323 {"uname", posix_uname},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001324#endif /* HAVE_UNAME */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001325 {"unlink", posix_unlink},
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00001326 {"utime", posix_utime},
Guido van Rossumb6775db1994-08-01 11:34:53 +00001327#ifdef HAVE_TIMES
Guido van Rossum22db57e1992-04-05 14:25:30 +00001328 {"times", posix_times},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001329#endif /* HAVE_TIMES */
Guido van Rossum85e3b011991-06-03 12:42:10 +00001330 {"_exit", posix__exit},
Guido van Rossum89b33251993-10-22 14:26:06 +00001331 {"execv", posix_execv},
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001332 {"execve", posix_execve},
Guido van Rossumb6775db1994-08-01 11:34:53 +00001333#ifndef NT
Guido van Rossum85e3b011991-06-03 12:42:10 +00001334 {"fork", posix_fork},
Guido van Rossum46003ff1992-05-15 11:05:24 +00001335 {"getegid", posix_getegid},
1336 {"geteuid", posix_geteuid},
1337 {"getgid", posix_getgid},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001338#endif /* !NT */
Guido van Rossum85e3b011991-06-03 12:42:10 +00001339 {"getpid", posix_getpid},
Guido van Rossumb6775db1994-08-01 11:34:53 +00001340#ifdef HAVE_GETPGRP
Guido van Rossum04814471991-06-04 20:23:49 +00001341 {"getpgrp", posix_getpgrp},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001342#endif /* HAVE_GETPGRP */
Guido van Rossumb6775db1994-08-01 11:34:53 +00001343#ifndef NT
Guido van Rossum85e3b011991-06-03 12:42:10 +00001344 {"getppid", posix_getppid},
Guido van Rossum46003ff1992-05-15 11:05:24 +00001345 {"getuid", posix_getuid},
Guido van Rossum85e3b011991-06-03 12:42:10 +00001346 {"kill", posix_kill},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001347#endif /* !NT */
Guido van Rossum3b066191991-06-04 19:40:25 +00001348 {"popen", posix_popen},
Guido van Rossumb6775db1994-08-01 11:34:53 +00001349#ifdef HAVE_SETUID
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00001350 {"setuid", posix_setuid},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001351#endif /* HAVE_SETUID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00001352#ifdef HAVE_SETGID
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00001353 {"setgid", posix_setgid},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001354#endif /* HAVE_SETGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00001355#ifdef HAVE_SETPGRP
Guido van Rossumc2670a01992-09-13 20:07:29 +00001356 {"setpgrp", posix_setpgrp},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001357#endif /* HAVE_SETPGRP */
Guido van Rossumb6775db1994-08-01 11:34:53 +00001358#ifndef NT
Guido van Rossum85e3b011991-06-03 12:42:10 +00001359 {"wait", posix_wait},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001360#endif /* !NT */
Guido van Rossumb6775db1994-08-01 11:34:53 +00001361#ifdef HAVE_WAITPID
Guido van Rossum21803b81992-08-09 12:55:27 +00001362 {"waitpid", posix_waitpid},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001363#endif /* HAVE_WAITPID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00001364#ifdef HAVE_SETSID
Guido van Rossumc2670a01992-09-13 20:07:29 +00001365 {"setsid", posix_setsid},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001366#endif /* HAVE_SETSID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00001367#ifdef HAVE_SETPGID
Guido van Rossumc2670a01992-09-13 20:07:29 +00001368 {"setpgid", posix_setpgid},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001369#endif /* HAVE_SETPGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00001370#ifdef HAVE_TCGETPGRP
Guido van Rossum7066dd71992-09-17 17:54:56 +00001371 {"tcgetpgrp", posix_tcgetpgrp},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001372#endif /* HAVE_TCGETPGRP */
Guido van Rossumb6775db1994-08-01 11:34:53 +00001373#ifdef HAVE_TCSETPGRP
Guido van Rossum7066dd71992-09-17 17:54:56 +00001374 {"tcsetpgrp", posix_tcsetpgrp},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001375#endif /* HAVE_TCSETPGRP */
Guido van Rossum687dd131993-05-17 08:34:16 +00001376 {"open", posix_open},
1377 {"close", posix_close},
1378 {"dup", posix_dup},
1379 {"dup2", posix_dup2},
1380 {"lseek", posix_lseek},
1381 {"read", posix_read},
1382 {"write", posix_write},
1383 {"fstat", posix_fstat},
1384 {"fdopen", posix_fdopen},
Guido van Rossum687dd131993-05-17 08:34:16 +00001385 {"pipe", posix_pipe},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001386 {NULL, NULL} /* Sentinel */
1387};
1388
1389
Guido van Rossumb6775db1994-08-01 11:34:53 +00001390#ifdef NT
1391void
1392initnt()
1393{
1394 object *m, *d, *v;
1395
1396 m = initmodule("nt", posix_methods);
1397 d = getmoduledict(m);
1398
1399 /* Initialize nt.environ dictionary */
1400 v = convertenviron();
1401 if (v == NULL || dictinsert(d, "environ", v) != 0)
1402 fatal("can't define nt.environ");
1403 DECREF(v);
1404
1405 /* Initialize nt.error exception */
1406 PosixError = newstringobject("nt.error");
1407 if (PosixError == NULL || dictinsert(d, "error", PosixError) != 0)
1408 fatal("can't define nt.error");
1409}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001410#else /* !NT */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001411void
1412initposix()
1413{
1414 object *m, *d, *v;
1415
1416 m = initmodule("posix", posix_methods);
1417 d = getmoduledict(m);
1418
1419 /* Initialize posix.environ dictionary */
1420 v = convertenviron();
1421 if (v == NULL || dictinsert(d, "environ", v) != 0)
1422 fatal("can't define posix.environ");
1423 DECREF(v);
1424
1425 /* Initialize posix.error exception */
1426 PosixError = newstringobject("posix.error");
1427 if (PosixError == NULL || dictinsert(d, "error", PosixError) != 0)
1428 fatal("can't define posix.error");
1429}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001430#endif /* !NT */