blob: a0f34e5aa1d7b472fc670ff692c953c7639834bd [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 Rossumb6775db1994-08-01 11:34:53 +000027#ifdef _M_IX86
28#define NT
29/* NT may be defined externally as well. If it is defined, the module is
30 actually called 'nt', not 'posix', and some functions don't exist. */
Guido van Rossum50e61dc1992-03-27 17:22:31 +000031#endif
32
Guido van Rossum3f5da241990-12-20 15:06:42 +000033#include "allobjects.h"
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000034#include "modsupport.h"
Guido van Rossumff4949e1992-08-05 19:58:53 +000035#include "ceval.h"
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000036
Guido van Rossumb6775db1994-08-01 11:34:53 +000037#include <string.h>
38#include <errno.h>
39
40#ifndef macintosh
41#include <sys/types.h>
42#include <sys/stat.h>
43#endif
44
45#include "mytime.h" /* For clock_t on some systems */
46
47#ifdef HAVE_FCNTL_H
48#include <fcntl.h>
49#endif
50
51#ifdef HAVE_UNISTD_H
Guido van Rossum0b0db8e1993-01-21 16:07:51 +000052#include <unistd.h>
Guido van Rossumb6775db1994-08-01 11:34:53 +000053#else /* !HAVE_UNISTD_H */
54
55#ifdef macintosh
56#include "macdefs.h"
57#else
Guido van Rossuma2b7f401993-01-04 09:09:59 +000058extern int mkdir PROTO((const char *, mode_t));
59extern int chdir PROTO((const char *));
Guido van Rossume22e6441993-07-09 10:51:31 +000060extern int rmdir PROTO((const char *));
61extern int chmod PROTO((const char *, mode_t));
Guido van Rossumb6775db1994-08-01 11:34:53 +000062extern int chown PROTO((const char *, uid_t, gid_t));
63extern char *getcwd PROTO((char *, int));
Guido van Rossume22e6441993-07-09 10:51:31 +000064extern char *strerror PROTO((int));
Guido van Rossuma2b7f401993-01-04 09:09:59 +000065extern int link PROTO((const char *, const char *));
66extern int rename PROTO((const char *, const char *));
Guido van Rossuma2b7f401993-01-04 09:09:59 +000067extern int stat PROTO((const char *, struct stat *));
68extern int unlink PROTO((const char *));
69extern int pclose PROTO((FILE *));
Guido van Rossumb6775db1994-08-01 11:34:53 +000070#ifdef HAVE_SYMLINK
Guido van Rossuma2b7f401993-01-04 09:09:59 +000071extern int symlink PROTO((const char *, const char *));
72#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +000073#ifdef HAVE_LSTAT
74extern int lstat PROTO((const char *, struct stat *));
75#endif
76#endif /* macintosh */
77#endif /* !HAVE_UNISTD_H */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000078
Guido van Rossumb6775db1994-08-01 11:34:53 +000079#if 1
80/* XXX These are for SunOS4.1.3 but shouldn't hurt elsewhere */
81extern int rename();
82extern int pclose();
83extern int lstat();
84extern int symlink();
85#endif
86
87#ifdef HAVE_UTIME_H
88#include <utime.h>
89#endif
90
91#ifdef HAVE_SYS_TIMES_H
92#include <sys/times.h>
93#endif
94
95#ifdef HAVE_SYS_PARAM_H
96#include <sys/param.h>
97#endif
98
99#ifdef HAVE_SYS_UTSNAME_H
100#include <sys/utsname.h>
101#endif
102
103#ifndef MAXPATHLEN
104#define MAXPATHLEN 1024
105#endif
106
107/* unistd.h defines _POSIX_VERSION on POSIX.1 systems. */
108#if defined(DIRENT) || defined(_POSIX_VERSION)
109#include <dirent.h>
110#define NLENGTH(dirent) (strlen((dirent)->d_name))
111#else /* not (DIRENT or _POSIX_VERSION) */
112#define dirent direct
113#define NLENGTH(dirent) ((dirent)->d_namlen)
114#ifdef SYSNDIR
115#include <sys/ndir.h>
116#endif /* SYSNDIR */
117#ifdef SYSDIR
118#include <sys/dir.h>
119#endif /* SYSDIR */
120#ifdef NDIR
121#include <ndir.h>
122#endif /* NDIR */
123#endif /* not (DIRENT or _POSIX_VERSION) */
124
125#ifdef NT
126#include <direct.h>
127#include <io.h>
128#include <process.h>
129#include <windows.h>
130#define popen _popen
131#endif /* NT */
132
133#ifdef OS2
134#include <io.h>
135#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000136
137/* Return a dictionary corresponding to the POSIX environment table */
138
139extern char **environ;
140
141static object *
142convertenviron()
143{
144 object *d;
145 char **e;
146 d = newdictobject();
147 if (d == NULL)
148 return NULL;
149 if (environ == NULL)
150 return d;
151 /* XXX This part ignores errors */
152 for (e = environ; *e != NULL; e++) {
153 object *v;
154 char *p = strchr(*e, '=');
155 if (p == NULL)
156 continue;
157 v = newstringobject(p+1);
158 if (v == NULL)
159 continue;
160 *p = '\0';
161 (void) dictinsert(d, *e, v);
162 *p = '=';
163 DECREF(v);
164 }
165 return d;
166}
167
168
169static object *PosixError; /* Exception posix.error */
170
171/* Set a POSIX-specific error from errno, and return NULL */
172
Guido van Rossum687dd131993-05-17 08:34:16 +0000173static object * posix_error() { return err_errno(PosixError);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000174}
175
176
177/* POSIX generic methods */
178
179static object *
180posix_1str(args, func)
181 object *args;
182 int (*func) FPROTO((const char *));
183{
Guido van Rossumef0a00e1992-01-27 16:51:30 +0000184 char *path1;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000185 int res;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +0000186 if (!getargs(args, "s", &path1))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000187 return NULL;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000188 BGN_SAVE
189 res = (*func)(path1);
190 END_SAVE
191 if (res < 0)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000192 return posix_error();
193 INCREF(None);
194 return None;
195}
196
197static object *
198posix_2str(args, func)
199 object *args;
200 int (*func) FPROTO((const char *, const char *));
201{
Guido van Rossumef0a00e1992-01-27 16:51:30 +0000202 char *path1, *path2;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000203 int res;
Guido van Rossum234f9421993-06-17 12:35:49 +0000204 if (!getargs(args, "(ss)", &path1, &path2))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000205 return NULL;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000206 BGN_SAVE
207 res = (*func)(path1, path2);
208 END_SAVE
209 if (res < 0)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000210 return posix_error();
211 INCREF(None);
212 return None;
213}
214
215static object *
216posix_strint(args, func)
217 object *args;
218 int (*func) FPROTO((const char *, int));
219{
Guido van Rossumef0a00e1992-01-27 16:51:30 +0000220 char *path;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000221 int i;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000222 int res;
Guido van Rossum234f9421993-06-17 12:35:49 +0000223 if (!getargs(args, "(si)", &path, &i))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000224 return NULL;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000225 BGN_SAVE
226 res = (*func)(path, i);
227 END_SAVE
228 if (res < 0)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000229 return posix_error();
230 INCREF(None);
231 return None;
232}
233
234static object *
Guido van Rossumb6775db1994-08-01 11:34:53 +0000235posix_strintint(args, func)
236 object *args;
237 int (*func) FPROTO((const char *, int, int));
238{
239 char *path;
240 int i,i2;
241 int res;
242 if (!getargs(args, "(sii)", &path, &i, &i2))
243 return NULL;
244 BGN_SAVE
245 res = (*func)(path, i, i2);
246 END_SAVE
247 if (res < 0)
248 return posix_error();
249 INCREF(None);
250 return None;
251}
252
253static object *
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000254posix_do_stat(self, args, statfunc)
255 object *self;
256 object *args;
257 int (*statfunc) FPROTO((const char *, struct stat *));
258{
259 struct stat st;
Guido van Rossumef0a00e1992-01-27 16:51:30 +0000260 char *path;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000261 int res;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +0000262 if (!getargs(args, "s", &path))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000263 return NULL;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000264 BGN_SAVE
265 res = (*statfunc)(path, &st);
266 END_SAVE
267 if (res != 0)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000268 return posix_error();
Guido van Rossum687dd131993-05-17 08:34:16 +0000269 return mkvalue("(llllllllll)",
Guido van Rossume5372401993-03-16 12:15:04 +0000270 (long)st.st_mode,
271 (long)st.st_ino,
272 (long)st.st_dev,
273 (long)st.st_nlink,
274 (long)st.st_uid,
275 (long)st.st_gid,
276 (long)st.st_size,
277 (long)st.st_atime,
278 (long)st.st_mtime,
279 (long)st.st_ctime);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000280}
281
282
283/* POSIX methods */
284
285static object *
286posix_chdir(self, args)
287 object *self;
288 object *args;
289{
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000290 return posix_1str(args, chdir);
291}
292
293static object *
294posix_chmod(self, args)
295 object *self;
296 object *args;
297{
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000298 return posix_strint(args, chmod);
299}
300
Guido van Rossumb6775db1994-08-01 11:34:53 +0000301#ifdef HAVE_CHOWN
302static object *
303posix_chown(self, args)
304 object *self;
305 object *args;
306{
307 return posix_strintint(args, chown);
308}
309#endif
310
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000311static object *
312posix_getcwd(self, args)
313 object *self;
314 object *args;
315{
316 char buf[1026];
Guido van Rossumff4949e1992-08-05 19:58:53 +0000317 char *res;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000318 if (!getnoarg(args))
319 return NULL;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000320 BGN_SAVE
321 res = getcwd(buf, sizeof buf);
322 END_SAVE
323 if (res == NULL)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000324 return posix_error();
325 return newstringobject(buf);
326}
327
Guido van Rossumb6775db1994-08-01 11:34:53 +0000328#ifdef HAVE_LINK
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000329static object *
330posix_link(self, args)
331 object *self;
332 object *args;
333{
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000334 return posix_2str(args, link);
335}
Guido van Rossumb6775db1994-08-01 11:34:53 +0000336#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000337
Guido van Rossumb6775db1994-08-01 11:34:53 +0000338#ifdef NT
339static object *
340posix_listdir(self, args)
341 object *self;
342 object *args;
343{
344 char *name;
345 int len;
346 object *d, *v;
347 HANDLE hFindFile;
348 WIN32_FIND_DATA FileData;
349 char namebuf[MAX_PATH+5];
350
351 if (!getargs(args, "s#", &name, &len))
352 return NULL;
353 if (len >= MAX_PATH) {
354 err_setstr(ValueError, "path too long");
355 return NULL;
356 }
357 strcpy(namebuf, name);
358 if (namebuf[len-1] != '/' && namebuf[len-1] != '\\')
359 namebuf[len++] = '/';
360 strcpy(namebuf + len, "*.*");
361
362 if ((d = newlistobject(0)) == NULL)
363 return NULL;
364
365 hFindFile = FindFirstFile(namebuf, &FileData);
366 if (hFindFile == INVALID_HANDLE_VALUE) {
367 errno = GetLastError();
368 return posix_error();
369 }
370 do {
371 v = newstringobject(FileData.cFileName);
372 if (v == NULL) {
373 DECREF(d);
374 d = NULL;
375 break;
376 }
377 if (addlistitem(d, v) != 0) {
378 DECREF(v);
379 DECREF(d);
380 d = NULL;
381 break;
382 }
383 DECREF(v);
384 } while (FindNextFile(hFindFile, &FileData) == TRUE);
385
386 if (FindClose(hFindFile) == FALSE) {
387 errno = GetLastError();
388 return posix_error();
389 }
390
391 return d;
392}
393#else /* ! NT */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000394static object *
395posix_listdir(self, args)
396 object *self;
397 object *args;
398{
Guido van Rossumef0a00e1992-01-27 16:51:30 +0000399 char *name;
400 object *d, *v;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000401 DIR *dirp;
Guido van Rossumb6775db1994-08-01 11:34:53 +0000402 struct dirent *ep;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +0000403 if (!getargs(args, "s", &name))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000404 return NULL;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000405 BGN_SAVE
406 if ((dirp = opendir(name)) == NULL) {
407 RET_SAVE
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000408 return posix_error();
Guido van Rossumff4949e1992-08-05 19:58:53 +0000409 }
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000410 if ((d = newlistobject(0)) == NULL) {
411 closedir(dirp);
Guido van Rossumff4949e1992-08-05 19:58:53 +0000412 RET_SAVE
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000413 return NULL;
414 }
415 while ((ep = readdir(dirp)) != NULL) {
416 v = newstringobject(ep->d_name);
417 if (v == NULL) {
418 DECREF(d);
419 d = NULL;
420 break;
421 }
422 if (addlistitem(d, v) != 0) {
423 DECREF(v);
424 DECREF(d);
425 d = NULL;
426 break;
427 }
428 DECREF(v);
429 }
430 closedir(dirp);
Guido van Rossumff4949e1992-08-05 19:58:53 +0000431 END_SAVE
Guido van Rossum0ee42cd1991-04-08 21:01:03 +0000432
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000433 return d;
434}
Guido van Rossumb6775db1994-08-01 11:34:53 +0000435#endif /* ! NT */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000436
437static object *
438posix_mkdir(self, args)
439 object *self;
440 object *args;
441{
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000442 return posix_strint(args, mkdir);
443}
444
Guido van Rossumb6775db1994-08-01 11:34:53 +0000445#ifdef HAVE_NICE
Guido van Rossum775f4da1993-01-09 17:18:52 +0000446static object *
447posix_nice(self, args)
448 object *self;
449 object *args;
450{
451 int increment, value;
452
453 if (!getargs(args, "i", &increment))
454 return NULL;
455 value = nice(increment);
456 if (value == -1)
457 return posix_error();
458 return newintobject((long) value);
459}
Guido van Rossumb6775db1994-08-01 11:34:53 +0000460#endif /* HAVE_NICE */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +0000461
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000462static object *
463posix_rename(self, args)
464 object *self;
465 object *args;
466{
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000467 return posix_2str(args, rename);
468}
469
470static object *
471posix_rmdir(self, args)
472 object *self;
473 object *args;
474{
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000475 return posix_1str(args, rmdir);
476}
477
478static object *
479posix_stat(self, args)
480 object *self;
481 object *args;
482{
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000483 return posix_do_stat(self, args, stat);
484}
485
486static object *
487posix_system(self, args)
488 object *self;
489 object *args;
490{
Guido van Rossumef0a00e1992-01-27 16:51:30 +0000491 char *command;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000492 long sts;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +0000493 if (!getargs(args, "s", &command))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000494 return NULL;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000495 BGN_SAVE
Guido van Rossumef0a00e1992-01-27 16:51:30 +0000496 sts = system(command);
Guido van Rossumff4949e1992-08-05 19:58:53 +0000497 END_SAVE
498 return newintobject(sts);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000499}
500
501static object *
502posix_umask(self, args)
503 object *self;
504 object *args;
505{
506 int i;
507 if (!getintarg(args, &i))
508 return NULL;
509 i = umask(i);
510 if (i < 0)
511 return posix_error();
512 return newintobject((long)i);
513}
514
515static object *
516posix_unlink(self, args)
517 object *self;
518 object *args;
519{
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000520 return posix_1str(args, unlink);
521}
522
Guido van Rossumb6775db1994-08-01 11:34:53 +0000523#ifdef HAVE_UNAME
Guido van Rossumc39de5f1992-02-05 11:15:54 +0000524static object *
525posix_uname(self, args)
526 object *self;
527 object *args;
528{
Guido van Rossumc39de5f1992-02-05 11:15:54 +0000529 struct utsname u;
530 object *v;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000531 int res;
Guido van Rossum50e61dc1992-03-27 17:22:31 +0000532 if (!getnoarg(args))
533 return NULL;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000534 BGN_SAVE
535 res = uname(&u);
536 END_SAVE
537 if (res < 0)
Guido van Rossumc39de5f1992-02-05 11:15:54 +0000538 return posix_error();
Guido van Rossume5372401993-03-16 12:15:04 +0000539 return mkvalue("(sssss)",
540 u.sysname,
541 u.nodename,
542 u.release,
543 u.version,
544 u.machine);
Guido van Rossumc39de5f1992-02-05 11:15:54 +0000545}
Guido van Rossumb6775db1994-08-01 11:34:53 +0000546#endif /* HAVE_UNAME */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +0000547
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000548static object *
Guido van Rossum1ff6cb41991-04-08 20:59:13 +0000549posix_utime(self, args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000550 object *self;
551 object *args;
552{
Guido van Rossumef0a00e1992-01-27 16:51:30 +0000553 char *path;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000554 int res;
Guido van Rossum1ff6cb41991-04-08 20:59:13 +0000555
Guido van Rossumb6775db1994-08-01 11:34:53 +0000556#ifdef HAVE_UTIME_H
Guido van Rossum1ff6cb41991-04-08 20:59:13 +0000557 struct utimbuf buf;
558#define ATIME buf.actime
559#define MTIME buf.modtime
560#define UTIME_ARG &buf
Guido van Rossum1ff6cb41991-04-08 20:59:13 +0000561#else
562 time_t buf[2];
563#define ATIME buf[0]
564#define MTIME buf[1]
565#define UTIME_ARG buf
566#endif
567
Guido van Rossumef0a00e1992-01-27 16:51:30 +0000568 if (!getargs(args, "(s(ll))", &path, &ATIME, &MTIME))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000569 return NULL;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000570 BGN_SAVE
571 res = utime(path, UTIME_ARG);
572 END_SAVE
573 if (res < 0)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000574 return posix_error();
575 INCREF(None);
576 return None;
Guido van Rossum1ff6cb41991-04-08 20:59:13 +0000577#undef UTIME_ARG
578#undef ATIME
579#undef MTIME
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000580}
581
Guido van Rossum85e3b011991-06-03 12:42:10 +0000582
Guido van Rossum3b066191991-06-04 19:40:25 +0000583/* Process operations */
Guido van Rossum85e3b011991-06-03 12:42:10 +0000584
585static object *
586posix__exit(self, args)
587 object *self;
588 object *args;
589{
590 int sts;
591 if (!getintarg(args, &sts))
592 return NULL;
593 _exit(sts);
594 /* NOTREACHED */
595}
596
Guido van Rossum85e3b011991-06-03 12:42:10 +0000597static object *
Guido van Rossum89b33251993-10-22 14:26:06 +0000598posix_execv(self, args)
Guido van Rossum85e3b011991-06-03 12:42:10 +0000599 object *self;
600 object *args;
601{
Guido van Rossumef0a00e1992-01-27 16:51:30 +0000602 char *path;
603 object *argv;
Guido van Rossum85e3b011991-06-03 12:42:10 +0000604 char **argvlist;
605 int i, argc;
606 object *(*getitem) PROTO((object *, int));
607
Guido van Rossum89b33251993-10-22 14:26:06 +0000608 /* execv has two arguments: (path, argv), where
Guido van Rossum85e3b011991-06-03 12:42:10 +0000609 argv is a list or tuple of strings. */
610
Guido van Rossumef0a00e1992-01-27 16:51:30 +0000611 if (!getargs(args, "(sO)", &path, &argv))
Guido van Rossum85e3b011991-06-03 12:42:10 +0000612 return NULL;
Guido van Rossum85e3b011991-06-03 12:42:10 +0000613 if (is_listobject(argv)) {
614 argc = getlistsize(argv);
615 getitem = getlistitem;
616 }
617 else if (is_tupleobject(argv)) {
618 argc = gettuplesize(argv);
619 getitem = gettupleitem;
620 }
Guido van Rossumef0a00e1992-01-27 16:51:30 +0000621 else {
622 badarg:
623 err_badarg();
624 return NULL;
625 }
Guido van Rossum85e3b011991-06-03 12:42:10 +0000626
627 argvlist = NEW(char *, argc+1);
628 if (argvlist == NULL)
629 return NULL;
630 for (i = 0; i < argc; i++) {
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +0000631 if (!getargs((*getitem)(argv, i), "s", &argvlist[i])) {
Guido van Rossum85e3b011991-06-03 12:42:10 +0000632 DEL(argvlist);
633 goto badarg;
634 }
Guido van Rossum85e3b011991-06-03 12:42:10 +0000635 }
636 argvlist[argc] = NULL;
637
Guido van Rossumb6775db1994-08-01 11:34:53 +0000638#ifdef BAD_EXEC_PROTOTYPES
639 execv(path, (const char **) argvlist);
640#else
Guido van Rossumef0a00e1992-01-27 16:51:30 +0000641 execv(path, argvlist);
Guido van Rossumb6775db1994-08-01 11:34:53 +0000642#endif
643
Guido van Rossum85e3b011991-06-03 12:42:10 +0000644 /* If we get here it's definitely an error */
645
646 DEL(argvlist);
647 return posix_error();
648}
649
650static object *
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +0000651posix_execve(self, args)
652 object *self;
653 object *args;
654{
655 char *path;
656 object *argv, *env;
657 char **argvlist;
658 char **envlist;
659 object *key, *val;
660 int i, pos, argc, envc;
661 object *(*getitem) PROTO((object *, int));
662
663 /* execve has three arguments: (path, argv, env), where
664 argv is a list or tuple of strings and env is a dictionary
665 like posix.environ. */
666
667 if (!getargs(args, "(sOO)", &path, &argv, &env))
668 return NULL;
669 if (is_listobject(argv)) {
670 argc = getlistsize(argv);
671 getitem = getlistitem;
672 }
673 else if (is_tupleobject(argv)) {
674 argc = gettuplesize(argv);
675 getitem = gettupleitem;
676 }
677 else {
678 err_setstr(TypeError, "argv must be tuple or list");
679 return NULL;
680 }
681 if (!is_dictobject(env)) {
682 err_setstr(TypeError, "env must be dictionary");
683 return NULL;
684 }
685
686 argvlist = NEW(char *, argc+1);
687 if (argvlist == NULL) {
688 err_nomem();
689 return NULL;
690 }
691 for (i = 0; i < argc; i++) {
692 if (!getargs((*getitem)(argv, i),
693 "s;argv must be list of strings",
694 &argvlist[i])) {
695 goto fail_1;
696 }
697 }
698 argvlist[argc] = NULL;
699
700 i = getmappingsize(env);
701 envlist = NEW(char *, i + 1);
702 if (envlist == NULL) {
703 err_nomem();
704 goto fail_1;
705 }
706 pos = 0;
707 envc = 0;
708 while (mappinggetnext(env, &pos, &key, &val)) {
709 char *p, *k, *v;
710 if (!getargs(key, "s;non-string key in env", &k) ||
711 !getargs(val, "s;non-string value in env", &v)) {
712 goto fail_2;
713 }
714 p = NEW(char, getstringsize(key) + getstringsize(val) + 2);
715 if (p == NULL) {
716 err_nomem();
717 goto fail_2;
718 }
719 sprintf(p, "%s=%s", k, v);
720 envlist[envc++] = p;
721 }
722 envlist[envc] = 0;
723
Guido van Rossumb6775db1994-08-01 11:34:53 +0000724
725#ifdef BAD_EXEC_PROTOTYPES
726 execve(path, (const char **)argvlist, envlist);
727#else
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +0000728 execve(path, argvlist, envlist);
Guido van Rossumb6775db1994-08-01 11:34:53 +0000729#endif
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +0000730
731 /* If we get here it's definitely an error */
732
733 (void) posix_error();
734
735 fail_2:
736 while (--envc >= 0)
737 DEL(envlist[envc]);
738 DEL(envlist);
739 fail_1:
740 DEL(argvlist);
741
742 return NULL;
743}
744
745static object *
Guido van Rossum85e3b011991-06-03 12:42:10 +0000746posix_fork(self, args)
747 object *self;
748 object *args;
749{
750 int pid;
Guido van Rossum50e61dc1992-03-27 17:22:31 +0000751 if (!getnoarg(args))
752 return NULL;
Guido van Rossum85e3b011991-06-03 12:42:10 +0000753 pid = fork();
754 if (pid == -1)
755 return posix_error();
756 return newintobject((long)pid);
757}
758
759static object *
Guido van Rossum46003ff1992-05-15 11:05:24 +0000760posix_getegid(self, args)
761 object *self;
762 object *args;
763{
764 if (!getnoarg(args))
765 return NULL;
766 return newintobject((long)getegid());
767}
768
769static object *
770posix_geteuid(self, args)
771 object *self;
772 object *args;
773{
774 if (!getnoarg(args))
775 return NULL;
776 return newintobject((long)geteuid());
777}
778
779static object *
780posix_getgid(self, args)
781 object *self;
782 object *args;
783{
784 if (!getnoarg(args))
785 return NULL;
786 return newintobject((long)getgid());
787}
788
789static object *
Guido van Rossum85e3b011991-06-03 12:42:10 +0000790posix_getpid(self, args)
791 object *self;
792 object *args;
793{
Guido van Rossum04814471991-06-04 20:23:49 +0000794 if (!getnoarg(args))
Guido van Rossum85e3b011991-06-03 12:42:10 +0000795 return NULL;
796 return newintobject((long)getpid());
797}
798
Guido van Rossumb6775db1994-08-01 11:34:53 +0000799#ifdef HAVE_GETPGRP
Guido van Rossum85e3b011991-06-03 12:42:10 +0000800static object *
Guido van Rossum04814471991-06-04 20:23:49 +0000801posix_getpgrp(self, args)
802 object *self;
803 object *args;
804{
805 if (!getnoarg(args))
806 return NULL;
Guido van Rossumb6775db1994-08-01 11:34:53 +0000807#ifdef GETPGRP_HAVE_ARG
Guido van Rossum971443b1991-06-07 13:59:29 +0000808 return newintobject((long)getpgrp(0));
Guido van Rossumb6775db1994-08-01 11:34:53 +0000809#else
810 return newintobject((long)getpgrp());
Guido van Rossum50e61dc1992-03-27 17:22:31 +0000811#endif
Guido van Rossum04814471991-06-04 20:23:49 +0000812}
Guido van Rossumb6775db1994-08-01 11:34:53 +0000813#endif /* HAVE_GETPGRP */
Guido van Rossum04814471991-06-04 20:23:49 +0000814
Guido van Rossumb6775db1994-08-01 11:34:53 +0000815#ifdef HAVE_SETPGRP
Guido van Rossum04814471991-06-04 20:23:49 +0000816static object *
Guido van Rossumc2670a01992-09-13 20:07:29 +0000817posix_setpgrp(self, args)
818 object *self;
819 object *args;
820{
821 if (!getnoarg(args))
822 return NULL;
Guido van Rossumb6775db1994-08-01 11:34:53 +0000823#ifdef GETPGRP_HAVE_ARG
Guido van Rossumc2670a01992-09-13 20:07:29 +0000824 if (setpgrp(0, 0) < 0)
Guido van Rossumb6775db1994-08-01 11:34:53 +0000825#else
826 if (setpgrp() < 0)
Guido van Rossumc2670a01992-09-13 20:07:29 +0000827#endif
Guido van Rossum687dd131993-05-17 08:34:16 +0000828 return posix_error();
Guido van Rossumc2670a01992-09-13 20:07:29 +0000829 INCREF(None);
830 return None;
831}
832
Guido van Rossumb6775db1994-08-01 11:34:53 +0000833#endif /* HAVE_SETPGRP */
834
Guido van Rossumc2670a01992-09-13 20:07:29 +0000835static object *
Guido van Rossum85e3b011991-06-03 12:42:10 +0000836posix_getppid(self, args)
837 object *self;
838 object *args;
839{
Guido van Rossum04814471991-06-04 20:23:49 +0000840 if (!getnoarg(args))
Guido van Rossum85e3b011991-06-03 12:42:10 +0000841 return NULL;
842 return newintobject((long)getppid());
843}
844
845static object *
Guido van Rossum46003ff1992-05-15 11:05:24 +0000846posix_getuid(self, args)
847 object *self;
848 object *args;
849{
850 if (!getnoarg(args))
851 return NULL;
852 return newintobject((long)getuid());
853}
854
855static object *
Guido van Rossum85e3b011991-06-03 12:42:10 +0000856posix_kill(self, args)
857 object *self;
858 object *args;
859{
860 int pid, sig;
Guido van Rossum234f9421993-06-17 12:35:49 +0000861 if (!getargs(args, "(ii)", &pid, &sig))
Guido van Rossum85e3b011991-06-03 12:42:10 +0000862 return NULL;
863 if (kill(pid, sig) == -1)
864 return posix_error();
865 INCREF(None);
866 return None;
867}
868
869static object *
Guido van Rossum3b066191991-06-04 19:40:25 +0000870posix_popen(self, args)
871 object *self;
872 object *args;
873{
Guido van Rossumef0a00e1992-01-27 16:51:30 +0000874 char *name, *mode;
Guido van Rossum3b066191991-06-04 19:40:25 +0000875 FILE *fp;
Guido van Rossumef0a00e1992-01-27 16:51:30 +0000876 if (!getargs(args, "(ss)", &name, &mode))
Guido van Rossum3b066191991-06-04 19:40:25 +0000877 return NULL;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000878 BGN_SAVE
Guido van Rossumef0a00e1992-01-27 16:51:30 +0000879 fp = popen(name, mode);
Guido van Rossumff4949e1992-08-05 19:58:53 +0000880 END_SAVE
Guido van Rossum3b066191991-06-04 19:40:25 +0000881 if (fp == NULL)
882 return posix_error();
Guido van Rossumef0a00e1992-01-27 16:51:30 +0000883 return newopenfileobject(fp, name, mode, pclose);
Guido van Rossum3b066191991-06-04 19:40:25 +0000884}
885
Guido van Rossumb6775db1994-08-01 11:34:53 +0000886#ifdef HAVE_SETUID
Guido van Rossum3b066191991-06-04 19:40:25 +0000887static object *
Guido van Rossuma3d78fb1993-11-10 09:23:53 +0000888posix_setuid(self, args)
889 object *self;
890 object *args;
891{
892 int uid;
893 if (!getargs(args, "i", &uid))
894 return NULL;
895 if (setuid(uid) < 0)
896 return posix_error();
897 INCREF(None);
898 return None;
899}
Guido van Rossumb6775db1994-08-01 11:34:53 +0000900#endif
Guido van Rossuma3d78fb1993-11-10 09:23:53 +0000901
Guido van Rossumb6775db1994-08-01 11:34:53 +0000902#ifdef HAVE_SETGID
Guido van Rossuma3d78fb1993-11-10 09:23:53 +0000903static object *
904posix_setgid(self, args)
905 object *self;
906 object *args;
907{
908 int gid;
909 if (!getargs(args, "i", &gid))
910 return NULL;
911 if (setgid(gid) < 0)
912 return posix_error();
913 INCREF(None);
914 return None;
915}
Guido van Rossumb6775db1994-08-01 11:34:53 +0000916#endif
Guido van Rossuma3d78fb1993-11-10 09:23:53 +0000917
Guido van Rossumb6775db1994-08-01 11:34:53 +0000918#ifdef HAVE_WAITPID
Guido van Rossuma3d78fb1993-11-10 09:23:53 +0000919static object *
Guido van Rossum21803b81992-08-09 12:55:27 +0000920posix_waitpid(self, args)
Guido van Rossum85e3b011991-06-03 12:42:10 +0000921 object *self;
922 object *args;
923{
Guido van Rossum21803b81992-08-09 12:55:27 +0000924 int pid, options, sts;
925 if (!getargs(args, "(ii)", &pid, &options))
926 return NULL;
927 BGN_SAVE
928 pid = waitpid(pid, &sts, options);
929 END_SAVE
Guido van Rossum85e3b011991-06-03 12:42:10 +0000930 if (pid == -1)
931 return posix_error();
Guido van Rossum21803b81992-08-09 12:55:27 +0000932 else
933 return mkvalue("ii", pid, sts);
Guido van Rossum21803b81992-08-09 12:55:27 +0000934}
Guido van Rossumb6775db1994-08-01 11:34:53 +0000935#endif /* HAVE_WAITPID */
Guido van Rossum21803b81992-08-09 12:55:27 +0000936
937static object *
938posix_wait(self, args)
939 object *self;
940 object *args;
941{
942 int pid, sts;
Guido van Rossum21803b81992-08-09 12:55:27 +0000943 BGN_SAVE
944 pid = wait(&sts);
945 END_SAVE
946 if (pid == -1)
947 return posix_error();
948 else
949 return mkvalue("ii", pid, sts);
Guido van Rossum85e3b011991-06-03 12:42:10 +0000950}
951
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 :-) */
997#endif
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 Rossum22db57e1992-04-05 14:25:30 +00001018
Guido van Rossumb6775db1994-08-01 11:34:53 +00001019#ifdef HAVE_SETSID
Guido van Rossumc2670a01992-09-13 20:07:29 +00001020static object *
1021posix_setsid(self, args)
1022 object *self;
1023 object *args;
1024{
1025 if (!getnoarg(args))
1026 return NULL;
Guido van Rossum687dd131993-05-17 08:34:16 +00001027 if (setsid() < 0)
1028 return posix_error();
Guido van Rossumc2670a01992-09-13 20:07:29 +00001029 INCREF(None);
1030 return None;
1031}
Guido van Rossumb6775db1994-08-01 11:34:53 +00001032#endif /* HAVE_SETSID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00001033
Guido van Rossumb6775db1994-08-01 11:34:53 +00001034#ifdef HAVE_SETPGID
Guido van Rossumc2670a01992-09-13 20:07:29 +00001035static object *
1036posix_setpgid(self, args)
1037 object *self;
1038 object *args;
1039{
1040 int pid, pgrp;
1041 if (!getargs(args, "(ii)", &pid, &pgrp))
1042 return NULL;
Guido van Rossum687dd131993-05-17 08:34:16 +00001043 if (setpgid(pid, pgrp) < 0)
1044 return posix_error();
Guido van Rossumc2670a01992-09-13 20:07:29 +00001045 INCREF(None);
1046 return None;
1047}
Guido van Rossumb6775db1994-08-01 11:34:53 +00001048#endif /* HAVE_SETPGID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00001049
Guido van Rossumb6775db1994-08-01 11:34:53 +00001050#ifdef HAVE_TCGETPGRP
Guido van Rossum7066dd71992-09-17 17:54:56 +00001051static object *
1052posix_tcgetpgrp(self, args)
1053 object *self;
1054 object *args;
1055{
1056 int fd, pgid;
1057 if (!getargs(args, "i", &fd))
1058 return NULL;
1059 pgid = tcgetpgrp(fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00001060 if (pgid < 0)
1061 return posix_error();
Guido van Rossum7066dd71992-09-17 17:54:56 +00001062 return newintobject((long)pgid);
1063}
Guido van Rossumb6775db1994-08-01 11:34:53 +00001064#endif /* HAVE_TCGETPGRP */
Guido van Rossum7066dd71992-09-17 17:54:56 +00001065
Guido van Rossumb6775db1994-08-01 11:34:53 +00001066#ifdef HAVE_TCSETPGRP
Guido van Rossum7066dd71992-09-17 17:54:56 +00001067static object *
1068posix_tcsetpgrp(self, args)
1069 object *self;
1070 object *args;
1071{
1072 int fd, pgid;
1073 if (!getargs(args, "(ii)", &fd, &pgid))
1074 return NULL;
Guido van Rossum687dd131993-05-17 08:34:16 +00001075 if (tcsetpgrp(fd, pgid) < 0)
1076 return posix_error();
Guido van Rossum7066dd71992-09-17 17:54:56 +00001077 INCREF(None);
1078 return None;
1079}
Guido van Rossumb6775db1994-08-01 11:34:53 +00001080#endif /* HAVE_TCSETPGRP */
Guido van Rossum22db57e1992-04-05 14:25:30 +00001081
Guido van Rossum687dd131993-05-17 08:34:16 +00001082/* Functions acting on file descriptors */
1083
Guido van Rossum234f9421993-06-17 12:35:49 +00001084static object *
Guido van Rossum687dd131993-05-17 08:34:16 +00001085posix_open(self, args)
1086 object *self;
1087 object *args;
1088{
1089 char *file;
1090 int flag;
1091 int mode = 0777;
1092 int fd;
1093 if (!getargs(args, "(si)", &file, &flag)) {
1094 err_clear();
1095 if (!getargs(args, "(sii)", &file, &flag, &mode))
1096 return NULL;
1097 }
1098 BGN_SAVE
1099 fd = open(file, flag, mode);
1100 END_SAVE
1101 if (fd < 0)
1102 return posix_error();
1103 return newintobject((long)fd);
1104}
1105
Guido van Rossum234f9421993-06-17 12:35:49 +00001106static object *
Guido van Rossum687dd131993-05-17 08:34:16 +00001107posix_close(self, args)
1108 object *self;
1109 object *args;
1110{
1111 int fd, res;
1112 if (!getargs(args, "i", &fd))
1113 return NULL;
1114 BGN_SAVE
1115 res = close(fd);
1116 END_SAVE
1117 if (res < 0)
1118 return posix_error();
1119 INCREF(None);
1120 return None;
1121}
1122
Guido van Rossum234f9421993-06-17 12:35:49 +00001123static object *
Guido van Rossum687dd131993-05-17 08:34:16 +00001124posix_dup(self, args)
1125 object *self;
1126 object *args;
1127{
1128 int fd;
1129 if (!getargs(args, "i", &fd))
1130 return NULL;
1131 BGN_SAVE
1132 fd = dup(fd);
1133 END_SAVE
1134 if (fd < 0)
1135 return posix_error();
1136 return newintobject((long)fd);
1137}
1138
Guido van Rossum234f9421993-06-17 12:35:49 +00001139static object *
Guido van Rossum687dd131993-05-17 08:34:16 +00001140posix_dup2(self, args)
1141 object *self;
1142 object *args;
1143{
1144 int fd, fd2, res;
1145 if (!getargs(args, "(ii)", &fd, &fd2))
1146 return NULL;
1147 BGN_SAVE
1148 res = dup2(fd, fd2);
1149 END_SAVE
1150 if (res < 0)
1151 return posix_error();
1152 INCREF(None);
1153 return None;
1154}
1155
Guido van Rossum234f9421993-06-17 12:35:49 +00001156static object *
Guido van Rossum687dd131993-05-17 08:34:16 +00001157posix_lseek(self, args)
1158 object *self;
1159 object *args;
1160{
1161 int fd, how;
1162 long pos, res;
1163 if (!getargs(args, "(ili)", &fd, &pos, &how))
1164 return NULL;
1165#ifdef SEEK_SET
1166 /* Turn 0, 1, 2 into SEEK_{SET,CUR,END} */
1167 switch (how) {
1168 case 0: how = SEEK_SET; break;
1169 case 1: how = SEEK_CUR; break;
1170 case 2: how = SEEK_END; break;
1171 }
1172#endif
1173 BGN_SAVE
1174 res = lseek(fd, pos, how);
1175 END_SAVE
1176 if (res < 0)
1177 return posix_error();
1178 return newintobject(res);
1179}
1180
Guido van Rossum234f9421993-06-17 12:35:49 +00001181static object *
Guido van Rossum687dd131993-05-17 08:34:16 +00001182posix_read(self, args)
1183 object *self;
1184 object *args;
1185{
1186 int fd, size;
1187 object *buffer;
1188 if (!getargs(args, "(ii)", &fd, &size))
1189 return NULL;
1190 buffer = newsizedstringobject((char *)NULL, size);
1191 if (buffer == NULL)
1192 return NULL;
1193 BGN_SAVE
1194 size = read(fd, getstringvalue(buffer), size);
1195 END_SAVE
1196 if (size < 0) {
1197 DECREF(buffer);
1198 return posix_error();
1199 }
1200 resizestring(&buffer, size);
1201 return buffer;
1202}
1203
Guido van Rossum234f9421993-06-17 12:35:49 +00001204static object *
Guido van Rossum687dd131993-05-17 08:34:16 +00001205posix_write(self, args)
1206 object *self;
1207 object *args;
1208{
1209 int fd, size;
1210 char *buffer;
1211 if (!getargs(args, "(is#)", &fd, &buffer, &size))
1212 return NULL;
1213 BGN_SAVE
1214 size = write(fd, buffer, size);
1215 END_SAVE
1216 if (size < 0)
1217 return posix_error();
1218 return newintobject((long)size);
1219}
1220
Guido van Rossum234f9421993-06-17 12:35:49 +00001221static object *
Guido van Rossum687dd131993-05-17 08:34:16 +00001222posix_fstat(self, args)
1223 object *self;
1224 object *args;
1225{
1226 int fd;
1227 struct stat st;
1228 int res;
1229 if (!getargs(args, "i", &fd))
1230 return NULL;
1231 BGN_SAVE
1232 res = fstat(fd, &st);
1233 END_SAVE
1234 if (res != 0)
1235 return posix_error();
1236 return mkvalue("(llllllllll)",
1237 (long)st.st_mode,
1238 (long)st.st_ino,
1239 (long)st.st_dev,
1240 (long)st.st_nlink,
1241 (long)st.st_uid,
1242 (long)st.st_gid,
1243 (long)st.st_size,
1244 (long)st.st_atime,
1245 (long)st.st_mtime,
1246 (long)st.st_ctime);
1247}
1248
1249static object *
1250posix_fdopen(self, args)
1251 object *self;
1252 object *args;
1253{
1254 extern int fclose PROTO((FILE *));
1255 int fd;
1256 char *mode;
1257 FILE *fp;
1258 if (!getargs(args, "(is)", &fd, &mode))
1259 return NULL;
1260 BGN_SAVE
1261 fp = fdopen(fd, mode);
1262 END_SAVE
1263 if (fp == NULL)
1264 return posix_error();
1265 /* From now on, ignore SIGPIPE and let the error checking
1266 do the work. */
Guido van Rossum687dd131993-05-17 08:34:16 +00001267 return newopenfileobject(fp, "(fdopen)", mode, fclose);
1268}
1269
Guido van Rossum234f9421993-06-17 12:35:49 +00001270static object *
Guido van Rossum687dd131993-05-17 08:34:16 +00001271posix_pipe(self, args)
1272 object *self;
1273 object *args;
1274{
1275 int fds[2];
1276 int res;
1277 if (!getargs(args, ""))
1278 return NULL;
1279 BGN_SAVE
1280 res = pipe(fds);
1281 END_SAVE
1282 if (res != 0)
1283 return posix_error();
1284 return mkvalue("(ii)", fds[0], fds[1]);
1285}
Guido van Rossum22db57e1992-04-05 14:25:30 +00001286
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001287static struct methodlist posix_methods[] = {
1288 {"chdir", posix_chdir},
1289 {"chmod", posix_chmod},
Guido van Rossumb6775db1994-08-01 11:34:53 +00001290#ifdef HAVE_CHOWN
1291 {"chown", posix_chown},
1292#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001293 {"getcwd", posix_getcwd},
Guido van Rossumb6775db1994-08-01 11:34:53 +00001294#ifdef HAVE_LINK
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001295 {"link", posix_link},
Guido van Rossumb6775db1994-08-01 11:34:53 +00001296#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001297 {"listdir", posix_listdir},
Guido van Rossumc39de5f1992-02-05 11:15:54 +00001298 {"lstat", posix_lstat},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001299 {"mkdir", posix_mkdir},
Guido van Rossumb6775db1994-08-01 11:34:53 +00001300#ifdef HAVE_NICE
Guido van Rossum775f4da1993-01-09 17:18:52 +00001301 {"nice", posix_nice},
Guido van Rossumb6775db1994-08-01 11:34:53 +00001302#endif
1303#ifdef HAVE_READLINK
Guido van Rossumc39de5f1992-02-05 11:15:54 +00001304 {"readlink", posix_readlink},
Guido van Rossumb6775db1994-08-01 11:34:53 +00001305#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001306 {"rename", posix_rename},
1307 {"rmdir", posix_rmdir},
1308 {"stat", posix_stat},
Guido van Rossumb6775db1994-08-01 11:34:53 +00001309#ifdef HAVE_SYMLINK
Guido van Rossumc39de5f1992-02-05 11:15:54 +00001310 {"symlink", posix_symlink},
Guido van Rossumb6775db1994-08-01 11:34:53 +00001311#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001312 {"system", posix_system},
1313 {"umask", posix_umask},
Guido van Rossumb6775db1994-08-01 11:34:53 +00001314#ifdef HAVE_UNAME
Guido van Rossumc39de5f1992-02-05 11:15:54 +00001315 {"uname", posix_uname},
1316#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001317 {"unlink", posix_unlink},
Guido van Rossumb6775db1994-08-01 11:34:53 +00001318#ifndef NT
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00001319 {"utime", posix_utime},
Guido van Rossumb6775db1994-08-01 11:34:53 +00001320#endif /* ! NT */
1321#ifdef HAVE_TIMES
Guido van Rossum22db57e1992-04-05 14:25:30 +00001322 {"times", posix_times},
1323#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00001324 {"_exit", posix__exit},
Guido van Rossum89b33251993-10-22 14:26:06 +00001325 {"execv", posix_execv},
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001326 {"execve", posix_execve},
Guido van Rossumb6775db1994-08-01 11:34:53 +00001327#ifndef NT
Guido van Rossum85e3b011991-06-03 12:42:10 +00001328 {"fork", posix_fork},
Guido van Rossum46003ff1992-05-15 11:05:24 +00001329 {"getegid", posix_getegid},
1330 {"geteuid", posix_geteuid},
1331 {"getgid", posix_getgid},
Guido van Rossumb6775db1994-08-01 11:34:53 +00001332#endif /* ! NT */
Guido van Rossum85e3b011991-06-03 12:42:10 +00001333 {"getpid", posix_getpid},
Guido van Rossumb6775db1994-08-01 11:34:53 +00001334#ifdef HAVE_GETPGRP
Guido van Rossum04814471991-06-04 20:23:49 +00001335 {"getpgrp", posix_getpgrp},
Guido van Rossumb6775db1994-08-01 11:34:53 +00001336#endif
1337#ifndef NT
Guido van Rossum85e3b011991-06-03 12:42:10 +00001338 {"getppid", posix_getppid},
Guido van Rossum46003ff1992-05-15 11:05:24 +00001339 {"getuid", posix_getuid},
Guido van Rossum85e3b011991-06-03 12:42:10 +00001340 {"kill", posix_kill},
Guido van Rossumb6775db1994-08-01 11:34:53 +00001341#endif /* ! NT */
Guido van Rossum3b066191991-06-04 19:40:25 +00001342 {"popen", posix_popen},
Guido van Rossumb6775db1994-08-01 11:34:53 +00001343#ifdef HAVE_SETUID
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00001344 {"setuid", posix_setuid},
Guido van Rossumb6775db1994-08-01 11:34:53 +00001345#endif
1346#ifdef HAVE_SETGID
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00001347 {"setgid", posix_setgid},
Guido van Rossumb6775db1994-08-01 11:34:53 +00001348#endif
1349#ifdef HAVE_SETPGRP
Guido van Rossumc2670a01992-09-13 20:07:29 +00001350 {"setpgrp", posix_setpgrp},
Guido van Rossumb6775db1994-08-01 11:34:53 +00001351#endif
1352#ifndef NT
Guido van Rossum85e3b011991-06-03 12:42:10 +00001353 {"wait", posix_wait},
Guido van Rossumb6775db1994-08-01 11:34:53 +00001354#endif /* ! NT */
1355#ifdef HAVE_WAITPID
Guido van Rossum21803b81992-08-09 12:55:27 +00001356 {"waitpid", posix_waitpid},
Guido van Rossumb6775db1994-08-01 11:34:53 +00001357#endif
1358#ifdef HAVE_SETSID
Guido van Rossumc2670a01992-09-13 20:07:29 +00001359 {"setsid", posix_setsid},
Guido van Rossumb6775db1994-08-01 11:34:53 +00001360#endif
1361#ifdef HAVE_SETPGID
Guido van Rossumc2670a01992-09-13 20:07:29 +00001362 {"setpgid", posix_setpgid},
Guido van Rossumb6775db1994-08-01 11:34:53 +00001363#endif
1364#ifdef HAVE_TCGETPGRP
Guido van Rossum7066dd71992-09-17 17:54:56 +00001365 {"tcgetpgrp", posix_tcgetpgrp},
Guido van Rossumb6775db1994-08-01 11:34:53 +00001366#endif
1367#ifdef HAVE_TCSETPGRP
Guido van Rossum7066dd71992-09-17 17:54:56 +00001368 {"tcsetpgrp", posix_tcsetpgrp},
Guido van Rossumc2670a01992-09-13 20:07:29 +00001369#endif
Guido van Rossum687dd131993-05-17 08:34:16 +00001370 {"open", posix_open},
1371 {"close", posix_close},
1372 {"dup", posix_dup},
1373 {"dup2", posix_dup2},
1374 {"lseek", posix_lseek},
1375 {"read", posix_read},
1376 {"write", posix_write},
1377 {"fstat", posix_fstat},
1378 {"fdopen", posix_fdopen},
Guido van Rossumb6775db1994-08-01 11:34:53 +00001379#ifndef NT
Guido van Rossum687dd131993-05-17 08:34:16 +00001380 {"pipe", posix_pipe},
Guido van Rossumb6775db1994-08-01 11:34:53 +00001381#endif /* ! NT */
Guido van Rossum687dd131993-05-17 08:34:16 +00001382
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001383 {NULL, NULL} /* Sentinel */
1384};
1385
1386
Guido van Rossumb6775db1994-08-01 11:34:53 +00001387#ifdef NT
1388void
1389initnt()
1390{
1391 object *m, *d, *v;
1392
1393 m = initmodule("nt", posix_methods);
1394 d = getmoduledict(m);
1395
1396 /* Initialize nt.environ dictionary */
1397 v = convertenviron();
1398 if (v == NULL || dictinsert(d, "environ", v) != 0)
1399 fatal("can't define nt.environ");
1400 DECREF(v);
1401
1402 /* Initialize nt.error exception */
1403 PosixError = newstringobject("nt.error");
1404 if (PosixError == NULL || dictinsert(d, "error", PosixError) != 0)
1405 fatal("can't define nt.error");
1406}
1407#else /* ! NT */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001408void
1409initposix()
1410{
1411 object *m, *d, *v;
1412
1413 m = initmodule("posix", posix_methods);
1414 d = getmoduledict(m);
1415
1416 /* Initialize posix.environ dictionary */
1417 v = convertenviron();
1418 if (v == NULL || dictinsert(d, "environ", v) != 0)
1419 fatal("can't define posix.environ");
1420 DECREF(v);
1421
1422 /* Initialize posix.error exception */
1423 PosixError = newstringobject("posix.error");
1424 if (PosixError == NULL || dictinsert(d, "error", PosixError) != 0)
1425 fatal("can't define posix.error");
1426}
Guido van Rossumb6775db1994-08-01 11:34:53 +00001427#endif /* ! NT */