posixmodule.c revision b37a3734960b0d4c06665e41b0451b6f814f1cb6
1/*********************************************************** 2Copyright (c) 2000, BeOpen.com. 3Copyright (c) 1995-2000, Corporation for National Research Initiatives. 4Copyright (c) 1990-1995, Stichting Mathematisch Centrum. 5All rights reserved. 6 7See the file "Misc/COPYRIGHT" for information on usage and 8redistribution of this file, and for a DISCLAIMER OF ALL WARRANTIES. 9******************************************************************/ 10 11/* POSIX module implementation */ 12 13/* This file is also used for Windows NT and MS-Win. In that case the module 14 actually calls itself 'nt', not 'posix', and a few functions are 15 either unimplemented or implemented differently. The source 16 assumes that for Windows NT, the macro 'MS_WIN32' is defined independent 17 of the compiler used. Different compilers define their own feature 18 test macro, e.g. '__BORLANDC__' or '_MSC_VER'. */ 19 20/* See also ../Dos/dosmodule.c */ 21 22static char posix__doc__ [] = 23"This module provides access to operating system functionality that is\n\ 24standardized by the C Standard and the POSIX standard (a thinly\n\ 25disguised Unix interface). Refer to the library manual and\n\ 26corresponding Unix manual entries for more information on calls."; 27 28#include "Python.h" 29 30#if defined(PYOS_OS2) 31#define INCL_DOS 32#define INCL_DOSERRORS 33#define INCL_DOSPROCESS 34#define INCL_NOPMAPI 35#include <os2.h> 36#endif 37 38#include <sys/types.h> 39#include <sys/stat.h> 40#ifdef HAVE_SYS_WAIT_H 41#include <sys/wait.h> /* For WNOHANG */ 42#endif 43 44#ifdef HAVE_SIGNAL_H 45#include <signal.h> 46#endif 47 48#ifdef HAVE_FCNTL_H 49#include <fcntl.h> 50#endif /* HAVE_FCNTL_H */ 51 52/* Various compilers have only certain posix functions */ 53/* XXX Gosh I wish these were all moved into config.h */ 54#if defined(PYCC_VACPP) && defined(PYOS_OS2) 55#include <process.h> 56#else 57#if defined(__WATCOMC__) && !defined(__QNX__) /* Watcom compiler */ 58#define HAVE_GETCWD 1 59#define HAVE_OPENDIR 1 60#define HAVE_SYSTEM 1 61#if defined(__OS2__) 62#define HAVE_EXECV 1 63#define HAVE_WAIT 1 64#endif 65#include <process.h> 66#else 67#ifdef __BORLANDC__ /* Borland compiler */ 68#define HAVE_EXECV 1 69#define HAVE_GETCWD 1 70#define HAVE_GETEGID 1 71#define HAVE_GETEUID 1 72#define HAVE_GETGID 1 73#define HAVE_GETPPID 1 74#define HAVE_GETUID 1 75#define HAVE_KILL 1 76#define HAVE_OPENDIR 1 77#define HAVE_PIPE 1 78#define HAVE_POPEN 1 79#define HAVE_SYSTEM 1 80#define HAVE_WAIT 1 81#else 82#ifdef _MSC_VER /* Microsoft compiler */ 83#define HAVE_GETCWD 1 84#ifdef MS_WIN32 85#define HAVE_SPAWNV 1 86#define HAVE_EXECV 1 87#define HAVE_PIPE 1 88#define HAVE_POPEN 1 89#define HAVE_SYSTEM 1 90#else /* 16-bit Windows */ 91#endif /* !MS_WIN32 */ 92#else /* all other compilers */ 93/* Unix functions that the configure script doesn't check for */ 94#define HAVE_EXECV 1 95#define HAVE_FORK 1 96#define HAVE_GETCWD 1 97#define HAVE_GETEGID 1 98#define HAVE_GETEUID 1 99#define HAVE_GETGID 1 100#define HAVE_GETPPID 1 101#define HAVE_GETUID 1 102#define HAVE_KILL 1 103#define HAVE_OPENDIR 1 104#define HAVE_PIPE 1 105#define HAVE_POPEN 1 106#define HAVE_SYSTEM 1 107#define HAVE_WAIT 1 108#define HAVE_TTYNAME 1 109#endif /* _MSC_VER */ 110#endif /* __BORLANDC__ */ 111#endif /* ! __WATCOMC__ || __QNX__ */ 112#endif /* ! __IBMC__ */ 113 114#ifndef _MSC_VER 115 116#ifdef HAVE_UNISTD_H 117#include <unistd.h> 118#endif 119 120#ifdef NeXT 121/* NeXT's <unistd.h> and <utime.h> aren't worth much */ 122#undef HAVE_UNISTD_H 123#undef HAVE_UTIME_H 124#define HAVE_WAITPID 125/* #undef HAVE_GETCWD */ 126#define UNION_WAIT /* This should really be checked for by autoconf */ 127#endif 128 129#ifndef HAVE_UNISTD_H 130#if defined(PYCC_VACPP) 131extern int mkdir(char *); 132#else 133#if ( defined(__WATCOMC__) || defined(_MSC_VER) ) && !defined(__QNX__) 134extern int mkdir(const char *); 135#else 136extern int mkdir(const char *, mode_t); 137#endif 138#endif 139#if defined(__IBMC__) || defined(__IBMCPP__) 140extern int chdir(char *); 141extern int rmdir(char *); 142#else 143extern int chdir(const char *); 144extern int rmdir(const char *); 145#endif 146extern int chmod(const char *, mode_t); 147extern int chown(const char *, uid_t, gid_t); 148extern char *getcwd(char *, int); 149extern char *strerror(int); 150extern int link(const char *, const char *); 151extern int rename(const char *, const char *); 152extern int stat(const char *, struct stat *); 153extern int unlink(const char *); 154extern int pclose(FILE *); 155#ifdef HAVE_SYMLINK 156extern int symlink(const char *, const char *); 157#endif /* HAVE_SYMLINK */ 158#ifdef HAVE_LSTAT 159extern int lstat(const char *, struct stat *); 160#endif /* HAVE_LSTAT */ 161#endif /* !HAVE_UNISTD_H */ 162 163#endif /* !_MSC_VER */ 164 165#ifdef HAVE_UTIME_H 166#include <utime.h> 167#endif /* HAVE_UTIME_H */ 168 169#ifdef HAVE_SYS_UTIME_H 170#include <sys/utime.h> 171#define HAVE_UTIME_H /* pretend we do for the rest of this file */ 172#endif /* HAVE_SYS_UTIME_H */ 173 174#ifdef HAVE_SYS_TIMES_H 175#include <sys/times.h> 176#endif /* HAVE_SYS_TIMES_H */ 177 178#ifdef HAVE_SYS_PARAM_H 179#include <sys/param.h> 180#endif /* HAVE_SYS_PARAM_H */ 181 182#ifdef HAVE_SYS_UTSNAME_H 183#include <sys/utsname.h> 184#endif /* HAVE_SYS_UTSNAME_H */ 185 186#ifndef MAXPATHLEN 187#define MAXPATHLEN 1024 188#endif /* MAXPATHLEN */ 189 190#ifdef HAVE_DIRENT_H 191#include <dirent.h> 192#define NAMLEN(dirent) strlen((dirent)->d_name) 193#else 194#if defined(__WATCOMC__) && !defined(__QNX__) 195#include <direct.h> 196#define NAMLEN(dirent) strlen((dirent)->d_name) 197#else 198#define dirent direct 199#define NAMLEN(dirent) (dirent)->d_namlen 200#endif 201#ifdef HAVE_SYS_NDIR_H 202#include <sys/ndir.h> 203#endif 204#ifdef HAVE_SYS_DIR_H 205#include <sys/dir.h> 206#endif 207#ifdef HAVE_NDIR_H 208#include <ndir.h> 209#endif 210#endif 211 212#ifdef _MSC_VER 213#include <direct.h> 214#include <io.h> 215#include <process.h> 216#define WINDOWS_LEAN_AND_MEAN 217#include <windows.h> 218#ifdef MS_WIN32 219#define popen _popen 220#define pclose _pclose 221#else /* 16-bit Windows */ 222#include <dos.h> 223#include <ctype.h> 224#endif /* MS_WIN32 */ 225#endif /* _MSC_VER */ 226 227#if defined(PYCC_VACPP) && defined(PYOS_OS2) 228#include <io.h> 229#endif /* OS2 */ 230 231#ifdef UNION_WAIT 232/* Emulate some macros on systems that have a union instead of macros */ 233 234#ifndef WIFEXITED 235#define WIFEXITED(u_wait) (!(u_wait).w_termsig && !(u_wait).w_coredump) 236#endif 237 238#ifndef WEXITSTATUS 239#define WEXITSTATUS(u_wait) (WIFEXITED(u_wait)?((u_wait).w_retcode):-1) 240#endif 241 242#ifndef WTERMSIG 243#define WTERMSIG(u_wait) ((u_wait).w_termsig) 244#endif 245 246#endif /* UNION_WAIT */ 247 248/* Don't use the "_r" form if we don't need it (also, won't have a 249 prototype for it, at least on Solaris -- maybe others as well?). */ 250#if defined(HAVE_CTERMID_R) && defined(WITH_THREAD) 251#define USE_CTERMID_R 252#endif 253 254#if defined(HAVE_TMPNAM_R) && defined(WITH_THREAD) 255#define USE_TMPNAM_R 256#endif 257 258/* choose the appropriate stat and fstat functions and return structs */ 259#undef STAT 260#ifdef MS_WIN64 261# define STAT _stati64 262# define FSTAT _fstati64 263# define STRUCT_STAT struct _stati64 264#else 265# define STAT stat 266# define FSTAT fstat 267# define STRUCT_STAT struct stat 268#endif 269 270 271/* Return a dictionary corresponding to the POSIX environment table */ 272 273#if !defined(_MSC_VER) && ( !defined(__WATCOMC__) || defined(__QNX__) ) 274extern char **environ; 275#endif /* !_MSC_VER */ 276 277static PyObject * 278convertenviron(void) 279{ 280 PyObject *d; 281 char **e; 282 d = PyDict_New(); 283 if (d == NULL) 284 return NULL; 285 if (environ == NULL) 286 return d; 287 /* This part ignores errors */ 288 for (e = environ; *e != NULL; e++) { 289 PyObject *k; 290 PyObject *v; 291 char *p = strchr(*e, '='); 292 if (p == NULL) 293 continue; 294 k = PyString_FromStringAndSize(*e, (int)(p-*e)); 295 if (k == NULL) { 296 PyErr_Clear(); 297 continue; 298 } 299 v = PyString_FromString(p+1); 300 if (v == NULL) { 301 PyErr_Clear(); 302 Py_DECREF(k); 303 continue; 304 } 305 if (PyDict_GetItem(d, k) == NULL) { 306 if (PyDict_SetItem(d, k, v) != 0) 307 PyErr_Clear(); 308 } 309 Py_DECREF(k); 310 Py_DECREF(v); 311 } 312#if defined(PYOS_OS2) 313 { 314 APIRET rc; 315 char buffer[1024]; /* OS/2 Provides a Documented Max of 1024 Chars */ 316 317 rc = DosQueryExtLIBPATH(buffer, BEGIN_LIBPATH); 318 if (rc == NO_ERROR) { /* (not a type, envname is NOT 'BEGIN_LIBPATH') */ 319 PyObject *v = PyString_FromString(buffer); 320 PyDict_SetItemString(d, "BEGINLIBPATH", v); 321 Py_DECREF(v); 322 } 323 rc = DosQueryExtLIBPATH(buffer, END_LIBPATH); 324 if (rc == NO_ERROR) { /* (not a typo, envname is NOT 'END_LIBPATH') */ 325 PyObject *v = PyString_FromString(buffer); 326 PyDict_SetItemString(d, "ENDLIBPATH", v); 327 Py_DECREF(v); 328 } 329 } 330#endif 331 return d; 332} 333 334 335/* Set a POSIX-specific error from errno, and return NULL */ 336 337static PyObject * 338posix_error(void) 339{ 340 return PyErr_SetFromErrno(PyExc_OSError); 341} 342static PyObject * 343posix_error_with_filename(char* name) 344{ 345 return PyErr_SetFromErrnoWithFilename(PyExc_OSError, name); 346} 347 348#ifdef MS_WIN32 349static PyObject * 350win32_error(char* function, char* filename) 351{ 352 /* XXX this could be improved */ 353 errno = GetLastError(); 354 if (filename) 355 return PyErr_SetFromErrnoWithFilename(PyExc_OSError, filename); 356 else 357 return PyErr_SetFromErrno(PyExc_OSError); 358} 359#endif 360 361#if defined(PYOS_OS2) 362/********************************************************************** 363 * Helper Function to Trim and Format OS/2 Messages 364 **********************************************************************/ 365 static void 366os2_formatmsg(char *msgbuf, int msglen, char *reason) 367{ 368 msgbuf[msglen] = '\0'; /* OS/2 Doesn't Guarantee a Terminator */ 369 370 if (strlen(msgbuf) > 0) { /* If Non-Empty Msg, Trim CRLF */ 371 char *lastc = &msgbuf[ strlen(msgbuf)-1 ]; 372 373 while (lastc > msgbuf && isspace(*lastc)) 374 *lastc-- = '\0'; /* Trim Trailing Whitespace (CRLF) */ 375 } 376 377 /* Add Optional Reason Text */ 378 if (reason) { 379 strcat(msgbuf, " : "); 380 strcat(msgbuf, reason); 381 } 382} 383 384/********************************************************************** 385 * Decode an OS/2 Operating System Error Code 386 * 387 * A convenience function to lookup an OS/2 error code and return a 388 * text message we can use to raise a Python exception. 389 * 390 * Notes: 391 * The messages for errors returned from the OS/2 kernel reside in 392 * the file OSO001.MSG in the \OS2 directory hierarchy. 393 * 394 **********************************************************************/ 395 static char * 396os2_strerror(char *msgbuf, int msgbuflen, int errorcode, char *reason) 397{ 398 APIRET rc; 399 ULONG msglen; 400 401 /* Retrieve Kernel-Related Error Message from OSO001.MSG File */ 402 Py_BEGIN_ALLOW_THREADS 403 rc = DosGetMessage(NULL, 0, msgbuf, msgbuflen, 404 errorcode, "oso001.msg", &msglen); 405 Py_END_ALLOW_THREADS 406 407 if (rc == NO_ERROR) 408 os2_formatmsg(msgbuf, msglen, reason); 409 else 410 sprintf(msgbuf, "unknown OS error #%d", errorcode); 411 412 return msgbuf; 413} 414 415/* Set an OS/2-specific error and return NULL. OS/2 kernel 416 errors are not in a global variable e.g. 'errno' nor are 417 they congruent with posix error numbers. */ 418 419static PyObject * os2_error(int code) 420{ 421 char text[1024]; 422 PyObject *v; 423 424 os2_strerror(text, sizeof(text), code, ""); 425 426 v = Py_BuildValue("(is)", code, text); 427 if (v != NULL) { 428 PyErr_SetObject(PyExc_OSError, v); 429 Py_DECREF(v); 430 } 431 return NULL; /* Signal to Python that an Exception is Pending */ 432} 433 434#endif /* OS2 */ 435 436/* POSIX generic methods */ 437 438static PyObject * 439posix_int(PyObject *args, char *format, int (*func)(int)) 440{ 441 int fd; 442 int res; 443 if (!PyArg_ParseTuple(args, format, &fd)) 444 return NULL; 445 Py_BEGIN_ALLOW_THREADS 446 res = (*func)(fd); 447 Py_END_ALLOW_THREADS 448 if (res < 0) 449 return posix_error(); 450 Py_INCREF(Py_None); 451 return Py_None; 452} 453 454 455static PyObject * 456posix_1str(PyObject *args, char *format, int (*func)(const char*)) 457{ 458 char *path1; 459 int res; 460 if (!PyArg_ParseTuple(args, format, &path1)) 461 return NULL; 462 Py_BEGIN_ALLOW_THREADS 463 res = (*func)(path1); 464 Py_END_ALLOW_THREADS 465 if (res < 0) 466 return posix_error_with_filename(path1); 467 Py_INCREF(Py_None); 468 return Py_None; 469} 470 471static PyObject * 472posix_2str(PyObject *args, char *format, 473 int (*func)(const char *, const char *)) 474{ 475 char *path1, *path2; 476 int res; 477 if (!PyArg_ParseTuple(args, format, &path1, &path2)) 478 return NULL; 479 Py_BEGIN_ALLOW_THREADS 480 res = (*func)(path1, path2); 481 Py_END_ALLOW_THREADS 482 if (res != 0) 483 /* XXX how to report both path1 and path2??? */ 484 return posix_error(); 485 Py_INCREF(Py_None); 486 return Py_None; 487} 488 489/* pack a system stat C structure into the Python stat tuple 490 (used by posix_stat() and posix_fstat()) */ 491static PyObject* 492_pystat_fromstructstat(STRUCT_STAT st) 493{ 494 PyObject *v = PyTuple_New(10); 495 if (v == NULL) 496 return NULL; 497 498 PyTuple_SetItem(v, 0, PyInt_FromLong((long)st.st_mode)); 499#ifdef HAVE_LARGEFILE_SUPPORT 500 PyTuple_SetItem(v, 1, PyLong_FromLongLong((LONG_LONG)st.st_ino)); 501#else 502 PyTuple_SetItem(v, 1, PyInt_FromLong((long)st.st_ino)); 503#endif 504#if defined(HAVE_LONG_LONG) && !defined(MS_WINDOWS) 505 PyTuple_SetItem(v, 2, PyLong_FromLongLong((LONG_LONG)st.st_dev)); 506#else 507 PyTuple_SetItem(v, 2, PyInt_FromLong((long)st.st_dev)); 508#endif 509 PyTuple_SetItem(v, 3, PyInt_FromLong((long)st.st_nlink)); 510 PyTuple_SetItem(v, 4, PyInt_FromLong((long)st.st_uid)); 511 PyTuple_SetItem(v, 5, PyInt_FromLong((long)st.st_gid)); 512#ifdef HAVE_LARGEFILE_SUPPORT 513 PyTuple_SetItem(v, 6, PyLong_FromLongLong((LONG_LONG)st.st_size)); 514#else 515 PyTuple_SetItem(v, 6, PyInt_FromLong(st.st_size)); 516#endif 517#if SIZEOF_TIME_T > SIZEOF_LONG 518 PyTuple_SetItem(v, 7, PyLong_FromLongLong((LONG_LONG)st.st_atime)); 519 PyTuple_SetItem(v, 8, PyLong_FromLongLong((LONG_LONG)st.st_mtime)); 520 PyTuple_SetItem(v, 9, PyLong_FromLongLong((LONG_LONG)st.st_ctime)); 521#else 522 PyTuple_SetItem(v, 7, PyInt_FromLong((long)st.st_atime)); 523 PyTuple_SetItem(v, 8, PyInt_FromLong((long)st.st_mtime)); 524 PyTuple_SetItem(v, 9, PyInt_FromLong((long)st.st_ctime)); 525#endif 526 527 if (PyErr_Occurred()) { 528 Py_DECREF(v); 529 return NULL; 530 } 531 532 return v; 533} 534 535 536static PyObject * 537posix_do_stat(PyObject *self, PyObject *args, char *format, 538 int (*statfunc)(const char *, STRUCT_STAT *)) 539{ 540 STRUCT_STAT st; 541 char *path; 542 int res; 543 544#ifdef MS_WIN32 545 int pathlen; 546 char pathcopy[MAX_PATH]; 547#endif /* MS_WIN32 */ 548 549 if (!PyArg_ParseTuple(args, format, &path)) 550 return NULL; 551 552#ifdef MS_WIN32 553 pathlen = strlen(path); 554 /* the library call can blow up if the file name is too long! */ 555 if (pathlen > MAX_PATH) { 556 errno = ENAMETOOLONG; 557 return posix_error(); 558 } 559 560 if ((pathlen > 0) && (path[pathlen-1] == '\\' || path[pathlen-1] == '/')) { 561 /* exception for specific or current drive root */ 562 if (!((pathlen == 1) || 563 ((pathlen == 3) && 564 (path[1] == ':') && 565 (path[2] == '\\' || path[2] == '/')))) 566 { 567 strncpy(pathcopy, path, pathlen); 568 pathcopy[pathlen-1] = '\0'; /* nuke the trailing backslash */ 569 path = pathcopy; 570 } 571 } 572#endif /* MS_WIN32 */ 573 574 Py_BEGIN_ALLOW_THREADS 575 res = (*statfunc)(path, &st); 576 Py_END_ALLOW_THREADS 577 if (res != 0) 578 return posix_error_with_filename(path); 579 580 return _pystat_fromstructstat(st); 581} 582 583 584/* POSIX methods */ 585 586static char posix_access__doc__[] = 587"access(path, mode) -> 1 if granted, 0 otherwise\n\ 588Test for access to a file."; 589 590static PyObject * 591posix_access(PyObject *self, PyObject *args) 592{ 593 char *path; 594 int mode; 595 int res; 596 597 if (!PyArg_ParseTuple(args, "si:access", &path, &mode)) 598 return NULL; 599 Py_BEGIN_ALLOW_THREADS 600 res = access(path, mode); 601 Py_END_ALLOW_THREADS 602 return(PyInt_FromLong(res == 0 ? 1L : 0L)); 603} 604 605#ifndef F_OK 606#define F_OK 0 607#endif 608#ifndef R_OK 609#define R_OK 4 610#endif 611#ifndef W_OK 612#define W_OK 2 613#endif 614#ifndef X_OK 615#define X_OK 1 616#endif 617 618#ifdef HAVE_TTYNAME 619static char posix_ttyname__doc__[] = 620"ttyname(fd) -> String\n\ 621Return the name of the terminal device connected to 'fd'."; 622 623static PyObject * 624posix_ttyname(PyObject *self, PyObject *args) 625{ 626 int id; 627 char *ret; 628 629 if (!PyArg_ParseTuple(args, "i:ttyname", &id)) 630 return NULL; 631 632 ret = ttyname(id); 633 if (ret == NULL) 634 return(posix_error()); 635 return(PyString_FromString(ret)); 636} 637#endif 638 639#ifdef HAVE_CTERMID 640static char posix_ctermid__doc__[] = 641"ctermid() -> String\n\ 642Return the name of the controlling terminal for this process."; 643 644static PyObject * 645posix_ctermid(PyObject *self, PyObject *args) 646{ 647 char *ret; 648 char buffer[L_ctermid]; 649 650 if (!PyArg_ParseTuple(args, ":ctermid")) 651 return NULL; 652 653#ifdef USE_CTERMID_R 654 ret = ctermid_r(buffer); 655#else 656 ret = ctermid(buffer); 657#endif 658 if (ret == NULL) 659 return(posix_error()); 660 return(PyString_FromString(buffer)); 661} 662#endif 663 664static char posix_chdir__doc__[] = 665"chdir(path) -> None\n\ 666Change the current working directory to the specified path."; 667 668static PyObject * 669posix_chdir(PyObject *self, PyObject *args) 670{ 671 return posix_1str(args, "s:chdir", chdir); 672} 673 674 675static char posix_chmod__doc__[] = 676"chmod(path, mode) -> None\n\ 677Change the access permissions of a file."; 678 679static PyObject * 680posix_chmod(PyObject *self, PyObject *args) 681{ 682 char *path; 683 int i; 684 int res; 685 if (!PyArg_ParseTuple(args, "si", &path, &i)) 686 return NULL; 687 Py_BEGIN_ALLOW_THREADS 688 res = chmod(path, i); 689 Py_END_ALLOW_THREADS 690 if (res < 0) 691 return posix_error_with_filename(path); 692 Py_INCREF(Py_None); 693 return Py_None; 694} 695 696 697#ifdef HAVE_FSYNC 698static char posix_fsync__doc__[] = 699"fsync(fildes) -> None\n\ 700force write of file with filedescriptor to disk."; 701 702static PyObject * 703posix_fsync(PyObject *self, PyObject *args) 704{ 705 return posix_int(args, "i:fsync", fsync); 706} 707#endif /* HAVE_FSYNC */ 708 709#ifdef HAVE_FDATASYNC 710static char posix_fdatasync__doc__[] = 711"fdatasync(fildes) -> None\n\ 712force write of file with filedescriptor to disk.\n\ 713 does not force update of metadata."; 714 715static PyObject * 716posix_fdatasync(PyObject *self, PyObject *args) 717{ 718 return posix_int(args, "i:fdatasync", fdatasync); 719} 720#endif /* HAVE_FDATASYNC */ 721 722 723#ifdef HAVE_CHOWN 724static char posix_chown__doc__[] = 725"chown(path, uid, gid) -> None\n\ 726Change the owner and group id of path to the numeric uid and gid."; 727 728static PyObject * 729posix_chown(PyObject *self, PyObject *args) 730{ 731 char *path; 732 int uid, gid; 733 int res; 734 if (!PyArg_ParseTuple(args, "sii:chown", &path, &uid, &gid)) 735 return NULL; 736 Py_BEGIN_ALLOW_THREADS 737 res = chown(path, (uid_t) uid, (gid_t) gid); 738 Py_END_ALLOW_THREADS 739 if (res < 0) 740 return posix_error_with_filename(path); 741 Py_INCREF(Py_None); 742 return Py_None; 743} 744#endif /* HAVE_CHOWN */ 745 746 747#ifdef HAVE_GETCWD 748static char posix_getcwd__doc__[] = 749"getcwd() -> path\n\ 750Return a string representing the current working directory."; 751 752static PyObject * 753posix_getcwd(PyObject *self, PyObject *args) 754{ 755 char buf[1026]; 756 char *res; 757 if (!PyArg_ParseTuple(args, ":getcwd")) 758 return NULL; 759 Py_BEGIN_ALLOW_THREADS 760 res = getcwd(buf, sizeof buf); 761 Py_END_ALLOW_THREADS 762 if (res == NULL) 763 return posix_error(); 764 return PyString_FromString(buf); 765} 766#endif 767 768 769#ifdef HAVE_LINK 770static char posix_link__doc__[] = 771"link(src, dst) -> None\n\ 772Create a hard link to a file."; 773 774static PyObject * 775posix_link(PyObject *self, PyObject *args) 776{ 777 return posix_2str(args, "ss:link", link); 778} 779#endif /* HAVE_LINK */ 780 781 782static char posix_listdir__doc__[] = 783"listdir(path) -> list_of_strings\n\ 784Return a list containing the names of the entries in the directory.\n\ 785\n\ 786 path: path of directory to list\n\ 787\n\ 788The list is in arbitrary order. It does not include the special\n\ 789entries '.' and '..' even if they are present in the directory."; 790 791static PyObject * 792posix_listdir(PyObject *self, PyObject *args) 793{ 794 /* XXX Should redo this putting the (now four) versions of opendir 795 in separate files instead of having them all here... */ 796#if defined(MS_WIN32) && !defined(HAVE_OPENDIR) 797 798 char *name; 799 int len; 800 PyObject *d, *v; 801 HANDLE hFindFile; 802 WIN32_FIND_DATA FileData; 803 char namebuf[MAX_PATH+5]; 804 805 if (!PyArg_ParseTuple(args, "t#:listdir", &name, &len)) 806 return NULL; 807 if (len >= MAX_PATH) { 808 PyErr_SetString(PyExc_ValueError, "path too long"); 809 return NULL; 810 } 811 strcpy(namebuf, name); 812 if (namebuf[len-1] != '/' && namebuf[len-1] != '\\') 813 namebuf[len++] = '/'; 814 strcpy(namebuf + len, "*.*"); 815 816 if ((d = PyList_New(0)) == NULL) 817 return NULL; 818 819 hFindFile = FindFirstFile(namebuf, &FileData); 820 if (hFindFile == INVALID_HANDLE_VALUE) { 821 errno = GetLastError(); 822 if (errno == ERROR_FILE_NOT_FOUND) 823 return PyList_New(0); 824 return win32_error("FindFirstFile", name); 825 } 826 do { 827 if (FileData.cFileName[0] == '.' && 828 (FileData.cFileName[1] == '\0' || 829 FileData.cFileName[1] == '.' && 830 FileData.cFileName[2] == '\0')) 831 continue; 832 v = PyString_FromString(FileData.cFileName); 833 if (v == NULL) { 834 Py_DECREF(d); 835 d = NULL; 836 break; 837 } 838 if (PyList_Append(d, v) != 0) { 839 Py_DECREF(v); 840 Py_DECREF(d); 841 d = NULL; 842 break; 843 } 844 Py_DECREF(v); 845 } while (FindNextFile(hFindFile, &FileData) == TRUE); 846 847 if (FindClose(hFindFile) == FALSE) 848 return win32_error("FindClose", name); 849 850 return d; 851 852#else /* !MS_WIN32 */ 853#ifdef _MSC_VER /* 16-bit Windows */ 854 855#ifndef MAX_PATH 856#define MAX_PATH 250 857#endif 858 char *name, *pt; 859 int len; 860 PyObject *d, *v; 861 char namebuf[MAX_PATH+5]; 862 struct _find_t ep; 863 864 if (!PyArg_ParseTuple(args, "t#:listdir", &name, &len)) 865 return NULL; 866 if (len >= MAX_PATH) { 867 PyErr_SetString(PyExc_ValueError, "path too long"); 868 return NULL; 869 } 870 strcpy(namebuf, name); 871 for (pt = namebuf; *pt; pt++) 872 if (*pt == '/') 873 *pt = '\\'; 874 if (namebuf[len-1] != '\\') 875 namebuf[len++] = '\\'; 876 strcpy(namebuf + len, "*.*"); 877 878 if ((d = PyList_New(0)) == NULL) 879 return NULL; 880 881 if (_dos_findfirst(namebuf, _A_RDONLY | 882 _A_HIDDEN | _A_SYSTEM | _A_SUBDIR, &ep) != 0) 883 { 884 errno = ENOENT; 885 return posix_error_with_filename(name); 886 } 887 do { 888 if (ep.name[0] == '.' && 889 (ep.name[1] == '\0' || 890 ep.name[1] == '.' && 891 ep.name[2] == '\0')) 892 continue; 893 strcpy(namebuf, ep.name); 894 for (pt = namebuf; *pt; pt++) 895 if (isupper(*pt)) 896 *pt = tolower(*pt); 897 v = PyString_FromString(namebuf); 898 if (v == NULL) { 899 Py_DECREF(d); 900 d = NULL; 901 break; 902 } 903 if (PyList_Append(d, v) != 0) { 904 Py_DECREF(v); 905 Py_DECREF(d); 906 d = NULL; 907 break; 908 } 909 Py_DECREF(v); 910 } while (_dos_findnext(&ep) == 0); 911 912 return d; 913 914#else 915#if defined(PYOS_OS2) 916 917#ifndef MAX_PATH 918#define MAX_PATH CCHMAXPATH 919#endif 920 char *name, *pt; 921 int len; 922 PyObject *d, *v; 923 char namebuf[MAX_PATH+5]; 924 HDIR hdir = 1; 925 ULONG srchcnt = 1; 926 FILEFINDBUF3 ep; 927 APIRET rc; 928 929 if (!PyArg_ParseTuple(args, "t#:listdir", &name, &len)) 930 return NULL; 931 if (len >= MAX_PATH) { 932 PyErr_SetString(PyExc_ValueError, "path too long"); 933 return NULL; 934 } 935 strcpy(namebuf, name); 936 for (pt = namebuf; *pt; pt++) 937 if (*pt == '/') 938 *pt = '\\'; 939 if (namebuf[len-1] != '\\') 940 namebuf[len++] = '\\'; 941 strcpy(namebuf + len, "*.*"); 942 943 if ((d = PyList_New(0)) == NULL) 944 return NULL; 945 946 rc = DosFindFirst(namebuf, /* Wildcard Pattern to Match */ 947 &hdir, /* Handle to Use While Search Directory */ 948 FILE_READONLY | FILE_HIDDEN | FILE_SYSTEM | FILE_DIRECTORY, 949 &ep, sizeof(ep), /* Structure to Receive Directory Entry */ 950 &srchcnt, /* Max and Actual Count of Entries Per Iteration */ 951 FIL_STANDARD); /* Format of Entry (EAs or Not) */ 952 953 if (rc != NO_ERROR) { 954 errno = ENOENT; 955 return posix_error_with_filename(name); 956 } 957 958 if (srchcnt > 0) { /* If Directory is NOT Totally Empty, */ 959 do { 960 if (ep.achName[0] == '.' 961 && (ep.achName[1] == '\0' || ep.achName[1] == '.' && ep.achName[2] == '\0')) 962 continue; /* Skip Over "." and ".." Names */ 963 964 strcpy(namebuf, ep.achName); 965 966 /* Leave Case of Name Alone -- In Native Form */ 967 /* (Removed Forced Lowercasing Code) */ 968 969 v = PyString_FromString(namebuf); 970 if (v == NULL) { 971 Py_DECREF(d); 972 d = NULL; 973 break; 974 } 975 if (PyList_Append(d, v) != 0) { 976 Py_DECREF(v); 977 Py_DECREF(d); 978 d = NULL; 979 break; 980 } 981 Py_DECREF(v); 982 } while (DosFindNext(hdir, &ep, sizeof(ep), &srchcnt) == NO_ERROR && srchcnt > 0); 983 } 984 985 return d; 986#else 987 988 char *name; 989 PyObject *d, *v; 990 DIR *dirp; 991 struct dirent *ep; 992 if (!PyArg_ParseTuple(args, "s:listdir", &name)) 993 return NULL; 994 if ((dirp = opendir(name)) == NULL) { 995 return posix_error_with_filename(name); 996 } 997 if ((d = PyList_New(0)) == NULL) { 998 closedir(dirp); 999 return NULL; 1000 } 1001 while ((ep = readdir(dirp)) != NULL) { 1002 if (ep->d_name[0] == '.' && 1003 (NAMLEN(ep) == 1 || 1004 (ep->d_name[1] == '.' && NAMLEN(ep) == 2))) 1005 continue; 1006 v = PyString_FromStringAndSize(ep->d_name, NAMLEN(ep)); 1007 if (v == NULL) { 1008 Py_DECREF(d); 1009 d = NULL; 1010 break; 1011 } 1012 if (PyList_Append(d, v) != 0) { 1013 Py_DECREF(v); 1014 Py_DECREF(d); 1015 d = NULL; 1016 break; 1017 } 1018 Py_DECREF(v); 1019 } 1020 closedir(dirp); 1021 1022 return d; 1023 1024#endif /* !PYOS_OS2 */ 1025#endif /* !_MSC_VER */ 1026#endif /* !MS_WIN32 */ 1027} 1028 1029static char posix_mkdir__doc__[] = 1030"mkdir(path [, mode=0777]) -> None\n\ 1031Create a directory."; 1032 1033static PyObject * 1034posix_mkdir(PyObject *self, PyObject *args) 1035{ 1036 int res; 1037 char *path; 1038 int mode = 0777; 1039 if (!PyArg_ParseTuple(args, "s|i:mkdir", &path, &mode)) 1040 return NULL; 1041 Py_BEGIN_ALLOW_THREADS 1042#if ( defined(__WATCOMC__) || defined(_MSC_VER) || defined(PYCC_VACPP) ) && !defined(__QNX__) 1043 res = mkdir(path); 1044#else 1045 res = mkdir(path, mode); 1046#endif 1047 Py_END_ALLOW_THREADS 1048 if (res < 0) 1049 return posix_error_with_filename(path); 1050 Py_INCREF(Py_None); 1051 return Py_None; 1052} 1053 1054 1055#ifdef HAVE_NICE 1056static char posix_nice__doc__[] = 1057"nice(inc) -> new_priority\n\ 1058Decrease the priority of process and return new priority."; 1059 1060static PyObject * 1061posix_nice(PyObject *self, PyObject *args) 1062{ 1063 int increment, value; 1064 1065 if (!PyArg_ParseTuple(args, "i:nice", &increment)) 1066 return NULL; 1067 value = nice(increment); 1068 if (value == -1) 1069 return posix_error(); 1070 return PyInt_FromLong((long) value); 1071} 1072#endif /* HAVE_NICE */ 1073 1074 1075static char posix_rename__doc__[] = 1076"rename(old, new) -> None\n\ 1077Rename a file or directory."; 1078 1079static PyObject * 1080posix_rename(PyObject *self, PyObject *args) 1081{ 1082 return posix_2str(args, "ss:rename", rename); 1083} 1084 1085 1086static char posix_rmdir__doc__[] = 1087"rmdir(path) -> None\n\ 1088Remove a directory."; 1089 1090static PyObject * 1091posix_rmdir(PyObject *self, PyObject *args) 1092{ 1093 return posix_1str(args, "s:rmdir", rmdir); 1094} 1095 1096 1097static char posix_stat__doc__[] = 1098"stat(path) -> (mode,ino,dev,nlink,uid,gid,size,atime,mtime,ctime)\n\ 1099Perform a stat system call on the given path."; 1100 1101static PyObject * 1102posix_stat(PyObject *self, PyObject *args) 1103{ 1104 return posix_do_stat(self, args, "s:stat", STAT); 1105} 1106 1107 1108#ifdef HAVE_SYSTEM 1109static char posix_system__doc__[] = 1110"system(command) -> exit_status\n\ 1111Execute the command (a string) in a subshell."; 1112 1113static PyObject * 1114posix_system(PyObject *self, PyObject *args) 1115{ 1116 char *command; 1117 long sts; 1118 if (!PyArg_ParseTuple(args, "s:system", &command)) 1119 return NULL; 1120 Py_BEGIN_ALLOW_THREADS 1121 sts = system(command); 1122 Py_END_ALLOW_THREADS 1123 return PyInt_FromLong(sts); 1124} 1125#endif 1126 1127 1128static char posix_umask__doc__[] = 1129"umask(new_mask) -> old_mask\n\ 1130Set the current numeric umask and return the previous umask."; 1131 1132static PyObject * 1133posix_umask(PyObject *self, PyObject *args) 1134{ 1135 int i; 1136 if (!PyArg_ParseTuple(args, "i:umask", &i)) 1137 return NULL; 1138 i = umask(i); 1139 if (i < 0) 1140 return posix_error(); 1141 return PyInt_FromLong((long)i); 1142} 1143 1144 1145static char posix_unlink__doc__[] = 1146"unlink(path) -> None\n\ 1147Remove a file (same as remove(path))."; 1148 1149static char posix_remove__doc__[] = 1150"remove(path) -> None\n\ 1151Remove a file (same as unlink(path))."; 1152 1153static PyObject * 1154posix_unlink(PyObject *self, PyObject *args) 1155{ 1156 return posix_1str(args, "s:remove", unlink); 1157} 1158 1159 1160#ifdef HAVE_UNAME 1161static char posix_uname__doc__[] = 1162"uname() -> (sysname, nodename, release, version, machine)\n\ 1163Return a tuple identifying the current operating system."; 1164 1165static PyObject * 1166posix_uname(PyObject *self, PyObject *args) 1167{ 1168 struct utsname u; 1169 int res; 1170 if (!PyArg_ParseTuple(args, ":uname")) 1171 return NULL; 1172 Py_BEGIN_ALLOW_THREADS 1173 res = uname(&u); 1174 Py_END_ALLOW_THREADS 1175 if (res < 0) 1176 return posix_error(); 1177 return Py_BuildValue("(sssss)", 1178 u.sysname, 1179 u.nodename, 1180 u.release, 1181 u.version, 1182 u.machine); 1183} 1184#endif /* HAVE_UNAME */ 1185 1186 1187static char posix_utime__doc__[] = 1188"utime(path, (atime, utime)) -> None\n\ 1189utime(path, None) -> None\n\ 1190Set the access and modified time of the file to the given values. If the\n\ 1191second form is used, set the access and modified times to the current time."; 1192 1193static PyObject * 1194posix_utime(PyObject *self, PyObject *args) 1195{ 1196 char *path; 1197 long atime, mtime; 1198 int res; 1199 PyObject* arg; 1200 1201/* XXX should define struct utimbuf instead, above */ 1202#ifdef HAVE_UTIME_H 1203 struct utimbuf buf; 1204#define ATIME buf.actime 1205#define MTIME buf.modtime 1206#define UTIME_ARG &buf 1207#else /* HAVE_UTIME_H */ 1208 time_t buf[2]; 1209#define ATIME buf[0] 1210#define MTIME buf[1] 1211#define UTIME_ARG buf 1212#endif /* HAVE_UTIME_H */ 1213 1214 if (!PyArg_ParseTuple(args, "sO:utime", &path, &arg)) 1215 return NULL; 1216 if (arg == Py_None) { 1217 /* optional time values not given */ 1218 Py_BEGIN_ALLOW_THREADS 1219 res = utime(path, NULL); 1220 Py_END_ALLOW_THREADS 1221 } 1222 else if (!PyArg_Parse(arg, "(ll)", &atime, &mtime)) { 1223 PyErr_SetString(PyExc_TypeError, 1224 "Second argument must be a 2-tuple of numbers."); 1225 return NULL; 1226 } 1227 else { 1228 ATIME = atime; 1229 MTIME = mtime; 1230 Py_BEGIN_ALLOW_THREADS 1231 res = utime(path, UTIME_ARG); 1232 Py_END_ALLOW_THREADS 1233 } 1234 if (res < 0) 1235 return posix_error_with_filename(path); 1236 Py_INCREF(Py_None); 1237 return Py_None; 1238#undef UTIME_ARG 1239#undef ATIME 1240#undef MTIME 1241} 1242 1243 1244/* Process operations */ 1245 1246static char posix__exit__doc__[] = 1247"_exit(status)\n\ 1248Exit to the system with specified status, without normal exit processing."; 1249 1250static PyObject * 1251posix__exit(PyObject *self, PyObject *args) 1252{ 1253 int sts; 1254 if (!PyArg_ParseTuple(args, "i:_exit", &sts)) 1255 return NULL; 1256 _exit(sts); 1257 return NULL; /* Make gcc -Wall happy */ 1258} 1259 1260 1261#ifdef HAVE_EXECV 1262static char posix_execv__doc__[] = 1263"execv(path, args)\n\ 1264Execute an executable path with arguments, replacing current process.\n\ 1265\n\ 1266 path: path of executable file\n\ 1267 args: tuple or list of strings"; 1268 1269static PyObject * 1270posix_execv(PyObject *self, PyObject *args) 1271{ 1272 char *path; 1273 PyObject *argv; 1274 char **argvlist; 1275 int i, argc; 1276 PyObject *(*getitem)(PyObject *, int); 1277 1278 /* execv has two arguments: (path, argv), where 1279 argv is a list or tuple of strings. */ 1280 1281 if (!PyArg_ParseTuple(args, "sO:execv", &path, &argv)) 1282 return NULL; 1283 if (PyList_Check(argv)) { 1284 argc = PyList_Size(argv); 1285 getitem = PyList_GetItem; 1286 } 1287 else if (PyTuple_Check(argv)) { 1288 argc = PyTuple_Size(argv); 1289 getitem = PyTuple_GetItem; 1290 } 1291 else { 1292 PyErr_SetString(PyExc_TypeError, "argv must be tuple or list"); 1293 return NULL; 1294 } 1295 1296 if (argc == 0) { 1297 PyErr_SetString(PyExc_ValueError, "empty argument list"); 1298 return NULL; 1299 } 1300 1301 argvlist = PyMem_NEW(char *, argc+1); 1302 if (argvlist == NULL) 1303 return NULL; 1304 for (i = 0; i < argc; i++) { 1305 if (!PyArg_Parse((*getitem)(argv, i), "s", &argvlist[i])) { 1306 PyMem_DEL(argvlist); 1307 PyErr_SetString(PyExc_TypeError, 1308 "all arguments must be strings"); 1309 return NULL; 1310 1311 } 1312 } 1313 argvlist[argc] = NULL; 1314 1315#ifdef BAD_EXEC_PROTOTYPES 1316 execv(path, (const char **) argvlist); 1317#else /* BAD_EXEC_PROTOTYPES */ 1318 execv(path, argvlist); 1319#endif /* BAD_EXEC_PROTOTYPES */ 1320 1321 /* If we get here it's definitely an error */ 1322 1323 PyMem_DEL(argvlist); 1324 return posix_error(); 1325} 1326 1327 1328static char posix_execve__doc__[] = 1329"execve(path, args, env)\n\ 1330Execute a path with arguments and environment, replacing current process.\n\ 1331\n\ 1332 path: path of executable file\n\ 1333 args: tuple or list of arguments\n\ 1334 env: dictionary of strings mapping to strings"; 1335 1336static PyObject * 1337posix_execve(PyObject *self, PyObject *args) 1338{ 1339 char *path; 1340 PyObject *argv, *env; 1341 char **argvlist; 1342 char **envlist; 1343 PyObject *key, *val, *keys=NULL, *vals=NULL; 1344 int i, pos, argc, envc; 1345 PyObject *(*getitem)(PyObject *, int); 1346 1347 /* execve has three arguments: (path, argv, env), where 1348 argv is a list or tuple of strings and env is a dictionary 1349 like posix.environ. */ 1350 1351 if (!PyArg_ParseTuple(args, "sOO:execve", &path, &argv, &env)) 1352 return NULL; 1353 if (PyList_Check(argv)) { 1354 argc = PyList_Size(argv); 1355 getitem = PyList_GetItem; 1356 } 1357 else if (PyTuple_Check(argv)) { 1358 argc = PyTuple_Size(argv); 1359 getitem = PyTuple_GetItem; 1360 } 1361 else { 1362 PyErr_SetString(PyExc_TypeError, "argv must be tuple or list"); 1363 return NULL; 1364 } 1365 if (!PyMapping_Check(env)) { 1366 PyErr_SetString(PyExc_TypeError, "env must be mapping object"); 1367 return NULL; 1368 } 1369 1370 if (argc == 0) { 1371 PyErr_SetString(PyExc_ValueError, 1372 "empty argument list"); 1373 return NULL; 1374 } 1375 1376 argvlist = PyMem_NEW(char *, argc+1); 1377 if (argvlist == NULL) { 1378 PyErr_NoMemory(); 1379 return NULL; 1380 } 1381 for (i = 0; i < argc; i++) { 1382 if (!PyArg_Parse((*getitem)(argv, i), 1383 "s;argv must be list of strings", 1384 &argvlist[i])) 1385 { 1386 goto fail_1; 1387 } 1388 } 1389 argvlist[argc] = NULL; 1390 1391 i = PyMapping_Size(env); 1392 envlist = PyMem_NEW(char *, i + 1); 1393 if (envlist == NULL) { 1394 PyErr_NoMemory(); 1395 goto fail_1; 1396 } 1397 envc = 0; 1398 keys = PyMapping_Keys(env); 1399 vals = PyMapping_Values(env); 1400 if (!keys || !vals) 1401 goto fail_2; 1402 1403 for (pos = 0; pos < i; pos++) { 1404 char *p, *k, *v; 1405 1406 key = PyList_GetItem(keys, pos); 1407 val = PyList_GetItem(vals, pos); 1408 if (!key || !val) 1409 goto fail_2; 1410 1411 if (!PyArg_Parse(key, "s;non-string key in env", &k) || 1412 !PyArg_Parse(val, "s;non-string value in env", &v)) 1413 { 1414 goto fail_2; 1415 } 1416 1417#if defined(PYOS_OS2) 1418 /* Omit Pseudo-Env Vars that Would Confuse Programs if Passed On */ 1419 if (stricmp(k, "BEGINLIBPATH") != 0 && stricmp(k, "ENDLIBPATH") != 0) { 1420#endif 1421 p = PyMem_NEW(char, PyString_Size(key)+PyString_Size(val) + 2); 1422 if (p == NULL) { 1423 PyErr_NoMemory(); 1424 goto fail_2; 1425 } 1426 sprintf(p, "%s=%s", k, v); 1427 envlist[envc++] = p; 1428#if defined(PYOS_OS2) 1429 } 1430#endif 1431 } 1432 envlist[envc] = 0; 1433 1434 1435#ifdef BAD_EXEC_PROTOTYPES 1436 execve(path, (const char **)argvlist, envlist); 1437#else /* BAD_EXEC_PROTOTYPES */ 1438 execve(path, argvlist, envlist); 1439#endif /* BAD_EXEC_PROTOTYPES */ 1440 1441 /* If we get here it's definitely an error */ 1442 1443 (void) posix_error(); 1444 1445 fail_2: 1446 while (--envc >= 0) 1447 PyMem_DEL(envlist[envc]); 1448 PyMem_DEL(envlist); 1449 fail_1: 1450 PyMem_DEL(argvlist); 1451 Py_XDECREF(vals); 1452 Py_XDECREF(keys); 1453 return NULL; 1454} 1455#endif /* HAVE_EXECV */ 1456 1457 1458#ifdef HAVE_SPAWNV 1459static char posix_spawnv__doc__[] = 1460"spawnv(mode, path, args)\n\ 1461Execute an executable path with arguments, replacing current process.\n\ 1462\n\ 1463 mode: mode of process creation\n\ 1464 path: path of executable file\n\ 1465 args: tuple or list of strings"; 1466 1467static PyObject * 1468posix_spawnv(PyObject *self, PyObject *args) 1469{ 1470 char *path; 1471 PyObject *argv; 1472 char **argvlist; 1473 int mode, i, argc; 1474 intptr_t spawnval; 1475 PyObject *(*getitem)(PyObject *, int); 1476 1477 /* spawnv has three arguments: (mode, path, argv), where 1478 argv is a list or tuple of strings. */ 1479 1480 if (!PyArg_ParseTuple(args, "isO:spawnv", &mode, &path, &argv)) 1481 return NULL; 1482 if (PyList_Check(argv)) { 1483 argc = PyList_Size(argv); 1484 getitem = PyList_GetItem; 1485 } 1486 else if (PyTuple_Check(argv)) { 1487 argc = PyTuple_Size(argv); 1488 getitem = PyTuple_GetItem; 1489 } 1490 else { 1491 PyErr_SetString(PyExc_TypeError, "argv must be tuple or list"); 1492 return NULL; 1493 } 1494 1495 argvlist = PyMem_NEW(char *, argc+1); 1496 if (argvlist == NULL) 1497 return NULL; 1498 for (i = 0; i < argc; i++) { 1499 if (!PyArg_Parse((*getitem)(argv, i), "s", &argvlist[i])) { 1500 PyMem_DEL(argvlist); 1501 PyErr_SetString(PyExc_TypeError, 1502 "all arguments must be strings"); 1503 return NULL; 1504 } 1505 } 1506 argvlist[argc] = NULL; 1507 1508 if (mode == _OLD_P_OVERLAY) 1509 mode = _P_OVERLAY; 1510 spawnval = _spawnv(mode, path, argvlist); 1511 1512 PyMem_DEL(argvlist); 1513 1514 if (spawnval == -1) 1515 return posix_error(); 1516 else 1517#if SIZEOF_LONG == SIZEOF_VOID_P 1518 return Py_BuildValue("l", (long) spawnval); 1519#else 1520 return Py_BuildValue("L", (LONG_LONG) spawnval); 1521#endif 1522} 1523 1524 1525static char posix_spawnve__doc__[] = 1526"spawnve(mode, path, args, env)\n\ 1527Execute a path with arguments and environment, replacing current process.\n\ 1528\n\ 1529 mode: mode of process creation\n\ 1530 path: path of executable file\n\ 1531 args: tuple or list of arguments\n\ 1532 env: dictionary of strings mapping to strings"; 1533 1534static PyObject * 1535posix_spawnve(PyObject *self, PyObject *args) 1536{ 1537 char *path; 1538 PyObject *argv, *env; 1539 char **argvlist; 1540 char **envlist; 1541 PyObject *key, *val, *keys=NULL, *vals=NULL, *res=NULL; 1542 int mode, i, pos, argc, envc; 1543 intptr_t spawnval; 1544 PyObject *(*getitem)(PyObject *, int); 1545 1546 /* spawnve has four arguments: (mode, path, argv, env), where 1547 argv is a list or tuple of strings and env is a dictionary 1548 like posix.environ. */ 1549 1550 if (!PyArg_ParseTuple(args, "isOO:spawnve", &mode, &path, &argv, &env)) 1551 return NULL; 1552 if (PyList_Check(argv)) { 1553 argc = PyList_Size(argv); 1554 getitem = PyList_GetItem; 1555 } 1556 else if (PyTuple_Check(argv)) { 1557 argc = PyTuple_Size(argv); 1558 getitem = PyTuple_GetItem; 1559 } 1560 else { 1561 PyErr_SetString(PyExc_TypeError, "argv must be tuple or list"); 1562 return NULL; 1563 } 1564 if (!PyMapping_Check(env)) { 1565 PyErr_SetString(PyExc_TypeError, "env must be mapping object"); 1566 return NULL; 1567 } 1568 1569 argvlist = PyMem_NEW(char *, argc+1); 1570 if (argvlist == NULL) { 1571 PyErr_NoMemory(); 1572 return NULL; 1573 } 1574 for (i = 0; i < argc; i++) { 1575 if (!PyArg_Parse((*getitem)(argv, i), 1576 "s;argv must be list of strings", 1577 &argvlist[i])) 1578 { 1579 goto fail_1; 1580 } 1581 } 1582 argvlist[argc] = NULL; 1583 1584 i = PyMapping_Size(env); 1585 envlist = PyMem_NEW(char *, i + 1); 1586 if (envlist == NULL) { 1587 PyErr_NoMemory(); 1588 goto fail_1; 1589 } 1590 envc = 0; 1591 keys = PyMapping_Keys(env); 1592 vals = PyMapping_Values(env); 1593 if (!keys || !vals) 1594 goto fail_2; 1595 1596 for (pos = 0; pos < i; pos++) { 1597 char *p, *k, *v; 1598 1599 key = PyList_GetItem(keys, pos); 1600 val = PyList_GetItem(vals, pos); 1601 if (!key || !val) 1602 goto fail_2; 1603 1604 if (!PyArg_Parse(key, "s;non-string key in env", &k) || 1605 !PyArg_Parse(val, "s;non-string value in env", &v)) 1606 { 1607 goto fail_2; 1608 } 1609 p = PyMem_NEW(char, PyString_Size(key)+PyString_Size(val) + 2); 1610 if (p == NULL) { 1611 PyErr_NoMemory(); 1612 goto fail_2; 1613 } 1614 sprintf(p, "%s=%s", k, v); 1615 envlist[envc++] = p; 1616 } 1617 envlist[envc] = 0; 1618 1619 if (mode == _OLD_P_OVERLAY) 1620 mode = _P_OVERLAY; 1621 spawnval = _spawnve(mode, path, argvlist, envlist); 1622 if (spawnval == -1) 1623 (void) posix_error(); 1624 else 1625#if SIZEOF_LONG == SIZEOF_VOID_P 1626 res = Py_BuildValue("l", (long) spawnval); 1627#else 1628 res = Py_BuildValue("L", (LONG_LONG) spawnval); 1629#endif 1630 1631 fail_2: 1632 while (--envc >= 0) 1633 PyMem_DEL(envlist[envc]); 1634 PyMem_DEL(envlist); 1635 fail_1: 1636 PyMem_DEL(argvlist); 1637 Py_XDECREF(vals); 1638 Py_XDECREF(keys); 1639 return res; 1640} 1641#endif /* HAVE_SPAWNV */ 1642 1643 1644#ifdef HAVE_FORK 1645static char posix_fork__doc__[] = 1646"fork() -> pid\n\ 1647Fork a child process.\n\ 1648\n\ 1649Return 0 to child process and PID of child to parent process."; 1650 1651static PyObject * 1652posix_fork(PyObject *self, PyObject *args) 1653{ 1654 int pid; 1655 if (!PyArg_ParseTuple(args, ":fork")) 1656 return NULL; 1657 pid = fork(); 1658 if (pid == -1) 1659 return posix_error(); 1660 if (pid == 0) 1661 PyOS_AfterFork(); 1662 return PyInt_FromLong((long)pid); 1663} 1664#endif 1665 1666#if defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) 1667#ifdef HAVE_PTY_H 1668#include <pty.h> 1669#else 1670#ifdef HAVE_LIBUTIL_H 1671#include <libutil.h> 1672#endif /* HAVE_LIBUTIL_H */ 1673#endif /* HAVE_PTY_H */ 1674#endif /* defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) */ 1675 1676#if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) 1677static char posix_openpty__doc__[] = 1678"openpty() -> (master_fd, slave_fd)\n\ 1679Open a pseudo-terminal, returning open fd's for both master and slave end.\n"; 1680 1681static PyObject * 1682posix_openpty(PyObject *self, PyObject *args) 1683{ 1684 int master_fd, slave_fd; 1685#ifndef HAVE_OPENPTY 1686 char * slave_name; 1687#endif 1688 1689 if (!PyArg_ParseTuple(args, ":openpty")) 1690 return NULL; 1691 1692#ifdef HAVE_OPENPTY 1693 if (openpty(&master_fd, &slave_fd, NULL, NULL, NULL) != 0) 1694 return posix_error(); 1695#else 1696 slave_name = _getpty(&master_fd, O_RDWR, 0666, 0); 1697 if (slave_name == NULL) 1698 return posix_error(); 1699 1700 slave_fd = open(slave_name, O_RDWR); 1701 if (slave_fd < 0) 1702 return posix_error(); 1703#endif /* HAVE_OPENPTY */ 1704 1705 return Py_BuildValue("(ii)", master_fd, slave_fd); 1706 1707} 1708#endif /* defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) */ 1709 1710#ifdef HAVE_FORKPTY 1711static char posix_forkpty__doc__[] = 1712"forkpty() -> (pid, master_fd)\n\ 1713Fork a new process with a new pseudo-terminal as controlling tty.\n\n\ 1714Like fork(), return 0 as pid to child process, and PID of child to parent.\n\ 1715To both, return fd of newly opened pseudo-terminal.\n"; 1716 1717static PyObject * 1718posix_forkpty(PyObject *self, PyObject *args) 1719{ 1720 int master_fd, pid; 1721 1722 if (!PyArg_ParseTuple(args, ":forkpty")) 1723 return NULL; 1724 pid = forkpty(&master_fd, NULL, NULL, NULL); 1725 if (pid == -1) 1726 return posix_error(); 1727 if (pid == 0) 1728 PyOS_AfterFork(); 1729 return Py_BuildValue("(ii)", pid, master_fd); 1730} 1731#endif 1732 1733#ifdef HAVE_GETEGID 1734static char posix_getegid__doc__[] = 1735"getegid() -> egid\n\ 1736Return the current process's effective group id."; 1737 1738static PyObject * 1739posix_getegid(PyObject *self, PyObject *args) 1740{ 1741 if (!PyArg_ParseTuple(args, ":getegid")) 1742 return NULL; 1743 return PyInt_FromLong((long)getegid()); 1744} 1745#endif 1746 1747 1748#ifdef HAVE_GETEUID 1749static char posix_geteuid__doc__[] = 1750"geteuid() -> euid\n\ 1751Return the current process's effective user id."; 1752 1753static PyObject * 1754posix_geteuid(PyObject *self, PyObject *args) 1755{ 1756 if (!PyArg_ParseTuple(args, ":geteuid")) 1757 return NULL; 1758 return PyInt_FromLong((long)geteuid()); 1759} 1760#endif 1761 1762 1763#ifdef HAVE_GETGID 1764static char posix_getgid__doc__[] = 1765"getgid() -> gid\n\ 1766Return the current process's group id."; 1767 1768static PyObject * 1769posix_getgid(PyObject *self, PyObject *args) 1770{ 1771 if (!PyArg_ParseTuple(args, ":getgid")) 1772 return NULL; 1773 return PyInt_FromLong((long)getgid()); 1774} 1775#endif 1776 1777 1778static char posix_getpid__doc__[] = 1779"getpid() -> pid\n\ 1780Return the current process id"; 1781 1782static PyObject * 1783posix_getpid(PyObject *self, PyObject *args) 1784{ 1785 if (!PyArg_ParseTuple(args, ":getpid")) 1786 return NULL; 1787 return PyInt_FromLong((long)getpid()); 1788} 1789 1790 1791#ifdef HAVE_GETGROUPS 1792static char posix_getgroups__doc__[] = "\ 1793getgroups() -> list of group IDs\n\ 1794Return list of supplemental group IDs for the process."; 1795 1796static PyObject * 1797posix_getgroups(PyObject *self, PyObject *args) 1798{ 1799 PyObject *result = NULL; 1800 1801 if (PyArg_ParseTuple(args, ":getgroups")) { 1802#ifdef NGROUPS_MAX 1803#define MAX_GROUPS NGROUPS_MAX 1804#else 1805 /* defined to be 16 on Solaris7, so this should be a small number */ 1806#define MAX_GROUPS 64 1807#endif 1808 gid_t grouplist[MAX_GROUPS]; 1809 int n; 1810 1811 n = getgroups(MAX_GROUPS, grouplist); 1812 if (n < 0) 1813 posix_error(); 1814 else { 1815 result = PyList_New(n); 1816 if (result != NULL) { 1817 PyObject *o; 1818 int i; 1819 for (i = 0; i < n; ++i) { 1820 o = PyInt_FromLong((long)grouplist[i]); 1821 if (o == NULL) { 1822 Py_DECREF(result); 1823 result = NULL; 1824 break; 1825 } 1826 PyList_SET_ITEM(result, i, o); 1827 } 1828 } 1829 } 1830 } 1831 return result; 1832} 1833#endif 1834 1835#ifdef HAVE_GETPGRP 1836static char posix_getpgrp__doc__[] = 1837"getpgrp() -> pgrp\n\ 1838Return the current process group id."; 1839 1840static PyObject * 1841posix_getpgrp(PyObject *self, PyObject *args) 1842{ 1843 if (!PyArg_ParseTuple(args, ":getpgrp")) 1844 return NULL; 1845#ifdef GETPGRP_HAVE_ARG 1846 return PyInt_FromLong((long)getpgrp(0)); 1847#else /* GETPGRP_HAVE_ARG */ 1848 return PyInt_FromLong((long)getpgrp()); 1849#endif /* GETPGRP_HAVE_ARG */ 1850} 1851#endif /* HAVE_GETPGRP */ 1852 1853 1854#ifdef HAVE_SETPGRP 1855static char posix_setpgrp__doc__[] = 1856"setpgrp() -> None\n\ 1857Make this process a session leader."; 1858 1859static PyObject * 1860posix_setpgrp(PyObject *self, PyObject *args) 1861{ 1862 if (!PyArg_ParseTuple(args, ":setpgrp")) 1863 return NULL; 1864#ifdef SETPGRP_HAVE_ARG 1865 if (setpgrp(0, 0) < 0) 1866#else /* SETPGRP_HAVE_ARG */ 1867 if (setpgrp() < 0) 1868#endif /* SETPGRP_HAVE_ARG */ 1869 return posix_error(); 1870 Py_INCREF(Py_None); 1871 return Py_None; 1872} 1873 1874#endif /* HAVE_SETPGRP */ 1875 1876#ifdef HAVE_GETPPID 1877static char posix_getppid__doc__[] = 1878"getppid() -> ppid\n\ 1879Return the parent's process id."; 1880 1881static PyObject * 1882posix_getppid(PyObject *self, PyObject *args) 1883{ 1884 if (!PyArg_ParseTuple(args, ":getppid")) 1885 return NULL; 1886 return PyInt_FromLong((long)getppid()); 1887} 1888#endif 1889 1890 1891#ifdef HAVE_GETLOGIN 1892static char posix_getlogin__doc__[] = "\ 1893getlogin() -> string\n\ 1894Return the actual login name."; 1895 1896static PyObject * 1897posix_getlogin(PyObject *self, PyObject *args) 1898{ 1899 PyObject *result = NULL; 1900 1901 if (PyArg_ParseTuple(args, ":getlogin")) { 1902 char *name = getlogin(); 1903 1904 if (name == NULL) 1905 posix_error(); 1906 else 1907 result = PyString_FromString(name); 1908 } 1909 return result; 1910} 1911#endif 1912 1913#ifdef HAVE_GETUID 1914static char posix_getuid__doc__[] = 1915"getuid() -> uid\n\ 1916Return the current process's user id."; 1917 1918static PyObject * 1919posix_getuid(PyObject *self, PyObject *args) 1920{ 1921 if (!PyArg_ParseTuple(args, ":getuid")) 1922 return NULL; 1923 return PyInt_FromLong((long)getuid()); 1924} 1925#endif 1926 1927 1928#ifdef HAVE_KILL 1929static char posix_kill__doc__[] = 1930"kill(pid, sig) -> None\n\ 1931Kill a process with a signal."; 1932 1933static PyObject * 1934posix_kill(PyObject *self, PyObject *args) 1935{ 1936 int pid, sig; 1937 if (!PyArg_ParseTuple(args, "ii:kill", &pid, &sig)) 1938 return NULL; 1939#if defined(PYOS_OS2) 1940 if (sig == XCPT_SIGNAL_INTR || sig == XCPT_SIGNAL_BREAK) { 1941 APIRET rc; 1942 if ((rc = DosSendSignalException(pid, sig)) != NO_ERROR) 1943 return os2_error(rc); 1944 1945 } else if (sig == XCPT_SIGNAL_KILLPROC) { 1946 APIRET rc; 1947 if ((rc = DosKillProcess(DKP_PROCESS, pid)) != NO_ERROR) 1948 return os2_error(rc); 1949 1950 } else 1951 return NULL; /* Unrecognized Signal Requested */ 1952#else 1953 if (kill(pid, sig) == -1) 1954 return posix_error(); 1955#endif 1956 Py_INCREF(Py_None); 1957 return Py_None; 1958} 1959#endif 1960 1961#ifdef HAVE_PLOCK 1962 1963#ifdef HAVE_SYS_LOCK_H 1964#include <sys/lock.h> 1965#endif 1966 1967static char posix_plock__doc__[] = 1968"plock(op) -> None\n\ 1969Lock program segments into memory."; 1970 1971static PyObject * 1972posix_plock(PyObject *self, PyObject *args) 1973{ 1974 int op; 1975 if (!PyArg_ParseTuple(args, "i:plock", &op)) 1976 return NULL; 1977 if (plock(op) == -1) 1978 return posix_error(); 1979 Py_INCREF(Py_None); 1980 return Py_None; 1981} 1982#endif 1983 1984 1985#ifdef HAVE_POPEN 1986static char posix_popen__doc__[] = 1987"popen(command [, mode='r' [, bufsize]]) -> pipe\n\ 1988Open a pipe to/from a command returning a file object."; 1989 1990#if defined(PYOS_OS2) 1991static int 1992async_system(const char *command) 1993{ 1994 char *p, errormsg[256], args[1024]; 1995 RESULTCODES rcodes; 1996 APIRET rc; 1997 char *shell = getenv("COMSPEC"); 1998 if (!shell) 1999 shell = "cmd"; 2000 2001 strcpy(args, shell); 2002 p = &args[ strlen(args)+1 ]; 2003 strcpy(p, "/c "); 2004 strcat(p, command); 2005 p += strlen(p) + 1; 2006 *p = '\0'; 2007 2008 rc = DosExecPgm(errormsg, sizeof(errormsg), 2009 EXEC_ASYNC, /* Execute Async w/o Wait for Results */ 2010 args, 2011 NULL, /* Inherit Parent's Environment */ 2012 &rcodes, shell); 2013 return rc; 2014} 2015 2016static FILE * 2017popen(const char *command, const char *mode, int pipesize, int *err) 2018{ 2019 HFILE rhan, whan; 2020 FILE *retfd = NULL; 2021 APIRET rc = DosCreatePipe(&rhan, &whan, pipesize); 2022 2023 if (rc != NO_ERROR) { 2024 *err = rc; 2025 return NULL; /* ERROR - Unable to Create Anon Pipe */ 2026 } 2027 2028 if (strchr(mode, 'r') != NULL) { /* Treat Command as a Data Source */ 2029 int oldfd = dup(1); /* Save STDOUT Handle in Another Handle */ 2030 2031 DosEnterCritSec(); /* Stop Other Threads While Changing Handles */ 2032 close(1); /* Make STDOUT Available for Reallocation */ 2033 2034 if (dup2(whan, 1) == 0) { /* Connect STDOUT to Pipe Write Side */ 2035 DosClose(whan); /* Close Now-Unused Pipe Write Handle */ 2036 2037 if (async_system(command) == NO_ERROR) 2038 retfd = fdopen(rhan, mode); /* And Return Pipe Read Handle */ 2039 } 2040 2041 dup2(oldfd, 1); /* Reconnect STDOUT to Original Handle */ 2042 DosExitCritSec(); /* Now Allow Other Threads to Run */ 2043 2044 close(oldfd); /* And Close Saved STDOUT Handle */ 2045 return retfd; /* Return fd of Pipe or NULL if Error */ 2046 2047 } else if (strchr(mode, 'w')) { /* Treat Command as a Data Sink */ 2048 int oldfd = dup(0); /* Save STDIN Handle in Another Handle */ 2049 2050 DosEnterCritSec(); /* Stop Other Threads While Changing Handles */ 2051 close(0); /* Make STDIN Available for Reallocation */ 2052 2053 if (dup2(rhan, 0) == 0) { /* Connect STDIN to Pipe Read Side */ 2054 DosClose(rhan); /* Close Now-Unused Pipe Read Handle */ 2055 2056 if (async_system(command) == NO_ERROR) 2057 retfd = fdopen(whan, mode); /* And Return Pipe Write Handle */ 2058 } 2059 2060 dup2(oldfd, 0); /* Reconnect STDIN to Original Handle */ 2061 DosExitCritSec(); /* Now Allow Other Threads to Run */ 2062 2063 close(oldfd); /* And Close Saved STDIN Handle */ 2064 return retfd; /* Return fd of Pipe or NULL if Error */ 2065 2066 } else { 2067 *err = ERROR_INVALID_ACCESS; 2068 return NULL; /* ERROR - Invalid Mode (Neither Read nor Write) */ 2069 } 2070} 2071 2072static PyObject * 2073posix_popen(PyObject *self, PyObject *args) 2074{ 2075 char *name; 2076 char *mode = "r"; 2077 int err, bufsize = -1; 2078 FILE *fp; 2079 PyObject *f; 2080 if (!PyArg_ParseTuple(args, "s|si:popen", &name, &mode, &bufsize)) 2081 return NULL; 2082 Py_BEGIN_ALLOW_THREADS 2083 fp = popen(name, mode, (bufsize > 0) ? bufsize : 4096, &err); 2084 Py_END_ALLOW_THREADS 2085 if (fp == NULL) 2086 return os2_error(err); 2087 2088 f = PyFile_FromFile(fp, name, mode, fclose); 2089 if (f != NULL) 2090 PyFile_SetBufSize(f, bufsize); 2091 return f; 2092} 2093 2094#elif defined(MS_WIN32) 2095 2096/* 2097 * Portable 'popen' replacement for Win32. 2098 * 2099 * Written by Bill Tutt <billtut@microsoft.com>. Minor tweaks 2100 * and 2.0 integration by Fredrik Lundh <fredrik@pythonware.com> 2101 * Return code handling by David Bolen <db3l@fitlinxx.com>. 2102 */ 2103 2104#include <malloc.h> 2105#include <io.h> 2106#include <fcntl.h> 2107 2108/* These tell _PyPopen() wether to return 1, 2, or 3 file objects. */ 2109#define POPEN_1 1 2110#define POPEN_2 2 2111#define POPEN_3 3 2112#define POPEN_4 4 2113 2114static PyObject *_PyPopen(char *, int, int); 2115static int _PyPclose(FILE *file); 2116 2117/* 2118 * Internal dictionary mapping popen* file pointers to process handles, 2119 * for use when retrieving the process exit code. See _PyPclose() below 2120 * for more information on this dictionary's use. 2121 */ 2122static PyObject *_PyPopenProcs = NULL; 2123 2124 2125/* popen that works from a GUI. 2126 * 2127 * The result of this function is a pipe (file) connected to the 2128 * processes stdin or stdout, depending on the requested mode. 2129 */ 2130 2131static PyObject * 2132posix_popen(PyObject *self, PyObject *args) 2133{ 2134 PyObject *f, *s; 2135 int tm = 0; 2136 2137 char *cmdstring; 2138 char *mode = "r"; 2139 int bufsize = -1; 2140 if (!PyArg_ParseTuple(args, "s|si:popen", &cmdstring, &mode, &bufsize)) 2141 return NULL; 2142 2143 s = PyTuple_New(0); 2144 2145 if (*mode == 'r') 2146 tm = _O_RDONLY; 2147 else if (*mode != 'w') { 2148 PyErr_SetString(PyExc_ValueError, "mode must be 'r' or 'w'"); 2149 return NULL; 2150 } else 2151 tm = _O_WRONLY; 2152 2153 if (bufsize != -1) { 2154 PyErr_SetString(PyExc_ValueError, "bufsize must be -1"); 2155 return NULL; 2156 } 2157 2158 if (*(mode+1) == 't') 2159 f = _PyPopen(cmdstring, tm | _O_TEXT, POPEN_1); 2160 else if (*(mode+1) == 'b') 2161 f = _PyPopen(cmdstring, tm | _O_BINARY, POPEN_1); 2162 else 2163 f = _PyPopen(cmdstring, tm | _O_TEXT, POPEN_1); 2164 2165 return f; 2166} 2167 2168/* Variation on win32pipe.popen 2169 * 2170 * The result of this function is a pipe (file) connected to the 2171 * process's stdin, and a pipe connected to the process's stdout. 2172 */ 2173 2174static PyObject * 2175win32_popen2(PyObject *self, PyObject *args) 2176{ 2177 PyObject *f; 2178 int tm=0; 2179 2180 char *cmdstring; 2181 char *mode = "t"; 2182 int bufsize = -1; 2183 if (!PyArg_ParseTuple(args, "s|si:popen2", &cmdstring, &mode, &bufsize)) 2184 return NULL; 2185 2186 if (*mode == 't') 2187 tm = _O_TEXT; 2188 else if (*mode != 'b') { 2189 PyErr_SetString(PyExc_ValueError, "mode must be 't' or 'b'"); 2190 return NULL; 2191 } else 2192 tm = _O_BINARY; 2193 2194 if (bufsize != -1) { 2195 PyErr_SetString(PyExc_ValueError, "bufsize must be -1"); 2196 return NULL; 2197 } 2198 2199 f = _PyPopen(cmdstring, tm, POPEN_2); 2200 2201 return f; 2202} 2203 2204/* 2205 * Variation on <om win32pipe.popen> 2206 * 2207 * The result of this function is 3 pipes - the process's stdin, 2208 * stdout and stderr 2209 */ 2210 2211static PyObject * 2212win32_popen3(PyObject *self, PyObject *args) 2213{ 2214 PyObject *f; 2215 int tm = 0; 2216 2217 char *cmdstring; 2218 char *mode = "t"; 2219 int bufsize = -1; 2220 if (!PyArg_ParseTuple(args, "s|si:popen3", &cmdstring, &mode, &bufsize)) 2221 return NULL; 2222 2223 if (*mode == 't') 2224 tm = _O_TEXT; 2225 else if (*mode != 'b') { 2226 PyErr_SetString(PyExc_ValueError, "mode must be 't' or 'b'"); 2227 return NULL; 2228 } else 2229 tm = _O_BINARY; 2230 2231 if (bufsize != -1) { 2232 PyErr_SetString(PyExc_ValueError, "bufsize must be -1"); 2233 return NULL; 2234 } 2235 2236 f = _PyPopen(cmdstring, tm, POPEN_3); 2237 2238 return f; 2239} 2240 2241/* 2242 * Variation on win32pipe.popen 2243 * 2244 * The result of this function is 2 pipes - the processes stdin, 2245 * and stdout+stderr combined as a single pipe. 2246 */ 2247 2248static PyObject * 2249win32_popen4(PyObject *self, PyObject *args) 2250{ 2251 PyObject *f; 2252 int tm = 0; 2253 2254 char *cmdstring; 2255 char *mode = "t"; 2256 int bufsize = -1; 2257 if (!PyArg_ParseTuple(args, "s|si:popen4", &cmdstring, &mode, &bufsize)) 2258 return NULL; 2259 2260 if (*mode == 't') 2261 tm = _O_TEXT; 2262 else if (*mode != 'b') { 2263 PyErr_SetString(PyExc_ValueError, "mode must be 't' or 'b'"); 2264 return NULL; 2265 } else 2266 tm = _O_BINARY; 2267 2268 if (bufsize != -1) { 2269 PyErr_SetString(PyExc_ValueError, "bufsize must be -1"); 2270 return NULL; 2271 } 2272 2273 f = _PyPopen(cmdstring, tm, POPEN_4); 2274 2275 return f; 2276} 2277 2278static int 2279_PyPopenCreateProcess(char *cmdstring, 2280 HANDLE hStdin, 2281 HANDLE hStdout, 2282 HANDLE hStderr, 2283 HANDLE *hProcess) 2284{ 2285 PROCESS_INFORMATION piProcInfo; 2286 STARTUPINFO siStartInfo; 2287 char *s1,*s2, *s3 = " /c "; 2288 const char *szConsoleSpawn = "w9xpopen.exe \""; 2289 int i; 2290 int x; 2291 2292 if (i = GetEnvironmentVariable("COMSPEC",NULL,0)) { 2293 s1 = (char *)_alloca(i); 2294 if (!(x = GetEnvironmentVariable("COMSPEC", s1, i))) 2295 return x; 2296 if (GetVersion() < 0x80000000) { 2297 /* 2298 * NT/2000 2299 */ 2300 x = i + strlen(s3) + strlen(cmdstring) + 1; 2301 s2 = (char *)_alloca(x); 2302 ZeroMemory(s2, x); 2303 sprintf(s2, "%s%s%s", s1, s3, cmdstring); 2304 } 2305 else { 2306 /* 2307 * Oh gag, we're on Win9x. Use the workaround listed in 2308 * KB: Q150956 2309 */ 2310 char modulepath[256]; 2311 GetModuleFileName(NULL, modulepath, sizeof(modulepath)); 2312 for (i = x = 0; modulepath[i]; i++) 2313 if (modulepath[i] == '\\') 2314 x = i+1; 2315 modulepath[x] = '\0'; 2316 x = i + strlen(s3) + strlen(cmdstring) + 1 + 2317 strlen(modulepath) + 2318 strlen(szConsoleSpawn) + 1; 2319 s2 = (char *)_alloca(x); 2320 ZeroMemory(s2, x); 2321 sprintf( 2322 s2, 2323 "%s%s%s%s%s\"", 2324 modulepath, 2325 szConsoleSpawn, 2326 s1, 2327 s3, 2328 cmdstring); 2329 } 2330 } 2331 2332 /* Could be an else here to try cmd.exe / command.com in the path 2333 Now we'll just error out.. */ 2334 else 2335 return -1; 2336 2337 ZeroMemory(&siStartInfo, sizeof(STARTUPINFO)); 2338 siStartInfo.cb = sizeof(STARTUPINFO); 2339 siStartInfo.dwFlags = STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW; 2340 siStartInfo.hStdInput = hStdin; 2341 siStartInfo.hStdOutput = hStdout; 2342 siStartInfo.hStdError = hStderr; 2343 siStartInfo.wShowWindow = SW_HIDE; 2344 2345 if (CreateProcess(NULL, 2346 s2, 2347 NULL, 2348 NULL, 2349 TRUE, 2350 CREATE_NEW_CONSOLE, 2351 NULL, 2352 NULL, 2353 &siStartInfo, 2354 &piProcInfo) ) { 2355 /* Close the handles now so anyone waiting is woken. */ 2356 CloseHandle(piProcInfo.hThread); 2357 2358 /* Return process handle */ 2359 *hProcess = piProcInfo.hProcess; 2360 return TRUE; 2361 } 2362 return FALSE; 2363} 2364 2365/* The following code is based off of KB: Q190351 */ 2366 2367static PyObject * 2368_PyPopen(char *cmdstring, int mode, int n) 2369{ 2370 HANDLE hChildStdinRd, hChildStdinWr, hChildStdoutRd, hChildStdoutWr, 2371 hChildStderrRd, hChildStderrWr, hChildStdinWrDup, hChildStdoutRdDup, 2372 hChildStderrRdDup, hProcess; /* hChildStdoutWrDup; */ 2373 2374 SECURITY_ATTRIBUTES saAttr; 2375 BOOL fSuccess; 2376 int fd1, fd2, fd3; 2377 FILE *f1, *f2, *f3; 2378 long file_count; 2379 PyObject *f; 2380 2381 saAttr.nLength = sizeof(SECURITY_ATTRIBUTES); 2382 saAttr.bInheritHandle = TRUE; 2383 saAttr.lpSecurityDescriptor = NULL; 2384 2385 if (!CreatePipe(&hChildStdinRd, &hChildStdinWr, &saAttr, 0)) 2386 return win32_error("CreatePipe", NULL); 2387 2388 /* Create new output read handle and the input write handle. Set 2389 * the inheritance properties to FALSE. Otherwise, the child inherits 2390 * the these handles; resulting in non-closeable handles to the pipes 2391 * being created. */ 2392 fSuccess = DuplicateHandle(GetCurrentProcess(), hChildStdinWr, 2393 GetCurrentProcess(), &hChildStdinWrDup, 0, 2394 FALSE, 2395 DUPLICATE_SAME_ACCESS); 2396 if (!fSuccess) 2397 return win32_error("DuplicateHandle", NULL); 2398 2399 /* Close the inheritable version of ChildStdin 2400 that we're using. */ 2401 CloseHandle(hChildStdinWr); 2402 2403 if (!CreatePipe(&hChildStdoutRd, &hChildStdoutWr, &saAttr, 0)) 2404 return win32_error("CreatePipe", NULL); 2405 2406 fSuccess = DuplicateHandle(GetCurrentProcess(), hChildStdoutRd, 2407 GetCurrentProcess(), &hChildStdoutRdDup, 0, 2408 FALSE, DUPLICATE_SAME_ACCESS); 2409 if (!fSuccess) 2410 return win32_error("DuplicateHandle", NULL); 2411 2412 /* Close the inheritable version of ChildStdout 2413 that we're using. */ 2414 CloseHandle(hChildStdoutRd); 2415 2416 if (n != POPEN_4) { 2417 if (!CreatePipe(&hChildStderrRd, &hChildStderrWr, &saAttr, 0)) 2418 return win32_error("CreatePipe", NULL); 2419 fSuccess = DuplicateHandle(GetCurrentProcess(), 2420 hChildStderrRd, 2421 GetCurrentProcess(), 2422 &hChildStderrRdDup, 0, 2423 FALSE, DUPLICATE_SAME_ACCESS); 2424 if (!fSuccess) 2425 return win32_error("DuplicateHandle", NULL); 2426 /* Close the inheritable version of ChildStdErr that we're using. */ 2427 CloseHandle(hChildStderrRd); 2428 } 2429 2430 switch (n) { 2431 case POPEN_1: 2432 switch (mode & (_O_RDONLY | _O_TEXT | _O_BINARY | _O_WRONLY)) { 2433 case _O_WRONLY | _O_TEXT: 2434 /* Case for writing to child Stdin in text mode. */ 2435 fd1 = _open_osfhandle((long)hChildStdinWrDup, mode); 2436 f1 = _fdopen(fd1, "w"); 2437 f = PyFile_FromFile(f1, cmdstring, "w", _PyPclose); 2438 PyFile_SetBufSize(f, 0); 2439 /* We don't care about these pipes anymore, so close them. */ 2440 CloseHandle(hChildStdoutRdDup); 2441 CloseHandle(hChildStderrRdDup); 2442 break; 2443 2444 case _O_RDONLY | _O_TEXT: 2445 /* Case for reading from child Stdout in text mode. */ 2446 fd1 = _open_osfhandle((long)hChildStdoutRdDup, mode); 2447 f1 = _fdopen(fd1, "r"); 2448 f = PyFile_FromFile(f1, cmdstring, "r", _PyPclose); 2449 PyFile_SetBufSize(f, 0); 2450 /* We don't care about these pipes anymore, so close them. */ 2451 CloseHandle(hChildStdinWrDup); 2452 CloseHandle(hChildStderrRdDup); 2453 break; 2454 2455 case _O_RDONLY | _O_BINARY: 2456 /* Case for readinig from child Stdout in binary mode. */ 2457 fd1 = _open_osfhandle((long)hChildStdoutRdDup, mode); 2458 f1 = _fdopen(fd1, "rb"); 2459 f = PyFile_FromFile(f1, cmdstring, "rb", _PyPclose); 2460 PyFile_SetBufSize(f, 0); 2461 /* We don't care about these pipes anymore, so close them. */ 2462 CloseHandle(hChildStdinWrDup); 2463 CloseHandle(hChildStderrRdDup); 2464 break; 2465 2466 case _O_WRONLY | _O_BINARY: 2467 /* Case for writing to child Stdin in binary mode. */ 2468 fd1 = _open_osfhandle((long)hChildStdinWrDup, mode); 2469 f1 = _fdopen(fd1, "wb"); 2470 f = PyFile_FromFile(f1, cmdstring, "wb", _PyPclose); 2471 PyFile_SetBufSize(f, 0); 2472 /* We don't care about these pipes anymore, so close them. */ 2473 CloseHandle(hChildStdoutRdDup); 2474 CloseHandle(hChildStderrRdDup); 2475 break; 2476 } 2477 file_count = 1; 2478 break; 2479 2480 case POPEN_2: 2481 case POPEN_4: 2482 { 2483 char *m1, *m2; 2484 PyObject *p1, *p2; 2485 2486 if (mode && _O_TEXT) { 2487 m1 = "r"; 2488 m2 = "w"; 2489 } else { 2490 m1 = "rb"; 2491 m2 = "wb"; 2492 } 2493 2494 fd1 = _open_osfhandle((long)hChildStdinWrDup, mode); 2495 f1 = _fdopen(fd1, m2); 2496 fd2 = _open_osfhandle((long)hChildStdoutRdDup, mode); 2497 f2 = _fdopen(fd2, m1); 2498 p1 = PyFile_FromFile(f1, cmdstring, m2, _PyPclose); 2499 PyFile_SetBufSize(p1, 0); 2500 p2 = PyFile_FromFile(f2, cmdstring, m1, _PyPclose); 2501 PyFile_SetBufSize(p2, 0); 2502 2503 if (n != 4) 2504 CloseHandle(hChildStderrRdDup); 2505 2506 f = Py_BuildValue("OO",p1,p2); 2507 file_count = 2; 2508 break; 2509 } 2510 2511 case POPEN_3: 2512 { 2513 char *m1, *m2; 2514 PyObject *p1, *p2, *p3; 2515 2516 if (mode && _O_TEXT) { 2517 m1 = "r"; 2518 m2 = "w"; 2519 } else { 2520 m1 = "rb"; 2521 m2 = "wb"; 2522 } 2523 2524 fd1 = _open_osfhandle((long)hChildStdinWrDup, mode); 2525 f1 = _fdopen(fd1, m2); 2526 fd2 = _open_osfhandle((long)hChildStdoutRdDup, mode); 2527 f2 = _fdopen(fd2, m1); 2528 fd3 = _open_osfhandle((long)hChildStderrRdDup, mode); 2529 f3 = _fdopen(fd3, m1); 2530 p1 = PyFile_FromFile(f1, cmdstring, m2, _PyPclose); 2531 p2 = PyFile_FromFile(f2, cmdstring, m1, _PyPclose); 2532 p3 = PyFile_FromFile(f3, cmdstring, m1, _PyPclose); 2533 PyFile_SetBufSize(p1, 0); 2534 PyFile_SetBufSize(p2, 0); 2535 PyFile_SetBufSize(p3, 0); 2536 f = Py_BuildValue("OOO",p1,p2,p3); 2537 file_count = 3; 2538 break; 2539 } 2540 } 2541 2542 if (n == POPEN_4) { 2543 if (!_PyPopenCreateProcess(cmdstring, 2544 hChildStdinRd, 2545 hChildStdoutWr, 2546 hChildStdoutWr, 2547 &hProcess)) 2548 return win32_error("CreateProcess", NULL); 2549 } 2550 else { 2551 if (!_PyPopenCreateProcess(cmdstring, 2552 hChildStdinRd, 2553 hChildStdoutWr, 2554 hChildStderrWr, 2555 &hProcess)) 2556 return win32_error("CreateProcess", NULL); 2557 } 2558 2559 /* 2560 * Insert the files we've created into the process dictionary 2561 * all referencing the list with the process handle and the 2562 * initial number of files (see description below in _PyPclose). 2563 * Since if _PyPclose later tried to wait on a process when all 2564 * handles weren't closed, it could create a deadlock with the 2565 * child, we spend some energy here to try to ensure that we 2566 * either insert all file handles into the dictionary or none 2567 * at all. It's a little clumsy with the various popen modes 2568 * and variable number of files involved. 2569 */ 2570 if (!_PyPopenProcs) { 2571 _PyPopenProcs = PyDict_New(); 2572 } 2573 2574 if (_PyPopenProcs) { 2575 PyObject *procObj, *hProcessObj, *intObj, *fileObj[3]; 2576 int ins_rc[3]; 2577 2578 fileObj[0] = fileObj[1] = fileObj[2] = NULL; 2579 ins_rc[0] = ins_rc[1] = ins_rc[2] = 0; 2580 2581 procObj = PyList_New(2); 2582 hProcessObj = PyLong_FromVoidPtr(hProcess); 2583 intObj = PyInt_FromLong(file_count); 2584 2585 if (procObj && hProcessObj && intObj) { 2586 PyList_SetItem(procObj,0,hProcessObj); 2587 PyList_SetItem(procObj,1,intObj); 2588 2589 fileObj[0] = PyLong_FromVoidPtr(f1); 2590 if (fileObj[0]) { 2591 ins_rc[0] = PyDict_SetItem(_PyPopenProcs, 2592 fileObj[0], 2593 procObj); 2594 } 2595 if (file_count >= 2) { 2596 fileObj[1] = PyLong_FromVoidPtr(f2); 2597 if (fileObj[1]) { 2598 ins_rc[1] = PyDict_SetItem(_PyPopenProcs, 2599 fileObj[1], 2600 procObj); 2601 } 2602 } 2603 if (file_count >= 3) { 2604 fileObj[2] = PyLong_FromVoidPtr(f3); 2605 if (fileObj[2]) { 2606 ins_rc[2] = PyDict_SetItem(_PyPopenProcs, 2607 fileObj[2], 2608 procObj); 2609 } 2610 } 2611 2612 if (ins_rc[0] < 0 || !fileObj[0] || 2613 ins_rc[1] < 0 || (file_count > 1 && !fileObj[1]) || 2614 ins_rc[2] < 0 || (file_count > 2 && !fileObj[2])) { 2615 /* Something failed - remove any dictionary 2616 * entries that did make it. 2617 */ 2618 if (!ins_rc[0] && fileObj[0]) { 2619 PyDict_DelItem(_PyPopenProcs, 2620 fileObj[0]); 2621 } 2622 if (!ins_rc[1] && fileObj[1]) { 2623 PyDict_DelItem(_PyPopenProcs, 2624 fileObj[1]); 2625 } 2626 if (!ins_rc[2] && fileObj[2]) { 2627 PyDict_DelItem(_PyPopenProcs, 2628 fileObj[2]); 2629 } 2630 } 2631 } 2632 2633 /* 2634 * Clean up our localized references for the dictionary keys 2635 * and value since PyDict_SetItem will Py_INCREF any copies 2636 * that got placed in the dictionary. 2637 */ 2638 Py_XDECREF(procObj); 2639 Py_XDECREF(fileObj[0]); 2640 Py_XDECREF(fileObj[1]); 2641 Py_XDECREF(fileObj[2]); 2642 } 2643 2644 /* Child is launched. Close the parents copy of those pipe 2645 * handles that only the child should have open. You need to 2646 * make sure that no handles to the write end of the output pipe 2647 * are maintained in this process or else the pipe will not close 2648 * when the child process exits and the ReadFile will hang. */ 2649 2650 if (!CloseHandle(hChildStdinRd)) 2651 return win32_error("CloseHandle", NULL); 2652 2653 if (!CloseHandle(hChildStdoutWr)) 2654 return win32_error("CloseHandle", NULL); 2655 2656 if ((n != 4) && (!CloseHandle(hChildStderrWr))) 2657 return win32_error("CloseHandle", NULL); 2658 2659 return f; 2660} 2661 2662/* 2663 * Wrapper for fclose() to use for popen* files, so we can retrieve the 2664 * exit code for the child process and return as a result of the close. 2665 * 2666 * This function uses the _PyPopenProcs dictionary in order to map the 2667 * input file pointer to information about the process that was 2668 * originally created by the popen* call that created the file pointer. 2669 * The dictionary uses the file pointer as a key (with one entry 2670 * inserted for each file returned by the original popen* call) and a 2671 * single list object as the value for all files from a single call. 2672 * The list object contains the Win32 process handle at [0], and a file 2673 * count at [1], which is initialized to the total number of file 2674 * handles using that list. 2675 * 2676 * This function closes whichever handle it is passed, and decrements 2677 * the file count in the dictionary for the process handle pointed to 2678 * by this file. On the last close (when the file count reaches zero), 2679 * this function will wait for the child process and then return its 2680 * exit code as the result of the close() operation. This permits the 2681 * files to be closed in any order - it is always the close() of the 2682 * final handle that will return the exit code. 2683 */ 2684static int _PyPclose(FILE *file) 2685{ 2686 int result; 2687 DWORD exit_code; 2688 HANDLE hProcess; 2689 PyObject *procObj, *hProcessObj, *intObj, *fileObj; 2690 long file_count; 2691 2692 /* Close the file handle first, to ensure it can't block the 2693 * child from exiting if it's the last handle. 2694 */ 2695 result = fclose(file); 2696 2697 if (_PyPopenProcs) { 2698 if ((fileObj = PyLong_FromVoidPtr(file)) != NULL && 2699 (procObj = PyDict_GetItem(_PyPopenProcs, 2700 fileObj)) != NULL && 2701 (hProcessObj = PyList_GetItem(procObj,0)) != NULL && 2702 (intObj = PyList_GetItem(procObj,1)) != NULL) { 2703 2704 hProcess = PyLong_AsVoidPtr(hProcessObj); 2705 file_count = PyInt_AsLong(intObj); 2706 2707 if (file_count > 1) { 2708 /* Still other files referencing process */ 2709 file_count--; 2710 PyList_SetItem(procObj,1, 2711 PyInt_FromLong(file_count)); 2712 } else { 2713 /* Last file for this process */ 2714 if (result != EOF && 2715 WaitForSingleObject(hProcess, INFINITE) != WAIT_FAILED && 2716 GetExitCodeProcess(hProcess, &exit_code)) { 2717 /* Possible truncation here in 16-bit environments, but 2718 * real exit codes are just the lower byte in any event. 2719 */ 2720 result = exit_code; 2721 } else { 2722 /* Indicate failure - this will cause the file object 2723 * to raise an I/O error and translate the last Win32 2724 * error code from errno. We do have a problem with 2725 * last errors that overlap the normal errno table, 2726 * but that's a consistent problem with the file object. 2727 */ 2728 if (result != EOF) { 2729 /* If the error wasn't from the fclose(), then 2730 * set errno for the file object error handling. 2731 */ 2732 errno = GetLastError(); 2733 } 2734 result = -1; 2735 } 2736 2737 /* Free up the native handle at this point */ 2738 CloseHandle(hProcess); 2739 } 2740 2741 /* Remove this file pointer from dictionary */ 2742 PyDict_DelItem(_PyPopenProcs, fileObj); 2743 2744 if (PyDict_Size(_PyPopenProcs) == 0) { 2745 Py_DECREF(_PyPopenProcs); 2746 _PyPopenProcs = NULL; 2747 } 2748 2749 } /* if object retrieval ok */ 2750 2751 Py_XDECREF(fileObj); 2752 } /* if _PyPopenProcs */ 2753 2754 return result; 2755} 2756#else 2757static PyObject * 2758posix_popen(PyObject *self, PyObject *args) 2759{ 2760 char *name; 2761 char *mode = "r"; 2762 int bufsize = -1; 2763 FILE *fp; 2764 PyObject *f; 2765 if (!PyArg_ParseTuple(args, "s|si:popen", &name, &mode, &bufsize)) 2766 return NULL; 2767 Py_BEGIN_ALLOW_THREADS 2768 fp = popen(name, mode); 2769 Py_END_ALLOW_THREADS 2770 if (fp == NULL) 2771 return posix_error(); 2772 f = PyFile_FromFile(fp, name, mode, pclose); 2773 if (f != NULL) 2774 PyFile_SetBufSize(f, bufsize); 2775 return f; 2776} 2777#endif 2778 2779#endif /* HAVE_POPEN */ 2780 2781 2782#ifdef HAVE_SETUID 2783static char posix_setuid__doc__[] = 2784"setuid(uid) -> None\n\ 2785Set the current process's user id."; 2786static PyObject * 2787posix_setuid(PyObject *self, PyObject *args) 2788{ 2789 int uid; 2790 if (!PyArg_ParseTuple(args, "i:setuid", &uid)) 2791 return NULL; 2792 if (setuid(uid) < 0) 2793 return posix_error(); 2794 Py_INCREF(Py_None); 2795 return Py_None; 2796} 2797#endif /* HAVE_SETUID */ 2798 2799 2800#ifdef HAVE_SETEUID 2801static char posix_seteuid__doc__[] = 2802"seteuid(uid) -> None\n\ 2803Set the current process's effective user id."; 2804static PyObject * 2805posix_seteuid (PyObject *self, PyObject *args) 2806{ 2807 int euid; 2808 if (!PyArg_ParseTuple(args, "i", &euid)) { 2809 return NULL; 2810 } else if (seteuid(euid) < 0) { 2811 return posix_error(); 2812 } else { 2813 Py_INCREF(Py_None); 2814 return Py_None; 2815 } 2816} 2817#endif /* HAVE_SETEUID */ 2818 2819#ifdef HAVE_SETEGID 2820static char posix_setegid__doc__[] = 2821"setegid(gid) -> None\n\ 2822Set the current process's effective group id."; 2823static PyObject * 2824posix_setegid (PyObject *self, PyObject *args) 2825{ 2826 int egid; 2827 if (!PyArg_ParseTuple(args, "i", &egid)) { 2828 return NULL; 2829 } else if (setegid(egid) < 0) { 2830 return posix_error(); 2831 } else { 2832 Py_INCREF(Py_None); 2833 return Py_None; 2834 } 2835} 2836#endif /* HAVE_SETEGID */ 2837 2838#ifdef HAVE_SETREUID 2839static char posix_setreuid__doc__[] = 2840"seteuid(ruid, euid) -> None\n\ 2841Set the current process's real and effective user ids."; 2842static PyObject * 2843posix_setreuid (PyObject *self, PyObject *args) 2844{ 2845 int ruid, euid; 2846 if (!PyArg_ParseTuple(args, "ii", &ruid, &euid)) { 2847 return NULL; 2848 } else if (setreuid(ruid, euid) < 0) { 2849 return posix_error(); 2850 } else { 2851 Py_INCREF(Py_None); 2852 return Py_None; 2853 } 2854} 2855#endif /* HAVE_SETREUID */ 2856 2857#ifdef HAVE_SETREGID 2858static char posix_setregid__doc__[] = 2859"setegid(rgid, egid) -> None\n\ 2860Set the current process's real and effective group ids."; 2861static PyObject * 2862posix_setregid (PyObject *self, PyObject *args) 2863{ 2864 int rgid, egid; 2865 if (!PyArg_ParseTuple(args, "ii", &rgid, &egid)) { 2866 return NULL; 2867 } else if (setregid(rgid, egid) < 0) { 2868 return posix_error(); 2869 } else { 2870 Py_INCREF(Py_None); 2871 return Py_None; 2872 } 2873} 2874#endif /* HAVE_SETREGID */ 2875 2876#ifdef HAVE_SETGID 2877static char posix_setgid__doc__[] = 2878"setgid(gid) -> None\n\ 2879Set the current process's group id."; 2880 2881static PyObject * 2882posix_setgid(PyObject *self, PyObject *args) 2883{ 2884 int gid; 2885 if (!PyArg_ParseTuple(args, "i:setgid", &gid)) 2886 return NULL; 2887 if (setgid(gid) < 0) 2888 return posix_error(); 2889 Py_INCREF(Py_None); 2890 return Py_None; 2891} 2892#endif /* HAVE_SETGID */ 2893 2894 2895#ifdef HAVE_WAITPID 2896static char posix_waitpid__doc__[] = 2897"waitpid(pid, options) -> (pid, status)\n\ 2898Wait for completion of a give child process."; 2899 2900static PyObject * 2901posix_waitpid(PyObject *self, PyObject *args) 2902{ 2903 int pid, options; 2904#ifdef UNION_WAIT 2905 union wait status; 2906#define status_i (status.w_status) 2907#else 2908 int status; 2909#define status_i status 2910#endif 2911 status_i = 0; 2912 2913 if (!PyArg_ParseTuple(args, "ii:waitpid", &pid, &options)) 2914 return NULL; 2915 Py_BEGIN_ALLOW_THREADS 2916#ifdef NeXT 2917 pid = wait4(pid, &status, options, NULL); 2918#else 2919 pid = waitpid(pid, &status, options); 2920#endif 2921 Py_END_ALLOW_THREADS 2922 if (pid == -1) 2923 return posix_error(); 2924 else 2925 return Py_BuildValue("ii", pid, status_i); 2926} 2927#endif /* HAVE_WAITPID */ 2928 2929 2930#ifdef HAVE_WAIT 2931static char posix_wait__doc__[] = 2932"wait() -> (pid, status)\n\ 2933Wait for completion of a child process."; 2934 2935static PyObject * 2936posix_wait(PyObject *self, PyObject *args) 2937{ 2938 int pid; 2939#ifdef UNION_WAIT 2940 union wait status; 2941#define status_i (status.w_status) 2942#else 2943 int status; 2944#define status_i status 2945#endif 2946 if (!PyArg_ParseTuple(args, ":wait")) 2947 return NULL; 2948 status_i = 0; 2949 Py_BEGIN_ALLOW_THREADS 2950 pid = wait(&status); 2951 Py_END_ALLOW_THREADS 2952 if (pid == -1) 2953 return posix_error(); 2954 else 2955 return Py_BuildValue("ii", pid, status_i); 2956#undef status_i 2957} 2958#endif 2959 2960 2961static char posix_lstat__doc__[] = 2962"lstat(path) -> (mode,ino,dev,nlink,uid,gid,size,atime,mtime,ctime)\n\ 2963Like stat(path), but do not follow symbolic links."; 2964 2965static PyObject * 2966posix_lstat(PyObject *self, PyObject *args) 2967{ 2968#ifdef HAVE_LSTAT 2969 return posix_do_stat(self, args, "s:lstat", lstat); 2970#else /* !HAVE_LSTAT */ 2971 return posix_do_stat(self, args, "s:lstat", STAT); 2972#endif /* !HAVE_LSTAT */ 2973} 2974 2975 2976#ifdef HAVE_READLINK 2977static char posix_readlink__doc__[] = 2978"readlink(path) -> path\n\ 2979Return a string representing the path to which the symbolic link points."; 2980 2981static PyObject * 2982posix_readlink(PyObject *self, PyObject *args) 2983{ 2984 char buf[MAXPATHLEN]; 2985 char *path; 2986 int n; 2987 if (!PyArg_ParseTuple(args, "s:readlink", &path)) 2988 return NULL; 2989 Py_BEGIN_ALLOW_THREADS 2990 n = readlink(path, buf, (int) sizeof buf); 2991 Py_END_ALLOW_THREADS 2992 if (n < 0) 2993 return posix_error_with_filename(path); 2994 return PyString_FromStringAndSize(buf, n); 2995} 2996#endif /* HAVE_READLINK */ 2997 2998 2999#ifdef HAVE_SYMLINK 3000static char posix_symlink__doc__[] = 3001"symlink(src, dst) -> None\n\ 3002Create a symbolic link."; 3003 3004static PyObject * 3005posix_symlink(PyObject *self, PyObject *args) 3006{ 3007 return posix_2str(args, "ss:symlink", symlink); 3008} 3009#endif /* HAVE_SYMLINK */ 3010 3011 3012#ifdef HAVE_TIMES 3013#ifndef HZ 3014#define HZ 60 /* Universal constant :-) */ 3015#endif /* HZ */ 3016 3017#if defined(PYCC_VACPP) && defined(PYOS_OS2) 3018static long 3019system_uptime(void) 3020{ 3021 ULONG value = 0; 3022 3023 Py_BEGIN_ALLOW_THREADS 3024 DosQuerySysInfo(QSV_MS_COUNT, QSV_MS_COUNT, &value, sizeof(value)); 3025 Py_END_ALLOW_THREADS 3026 3027 return value; 3028} 3029 3030static PyObject * 3031posix_times(PyObject *self, PyObject *args) 3032{ 3033 if (!PyArg_ParseTuple(args, ":times")) 3034 return NULL; 3035 3036 /* Currently Only Uptime is Provided -- Others Later */ 3037 return Py_BuildValue("ddddd", 3038 (double)0 /* t.tms_utime / HZ */, 3039 (double)0 /* t.tms_stime / HZ */, 3040 (double)0 /* t.tms_cutime / HZ */, 3041 (double)0 /* t.tms_cstime / HZ */, 3042 (double)system_uptime() / 1000); 3043} 3044#else /* not OS2 */ 3045static PyObject * 3046posix_times(PyObject *self, PyObject *args) 3047{ 3048 struct tms t; 3049 clock_t c; 3050 if (!PyArg_ParseTuple(args, ":times")) 3051 return NULL; 3052 errno = 0; 3053 c = times(&t); 3054 if (c == (clock_t) -1) 3055 return posix_error(); 3056 return Py_BuildValue("ddddd", 3057 (double)t.tms_utime / HZ, 3058 (double)t.tms_stime / HZ, 3059 (double)t.tms_cutime / HZ, 3060 (double)t.tms_cstime / HZ, 3061 (double)c / HZ); 3062} 3063#endif /* not OS2 */ 3064#endif /* HAVE_TIMES */ 3065 3066 3067#ifdef MS_WIN32 3068#define HAVE_TIMES /* so the method table will pick it up */ 3069static PyObject * 3070posix_times(PyObject *self, PyObject *args) 3071{ 3072 FILETIME create, exit, kernel, user; 3073 HANDLE hProc; 3074 if (!PyArg_ParseTuple(args, ":times")) 3075 return NULL; 3076 hProc = GetCurrentProcess(); 3077 GetProcessTimes(hProc, &create, &exit, &kernel, &user); 3078 /* The fields of a FILETIME structure are the hi and lo part 3079 of a 64-bit value expressed in 100 nanosecond units. 3080 1e7 is one second in such units; 1e-7 the inverse. 3081 429.4967296 is 2**32 / 1e7 or 2**32 * 1e-7. 3082 */ 3083 return Py_BuildValue( 3084 "ddddd", 3085 (double)(kernel.dwHighDateTime*429.4967296 + 3086 kernel.dwLowDateTime*1e-7), 3087 (double)(user.dwHighDateTime*429.4967296 + 3088 user.dwLowDateTime*1e-7), 3089 (double)0, 3090 (double)0, 3091 (double)0); 3092} 3093#endif /* MS_WIN32 */ 3094 3095#ifdef HAVE_TIMES 3096static char posix_times__doc__[] = 3097"times() -> (utime, stime, cutime, cstime, elapsed_time)\n\ 3098Return a tuple of floating point numbers indicating process times."; 3099#endif 3100 3101 3102#ifdef HAVE_SETSID 3103static char posix_setsid__doc__[] = 3104"setsid() -> None\n\ 3105Call the system call setsid()."; 3106 3107static PyObject * 3108posix_setsid(PyObject *self, PyObject *args) 3109{ 3110 if (!PyArg_ParseTuple(args, ":setsid")) 3111 return NULL; 3112 if (setsid() < 0) 3113 return posix_error(); 3114 Py_INCREF(Py_None); 3115 return Py_None; 3116} 3117#endif /* HAVE_SETSID */ 3118 3119#ifdef HAVE_SETPGID 3120static char posix_setpgid__doc__[] = 3121"setpgid(pid, pgrp) -> None\n\ 3122Call the system call setpgid()."; 3123 3124static PyObject * 3125posix_setpgid(PyObject *self, PyObject *args) 3126{ 3127 int pid, pgrp; 3128 if (!PyArg_ParseTuple(args, "ii:setpgid", &pid, &pgrp)) 3129 return NULL; 3130 if (setpgid(pid, pgrp) < 0) 3131 return posix_error(); 3132 Py_INCREF(Py_None); 3133 return Py_None; 3134} 3135#endif /* HAVE_SETPGID */ 3136 3137 3138#ifdef HAVE_TCGETPGRP 3139static char posix_tcgetpgrp__doc__[] = 3140"tcgetpgrp(fd) -> pgid\n\ 3141Return the process group associated with the terminal given by a fd."; 3142 3143static PyObject * 3144posix_tcgetpgrp(PyObject *self, PyObject *args) 3145{ 3146 int fd, pgid; 3147 if (!PyArg_ParseTuple(args, "i:tcgetpgrp", &fd)) 3148 return NULL; 3149 pgid = tcgetpgrp(fd); 3150 if (pgid < 0) 3151 return posix_error(); 3152 return PyInt_FromLong((long)pgid); 3153} 3154#endif /* HAVE_TCGETPGRP */ 3155 3156 3157#ifdef HAVE_TCSETPGRP 3158static char posix_tcsetpgrp__doc__[] = 3159"tcsetpgrp(fd, pgid) -> None\n\ 3160Set the process group associated with the terminal given by a fd."; 3161 3162static PyObject * 3163posix_tcsetpgrp(PyObject *self, PyObject *args) 3164{ 3165 int fd, pgid; 3166 if (!PyArg_ParseTuple(args, "ii:tcsetpgrp", &fd, &pgid)) 3167 return NULL; 3168 if (tcsetpgrp(fd, pgid) < 0) 3169 return posix_error(); 3170 Py_INCREF(Py_None); 3171 return Py_None; 3172} 3173#endif /* HAVE_TCSETPGRP */ 3174 3175/* Functions acting on file descriptors */ 3176 3177static char posix_open__doc__[] = 3178"open(filename, flag [, mode=0777]) -> fd\n\ 3179Open a file (for low level IO)."; 3180 3181static PyObject * 3182posix_open(PyObject *self, PyObject *args) 3183{ 3184 char *file; 3185 int flag; 3186 int mode = 0777; 3187 int fd; 3188 if (!PyArg_ParseTuple(args, "si|i", &file, &flag, &mode)) 3189 return NULL; 3190 3191 Py_BEGIN_ALLOW_THREADS 3192 fd = open(file, flag, mode); 3193 Py_END_ALLOW_THREADS 3194 if (fd < 0) 3195 return posix_error_with_filename(file); 3196 return PyInt_FromLong((long)fd); 3197} 3198 3199 3200static char posix_close__doc__[] = 3201"close(fd) -> None\n\ 3202Close a file descriptor (for low level IO)."; 3203 3204static PyObject * 3205posix_close(PyObject *self, PyObject *args) 3206{ 3207 int fd, res; 3208 if (!PyArg_ParseTuple(args, "i:close", &fd)) 3209 return NULL; 3210 Py_BEGIN_ALLOW_THREADS 3211 res = close(fd); 3212 Py_END_ALLOW_THREADS 3213 if (res < 0) 3214 return posix_error(); 3215 Py_INCREF(Py_None); 3216 return Py_None; 3217} 3218 3219 3220static char posix_dup__doc__[] = 3221"dup(fd) -> fd2\n\ 3222Return a duplicate of a file descriptor."; 3223 3224static PyObject * 3225posix_dup(PyObject *self, PyObject *args) 3226{ 3227 int fd; 3228 if (!PyArg_ParseTuple(args, "i:dup", &fd)) 3229 return NULL; 3230 Py_BEGIN_ALLOW_THREADS 3231 fd = dup(fd); 3232 Py_END_ALLOW_THREADS 3233 if (fd < 0) 3234 return posix_error(); 3235 return PyInt_FromLong((long)fd); 3236} 3237 3238 3239static char posix_dup2__doc__[] = 3240"dup2(fd, fd2) -> None\n\ 3241Duplicate file descriptor."; 3242 3243static PyObject * 3244posix_dup2(PyObject *self, PyObject *args) 3245{ 3246 int fd, fd2, res; 3247 if (!PyArg_ParseTuple(args, "ii:dup2", &fd, &fd2)) 3248 return NULL; 3249 Py_BEGIN_ALLOW_THREADS 3250 res = dup2(fd, fd2); 3251 Py_END_ALLOW_THREADS 3252 if (res < 0) 3253 return posix_error(); 3254 Py_INCREF(Py_None); 3255 return Py_None; 3256} 3257 3258 3259static char posix_lseek__doc__[] = 3260"lseek(fd, pos, how) -> newpos\n\ 3261Set the current position of a file descriptor."; 3262 3263static PyObject * 3264posix_lseek(PyObject *self, PyObject *args) 3265{ 3266 int fd, how; 3267#ifdef MS_WIN64 3268 LONG_LONG pos, res; 3269#else 3270 off_t pos, res; 3271#endif 3272 PyObject *posobj; 3273 if (!PyArg_ParseTuple(args, "iOi:lseek", &fd, &posobj, &how)) 3274 return NULL; 3275#ifdef SEEK_SET 3276 /* Turn 0, 1, 2 into SEEK_{SET,CUR,END} */ 3277 switch (how) { 3278 case 0: how = SEEK_SET; break; 3279 case 1: how = SEEK_CUR; break; 3280 case 2: how = SEEK_END; break; 3281 } 3282#endif /* SEEK_END */ 3283 3284#if !defined(HAVE_LARGEFILE_SUPPORT) 3285 pos = PyInt_AsLong(posobj); 3286#else 3287 pos = PyLong_Check(posobj) ? 3288 PyLong_AsLongLong(posobj) : PyInt_AsLong(posobj); 3289#endif 3290 if (PyErr_Occurred()) 3291 return NULL; 3292 3293 Py_BEGIN_ALLOW_THREADS 3294#ifdef MS_WIN64 3295 res = _lseeki64(fd, pos, how); 3296#else 3297 res = lseek(fd, pos, how); 3298#endif 3299 Py_END_ALLOW_THREADS 3300 if (res < 0) 3301 return posix_error(); 3302 3303#if !defined(HAVE_LARGEFILE_SUPPORT) 3304 return PyInt_FromLong(res); 3305#else 3306 return PyLong_FromLongLong(res); 3307#endif 3308} 3309 3310 3311static char posix_read__doc__[] = 3312"read(fd, buffersize) -> string\n\ 3313Read a file descriptor."; 3314 3315static PyObject * 3316posix_read(PyObject *self, PyObject *args) 3317{ 3318 int fd, size, n; 3319 PyObject *buffer; 3320 if (!PyArg_ParseTuple(args, "ii:read", &fd, &size)) 3321 return NULL; 3322 buffer = PyString_FromStringAndSize((char *)NULL, size); 3323 if (buffer == NULL) 3324 return NULL; 3325 Py_BEGIN_ALLOW_THREADS 3326 n = read(fd, PyString_AsString(buffer), size); 3327 Py_END_ALLOW_THREADS 3328 if (n < 0) { 3329 Py_DECREF(buffer); 3330 return posix_error(); 3331 } 3332 if (n != size) 3333 _PyString_Resize(&buffer, n); 3334 return buffer; 3335} 3336 3337 3338static char posix_write__doc__[] = 3339"write(fd, string) -> byteswritten\n\ 3340Write a string to a file descriptor."; 3341 3342static PyObject * 3343posix_write(PyObject *self, PyObject *args) 3344{ 3345 int fd, size; 3346 char *buffer; 3347 if (!PyArg_ParseTuple(args, "is#:write", &fd, &buffer, &size)) 3348 return NULL; 3349 Py_BEGIN_ALLOW_THREADS 3350 size = write(fd, buffer, size); 3351 Py_END_ALLOW_THREADS 3352 if (size < 0) 3353 return posix_error(); 3354 return PyInt_FromLong((long)size); 3355} 3356 3357 3358static char posix_fstat__doc__[]= 3359"fstat(fd) -> (mode, ino, dev, nlink, uid, gid, size, atime, mtime, ctime)\n\ 3360Like stat(), but for an open file descriptor."; 3361 3362static PyObject * 3363posix_fstat(PyObject *self, PyObject *args) 3364{ 3365 int fd; 3366 STRUCT_STAT st; 3367 int res; 3368 if (!PyArg_ParseTuple(args, "i:fstat", &fd)) 3369 return NULL; 3370 Py_BEGIN_ALLOW_THREADS 3371 res = FSTAT(fd, &st); 3372 Py_END_ALLOW_THREADS 3373 if (res != 0) 3374 return posix_error(); 3375 3376 return _pystat_fromstructstat(st); 3377} 3378 3379 3380static char posix_fdopen__doc__[] = 3381"fdopen(fd, [, mode='r' [, bufsize]]) -> file_object\n\ 3382Return an open file object connected to a file descriptor."; 3383 3384static PyObject * 3385posix_fdopen(PyObject *self, PyObject *args) 3386{ 3387 int fd; 3388 char *mode = "r"; 3389 int bufsize = -1; 3390 FILE *fp; 3391 PyObject *f; 3392 if (!PyArg_ParseTuple(args, "i|si", &fd, &mode, &bufsize)) 3393 return NULL; 3394 3395 Py_BEGIN_ALLOW_THREADS 3396 fp = fdopen(fd, mode); 3397 Py_END_ALLOW_THREADS 3398 if (fp == NULL) 3399 return posix_error(); 3400 f = PyFile_FromFile(fp, "(fdopen)", mode, fclose); 3401 if (f != NULL) 3402 PyFile_SetBufSize(f, bufsize); 3403 return f; 3404} 3405 3406static char posix_isatty__doc__[] = 3407"isatty(fd) -> Boolean\n\ 3408Return true if the file descriptor 'fd' is an open file descriptor\n\ 3409connected to a terminal."; 3410 3411static PyObject * 3412posix_isatty(PyObject *self, PyObject *args) 3413{ 3414 int fd; 3415 if (!PyArg_ParseTuple(args, "i:isatty", &fd)) 3416 return NULL; 3417 return Py_BuildValue("i", isatty(fd)); 3418} 3419 3420#ifdef HAVE_PIPE 3421static char posix_pipe__doc__[] = 3422"pipe() -> (read_end, write_end)\n\ 3423Create a pipe."; 3424 3425static PyObject * 3426posix_pipe(PyObject *self, PyObject *args) 3427{ 3428#if defined(PYOS_OS2) 3429 HFILE read, write; 3430 APIRET rc; 3431 3432 if (!PyArg_ParseTuple(args, ":pipe")) 3433 return NULL; 3434 3435 Py_BEGIN_ALLOW_THREADS 3436 rc = DosCreatePipe( &read, &write, 4096); 3437 Py_END_ALLOW_THREADS 3438 if (rc != NO_ERROR) 3439 return os2_error(rc); 3440 3441 return Py_BuildValue("(ii)", read, write); 3442#else 3443#if !defined(MS_WIN32) 3444 int fds[2]; 3445 int res; 3446 if (!PyArg_ParseTuple(args, ":pipe")) 3447 return NULL; 3448 Py_BEGIN_ALLOW_THREADS 3449 res = pipe(fds); 3450 Py_END_ALLOW_THREADS 3451 if (res != 0) 3452 return posix_error(); 3453 return Py_BuildValue("(ii)", fds[0], fds[1]); 3454#else /* MS_WIN32 */ 3455 HANDLE read, write; 3456 int read_fd, write_fd; 3457 BOOL ok; 3458 if (!PyArg_ParseTuple(args, ":pipe")) 3459 return NULL; 3460 Py_BEGIN_ALLOW_THREADS 3461 ok = CreatePipe(&read, &write, NULL, 0); 3462 Py_END_ALLOW_THREADS 3463 if (!ok) 3464 return win32_error("CreatePipe", NULL); 3465 read_fd = _open_osfhandle((intptr_t)read, 0); 3466 write_fd = _open_osfhandle((intptr_t)write, 1); 3467 return Py_BuildValue("(ii)", read_fd, write_fd); 3468#endif /* MS_WIN32 */ 3469#endif 3470} 3471#endif /* HAVE_PIPE */ 3472 3473 3474#ifdef HAVE_MKFIFO 3475static char posix_mkfifo__doc__[] = 3476"mkfifo(file, [, mode=0666]) -> None\n\ 3477Create a FIFO (a POSIX named pipe)."; 3478 3479static PyObject * 3480posix_mkfifo(PyObject *self, PyObject *args) 3481{ 3482 char *file; 3483 int mode = 0666; 3484 int res; 3485 if (!PyArg_ParseTuple(args, "s|i:mkfifo", &file, &mode)) 3486 return NULL; 3487 Py_BEGIN_ALLOW_THREADS 3488 res = mkfifo(file, mode); 3489 Py_END_ALLOW_THREADS 3490 if (res < 0) 3491 return posix_error(); 3492 Py_INCREF(Py_None); 3493 return Py_None; 3494} 3495#endif 3496 3497 3498#ifdef HAVE_FTRUNCATE 3499static char posix_ftruncate__doc__[] = 3500"ftruncate(fd, length) -> None\n\ 3501Truncate a file to a specified length."; 3502 3503static PyObject * 3504posix_ftruncate(PyObject *self, PyObject *args) 3505{ 3506 int fd; 3507 off_t length; 3508 int res; 3509 PyObject *lenobj; 3510 3511 if (!PyArg_ParseTuple(args, "iO:ftruncate", &fd, &lenobj)) 3512 return NULL; 3513 3514#if !defined(HAVE_LARGEFILE_SUPPORT) 3515 length = PyInt_AsLong(lenobj); 3516#else 3517 length = PyLong_Check(lenobj) ? 3518 PyLong_AsLongLong(lenobj) : PyInt_AsLong(lenobj); 3519#endif 3520 if (PyErr_Occurred()) 3521 return NULL; 3522 3523 Py_BEGIN_ALLOW_THREADS 3524 res = ftruncate(fd, length); 3525 Py_END_ALLOW_THREADS 3526 if (res < 0) { 3527 PyErr_SetFromErrno(PyExc_IOError); 3528 return NULL; 3529 } 3530 Py_INCREF(Py_None); 3531 return Py_None; 3532} 3533#endif 3534 3535#ifdef NeXT 3536#define HAVE_PUTENV 3537/* Steve Spicklemire got this putenv from NeXTAnswers */ 3538static int 3539putenv(char *newval) 3540{ 3541 extern char **environ; 3542 3543 static int firstTime = 1; 3544 char **ep; 3545 char *cp; 3546 int esiz; 3547 char *np; 3548 3549 if (!(np = strchr(newval, '='))) 3550 return 1; 3551 *np = '\0'; 3552 3553 /* look it up */ 3554 for (ep=environ ; *ep ; ep++) 3555 { 3556 /* this should always be true... */ 3557 if (cp = strchr(*ep, '=')) 3558 { 3559 *cp = '\0'; 3560 if (!strcmp(*ep, newval)) 3561 { 3562 /* got it! */ 3563 *cp = '='; 3564 break; 3565 } 3566 *cp = '='; 3567 } 3568 else 3569 { 3570 *np = '='; 3571 return 1; 3572 } 3573 } 3574 3575 *np = '='; 3576 if (*ep) 3577 { 3578 /* the string was already there: 3579 just replace it with the new one */ 3580 *ep = newval; 3581 return 0; 3582 } 3583 3584 /* expand environ by one */ 3585 for (esiz=2, ep=environ ; *ep ; ep++) 3586 esiz++; 3587 if (firstTime) 3588 { 3589 char **epp; 3590 char **newenv; 3591 if (!(newenv = malloc(esiz * sizeof(char *)))) 3592 return 1; 3593 3594 for (ep=environ, epp=newenv ; *ep ;) 3595 *epp++ = *ep++; 3596 *epp++ = newval; 3597 *epp = (char *) 0; 3598 environ = newenv; 3599 } 3600 else 3601 { 3602 if (!(environ = realloc(environ, esiz * sizeof(char *)))) 3603 return 1; 3604 environ[esiz - 2] = newval; 3605 environ[esiz - 1] = (char *) 0; 3606 firstTime = 0; 3607 } 3608 3609 return 0; 3610} 3611#endif /* NeXT */ 3612 3613 3614#ifdef HAVE_PUTENV 3615static char posix_putenv__doc__[] = 3616"putenv(key, value) -> None\n\ 3617Change or add an environment variable."; 3618 3619#ifdef __BEOS__ 3620/* We have putenv(), but not in the headers (as of PR2). - [cjh] */ 3621int putenv( const char *str ); 3622#endif 3623 3624/* Save putenv() parameters as values here, so we can collect them when they 3625 * get re-set with another call for the same key. */ 3626static PyObject *posix_putenv_garbage; 3627 3628static PyObject * 3629posix_putenv(PyObject *self, PyObject *args) 3630{ 3631 char *s1, *s2; 3632 char *new; 3633 PyObject *newstr; 3634 3635 if (!PyArg_ParseTuple(args, "ss:putenv", &s1, &s2)) 3636 return NULL; 3637 3638#if defined(PYOS_OS2) 3639 if (stricmp(s1, "BEGINLIBPATH") == 0) { 3640 APIRET rc; 3641 3642 if (strlen(s2) == 0) /* If New Value is an Empty String */ 3643 s2 = NULL; /* Then OS/2 API Wants a NULL to Undefine It */ 3644 3645 rc = DosSetExtLIBPATH(s2, BEGIN_LIBPATH); 3646 if (rc != NO_ERROR) 3647 return os2_error(rc); 3648 3649 } else if (stricmp(s1, "ENDLIBPATH") == 0) { 3650 APIRET rc; 3651 3652 if (strlen(s2) == 0) /* If New Value is an Empty String */ 3653 s2 = NULL; /* Then OS/2 API Wants a NULL to Undefine It */ 3654 3655 rc = DosSetExtLIBPATH(s2, END_LIBPATH); 3656 if (rc != NO_ERROR) 3657 return os2_error(rc); 3658 } else { 3659#endif 3660 3661 /* XXX This can leak memory -- not easy to fix :-( */ 3662 newstr = PyString_FromStringAndSize(NULL, strlen(s1) + strlen(s2) + 2); 3663 if (newstr == NULL) 3664 return PyErr_NoMemory(); 3665 new = PyString_AS_STRING(newstr); 3666 (void) sprintf(new, "%s=%s", s1, s2); 3667 if (putenv(new)) { 3668 posix_error(); 3669 return NULL; 3670 } 3671 /* Install the first arg and newstr in posix_putenv_garbage; 3672 * this will cause previous value to be collected. This has to 3673 * happen after the real putenv() call because the old value 3674 * was still accessible until then. */ 3675 if (PyDict_SetItem(posix_putenv_garbage, 3676 PyTuple_GET_ITEM(args, 0), newstr)) { 3677 /* really not much we can do; just leak */ 3678 PyErr_Clear(); 3679 } 3680 else { 3681 Py_DECREF(newstr); 3682 } 3683 3684#if defined(PYOS_OS2) 3685 } 3686#endif 3687 Py_INCREF(Py_None); 3688 return Py_None; 3689} 3690#endif /* putenv */ 3691 3692#ifdef HAVE_STRERROR 3693static char posix_strerror__doc__[] = 3694"strerror(code) -> string\n\ 3695Translate an error code to a message string."; 3696 3697PyObject * 3698posix_strerror(PyObject *self, PyObject *args) 3699{ 3700 int code; 3701 char *message; 3702 if (!PyArg_ParseTuple(args, "i:strerror", &code)) 3703 return NULL; 3704 message = strerror(code); 3705 if (message == NULL) { 3706 PyErr_SetString(PyExc_ValueError, 3707 "strerror code out of range"); 3708 return NULL; 3709 } 3710 return PyString_FromString(message); 3711} 3712#endif /* strerror */ 3713 3714 3715#ifdef HAVE_SYS_WAIT_H 3716 3717#ifdef WIFSTOPPED 3718static char posix_WIFSTOPPED__doc__[] = 3719"WIFSTOPPED(status) -> Boolean\n\ 3720Return true if the process returning 'status' was stopped."; 3721 3722static PyObject * 3723posix_WIFSTOPPED(PyObject *self, PyObject *args) 3724{ 3725#ifdef UNION_WAIT 3726 union wait status; 3727#define status_i (status.w_status) 3728#else 3729 int status; 3730#define status_i status 3731#endif 3732 status_i = 0; 3733 3734 if (!PyArg_ParseTuple(args, "i:WIFSTOPPED", &status_i)) 3735 { 3736 return NULL; 3737 } 3738 3739 return Py_BuildValue("i", WIFSTOPPED(status)); 3740#undef status_i 3741} 3742#endif /* WIFSTOPPED */ 3743 3744#ifdef WIFSIGNALED 3745static char posix_WIFSIGNALED__doc__[] = 3746"WIFSIGNALED(status) -> Boolean\n\ 3747Return true if the process returning 'status' was terminated by a signal."; 3748 3749static PyObject * 3750posix_WIFSIGNALED(PyObject *self, PyObject *args) 3751{ 3752#ifdef UNION_WAIT 3753 union wait status; 3754#define status_i (status.w_status) 3755#else 3756 int status; 3757#define status_i status 3758#endif 3759 status_i = 0; 3760 3761 if (!PyArg_ParseTuple(args, "i:WIFSIGNALED", &status_i)) 3762 { 3763 return NULL; 3764 } 3765 3766 return Py_BuildValue("i", WIFSIGNALED(status)); 3767#undef status_i 3768} 3769#endif /* WIFSIGNALED */ 3770 3771#ifdef WIFEXITED 3772static char posix_WIFEXITED__doc__[] = 3773"WIFEXITED(status) -> Boolean\n\ 3774Return true if the process returning 'status' exited using the exit()\n\ 3775system call."; 3776 3777static PyObject * 3778posix_WIFEXITED(PyObject *self, PyObject *args) 3779{ 3780#ifdef UNION_WAIT 3781 union wait status; 3782#define status_i (status.w_status) 3783#else 3784 int status; 3785#define status_i status 3786#endif 3787 status_i = 0; 3788 3789 if (!PyArg_ParseTuple(args, "i:WIFEXITED", &status_i)) 3790 { 3791 return NULL; 3792 } 3793 3794 return Py_BuildValue("i", WIFEXITED(status)); 3795#undef status_i 3796} 3797#endif /* WIFEXITED */ 3798 3799#ifdef WEXITSTATUS 3800static char posix_WEXITSTATUS__doc__[] = 3801"WEXITSTATUS(status) -> integer\n\ 3802Return the process return code from 'status'."; 3803 3804static PyObject * 3805posix_WEXITSTATUS(PyObject *self, PyObject *args) 3806{ 3807#ifdef UNION_WAIT 3808 union wait status; 3809#define status_i (status.w_status) 3810#else 3811 int status; 3812#define status_i status 3813#endif 3814 status_i = 0; 3815 3816 if (!PyArg_ParseTuple(args, "i:WEXITSTATUS", &status_i)) 3817 { 3818 return NULL; 3819 } 3820 3821 return Py_BuildValue("i", WEXITSTATUS(status)); 3822#undef status_i 3823} 3824#endif /* WEXITSTATUS */ 3825 3826#ifdef WTERMSIG 3827static char posix_WTERMSIG__doc__[] = 3828"WTERMSIG(status) -> integer\n\ 3829Return the signal that terminated the process that provided the 'status'\n\ 3830value."; 3831 3832static PyObject * 3833posix_WTERMSIG(PyObject *self, PyObject *args) 3834{ 3835#ifdef UNION_WAIT 3836 union wait status; 3837#define status_i (status.w_status) 3838#else 3839 int status; 3840#define status_i status 3841#endif 3842 status_i = 0; 3843 3844 if (!PyArg_ParseTuple(args, "i:WTERMSIG", &status_i)) 3845 { 3846 return NULL; 3847 } 3848 3849 return Py_BuildValue("i", WTERMSIG(status)); 3850#undef status_i 3851} 3852#endif /* WTERMSIG */ 3853 3854#ifdef WSTOPSIG 3855static char posix_WSTOPSIG__doc__[] = 3856"WSTOPSIG(status) -> integer\n\ 3857Return the signal that stopped the process that provided the 'status' value."; 3858 3859static PyObject * 3860posix_WSTOPSIG(PyObject *self, PyObject *args) 3861{ 3862#ifdef UNION_WAIT 3863 union wait status; 3864#define status_i (status.w_status) 3865#else 3866 int status; 3867#define status_i status 3868#endif 3869 status_i = 0; 3870 3871 if (!PyArg_ParseTuple(args, "i:WSTOPSIG", &status_i)) 3872 { 3873 return NULL; 3874 } 3875 3876 return Py_BuildValue("i", WSTOPSIG(status)); 3877#undef status_i 3878} 3879#endif /* WSTOPSIG */ 3880 3881#endif /* HAVE_SYS_WAIT_H */ 3882 3883 3884#if defined(HAVE_FSTATVFS) 3885#ifdef _SCO_DS 3886/* SCO OpenServer 5.0 and later requires _SVID3 before it reveals the 3887 needed definitions in sys/statvfs.h */ 3888#define _SVID3 3889#endif 3890#include <sys/statvfs.h> 3891 3892static char posix_fstatvfs__doc__[] = 3893"fstatvfs(fd) -> \n\ 3894 (bsize, frsize, blocks, bfree, bavail, files, ffree, favail, flag, namemax)\n\ 3895Perform an fstatvfs system call on the given fd."; 3896 3897static PyObject * 3898posix_fstatvfs(PyObject *self, PyObject *args) 3899{ 3900 int fd, res; 3901 struct statvfs st; 3902 if (!PyArg_ParseTuple(args, "i:fstatvfs", &fd)) 3903 return NULL; 3904 Py_BEGIN_ALLOW_THREADS 3905 res = fstatvfs(fd, &st); 3906 Py_END_ALLOW_THREADS 3907 if (res != 0) 3908 return posix_error(); 3909#if !defined(HAVE_LARGEFILE_SUPPORT) 3910 return Py_BuildValue("(llllllllll)", 3911 (long) st.f_bsize, 3912 (long) st.f_frsize, 3913 (long) st.f_blocks, 3914 (long) st.f_bfree, 3915 (long) st.f_bavail, 3916 (long) st.f_files, 3917 (long) st.f_ffree, 3918 (long) st.f_favail, 3919 (long) st.f_flag, 3920 (long) st.f_namemax); 3921#else 3922 return Py_BuildValue("(llLLLLLLll)", 3923 (long) st.f_bsize, 3924 (long) st.f_frsize, 3925 (LONG_LONG) st.f_blocks, 3926 (LONG_LONG) st.f_bfree, 3927 (LONG_LONG) st.f_bavail, 3928 (LONG_LONG) st.f_files, 3929 (LONG_LONG) st.f_ffree, 3930 (LONG_LONG) st.f_favail, 3931 (long) st.f_flag, 3932 (long) st.f_namemax); 3933#endif 3934} 3935#endif /* HAVE_FSTATVFS */ 3936 3937 3938#if defined(HAVE_STATVFS) 3939#include <sys/statvfs.h> 3940 3941static char posix_statvfs__doc__[] = 3942"statvfs(path) -> \n\ 3943 (bsize, frsize, blocks, bfree, bavail, files, ffree, favail, flag, namemax)\n\ 3944Perform a statvfs system call on the given path."; 3945 3946static PyObject * 3947posix_statvfs(PyObject *self, PyObject *args) 3948{ 3949 char *path; 3950 int res; 3951 struct statvfs st; 3952 if (!PyArg_ParseTuple(args, "s:statvfs", &path)) 3953 return NULL; 3954 Py_BEGIN_ALLOW_THREADS 3955 res = statvfs(path, &st); 3956 Py_END_ALLOW_THREADS 3957 if (res != 0) 3958 return posix_error_with_filename(path); 3959#if !defined(HAVE_LARGEFILE_SUPPORT) 3960 return Py_BuildValue("(llllllllll)", 3961 (long) st.f_bsize, 3962 (long) st.f_frsize, 3963 (long) st.f_blocks, 3964 (long) st.f_bfree, 3965 (long) st.f_bavail, 3966 (long) st.f_files, 3967 (long) st.f_ffree, 3968 (long) st.f_favail, 3969 (long) st.f_flag, 3970 (long) st.f_namemax); 3971#else /* HAVE_LARGEFILE_SUPPORT */ 3972 return Py_BuildValue("(llLLLLLLll)", 3973 (long) st.f_bsize, 3974 (long) st.f_frsize, 3975 (LONG_LONG) st.f_blocks, 3976 (LONG_LONG) st.f_bfree, 3977 (LONG_LONG) st.f_bavail, 3978 (LONG_LONG) st.f_files, 3979 (LONG_LONG) st.f_ffree, 3980 (LONG_LONG) st.f_favail, 3981 (long) st.f_flag, 3982 (long) st.f_namemax); 3983#endif 3984} 3985#endif /* HAVE_STATVFS */ 3986 3987 3988#ifdef HAVE_TEMPNAM 3989static char posix_tempnam__doc__[] = "\ 3990tempnam([dir[, prefix]]) -> string\n\ 3991Return a unique name for a temporary file.\n\ 3992The directory and a short may be specified as strings; they may be omitted\n\ 3993or None if not needed."; 3994 3995static PyObject * 3996posix_tempnam(PyObject *self, PyObject *args) 3997{ 3998 PyObject *result = NULL; 3999 char *dir = NULL; 4000 char *pfx = NULL; 4001 char *name; 4002 4003 if (!PyArg_ParseTuple(args, "|zz:tempnam", &dir, &pfx)) 4004 return NULL; 4005 name = tempnam(dir, pfx); 4006 if (name == NULL) 4007 return PyErr_NoMemory(); 4008 result = PyString_FromString(name); 4009 free(name); 4010 return result; 4011} 4012#endif 4013 4014 4015#ifdef HAVE_TMPFILE 4016static char posix_tmpfile__doc__[] = "\ 4017tmpfile() -> file object\n\ 4018Create a temporary file with no directory entries."; 4019 4020static PyObject * 4021posix_tmpfile(PyObject *self, PyObject *args) 4022{ 4023 FILE *fp; 4024 4025 if (!PyArg_ParseTuple(args, ":tmpfile")) 4026 return NULL; 4027 fp = tmpfile(); 4028 if (fp == NULL) 4029 return posix_error(); 4030 return PyFile_FromFile(fp, "<tmpfile>", "w+", fclose); 4031} 4032#endif 4033 4034 4035#ifdef HAVE_TMPNAM 4036static char posix_tmpnam__doc__[] = "\ 4037tmpnam() -> string\n\ 4038Return a unique name for a temporary file."; 4039 4040static PyObject * 4041posix_tmpnam(PyObject *self, PyObject *args) 4042{ 4043 char buffer[L_tmpnam]; 4044 char *name; 4045 4046 if (!PyArg_ParseTuple(args, ":tmpnam")) 4047 return NULL; 4048#ifdef USE_TMPNAM_R 4049 name = tmpnam_r(buffer); 4050#else 4051 name = tmpnam(buffer); 4052#endif 4053 if (name == NULL) { 4054 PyErr_SetObject(PyExc_OSError, 4055 Py_BuildValue("is", 0, 4056#ifdef USE_TMPNAM_R 4057 "unexpected NULL from tmpnam_r" 4058#else 4059 "unexpected NULL from tmpnam" 4060#endif 4061 )); 4062 return NULL; 4063 } 4064 return PyString_FromString(buffer); 4065} 4066#endif 4067 4068 4069/* This is used for fpathconf(), pathconf(), confstr() and sysconf(). 4070 * It maps strings representing configuration variable names to 4071 * integer values, allowing those functions to be called with the 4072 * magic names instead of polluting the module's namespace with tons of 4073 * rarely-used constants. There are three separate tables that use 4074 * these definitions. 4075 * 4076 * This code is always included, even if none of the interfaces that 4077 * need it are included. The #if hackery needed to avoid it would be 4078 * sufficiently pervasive that it's not worth the loss of readability. 4079 */ 4080struct constdef { 4081 char *name; 4082 long value; 4083}; 4084 4085static int 4086conv_confname(PyObject *arg, int *valuep, struct constdef *table, 4087 size_t tablesize) 4088{ 4089 if (PyInt_Check(arg)) { 4090 *valuep = PyInt_AS_LONG(arg); 4091 return 1; 4092 } 4093 if (PyString_Check(arg)) { 4094 /* look up the value in the table using a binary search */ 4095 size_t lo = 0; 4096 size_t mid; 4097 size_t hi = tablesize; 4098 int cmp; 4099 char *confname = PyString_AS_STRING(arg); 4100 while (lo < hi) { 4101 mid = (lo + hi) / 2; 4102 cmp = strcmp(confname, table[mid].name); 4103 if (cmp < 0) 4104 hi = mid; 4105 else if (cmp > 0) 4106 lo = mid + 1; 4107 else { 4108 *valuep = table[mid].value; 4109 return 1; 4110 } 4111 } 4112 PyErr_SetString(PyExc_ValueError, "unrecognized configuration name"); 4113 } 4114 else 4115 PyErr_SetString(PyExc_TypeError, 4116 "configuration names must be strings or integers"); 4117 return 0; 4118} 4119 4120 4121#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF) 4122static struct constdef posix_constants_pathconf[] = { 4123#ifdef _PC_ABI_AIO_XFER_MAX 4124 {"PC_ABI_AIO_XFER_MAX", _PC_ABI_AIO_XFER_MAX}, 4125#endif 4126#ifdef _PC_ABI_ASYNC_IO 4127 {"PC_ABI_ASYNC_IO", _PC_ABI_ASYNC_IO}, 4128#endif 4129#ifdef _PC_ASYNC_IO 4130 {"PC_ASYNC_IO", _PC_ASYNC_IO}, 4131#endif 4132#ifdef _PC_CHOWN_RESTRICTED 4133 {"PC_CHOWN_RESTRICTED", _PC_CHOWN_RESTRICTED}, 4134#endif 4135#ifdef _PC_FILESIZEBITS 4136 {"PC_FILESIZEBITS", _PC_FILESIZEBITS}, 4137#endif 4138#ifdef _PC_LAST 4139 {"PC_LAST", _PC_LAST}, 4140#endif 4141#ifdef _PC_LINK_MAX 4142 {"PC_LINK_MAX", _PC_LINK_MAX}, 4143#endif 4144#ifdef _PC_MAX_CANON 4145 {"PC_MAX_CANON", _PC_MAX_CANON}, 4146#endif 4147#ifdef _PC_MAX_INPUT 4148 {"PC_MAX_INPUT", _PC_MAX_INPUT}, 4149#endif 4150#ifdef _PC_NAME_MAX 4151 {"PC_NAME_MAX", _PC_NAME_MAX}, 4152#endif 4153#ifdef _PC_NO_TRUNC 4154 {"PC_NO_TRUNC", _PC_NO_TRUNC}, 4155#endif 4156#ifdef _PC_PATH_MAX 4157 {"PC_PATH_MAX", _PC_PATH_MAX}, 4158#endif 4159#ifdef _PC_PIPE_BUF 4160 {"PC_PIPE_BUF", _PC_PIPE_BUF}, 4161#endif 4162#ifdef _PC_PRIO_IO 4163 {"PC_PRIO_IO", _PC_PRIO_IO}, 4164#endif 4165#ifdef _PC_SOCK_MAXBUF 4166 {"PC_SOCK_MAXBUF", _PC_SOCK_MAXBUF}, 4167#endif 4168#ifdef _PC_SYNC_IO 4169 {"PC_SYNC_IO", _PC_SYNC_IO}, 4170#endif 4171#ifdef _PC_VDISABLE 4172 {"PC_VDISABLE", _PC_VDISABLE}, 4173#endif 4174}; 4175 4176static int 4177conv_path_confname(PyObject *arg, int *valuep) 4178{ 4179 return conv_confname(arg, valuep, posix_constants_pathconf, 4180 sizeof(posix_constants_pathconf) 4181 / sizeof(struct constdef)); 4182} 4183#endif 4184 4185#ifdef HAVE_FPATHCONF 4186static char posix_fpathconf__doc__[] = "\ 4187fpathconf(fd, name) -> integer\n\ 4188Return the configuration limit name for the file descriptor fd.\n\ 4189If there is no limit, return -1."; 4190 4191static PyObject * 4192posix_fpathconf(PyObject *self, PyObject *args) 4193{ 4194 PyObject *result = NULL; 4195 int name, fd; 4196 4197 if (PyArg_ParseTuple(args, "iO&:fpathconf", &fd, 4198 conv_path_confname, &name)) { 4199 long limit; 4200 4201 errno = 0; 4202 limit = fpathconf(fd, name); 4203 if (limit == -1 && errno != 0) 4204 posix_error(); 4205 else 4206 result = PyInt_FromLong(limit); 4207 } 4208 return result; 4209} 4210#endif 4211 4212 4213#ifdef HAVE_PATHCONF 4214static char posix_pathconf__doc__[] = "\ 4215pathconf(path, name) -> integer\n\ 4216Return the configuration limit name for the file or directory path.\n\ 4217If there is no limit, return -1."; 4218 4219static PyObject * 4220posix_pathconf(PyObject *self, PyObject *args) 4221{ 4222 PyObject *result = NULL; 4223 int name; 4224 char *path; 4225 4226 if (PyArg_ParseTuple(args, "sO&:pathconf", &path, 4227 conv_path_confname, &name)) { 4228 long limit; 4229 4230 errno = 0; 4231 limit = pathconf(path, name); 4232 if (limit == -1 && errno != 0) { 4233 if (errno == EINVAL) 4234 /* could be a path or name problem */ 4235 posix_error(); 4236 else 4237 posix_error_with_filename(path); 4238 } 4239 else 4240 result = PyInt_FromLong(limit); 4241 } 4242 return result; 4243} 4244#endif 4245 4246#ifdef HAVE_CONFSTR 4247static struct constdef posix_constants_confstr[] = { 4248#ifdef _CS_ARCHITECTURE 4249 {"CS_ARCHITECTURE", _CS_ARCHITECTURE}, 4250#endif 4251#ifdef _CS_HOSTNAME 4252 {"CS_HOSTNAME", _CS_HOSTNAME}, 4253#endif 4254#ifdef _CS_HW_PROVIDER 4255 {"CS_HW_PROVIDER", _CS_HW_PROVIDER}, 4256#endif 4257#ifdef _CS_HW_SERIAL 4258 {"CS_HW_SERIAL", _CS_HW_SERIAL}, 4259#endif 4260#ifdef _CS_INITTAB_NAME 4261 {"CS_INITTAB_NAME", _CS_INITTAB_NAME}, 4262#endif 4263#ifdef _CS_LFS64_CFLAGS 4264 {"CS_LFS64_CFLAGS", _CS_LFS64_CFLAGS}, 4265#endif 4266#ifdef _CS_LFS64_LDFLAGS 4267 {"CS_LFS64_LDFLAGS", _CS_LFS64_LDFLAGS}, 4268#endif 4269#ifdef _CS_LFS64_LIBS 4270 {"CS_LFS64_LIBS", _CS_LFS64_LIBS}, 4271#endif 4272#ifdef _CS_LFS64_LINTFLAGS 4273 {"CS_LFS64_LINTFLAGS", _CS_LFS64_LINTFLAGS}, 4274#endif 4275#ifdef _CS_LFS_CFLAGS 4276 {"CS_LFS_CFLAGS", _CS_LFS_CFLAGS}, 4277#endif 4278#ifdef _CS_LFS_LDFLAGS 4279 {"CS_LFS_LDFLAGS", _CS_LFS_LDFLAGS}, 4280#endif 4281#ifdef _CS_LFS_LIBS 4282 {"CS_LFS_LIBS", _CS_LFS_LIBS}, 4283#endif 4284#ifdef _CS_LFS_LINTFLAGS 4285 {"CS_LFS_LINTFLAGS", _CS_LFS_LINTFLAGS}, 4286#endif 4287#ifdef _CS_MACHINE 4288 {"CS_MACHINE", _CS_MACHINE}, 4289#endif 4290#ifdef _CS_PATH 4291 {"CS_PATH", _CS_PATH}, 4292#endif 4293#ifdef _CS_RELEASE 4294 {"CS_RELEASE", _CS_RELEASE}, 4295#endif 4296#ifdef _CS_SRPC_DOMAIN 4297 {"CS_SRPC_DOMAIN", _CS_SRPC_DOMAIN}, 4298#endif 4299#ifdef _CS_SYSNAME 4300 {"CS_SYSNAME", _CS_SYSNAME}, 4301#endif 4302#ifdef _CS_VERSION 4303 {"CS_VERSION", _CS_VERSION}, 4304#endif 4305#ifdef _CS_XBS5_ILP32_OFF32_CFLAGS 4306 {"CS_XBS5_ILP32_OFF32_CFLAGS", _CS_XBS5_ILP32_OFF32_CFLAGS}, 4307#endif 4308#ifdef _CS_XBS5_ILP32_OFF32_LDFLAGS 4309 {"CS_XBS5_ILP32_OFF32_LDFLAGS", _CS_XBS5_ILP32_OFF32_LDFLAGS}, 4310#endif 4311#ifdef _CS_XBS5_ILP32_OFF32_LIBS 4312 {"CS_XBS5_ILP32_OFF32_LIBS", _CS_XBS5_ILP32_OFF32_LIBS}, 4313#endif 4314#ifdef _CS_XBS5_ILP32_OFF32_LINTFLAGS 4315 {"CS_XBS5_ILP32_OFF32_LINTFLAGS", _CS_XBS5_ILP32_OFF32_LINTFLAGS}, 4316#endif 4317#ifdef _CS_XBS5_ILP32_OFFBIG_CFLAGS 4318 {"CS_XBS5_ILP32_OFFBIG_CFLAGS", _CS_XBS5_ILP32_OFFBIG_CFLAGS}, 4319#endif 4320#ifdef _CS_XBS5_ILP32_OFFBIG_LDFLAGS 4321 {"CS_XBS5_ILP32_OFFBIG_LDFLAGS", _CS_XBS5_ILP32_OFFBIG_LDFLAGS}, 4322#endif 4323#ifdef _CS_XBS5_ILP32_OFFBIG_LIBS 4324 {"CS_XBS5_ILP32_OFFBIG_LIBS", _CS_XBS5_ILP32_OFFBIG_LIBS}, 4325#endif 4326#ifdef _CS_XBS5_ILP32_OFFBIG_LINTFLAGS 4327 {"CS_XBS5_ILP32_OFFBIG_LINTFLAGS", _CS_XBS5_ILP32_OFFBIG_LINTFLAGS}, 4328#endif 4329#ifdef _CS_XBS5_LP64_OFF64_CFLAGS 4330 {"CS_XBS5_LP64_OFF64_CFLAGS", _CS_XBS5_LP64_OFF64_CFLAGS}, 4331#endif 4332#ifdef _CS_XBS5_LP64_OFF64_LDFLAGS 4333 {"CS_XBS5_LP64_OFF64_LDFLAGS", _CS_XBS5_LP64_OFF64_LDFLAGS}, 4334#endif 4335#ifdef _CS_XBS5_LP64_OFF64_LIBS 4336 {"CS_XBS5_LP64_OFF64_LIBS", _CS_XBS5_LP64_OFF64_LIBS}, 4337#endif 4338#ifdef _CS_XBS5_LP64_OFF64_LINTFLAGS 4339 {"CS_XBS5_LP64_OFF64_LINTFLAGS", _CS_XBS5_LP64_OFF64_LINTFLAGS}, 4340#endif 4341#ifdef _CS_XBS5_LPBIG_OFFBIG_CFLAGS 4342 {"CS_XBS5_LPBIG_OFFBIG_CFLAGS", _CS_XBS5_LPBIG_OFFBIG_CFLAGS}, 4343#endif 4344#ifdef _CS_XBS5_LPBIG_OFFBIG_LDFLAGS 4345 {"CS_XBS5_LPBIG_OFFBIG_LDFLAGS", _CS_XBS5_LPBIG_OFFBIG_LDFLAGS}, 4346#endif 4347#ifdef _CS_XBS5_LPBIG_OFFBIG_LIBS 4348 {"CS_XBS5_LPBIG_OFFBIG_LIBS", _CS_XBS5_LPBIG_OFFBIG_LIBS}, 4349#endif 4350#ifdef _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS 4351 {"CS_XBS5_LPBIG_OFFBIG_LINTFLAGS", _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS}, 4352#endif 4353#ifdef _MIPS_CS_AVAIL_PROCESSORS 4354 {"MIPS_CS_AVAIL_PROCESSORS", _MIPS_CS_AVAIL_PROCESSORS}, 4355#endif 4356#ifdef _MIPS_CS_BASE 4357 {"MIPS_CS_BASE", _MIPS_CS_BASE}, 4358#endif 4359#ifdef _MIPS_CS_HOSTID 4360 {"MIPS_CS_HOSTID", _MIPS_CS_HOSTID}, 4361#endif 4362#ifdef _MIPS_CS_HW_NAME 4363 {"MIPS_CS_HW_NAME", _MIPS_CS_HW_NAME}, 4364#endif 4365#ifdef _MIPS_CS_NUM_PROCESSORS 4366 {"MIPS_CS_NUM_PROCESSORS", _MIPS_CS_NUM_PROCESSORS}, 4367#endif 4368#ifdef _MIPS_CS_OSREL_MAJ 4369 {"MIPS_CS_OSREL_MAJ", _MIPS_CS_OSREL_MAJ}, 4370#endif 4371#ifdef _MIPS_CS_OSREL_MIN 4372 {"MIPS_CS_OSREL_MIN", _MIPS_CS_OSREL_MIN}, 4373#endif 4374#ifdef _MIPS_CS_OSREL_PATCH 4375 {"MIPS_CS_OSREL_PATCH", _MIPS_CS_OSREL_PATCH}, 4376#endif 4377#ifdef _MIPS_CS_OS_NAME 4378 {"MIPS_CS_OS_NAME", _MIPS_CS_OS_NAME}, 4379#endif 4380#ifdef _MIPS_CS_OS_PROVIDER 4381 {"MIPS_CS_OS_PROVIDER", _MIPS_CS_OS_PROVIDER}, 4382#endif 4383#ifdef _MIPS_CS_PROCESSORS 4384 {"MIPS_CS_PROCESSORS", _MIPS_CS_PROCESSORS}, 4385#endif 4386#ifdef _MIPS_CS_SERIAL 4387 {"MIPS_CS_SERIAL", _MIPS_CS_SERIAL}, 4388#endif 4389#ifdef _MIPS_CS_VENDOR 4390 {"MIPS_CS_VENDOR", _MIPS_CS_VENDOR}, 4391#endif 4392}; 4393 4394static int 4395conv_confstr_confname(PyObject *arg, int *valuep) 4396{ 4397 return conv_confname(arg, valuep, posix_constants_confstr, 4398 sizeof(posix_constants_confstr) 4399 / sizeof(struct constdef)); 4400} 4401 4402static char posix_confstr__doc__[] = "\ 4403confstr(name) -> string\n\ 4404Return a string-valued system configuration variable."; 4405 4406static PyObject * 4407posix_confstr(PyObject *self, PyObject *args) 4408{ 4409 PyObject *result = NULL; 4410 int name; 4411 char buffer[64]; 4412 4413 if (PyArg_ParseTuple(args, "O&:confstr", conv_confstr_confname, &name)) { 4414 int len = confstr(name, buffer, sizeof(buffer)); 4415 4416 errno = 0; 4417 if (len == 0) { 4418 if (errno != 0) 4419 posix_error(); 4420 else 4421 result = PyString_FromString(""); 4422 } 4423 else { 4424 if (len >= sizeof(buffer)) { 4425 result = PyString_FromStringAndSize(NULL, len); 4426 if (result != NULL) 4427 confstr(name, PyString_AS_STRING(result), len+1); 4428 } 4429 else 4430 result = PyString_FromString(buffer); 4431 } 4432 } 4433 return result; 4434} 4435#endif 4436 4437 4438#ifdef HAVE_SYSCONF 4439static struct constdef posix_constants_sysconf[] = { 4440#ifdef _SC_2_CHAR_TERM 4441 {"SC_2_CHAR_TERM", _SC_2_CHAR_TERM}, 4442#endif 4443#ifdef _SC_2_C_BIND 4444 {"SC_2_C_BIND", _SC_2_C_BIND}, 4445#endif 4446#ifdef _SC_2_C_DEV 4447 {"SC_2_C_DEV", _SC_2_C_DEV}, 4448#endif 4449#ifdef _SC_2_C_VERSION 4450 {"SC_2_C_VERSION", _SC_2_C_VERSION}, 4451#endif 4452#ifdef _SC_2_FORT_DEV 4453 {"SC_2_FORT_DEV", _SC_2_FORT_DEV}, 4454#endif 4455#ifdef _SC_2_FORT_RUN 4456 {"SC_2_FORT_RUN", _SC_2_FORT_RUN}, 4457#endif 4458#ifdef _SC_2_LOCALEDEF 4459 {"SC_2_LOCALEDEF", _SC_2_LOCALEDEF}, 4460#endif 4461#ifdef _SC_2_SW_DEV 4462 {"SC_2_SW_DEV", _SC_2_SW_DEV}, 4463#endif 4464#ifdef _SC_2_UPE 4465 {"SC_2_UPE", _SC_2_UPE}, 4466#endif 4467#ifdef _SC_2_VERSION 4468 {"SC_2_VERSION", _SC_2_VERSION}, 4469#endif 4470#ifdef _SC_ABI_ASYNCHRONOUS_IO 4471 {"SC_ABI_ASYNCHRONOUS_IO", _SC_ABI_ASYNCHRONOUS_IO}, 4472#endif 4473#ifdef _SC_ACL 4474 {"SC_ACL", _SC_ACL}, 4475#endif 4476#ifdef _SC_AIO_LISTIO_MAX 4477 {"SC_AIO_LISTIO_MAX", _SC_AIO_LISTIO_MAX}, 4478#endif 4479#ifdef _SC_AIO_MAX 4480 {"SC_AIO_MAX", _SC_AIO_MAX}, 4481#endif 4482#ifdef _SC_AIO_PRIO_DELTA_MAX 4483 {"SC_AIO_PRIO_DELTA_MAX", _SC_AIO_PRIO_DELTA_MAX}, 4484#endif 4485#ifdef _SC_ARG_MAX 4486 {"SC_ARG_MAX", _SC_ARG_MAX}, 4487#endif 4488#ifdef _SC_ASYNCHRONOUS_IO 4489 {"SC_ASYNCHRONOUS_IO", _SC_ASYNCHRONOUS_IO}, 4490#endif 4491#ifdef _SC_ATEXIT_MAX 4492 {"SC_ATEXIT_MAX", _SC_ATEXIT_MAX}, 4493#endif 4494#ifdef _SC_AUDIT 4495 {"SC_AUDIT", _SC_AUDIT}, 4496#endif 4497#ifdef _SC_AVPHYS_PAGES 4498 {"SC_AVPHYS_PAGES", _SC_AVPHYS_PAGES}, 4499#endif 4500#ifdef _SC_BC_BASE_MAX 4501 {"SC_BC_BASE_MAX", _SC_BC_BASE_MAX}, 4502#endif 4503#ifdef _SC_BC_DIM_MAX 4504 {"SC_BC_DIM_MAX", _SC_BC_DIM_MAX}, 4505#endif 4506#ifdef _SC_BC_SCALE_MAX 4507 {"SC_BC_SCALE_MAX", _SC_BC_SCALE_MAX}, 4508#endif 4509#ifdef _SC_BC_STRING_MAX 4510 {"SC_BC_STRING_MAX", _SC_BC_STRING_MAX}, 4511#endif 4512#ifdef _SC_CAP 4513 {"SC_CAP", _SC_CAP}, 4514#endif 4515#ifdef _SC_CHARCLASS_NAME_MAX 4516 {"SC_CHARCLASS_NAME_MAX", _SC_CHARCLASS_NAME_MAX}, 4517#endif 4518#ifdef _SC_CHAR_BIT 4519 {"SC_CHAR_BIT", _SC_CHAR_BIT}, 4520#endif 4521#ifdef _SC_CHAR_MAX 4522 {"SC_CHAR_MAX", _SC_CHAR_MAX}, 4523#endif 4524#ifdef _SC_CHAR_MIN 4525 {"SC_CHAR_MIN", _SC_CHAR_MIN}, 4526#endif 4527#ifdef _SC_CHILD_MAX 4528 {"SC_CHILD_MAX", _SC_CHILD_MAX}, 4529#endif 4530#ifdef _SC_CLK_TCK 4531 {"SC_CLK_TCK", _SC_CLK_TCK}, 4532#endif 4533#ifdef _SC_COHER_BLKSZ 4534 {"SC_COHER_BLKSZ", _SC_COHER_BLKSZ}, 4535#endif 4536#ifdef _SC_COLL_WEIGHTS_MAX 4537 {"SC_COLL_WEIGHTS_MAX", _SC_COLL_WEIGHTS_MAX}, 4538#endif 4539#ifdef _SC_DCACHE_ASSOC 4540 {"SC_DCACHE_ASSOC", _SC_DCACHE_ASSOC}, 4541#endif 4542#ifdef _SC_DCACHE_BLKSZ 4543 {"SC_DCACHE_BLKSZ", _SC_DCACHE_BLKSZ}, 4544#endif 4545#ifdef _SC_DCACHE_LINESZ 4546 {"SC_DCACHE_LINESZ", _SC_DCACHE_LINESZ}, 4547#endif 4548#ifdef _SC_DCACHE_SZ 4549 {"SC_DCACHE_SZ", _SC_DCACHE_SZ}, 4550#endif 4551#ifdef _SC_DCACHE_TBLKSZ 4552 {"SC_DCACHE_TBLKSZ", _SC_DCACHE_TBLKSZ}, 4553#endif 4554#ifdef _SC_DELAYTIMER_MAX 4555 {"SC_DELAYTIMER_MAX", _SC_DELAYTIMER_MAX}, 4556#endif 4557#ifdef _SC_EQUIV_CLASS_MAX 4558 {"SC_EQUIV_CLASS_MAX", _SC_EQUIV_CLASS_MAX}, 4559#endif 4560#ifdef _SC_EXPR_NEST_MAX 4561 {"SC_EXPR_NEST_MAX", _SC_EXPR_NEST_MAX}, 4562#endif 4563#ifdef _SC_FSYNC 4564 {"SC_FSYNC", _SC_FSYNC}, 4565#endif 4566#ifdef _SC_GETGR_R_SIZE_MAX 4567 {"SC_GETGR_R_SIZE_MAX", _SC_GETGR_R_SIZE_MAX}, 4568#endif 4569#ifdef _SC_GETPW_R_SIZE_MAX 4570 {"SC_GETPW_R_SIZE_MAX", _SC_GETPW_R_SIZE_MAX}, 4571#endif 4572#ifdef _SC_ICACHE_ASSOC 4573 {"SC_ICACHE_ASSOC", _SC_ICACHE_ASSOC}, 4574#endif 4575#ifdef _SC_ICACHE_BLKSZ 4576 {"SC_ICACHE_BLKSZ", _SC_ICACHE_BLKSZ}, 4577#endif 4578#ifdef _SC_ICACHE_LINESZ 4579 {"SC_ICACHE_LINESZ", _SC_ICACHE_LINESZ}, 4580#endif 4581#ifdef _SC_ICACHE_SZ 4582 {"SC_ICACHE_SZ", _SC_ICACHE_SZ}, 4583#endif 4584#ifdef _SC_INF 4585 {"SC_INF", _SC_INF}, 4586#endif 4587#ifdef _SC_INT_MAX 4588 {"SC_INT_MAX", _SC_INT_MAX}, 4589#endif 4590#ifdef _SC_INT_MIN 4591 {"SC_INT_MIN", _SC_INT_MIN}, 4592#endif 4593#ifdef _SC_IOV_MAX 4594 {"SC_IOV_MAX", _SC_IOV_MAX}, 4595#endif 4596#ifdef _SC_IP_SECOPTS 4597 {"SC_IP_SECOPTS", _SC_IP_SECOPTS}, 4598#endif 4599#ifdef _SC_JOB_CONTROL 4600 {"SC_JOB_CONTROL", _SC_JOB_CONTROL}, 4601#endif 4602#ifdef _SC_KERN_POINTERS 4603 {"SC_KERN_POINTERS", _SC_KERN_POINTERS}, 4604#endif 4605#ifdef _SC_KERN_SIM 4606 {"SC_KERN_SIM", _SC_KERN_SIM}, 4607#endif 4608#ifdef _SC_LINE_MAX 4609 {"SC_LINE_MAX", _SC_LINE_MAX}, 4610#endif 4611#ifdef _SC_LOGIN_NAME_MAX 4612 {"SC_LOGIN_NAME_MAX", _SC_LOGIN_NAME_MAX}, 4613#endif 4614#ifdef _SC_LOGNAME_MAX 4615 {"SC_LOGNAME_MAX", _SC_LOGNAME_MAX}, 4616#endif 4617#ifdef _SC_LONG_BIT 4618 {"SC_LONG_BIT", _SC_LONG_BIT}, 4619#endif 4620#ifdef _SC_MAC 4621 {"SC_MAC", _SC_MAC}, 4622#endif 4623#ifdef _SC_MAPPED_FILES 4624 {"SC_MAPPED_FILES", _SC_MAPPED_FILES}, 4625#endif 4626#ifdef _SC_MAXPID 4627 {"SC_MAXPID", _SC_MAXPID}, 4628#endif 4629#ifdef _SC_MB_LEN_MAX 4630 {"SC_MB_LEN_MAX", _SC_MB_LEN_MAX}, 4631#endif 4632#ifdef _SC_MEMLOCK 4633 {"SC_MEMLOCK", _SC_MEMLOCK}, 4634#endif 4635#ifdef _SC_MEMLOCK_RANGE 4636 {"SC_MEMLOCK_RANGE", _SC_MEMLOCK_RANGE}, 4637#endif 4638#ifdef _SC_MEMORY_PROTECTION 4639 {"SC_MEMORY_PROTECTION", _SC_MEMORY_PROTECTION}, 4640#endif 4641#ifdef _SC_MESSAGE_PASSING 4642 {"SC_MESSAGE_PASSING", _SC_MESSAGE_PASSING}, 4643#endif 4644#ifdef _SC_MMAP_FIXED_ALIGNMENT 4645 {"SC_MMAP_FIXED_ALIGNMENT", _SC_MMAP_FIXED_ALIGNMENT}, 4646#endif 4647#ifdef _SC_MQ_OPEN_MAX 4648 {"SC_MQ_OPEN_MAX", _SC_MQ_OPEN_MAX}, 4649#endif 4650#ifdef _SC_MQ_PRIO_MAX 4651 {"SC_MQ_PRIO_MAX", _SC_MQ_PRIO_MAX}, 4652#endif 4653#ifdef _SC_NACLS_MAX 4654 {"SC_NACLS_MAX", _SC_NACLS_MAX}, 4655#endif 4656#ifdef _SC_NGROUPS_MAX 4657 {"SC_NGROUPS_MAX", _SC_NGROUPS_MAX}, 4658#endif 4659#ifdef _SC_NL_ARGMAX 4660 {"SC_NL_ARGMAX", _SC_NL_ARGMAX}, 4661#endif 4662#ifdef _SC_NL_LANGMAX 4663 {"SC_NL_LANGMAX", _SC_NL_LANGMAX}, 4664#endif 4665#ifdef _SC_NL_MSGMAX 4666 {"SC_NL_MSGMAX", _SC_NL_MSGMAX}, 4667#endif 4668#ifdef _SC_NL_NMAX 4669 {"SC_NL_NMAX", _SC_NL_NMAX}, 4670#endif 4671#ifdef _SC_NL_SETMAX 4672 {"SC_NL_SETMAX", _SC_NL_SETMAX}, 4673#endif 4674#ifdef _SC_NL_TEXTMAX 4675 {"SC_NL_TEXTMAX", _SC_NL_TEXTMAX}, 4676#endif 4677#ifdef _SC_NPROCESSORS_CONF 4678 {"SC_NPROCESSORS_CONF", _SC_NPROCESSORS_CONF}, 4679#endif 4680#ifdef _SC_NPROCESSORS_ONLN 4681 {"SC_NPROCESSORS_ONLN", _SC_NPROCESSORS_ONLN}, 4682#endif 4683#ifdef _SC_NPROC_CONF 4684 {"SC_NPROC_CONF", _SC_NPROC_CONF}, 4685#endif 4686#ifdef _SC_NPROC_ONLN 4687 {"SC_NPROC_ONLN", _SC_NPROC_ONLN}, 4688#endif 4689#ifdef _SC_NZERO 4690 {"SC_NZERO", _SC_NZERO}, 4691#endif 4692#ifdef _SC_OPEN_MAX 4693 {"SC_OPEN_MAX", _SC_OPEN_MAX}, 4694#endif 4695#ifdef _SC_PAGESIZE 4696 {"SC_PAGESIZE", _SC_PAGESIZE}, 4697#endif 4698#ifdef _SC_PAGE_SIZE 4699 {"SC_PAGE_SIZE", _SC_PAGE_SIZE}, 4700#endif 4701#ifdef _SC_PASS_MAX 4702 {"SC_PASS_MAX", _SC_PASS_MAX}, 4703#endif 4704#ifdef _SC_PHYS_PAGES 4705 {"SC_PHYS_PAGES", _SC_PHYS_PAGES}, 4706#endif 4707#ifdef _SC_PII 4708 {"SC_PII", _SC_PII}, 4709#endif 4710#ifdef _SC_PII_INTERNET 4711 {"SC_PII_INTERNET", _SC_PII_INTERNET}, 4712#endif 4713#ifdef _SC_PII_INTERNET_DGRAM 4714 {"SC_PII_INTERNET_DGRAM", _SC_PII_INTERNET_DGRAM}, 4715#endif 4716#ifdef _SC_PII_INTERNET_STREAM 4717 {"SC_PII_INTERNET_STREAM", _SC_PII_INTERNET_STREAM}, 4718#endif 4719#ifdef _SC_PII_OSI 4720 {"SC_PII_OSI", _SC_PII_OSI}, 4721#endif 4722#ifdef _SC_PII_OSI_CLTS 4723 {"SC_PII_OSI_CLTS", _SC_PII_OSI_CLTS}, 4724#endif 4725#ifdef _SC_PII_OSI_COTS 4726 {"SC_PII_OSI_COTS", _SC_PII_OSI_COTS}, 4727#endif 4728#ifdef _SC_PII_OSI_M 4729 {"SC_PII_OSI_M", _SC_PII_OSI_M}, 4730#endif 4731#ifdef _SC_PII_SOCKET 4732 {"SC_PII_SOCKET", _SC_PII_SOCKET}, 4733#endif 4734#ifdef _SC_PII_XTI 4735 {"SC_PII_XTI", _SC_PII_XTI}, 4736#endif 4737#ifdef _SC_POLL 4738 {"SC_POLL", _SC_POLL}, 4739#endif 4740#ifdef _SC_PRIORITIZED_IO 4741 {"SC_PRIORITIZED_IO", _SC_PRIORITIZED_IO}, 4742#endif 4743#ifdef _SC_PRIORITY_SCHEDULING 4744 {"SC_PRIORITY_SCHEDULING", _SC_PRIORITY_SCHEDULING}, 4745#endif 4746#ifdef _SC_REALTIME_SIGNALS 4747 {"SC_REALTIME_SIGNALS", _SC_REALTIME_SIGNALS}, 4748#endif 4749#ifdef _SC_RE_DUP_MAX 4750 {"SC_RE_DUP_MAX", _SC_RE_DUP_MAX}, 4751#endif 4752#ifdef _SC_RTSIG_MAX 4753 {"SC_RTSIG_MAX", _SC_RTSIG_MAX}, 4754#endif 4755#ifdef _SC_SAVED_IDS 4756 {"SC_SAVED_IDS", _SC_SAVED_IDS}, 4757#endif 4758#ifdef _SC_SCHAR_MAX 4759 {"SC_SCHAR_MAX", _SC_SCHAR_MAX}, 4760#endif 4761#ifdef _SC_SCHAR_MIN 4762 {"SC_SCHAR_MIN", _SC_SCHAR_MIN}, 4763#endif 4764#ifdef _SC_SELECT 4765 {"SC_SELECT", _SC_SELECT}, 4766#endif 4767#ifdef _SC_SEMAPHORES 4768 {"SC_SEMAPHORES", _SC_SEMAPHORES}, 4769#endif 4770#ifdef _SC_SEM_NSEMS_MAX 4771 {"SC_SEM_NSEMS_MAX", _SC_SEM_NSEMS_MAX}, 4772#endif 4773#ifdef _SC_SEM_VALUE_MAX 4774 {"SC_SEM_VALUE_MAX", _SC_SEM_VALUE_MAX}, 4775#endif 4776#ifdef _SC_SHARED_MEMORY_OBJECTS 4777 {"SC_SHARED_MEMORY_OBJECTS", _SC_SHARED_MEMORY_OBJECTS}, 4778#endif 4779#ifdef _SC_SHRT_MAX 4780 {"SC_SHRT_MAX", _SC_SHRT_MAX}, 4781#endif 4782#ifdef _SC_SHRT_MIN 4783 {"SC_SHRT_MIN", _SC_SHRT_MIN}, 4784#endif 4785#ifdef _SC_SIGQUEUE_MAX 4786 {"SC_SIGQUEUE_MAX", _SC_SIGQUEUE_MAX}, 4787#endif 4788#ifdef _SC_SIGRT_MAX 4789 {"SC_SIGRT_MAX", _SC_SIGRT_MAX}, 4790#endif 4791#ifdef _SC_SIGRT_MIN 4792 {"SC_SIGRT_MIN", _SC_SIGRT_MIN}, 4793#endif 4794#ifdef _SC_SOFTPOWER 4795 {"SC_SOFTPOWER", _SC_SOFTPOWER}, 4796#endif 4797#ifdef _SC_SPLIT_CACHE 4798 {"SC_SPLIT_CACHE", _SC_SPLIT_CACHE}, 4799#endif 4800#ifdef _SC_SSIZE_MAX 4801 {"SC_SSIZE_MAX", _SC_SSIZE_MAX}, 4802#endif 4803#ifdef _SC_STACK_PROT 4804 {"SC_STACK_PROT", _SC_STACK_PROT}, 4805#endif 4806#ifdef _SC_STREAM_MAX 4807 {"SC_STREAM_MAX", _SC_STREAM_MAX}, 4808#endif 4809#ifdef _SC_SYNCHRONIZED_IO 4810 {"SC_SYNCHRONIZED_IO", _SC_SYNCHRONIZED_IO}, 4811#endif 4812#ifdef _SC_THREADS 4813 {"SC_THREADS", _SC_THREADS}, 4814#endif 4815#ifdef _SC_THREAD_ATTR_STACKADDR 4816 {"SC_THREAD_ATTR_STACKADDR", _SC_THREAD_ATTR_STACKADDR}, 4817#endif 4818#ifdef _SC_THREAD_ATTR_STACKSIZE 4819 {"SC_THREAD_ATTR_STACKSIZE", _SC_THREAD_ATTR_STACKSIZE}, 4820#endif 4821#ifdef _SC_THREAD_DESTRUCTOR_ITERATIONS 4822 {"SC_THREAD_DESTRUCTOR_ITERATIONS", _SC_THREAD_DESTRUCTOR_ITERATIONS}, 4823#endif 4824#ifdef _SC_THREAD_KEYS_MAX 4825 {"SC_THREAD_KEYS_MAX", _SC_THREAD_KEYS_MAX}, 4826#endif 4827#ifdef _SC_THREAD_PRIORITY_SCHEDULING 4828 {"SC_THREAD_PRIORITY_SCHEDULING", _SC_THREAD_PRIORITY_SCHEDULING}, 4829#endif 4830#ifdef _SC_THREAD_PRIO_INHERIT 4831 {"SC_THREAD_PRIO_INHERIT", _SC_THREAD_PRIO_INHERIT}, 4832#endif 4833#ifdef _SC_THREAD_PRIO_PROTECT 4834 {"SC_THREAD_PRIO_PROTECT", _SC_THREAD_PRIO_PROTECT}, 4835#endif 4836#ifdef _SC_THREAD_PROCESS_SHARED 4837 {"SC_THREAD_PROCESS_SHARED", _SC_THREAD_PROCESS_SHARED}, 4838#endif 4839#ifdef _SC_THREAD_SAFE_FUNCTIONS 4840 {"SC_THREAD_SAFE_FUNCTIONS", _SC_THREAD_SAFE_FUNCTIONS}, 4841#endif 4842#ifdef _SC_THREAD_STACK_MIN 4843 {"SC_THREAD_STACK_MIN", _SC_THREAD_STACK_MIN}, 4844#endif 4845#ifdef _SC_THREAD_THREADS_MAX 4846 {"SC_THREAD_THREADS_MAX", _SC_THREAD_THREADS_MAX}, 4847#endif 4848#ifdef _SC_TIMERS 4849 {"SC_TIMERS", _SC_TIMERS}, 4850#endif 4851#ifdef _SC_TIMER_MAX 4852 {"SC_TIMER_MAX", _SC_TIMER_MAX}, 4853#endif 4854#ifdef _SC_TTY_NAME_MAX 4855 {"SC_TTY_NAME_MAX", _SC_TTY_NAME_MAX}, 4856#endif 4857#ifdef _SC_TZNAME_MAX 4858 {"SC_TZNAME_MAX", _SC_TZNAME_MAX}, 4859#endif 4860#ifdef _SC_T_IOV_MAX 4861 {"SC_T_IOV_MAX", _SC_T_IOV_MAX}, 4862#endif 4863#ifdef _SC_UCHAR_MAX 4864 {"SC_UCHAR_MAX", _SC_UCHAR_MAX}, 4865#endif 4866#ifdef _SC_UINT_MAX 4867 {"SC_UINT_MAX", _SC_UINT_MAX}, 4868#endif 4869#ifdef _SC_UIO_MAXIOV 4870 {"SC_UIO_MAXIOV", _SC_UIO_MAXIOV}, 4871#endif 4872#ifdef _SC_ULONG_MAX 4873 {"SC_ULONG_MAX", _SC_ULONG_MAX}, 4874#endif 4875#ifdef _SC_USHRT_MAX 4876 {"SC_USHRT_MAX", _SC_USHRT_MAX}, 4877#endif 4878#ifdef _SC_VERSION 4879 {"SC_VERSION", _SC_VERSION}, 4880#endif 4881#ifdef _SC_WORD_BIT 4882 {"SC_WORD_BIT", _SC_WORD_BIT}, 4883#endif 4884#ifdef _SC_XBS5_ILP32_OFF32 4885 {"SC_XBS5_ILP32_OFF32", _SC_XBS5_ILP32_OFF32}, 4886#endif 4887#ifdef _SC_XBS5_ILP32_OFFBIG 4888 {"SC_XBS5_ILP32_OFFBIG", _SC_XBS5_ILP32_OFFBIG}, 4889#endif 4890#ifdef _SC_XBS5_LP64_OFF64 4891 {"SC_XBS5_LP64_OFF64", _SC_XBS5_LP64_OFF64}, 4892#endif 4893#ifdef _SC_XBS5_LPBIG_OFFBIG 4894 {"SC_XBS5_LPBIG_OFFBIG", _SC_XBS5_LPBIG_OFFBIG}, 4895#endif 4896#ifdef _SC_XOPEN_CRYPT 4897 {"SC_XOPEN_CRYPT", _SC_XOPEN_CRYPT}, 4898#endif 4899#ifdef _SC_XOPEN_ENH_I18N 4900 {"SC_XOPEN_ENH_I18N", _SC_XOPEN_ENH_I18N}, 4901#endif 4902#ifdef _SC_XOPEN_LEGACY 4903 {"SC_XOPEN_LEGACY", _SC_XOPEN_LEGACY}, 4904#endif 4905#ifdef _SC_XOPEN_REALTIME 4906 {"SC_XOPEN_REALTIME", _SC_XOPEN_REALTIME}, 4907#endif 4908#ifdef _SC_XOPEN_REALTIME_THREADS 4909 {"SC_XOPEN_REALTIME_THREADS", _SC_XOPEN_REALTIME_THREADS}, 4910#endif 4911#ifdef _SC_XOPEN_SHM 4912 {"SC_XOPEN_SHM", _SC_XOPEN_SHM}, 4913#endif 4914#ifdef _SC_XOPEN_UNIX 4915 {"SC_XOPEN_UNIX", _SC_XOPEN_UNIX}, 4916#endif 4917#ifdef _SC_XOPEN_VERSION 4918 {"SC_XOPEN_VERSION", _SC_XOPEN_VERSION}, 4919#endif 4920#ifdef _SC_XOPEN_XCU_VERSION 4921 {"SC_XOPEN_XCU_VERSION", _SC_XOPEN_XCU_VERSION}, 4922#endif 4923#ifdef _SC_XOPEN_XPG2 4924 {"SC_XOPEN_XPG2", _SC_XOPEN_XPG2}, 4925#endif 4926#ifdef _SC_XOPEN_XPG3 4927 {"SC_XOPEN_XPG3", _SC_XOPEN_XPG3}, 4928#endif 4929#ifdef _SC_XOPEN_XPG4 4930 {"SC_XOPEN_XPG4", _SC_XOPEN_XPG4}, 4931#endif 4932}; 4933 4934static int 4935conv_sysconf_confname(PyObject *arg, int *valuep) 4936{ 4937 return conv_confname(arg, valuep, posix_constants_sysconf, 4938 sizeof(posix_constants_sysconf) 4939 / sizeof(struct constdef)); 4940} 4941 4942static char posix_sysconf__doc__[] = "\ 4943sysconf(name) -> integer\n\ 4944Return an integer-valued system configuration variable."; 4945 4946static PyObject * 4947posix_sysconf(PyObject *self, PyObject *args) 4948{ 4949 PyObject *result = NULL; 4950 int name; 4951 4952 if (PyArg_ParseTuple(args, "O&:sysconf", conv_sysconf_confname, &name)) { 4953 int value; 4954 4955 errno = 0; 4956 value = sysconf(name); 4957 if (value == -1 && errno != 0) 4958 posix_error(); 4959 else 4960 result = PyInt_FromLong(value); 4961 } 4962 return result; 4963} 4964#endif 4965 4966 4967/* This code is used to ensure that the tables of configuration value names 4968 * are in sorted order as required by conv_confname(), and also to build the 4969 * the exported dictionaries that are used to publish information about the 4970 * names available on the host platform. 4971 * 4972 * Sorting the table at runtime ensures that the table is properly ordered 4973 * when used, even for platforms we're not able to test on. It also makes 4974 * it easier to add additional entries to the tables. 4975 */ 4976 4977static int 4978cmp_constdefs(const void *v1, const void *v2) 4979{ 4980 const struct constdef *c1 = 4981 (const struct constdef *) v1; 4982 const struct constdef *c2 = 4983 (const struct constdef *) v2; 4984 4985 return strcmp(c1->name, c2->name); 4986} 4987 4988static int 4989setup_confname_table(struct constdef *table, size_t tablesize, 4990 char *tablename, PyObject *moddict) 4991{ 4992 PyObject *d = NULL; 4993 size_t i; 4994 int status; 4995 4996 qsort(table, tablesize, sizeof(struct constdef), cmp_constdefs); 4997 d = PyDict_New(); 4998 if (d == NULL) 4999 return -1; 5000 5001 for (i=0; i < tablesize; ++i) { 5002 PyObject *o = PyInt_FromLong(table[i].value); 5003 if (o == NULL || PyDict_SetItemString(d, table[i].name, o) == -1) { 5004 Py_XDECREF(o); 5005 Py_DECREF(d); 5006 return -1; 5007 } 5008 Py_DECREF(o); 5009 } 5010 status = PyDict_SetItemString(moddict, tablename, d); 5011 Py_DECREF(d); 5012 return status; 5013} 5014 5015/* Return -1 on failure, 0 on success. */ 5016static int 5017setup_confname_tables(PyObject *moddict) 5018{ 5019#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF) 5020 if (setup_confname_table(posix_constants_pathconf, 5021 sizeof(posix_constants_pathconf) 5022 / sizeof(struct constdef), 5023 "pathconf_names", moddict)) 5024 return -1; 5025#endif 5026#ifdef HAVE_CONFSTR 5027 if (setup_confname_table(posix_constants_confstr, 5028 sizeof(posix_constants_confstr) 5029 / sizeof(struct constdef), 5030 "confstr_names", moddict)) 5031 return -1; 5032#endif 5033#ifdef HAVE_SYSCONF 5034 if (setup_confname_table(posix_constants_sysconf, 5035 sizeof(posix_constants_sysconf) 5036 / sizeof(struct constdef), 5037 "sysconf_names", moddict)) 5038 return -1; 5039#endif 5040 return 0; 5041} 5042 5043 5044static char posix_abort__doc__[] = "\ 5045abort() -> does not return!\n\ 5046Abort the interpreter immediately. This 'dumps core' or otherwise fails\n\ 5047in the hardest way possible on the hosting operating system."; 5048 5049static PyObject * 5050posix_abort(PyObject *self, PyObject *args) 5051{ 5052 if (!PyArg_ParseTuple(args, ":abort")) 5053 return NULL; 5054 abort(); 5055 /*NOTREACHED*/ 5056 Py_FatalError("abort() called from Python code didn't abort!"); 5057 return NULL; 5058} 5059 5060 5061static PyMethodDef posix_methods[] = { 5062 {"access", posix_access, METH_VARARGS, posix_access__doc__}, 5063#ifdef HAVE_TTYNAME 5064 {"ttyname", posix_ttyname, METH_VARARGS, posix_ttyname__doc__}, 5065#endif 5066 {"chdir", posix_chdir, METH_VARARGS, posix_chdir__doc__}, 5067 {"chmod", posix_chmod, METH_VARARGS, posix_chmod__doc__}, 5068#ifdef HAVE_CHOWN 5069 {"chown", posix_chown, METH_VARARGS, posix_chown__doc__}, 5070#endif /* HAVE_CHOWN */ 5071#ifdef HAVE_CTERMID 5072 {"ctermid", posix_ctermid, METH_VARARGS, posix_ctermid__doc__}, 5073#endif 5074#ifdef HAVE_GETCWD 5075 {"getcwd", posix_getcwd, METH_VARARGS, posix_getcwd__doc__}, 5076#endif 5077#ifdef HAVE_LINK 5078 {"link", posix_link, METH_VARARGS, posix_link__doc__}, 5079#endif /* HAVE_LINK */ 5080 {"listdir", posix_listdir, METH_VARARGS, posix_listdir__doc__}, 5081 {"lstat", posix_lstat, METH_VARARGS, posix_lstat__doc__}, 5082 {"mkdir", posix_mkdir, METH_VARARGS, posix_mkdir__doc__}, 5083#ifdef HAVE_NICE 5084 {"nice", posix_nice, METH_VARARGS, posix_nice__doc__}, 5085#endif /* HAVE_NICE */ 5086#ifdef HAVE_READLINK 5087 {"readlink", posix_readlink, METH_VARARGS, posix_readlink__doc__}, 5088#endif /* HAVE_READLINK */ 5089 {"rename", posix_rename, METH_VARARGS, posix_rename__doc__}, 5090 {"rmdir", posix_rmdir, METH_VARARGS, posix_rmdir__doc__}, 5091 {"stat", posix_stat, METH_VARARGS, posix_stat__doc__}, 5092#ifdef HAVE_SYMLINK 5093 {"symlink", posix_symlink, METH_VARARGS, posix_symlink__doc__}, 5094#endif /* HAVE_SYMLINK */ 5095#ifdef HAVE_SYSTEM 5096 {"system", posix_system, METH_VARARGS, posix_system__doc__}, 5097#endif 5098 {"umask", posix_umask, METH_VARARGS, posix_umask__doc__}, 5099#ifdef HAVE_UNAME 5100 {"uname", posix_uname, METH_VARARGS, posix_uname__doc__}, 5101#endif /* HAVE_UNAME */ 5102 {"unlink", posix_unlink, METH_VARARGS, posix_unlink__doc__}, 5103 {"remove", posix_unlink, METH_VARARGS, posix_remove__doc__}, 5104 {"utime", posix_utime, METH_VARARGS, posix_utime__doc__}, 5105#ifdef HAVE_TIMES 5106 {"times", posix_times, METH_VARARGS, posix_times__doc__}, 5107#endif /* HAVE_TIMES */ 5108 {"_exit", posix__exit, METH_VARARGS, posix__exit__doc__}, 5109#ifdef HAVE_EXECV 5110 {"execv", posix_execv, METH_VARARGS, posix_execv__doc__}, 5111 {"execve", posix_execve, METH_VARARGS, posix_execve__doc__}, 5112#endif /* HAVE_EXECV */ 5113#ifdef HAVE_SPAWNV 5114 {"spawnv", posix_spawnv, METH_VARARGS, posix_spawnv__doc__}, 5115 {"spawnve", posix_spawnve, METH_VARARGS, posix_spawnve__doc__}, 5116#endif /* HAVE_SPAWNV */ 5117#ifdef HAVE_FORK 5118 {"fork", posix_fork, METH_VARARGS, posix_fork__doc__}, 5119#endif /* HAVE_FORK */ 5120#if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) 5121 {"openpty", posix_openpty, METH_VARARGS, posix_openpty__doc__}, 5122#endif /* HAVE_OPENPTY || HAVE__GETPTY */ 5123#ifdef HAVE_FORKPTY 5124 {"forkpty", posix_forkpty, METH_VARARGS, posix_forkpty__doc__}, 5125#endif /* HAVE_FORKPTY */ 5126#ifdef HAVE_GETEGID 5127 {"getegid", posix_getegid, METH_VARARGS, posix_getegid__doc__}, 5128#endif /* HAVE_GETEGID */ 5129#ifdef HAVE_GETEUID 5130 {"geteuid", posix_geteuid, METH_VARARGS, posix_geteuid__doc__}, 5131#endif /* HAVE_GETEUID */ 5132#ifdef HAVE_GETGID 5133 {"getgid", posix_getgid, METH_VARARGS, posix_getgid__doc__}, 5134#endif /* HAVE_GETGID */ 5135#ifdef HAVE_GETGROUPS 5136 {"getgroups", posix_getgroups, METH_VARARGS, posix_getgroups__doc__}, 5137#endif 5138 {"getpid", posix_getpid, METH_VARARGS, posix_getpid__doc__}, 5139#ifdef HAVE_GETPGRP 5140 {"getpgrp", posix_getpgrp, METH_VARARGS, posix_getpgrp__doc__}, 5141#endif /* HAVE_GETPGRP */ 5142#ifdef HAVE_GETPPID 5143 {"getppid", posix_getppid, METH_VARARGS, posix_getppid__doc__}, 5144#endif /* HAVE_GETPPID */ 5145#ifdef HAVE_GETUID 5146 {"getuid", posix_getuid, METH_VARARGS, posix_getuid__doc__}, 5147#endif /* HAVE_GETUID */ 5148#ifdef HAVE_GETLOGIN 5149 {"getlogin", posix_getlogin, METH_VARARGS, posix_getlogin__doc__}, 5150#endif 5151#ifdef HAVE_KILL 5152 {"kill", posix_kill, METH_VARARGS, posix_kill__doc__}, 5153#endif /* HAVE_KILL */ 5154#ifdef HAVE_PLOCK 5155 {"plock", posix_plock, METH_VARARGS, posix_plock__doc__}, 5156#endif /* HAVE_PLOCK */ 5157#ifdef HAVE_POPEN 5158 {"popen", posix_popen, METH_VARARGS, posix_popen__doc__}, 5159#ifdef MS_WIN32 5160 {"popen2", win32_popen2, METH_VARARGS}, 5161 {"popen3", win32_popen3, METH_VARARGS}, 5162 {"popen4", win32_popen4, METH_VARARGS}, 5163#endif 5164#endif /* HAVE_POPEN */ 5165#ifdef HAVE_SETUID 5166 {"setuid", posix_setuid, METH_VARARGS, posix_setuid__doc__}, 5167#endif /* HAVE_SETUID */ 5168#ifdef HAVE_SETEUID 5169 {"seteuid", posix_seteuid, METH_VARARGS, posix_seteuid__doc__}, 5170#endif /* HAVE_SETEUID */ 5171#ifdef HAVE_SETEGID 5172 {"setegid", posix_setegid, METH_VARARGS, posix_setegid__doc__}, 5173#endif /* HAVE_SETEGID */ 5174#ifdef HAVE_SETREUID 5175 {"setreuid", posix_setreuid, METH_VARARGS, posix_setreuid__doc__}, 5176#endif /* HAVE_SETREUID */ 5177#ifdef HAVE_SETREGID 5178 {"setregid", posix_setregid, METH_VARARGS, posix_setregid__doc__}, 5179#endif /* HAVE_SETREGID */ 5180#ifdef HAVE_SETGID 5181 {"setgid", posix_setgid, METH_VARARGS, posix_setgid__doc__}, 5182#endif /* HAVE_SETGID */ 5183#ifdef HAVE_SETPGRP 5184 {"setpgrp", posix_setpgrp, METH_VARARGS, posix_setpgrp__doc__}, 5185#endif /* HAVE_SETPGRP */ 5186#ifdef HAVE_WAIT 5187 {"wait", posix_wait, METH_VARARGS, posix_wait__doc__}, 5188#endif /* HAVE_WAIT */ 5189#ifdef HAVE_WAITPID 5190 {"waitpid", posix_waitpid, METH_VARARGS, posix_waitpid__doc__}, 5191#endif /* HAVE_WAITPID */ 5192#ifdef HAVE_SETSID 5193 {"setsid", posix_setsid, METH_VARARGS, posix_setsid__doc__}, 5194#endif /* HAVE_SETSID */ 5195#ifdef HAVE_SETPGID 5196 {"setpgid", posix_setpgid, METH_VARARGS, posix_setpgid__doc__}, 5197#endif /* HAVE_SETPGID */ 5198#ifdef HAVE_TCGETPGRP 5199 {"tcgetpgrp", posix_tcgetpgrp, METH_VARARGS, posix_tcgetpgrp__doc__}, 5200#endif /* HAVE_TCGETPGRP */ 5201#ifdef HAVE_TCSETPGRP 5202 {"tcsetpgrp", posix_tcsetpgrp, METH_VARARGS, posix_tcsetpgrp__doc__}, 5203#endif /* HAVE_TCSETPGRP */ 5204 {"open", posix_open, METH_VARARGS, posix_open__doc__}, 5205 {"close", posix_close, METH_VARARGS, posix_close__doc__}, 5206 {"dup", posix_dup, METH_VARARGS, posix_dup__doc__}, 5207 {"dup2", posix_dup2, METH_VARARGS, posix_dup2__doc__}, 5208 {"lseek", posix_lseek, METH_VARARGS, posix_lseek__doc__}, 5209 {"read", posix_read, METH_VARARGS, posix_read__doc__}, 5210 {"write", posix_write, METH_VARARGS, posix_write__doc__}, 5211 {"fstat", posix_fstat, METH_VARARGS, posix_fstat__doc__}, 5212 {"fdopen", posix_fdopen, METH_VARARGS, posix_fdopen__doc__}, 5213 {"isatty", posix_isatty, METH_VARARGS, posix_isatty__doc__}, 5214#ifdef HAVE_PIPE 5215 {"pipe", posix_pipe, METH_VARARGS, posix_pipe__doc__}, 5216#endif 5217#ifdef HAVE_MKFIFO 5218 {"mkfifo", posix_mkfifo, METH_VARARGS, posix_mkfifo__doc__}, 5219#endif 5220#ifdef HAVE_FTRUNCATE 5221 {"ftruncate", posix_ftruncate, METH_VARARGS, posix_ftruncate__doc__}, 5222#endif 5223#ifdef HAVE_PUTENV 5224 {"putenv", posix_putenv, METH_VARARGS, posix_putenv__doc__}, 5225#endif 5226#ifdef HAVE_STRERROR 5227 {"strerror", posix_strerror, METH_VARARGS, posix_strerror__doc__}, 5228#endif 5229#ifdef HAVE_FSYNC 5230 {"fsync", posix_fsync, METH_VARARGS, posix_fsync__doc__}, 5231#endif 5232#ifdef HAVE_FDATASYNC 5233 {"fdatasync", posix_fdatasync, METH_VARARGS, posix_fdatasync__doc__}, 5234#endif 5235#ifdef HAVE_SYS_WAIT_H 5236#ifdef WIFSTOPPED 5237 {"WIFSTOPPED", posix_WIFSTOPPED, METH_VARARGS, posix_WIFSTOPPED__doc__}, 5238#endif /* WIFSTOPPED */ 5239#ifdef WIFSIGNALED 5240 {"WIFSIGNALED", posix_WIFSIGNALED, METH_VARARGS, posix_WIFSIGNALED__doc__}, 5241#endif /* WIFSIGNALED */ 5242#ifdef WIFEXITED 5243 {"WIFEXITED", posix_WIFEXITED, METH_VARARGS, posix_WIFEXITED__doc__}, 5244#endif /* WIFEXITED */ 5245#ifdef WEXITSTATUS 5246 {"WEXITSTATUS", posix_WEXITSTATUS, METH_VARARGS, posix_WEXITSTATUS__doc__}, 5247#endif /* WEXITSTATUS */ 5248#ifdef WTERMSIG 5249 {"WTERMSIG", posix_WTERMSIG, METH_VARARGS, posix_WTERMSIG__doc__}, 5250#endif /* WTERMSIG */ 5251#ifdef WSTOPSIG 5252 {"WSTOPSIG", posix_WSTOPSIG, METH_VARARGS, posix_WSTOPSIG__doc__}, 5253#endif /* WSTOPSIG */ 5254#endif /* HAVE_SYS_WAIT_H */ 5255#ifdef HAVE_FSTATVFS 5256 {"fstatvfs", posix_fstatvfs, METH_VARARGS, posix_fstatvfs__doc__}, 5257#endif 5258#ifdef HAVE_STATVFS 5259 {"statvfs", posix_statvfs, METH_VARARGS, posix_statvfs__doc__}, 5260#endif 5261#ifdef HAVE_TMPNAM 5262 {"tmpfile", posix_tmpfile, METH_VARARGS, posix_tmpfile__doc__}, 5263#endif 5264#ifdef HAVE_TEMPNAM 5265 {"tempnam", posix_tempnam, METH_VARARGS, posix_tempnam__doc__}, 5266#endif 5267#ifdef HAVE_TMPNAM 5268 {"tmpnam", posix_tmpnam, METH_VARARGS, posix_tmpnam__doc__}, 5269#endif 5270#ifdef HAVE_CONFSTR 5271 {"confstr", posix_confstr, METH_VARARGS, posix_confstr__doc__}, 5272#endif 5273#ifdef HAVE_SYSCONF 5274 {"sysconf", posix_sysconf, METH_VARARGS, posix_sysconf__doc__}, 5275#endif 5276#ifdef HAVE_FPATHCONF 5277 {"fpathconf", posix_fpathconf, METH_VARARGS, posix_fpathconf__doc__}, 5278#endif 5279#ifdef HAVE_PATHCONF 5280 {"pathconf", posix_pathconf, METH_VARARGS, posix_pathconf__doc__}, 5281#endif 5282 {"abort", posix_abort, METH_VARARGS, posix_abort__doc__}, 5283 {NULL, NULL} /* Sentinel */ 5284}; 5285 5286 5287static int 5288ins(PyObject *d, char *symbol, long value) 5289{ 5290 PyObject* v = PyInt_FromLong(value); 5291 if (!v || PyDict_SetItemString(d, symbol, v) < 0) 5292 return -1; /* triggers fatal error */ 5293 5294 Py_DECREF(v); 5295 return 0; 5296} 5297 5298#if defined(PYOS_OS2) 5299/* Insert Platform-Specific Constant Values (Strings & Numbers) of Common Use */ 5300static int insertvalues(PyObject *d) 5301{ 5302 APIRET rc; 5303 ULONG values[QSV_MAX+1]; 5304 PyObject *v; 5305 char *ver, tmp[10]; 5306 5307 Py_BEGIN_ALLOW_THREADS 5308 rc = DosQuerySysInfo(1, QSV_MAX, &values[1], sizeof(values)); 5309 Py_END_ALLOW_THREADS 5310 5311 if (rc != NO_ERROR) { 5312 os2_error(rc); 5313 return -1; 5314 } 5315 5316 if (ins(d, "meminstalled", values[QSV_TOTPHYSMEM])) return -1; 5317 if (ins(d, "memkernel", values[QSV_TOTRESMEM])) return -1; 5318 if (ins(d, "memvirtual", values[QSV_TOTAVAILMEM])) return -1; 5319 if (ins(d, "maxpathlen", values[QSV_MAX_PATH_LENGTH])) return -1; 5320 if (ins(d, "maxnamelen", values[QSV_MAX_COMP_LENGTH])) return -1; 5321 if (ins(d, "revision", values[QSV_VERSION_REVISION])) return -1; 5322 if (ins(d, "timeslice", values[QSV_MIN_SLICE])) return -1; 5323 5324 switch (values[QSV_VERSION_MINOR]) { 5325 case 0: ver = "2.00"; break; 5326 case 10: ver = "2.10"; break; 5327 case 11: ver = "2.11"; break; 5328 case 30: ver = "3.00"; break; 5329 case 40: ver = "4.00"; break; 5330 case 50: ver = "5.00"; break; 5331 default: 5332 sprintf(tmp, "%d-%d", values[QSV_VERSION_MAJOR], 5333 values[QSV_VERSION_MINOR]); 5334 ver = &tmp[0]; 5335 } 5336 5337 /* Add Indicator of the Version of the Operating System */ 5338 v = PyString_FromString(ver); 5339 if (!v || PyDict_SetItemString(d, "version", v) < 0) 5340 return -1; 5341 Py_DECREF(v); 5342 5343 /* Add Indicator of Which Drive was Used to Boot the System */ 5344 tmp[0] = 'A' + values[QSV_BOOT_DRIVE] - 1; 5345 tmp[1] = ':'; 5346 tmp[2] = '\0'; 5347 5348 v = PyString_FromString(tmp); 5349 if (!v || PyDict_SetItemString(d, "bootdrive", v) < 0) 5350 return -1; 5351 Py_DECREF(v); 5352 5353 return 0; 5354} 5355#endif 5356 5357static int 5358all_ins(PyObject *d) 5359{ 5360#ifdef F_OK 5361 if (ins(d, "F_OK", (long)F_OK)) return -1; 5362#endif 5363#ifdef R_OK 5364 if (ins(d, "R_OK", (long)R_OK)) return -1; 5365#endif 5366#ifdef W_OK 5367 if (ins(d, "W_OK", (long)W_OK)) return -1; 5368#endif 5369#ifdef X_OK 5370 if (ins(d, "X_OK", (long)X_OK)) return -1; 5371#endif 5372#ifdef NGROUPS_MAX 5373 if (ins(d, "NGROUPS_MAX", (long)NGROUPS_MAX)) return -1; 5374#endif 5375#ifdef TMP_MAX 5376 if (ins(d, "TMP_MAX", (long)TMP_MAX)) return -1; 5377#endif 5378#ifdef WNOHANG 5379 if (ins(d, "WNOHANG", (long)WNOHANG)) return -1; 5380#endif 5381#ifdef O_RDONLY 5382 if (ins(d, "O_RDONLY", (long)O_RDONLY)) return -1; 5383#endif 5384#ifdef O_WRONLY 5385 if (ins(d, "O_WRONLY", (long)O_WRONLY)) return -1; 5386#endif 5387#ifdef O_RDWR 5388 if (ins(d, "O_RDWR", (long)O_RDWR)) return -1; 5389#endif 5390#ifdef O_NDELAY 5391 if (ins(d, "O_NDELAY", (long)O_NDELAY)) return -1; 5392#endif 5393#ifdef O_NONBLOCK 5394 if (ins(d, "O_NONBLOCK", (long)O_NONBLOCK)) return -1; 5395#endif 5396#ifdef O_APPEND 5397 if (ins(d, "O_APPEND", (long)O_APPEND)) return -1; 5398#endif 5399#ifdef O_DSYNC 5400 if (ins(d, "O_DSYNC", (long)O_DSYNC)) return -1; 5401#endif 5402#ifdef O_RSYNC 5403 if (ins(d, "O_RSYNC", (long)O_RSYNC)) return -1; 5404#endif 5405#ifdef O_SYNC 5406 if (ins(d, "O_SYNC", (long)O_SYNC)) return -1; 5407#endif 5408#ifdef O_NOCTTY 5409 if (ins(d, "O_NOCTTY", (long)O_NOCTTY)) return -1; 5410#endif 5411#ifdef O_CREAT 5412 if (ins(d, "O_CREAT", (long)O_CREAT)) return -1; 5413#endif 5414#ifdef O_EXCL 5415 if (ins(d, "O_EXCL", (long)O_EXCL)) return -1; 5416#endif 5417#ifdef O_TRUNC 5418 if (ins(d, "O_TRUNC", (long)O_TRUNC)) return -1; 5419#endif 5420#ifdef O_BINARY 5421 if (ins(d, "O_BINARY", (long)O_BINARY)) return -1; 5422#endif 5423#ifdef O_TEXT 5424 if (ins(d, "O_TEXT", (long)O_TEXT)) return -1; 5425#endif 5426 5427#ifdef HAVE_SPAWNV 5428 if (ins(d, "P_WAIT", (long)_P_WAIT)) return -1; 5429 if (ins(d, "P_NOWAIT", (long)_P_NOWAIT)) return -1; 5430 if (ins(d, "P_OVERLAY", (long)_OLD_P_OVERLAY)) return -1; 5431 if (ins(d, "P_NOWAITO", (long)_P_NOWAITO)) return -1; 5432 if (ins(d, "P_DETACH", (long)_P_DETACH)) return -1; 5433#endif 5434 5435#if defined(PYOS_OS2) 5436 if (insertvalues(d)) return -1; 5437#endif 5438 return 0; 5439} 5440 5441 5442#if ( defined(_MSC_VER) || defined(__WATCOMC__) ) && !defined(__QNX__) 5443#define INITFUNC initnt 5444#define MODNAME "nt" 5445#else 5446#if defined(PYOS_OS2) 5447#define INITFUNC initos2 5448#define MODNAME "os2" 5449#else 5450#define INITFUNC initposix 5451#define MODNAME "posix" 5452#endif 5453#endif 5454 5455DL_EXPORT(void) 5456INITFUNC(void) 5457{ 5458 PyObject *m, *d, *v; 5459 5460 m = Py_InitModule4(MODNAME, 5461 posix_methods, 5462 posix__doc__, 5463 (PyObject *)NULL, 5464 PYTHON_API_VERSION); 5465 d = PyModule_GetDict(m); 5466 5467 /* Initialize environ dictionary */ 5468 v = convertenviron(); 5469 if (v == NULL || PyDict_SetItemString(d, "environ", v) != 0) 5470 return; 5471 Py_DECREF(v); 5472 5473 if (all_ins(d)) 5474 return; 5475 5476 if (setup_confname_tables(d)) 5477 return; 5478 5479 PyDict_SetItemString(d, "error", PyExc_OSError); 5480 5481#ifdef HAVE_PUTENV 5482 posix_putenv_garbage = PyDict_New(); 5483#endif 5484} 5485