posixmodule.c revision dbe3f76270d8bc22f1201e6ac1d63dbe3124dc3f
1 2/* POSIX module implementation */ 3 4/* This file is also used for Windows NT/MS-Win and OS/2. In that case the 5 module actually calls itself 'nt' or 'os2', not 'posix', and a few 6 functions are either unimplemented or implemented differently. The source 7 assumes that for Windows NT, the macro 'MS_WINDOWS' is defined independent 8 of the compiler used. Different compilers define their own feature 9 test macro, e.g. '__BORLANDC__' or '_MSC_VER'. For OS/2, the compiler 10 independent macro PYOS_OS2 should be defined. On OS/2 the default 11 compiler is assumed to be IBM's VisualAge C++ (VACPP). PYCC_GCC is used 12 as the compiler specific macro for the EMX port of gcc to OS/2. */ 13 14/* See also ../Dos/dosmodule.c */ 15 16#include "Python.h" 17#include "structseq.h" 18 19PyDoc_STRVAR(posix__doc__, 20"This module provides access to operating system functionality that is\n\ 21standardized by the C Standard and the POSIX standard (a thinly\n\ 22disguised Unix interface). Refer to the library manual and\n\ 23corresponding Unix manual entries for more information on calls."); 24 25#if defined(PYOS_OS2) 26#define INCL_DOS 27#define INCL_DOSERRORS 28#define INCL_DOSPROCESS 29#define INCL_NOPMAPI 30#include <os2.h> 31#if defined(PYCC_GCC) 32#include <ctype.h> 33#include <io.h> 34#include <stdio.h> 35#include <process.h> 36#include "osdefs.h" 37#endif 38#endif 39 40#include <sys/types.h> 41#include <sys/stat.h> 42 43#ifdef HAVE_SYS_WAIT_H 44#include <sys/wait.h> /* For WNOHANG */ 45#endif 46 47#ifdef HAVE_SIGNAL_H 48#include <signal.h> 49#endif 50 51#ifdef HAVE_FCNTL_H 52#include <fcntl.h> 53#endif /* HAVE_FCNTL_H */ 54 55#ifdef HAVE_GRP_H 56#include <grp.h> 57#endif 58 59/* Various compilers have only certain posix functions */ 60/* XXX Gosh I wish these were all moved into pyconfig.h */ 61#if defined(PYCC_VACPP) && defined(PYOS_OS2) 62#include <process.h> 63#else 64#if defined(__WATCOMC__) && !defined(__QNX__) /* Watcom compiler */ 65#define HAVE_GETCWD 1 66#define HAVE_OPENDIR 1 67#define HAVE_SYSTEM 1 68#if defined(__OS2__) 69#define HAVE_EXECV 1 70#define HAVE_WAIT 1 71#endif 72#include <process.h> 73#else 74#ifdef __BORLANDC__ /* Borland compiler */ 75#define HAVE_EXECV 1 76#define HAVE_GETCWD 1 77#define HAVE_OPENDIR 1 78#define HAVE_PIPE 1 79#define HAVE_POPEN 1 80#define HAVE_SYSTEM 1 81#define HAVE_WAIT 1 82#else 83#ifdef _MSC_VER /* Microsoft compiler */ 84#define HAVE_GETCWD 1 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#define HAVE_CWAIT 1 91#else 92#if defined(PYOS_OS2) && defined(PYCC_GCC) 93/* Everything needed is defined in PC/os2emx/pyconfig.h */ 94#else /* all other compilers */ 95/* Unix functions that the configure script doesn't check for */ 96#define HAVE_EXECV 1 97#define HAVE_FORK 1 98#if defined(__USLC__) && defined(__SCO_VERSION__) /* SCO UDK Compiler */ 99#define HAVE_FORK1 1 100#endif 101#define HAVE_GETCWD 1 102#define HAVE_GETEGID 1 103#define HAVE_GETEUID 1 104#define HAVE_GETGID 1 105#define HAVE_GETPPID 1 106#define HAVE_GETUID 1 107#define HAVE_KILL 1 108#define HAVE_OPENDIR 1 109#define HAVE_PIPE 1 110#define HAVE_POPEN 1 111#define HAVE_SYSTEM 1 112#define HAVE_WAIT 1 113#define HAVE_TTYNAME 1 114#endif /* PYOS_OS2 && PYCC_GCC */ 115#endif /* _MSC_VER */ 116#endif /* __BORLANDC__ */ 117#endif /* ! __WATCOMC__ || __QNX__ */ 118#endif /* ! __IBMC__ */ 119 120#ifndef _MSC_VER 121 122#if defined(sun) && !defined(__SVR4) 123/* SunOS 4.1.4 doesn't have prototypes for these: */ 124extern int rename(const char *, const char *); 125extern int pclose(FILE *); 126extern int fclose(FILE *); 127extern int fsync(int); 128extern int lstat(const char *, struct stat *); 129extern int symlink(const char *, const char *); 130#endif 131 132#if defined(__sgi)&&_COMPILER_VERSION>=700 133/* declare ctermid_r if compiling with MIPSPro 7.x in ANSI C mode 134 (default) */ 135extern char *ctermid_r(char *); 136#endif 137 138#ifndef HAVE_UNISTD_H 139#if defined(PYCC_VACPP) 140extern int mkdir(char *); 141#else 142#if ( defined(__WATCOMC__) || defined(_MSC_VER) ) && !defined(__QNX__) 143extern int mkdir(const char *); 144#else 145extern int mkdir(const char *, mode_t); 146#endif 147#endif 148#if defined(__IBMC__) || defined(__IBMCPP__) 149extern int chdir(char *); 150extern int rmdir(char *); 151#else 152extern int chdir(const char *); 153extern int rmdir(const char *); 154#endif 155#ifdef __BORLANDC__ 156extern int chmod(const char *, int); 157#else 158extern int chmod(const char *, mode_t); 159#endif 160extern int chown(const char *, uid_t, gid_t); 161extern char *getcwd(char *, int); 162extern char *strerror(int); 163extern int link(const char *, const char *); 164extern int rename(const char *, const char *); 165extern int stat(const char *, struct stat *); 166extern int unlink(const char *); 167extern int pclose(FILE *); 168#ifdef HAVE_SYMLINK 169extern int symlink(const char *, const char *); 170#endif /* HAVE_SYMLINK */ 171#ifdef HAVE_LSTAT 172extern int lstat(const char *, struct stat *); 173#endif /* HAVE_LSTAT */ 174#endif /* !HAVE_UNISTD_H */ 175 176#endif /* !_MSC_VER */ 177 178#ifdef HAVE_UTIME_H 179#include <utime.h> 180#endif /* HAVE_UTIME_H */ 181 182#ifdef HAVE_SYS_UTIME_H 183#include <sys/utime.h> 184#define HAVE_UTIME_H /* pretend we do for the rest of this file */ 185#endif /* HAVE_SYS_UTIME_H */ 186 187#ifdef HAVE_SYS_TIMES_H 188#include <sys/times.h> 189#endif /* HAVE_SYS_TIMES_H */ 190 191#ifdef HAVE_SYS_PARAM_H 192#include <sys/param.h> 193#endif /* HAVE_SYS_PARAM_H */ 194 195#ifdef HAVE_SYS_UTSNAME_H 196#include <sys/utsname.h> 197#endif /* HAVE_SYS_UTSNAME_H */ 198 199#ifdef HAVE_DIRENT_H 200#include <dirent.h> 201#define NAMLEN(dirent) strlen((dirent)->d_name) 202#else 203#if defined(__WATCOMC__) && !defined(__QNX__) 204#include <direct.h> 205#define NAMLEN(dirent) strlen((dirent)->d_name) 206#else 207#define dirent direct 208#define NAMLEN(dirent) (dirent)->d_namlen 209#endif 210#ifdef HAVE_SYS_NDIR_H 211#include <sys/ndir.h> 212#endif 213#ifdef HAVE_SYS_DIR_H 214#include <sys/dir.h> 215#endif 216#ifdef HAVE_NDIR_H 217#include <ndir.h> 218#endif 219#endif 220 221#ifdef _MSC_VER 222#include <direct.h> 223#include <io.h> 224#include <process.h> 225#include "osdefs.h" 226#define WIN32_LEAN_AND_MEAN 227#include <windows.h> 228#include <shellapi.h> /* for ShellExecute() */ 229#define popen _popen 230#define pclose _pclose 231#endif /* _MSC_VER */ 232 233#if defined(PYCC_VACPP) && defined(PYOS_OS2) 234#include <io.h> 235#endif /* OS2 */ 236 237#ifndef MAXPATHLEN 238#define MAXPATHLEN 1024 239#endif /* MAXPATHLEN */ 240 241#ifdef UNION_WAIT 242/* Emulate some macros on systems that have a union instead of macros */ 243 244#ifndef WIFEXITED 245#define WIFEXITED(u_wait) (!(u_wait).w_termsig && !(u_wait).w_coredump) 246#endif 247 248#ifndef WEXITSTATUS 249#define WEXITSTATUS(u_wait) (WIFEXITED(u_wait)?((u_wait).w_retcode):-1) 250#endif 251 252#ifndef WTERMSIG 253#define WTERMSIG(u_wait) ((u_wait).w_termsig) 254#endif 255 256#endif /* UNION_WAIT */ 257 258/* Don't use the "_r" form if we don't need it (also, won't have a 259 prototype for it, at least on Solaris -- maybe others as well?). */ 260#if defined(HAVE_CTERMID_R) && defined(WITH_THREAD) 261#define USE_CTERMID_R 262#endif 263 264#if defined(HAVE_TMPNAM_R) && defined(WITH_THREAD) 265#define USE_TMPNAM_R 266#endif 267 268/* choose the appropriate stat and fstat functions and return structs */ 269#undef STAT 270#if defined(MS_WIN64) || defined(MS_WINDOWS) 271# define STAT _stati64 272# define FSTAT _fstati64 273# define STRUCT_STAT struct _stati64 274#else 275# define STAT stat 276# define FSTAT fstat 277# define STRUCT_STAT struct stat 278#endif 279 280#if defined(MAJOR_IN_MKDEV) 281#include <sys/mkdev.h> 282#else 283#if defined(MAJOR_IN_SYSMACROS) 284#include <sys/sysmacros.h> 285#endif 286#if defined(HAVE_MKNOD) && defined(HAVE_SYS_MKDEV_H) 287#include <sys/mkdev.h> 288#endif 289#endif 290 291/* Return a dictionary corresponding to the POSIX environment table */ 292#ifdef WITH_NEXT_FRAMEWORK 293/* On Darwin/MacOSX a shared library or framework has no access to 294** environ directly, we must obtain it with _NSGetEnviron(). 295*/ 296#include <crt_externs.h> 297static char **environ; 298#elif !defined(_MSC_VER) && ( !defined(__WATCOMC__) || defined(__QNX__) ) 299extern char **environ; 300#endif /* !_MSC_VER */ 301 302static PyObject * 303convertenviron(void) 304{ 305 PyObject *d; 306 char **e; 307 d = PyDict_New(); 308 if (d == NULL) 309 return NULL; 310#ifdef WITH_NEXT_FRAMEWORK 311 if (environ == NULL) 312 environ = *_NSGetEnviron(); 313#endif 314 if (environ == NULL) 315 return d; 316 /* This part ignores errors */ 317 for (e = environ; *e != NULL; e++) { 318 PyObject *k; 319 PyObject *v; 320 char *p = strchr(*e, '='); 321 if (p == NULL) 322 continue; 323 k = PyString_FromStringAndSize(*e, (int)(p-*e)); 324 if (k == NULL) { 325 PyErr_Clear(); 326 continue; 327 } 328 v = PyString_FromString(p+1); 329 if (v == NULL) { 330 PyErr_Clear(); 331 Py_DECREF(k); 332 continue; 333 } 334 if (PyDict_GetItem(d, k) == NULL) { 335 if (PyDict_SetItem(d, k, v) != 0) 336 PyErr_Clear(); 337 } 338 Py_DECREF(k); 339 Py_DECREF(v); 340 } 341#if defined(PYOS_OS2) 342 { 343 APIRET rc; 344 char buffer[1024]; /* OS/2 Provides a Documented Max of 1024 Chars */ 345 346 rc = DosQueryExtLIBPATH(buffer, BEGIN_LIBPATH); 347 if (rc == NO_ERROR) { /* (not a type, envname is NOT 'BEGIN_LIBPATH') */ 348 PyObject *v = PyString_FromString(buffer); 349 PyDict_SetItemString(d, "BEGINLIBPATH", v); 350 Py_DECREF(v); 351 } 352 rc = DosQueryExtLIBPATH(buffer, END_LIBPATH); 353 if (rc == NO_ERROR) { /* (not a typo, envname is NOT 'END_LIBPATH') */ 354 PyObject *v = PyString_FromString(buffer); 355 PyDict_SetItemString(d, "ENDLIBPATH", v); 356 Py_DECREF(v); 357 } 358 } 359#endif 360 return d; 361} 362 363 364/* Set a POSIX-specific error from errno, and return NULL */ 365 366static PyObject * 367posix_error(void) 368{ 369 return PyErr_SetFromErrno(PyExc_OSError); 370} 371static PyObject * 372posix_error_with_filename(char* name) 373{ 374 return PyErr_SetFromErrnoWithFilename(PyExc_OSError, name); 375} 376 377#ifdef Py_WIN_WIDE_FILENAMES 378static PyObject * 379posix_error_with_unicode_filename(Py_UNICODE* name) 380{ 381 return PyErr_SetFromErrnoWithUnicodeFilename(PyExc_OSError, name); 382} 383#endif /* Py_WIN_WIDE_FILENAMES */ 384 385 386static PyObject * 387posix_error_with_allocated_filename(char* name) 388{ 389 PyObject *rc = PyErr_SetFromErrnoWithFilename(PyExc_OSError, name); 390 PyMem_Free(name); 391 return rc; 392} 393 394#ifdef MS_WINDOWS 395static PyObject * 396win32_error(char* function, char* filename) 397{ 398 /* XXX We should pass the function name along in the future. 399 (_winreg.c also wants to pass the function name.) 400 This would however require an additional param to the 401 Windows error object, which is non-trivial. 402 */ 403 errno = GetLastError(); 404 if (filename) 405 return PyErr_SetFromWindowsErrWithFilename(errno, filename); 406 else 407 return PyErr_SetFromWindowsErr(errno); 408} 409 410#ifdef Py_WIN_WIDE_FILENAMES 411static PyObject * 412win32_error_unicode(char* function, Py_UNICODE* filename) 413{ 414 /* XXX - see win32_error for comments on 'function' */ 415 errno = GetLastError(); 416 if (filename) 417 return PyErr_SetFromWindowsErrWithUnicodeFilename(errno, filename); 418 else 419 return PyErr_SetFromWindowsErr(errno); 420} 421 422static PyObject *_PyUnicode_FromFileSystemEncodedObject(register PyObject *obj) 423{ 424 /* XXX Perhaps we should make this API an alias of 425 PyObject_Unicode() instead ?! */ 426 if (PyUnicode_CheckExact(obj)) { 427 Py_INCREF(obj); 428 return obj; 429 } 430 if (PyUnicode_Check(obj)) { 431 /* For a Unicode subtype that's not a Unicode object, 432 return a true Unicode object with the same data. */ 433 return PyUnicode_FromUnicode(PyUnicode_AS_UNICODE(obj), 434 PyUnicode_GET_SIZE(obj)); 435 } 436 return PyUnicode_FromEncodedObject(obj, 437 Py_FileSystemDefaultEncoding, 438 "strict"); 439} 440 441#endif /* Py_WIN_WIDE_FILENAMES */ 442 443#endif 444 445#if defined(PYOS_OS2) 446/********************************************************************** 447 * Helper Function to Trim and Format OS/2 Messages 448 **********************************************************************/ 449 static void 450os2_formatmsg(char *msgbuf, int msglen, char *reason) 451{ 452 msgbuf[msglen] = '\0'; /* OS/2 Doesn't Guarantee a Terminator */ 453 454 if (strlen(msgbuf) > 0) { /* If Non-Empty Msg, Trim CRLF */ 455 char *lastc = &msgbuf[ strlen(msgbuf)-1 ]; 456 457 while (lastc > msgbuf && isspace(*lastc)) 458 *lastc-- = '\0'; /* Trim Trailing Whitespace (CRLF) */ 459 } 460 461 /* Add Optional Reason Text */ 462 if (reason) { 463 strcat(msgbuf, " : "); 464 strcat(msgbuf, reason); 465 } 466} 467 468/********************************************************************** 469 * Decode an OS/2 Operating System Error Code 470 * 471 * A convenience function to lookup an OS/2 error code and return a 472 * text message we can use to raise a Python exception. 473 * 474 * Notes: 475 * The messages for errors returned from the OS/2 kernel reside in 476 * the file OSO001.MSG in the \OS2 directory hierarchy. 477 * 478 **********************************************************************/ 479 static char * 480os2_strerror(char *msgbuf, int msgbuflen, int errorcode, char *reason) 481{ 482 APIRET rc; 483 ULONG msglen; 484 485 /* Retrieve Kernel-Related Error Message from OSO001.MSG File */ 486 Py_BEGIN_ALLOW_THREADS 487 rc = DosGetMessage(NULL, 0, msgbuf, msgbuflen, 488 errorcode, "oso001.msg", &msglen); 489 Py_END_ALLOW_THREADS 490 491 if (rc == NO_ERROR) 492 os2_formatmsg(msgbuf, msglen, reason); 493 else 494 PyOS_snprintf(msgbuf, msgbuflen, 495 "unknown OS error #%d", errorcode); 496 497 return msgbuf; 498} 499 500/* Set an OS/2-specific error and return NULL. OS/2 kernel 501 errors are not in a global variable e.g. 'errno' nor are 502 they congruent with posix error numbers. */ 503 504static PyObject * os2_error(int code) 505{ 506 char text[1024]; 507 PyObject *v; 508 509 os2_strerror(text, sizeof(text), code, ""); 510 511 v = Py_BuildValue("(is)", code, text); 512 if (v != NULL) { 513 PyErr_SetObject(PyExc_OSError, v); 514 Py_DECREF(v); 515 } 516 return NULL; /* Signal to Python that an Exception is Pending */ 517} 518 519#endif /* OS2 */ 520 521/* POSIX generic methods */ 522 523static PyObject * 524posix_fildes(PyObject *fdobj, int (*func)(int)) 525{ 526 int fd; 527 int res; 528 fd = PyObject_AsFileDescriptor(fdobj); 529 if (fd < 0) 530 return NULL; 531 Py_BEGIN_ALLOW_THREADS 532 res = (*func)(fd); 533 Py_END_ALLOW_THREADS 534 if (res < 0) 535 return posix_error(); 536 Py_INCREF(Py_None); 537 return Py_None; 538} 539 540#ifdef Py_WIN_WIDE_FILENAMES 541static int 542unicode_file_names(void) 543{ 544 static int canusewide = -1; 545 if (canusewide == -1) { 546 /* As per doc for ::GetVersion(), this is the correct test for 547 the Windows NT family. */ 548 canusewide = (GetVersion() < 0x80000000) ? 1 : 0; 549 } 550 return canusewide; 551} 552#endif 553 554static PyObject * 555posix_1str(PyObject *args, char *format, int (*func)(const char*), 556 char *wformat, int (*wfunc)(const Py_UNICODE*)) 557{ 558 char *path1 = NULL; 559 int res; 560#ifdef Py_WIN_WIDE_FILENAMES 561 if (unicode_file_names()) { 562 PyUnicodeObject *po; 563 if (PyArg_ParseTuple(args, wformat, &po)) { 564 Py_BEGIN_ALLOW_THREADS 565 /* PyUnicode_AS_UNICODE OK without thread 566 lock as it is a simple dereference. */ 567 res = (*wfunc)(PyUnicode_AS_UNICODE(po)); 568 Py_END_ALLOW_THREADS 569 if (res < 0) 570 return posix_error_with_unicode_filename(PyUnicode_AS_UNICODE(po)); 571 Py_INCREF(Py_None); 572 return Py_None; 573 } 574 /* Drop the argument parsing error as narrow 575 strings are also valid. */ 576 PyErr_Clear(); 577 } 578#else 579 /* Platforms that don't support Unicode filenames 580 shouldn't be passing these extra params */ 581 assert(wformat==NULL && wfunc == NULL); 582#endif 583 584 if (!PyArg_ParseTuple(args, format, 585 Py_FileSystemDefaultEncoding, &path1)) 586 return NULL; 587 Py_BEGIN_ALLOW_THREADS 588 res = (*func)(path1); 589 Py_END_ALLOW_THREADS 590 if (res < 0) 591 return posix_error_with_allocated_filename(path1); 592 PyMem_Free(path1); 593 Py_INCREF(Py_None); 594 return Py_None; 595} 596 597static PyObject * 598posix_2str(PyObject *args, 599 char *format, 600 int (*func)(const char *, const char *), 601 char *wformat, 602 int (*wfunc)(const Py_UNICODE *, const Py_UNICODE *)) 603{ 604 char *path1 = NULL, *path2 = NULL; 605 int res; 606#ifdef Py_WIN_WIDE_FILENAMES 607 if (unicode_file_names()) { 608 PyObject *po1; 609 PyObject *po2; 610 if (PyArg_ParseTuple(args, wformat, &po1, &po2)) { 611 if (PyUnicode_Check(po1) || PyUnicode_Check(po2)) { 612 PyObject *wpath1; 613 PyObject *wpath2; 614 wpath1 = _PyUnicode_FromFileSystemEncodedObject(po1); 615 wpath2 = _PyUnicode_FromFileSystemEncodedObject(po2); 616 if (!wpath1 || !wpath2) { 617 Py_XDECREF(wpath1); 618 Py_XDECREF(wpath2); 619 return NULL; 620 } 621 Py_BEGIN_ALLOW_THREADS 622 /* PyUnicode_AS_UNICODE OK without thread 623 lock as it is a simple dereference. */ 624 res = (*wfunc)(PyUnicode_AS_UNICODE(wpath1), 625 PyUnicode_AS_UNICODE(wpath2)); 626 Py_END_ALLOW_THREADS 627 Py_XDECREF(wpath1); 628 Py_XDECREF(wpath2); 629 if (res != 0) 630 return posix_error(); 631 Py_INCREF(Py_None); 632 return Py_None; 633 } 634 /* Else flow through as neither is Unicode. */ 635 } 636 /* Drop the argument parsing error as narrow 637 strings are also valid. */ 638 PyErr_Clear(); 639 } 640#else 641 /* Platforms that don't support Unicode filenames 642 shouldn't be passing these extra params */ 643 assert(wformat==NULL && wfunc == NULL); 644#endif 645 646 if (!PyArg_ParseTuple(args, format, 647 Py_FileSystemDefaultEncoding, &path1, 648 Py_FileSystemDefaultEncoding, &path2)) 649 return NULL; 650 Py_BEGIN_ALLOW_THREADS 651 res = (*func)(path1, path2); 652 Py_END_ALLOW_THREADS 653 PyMem_Free(path1); 654 PyMem_Free(path2); 655 if (res != 0) 656 /* XXX how to report both path1 and path2??? */ 657 return posix_error(); 658 Py_INCREF(Py_None); 659 return Py_None; 660} 661 662PyDoc_STRVAR(stat_result__doc__, 663"stat_result: Result from stat or lstat.\n\n\ 664This object may be accessed either as a tuple of\n\ 665 (mode, ino, dev, nlink, uid, gid, size, atime, mtime, ctime)\n\ 666or via the attributes st_mode, st_ino, st_dev, st_nlink, st_uid, and so on.\n\ 667\n\ 668Posix/windows: If your platform supports st_blksize, st_blocks, or st_rdev,\n\ 669they are available as attributes only.\n\ 670\n\ 671See os.stat for more information."); 672 673static PyStructSequence_Field stat_result_fields[] = { 674 {"st_mode", "protection bits"}, 675 {"st_ino", "inode"}, 676 {"st_dev", "device"}, 677 {"st_nlink", "number of hard links"}, 678 {"st_uid", "user ID of owner"}, 679 {"st_gid", "group ID of owner"}, 680 {"st_size", "total size, in bytes"}, 681 {"st_atime", "time of last access"}, 682 {"st_mtime", "time of last modification"}, 683 {"st_ctime", "time of last change"}, 684#ifdef HAVE_ST_BLKSIZE 685 {"st_blksize", "blocksize for filesystem I/O"}, 686#endif 687#ifdef HAVE_ST_BLOCKS 688 {"st_blocks", "number of blocks allocated"}, 689#endif 690#ifdef HAVE_ST_RDEV 691 {"st_rdev", "device type (if inode device)"}, 692#endif 693 {0} 694}; 695 696#ifdef HAVE_ST_BLKSIZE 697#define ST_BLKSIZE_IDX 10 698#else 699#define ST_BLKSIZE_IDX 9 700#endif 701 702#ifdef HAVE_ST_BLOCKS 703#define ST_BLOCKS_IDX (ST_BLKSIZE_IDX+1) 704#else 705#define ST_BLOCKS_IDX ST_BLKSIZE_IDX 706#endif 707 708#ifdef HAVE_ST_RDEV 709#define ST_RDEV_IDX (ST_BLOCKS_IDX+1) 710#else 711#define ST_RDEV_IDX ST_BLOCKS_IDX 712#endif 713 714static PyStructSequence_Desc stat_result_desc = { 715 "stat_result", /* name */ 716 stat_result__doc__, /* doc */ 717 stat_result_fields, 718 10 719}; 720 721PyDoc_STRVAR(statvfs_result__doc__, 722"statvfs_result: Result from statvfs or fstatvfs.\n\n\ 723This object may be accessed either as a tuple of\n\ 724 (bsize, frsize, blocks, bfree, bavail, files, ffree, favail, flag, namemax),\n\ 725or via the attributes f_bsize, f_frsize, f_blocks, f_bfree, and so on.\n\ 726\n\ 727See os.statvfs for more information."); 728 729static PyStructSequence_Field statvfs_result_fields[] = { 730 {"f_bsize", }, 731 {"f_frsize", }, 732 {"f_blocks", }, 733 {"f_bfree", }, 734 {"f_bavail", }, 735 {"f_files", }, 736 {"f_ffree", }, 737 {"f_favail", }, 738 {"f_flag", }, 739 {"f_namemax",}, 740 {0} 741}; 742 743static PyStructSequence_Desc statvfs_result_desc = { 744 "statvfs_result", /* name */ 745 statvfs_result__doc__, /* doc */ 746 statvfs_result_fields, 747 10 748}; 749 750static PyTypeObject StatResultType; 751static PyTypeObject StatVFSResultType; 752 753static void 754fill_time(PyObject *v, int index, time_t sec, unsigned long nsec) 755{ 756 PyObject *val; 757 val = PyFloat_FromDouble(sec + 1e-9*nsec); 758 PyStructSequence_SET_ITEM(v, index, val); 759} 760 761/* pack a system stat C structure into the Python stat tuple 762 (used by posix_stat() and posix_fstat()) */ 763static PyObject* 764_pystat_fromstructstat(STRUCT_STAT st) 765{ 766 unsigned long ansec, mnsec, cnsec; 767 PyObject *v = PyStructSequence_New(&StatResultType); 768 if (v == NULL) 769 return NULL; 770 771 PyStructSequence_SET_ITEM(v, 0, PyInt_FromLong((long)st.st_mode)); 772#ifdef HAVE_LARGEFILE_SUPPORT 773 PyStructSequence_SET_ITEM(v, 1, 774 PyLong_FromLongLong((LONG_LONG)st.st_ino)); 775#else 776 PyStructSequence_SET_ITEM(v, 1, PyInt_FromLong((long)st.st_ino)); 777#endif 778#if defined(HAVE_LONG_LONG) && !defined(MS_WINDOWS) 779 PyStructSequence_SET_ITEM(v, 2, 780 PyLong_FromLongLong((LONG_LONG)st.st_dev)); 781#else 782 PyStructSequence_SET_ITEM(v, 2, PyInt_FromLong((long)st.st_dev)); 783#endif 784 PyStructSequence_SET_ITEM(v, 3, PyInt_FromLong((long)st.st_nlink)); 785 PyStructSequence_SET_ITEM(v, 4, PyInt_FromLong((long)st.st_uid)); 786 PyStructSequence_SET_ITEM(v, 5, PyInt_FromLong((long)st.st_gid)); 787#ifdef HAVE_LARGEFILE_SUPPORT 788 PyStructSequence_SET_ITEM(v, 6, 789 PyLong_FromLongLong((LONG_LONG)st.st_size)); 790#else 791 PyStructSequence_SET_ITEM(v, 6, PyInt_FromLong(st.st_size)); 792#endif 793 794#ifdef HAVE_STAT_TV_NSEC 795 ansec = st.st_atim.tv_nsec; 796 mnsec = st.st_mtim.tv_nsec; 797 cnsec = st.st_ctim.tv_nsec; 798#else 799 ansec = mnsec = cnsec = 0; 800#endif 801 fill_time(v, 7, st.st_atime, ansec); 802 fill_time(v, 8, st.st_mtime, mnsec); 803 fill_time(v, 9, st.st_ctime, cnsec); 804 805#ifdef HAVE_ST_BLKSIZE 806 PyStructSequence_SET_ITEM(v, ST_BLKSIZE_IDX, 807 PyInt_FromLong((long)st.st_blksize)); 808#endif 809#ifdef HAVE_ST_BLOCKS 810 PyStructSequence_SET_ITEM(v, ST_BLOCKS_IDX, 811 PyInt_FromLong((long)st.st_blocks)); 812#endif 813#ifdef HAVE_ST_RDEV 814 PyStructSequence_SET_ITEM(v, ST_RDEV_IDX, 815 PyInt_FromLong((long)st.st_rdev)); 816#endif 817 818 if (PyErr_Occurred()) { 819 Py_DECREF(v); 820 return NULL; 821 } 822 823 return v; 824} 825 826static PyObject * 827posix_do_stat(PyObject *self, PyObject *args, 828 char *format, 829 int (*statfunc)(const char *, STRUCT_STAT *), 830 char *wformat, 831 int (*wstatfunc)(const Py_UNICODE *, STRUCT_STAT *)) 832{ 833 STRUCT_STAT st; 834 char *path = NULL; /* pass this to stat; do not free() it */ 835 char *pathfree = NULL; /* this memory must be free'd */ 836 int res; 837 838#ifdef MS_WINDOWS 839 int pathlen; 840 char pathcopy[MAX_PATH]; 841#endif /* MS_WINDOWS */ 842 843 844#ifdef Py_WIN_WIDE_FILENAMES 845 /* If on wide-character-capable OS see if argument 846 is Unicode and if so use wide API. */ 847 if (unicode_file_names()) { 848 PyUnicodeObject *po; 849 if (PyArg_ParseTuple(args, wformat, &po)) { 850 Py_UNICODE wpath[MAX_PATH+1]; 851 pathlen = wcslen(PyUnicode_AS_UNICODE(po)); 852 /* the library call can blow up if the file name is too long! */ 853 if (pathlen > MAX_PATH) { 854 errno = ENAMETOOLONG; 855 return posix_error(); 856 } 857 wcscpy(wpath, PyUnicode_AS_UNICODE(po)); 858 /* Remove trailing slash or backslash, unless it's the current 859 drive root (/ or \) or a specific drive's root (like c:\ or c:/). 860 */ 861 if (pathlen > 0 && 862 (wpath[pathlen-1]== L'\\' || wpath[pathlen-1] == L'/')) { 863 /* It does end with a slash -- exempt the root drive cases. */ 864 /* XXX UNC root drives should also be exempted? */ 865 if (pathlen == 1 || (pathlen == 3 && wpath[1] == L':')) 866 /* leave it alone */; 867 else { 868 /* nuke the trailing backslash */ 869 wpath[pathlen-1] = L'\0'; 870 } 871 } 872 Py_BEGIN_ALLOW_THREADS 873 /* PyUnicode_AS_UNICODE result OK without 874 thread lock as it is a simple dereference. */ 875 res = wstatfunc(wpath, &st); 876 Py_END_ALLOW_THREADS 877 if (res != 0) 878 return posix_error_with_unicode_filename(wpath); 879 return _pystat_fromstructstat(st); 880 } 881 /* Drop the argument parsing error as narrow strings 882 are also valid. */ 883 PyErr_Clear(); 884 } 885#endif 886 887 if (!PyArg_ParseTuple(args, format, 888 Py_FileSystemDefaultEncoding, &path)) 889 return NULL; 890 pathfree = path; 891 892#ifdef MS_WINDOWS 893 pathlen = strlen(path); 894 /* the library call can blow up if the file name is too long! */ 895 if (pathlen > MAX_PATH) { 896 PyMem_Free(pathfree); 897 errno = ENAMETOOLONG; 898 return posix_error(); 899 } 900 901 /* Remove trailing slash or backslash, unless it's the current 902 drive root (/ or \) or a specific drive's root (like c:\ or c:/). 903 */ 904 if (pathlen > 0 && 905 (path[pathlen-1]== '\\' || path[pathlen-1] == '/')) { 906 /* It does end with a slash -- exempt the root drive cases. */ 907 /* XXX UNC root drives should also be exempted? */ 908 if (pathlen == 1 || (pathlen == 3 && path[1] == ':')) 909 /* leave it alone */; 910 else { 911 /* nuke the trailing backslash */ 912 strncpy(pathcopy, path, pathlen); 913 pathcopy[pathlen-1] = '\0'; 914 path = pathcopy; 915 } 916 } 917#endif /* MS_WINDOWS */ 918 919 Py_BEGIN_ALLOW_THREADS 920 res = (*statfunc)(path, &st); 921 Py_END_ALLOW_THREADS 922 if (res != 0) 923 return posix_error_with_allocated_filename(pathfree); 924 925 PyMem_Free(pathfree); 926 return _pystat_fromstructstat(st); 927} 928 929 930/* POSIX methods */ 931 932PyDoc_STRVAR(posix_access__doc__, 933"access(path, mode) -> 1 if granted, 0 otherwise\n\n\ 934Use the real uid/gid to test for access to a path. Note that most\n\ 935operations will use the effective uid/gid, therefore this routine can\n\ 936be used in a suid/sgid environment to test if the invoking user has the\n\ 937specified access to the path. The mode argument can be F_OK to test\n\ 938existence, or the inclusive-OR of R_OK, W_OK, and X_OK."); 939 940static PyObject * 941posix_access(PyObject *self, PyObject *args) 942{ 943 char *path; 944 int mode; 945 int res; 946 947 if (!PyArg_ParseTuple(args, "si:access", &path, &mode)) 948 return NULL; 949 Py_BEGIN_ALLOW_THREADS 950 res = access(path, mode); 951 Py_END_ALLOW_THREADS 952 return(PyBool_FromLong(res == 0)); 953} 954 955#ifndef F_OK 956#define F_OK 0 957#endif 958#ifndef R_OK 959#define R_OK 4 960#endif 961#ifndef W_OK 962#define W_OK 2 963#endif 964#ifndef X_OK 965#define X_OK 1 966#endif 967 968#ifdef HAVE_TTYNAME 969PyDoc_STRVAR(posix_ttyname__doc__, 970"ttyname(fd) -> string\n\n\ 971Return the name of the terminal device connected to 'fd'."); 972 973static PyObject * 974posix_ttyname(PyObject *self, PyObject *args) 975{ 976 int id; 977 char *ret; 978 979 if (!PyArg_ParseTuple(args, "i:ttyname", &id)) 980 return NULL; 981 982 ret = ttyname(id); 983 if (ret == NULL) 984 return(posix_error()); 985 return(PyString_FromString(ret)); 986} 987#endif 988 989#ifdef HAVE_CTERMID 990PyDoc_STRVAR(posix_ctermid__doc__, 991"ctermid() -> string\n\n\ 992Return the name of the controlling terminal for this process."); 993 994static PyObject * 995posix_ctermid(PyObject *self, PyObject *args) 996{ 997 char *ret; 998 char buffer[L_ctermid]; 999 1000 if (!PyArg_ParseTuple(args, ":ctermid")) 1001 return NULL; 1002 1003#ifdef USE_CTERMID_R 1004 ret = ctermid_r(buffer); 1005#else 1006 ret = ctermid(buffer); 1007#endif 1008 if (ret == NULL) 1009 return(posix_error()); 1010 return(PyString_FromString(buffer)); 1011} 1012#endif 1013 1014PyDoc_STRVAR(posix_chdir__doc__, 1015"chdir(path)\n\n\ 1016Change the current working directory to the specified path."); 1017 1018static PyObject * 1019posix_chdir(PyObject *self, PyObject *args) 1020{ 1021#ifdef MS_WINDOWS 1022 return posix_1str(args, "et:chdir", chdir, "U:chdir", _wchdir); 1023#elif defined(PYOS_OS2) && defined(PYCC_GCC) 1024 return posix_1str(args, "et:chdir", _chdir2, NULL, NULL); 1025#else 1026 return posix_1str(args, "et:chdir", chdir, NULL, NULL); 1027#endif 1028} 1029 1030#ifdef HAVE_FCHDIR 1031PyDoc_STRVAR(posix_fchdir__doc__, 1032"fchdir(fildes)\n\n\ 1033Change to the directory of the given file descriptor. fildes must be\n\ 1034opened on a directory, not a file."); 1035 1036static PyObject * 1037posix_fchdir(PyObject *self, PyObject *fdobj) 1038{ 1039 return posix_fildes(fdobj, fchdir); 1040} 1041#endif /* HAVE_FCHDIR */ 1042 1043 1044PyDoc_STRVAR(posix_chmod__doc__, 1045"chmod(path, mode)\n\n\ 1046Change the access permissions of a file."); 1047 1048static PyObject * 1049posix_chmod(PyObject *self, PyObject *args) 1050{ 1051 char *path = NULL; 1052 int i; 1053 int res; 1054 if (!PyArg_ParseTuple(args, "eti", Py_FileSystemDefaultEncoding, 1055 &path, &i)) 1056 return NULL; 1057 Py_BEGIN_ALLOW_THREADS 1058 res = chmod(path, i); 1059 Py_END_ALLOW_THREADS 1060 if (res < 0) 1061 return posix_error_with_allocated_filename(path); 1062 PyMem_Free(path); 1063 Py_INCREF(Py_None); 1064 return Py_None; 1065} 1066 1067 1068#ifdef HAVE_CHROOT 1069PyDoc_STRVAR(posix_chroot__doc__, 1070"chroot(path)\n\n\ 1071Change root directory to path."); 1072 1073static PyObject * 1074posix_chroot(PyObject *self, PyObject *args) 1075{ 1076 return posix_1str(args, "et:chroot", chroot, NULL, NULL); 1077} 1078#endif 1079 1080#ifdef HAVE_FSYNC 1081PyDoc_STRVAR(posix_fsync__doc__, 1082"fsync(fildes)\n\n\ 1083force write of file with filedescriptor to disk."); 1084 1085static PyObject * 1086posix_fsync(PyObject *self, PyObject *fdobj) 1087{ 1088 return posix_fildes(fdobj, fsync); 1089} 1090#endif /* HAVE_FSYNC */ 1091 1092#ifdef HAVE_FDATASYNC 1093 1094#ifdef __hpux 1095extern int fdatasync(int); /* On HP-UX, in libc but not in unistd.h */ 1096#endif 1097 1098PyDoc_STRVAR(posix_fdatasync__doc__, 1099"fdatasync(fildes)\n\n\ 1100force write of file with filedescriptor to disk.\n\ 1101 does not force update of metadata."); 1102 1103static PyObject * 1104posix_fdatasync(PyObject *self, PyObject *fdobj) 1105{ 1106 return posix_fildes(fdobj, fdatasync); 1107} 1108#endif /* HAVE_FDATASYNC */ 1109 1110 1111#ifdef HAVE_CHOWN 1112PyDoc_STRVAR(posix_chown__doc__, 1113"chown(path, uid, gid)\n\n\ 1114Change the owner and group id of path to the numeric uid and gid."); 1115 1116static PyObject * 1117posix_chown(PyObject *self, PyObject *args) 1118{ 1119 char *path = NULL; 1120 int uid, gid; 1121 int res; 1122 if (!PyArg_ParseTuple(args, "etii:chown", 1123 Py_FileSystemDefaultEncoding, &path, 1124 &uid, &gid)) 1125 return NULL; 1126 Py_BEGIN_ALLOW_THREADS 1127 res = chown(path, (uid_t) uid, (gid_t) gid); 1128 Py_END_ALLOW_THREADS 1129 if (res < 0) 1130 return posix_error_with_allocated_filename(path); 1131 PyMem_Free(path); 1132 Py_INCREF(Py_None); 1133 return Py_None; 1134} 1135#endif /* HAVE_CHOWN */ 1136 1137#ifdef HAVE_LCHOWN 1138PyDoc_STRVAR(posix_lchown__doc__, 1139"lchown(path, uid, gid)\n\n\ 1140Change the owner and group id of path to the numeric uid and gid.\n\ 1141This function will not follow symbolic links."); 1142 1143static PyObject * 1144posix_lchown(PyObject *self, PyObject *args) 1145{ 1146 char *path = NULL; 1147 int uid, gid; 1148 int res; 1149 if (!PyArg_ParseTuple(args, "etii:lchown", 1150 Py_FileSystemDefaultEncoding, &path, 1151 &uid, &gid)) 1152 return NULL; 1153 Py_BEGIN_ALLOW_THREADS 1154 res = lchown(path, (uid_t) uid, (gid_t) gid); 1155 Py_END_ALLOW_THREADS 1156 if (res < 0) 1157 return posix_error_with_allocated_filename(path); 1158 PyMem_Free(path); 1159 Py_INCREF(Py_None); 1160 return Py_None; 1161} 1162#endif /* HAVE_LCHOWN */ 1163 1164 1165#ifdef HAVE_GETCWD 1166PyDoc_STRVAR(posix_getcwd__doc__, 1167"getcwd() -> path\n\n\ 1168Return a string representing the current working directory."); 1169 1170static PyObject * 1171posix_getcwd(PyObject *self, PyObject *args) 1172{ 1173 char buf[1026]; 1174 char *res; 1175 if (!PyArg_ParseTuple(args, ":getcwd")) 1176 return NULL; 1177 Py_BEGIN_ALLOW_THREADS 1178#if defined(PYOS_OS2) && defined(PYCC_GCC) 1179 res = _getcwd2(buf, sizeof buf); 1180#else 1181 res = getcwd(buf, sizeof buf); 1182#endif 1183 Py_END_ALLOW_THREADS 1184 if (res == NULL) 1185 return posix_error(); 1186 return PyString_FromString(buf); 1187} 1188 1189PyDoc_STRVAR(posix_getcwdu__doc__, 1190"getcwdu() -> path\n\n\ 1191Return a unicode string representing the current working directory."); 1192 1193static PyObject * 1194posix_getcwdu(PyObject *self, PyObject *args) 1195{ 1196 char buf[1026]; 1197 char *res; 1198 if (!PyArg_ParseTuple(args, ":getcwd")) 1199 return NULL; 1200 1201#ifdef Py_WIN_WIDE_FILENAMES 1202 if (unicode_file_names()) { 1203 wchar_t *wres; 1204 wchar_t wbuf[1026]; 1205 Py_BEGIN_ALLOW_THREADS 1206 wres = _wgetcwd(wbuf, sizeof wbuf/ sizeof wbuf[0]); 1207 Py_END_ALLOW_THREADS 1208 if (wres == NULL) 1209 return posix_error(); 1210 return PyUnicode_FromWideChar(wbuf, wcslen(wbuf)); 1211 } 1212#endif 1213 1214 Py_BEGIN_ALLOW_THREADS 1215#if defined(PYOS_OS2) && defined(PYCC_GCC) 1216 res = _getcwd2(buf, sizeof buf); 1217#else 1218 res = getcwd(buf, sizeof buf); 1219#endif 1220 Py_END_ALLOW_THREADS 1221 if (res == NULL) 1222 return posix_error(); 1223 return PyUnicode_Decode(buf, strlen(buf), Py_FileSystemDefaultEncoding,"strict"); 1224} 1225#endif 1226 1227 1228#ifdef HAVE_LINK 1229PyDoc_STRVAR(posix_link__doc__, 1230"link(src, dst)\n\n\ 1231Create a hard link to a file."); 1232 1233static PyObject * 1234posix_link(PyObject *self, PyObject *args) 1235{ 1236 return posix_2str(args, "etet:link", link, NULL, NULL); 1237} 1238#endif /* HAVE_LINK */ 1239 1240 1241PyDoc_STRVAR(posix_listdir__doc__, 1242"listdir(path) -> list_of_strings\n\n\ 1243Return a list containing the names of the entries in the directory.\n\ 1244\n\ 1245 path: path of directory to list\n\ 1246\n\ 1247The list is in arbitrary order. It does not include the special\n\ 1248entries '.' and '..' even if they are present in the directory."); 1249 1250static PyObject * 1251posix_listdir(PyObject *self, PyObject *args) 1252{ 1253 /* XXX Should redo this putting the (now four) versions of opendir 1254 in separate files instead of having them all here... */ 1255#if defined(MS_WINDOWS) && !defined(HAVE_OPENDIR) 1256 1257 PyObject *d, *v; 1258 HANDLE hFindFile; 1259 WIN32_FIND_DATA FileData; 1260 /* MAX_PATH characters could mean a bigger encoded string */ 1261 char namebuf[MAX_PATH*2+5]; 1262 char *bufptr = namebuf; 1263 int len = sizeof(namebuf)/sizeof(namebuf[0]); 1264 1265#ifdef Py_WIN_WIDE_FILENAMES 1266 /* If on wide-character-capable OS see if argument 1267 is Unicode and if so use wide API. */ 1268 if (unicode_file_names()) { 1269 PyUnicodeObject *po; 1270 if (PyArg_ParseTuple(args, "U:listdir", &po)) { 1271 WIN32_FIND_DATAW wFileData; 1272 Py_UNICODE wnamebuf[MAX_PATH*2+5]; 1273 Py_UNICODE wch; 1274 wcsncpy(wnamebuf, PyUnicode_AS_UNICODE(po), MAX_PATH); 1275 wnamebuf[MAX_PATH] = L'\0'; 1276 len = wcslen(wnamebuf); 1277 wch = (len > 0) ? wnamebuf[len-1] : L'\0'; 1278 if (wch != L'/' && wch != L'\\' && wch != L':') 1279 wnamebuf[len++] = L'/'; 1280 wcscpy(wnamebuf + len, L"*.*"); 1281 if ((d = PyList_New(0)) == NULL) 1282 return NULL; 1283 hFindFile = FindFirstFileW(wnamebuf, &wFileData); 1284 if (hFindFile == INVALID_HANDLE_VALUE) { 1285 errno = GetLastError(); 1286 if (errno == ERROR_FILE_NOT_FOUND) { 1287 return d; 1288 } 1289 Py_DECREF(d); 1290 return win32_error_unicode("FindFirstFileW", wnamebuf); 1291 } 1292 do { 1293 if (wFileData.cFileName[0] == L'.' && 1294 (wFileData.cFileName[1] == L'\0' || 1295 wFileData.cFileName[1] == L'.' && 1296 wFileData.cFileName[2] == L'\0')) 1297 continue; 1298 v = PyUnicode_FromUnicode(wFileData.cFileName, wcslen(wFileData.cFileName)); 1299 if (v == NULL) { 1300 Py_DECREF(d); 1301 d = NULL; 1302 break; 1303 } 1304 if (PyList_Append(d, v) != 0) { 1305 Py_DECREF(v); 1306 Py_DECREF(d); 1307 d = NULL; 1308 break; 1309 } 1310 Py_DECREF(v); 1311 } while (FindNextFileW(hFindFile, &wFileData) == TRUE); 1312 1313 if (FindClose(hFindFile) == FALSE) { 1314 Py_DECREF(d); 1315 return win32_error_unicode("FindClose", wnamebuf); 1316 } 1317 return d; 1318 } 1319 /* Drop the argument parsing error as narrow strings 1320 are also valid. */ 1321 PyErr_Clear(); 1322 } 1323#endif 1324 1325 if (!PyArg_ParseTuple(args, "et#:listdir", 1326 Py_FileSystemDefaultEncoding, &bufptr, &len)) 1327 return NULL; 1328 if (len > 0) { 1329 char ch = namebuf[len-1]; 1330 if (ch != SEP && ch != ALTSEP && ch != ':') 1331 namebuf[len++] = '/'; 1332 } 1333 strcpy(namebuf + len, "*.*"); 1334 1335 if ((d = PyList_New(0)) == NULL) 1336 return NULL; 1337 1338 hFindFile = FindFirstFile(namebuf, &FileData); 1339 if (hFindFile == INVALID_HANDLE_VALUE) { 1340 errno = GetLastError(); 1341 if (errno == ERROR_FILE_NOT_FOUND) 1342 return d; 1343 Py_DECREF(d); 1344 return win32_error("FindFirstFile", namebuf); 1345 } 1346 do { 1347 if (FileData.cFileName[0] == '.' && 1348 (FileData.cFileName[1] == '\0' || 1349 FileData.cFileName[1] == '.' && 1350 FileData.cFileName[2] == '\0')) 1351 continue; 1352 v = PyString_FromString(FileData.cFileName); 1353 if (v == NULL) { 1354 Py_DECREF(d); 1355 d = NULL; 1356 break; 1357 } 1358 if (PyList_Append(d, v) != 0) { 1359 Py_DECREF(v); 1360 Py_DECREF(d); 1361 d = NULL; 1362 break; 1363 } 1364 Py_DECREF(v); 1365 } while (FindNextFile(hFindFile, &FileData) == TRUE); 1366 1367 if (FindClose(hFindFile) == FALSE) { 1368 Py_DECREF(d); 1369 return win32_error("FindClose", namebuf); 1370 } 1371 1372 return d; 1373 1374#elif defined(PYOS_OS2) 1375 1376#ifndef MAX_PATH 1377#define MAX_PATH CCHMAXPATH 1378#endif 1379 char *name, *pt; 1380 int len; 1381 PyObject *d, *v; 1382 char namebuf[MAX_PATH+5]; 1383 HDIR hdir = 1; 1384 ULONG srchcnt = 1; 1385 FILEFINDBUF3 ep; 1386 APIRET rc; 1387 1388 if (!PyArg_ParseTuple(args, "t#:listdir", &name, &len)) 1389 return NULL; 1390 if (len >= MAX_PATH) { 1391 PyErr_SetString(PyExc_ValueError, "path too long"); 1392 return NULL; 1393 } 1394 strcpy(namebuf, name); 1395 for (pt = namebuf; *pt; pt++) 1396 if (*pt == ALTSEP) 1397 *pt = SEP; 1398 if (namebuf[len-1] != SEP) 1399 namebuf[len++] = SEP; 1400 strcpy(namebuf + len, "*.*"); 1401 1402 if ((d = PyList_New(0)) == NULL) 1403 return NULL; 1404 1405 rc = DosFindFirst(namebuf, /* Wildcard Pattern to Match */ 1406 &hdir, /* Handle to Use While Search Directory */ 1407 FILE_READONLY | FILE_HIDDEN | FILE_SYSTEM | FILE_DIRECTORY, 1408 &ep, sizeof(ep), /* Structure to Receive Directory Entry */ 1409 &srchcnt, /* Max and Actual Count of Entries Per Iteration */ 1410 FIL_STANDARD); /* Format of Entry (EAs or Not) */ 1411 1412 if (rc != NO_ERROR) { 1413 errno = ENOENT; 1414 return posix_error_with_filename(name); 1415 } 1416 1417 if (srchcnt > 0) { /* If Directory is NOT Totally Empty, */ 1418 do { 1419 if (ep.achName[0] == '.' 1420 && (ep.achName[1] == '\0' || (ep.achName[1] == '.' && ep.achName[2] == '\0'))) 1421 continue; /* Skip Over "." and ".." Names */ 1422 1423 strcpy(namebuf, ep.achName); 1424 1425 /* Leave Case of Name Alone -- In Native Form */ 1426 /* (Removed Forced Lowercasing Code) */ 1427 1428 v = PyString_FromString(namebuf); 1429 if (v == NULL) { 1430 Py_DECREF(d); 1431 d = NULL; 1432 break; 1433 } 1434 if (PyList_Append(d, v) != 0) { 1435 Py_DECREF(v); 1436 Py_DECREF(d); 1437 d = NULL; 1438 break; 1439 } 1440 Py_DECREF(v); 1441 } while (DosFindNext(hdir, &ep, sizeof(ep), &srchcnt) == NO_ERROR && srchcnt > 0); 1442 } 1443 1444 return d; 1445#else 1446 1447 char *name; 1448 PyObject *d, *v; 1449 DIR *dirp; 1450 struct dirent *ep; 1451 if (!PyArg_ParseTuple(args, "s:listdir", &name)) 1452 return NULL; 1453 if ((dirp = opendir(name)) == NULL) { 1454 return posix_error_with_filename(name); 1455 } 1456 if ((d = PyList_New(0)) == NULL) { 1457 closedir(dirp); 1458 return NULL; 1459 } 1460 while ((ep = readdir(dirp)) != NULL) { 1461 if (ep->d_name[0] == '.' && 1462 (NAMLEN(ep) == 1 || 1463 (ep->d_name[1] == '.' && NAMLEN(ep) == 2))) 1464 continue; 1465 v = PyString_FromStringAndSize(ep->d_name, NAMLEN(ep)); 1466 if (v == NULL) { 1467 Py_DECREF(d); 1468 d = NULL; 1469 break; 1470 } 1471 if (PyList_Append(d, v) != 0) { 1472 Py_DECREF(v); 1473 Py_DECREF(d); 1474 d = NULL; 1475 break; 1476 } 1477 Py_DECREF(v); 1478 } 1479 closedir(dirp); 1480 1481 return d; 1482 1483#endif /* which OS */ 1484} /* end of posix_listdir */ 1485 1486#ifdef MS_WINDOWS 1487/* A helper function for abspath on win32 */ 1488static PyObject * 1489posix__getfullpathname(PyObject *self, PyObject *args) 1490{ 1491 /* assume encoded strings wont more than double no of chars */ 1492 char inbuf[MAX_PATH*2]; 1493 char *inbufp = inbuf; 1494 int insize = sizeof(inbuf)/sizeof(inbuf[0]); 1495 char outbuf[MAX_PATH*2]; 1496 char *temp; 1497#ifdef Py_WIN_WIDE_FILENAMES 1498 if (unicode_file_names()) { 1499 PyUnicodeObject *po; 1500 if (PyArg_ParseTuple(args, "U|:_getfullpathname", &po)) { 1501 Py_UNICODE woutbuf[MAX_PATH*2]; 1502 Py_UNICODE *wtemp; 1503 if (!GetFullPathNameW(PyUnicode_AS_UNICODE(po), 1504 sizeof(woutbuf)/sizeof(woutbuf[0]), 1505 woutbuf, &wtemp)) 1506 return win32_error("GetFullPathName", ""); 1507 return PyUnicode_FromUnicode(woutbuf, wcslen(woutbuf)); 1508 } 1509 /* Drop the argument parsing error as narrow strings 1510 are also valid. */ 1511 PyErr_Clear(); 1512 } 1513#endif 1514 if (!PyArg_ParseTuple (args, "et#:_getfullpathname", 1515 Py_FileSystemDefaultEncoding, &inbufp, 1516 &insize)) 1517 return NULL; 1518 if (!GetFullPathName(inbuf, sizeof(outbuf)/sizeof(outbuf[0]), 1519 outbuf, &temp)) 1520 return win32_error("GetFullPathName", inbuf); 1521 return PyString_FromString(outbuf); 1522} /* end of posix__getfullpathname */ 1523#endif /* MS_WINDOWS */ 1524 1525PyDoc_STRVAR(posix_mkdir__doc__, 1526"mkdir(path [, mode=0777])\n\n\ 1527Create a directory."); 1528 1529static PyObject * 1530posix_mkdir(PyObject *self, PyObject *args) 1531{ 1532 int res; 1533 char *path = NULL; 1534 int mode = 0777; 1535 1536#ifdef Py_WIN_WIDE_FILENAMES 1537 if (unicode_file_names()) { 1538 PyUnicodeObject *po; 1539 if (PyArg_ParseTuple(args, "U|i:mkdir", &po)) { 1540 Py_BEGIN_ALLOW_THREADS 1541 /* PyUnicode_AS_UNICODE OK without thread lock as 1542 it is a simple dereference. */ 1543 res = _wmkdir(PyUnicode_AS_UNICODE(po)); 1544 Py_END_ALLOW_THREADS 1545 if (res < 0) 1546 return posix_error(); 1547 Py_INCREF(Py_None); 1548 return Py_None; 1549 } 1550 /* Drop the argument parsing error as narrow strings 1551 are also valid. */ 1552 PyErr_Clear(); 1553 } 1554#endif 1555 1556 if (!PyArg_ParseTuple(args, "et|i:mkdir", 1557 Py_FileSystemDefaultEncoding, &path, &mode)) 1558 return NULL; 1559 Py_BEGIN_ALLOW_THREADS 1560#if ( defined(__WATCOMC__) || defined(_MSC_VER) || defined(PYCC_VACPP) ) && !defined(__QNX__) 1561 res = mkdir(path); 1562#else 1563 res = mkdir(path, mode); 1564#endif 1565 Py_END_ALLOW_THREADS 1566 if (res < 0) 1567 return posix_error_with_allocated_filename(path); 1568 PyMem_Free(path); 1569 Py_INCREF(Py_None); 1570 return Py_None; 1571} 1572 1573 1574#ifdef HAVE_NICE 1575#if defined(HAVE_BROKEN_NICE) && defined(HAVE_SYS_RESOURCE_H) 1576#if defined(HAVE_GETPRIORITY) && !defined(PRIO_PROCESS) 1577#include <sys/resource.h> 1578#endif 1579#endif 1580 1581PyDoc_STRVAR(posix_nice__doc__, 1582"nice(inc) -> new_priority\n\n\ 1583Decrease the priority of process by inc and return the new priority."); 1584 1585static PyObject * 1586posix_nice(PyObject *self, PyObject *args) 1587{ 1588 int increment, value; 1589 1590 if (!PyArg_ParseTuple(args, "i:nice", &increment)) 1591 return NULL; 1592 1593 /* There are two flavours of 'nice': one that returns the new 1594 priority (as required by almost all standards out there) and the 1595 Linux/FreeBSD/BSDI one, which returns '0' on success and advices 1596 the use of getpriority() to get the new priority. 1597 1598 If we are of the nice family that returns the new priority, we 1599 need to clear errno before the call, and check if errno is filled 1600 before calling posix_error() on a returnvalue of -1, because the 1601 -1 may be the actual new priority! */ 1602 1603 errno = 0; 1604 value = nice(increment); 1605#if defined(HAVE_BROKEN_NICE) && defined(HAVE_GETPRIORITY) 1606 if (value == 0) 1607 value = getpriority(PRIO_PROCESS, 0); 1608#endif 1609 if (value == -1 && errno != 0) 1610 /* either nice() or getpriority() returned an error */ 1611 return posix_error(); 1612 return PyInt_FromLong((long) value); 1613} 1614#endif /* HAVE_NICE */ 1615 1616 1617PyDoc_STRVAR(posix_rename__doc__, 1618"rename(old, new)\n\n\ 1619Rename a file or directory."); 1620 1621static PyObject * 1622posix_rename(PyObject *self, PyObject *args) 1623{ 1624#ifdef MS_WINDOWS 1625 return posix_2str(args, "etet:rename", rename, "OO:rename", _wrename); 1626#else 1627 return posix_2str(args, "etet:rename", rename, NULL, NULL); 1628#endif 1629} 1630 1631 1632PyDoc_STRVAR(posix_rmdir__doc__, 1633"rmdir(path)\n\n\ 1634Remove a directory."); 1635 1636static PyObject * 1637posix_rmdir(PyObject *self, PyObject *args) 1638{ 1639#ifdef MS_WINDOWS 1640 return posix_1str(args, "et:rmdir", rmdir, "U:rmdir", _wrmdir); 1641#else 1642 return posix_1str(args, "et:rmdir", rmdir, NULL, NULL); 1643#endif 1644} 1645 1646 1647PyDoc_STRVAR(posix_stat__doc__, 1648"stat(path) -> stat result\n\n\ 1649Perform a stat system call on the given path."); 1650 1651static PyObject * 1652posix_stat(PyObject *self, PyObject *args) 1653{ 1654#ifdef MS_WINDOWS 1655 return posix_do_stat(self, args, "et:stat", STAT, "U:stat", _wstati64); 1656#else 1657 return posix_do_stat(self, args, "et:stat", STAT, NULL, NULL); 1658#endif 1659} 1660 1661 1662#ifdef HAVE_SYSTEM 1663PyDoc_STRVAR(posix_system__doc__, 1664"system(command) -> exit_status\n\n\ 1665Execute the command (a string) in a subshell."); 1666 1667static PyObject * 1668posix_system(PyObject *self, PyObject *args) 1669{ 1670 char *command; 1671 long sts; 1672 if (!PyArg_ParseTuple(args, "s:system", &command)) 1673 return NULL; 1674 Py_BEGIN_ALLOW_THREADS 1675 sts = system(command); 1676 Py_END_ALLOW_THREADS 1677 return PyInt_FromLong(sts); 1678} 1679#endif 1680 1681 1682PyDoc_STRVAR(posix_umask__doc__, 1683"umask(new_mask) -> old_mask\n\n\ 1684Set the current numeric umask and return the previous umask."); 1685 1686static PyObject * 1687posix_umask(PyObject *self, PyObject *args) 1688{ 1689 int i; 1690 if (!PyArg_ParseTuple(args, "i:umask", &i)) 1691 return NULL; 1692 i = (int)umask(i); 1693 if (i < 0) 1694 return posix_error(); 1695 return PyInt_FromLong((long)i); 1696} 1697 1698 1699PyDoc_STRVAR(posix_unlink__doc__, 1700"unlink(path)\n\n\ 1701Remove a file (same as remove(path))."); 1702 1703PyDoc_STRVAR(posix_remove__doc__, 1704"remove(path)\n\n\ 1705Remove a file (same as unlink(path))."); 1706 1707static PyObject * 1708posix_unlink(PyObject *self, PyObject *args) 1709{ 1710#ifdef MS_WINDOWS 1711 return posix_1str(args, "et:remove", unlink, "U:remove", _wunlink); 1712#else 1713 return posix_1str(args, "et:remove", unlink, NULL, NULL); 1714#endif 1715} 1716 1717 1718#ifdef HAVE_UNAME 1719PyDoc_STRVAR(posix_uname__doc__, 1720"uname() -> (sysname, nodename, release, version, machine)\n\n\ 1721Return a tuple identifying the current operating system."); 1722 1723static PyObject * 1724posix_uname(PyObject *self, PyObject *args) 1725{ 1726 struct utsname u; 1727 int res; 1728 if (!PyArg_ParseTuple(args, ":uname")) 1729 return NULL; 1730 Py_BEGIN_ALLOW_THREADS 1731 res = uname(&u); 1732 Py_END_ALLOW_THREADS 1733 if (res < 0) 1734 return posix_error(); 1735 return Py_BuildValue("(sssss)", 1736 u.sysname, 1737 u.nodename, 1738 u.release, 1739 u.version, 1740 u.machine); 1741} 1742#endif /* HAVE_UNAME */ 1743 1744static int 1745extract_time(PyObject *t, long* sec, long* usec) 1746{ 1747 long intval; 1748 if (PyFloat_Check(t)) { 1749 double tval = PyFloat_AsDouble(t); 1750 PyObject *intobj = t->ob_type->tp_as_number->nb_int(t); 1751 if (!intobj) 1752 return -1; 1753 intval = PyInt_AsLong(intobj); 1754 Py_DECREF(intobj); 1755 *sec = intval; 1756 *usec = (long)((tval - intval) * 1e6); /* can't exceed 1000000 */ 1757 if (*usec < 0) 1758 /* If rounding gave us a negative number, 1759 truncate. */ 1760 *usec = 0; 1761 return 0; 1762 } 1763 intval = PyInt_AsLong(t); 1764 if (intval == -1 && PyErr_Occurred()) 1765 return -1; 1766 *sec = intval; 1767 *usec = 0; 1768 return 0; 1769} 1770 1771PyDoc_STRVAR(posix_utime__doc__, 1772"utime(path, (atime, utime))\n\ 1773utime(path, None)\n\n\ 1774Set the access and modified time of the file to the given values. If the\n\ 1775second form is used, set the access and modified times to the current time."); 1776 1777static PyObject * 1778posix_utime(PyObject *self, PyObject *args) 1779{ 1780 char *path; 1781 long atime, mtime, ausec, musec; 1782 int res; 1783 PyObject* arg; 1784 1785#if defined(HAVE_UTIMES) 1786 struct timeval buf[2]; 1787#define ATIME buf[0].tv_sec 1788#define MTIME buf[1].tv_sec 1789#elif defined(HAVE_UTIME_H) 1790/* XXX should define struct utimbuf instead, above */ 1791 struct utimbuf buf; 1792#define ATIME buf.actime 1793#define MTIME buf.modtime 1794#define UTIME_ARG &buf 1795#else /* HAVE_UTIMES */ 1796 time_t buf[2]; 1797#define ATIME buf[0] 1798#define MTIME buf[1] 1799#define UTIME_ARG buf 1800#endif /* HAVE_UTIMES */ 1801 1802 if (!PyArg_ParseTuple(args, "sO:utime", &path, &arg)) 1803 return NULL; 1804 if (arg == Py_None) { 1805 /* optional time values not given */ 1806 Py_BEGIN_ALLOW_THREADS 1807 res = utime(path, NULL); 1808 Py_END_ALLOW_THREADS 1809 } 1810 else if (!PyTuple_Check(arg) || PyTuple_Size(arg) != 2) { 1811 PyErr_SetString(PyExc_TypeError, 1812 "utime() arg 2 must be a tuple (atime, mtime)"); 1813 return NULL; 1814 } 1815 else { 1816 if (extract_time(PyTuple_GET_ITEM(arg, 0), 1817 &atime, &ausec) == -1) 1818 return NULL; 1819 if (extract_time(PyTuple_GET_ITEM(arg, 1), 1820 &mtime, &musec) == -1) 1821 return NULL; 1822 ATIME = atime; 1823 MTIME = mtime; 1824#ifdef HAVE_UTIMES 1825 buf[0].tv_usec = ausec; 1826 buf[1].tv_usec = musec; 1827 Py_BEGIN_ALLOW_THREADS 1828 res = utimes(path, buf); 1829 Py_END_ALLOW_THREADS 1830#else 1831 Py_BEGIN_ALLOW_THREADS 1832 res = utime(path, UTIME_ARG); 1833 Py_END_ALLOW_THREADS 1834#endif 1835 } 1836 if (res < 0) 1837 return posix_error_with_filename(path); 1838 Py_INCREF(Py_None); 1839 return Py_None; 1840#undef UTIME_ARG 1841#undef ATIME 1842#undef MTIME 1843} 1844 1845 1846/* Process operations */ 1847 1848PyDoc_STRVAR(posix__exit__doc__, 1849"_exit(status)\n\n\ 1850Exit to the system with specified status, without normal exit processing."); 1851 1852static PyObject * 1853posix__exit(PyObject *self, PyObject *args) 1854{ 1855 int sts; 1856 if (!PyArg_ParseTuple(args, "i:_exit", &sts)) 1857 return NULL; 1858 _exit(sts); 1859 return NULL; /* Make gcc -Wall happy */ 1860} 1861 1862#if defined(HAVE_EXECV) || defined(HAVE_SPAWNV) 1863static void 1864free_string_array(char **array, int count) 1865{ 1866 int i; 1867 for (i = 0; i < count; i++) 1868 PyMem_Free(array[i]); 1869 PyMem_DEL(array); 1870} 1871#endif 1872 1873 1874#ifdef HAVE_EXECV 1875PyDoc_STRVAR(posix_execv__doc__, 1876"execv(path, args)\n\n\ 1877Execute an executable path with arguments, replacing current process.\n\ 1878\n\ 1879 path: path of executable file\n\ 1880 args: tuple or list of strings"); 1881 1882static PyObject * 1883posix_execv(PyObject *self, PyObject *args) 1884{ 1885 char *path; 1886 PyObject *argv; 1887 char **argvlist; 1888 int i, argc; 1889 PyObject *(*getitem)(PyObject *, int); 1890 1891 /* execv has two arguments: (path, argv), where 1892 argv is a list or tuple of strings. */ 1893 1894 if (!PyArg_ParseTuple(args, "etO:execv", 1895 Py_FileSystemDefaultEncoding, 1896 &path, &argv)) 1897 return NULL; 1898 if (PyList_Check(argv)) { 1899 argc = PyList_Size(argv); 1900 getitem = PyList_GetItem; 1901 } 1902 else if (PyTuple_Check(argv)) { 1903 argc = PyTuple_Size(argv); 1904 getitem = PyTuple_GetItem; 1905 } 1906 else { 1907 PyErr_SetString(PyExc_TypeError, "execv() arg 2 must be a tuple or list"); 1908 PyMem_Free(path); 1909 return NULL; 1910 } 1911 1912 if (argc == 0) { 1913 PyErr_SetString(PyExc_ValueError, "execv() arg 2 must not be empty"); 1914 PyMem_Free(path); 1915 return NULL; 1916 } 1917 1918 argvlist = PyMem_NEW(char *, argc+1); 1919 if (argvlist == NULL) { 1920 PyMem_Free(path); 1921 return NULL; 1922 } 1923 for (i = 0; i < argc; i++) { 1924 if (!PyArg_Parse((*getitem)(argv, i), "et", 1925 Py_FileSystemDefaultEncoding, 1926 &argvlist[i])) { 1927 free_string_array(argvlist, i); 1928 PyErr_SetString(PyExc_TypeError, 1929 "execv() arg 2 must contain only strings"); 1930 PyMem_Free(path); 1931 return NULL; 1932 1933 } 1934 } 1935 argvlist[argc] = NULL; 1936 1937#ifdef BAD_EXEC_PROTOTYPES 1938 execv(path, (const char **) argvlist); 1939#else /* BAD_EXEC_PROTOTYPES */ 1940 execv(path, argvlist); 1941#endif /* BAD_EXEC_PROTOTYPES */ 1942 1943 /* If we get here it's definitely an error */ 1944 1945 free_string_array(argvlist, argc); 1946 PyMem_Free(path); 1947 return posix_error(); 1948} 1949 1950 1951PyDoc_STRVAR(posix_execve__doc__, 1952"execve(path, args, env)\n\n\ 1953Execute a path with arguments and environment, replacing current process.\n\ 1954\n\ 1955 path: path of executable file\n\ 1956 args: tuple or list of arguments\n\ 1957 env: dictionary of strings mapping to strings"); 1958 1959static PyObject * 1960posix_execve(PyObject *self, PyObject *args) 1961{ 1962 char *path; 1963 PyObject *argv, *env; 1964 char **argvlist; 1965 char **envlist; 1966 PyObject *key, *val, *keys=NULL, *vals=NULL; 1967 int i, pos, argc, envc; 1968 PyObject *(*getitem)(PyObject *, int); 1969 int lastarg = 0; 1970 1971 /* execve has three arguments: (path, argv, env), where 1972 argv is a list or tuple of strings and env is a dictionary 1973 like posix.environ. */ 1974 1975 if (!PyArg_ParseTuple(args, "etOO:execve", 1976 Py_FileSystemDefaultEncoding, 1977 &path, &argv, &env)) 1978 return NULL; 1979 if (PyList_Check(argv)) { 1980 argc = PyList_Size(argv); 1981 getitem = PyList_GetItem; 1982 } 1983 else if (PyTuple_Check(argv)) { 1984 argc = PyTuple_Size(argv); 1985 getitem = PyTuple_GetItem; 1986 } 1987 else { 1988 PyErr_SetString(PyExc_TypeError, "execve() arg 2 must be a tuple or list"); 1989 goto fail_0; 1990 } 1991 if (!PyMapping_Check(env)) { 1992 PyErr_SetString(PyExc_TypeError, "execve() arg 3 must be a mapping object"); 1993 goto fail_0; 1994 } 1995 1996 if (argc == 0) { 1997 PyErr_SetString(PyExc_ValueError, 1998 "execve() arg 2 must not be empty"); 1999 goto fail_0; 2000 } 2001 2002 argvlist = PyMem_NEW(char *, argc+1); 2003 if (argvlist == NULL) { 2004 PyErr_NoMemory(); 2005 goto fail_0; 2006 } 2007 for (i = 0; i < argc; i++) { 2008 if (!PyArg_Parse((*getitem)(argv, i), 2009 "et;execve() arg 2 must contain only strings", 2010 &argvlist[i])) 2011 { 2012 lastarg = i; 2013 goto fail_1; 2014 } 2015 } 2016 lastarg = argc; 2017 argvlist[argc] = NULL; 2018 2019 i = PyMapping_Size(env); 2020 envlist = PyMem_NEW(char *, i + 1); 2021 if (envlist == NULL) { 2022 PyErr_NoMemory(); 2023 goto fail_1; 2024 } 2025 envc = 0; 2026 keys = PyMapping_Keys(env); 2027 vals = PyMapping_Values(env); 2028 if (!keys || !vals) 2029 goto fail_2; 2030 2031 for (pos = 0; pos < i; pos++) { 2032 char *p, *k, *v; 2033 size_t len; 2034 2035 key = PyList_GetItem(keys, pos); 2036 val = PyList_GetItem(vals, pos); 2037 if (!key || !val) 2038 goto fail_2; 2039 2040 if (!PyArg_Parse(key, "s;execve() arg 3 contains a non-string key", &k) || 2041 !PyArg_Parse(val, "s;execve() arg 3 contains a non-string value", &v)) 2042 { 2043 goto fail_2; 2044 } 2045 2046#if defined(PYOS_OS2) 2047 /* Omit Pseudo-Env Vars that Would Confuse Programs if Passed On */ 2048 if (stricmp(k, "BEGINLIBPATH") != 0 && stricmp(k, "ENDLIBPATH") != 0) { 2049#endif 2050 len = PyString_Size(key) + PyString_Size(val) + 2; 2051 p = PyMem_NEW(char, len); 2052 if (p == NULL) { 2053 PyErr_NoMemory(); 2054 goto fail_2; 2055 } 2056 PyOS_snprintf(p, len, "%s=%s", k, v); 2057 envlist[envc++] = p; 2058#if defined(PYOS_OS2) 2059 } 2060#endif 2061 } 2062 envlist[envc] = 0; 2063 2064 2065#ifdef BAD_EXEC_PROTOTYPES 2066 execve(path, (const char **)argvlist, envlist); 2067#else /* BAD_EXEC_PROTOTYPES */ 2068 execve(path, argvlist, envlist); 2069#endif /* BAD_EXEC_PROTOTYPES */ 2070 2071 /* If we get here it's definitely an error */ 2072 2073 (void) posix_error(); 2074 2075 fail_2: 2076 while (--envc >= 0) 2077 PyMem_DEL(envlist[envc]); 2078 PyMem_DEL(envlist); 2079 fail_1: 2080 free_string_array(argvlist,lastarg); 2081 Py_XDECREF(vals); 2082 Py_XDECREF(keys); 2083 fail_0: 2084 PyMem_Free(path); 2085 return NULL; 2086} 2087#endif /* HAVE_EXECV */ 2088 2089 2090#ifdef HAVE_SPAWNV 2091PyDoc_STRVAR(posix_spawnv__doc__, 2092"spawnv(mode, path, args)\n\n\ 2093Execute the program 'path' in a new process.\n\ 2094\n\ 2095 mode: mode of process creation\n\ 2096 path: path of executable file\n\ 2097 args: tuple or list of strings"); 2098 2099static PyObject * 2100posix_spawnv(PyObject *self, PyObject *args) 2101{ 2102 char *path; 2103 PyObject *argv; 2104 char **argvlist; 2105 int mode, i, argc; 2106 Py_intptr_t spawnval; 2107 PyObject *(*getitem)(PyObject *, int); 2108 2109 /* spawnv has three arguments: (mode, path, argv), where 2110 argv is a list or tuple of strings. */ 2111 2112 if (!PyArg_ParseTuple(args, "ietO:spawnv", &mode, 2113 Py_FileSystemDefaultEncoding, 2114 &path, &argv)) 2115 return NULL; 2116 if (PyList_Check(argv)) { 2117 argc = PyList_Size(argv); 2118 getitem = PyList_GetItem; 2119 } 2120 else if (PyTuple_Check(argv)) { 2121 argc = PyTuple_Size(argv); 2122 getitem = PyTuple_GetItem; 2123 } 2124 else { 2125 PyErr_SetString(PyExc_TypeError, "spawnv() arg 2 must be a tuple or list"); 2126 PyMem_Free(path); 2127 return NULL; 2128 } 2129 2130 argvlist = PyMem_NEW(char *, argc+1); 2131 if (argvlist == NULL) { 2132 PyMem_Free(path); 2133 return NULL; 2134 } 2135 for (i = 0; i < argc; i++) { 2136 if (!PyArg_Parse((*getitem)(argv, i), "et", 2137 Py_FileSystemDefaultEncoding, 2138 &argvlist[i])) { 2139 free_string_array(argvlist, i); 2140 PyErr_SetString(PyExc_TypeError, 2141 "spawnv() arg 2 must contain only strings"); 2142 PyMem_Free(path); 2143 return NULL; 2144 } 2145 } 2146 argvlist[argc] = NULL; 2147 2148#if defined(PYOS_OS2) && defined(PYCC_GCC) 2149 Py_BEGIN_ALLOW_THREADS 2150 spawnval = spawnv(mode, path, argvlist); 2151 Py_END_ALLOW_THREADS 2152#else 2153 if (mode == _OLD_P_OVERLAY) 2154 mode = _P_OVERLAY; 2155 2156 Py_BEGIN_ALLOW_THREADS 2157 spawnval = _spawnv(mode, path, argvlist); 2158 Py_END_ALLOW_THREADS 2159#endif 2160 2161 free_string_array(argvlist, argc); 2162 PyMem_Free(path); 2163 2164 if (spawnval == -1) 2165 return posix_error(); 2166 else 2167#if SIZEOF_LONG == SIZEOF_VOID_P 2168 return Py_BuildValue("l", (long) spawnval); 2169#else 2170 return Py_BuildValue("L", (LONG_LONG) spawnval); 2171#endif 2172} 2173 2174 2175PyDoc_STRVAR(posix_spawnve__doc__, 2176"spawnve(mode, path, args, env)\n\n\ 2177Execute the program 'path' in a new process.\n\ 2178\n\ 2179 mode: mode of process creation\n\ 2180 path: path of executable file\n\ 2181 args: tuple or list of arguments\n\ 2182 env: dictionary of strings mapping to strings"); 2183 2184static PyObject * 2185posix_spawnve(PyObject *self, PyObject *args) 2186{ 2187 char *path; 2188 PyObject *argv, *env; 2189 char **argvlist; 2190 char **envlist; 2191 PyObject *key, *val, *keys=NULL, *vals=NULL, *res=NULL; 2192 int mode, i, pos, argc, envc; 2193 Py_intptr_t spawnval; 2194 PyObject *(*getitem)(PyObject *, int); 2195 int lastarg = 0; 2196 2197 /* spawnve has four arguments: (mode, path, argv, env), where 2198 argv is a list or tuple of strings and env is a dictionary 2199 like posix.environ. */ 2200 2201 if (!PyArg_ParseTuple(args, "ietOO:spawnve", &mode, 2202 Py_FileSystemDefaultEncoding, 2203 &path, &argv, &env)) 2204 return NULL; 2205 if (PyList_Check(argv)) { 2206 argc = PyList_Size(argv); 2207 getitem = PyList_GetItem; 2208 } 2209 else if (PyTuple_Check(argv)) { 2210 argc = PyTuple_Size(argv); 2211 getitem = PyTuple_GetItem; 2212 } 2213 else { 2214 PyErr_SetString(PyExc_TypeError, "spawnve() arg 2 must be a tuple or list"); 2215 goto fail_0; 2216 } 2217 if (!PyMapping_Check(env)) { 2218 PyErr_SetString(PyExc_TypeError, "spawnve() arg 3 must be a mapping object"); 2219 goto fail_0; 2220 } 2221 2222 argvlist = PyMem_NEW(char *, argc+1); 2223 if (argvlist == NULL) { 2224 PyErr_NoMemory(); 2225 goto fail_0; 2226 } 2227 for (i = 0; i < argc; i++) { 2228 if (!PyArg_Parse((*getitem)(argv, i), 2229 "et;spawnve() arg 2 must contain only strings", 2230 Py_FileSystemDefaultEncoding, 2231 &argvlist[i])) 2232 { 2233 lastarg = i; 2234 goto fail_1; 2235 } 2236 } 2237 lastarg = argc; 2238 argvlist[argc] = NULL; 2239 2240 i = PyMapping_Size(env); 2241 envlist = PyMem_NEW(char *, i + 1); 2242 if (envlist == NULL) { 2243 PyErr_NoMemory(); 2244 goto fail_1; 2245 } 2246 envc = 0; 2247 keys = PyMapping_Keys(env); 2248 vals = PyMapping_Values(env); 2249 if (!keys || !vals) 2250 goto fail_2; 2251 2252 for (pos = 0; pos < i; pos++) { 2253 char *p, *k, *v; 2254 size_t len; 2255 2256 key = PyList_GetItem(keys, pos); 2257 val = PyList_GetItem(vals, pos); 2258 if (!key || !val) 2259 goto fail_2; 2260 2261 if (!PyArg_Parse(key, "s;spawnve() arg 3 contains a non-string key", &k) || 2262 !PyArg_Parse(val, "s;spawnve() arg 3 contains a non-string value", &v)) 2263 { 2264 goto fail_2; 2265 } 2266 len = PyString_Size(key) + PyString_Size(val) + 2; 2267 p = PyMem_NEW(char, len); 2268 if (p == NULL) { 2269 PyErr_NoMemory(); 2270 goto fail_2; 2271 } 2272 PyOS_snprintf(p, len, "%s=%s", k, v); 2273 envlist[envc++] = p; 2274 } 2275 envlist[envc] = 0; 2276 2277#if defined(PYOS_OS2) && defined(PYCC_GCC) 2278 Py_BEGIN_ALLOW_THREADS 2279 spawnval = spawnve(mode, path, argvlist, envlist); 2280 Py_END_ALLOW_THREADS 2281#else 2282 if (mode == _OLD_P_OVERLAY) 2283 mode = _P_OVERLAY; 2284 2285 Py_BEGIN_ALLOW_THREADS 2286 spawnval = _spawnve(mode, path, argvlist, envlist); 2287 Py_END_ALLOW_THREADS 2288#endif 2289 2290 if (spawnval == -1) 2291 (void) posix_error(); 2292 else 2293#if SIZEOF_LONG == SIZEOF_VOID_P 2294 res = Py_BuildValue("l", (long) spawnval); 2295#else 2296 res = Py_BuildValue("L", (LONG_LONG) spawnval); 2297#endif 2298 2299 fail_2: 2300 while (--envc >= 0) 2301 PyMem_DEL(envlist[envc]); 2302 PyMem_DEL(envlist); 2303 fail_1: 2304 free_string_array(argvlist, lastarg); 2305 Py_XDECREF(vals); 2306 Py_XDECREF(keys); 2307 fail_0: 2308 PyMem_Free(path); 2309 return res; 2310} 2311#endif /* HAVE_SPAWNV */ 2312 2313 2314#ifdef HAVE_FORK1 2315PyDoc_STRVAR(posix_fork1__doc__, 2316"fork1() -> pid\n\n\ 2317Fork a child process with a single multiplexed (i.e., not bound) thread.\n\ 2318\n\ 2319Return 0 to child process and PID of child to parent process."); 2320 2321static PyObject * 2322posix_fork1(self, args) 2323 PyObject *self; 2324 PyObject *args; 2325{ 2326 int pid; 2327 if (!PyArg_ParseTuple(args, ":fork1")) 2328 return NULL; 2329 pid = fork1(); 2330 if (pid == -1) 2331 return posix_error(); 2332 PyOS_AfterFork(); 2333 return PyInt_FromLong((long)pid); 2334} 2335#endif 2336 2337 2338#ifdef HAVE_FORK 2339PyDoc_STRVAR(posix_fork__doc__, 2340"fork() -> pid\n\n\ 2341Fork a child process.\n\ 2342Return 0 to child process and PID of child to parent process."); 2343 2344static PyObject * 2345posix_fork(PyObject *self, PyObject *args) 2346{ 2347 int pid; 2348 if (!PyArg_ParseTuple(args, ":fork")) 2349 return NULL; 2350 pid = fork(); 2351 if (pid == -1) 2352 return posix_error(); 2353 if (pid == 0) 2354 PyOS_AfterFork(); 2355 return PyInt_FromLong((long)pid); 2356} 2357#endif 2358 2359#if defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) 2360#ifdef HAVE_PTY_H 2361#include <pty.h> 2362#else 2363#ifdef HAVE_LIBUTIL_H 2364#include <libutil.h> 2365#endif /* HAVE_LIBUTIL_H */ 2366#endif /* HAVE_PTY_H */ 2367#endif /* defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) */ 2368 2369#if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) 2370PyDoc_STRVAR(posix_openpty__doc__, 2371"openpty() -> (master_fd, slave_fd)\n\n\ 2372Open a pseudo-terminal, returning open fd's for both master and slave end.\n"); 2373 2374static PyObject * 2375posix_openpty(PyObject *self, PyObject *args) 2376{ 2377 int master_fd, slave_fd; 2378#ifndef HAVE_OPENPTY 2379 char * slave_name; 2380#endif 2381 2382 if (!PyArg_ParseTuple(args, ":openpty")) 2383 return NULL; 2384 2385#ifdef HAVE_OPENPTY 2386 if (openpty(&master_fd, &slave_fd, NULL, NULL, NULL) != 0) 2387 return posix_error(); 2388#else 2389 slave_name = _getpty(&master_fd, O_RDWR, 0666, 0); 2390 if (slave_name == NULL) 2391 return posix_error(); 2392 2393 slave_fd = open(slave_name, O_RDWR); 2394 if (slave_fd < 0) 2395 return posix_error(); 2396#endif /* HAVE_OPENPTY */ 2397 2398 return Py_BuildValue("(ii)", master_fd, slave_fd); 2399 2400} 2401#endif /* defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) */ 2402 2403#ifdef HAVE_FORKPTY 2404PyDoc_STRVAR(posix_forkpty__doc__, 2405"forkpty() -> (pid, master_fd)\n\n\ 2406Fork a new process with a new pseudo-terminal as controlling tty.\n\n\ 2407Like fork(), return 0 as pid to child process, and PID of child to parent.\n\ 2408To both, return fd of newly opened pseudo-terminal.\n"); 2409 2410static PyObject * 2411posix_forkpty(PyObject *self, PyObject *args) 2412{ 2413 int master_fd, pid; 2414 2415 if (!PyArg_ParseTuple(args, ":forkpty")) 2416 return NULL; 2417 pid = forkpty(&master_fd, NULL, NULL, NULL); 2418 if (pid == -1) 2419 return posix_error(); 2420 if (pid == 0) 2421 PyOS_AfterFork(); 2422 return Py_BuildValue("(ii)", pid, master_fd); 2423} 2424#endif 2425 2426#ifdef HAVE_GETEGID 2427PyDoc_STRVAR(posix_getegid__doc__, 2428"getegid() -> egid\n\n\ 2429Return the current process's effective group id."); 2430 2431static PyObject * 2432posix_getegid(PyObject *self, PyObject *args) 2433{ 2434 if (!PyArg_ParseTuple(args, ":getegid")) 2435 return NULL; 2436 return PyInt_FromLong((long)getegid()); 2437} 2438#endif 2439 2440 2441#ifdef HAVE_GETEUID 2442PyDoc_STRVAR(posix_geteuid__doc__, 2443"geteuid() -> euid\n\n\ 2444Return the current process's effective user id."); 2445 2446static PyObject * 2447posix_geteuid(PyObject *self, PyObject *args) 2448{ 2449 if (!PyArg_ParseTuple(args, ":geteuid")) 2450 return NULL; 2451 return PyInt_FromLong((long)geteuid()); 2452} 2453#endif 2454 2455 2456#ifdef HAVE_GETGID 2457PyDoc_STRVAR(posix_getgid__doc__, 2458"getgid() -> gid\n\n\ 2459Return the current process's group id."); 2460 2461static PyObject * 2462posix_getgid(PyObject *self, PyObject *args) 2463{ 2464 if (!PyArg_ParseTuple(args, ":getgid")) 2465 return NULL; 2466 return PyInt_FromLong((long)getgid()); 2467} 2468#endif 2469 2470 2471PyDoc_STRVAR(posix_getpid__doc__, 2472"getpid() -> pid\n\n\ 2473Return the current process id"); 2474 2475static PyObject * 2476posix_getpid(PyObject *self, PyObject *args) 2477{ 2478 if (!PyArg_ParseTuple(args, ":getpid")) 2479 return NULL; 2480 return PyInt_FromLong((long)getpid()); 2481} 2482 2483 2484#ifdef HAVE_GETGROUPS 2485PyDoc_STRVAR(posix_getgroups__doc__, 2486"getgroups() -> list of group IDs\n\n\ 2487Return list of supplemental group IDs for the process."); 2488 2489static PyObject * 2490posix_getgroups(PyObject *self, PyObject *args) 2491{ 2492 PyObject *result = NULL; 2493 2494 if (PyArg_ParseTuple(args, ":getgroups")) { 2495#ifdef NGROUPS_MAX 2496#define MAX_GROUPS NGROUPS_MAX 2497#else 2498 /* defined to be 16 on Solaris7, so this should be a small number */ 2499#define MAX_GROUPS 64 2500#endif 2501 gid_t grouplist[MAX_GROUPS]; 2502 int n; 2503 2504 n = getgroups(MAX_GROUPS, grouplist); 2505 if (n < 0) 2506 posix_error(); 2507 else { 2508 result = PyList_New(n); 2509 if (result != NULL) { 2510 PyObject *o; 2511 int i; 2512 for (i = 0; i < n; ++i) { 2513 o = PyInt_FromLong((long)grouplist[i]); 2514 if (o == NULL) { 2515 Py_DECREF(result); 2516 result = NULL; 2517 break; 2518 } 2519 PyList_SET_ITEM(result, i, o); 2520 } 2521 } 2522 } 2523 } 2524 return result; 2525} 2526#endif 2527 2528#ifdef HAVE_GETPGID 2529PyDoc_STRVAR(posix_getpgid__doc__, 2530"getpgid(pid) -> pgid\n\n\ 2531Call the system call getpgid()."); 2532 2533static PyObject * 2534posix_getpgid(PyObject *self, PyObject *args) 2535{ 2536 int pid, pgid; 2537 if (!PyArg_ParseTuple(args, "i:getpgid", &pid)) 2538 return NULL; 2539 pgid = getpgid(pid); 2540 if (pgid < 0) 2541 return posix_error(); 2542 return PyInt_FromLong((long)pgid); 2543} 2544#endif /* HAVE_GETPGID */ 2545 2546 2547#ifdef HAVE_GETPGRP 2548PyDoc_STRVAR(posix_getpgrp__doc__, 2549"getpgrp() -> pgrp\n\n\ 2550Return the current process group id."); 2551 2552static PyObject * 2553posix_getpgrp(PyObject *self, PyObject *args) 2554{ 2555 if (!PyArg_ParseTuple(args, ":getpgrp")) 2556 return NULL; 2557#ifdef GETPGRP_HAVE_ARG 2558 return PyInt_FromLong((long)getpgrp(0)); 2559#else /* GETPGRP_HAVE_ARG */ 2560 return PyInt_FromLong((long)getpgrp()); 2561#endif /* GETPGRP_HAVE_ARG */ 2562} 2563#endif /* HAVE_GETPGRP */ 2564 2565 2566#ifdef HAVE_SETPGRP 2567PyDoc_STRVAR(posix_setpgrp__doc__, 2568"setpgrp()\n\n\ 2569Make this process a session leader."); 2570 2571static PyObject * 2572posix_setpgrp(PyObject *self, PyObject *args) 2573{ 2574 if (!PyArg_ParseTuple(args, ":setpgrp")) 2575 return NULL; 2576#ifdef SETPGRP_HAVE_ARG 2577 if (setpgrp(0, 0) < 0) 2578#else /* SETPGRP_HAVE_ARG */ 2579 if (setpgrp() < 0) 2580#endif /* SETPGRP_HAVE_ARG */ 2581 return posix_error(); 2582 Py_INCREF(Py_None); 2583 return Py_None; 2584} 2585 2586#endif /* HAVE_SETPGRP */ 2587 2588#ifdef HAVE_GETPPID 2589PyDoc_STRVAR(posix_getppid__doc__, 2590"getppid() -> ppid\n\n\ 2591Return the parent's process id."); 2592 2593static PyObject * 2594posix_getppid(PyObject *self, PyObject *args) 2595{ 2596 if (!PyArg_ParseTuple(args, ":getppid")) 2597 return NULL; 2598 return PyInt_FromLong((long)getppid()); 2599} 2600#endif 2601 2602 2603#ifdef HAVE_GETLOGIN 2604PyDoc_STRVAR(posix_getlogin__doc__, 2605"getlogin() -> string\n\n\ 2606Return the actual login name."); 2607 2608static PyObject * 2609posix_getlogin(PyObject *self, PyObject *args) 2610{ 2611 PyObject *result = NULL; 2612 2613 if (PyArg_ParseTuple(args, ":getlogin")) { 2614 char *name; 2615 int old_errno = errno; 2616 2617 errno = 0; 2618 name = getlogin(); 2619 if (name == NULL) { 2620 if (errno) 2621 posix_error(); 2622 else 2623 PyErr_SetString(PyExc_OSError, 2624 "unable to determine login name"); 2625 } 2626 else 2627 result = PyString_FromString(name); 2628 errno = old_errno; 2629 } 2630 return result; 2631} 2632#endif 2633 2634#ifdef HAVE_GETUID 2635PyDoc_STRVAR(posix_getuid__doc__, 2636"getuid() -> uid\n\n\ 2637Return the current process's user id."); 2638 2639static PyObject * 2640posix_getuid(PyObject *self, PyObject *args) 2641{ 2642 if (!PyArg_ParseTuple(args, ":getuid")) 2643 return NULL; 2644 return PyInt_FromLong((long)getuid()); 2645} 2646#endif 2647 2648 2649#ifdef HAVE_KILL 2650PyDoc_STRVAR(posix_kill__doc__, 2651"kill(pid, sig)\n\n\ 2652Kill a process with a signal."); 2653 2654static PyObject * 2655posix_kill(PyObject *self, PyObject *args) 2656{ 2657 int pid, sig; 2658 if (!PyArg_ParseTuple(args, "ii:kill", &pid, &sig)) 2659 return NULL; 2660#if defined(PYOS_OS2) && !defined(PYCC_GCC) 2661 if (sig == XCPT_SIGNAL_INTR || sig == XCPT_SIGNAL_BREAK) { 2662 APIRET rc; 2663 if ((rc = DosSendSignalException(pid, sig)) != NO_ERROR) 2664 return os2_error(rc); 2665 2666 } else if (sig == XCPT_SIGNAL_KILLPROC) { 2667 APIRET rc; 2668 if ((rc = DosKillProcess(DKP_PROCESS, pid)) != NO_ERROR) 2669 return os2_error(rc); 2670 2671 } else 2672 return NULL; /* Unrecognized Signal Requested */ 2673#else 2674 if (kill(pid, sig) == -1) 2675 return posix_error(); 2676#endif 2677 Py_INCREF(Py_None); 2678 return Py_None; 2679} 2680#endif 2681 2682#ifdef HAVE_KILLPG 2683PyDoc_STRVAR(posix_killpg__doc__, 2684"killpg(pgid, sig)\n\n\ 2685Kill a process group with a signal."); 2686 2687static PyObject * 2688posix_killpg(PyObject *self, PyObject *args) 2689{ 2690 int pgid, sig; 2691 if (!PyArg_ParseTuple(args, "ii:killpg", &pgid, &sig)) 2692 return NULL; 2693 if (killpg(pgid, sig) == -1) 2694 return posix_error(); 2695 Py_INCREF(Py_None); 2696 return Py_None; 2697} 2698#endif 2699 2700#ifdef HAVE_PLOCK 2701 2702#ifdef HAVE_SYS_LOCK_H 2703#include <sys/lock.h> 2704#endif 2705 2706PyDoc_STRVAR(posix_plock__doc__, 2707"plock(op)\n\n\ 2708Lock program segments into memory."); 2709 2710static PyObject * 2711posix_plock(PyObject *self, PyObject *args) 2712{ 2713 int op; 2714 if (!PyArg_ParseTuple(args, "i:plock", &op)) 2715 return NULL; 2716 if (plock(op) == -1) 2717 return posix_error(); 2718 Py_INCREF(Py_None); 2719 return Py_None; 2720} 2721#endif 2722 2723 2724#ifdef HAVE_POPEN 2725PyDoc_STRVAR(posix_popen__doc__, 2726"popen(command [, mode='r' [, bufsize]]) -> pipe\n\n\ 2727Open a pipe to/from a command returning a file object."); 2728 2729#if defined(PYOS_OS2) 2730#if defined(PYCC_VACPP) 2731static int 2732async_system(const char *command) 2733{ 2734 char *p, errormsg[256], args[1024]; 2735 RESULTCODES rcodes; 2736 APIRET rc; 2737 char *shell = getenv("COMSPEC"); 2738 if (!shell) 2739 shell = "cmd"; 2740 2741 strcpy(args, shell); 2742 p = &args[ strlen(args)+1 ]; 2743 strcpy(p, "/c "); 2744 strcat(p, command); 2745 p += strlen(p) + 1; 2746 *p = '\0'; 2747 2748 rc = DosExecPgm(errormsg, sizeof(errormsg), 2749 EXEC_ASYNC, /* Execute Async w/o Wait for Results */ 2750 args, 2751 NULL, /* Inherit Parent's Environment */ 2752 &rcodes, shell); 2753 return rc; 2754} 2755 2756static FILE * 2757popen(const char *command, const char *mode, int pipesize, int *err) 2758{ 2759 HFILE rhan, whan; 2760 FILE *retfd = NULL; 2761 APIRET rc = DosCreatePipe(&rhan, &whan, pipesize); 2762 2763 if (rc != NO_ERROR) { 2764 *err = rc; 2765 return NULL; /* ERROR - Unable to Create Anon Pipe */ 2766 } 2767 2768 if (strchr(mode, 'r') != NULL) { /* Treat Command as a Data Source */ 2769 int oldfd = dup(1); /* Save STDOUT Handle in Another Handle */ 2770 2771 DosEnterCritSec(); /* Stop Other Threads While Changing Handles */ 2772 close(1); /* Make STDOUT Available for Reallocation */ 2773 2774 if (dup2(whan, 1) == 0) { /* Connect STDOUT to Pipe Write Side */ 2775 DosClose(whan); /* Close Now-Unused Pipe Write Handle */ 2776 2777 rc = async_system(command); 2778 } 2779 2780 dup2(oldfd, 1); /* Reconnect STDOUT to Original Handle */ 2781 DosExitCritSec(); /* Now Allow Other Threads to Run */ 2782 2783 if (rc == NO_ERROR) 2784 retfd = fdopen(rhan, mode); /* And Return Pipe Read Handle */ 2785 2786 close(oldfd); /* And Close Saved STDOUT Handle */ 2787 return retfd; /* Return fd of Pipe or NULL if Error */ 2788 2789 } else if (strchr(mode, 'w')) { /* Treat Command as a Data Sink */ 2790 int oldfd = dup(0); /* Save STDIN Handle in Another Handle */ 2791 2792 DosEnterCritSec(); /* Stop Other Threads While Changing Handles */ 2793 close(0); /* Make STDIN Available for Reallocation */ 2794 2795 if (dup2(rhan, 0) == 0) { /* Connect STDIN to Pipe Read Side */ 2796 DosClose(rhan); /* Close Now-Unused Pipe Read Handle */ 2797 2798 rc = async_system(command); 2799 } 2800 2801 dup2(oldfd, 0); /* Reconnect STDIN to Original Handle */ 2802 DosExitCritSec(); /* Now Allow Other Threads to Run */ 2803 2804 if (rc == NO_ERROR) 2805 retfd = fdopen(whan, mode); /* And Return Pipe Write Handle */ 2806 2807 close(oldfd); /* And Close Saved STDIN Handle */ 2808 return retfd; /* Return fd of Pipe or NULL if Error */ 2809 2810 } else { 2811 *err = ERROR_INVALID_ACCESS; 2812 return NULL; /* ERROR - Invalid Mode (Neither Read nor Write) */ 2813 } 2814} 2815 2816static PyObject * 2817posix_popen(PyObject *self, PyObject *args) 2818{ 2819 char *name; 2820 char *mode = "r"; 2821 int err, bufsize = -1; 2822 FILE *fp; 2823 PyObject *f; 2824 if (!PyArg_ParseTuple(args, "s|si:popen", &name, &mode, &bufsize)) 2825 return NULL; 2826 Py_BEGIN_ALLOW_THREADS 2827 fp = popen(name, mode, (bufsize > 0) ? bufsize : 4096, &err); 2828 Py_END_ALLOW_THREADS 2829 if (fp == NULL) 2830 return os2_error(err); 2831 2832 f = PyFile_FromFile(fp, name, mode, fclose); 2833 if (f != NULL) 2834 PyFile_SetBufSize(f, bufsize); 2835 return f; 2836} 2837 2838#elif defined(PYCC_GCC) 2839 2840/* standard posix version of popen() support */ 2841static PyObject * 2842posix_popen(PyObject *self, PyObject *args) 2843{ 2844 char *name; 2845 char *mode = "r"; 2846 int bufsize = -1; 2847 FILE *fp; 2848 PyObject *f; 2849 if (!PyArg_ParseTuple(args, "s|si:popen", &name, &mode, &bufsize)) 2850 return NULL; 2851 Py_BEGIN_ALLOW_THREADS 2852 fp = popen(name, mode); 2853 Py_END_ALLOW_THREADS 2854 if (fp == NULL) 2855 return posix_error(); 2856 f = PyFile_FromFile(fp, name, mode, pclose); 2857 if (f != NULL) 2858 PyFile_SetBufSize(f, bufsize); 2859 return f; 2860} 2861 2862/* fork() under OS/2 has lots'o'warts 2863 * EMX supports pipe() and spawn*() so we can synthesize popen[234]() 2864 * most of this code is a ripoff of the win32 code, but using the 2865 * capabilities of EMX's C library routines 2866 */ 2867 2868/* These tell _PyPopen() whether to return 1, 2, or 3 file objects. */ 2869#define POPEN_1 1 2870#define POPEN_2 2 2871#define POPEN_3 3 2872#define POPEN_4 4 2873 2874static PyObject *_PyPopen(char *, int, int, int); 2875static int _PyPclose(FILE *file); 2876 2877/* 2878 * Internal dictionary mapping popen* file pointers to process handles, 2879 * for use when retrieving the process exit code. See _PyPclose() below 2880 * for more information on this dictionary's use. 2881 */ 2882static PyObject *_PyPopenProcs = NULL; 2883 2884/* os2emx version of popen2() 2885 * 2886 * The result of this function is a pipe (file) connected to the 2887 * process's stdin, and a pipe connected to the process's stdout. 2888 */ 2889 2890static PyObject * 2891os2emx_popen2(PyObject *self, PyObject *args) 2892{ 2893 PyObject *f; 2894 int tm=0; 2895 2896 char *cmdstring; 2897 char *mode = "t"; 2898 int bufsize = -1; 2899 if (!PyArg_ParseTuple(args, "s|si:popen2", &cmdstring, &mode, &bufsize)) 2900 return NULL; 2901 2902 if (*mode == 't') 2903 tm = O_TEXT; 2904 else if (*mode != 'b') { 2905 PyErr_SetString(PyExc_ValueError, "mode must be 't' or 'b'"); 2906 return NULL; 2907 } else 2908 tm = O_BINARY; 2909 2910 f = _PyPopen(cmdstring, tm, POPEN_2, bufsize); 2911 2912 return f; 2913} 2914 2915/* 2916 * Variation on os2emx.popen2 2917 * 2918 * The result of this function is 3 pipes - the process's stdin, 2919 * stdout and stderr 2920 */ 2921 2922static PyObject * 2923os2emx_popen3(PyObject *self, PyObject *args) 2924{ 2925 PyObject *f; 2926 int tm = 0; 2927 2928 char *cmdstring; 2929 char *mode = "t"; 2930 int bufsize = -1; 2931 if (!PyArg_ParseTuple(args, "s|si:popen3", &cmdstring, &mode, &bufsize)) 2932 return NULL; 2933 2934 if (*mode == 't') 2935 tm = O_TEXT; 2936 else if (*mode != 'b') { 2937 PyErr_SetString(PyExc_ValueError, "mode must be 't' or 'b'"); 2938 return NULL; 2939 } else 2940 tm = O_BINARY; 2941 2942 f = _PyPopen(cmdstring, tm, POPEN_3, bufsize); 2943 2944 return f; 2945} 2946 2947/* 2948 * Variation on os2emx.popen2 2949 * 2950 * The result of this function is 2 pipes - the processes stdin, 2951 * and stdout+stderr combined as a single pipe. 2952 */ 2953 2954static PyObject * 2955os2emx_popen4(PyObject *self, PyObject *args) 2956{ 2957 PyObject *f; 2958 int tm = 0; 2959 2960 char *cmdstring; 2961 char *mode = "t"; 2962 int bufsize = -1; 2963 if (!PyArg_ParseTuple(args, "s|si:popen4", &cmdstring, &mode, &bufsize)) 2964 return NULL; 2965 2966 if (*mode == 't') 2967 tm = O_TEXT; 2968 else if (*mode != 'b') { 2969 PyErr_SetString(PyExc_ValueError, "mode must be 't' or 'b'"); 2970 return NULL; 2971 } else 2972 tm = O_BINARY; 2973 2974 f = _PyPopen(cmdstring, tm, POPEN_4, bufsize); 2975 2976 return f; 2977} 2978 2979/* a couple of structures for convenient handling of multiple 2980 * file handles and pipes 2981 */ 2982struct file_ref 2983{ 2984 int handle; 2985 int flags; 2986}; 2987 2988struct pipe_ref 2989{ 2990 int rd; 2991 int wr; 2992}; 2993 2994/* The following code is derived from the win32 code */ 2995 2996static PyObject * 2997_PyPopen(char *cmdstring, int mode, int n, int bufsize) 2998{ 2999 struct file_ref stdio[3]; 3000 struct pipe_ref p_fd[3]; 3001 FILE *p_s[3]; 3002 int file_count, i, pipe_err, pipe_pid; 3003 char *shell, *sh_name, *opt, *rd_mode, *wr_mode; 3004 PyObject *f, *p_f[3]; 3005 3006 /* file modes for subsequent fdopen's on pipe handles */ 3007 if (mode == O_TEXT) 3008 { 3009 rd_mode = "rt"; 3010 wr_mode = "wt"; 3011 } 3012 else 3013 { 3014 rd_mode = "rb"; 3015 wr_mode = "wb"; 3016 } 3017 3018 /* prepare shell references */ 3019 if ((shell = getenv("EMXSHELL")) == NULL) 3020 if ((shell = getenv("COMSPEC")) == NULL) 3021 { 3022 errno = ENOENT; 3023 return posix_error(); 3024 } 3025 3026 sh_name = _getname(shell); 3027 if (stricmp(sh_name, "cmd.exe") == 0 || stricmp(sh_name, "4os2.exe") == 0) 3028 opt = "/c"; 3029 else 3030 opt = "-c"; 3031 3032 /* save current stdio fds + their flags, and set not inheritable */ 3033 i = pipe_err = 0; 3034 while (pipe_err >= 0 && i < 3) 3035 { 3036 pipe_err = stdio[i].handle = dup(i); 3037 stdio[i].flags = fcntl(i, F_GETFD, 0); 3038 fcntl(stdio[i].handle, F_SETFD, stdio[i].flags | FD_CLOEXEC); 3039 i++; 3040 } 3041 if (pipe_err < 0) 3042 { 3043 /* didn't get them all saved - clean up and bail out */ 3044 int saved_err = errno; 3045 while (i-- > 0) 3046 { 3047 close(stdio[i].handle); 3048 } 3049 errno = saved_err; 3050 return posix_error(); 3051 } 3052 3053 /* create pipe ends */ 3054 file_count = 2; 3055 if (n == POPEN_3) 3056 file_count = 3; 3057 i = pipe_err = 0; 3058 while ((pipe_err == 0) && (i < file_count)) 3059 pipe_err = pipe((int *)&p_fd[i++]); 3060 if (pipe_err < 0) 3061 { 3062 /* didn't get them all made - clean up and bail out */ 3063 while (i-- > 0) 3064 { 3065 close(p_fd[i].wr); 3066 close(p_fd[i].rd); 3067 } 3068 errno = EPIPE; 3069 return posix_error(); 3070 } 3071 3072 /* change the actual standard IO streams over temporarily, 3073 * making the retained pipe ends non-inheritable 3074 */ 3075 pipe_err = 0; 3076 3077 /* - stdin */ 3078 if (dup2(p_fd[0].rd, 0) == 0) 3079 { 3080 close(p_fd[0].rd); 3081 i = fcntl(p_fd[0].wr, F_GETFD, 0); 3082 fcntl(p_fd[0].wr, F_SETFD, i | FD_CLOEXEC); 3083 if ((p_s[0] = fdopen(p_fd[0].wr, wr_mode)) == NULL) 3084 { 3085 close(p_fd[0].wr); 3086 pipe_err = -1; 3087 } 3088 } 3089 else 3090 { 3091 pipe_err = -1; 3092 } 3093 3094 /* - stdout */ 3095 if (pipe_err == 0) 3096 { 3097 if (dup2(p_fd[1].wr, 1) == 1) 3098 { 3099 close(p_fd[1].wr); 3100 i = fcntl(p_fd[1].rd, F_GETFD, 0); 3101 fcntl(p_fd[1].rd, F_SETFD, i | FD_CLOEXEC); 3102 if ((p_s[1] = fdopen(p_fd[1].rd, rd_mode)) == NULL) 3103 { 3104 close(p_fd[1].rd); 3105 pipe_err = -1; 3106 } 3107 } 3108 else 3109 { 3110 pipe_err = -1; 3111 } 3112 } 3113 3114 /* - stderr, as required */ 3115 if (pipe_err == 0) 3116 switch (n) 3117 { 3118 case POPEN_3: 3119 { 3120 if (dup2(p_fd[2].wr, 2) == 2) 3121 { 3122 close(p_fd[2].wr); 3123 i = fcntl(p_fd[2].rd, F_GETFD, 0); 3124 fcntl(p_fd[2].rd, F_SETFD, i | FD_CLOEXEC); 3125 if ((p_s[2] = fdopen(p_fd[2].rd, rd_mode)) == NULL) 3126 { 3127 close(p_fd[2].rd); 3128 pipe_err = -1; 3129 } 3130 } 3131 else 3132 { 3133 pipe_err = -1; 3134 } 3135 break; 3136 } 3137 3138 case POPEN_4: 3139 { 3140 if (dup2(1, 2) != 2) 3141 { 3142 pipe_err = -1; 3143 } 3144 break; 3145 } 3146 } 3147 3148 /* spawn the child process */ 3149 if (pipe_err == 0) 3150 { 3151 pipe_pid = spawnlp(P_NOWAIT, shell, shell, opt, cmdstring, (char *)0); 3152 if (pipe_pid == -1) 3153 { 3154 pipe_err = -1; 3155 } 3156 else 3157 { 3158 /* save the PID into the FILE structure 3159 * NOTE: this implementation doesn't actually 3160 * take advantage of this, but do it for 3161 * completeness - AIM Apr01 3162 */ 3163 for (i = 0; i < file_count; i++) 3164 p_s[i]->_pid = pipe_pid; 3165 } 3166 } 3167 3168 /* reset standard IO to normal */ 3169 for (i = 0; i < 3; i++) 3170 { 3171 dup2(stdio[i].handle, i); 3172 fcntl(i, F_SETFD, stdio[i].flags); 3173 close(stdio[i].handle); 3174 } 3175 3176 /* if any remnant problems, clean up and bail out */ 3177 if (pipe_err < 0) 3178 { 3179 for (i = 0; i < 3; i++) 3180 { 3181 close(p_fd[i].rd); 3182 close(p_fd[i].wr); 3183 } 3184 errno = EPIPE; 3185 return posix_error_with_filename(cmdstring); 3186 } 3187 3188 /* build tuple of file objects to return */ 3189 if ((p_f[0] = PyFile_FromFile(p_s[0], cmdstring, wr_mode, _PyPclose)) != NULL) 3190 PyFile_SetBufSize(p_f[0], bufsize); 3191 if ((p_f[1] = PyFile_FromFile(p_s[1], cmdstring, rd_mode, _PyPclose)) != NULL) 3192 PyFile_SetBufSize(p_f[1], bufsize); 3193 if (n == POPEN_3) 3194 { 3195 if ((p_f[2] = PyFile_FromFile(p_s[2], cmdstring, rd_mode, _PyPclose)) != NULL) 3196 PyFile_SetBufSize(p_f[0], bufsize); 3197 f = Py_BuildValue("OOO", p_f[0], p_f[1], p_f[2]); 3198 } 3199 else 3200 f = Py_BuildValue("OO", p_f[0], p_f[1]); 3201 3202 /* 3203 * Insert the files we've created into the process dictionary 3204 * all referencing the list with the process handle and the 3205 * initial number of files (see description below in _PyPclose). 3206 * Since if _PyPclose later tried to wait on a process when all 3207 * handles weren't closed, it could create a deadlock with the 3208 * child, we spend some energy here to try to ensure that we 3209 * either insert all file handles into the dictionary or none 3210 * at all. It's a little clumsy with the various popen modes 3211 * and variable number of files involved. 3212 */ 3213 if (!_PyPopenProcs) 3214 { 3215 _PyPopenProcs = PyDict_New(); 3216 } 3217 3218 if (_PyPopenProcs) 3219 { 3220 PyObject *procObj, *pidObj, *intObj, *fileObj[3]; 3221 int ins_rc[3]; 3222 3223 fileObj[0] = fileObj[1] = fileObj[2] = NULL; 3224 ins_rc[0] = ins_rc[1] = ins_rc[2] = 0; 3225 3226 procObj = PyList_New(2); 3227 pidObj = PyInt_FromLong((long) pipe_pid); 3228 intObj = PyInt_FromLong((long) file_count); 3229 3230 if (procObj && pidObj && intObj) 3231 { 3232 PyList_SetItem(procObj, 0, pidObj); 3233 PyList_SetItem(procObj, 1, intObj); 3234 3235 fileObj[0] = PyLong_FromVoidPtr(p_s[0]); 3236 if (fileObj[0]) 3237 { 3238 ins_rc[0] = PyDict_SetItem(_PyPopenProcs, 3239 fileObj[0], 3240 procObj); 3241 } 3242 fileObj[1] = PyLong_FromVoidPtr(p_s[1]); 3243 if (fileObj[1]) 3244 { 3245 ins_rc[1] = PyDict_SetItem(_PyPopenProcs, 3246 fileObj[1], 3247 procObj); 3248 } 3249 if (file_count >= 3) 3250 { 3251 fileObj[2] = PyLong_FromVoidPtr(p_s[2]); 3252 if (fileObj[2]) 3253 { 3254 ins_rc[2] = PyDict_SetItem(_PyPopenProcs, 3255 fileObj[2], 3256 procObj); 3257 } 3258 } 3259 3260 if (ins_rc[0] < 0 || !fileObj[0] || 3261 ins_rc[1] < 0 || (file_count > 1 && !fileObj[1]) || 3262 ins_rc[2] < 0 || (file_count > 2 && !fileObj[2])) 3263 { 3264 /* Something failed - remove any dictionary 3265 * entries that did make it. 3266 */ 3267 if (!ins_rc[0] && fileObj[0]) 3268 { 3269 PyDict_DelItem(_PyPopenProcs, 3270 fileObj[0]); 3271 } 3272 if (!ins_rc[1] && fileObj[1]) 3273 { 3274 PyDict_DelItem(_PyPopenProcs, 3275 fileObj[1]); 3276 } 3277 if (!ins_rc[2] && fileObj[2]) 3278 { 3279 PyDict_DelItem(_PyPopenProcs, 3280 fileObj[2]); 3281 } 3282 } 3283 } 3284 3285 /* 3286 * Clean up our localized references for the dictionary keys 3287 * and value since PyDict_SetItem will Py_INCREF any copies 3288 * that got placed in the dictionary. 3289 */ 3290 Py_XDECREF(procObj); 3291 Py_XDECREF(fileObj[0]); 3292 Py_XDECREF(fileObj[1]); 3293 Py_XDECREF(fileObj[2]); 3294 } 3295 3296 /* Child is launched. */ 3297 return f; 3298} 3299 3300/* 3301 * Wrapper for fclose() to use for popen* files, so we can retrieve the 3302 * exit code for the child process and return as a result of the close. 3303 * 3304 * This function uses the _PyPopenProcs dictionary in order to map the 3305 * input file pointer to information about the process that was 3306 * originally created by the popen* call that created the file pointer. 3307 * The dictionary uses the file pointer as a key (with one entry 3308 * inserted for each file returned by the original popen* call) and a 3309 * single list object as the value for all files from a single call. 3310 * The list object contains the Win32 process handle at [0], and a file 3311 * count at [1], which is initialized to the total number of file 3312 * handles using that list. 3313 * 3314 * This function closes whichever handle it is passed, and decrements 3315 * the file count in the dictionary for the process handle pointed to 3316 * by this file. On the last close (when the file count reaches zero), 3317 * this function will wait for the child process and then return its 3318 * exit code as the result of the close() operation. This permits the 3319 * files to be closed in any order - it is always the close() of the 3320 * final handle that will return the exit code. 3321 */ 3322 3323 /* RED_FLAG 31-Aug-2000 Tim 3324 * This is always called (today!) between a pair of 3325 * Py_BEGIN_ALLOW_THREADS/ Py_END_ALLOW_THREADS 3326 * macros. So the thread running this has no valid thread state, as 3327 * far as Python is concerned. However, this calls some Python API 3328 * functions that cannot be called safely without a valid thread 3329 * state, in particular PyDict_GetItem. 3330 * As a temporary hack (although it may last for years ...), we 3331 * *rely* on not having a valid thread state in this function, in 3332 * order to create our own "from scratch". 3333 * This will deadlock if _PyPclose is ever called by a thread 3334 * holding the global lock. 3335 * (The OS/2 EMX thread support appears to cover the case where the 3336 * lock is already held - AIM Apr01) 3337 */ 3338 3339static int _PyPclose(FILE *file) 3340{ 3341 int result; 3342 int exit_code; 3343 int pipe_pid; 3344 PyObject *procObj, *pidObj, *intObj, *fileObj; 3345 int file_count; 3346#ifdef WITH_THREAD 3347 PyInterpreterState* pInterpreterState; 3348 PyThreadState* pThreadState; 3349#endif 3350 3351 /* Close the file handle first, to ensure it can't block the 3352 * child from exiting if it's the last handle. 3353 */ 3354 result = fclose(file); 3355 3356#ifdef WITH_THREAD 3357 /* Bootstrap a valid thread state into existence. */ 3358 pInterpreterState = PyInterpreterState_New(); 3359 if (!pInterpreterState) { 3360 /* Well, we're hosed now! We don't have a thread 3361 * state, so can't call a nice error routine, or raise 3362 * an exception. Just die. 3363 */ 3364 Py_FatalError("unable to allocate interpreter state " 3365 "when closing popen object."); 3366 return -1; /* unreachable */ 3367 } 3368 pThreadState = PyThreadState_New(pInterpreterState); 3369 if (!pThreadState) { 3370 Py_FatalError("unable to allocate thread state " 3371 "when closing popen object."); 3372 return -1; /* unreachable */ 3373 } 3374 /* Grab the global lock. Note that this will deadlock if the 3375 * current thread already has the lock! (see RED_FLAG comments 3376 * before this function) 3377 */ 3378 PyEval_RestoreThread(pThreadState); 3379#endif 3380 3381 if (_PyPopenProcs) 3382 { 3383 if ((fileObj = PyLong_FromVoidPtr(file)) != NULL && 3384 (procObj = PyDict_GetItem(_PyPopenProcs, 3385 fileObj)) != NULL && 3386 (pidObj = PyList_GetItem(procObj,0)) != NULL && 3387 (intObj = PyList_GetItem(procObj,1)) != NULL) 3388 { 3389 pipe_pid = (int) PyInt_AsLong(pidObj); 3390 file_count = (int) PyInt_AsLong(intObj); 3391 3392 if (file_count > 1) 3393 { 3394 /* Still other files referencing process */ 3395 file_count--; 3396 PyList_SetItem(procObj,1, 3397 PyInt_FromLong((long) file_count)); 3398 } 3399 else 3400 { 3401 /* Last file for this process */ 3402 if (result != EOF && 3403 waitpid(pipe_pid, &exit_code, 0) == pipe_pid) 3404 { 3405 /* extract exit status */ 3406 if (WIFEXITED(exit_code)) 3407 { 3408 result = WEXITSTATUS(exit_code); 3409 } 3410 else 3411 { 3412 errno = EPIPE; 3413 result = -1; 3414 } 3415 } 3416 else 3417 { 3418 /* Indicate failure - this will cause the file object 3419 * to raise an I/O error and translate the last 3420 * error code from errno. We do have a problem with 3421 * last errors that overlap the normal errno table, 3422 * but that's a consistent problem with the file object. 3423 */ 3424 result = -1; 3425 } 3426 } 3427 3428 /* Remove this file pointer from dictionary */ 3429 PyDict_DelItem(_PyPopenProcs, fileObj); 3430 3431 if (PyDict_Size(_PyPopenProcs) == 0) 3432 { 3433 Py_DECREF(_PyPopenProcs); 3434 _PyPopenProcs = NULL; 3435 } 3436 3437 } /* if object retrieval ok */ 3438 3439 Py_XDECREF(fileObj); 3440 } /* if _PyPopenProcs */ 3441 3442#ifdef WITH_THREAD 3443 /* Tear down the thread & interpreter states. 3444 * Note that interpreter state clear & delete functions automatically 3445 * call the thread clear & delete functions, and indeed insist on 3446 * doing that themselves. The lock must be held during the clear, but 3447 * need not be held during the delete. 3448 */ 3449 PyInterpreterState_Clear(pInterpreterState); 3450 PyEval_ReleaseThread(pThreadState); 3451 PyInterpreterState_Delete(pInterpreterState); 3452#endif 3453 3454 return result; 3455} 3456 3457#endif /* PYCC_??? */ 3458 3459#elif defined(MS_WINDOWS) 3460 3461/* 3462 * Portable 'popen' replacement for Win32. 3463 * 3464 * Written by Bill Tutt <billtut@microsoft.com>. Minor tweaks 3465 * and 2.0 integration by Fredrik Lundh <fredrik@pythonware.com> 3466 * Return code handling by David Bolen <db3l@fitlinxx.com>. 3467 */ 3468 3469#include <malloc.h> 3470#include <io.h> 3471#include <fcntl.h> 3472 3473/* These tell _PyPopen() wether to return 1, 2, or 3 file objects. */ 3474#define POPEN_1 1 3475#define POPEN_2 2 3476#define POPEN_3 3 3477#define POPEN_4 4 3478 3479static PyObject *_PyPopen(char *, int, int); 3480static int _PyPclose(FILE *file); 3481 3482/* 3483 * Internal dictionary mapping popen* file pointers to process handles, 3484 * for use when retrieving the process exit code. See _PyPclose() below 3485 * for more information on this dictionary's use. 3486 */ 3487static PyObject *_PyPopenProcs = NULL; 3488 3489 3490/* popen that works from a GUI. 3491 * 3492 * The result of this function is a pipe (file) connected to the 3493 * processes stdin or stdout, depending on the requested mode. 3494 */ 3495 3496static PyObject * 3497posix_popen(PyObject *self, PyObject *args) 3498{ 3499 PyObject *f, *s; 3500 int tm = 0; 3501 3502 char *cmdstring; 3503 char *mode = "r"; 3504 int bufsize = -1; 3505 if (!PyArg_ParseTuple(args, "s|si:popen", &cmdstring, &mode, &bufsize)) 3506 return NULL; 3507 3508 s = PyTuple_New(0); 3509 3510 if (*mode == 'r') 3511 tm = _O_RDONLY; 3512 else if (*mode != 'w') { 3513 PyErr_SetString(PyExc_ValueError, "popen() arg 2 must be 'r' or 'w'"); 3514 return NULL; 3515 } else 3516 tm = _O_WRONLY; 3517 3518 if (bufsize != -1) { 3519 PyErr_SetString(PyExc_ValueError, "popen() arg 3 must be -1"); 3520 return NULL; 3521 } 3522 3523 if (*(mode+1) == 't') 3524 f = _PyPopen(cmdstring, tm | _O_TEXT, POPEN_1); 3525 else if (*(mode+1) == 'b') 3526 f = _PyPopen(cmdstring, tm | _O_BINARY, POPEN_1); 3527 else 3528 f = _PyPopen(cmdstring, tm | _O_TEXT, POPEN_1); 3529 3530 return f; 3531} 3532 3533/* Variation on win32pipe.popen 3534 * 3535 * The result of this function is a pipe (file) connected to the 3536 * process's stdin, and a pipe connected to the process's stdout. 3537 */ 3538 3539static PyObject * 3540win32_popen2(PyObject *self, PyObject *args) 3541{ 3542 PyObject *f; 3543 int tm=0; 3544 3545 char *cmdstring; 3546 char *mode = "t"; 3547 int bufsize = -1; 3548 if (!PyArg_ParseTuple(args, "s|si:popen2", &cmdstring, &mode, &bufsize)) 3549 return NULL; 3550 3551 if (*mode == 't') 3552 tm = _O_TEXT; 3553 else if (*mode != 'b') { 3554 PyErr_SetString(PyExc_ValueError, "popen2() arg 2 must be 't' or 'b'"); 3555 return NULL; 3556 } else 3557 tm = _O_BINARY; 3558 3559 if (bufsize != -1) { 3560 PyErr_SetString(PyExc_ValueError, "popen2() arg 3 must be -1"); 3561 return NULL; 3562 } 3563 3564 f = _PyPopen(cmdstring, tm, POPEN_2); 3565 3566 return f; 3567} 3568 3569/* 3570 * Variation on <om win32pipe.popen> 3571 * 3572 * The result of this function is 3 pipes - the process's stdin, 3573 * stdout and stderr 3574 */ 3575 3576static PyObject * 3577win32_popen3(PyObject *self, PyObject *args) 3578{ 3579 PyObject *f; 3580 int tm = 0; 3581 3582 char *cmdstring; 3583 char *mode = "t"; 3584 int bufsize = -1; 3585 if (!PyArg_ParseTuple(args, "s|si:popen3", &cmdstring, &mode, &bufsize)) 3586 return NULL; 3587 3588 if (*mode == 't') 3589 tm = _O_TEXT; 3590 else if (*mode != 'b') { 3591 PyErr_SetString(PyExc_ValueError, "popen3() arg 2 must be 't' or 'b'"); 3592 return NULL; 3593 } else 3594 tm = _O_BINARY; 3595 3596 if (bufsize != -1) { 3597 PyErr_SetString(PyExc_ValueError, "popen3() arg 3 must be -1"); 3598 return NULL; 3599 } 3600 3601 f = _PyPopen(cmdstring, tm, POPEN_3); 3602 3603 return f; 3604} 3605 3606/* 3607 * Variation on win32pipe.popen 3608 * 3609 * The result of this function is 2 pipes - the processes stdin, 3610 * and stdout+stderr combined as a single pipe. 3611 */ 3612 3613static PyObject * 3614win32_popen4(PyObject *self, PyObject *args) 3615{ 3616 PyObject *f; 3617 int tm = 0; 3618 3619 char *cmdstring; 3620 char *mode = "t"; 3621 int bufsize = -1; 3622 if (!PyArg_ParseTuple(args, "s|si:popen4", &cmdstring, &mode, &bufsize)) 3623 return NULL; 3624 3625 if (*mode == 't') 3626 tm = _O_TEXT; 3627 else if (*mode != 'b') { 3628 PyErr_SetString(PyExc_ValueError, "popen4() arg 2 must be 't' or 'b'"); 3629 return NULL; 3630 } else 3631 tm = _O_BINARY; 3632 3633 if (bufsize != -1) { 3634 PyErr_SetString(PyExc_ValueError, "popen4() arg 3 must be -1"); 3635 return NULL; 3636 } 3637 3638 f = _PyPopen(cmdstring, tm, POPEN_4); 3639 3640 return f; 3641} 3642 3643static BOOL 3644_PyPopenCreateProcess(char *cmdstring, 3645 HANDLE hStdin, 3646 HANDLE hStdout, 3647 HANDLE hStderr, 3648 HANDLE *hProcess) 3649{ 3650 PROCESS_INFORMATION piProcInfo; 3651 STARTUPINFO siStartInfo; 3652 DWORD dwProcessFlags = 0; /* no NEW_CONSOLE by default for Ctrl+C handling */ 3653 char *s1,*s2, *s3 = " /c "; 3654 const char *szConsoleSpawn = "w9xpopen.exe"; 3655 int i; 3656 int x; 3657 3658 if (i = GetEnvironmentVariable("COMSPEC",NULL,0)) { 3659 char *comshell; 3660 3661 s1 = (char *)alloca(i); 3662 if (!(x = GetEnvironmentVariable("COMSPEC", s1, i))) 3663 return x; 3664 3665 /* Explicitly check if we are using COMMAND.COM. If we are 3666 * then use the w9xpopen hack. 3667 */ 3668 comshell = s1 + x; 3669 while (comshell >= s1 && *comshell != '\\') 3670 --comshell; 3671 ++comshell; 3672 3673 if (GetVersion() < 0x80000000 && 3674 _stricmp(comshell, "command.com") != 0) { 3675 /* NT/2000 and not using command.com. */ 3676 x = i + strlen(s3) + strlen(cmdstring) + 1; 3677 s2 = (char *)alloca(x); 3678 ZeroMemory(s2, x); 3679 PyOS_snprintf(s2, x, "%s%s%s", s1, s3, cmdstring); 3680 } 3681 else { 3682 /* 3683 * Oh gag, we're on Win9x or using COMMAND.COM. Use 3684 * the workaround listed in KB: Q150956 3685 */ 3686 char modulepath[_MAX_PATH]; 3687 struct stat statinfo; 3688 GetModuleFileName(NULL, modulepath, sizeof(modulepath)); 3689 for (i = x = 0; modulepath[i]; i++) 3690 if (modulepath[i] == SEP) 3691 x = i+1; 3692 modulepath[x] = '\0'; 3693 /* Create the full-name to w9xpopen, so we can test it exists */ 3694 strncat(modulepath, 3695 szConsoleSpawn, 3696 (sizeof(modulepath)/sizeof(modulepath[0])) 3697 -strlen(modulepath)); 3698 if (stat(modulepath, &statinfo) != 0) { 3699 /* Eeek - file-not-found - possibly an embedding 3700 situation - see if we can locate it in sys.prefix 3701 */ 3702 strncpy(modulepath, 3703 Py_GetExecPrefix(), 3704 sizeof(modulepath)/sizeof(modulepath[0])); 3705 if (modulepath[strlen(modulepath)-1] != '\\') 3706 strcat(modulepath, "\\"); 3707 strncat(modulepath, 3708 szConsoleSpawn, 3709 (sizeof(modulepath)/sizeof(modulepath[0])) 3710 -strlen(modulepath)); 3711 /* No where else to look - raise an easily identifiable 3712 error, rather than leaving Windows to report 3713 "file not found" - as the user is probably blissfully 3714 unaware this shim EXE is used, and it will confuse them. 3715 (well, it confused me for a while ;-) 3716 */ 3717 if (stat(modulepath, &statinfo) != 0) { 3718 PyErr_Format(PyExc_RuntimeError, 3719 "Can not locate '%s' which is needed " 3720 "for popen to work with your shell " 3721 "or platform.", 3722 szConsoleSpawn); 3723 return FALSE; 3724 } 3725 } 3726 x = i + strlen(s3) + strlen(cmdstring) + 1 + 3727 strlen(modulepath) + 3728 strlen(szConsoleSpawn) + 1; 3729 3730 s2 = (char *)alloca(x); 3731 ZeroMemory(s2, x); 3732 /* To maintain correct argument passing semantics, 3733 we pass the command-line as it stands, and allow 3734 quoting to be applied. w9xpopen.exe will then 3735 use its argv vector, and re-quote the necessary 3736 args for the ultimate child process. 3737 */ 3738 PyOS_snprintf( 3739 s2, x, 3740 "\"%s\" %s%s%s", 3741 modulepath, 3742 s1, 3743 s3, 3744 cmdstring); 3745 /* Not passing CREATE_NEW_CONSOLE has been known to 3746 cause random failures on win9x. Specifically a 3747 dialog: 3748 "Your program accessed mem currently in use at xxx" 3749 and a hopeful warning about the stability of your 3750 system. 3751 Cost is Ctrl+C wont kill children, but anyone 3752 who cares can have a go! 3753 */ 3754 dwProcessFlags |= CREATE_NEW_CONSOLE; 3755 } 3756 } 3757 3758 /* Could be an else here to try cmd.exe / command.com in the path 3759 Now we'll just error out.. */ 3760 else { 3761 PyErr_SetString(PyExc_RuntimeError, 3762 "Cannot locate a COMSPEC environment variable to " 3763 "use as the shell"); 3764 return FALSE; 3765 } 3766 3767 ZeroMemory(&siStartInfo, sizeof(STARTUPINFO)); 3768 siStartInfo.cb = sizeof(STARTUPINFO); 3769 siStartInfo.dwFlags = STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW; 3770 siStartInfo.hStdInput = hStdin; 3771 siStartInfo.hStdOutput = hStdout; 3772 siStartInfo.hStdError = hStderr; 3773 siStartInfo.wShowWindow = SW_HIDE; 3774 3775 if (CreateProcess(NULL, 3776 s2, 3777 NULL, 3778 NULL, 3779 TRUE, 3780 dwProcessFlags, 3781 NULL, 3782 NULL, 3783 &siStartInfo, 3784 &piProcInfo) ) { 3785 /* Close the handles now so anyone waiting is woken. */ 3786 CloseHandle(piProcInfo.hThread); 3787 3788 /* Return process handle */ 3789 *hProcess = piProcInfo.hProcess; 3790 return TRUE; 3791 } 3792 win32_error("CreateProcess", s2); 3793 return FALSE; 3794} 3795 3796/* The following code is based off of KB: Q190351 */ 3797 3798static PyObject * 3799_PyPopen(char *cmdstring, int mode, int n) 3800{ 3801 HANDLE hChildStdinRd, hChildStdinWr, hChildStdoutRd, hChildStdoutWr, 3802 hChildStderrRd, hChildStderrWr, hChildStdinWrDup, hChildStdoutRdDup, 3803 hChildStderrRdDup, hProcess; /* hChildStdoutWrDup; */ 3804 3805 SECURITY_ATTRIBUTES saAttr; 3806 BOOL fSuccess; 3807 int fd1, fd2, fd3; 3808 FILE *f1, *f2, *f3; 3809 long file_count; 3810 PyObject *f; 3811 3812 saAttr.nLength = sizeof(SECURITY_ATTRIBUTES); 3813 saAttr.bInheritHandle = TRUE; 3814 saAttr.lpSecurityDescriptor = NULL; 3815 3816 if (!CreatePipe(&hChildStdinRd, &hChildStdinWr, &saAttr, 0)) 3817 return win32_error("CreatePipe", NULL); 3818 3819 /* Create new output read handle and the input write handle. Set 3820 * the inheritance properties to FALSE. Otherwise, the child inherits 3821 * the these handles; resulting in non-closeable handles to the pipes 3822 * being created. */ 3823 fSuccess = DuplicateHandle(GetCurrentProcess(), hChildStdinWr, 3824 GetCurrentProcess(), &hChildStdinWrDup, 0, 3825 FALSE, 3826 DUPLICATE_SAME_ACCESS); 3827 if (!fSuccess) 3828 return win32_error("DuplicateHandle", NULL); 3829 3830 /* Close the inheritable version of ChildStdin 3831 that we're using. */ 3832 CloseHandle(hChildStdinWr); 3833 3834 if (!CreatePipe(&hChildStdoutRd, &hChildStdoutWr, &saAttr, 0)) 3835 return win32_error("CreatePipe", NULL); 3836 3837 fSuccess = DuplicateHandle(GetCurrentProcess(), hChildStdoutRd, 3838 GetCurrentProcess(), &hChildStdoutRdDup, 0, 3839 FALSE, DUPLICATE_SAME_ACCESS); 3840 if (!fSuccess) 3841 return win32_error("DuplicateHandle", NULL); 3842 3843 /* Close the inheritable version of ChildStdout 3844 that we're using. */ 3845 CloseHandle(hChildStdoutRd); 3846 3847 if (n != POPEN_4) { 3848 if (!CreatePipe(&hChildStderrRd, &hChildStderrWr, &saAttr, 0)) 3849 return win32_error("CreatePipe", NULL); 3850 fSuccess = DuplicateHandle(GetCurrentProcess(), 3851 hChildStderrRd, 3852 GetCurrentProcess(), 3853 &hChildStderrRdDup, 0, 3854 FALSE, DUPLICATE_SAME_ACCESS); 3855 if (!fSuccess) 3856 return win32_error("DuplicateHandle", NULL); 3857 /* Close the inheritable version of ChildStdErr that we're using. */ 3858 CloseHandle(hChildStderrRd); 3859 } 3860 3861 switch (n) { 3862 case POPEN_1: 3863 switch (mode & (_O_RDONLY | _O_TEXT | _O_BINARY | _O_WRONLY)) { 3864 case _O_WRONLY | _O_TEXT: 3865 /* Case for writing to child Stdin in text mode. */ 3866 fd1 = _open_osfhandle((long)hChildStdinWrDup, mode); 3867 f1 = _fdopen(fd1, "w"); 3868 f = PyFile_FromFile(f1, cmdstring, "w", _PyPclose); 3869 PyFile_SetBufSize(f, 0); 3870 /* We don't care about these pipes anymore, so close them. */ 3871 CloseHandle(hChildStdoutRdDup); 3872 CloseHandle(hChildStderrRdDup); 3873 break; 3874 3875 case _O_RDONLY | _O_TEXT: 3876 /* Case for reading from child Stdout in text mode. */ 3877 fd1 = _open_osfhandle((long)hChildStdoutRdDup, mode); 3878 f1 = _fdopen(fd1, "r"); 3879 f = PyFile_FromFile(f1, cmdstring, "r", _PyPclose); 3880 PyFile_SetBufSize(f, 0); 3881 /* We don't care about these pipes anymore, so close them. */ 3882 CloseHandle(hChildStdinWrDup); 3883 CloseHandle(hChildStderrRdDup); 3884 break; 3885 3886 case _O_RDONLY | _O_BINARY: 3887 /* Case for readinig from child Stdout in binary mode. */ 3888 fd1 = _open_osfhandle((long)hChildStdoutRdDup, mode); 3889 f1 = _fdopen(fd1, "rb"); 3890 f = PyFile_FromFile(f1, cmdstring, "rb", _PyPclose); 3891 PyFile_SetBufSize(f, 0); 3892 /* We don't care about these pipes anymore, so close them. */ 3893 CloseHandle(hChildStdinWrDup); 3894 CloseHandle(hChildStderrRdDup); 3895 break; 3896 3897 case _O_WRONLY | _O_BINARY: 3898 /* Case for writing to child Stdin in binary mode. */ 3899 fd1 = _open_osfhandle((long)hChildStdinWrDup, mode); 3900 f1 = _fdopen(fd1, "wb"); 3901 f = PyFile_FromFile(f1, cmdstring, "wb", _PyPclose); 3902 PyFile_SetBufSize(f, 0); 3903 /* We don't care about these pipes anymore, so close them. */ 3904 CloseHandle(hChildStdoutRdDup); 3905 CloseHandle(hChildStderrRdDup); 3906 break; 3907 } 3908 file_count = 1; 3909 break; 3910 3911 case POPEN_2: 3912 case POPEN_4: 3913 { 3914 char *m1, *m2; 3915 PyObject *p1, *p2; 3916 3917 if (mode & _O_TEXT) { 3918 m1 = "r"; 3919 m2 = "w"; 3920 } else { 3921 m1 = "rb"; 3922 m2 = "wb"; 3923 } 3924 3925 fd1 = _open_osfhandle((long)hChildStdinWrDup, mode); 3926 f1 = _fdopen(fd1, m2); 3927 fd2 = _open_osfhandle((long)hChildStdoutRdDup, mode); 3928 f2 = _fdopen(fd2, m1); 3929 p1 = PyFile_FromFile(f1, cmdstring, m2, _PyPclose); 3930 PyFile_SetBufSize(p1, 0); 3931 p2 = PyFile_FromFile(f2, cmdstring, m1, _PyPclose); 3932 PyFile_SetBufSize(p2, 0); 3933 3934 if (n != 4) 3935 CloseHandle(hChildStderrRdDup); 3936 3937 f = Py_BuildValue("OO",p1,p2); 3938 Py_XDECREF(p1); 3939 Py_XDECREF(p2); 3940 file_count = 2; 3941 break; 3942 } 3943 3944 case POPEN_3: 3945 { 3946 char *m1, *m2; 3947 PyObject *p1, *p2, *p3; 3948 3949 if (mode & _O_TEXT) { 3950 m1 = "r"; 3951 m2 = "w"; 3952 } else { 3953 m1 = "rb"; 3954 m2 = "wb"; 3955 } 3956 3957 fd1 = _open_osfhandle((long)hChildStdinWrDup, mode); 3958 f1 = _fdopen(fd1, m2); 3959 fd2 = _open_osfhandle((long)hChildStdoutRdDup, mode); 3960 f2 = _fdopen(fd2, m1); 3961 fd3 = _open_osfhandle((long)hChildStderrRdDup, mode); 3962 f3 = _fdopen(fd3, m1); 3963 p1 = PyFile_FromFile(f1, cmdstring, m2, _PyPclose); 3964 p2 = PyFile_FromFile(f2, cmdstring, m1, _PyPclose); 3965 p3 = PyFile_FromFile(f3, cmdstring, m1, _PyPclose); 3966 PyFile_SetBufSize(p1, 0); 3967 PyFile_SetBufSize(p2, 0); 3968 PyFile_SetBufSize(p3, 0); 3969 f = Py_BuildValue("OOO",p1,p2,p3); 3970 Py_XDECREF(p1); 3971 Py_XDECREF(p2); 3972 Py_XDECREF(p3); 3973 file_count = 3; 3974 break; 3975 } 3976 } 3977 3978 if (n == POPEN_4) { 3979 if (!_PyPopenCreateProcess(cmdstring, 3980 hChildStdinRd, 3981 hChildStdoutWr, 3982 hChildStdoutWr, 3983 &hProcess)) 3984 return NULL; 3985 } 3986 else { 3987 if (!_PyPopenCreateProcess(cmdstring, 3988 hChildStdinRd, 3989 hChildStdoutWr, 3990 hChildStderrWr, 3991 &hProcess)) 3992 return NULL; 3993 } 3994 3995 /* 3996 * Insert the files we've created into the process dictionary 3997 * all referencing the list with the process handle and the 3998 * initial number of files (see description below in _PyPclose). 3999 * Since if _PyPclose later tried to wait on a process when all 4000 * handles weren't closed, it could create a deadlock with the 4001 * child, we spend some energy here to try to ensure that we 4002 * either insert all file handles into the dictionary or none 4003 * at all. It's a little clumsy with the various popen modes 4004 * and variable number of files involved. 4005 */ 4006 if (!_PyPopenProcs) { 4007 _PyPopenProcs = PyDict_New(); 4008 } 4009 4010 if (_PyPopenProcs) { 4011 PyObject *procObj, *hProcessObj, *intObj, *fileObj[3]; 4012 int ins_rc[3]; 4013 4014 fileObj[0] = fileObj[1] = fileObj[2] = NULL; 4015 ins_rc[0] = ins_rc[1] = ins_rc[2] = 0; 4016 4017 procObj = PyList_New(2); 4018 hProcessObj = PyLong_FromVoidPtr(hProcess); 4019 intObj = PyInt_FromLong(file_count); 4020 4021 if (procObj && hProcessObj && intObj) { 4022 PyList_SetItem(procObj,0,hProcessObj); 4023 PyList_SetItem(procObj,1,intObj); 4024 4025 fileObj[0] = PyLong_FromVoidPtr(f1); 4026 if (fileObj[0]) { 4027 ins_rc[0] = PyDict_SetItem(_PyPopenProcs, 4028 fileObj[0], 4029 procObj); 4030 } 4031 if (file_count >= 2) { 4032 fileObj[1] = PyLong_FromVoidPtr(f2); 4033 if (fileObj[1]) { 4034 ins_rc[1] = PyDict_SetItem(_PyPopenProcs, 4035 fileObj[1], 4036 procObj); 4037 } 4038 } 4039 if (file_count >= 3) { 4040 fileObj[2] = PyLong_FromVoidPtr(f3); 4041 if (fileObj[2]) { 4042 ins_rc[2] = PyDict_SetItem(_PyPopenProcs, 4043 fileObj[2], 4044 procObj); 4045 } 4046 } 4047 4048 if (ins_rc[0] < 0 || !fileObj[0] || 4049 ins_rc[1] < 0 || (file_count > 1 && !fileObj[1]) || 4050 ins_rc[2] < 0 || (file_count > 2 && !fileObj[2])) { 4051 /* Something failed - remove any dictionary 4052 * entries that did make it. 4053 */ 4054 if (!ins_rc[0] && fileObj[0]) { 4055 PyDict_DelItem(_PyPopenProcs, 4056 fileObj[0]); 4057 } 4058 if (!ins_rc[1] && fileObj[1]) { 4059 PyDict_DelItem(_PyPopenProcs, 4060 fileObj[1]); 4061 } 4062 if (!ins_rc[2] && fileObj[2]) { 4063 PyDict_DelItem(_PyPopenProcs, 4064 fileObj[2]); 4065 } 4066 } 4067 } 4068 4069 /* 4070 * Clean up our localized references for the dictionary keys 4071 * and value since PyDict_SetItem will Py_INCREF any copies 4072 * that got placed in the dictionary. 4073 */ 4074 Py_XDECREF(procObj); 4075 Py_XDECREF(fileObj[0]); 4076 Py_XDECREF(fileObj[1]); 4077 Py_XDECREF(fileObj[2]); 4078 } 4079 4080 /* Child is launched. Close the parents copy of those pipe 4081 * handles that only the child should have open. You need to 4082 * make sure that no handles to the write end of the output pipe 4083 * are maintained in this process or else the pipe will not close 4084 * when the child process exits and the ReadFile will hang. */ 4085 4086 if (!CloseHandle(hChildStdinRd)) 4087 return win32_error("CloseHandle", NULL); 4088 4089 if (!CloseHandle(hChildStdoutWr)) 4090 return win32_error("CloseHandle", NULL); 4091 4092 if ((n != 4) && (!CloseHandle(hChildStderrWr))) 4093 return win32_error("CloseHandle", NULL); 4094 4095 return f; 4096} 4097 4098/* 4099 * Wrapper for fclose() to use for popen* files, so we can retrieve the 4100 * exit code for the child process and return as a result of the close. 4101 * 4102 * This function uses the _PyPopenProcs dictionary in order to map the 4103 * input file pointer to information about the process that was 4104 * originally created by the popen* call that created the file pointer. 4105 * The dictionary uses the file pointer as a key (with one entry 4106 * inserted for each file returned by the original popen* call) and a 4107 * single list object as the value for all files from a single call. 4108 * The list object contains the Win32 process handle at [0], and a file 4109 * count at [1], which is initialized to the total number of file 4110 * handles using that list. 4111 * 4112 * This function closes whichever handle it is passed, and decrements 4113 * the file count in the dictionary for the process handle pointed to 4114 * by this file. On the last close (when the file count reaches zero), 4115 * this function will wait for the child process and then return its 4116 * exit code as the result of the close() operation. This permits the 4117 * files to be closed in any order - it is always the close() of the 4118 * final handle that will return the exit code. 4119 */ 4120 4121 /* RED_FLAG 31-Aug-2000 Tim 4122 * This is always called (today!) between a pair of 4123 * Py_BEGIN_ALLOW_THREADS/ Py_END_ALLOW_THREADS 4124 * macros. So the thread running this has no valid thread state, as 4125 * far as Python is concerned. However, this calls some Python API 4126 * functions that cannot be called safely without a valid thread 4127 * state, in particular PyDict_GetItem. 4128 * As a temporary hack (although it may last for years ...), we 4129 * *rely* on not having a valid thread state in this function, in 4130 * order to create our own "from scratch". 4131 * This will deadlock if _PyPclose is ever called by a thread 4132 * holding the global lock. 4133 */ 4134 4135static int _PyPclose(FILE *file) 4136{ 4137 int result; 4138 DWORD exit_code; 4139 HANDLE hProcess; 4140 PyObject *procObj, *hProcessObj, *intObj, *fileObj; 4141 long file_count; 4142#ifdef WITH_THREAD 4143 PyInterpreterState* pInterpreterState; 4144 PyThreadState* pThreadState; 4145#endif 4146 4147 /* Close the file handle first, to ensure it can't block the 4148 * child from exiting if it's the last handle. 4149 */ 4150 result = fclose(file); 4151 4152#ifdef WITH_THREAD 4153 /* Bootstrap a valid thread state into existence. */ 4154 pInterpreterState = PyInterpreterState_New(); 4155 if (!pInterpreterState) { 4156 /* Well, we're hosed now! We don't have a thread 4157 * state, so can't call a nice error routine, or raise 4158 * an exception. Just die. 4159 */ 4160 Py_FatalError("unable to allocate interpreter state " 4161 "when closing popen object"); 4162 return -1; /* unreachable */ 4163 } 4164 pThreadState = PyThreadState_New(pInterpreterState); 4165 if (!pThreadState) { 4166 Py_FatalError("unable to allocate thread state " 4167 "when closing popen object"); 4168 return -1; /* unreachable */ 4169 } 4170 /* Grab the global lock. Note that this will deadlock if the 4171 * current thread already has the lock! (see RED_FLAG comments 4172 * before this function) 4173 */ 4174 PyEval_RestoreThread(pThreadState); 4175#endif 4176 4177 if (_PyPopenProcs) { 4178 if ((fileObj = PyLong_FromVoidPtr(file)) != NULL && 4179 (procObj = PyDict_GetItem(_PyPopenProcs, 4180 fileObj)) != NULL && 4181 (hProcessObj = PyList_GetItem(procObj,0)) != NULL && 4182 (intObj = PyList_GetItem(procObj,1)) != NULL) { 4183 4184 hProcess = PyLong_AsVoidPtr(hProcessObj); 4185 file_count = PyInt_AsLong(intObj); 4186 4187 if (file_count > 1) { 4188 /* Still other files referencing process */ 4189 file_count--; 4190 PyList_SetItem(procObj,1, 4191 PyInt_FromLong(file_count)); 4192 } else { 4193 /* Last file for this process */ 4194 if (result != EOF && 4195 WaitForSingleObject(hProcess, INFINITE) != WAIT_FAILED && 4196 GetExitCodeProcess(hProcess, &exit_code)) { 4197 /* Possible truncation here in 16-bit environments, but 4198 * real exit codes are just the lower byte in any event. 4199 */ 4200 result = exit_code; 4201 } else { 4202 /* Indicate failure - this will cause the file object 4203 * to raise an I/O error and translate the last Win32 4204 * error code from errno. We do have a problem with 4205 * last errors that overlap the normal errno table, 4206 * but that's a consistent problem with the file object. 4207 */ 4208 if (result != EOF) { 4209 /* If the error wasn't from the fclose(), then 4210 * set errno for the file object error handling. 4211 */ 4212 errno = GetLastError(); 4213 } 4214 result = -1; 4215 } 4216 4217 /* Free up the native handle at this point */ 4218 CloseHandle(hProcess); 4219 } 4220 4221 /* Remove this file pointer from dictionary */ 4222 PyDict_DelItem(_PyPopenProcs, fileObj); 4223 4224 if (PyDict_Size(_PyPopenProcs) == 0) { 4225 Py_DECREF(_PyPopenProcs); 4226 _PyPopenProcs = NULL; 4227 } 4228 4229 } /* if object retrieval ok */ 4230 4231 Py_XDECREF(fileObj); 4232 } /* if _PyPopenProcs */ 4233 4234#ifdef WITH_THREAD 4235 /* Tear down the thread & interpreter states. 4236 * Note that interpreter state clear & delete functions automatically 4237 * call the thread clear & delete functions, and indeed insist on 4238 * doing that themselves. The lock must be held during the clear, but 4239 * need not be held during the delete. 4240 */ 4241 PyInterpreterState_Clear(pInterpreterState); 4242 PyEval_ReleaseThread(pThreadState); 4243 PyInterpreterState_Delete(pInterpreterState); 4244#endif 4245 4246 return result; 4247} 4248 4249#else /* which OS? */ 4250static PyObject * 4251posix_popen(PyObject *self, PyObject *args) 4252{ 4253 char *name; 4254 char *mode = "r"; 4255 int bufsize = -1; 4256 FILE *fp; 4257 PyObject *f; 4258 if (!PyArg_ParseTuple(args, "s|si:popen", &name, &mode, &bufsize)) 4259 return NULL; 4260 Py_BEGIN_ALLOW_THREADS 4261 fp = popen(name, mode); 4262 Py_END_ALLOW_THREADS 4263 if (fp == NULL) 4264 return posix_error(); 4265 f = PyFile_FromFile(fp, name, mode, pclose); 4266 if (f != NULL) 4267 PyFile_SetBufSize(f, bufsize); 4268 return f; 4269} 4270 4271#endif /* PYOS_??? */ 4272#endif /* HAVE_POPEN */ 4273 4274 4275#ifdef HAVE_SETUID 4276PyDoc_STRVAR(posix_setuid__doc__, 4277"setuid(uid)\n\n\ 4278Set the current process's user id."); 4279 4280static PyObject * 4281posix_setuid(PyObject *self, PyObject *args) 4282{ 4283 int uid; 4284 if (!PyArg_ParseTuple(args, "i:setuid", &uid)) 4285 return NULL; 4286 if (setuid(uid) < 0) 4287 return posix_error(); 4288 Py_INCREF(Py_None); 4289 return Py_None; 4290} 4291#endif /* HAVE_SETUID */ 4292 4293 4294#ifdef HAVE_SETEUID 4295PyDoc_STRVAR(posix_seteuid__doc__, 4296"seteuid(uid)\n\n\ 4297Set the current process's effective user id."); 4298 4299static PyObject * 4300posix_seteuid (PyObject *self, PyObject *args) 4301{ 4302 int euid; 4303 if (!PyArg_ParseTuple(args, "i", &euid)) { 4304 return NULL; 4305 } else if (seteuid(euid) < 0) { 4306 return posix_error(); 4307 } else { 4308 Py_INCREF(Py_None); 4309 return Py_None; 4310 } 4311} 4312#endif /* HAVE_SETEUID */ 4313 4314#ifdef HAVE_SETEGID 4315PyDoc_STRVAR(posix_setegid__doc__, 4316"setegid(gid)\n\n\ 4317Set the current process's effective group id."); 4318 4319static PyObject * 4320posix_setegid (PyObject *self, PyObject *args) 4321{ 4322 int egid; 4323 if (!PyArg_ParseTuple(args, "i", &egid)) { 4324 return NULL; 4325 } else if (setegid(egid) < 0) { 4326 return posix_error(); 4327 } else { 4328 Py_INCREF(Py_None); 4329 return Py_None; 4330 } 4331} 4332#endif /* HAVE_SETEGID */ 4333 4334#ifdef HAVE_SETREUID 4335PyDoc_STRVAR(posix_setreuid__doc__, 4336"seteuid(ruid, euid)\n\n\ 4337Set the current process's real and effective user ids."); 4338 4339static PyObject * 4340posix_setreuid (PyObject *self, PyObject *args) 4341{ 4342 int ruid, euid; 4343 if (!PyArg_ParseTuple(args, "ii", &ruid, &euid)) { 4344 return NULL; 4345 } else if (setreuid(ruid, euid) < 0) { 4346 return posix_error(); 4347 } else { 4348 Py_INCREF(Py_None); 4349 return Py_None; 4350 } 4351} 4352#endif /* HAVE_SETREUID */ 4353 4354#ifdef HAVE_SETREGID 4355PyDoc_STRVAR(posix_setregid__doc__, 4356"setegid(rgid, egid)\n\n\ 4357Set the current process's real and effective group ids."); 4358 4359static PyObject * 4360posix_setregid (PyObject *self, PyObject *args) 4361{ 4362 int rgid, egid; 4363 if (!PyArg_ParseTuple(args, "ii", &rgid, &egid)) { 4364 return NULL; 4365 } else if (setregid(rgid, egid) < 0) { 4366 return posix_error(); 4367 } else { 4368 Py_INCREF(Py_None); 4369 return Py_None; 4370 } 4371} 4372#endif /* HAVE_SETREGID */ 4373 4374#ifdef HAVE_SETGID 4375PyDoc_STRVAR(posix_setgid__doc__, 4376"setgid(gid)\n\n\ 4377Set the current process's group id."); 4378 4379static PyObject * 4380posix_setgid(PyObject *self, PyObject *args) 4381{ 4382 int gid; 4383 if (!PyArg_ParseTuple(args, "i:setgid", &gid)) 4384 return NULL; 4385 if (setgid(gid) < 0) 4386 return posix_error(); 4387 Py_INCREF(Py_None); 4388 return Py_None; 4389} 4390#endif /* HAVE_SETGID */ 4391 4392#ifdef HAVE_SETGROUPS 4393PyDoc_STRVAR(posix_setgroups__doc__, 4394"setgroups(list)\n\n\ 4395Set the groups of the current process to list."); 4396 4397static PyObject * 4398posix_setgroups(PyObject *self, PyObject *args) 4399{ 4400 PyObject *groups; 4401 int i, len; 4402 gid_t grouplist[MAX_GROUPS]; 4403 4404 if (!PyArg_ParseTuple(args, "O:setgid", &groups)) 4405 return NULL; 4406 if (!PySequence_Check(groups)) { 4407 PyErr_SetString(PyExc_TypeError, "setgroups argument must be a sequence"); 4408 return NULL; 4409 } 4410 len = PySequence_Size(groups); 4411 if (len > MAX_GROUPS) { 4412 PyErr_SetString(PyExc_ValueError, "too many groups"); 4413 return NULL; 4414 } 4415 for(i = 0; i < len; i++) { 4416 PyObject *elem; 4417 elem = PySequence_GetItem(groups, i); 4418 if (!elem) 4419 return NULL; 4420 if (!PyInt_Check(elem)) { 4421 PyErr_SetString(PyExc_TypeError, 4422 "groups must be integers"); 4423 Py_DECREF(elem); 4424 return NULL; 4425 } 4426 /* XXX: check that value fits into gid_t. */ 4427 grouplist[i] = PyInt_AsLong(elem); 4428 Py_DECREF(elem); 4429 } 4430 4431 if (setgroups(len, grouplist) < 0) 4432 return posix_error(); 4433 Py_INCREF(Py_None); 4434 return Py_None; 4435} 4436#endif /* HAVE_SETGROUPS */ 4437 4438#ifdef HAVE_WAITPID 4439PyDoc_STRVAR(posix_waitpid__doc__, 4440"waitpid(pid, options) -> (pid, status)\n\n\ 4441Wait for completion of a given child process."); 4442 4443static PyObject * 4444posix_waitpid(PyObject *self, PyObject *args) 4445{ 4446 int pid, options; 4447#ifdef UNION_WAIT 4448 union wait status; 4449#define status_i (status.w_status) 4450#else 4451 int status; 4452#define status_i status 4453#endif 4454 status_i = 0; 4455 4456 if (!PyArg_ParseTuple(args, "ii:waitpid", &pid, &options)) 4457 return NULL; 4458 Py_BEGIN_ALLOW_THREADS 4459 pid = waitpid(pid, &status, options); 4460 Py_END_ALLOW_THREADS 4461 if (pid == -1) 4462 return posix_error(); 4463 else 4464 return Py_BuildValue("ii", pid, status_i); 4465} 4466 4467#elif defined(HAVE_CWAIT) 4468 4469/* MS C has a variant of waitpid() that's usable for most purposes. */ 4470PyDoc_STRVAR(posix_waitpid__doc__, 4471"waitpid(pid, options) -> (pid, status << 8)\n\n" 4472"Wait for completion of a given process. options is ignored on Windows."); 4473 4474static PyObject * 4475posix_waitpid(PyObject *self, PyObject *args) 4476{ 4477 int pid, options; 4478 int status; 4479 4480 if (!PyArg_ParseTuple(args, "ii:waitpid", &pid, &options)) 4481 return NULL; 4482 Py_BEGIN_ALLOW_THREADS 4483 pid = _cwait(&status, pid, options); 4484 Py_END_ALLOW_THREADS 4485 if (pid == -1) 4486 return posix_error(); 4487 else 4488 /* shift the status left a byte so this is more like the 4489 POSIX waitpid */ 4490 return Py_BuildValue("ii", pid, status << 8); 4491} 4492#endif /* HAVE_WAITPID || HAVE_CWAIT */ 4493 4494#ifdef HAVE_WAIT 4495PyDoc_STRVAR(posix_wait__doc__, 4496"wait() -> (pid, status)\n\n\ 4497Wait for completion of a child process."); 4498 4499static PyObject * 4500posix_wait(PyObject *self, PyObject *args) 4501{ 4502 int pid; 4503#ifdef UNION_WAIT 4504 union wait status; 4505#define status_i (status.w_status) 4506#else 4507 int status; 4508#define status_i status 4509#endif 4510 if (!PyArg_ParseTuple(args, ":wait")) 4511 return NULL; 4512 status_i = 0; 4513 Py_BEGIN_ALLOW_THREADS 4514 pid = wait(&status); 4515 Py_END_ALLOW_THREADS 4516 if (pid == -1) 4517 return posix_error(); 4518 else 4519 return Py_BuildValue("ii", pid, status_i); 4520#undef status_i 4521} 4522#endif 4523 4524 4525PyDoc_STRVAR(posix_lstat__doc__, 4526"lstat(path) -> stat result\n\n\ 4527Like stat(path), but do not follow symbolic links."); 4528 4529static PyObject * 4530posix_lstat(PyObject *self, PyObject *args) 4531{ 4532#ifdef HAVE_LSTAT 4533 return posix_do_stat(self, args, "et:lstat", lstat, NULL, NULL); 4534#else /* !HAVE_LSTAT */ 4535#ifdef MS_WINDOWS 4536 return posix_do_stat(self, args, "et:lstat", STAT, "u:lstat", _wstati64); 4537#else 4538 return posix_do_stat(self, args, "et:lstat", STAT, NULL, NULL); 4539#endif 4540#endif /* !HAVE_LSTAT */ 4541} 4542 4543 4544#ifdef HAVE_READLINK 4545PyDoc_STRVAR(posix_readlink__doc__, 4546"readlink(path) -> path\n\n\ 4547Return a string representing the path to which the symbolic link points."); 4548 4549static PyObject * 4550posix_readlink(PyObject *self, PyObject *args) 4551{ 4552 char buf[MAXPATHLEN]; 4553 char *path; 4554 int n; 4555 if (!PyArg_ParseTuple(args, "s:readlink", &path)) 4556 return NULL; 4557 Py_BEGIN_ALLOW_THREADS 4558 n = readlink(path, buf, (int) sizeof buf); 4559 Py_END_ALLOW_THREADS 4560 if (n < 0) 4561 return posix_error_with_filename(path); 4562 return PyString_FromStringAndSize(buf, n); 4563} 4564#endif /* HAVE_READLINK */ 4565 4566 4567#ifdef HAVE_SYMLINK 4568PyDoc_STRVAR(posix_symlink__doc__, 4569"symlink(src, dst)\n\n\ 4570Create a symbolic link."); 4571 4572static PyObject * 4573posix_symlink(PyObject *self, PyObject *args) 4574{ 4575 return posix_2str(args, "etet:symlink", symlink, NULL, NULL); 4576} 4577#endif /* HAVE_SYMLINK */ 4578 4579 4580#ifdef HAVE_TIMES 4581#ifndef HZ 4582#define HZ 60 /* Universal constant :-) */ 4583#endif /* HZ */ 4584 4585#if defined(PYCC_VACPP) && defined(PYOS_OS2) 4586static long 4587system_uptime(void) 4588{ 4589 ULONG value = 0; 4590 4591 Py_BEGIN_ALLOW_THREADS 4592 DosQuerySysInfo(QSV_MS_COUNT, QSV_MS_COUNT, &value, sizeof(value)); 4593 Py_END_ALLOW_THREADS 4594 4595 return value; 4596} 4597 4598static PyObject * 4599posix_times(PyObject *self, PyObject *args) 4600{ 4601 if (!PyArg_ParseTuple(args, ":times")) 4602 return NULL; 4603 4604 /* Currently Only Uptime is Provided -- Others Later */ 4605 return Py_BuildValue("ddddd", 4606 (double)0 /* t.tms_utime / HZ */, 4607 (double)0 /* t.tms_stime / HZ */, 4608 (double)0 /* t.tms_cutime / HZ */, 4609 (double)0 /* t.tms_cstime / HZ */, 4610 (double)system_uptime() / 1000); 4611} 4612#else /* not OS2 */ 4613static PyObject * 4614posix_times(PyObject *self, PyObject *args) 4615{ 4616 struct tms t; 4617 clock_t c; 4618 if (!PyArg_ParseTuple(args, ":times")) 4619 return NULL; 4620 errno = 0; 4621 c = times(&t); 4622 if (c == (clock_t) -1) 4623 return posix_error(); 4624 return Py_BuildValue("ddddd", 4625 (double)t.tms_utime / HZ, 4626 (double)t.tms_stime / HZ, 4627 (double)t.tms_cutime / HZ, 4628 (double)t.tms_cstime / HZ, 4629 (double)c / HZ); 4630} 4631#endif /* not OS2 */ 4632#endif /* HAVE_TIMES */ 4633 4634 4635#ifdef MS_WINDOWS 4636#define HAVE_TIMES /* so the method table will pick it up */ 4637static PyObject * 4638posix_times(PyObject *self, PyObject *args) 4639{ 4640 FILETIME create, exit, kernel, user; 4641 HANDLE hProc; 4642 if (!PyArg_ParseTuple(args, ":times")) 4643 return NULL; 4644 hProc = GetCurrentProcess(); 4645 GetProcessTimes(hProc, &create, &exit, &kernel, &user); 4646 /* The fields of a FILETIME structure are the hi and lo part 4647 of a 64-bit value expressed in 100 nanosecond units. 4648 1e7 is one second in such units; 1e-7 the inverse. 4649 429.4967296 is 2**32 / 1e7 or 2**32 * 1e-7. 4650 */ 4651 return Py_BuildValue( 4652 "ddddd", 4653 (double)(kernel.dwHighDateTime*429.4967296 + 4654 kernel.dwLowDateTime*1e-7), 4655 (double)(user.dwHighDateTime*429.4967296 + 4656 user.dwLowDateTime*1e-7), 4657 (double)0, 4658 (double)0, 4659 (double)0); 4660} 4661#endif /* MS_WINDOWS */ 4662 4663#ifdef HAVE_TIMES 4664PyDoc_STRVAR(posix_times__doc__, 4665"times() -> (utime, stime, cutime, cstime, elapsed_time)\n\n\ 4666Return a tuple of floating point numbers indicating process times."); 4667#endif 4668 4669 4670#ifdef HAVE_SETSID 4671PyDoc_STRVAR(posix_setsid__doc__, 4672"setsid()\n\n\ 4673Call the system call setsid()."); 4674 4675static PyObject * 4676posix_setsid(PyObject *self, PyObject *args) 4677{ 4678 if (!PyArg_ParseTuple(args, ":setsid")) 4679 return NULL; 4680 if (setsid() < 0) 4681 return posix_error(); 4682 Py_INCREF(Py_None); 4683 return Py_None; 4684} 4685#endif /* HAVE_SETSID */ 4686 4687#ifdef HAVE_SETPGID 4688PyDoc_STRVAR(posix_setpgid__doc__, 4689"setpgid(pid, pgrp)\n\n\ 4690Call the system call setpgid()."); 4691 4692static PyObject * 4693posix_setpgid(PyObject *self, PyObject *args) 4694{ 4695 int pid, pgrp; 4696 if (!PyArg_ParseTuple(args, "ii:setpgid", &pid, &pgrp)) 4697 return NULL; 4698 if (setpgid(pid, pgrp) < 0) 4699 return posix_error(); 4700 Py_INCREF(Py_None); 4701 return Py_None; 4702} 4703#endif /* HAVE_SETPGID */ 4704 4705 4706#ifdef HAVE_TCGETPGRP 4707PyDoc_STRVAR(posix_tcgetpgrp__doc__, 4708"tcgetpgrp(fd) -> pgid\n\n\ 4709Return the process group associated with the terminal given by a fd."); 4710 4711static PyObject * 4712posix_tcgetpgrp(PyObject *self, PyObject *args) 4713{ 4714 int fd, pgid; 4715 if (!PyArg_ParseTuple(args, "i:tcgetpgrp", &fd)) 4716 return NULL; 4717 pgid = tcgetpgrp(fd); 4718 if (pgid < 0) 4719 return posix_error(); 4720 return PyInt_FromLong((long)pgid); 4721} 4722#endif /* HAVE_TCGETPGRP */ 4723 4724 4725#ifdef HAVE_TCSETPGRP 4726PyDoc_STRVAR(posix_tcsetpgrp__doc__, 4727"tcsetpgrp(fd, pgid)\n\n\ 4728Set the process group associated with the terminal given by a fd."); 4729 4730static PyObject * 4731posix_tcsetpgrp(PyObject *self, PyObject *args) 4732{ 4733 int fd, pgid; 4734 if (!PyArg_ParseTuple(args, "ii:tcsetpgrp", &fd, &pgid)) 4735 return NULL; 4736 if (tcsetpgrp(fd, pgid) < 0) 4737 return posix_error(); 4738 Py_INCREF(Py_None); 4739 return Py_None; 4740} 4741#endif /* HAVE_TCSETPGRP */ 4742 4743/* Functions acting on file descriptors */ 4744 4745PyDoc_STRVAR(posix_open__doc__, 4746"open(filename, flag [, mode=0777]) -> fd\n\n\ 4747Open a file (for low level IO)."); 4748 4749static PyObject * 4750posix_open(PyObject *self, PyObject *args) 4751{ 4752 char *file = NULL; 4753 int flag; 4754 int mode = 0777; 4755 int fd; 4756 4757#ifdef MS_WINDOWS 4758 if (unicode_file_names()) { 4759 PyUnicodeObject *po; 4760 if (PyArg_ParseTuple(args, "Ui|i:mkdir", &po, &flag, &mode)) { 4761 Py_BEGIN_ALLOW_THREADS 4762 /* PyUnicode_AS_UNICODE OK without thread 4763 lock as it is a simple dereference. */ 4764 fd = _wopen(PyUnicode_AS_UNICODE(po), flag, mode); 4765 Py_END_ALLOW_THREADS 4766 if (fd < 0) 4767 return posix_error(); 4768 return PyInt_FromLong((long)fd); 4769 } 4770 /* Drop the argument parsing error as narrow strings 4771 are also valid. */ 4772 PyErr_Clear(); 4773 } 4774#endif 4775 4776 if (!PyArg_ParseTuple(args, "eti|i", 4777 Py_FileSystemDefaultEncoding, &file, 4778 &flag, &mode)) 4779 return NULL; 4780 4781 Py_BEGIN_ALLOW_THREADS 4782 fd = open(file, flag, mode); 4783 Py_END_ALLOW_THREADS 4784 if (fd < 0) 4785 return posix_error_with_allocated_filename(file); 4786 PyMem_Free(file); 4787 return PyInt_FromLong((long)fd); 4788} 4789 4790 4791PyDoc_STRVAR(posix_close__doc__, 4792"close(fd)\n\n\ 4793Close a file descriptor (for low level IO)."); 4794 4795static PyObject * 4796posix_close(PyObject *self, PyObject *args) 4797{ 4798 int fd, res; 4799 if (!PyArg_ParseTuple(args, "i:close", &fd)) 4800 return NULL; 4801 Py_BEGIN_ALLOW_THREADS 4802 res = close(fd); 4803 Py_END_ALLOW_THREADS 4804 if (res < 0) 4805 return posix_error(); 4806 Py_INCREF(Py_None); 4807 return Py_None; 4808} 4809 4810 4811PyDoc_STRVAR(posix_dup__doc__, 4812"dup(fd) -> fd2\n\n\ 4813Return a duplicate of a file descriptor."); 4814 4815static PyObject * 4816posix_dup(PyObject *self, PyObject *args) 4817{ 4818 int fd; 4819 if (!PyArg_ParseTuple(args, "i:dup", &fd)) 4820 return NULL; 4821 Py_BEGIN_ALLOW_THREADS 4822 fd = dup(fd); 4823 Py_END_ALLOW_THREADS 4824 if (fd < 0) 4825 return posix_error(); 4826 return PyInt_FromLong((long)fd); 4827} 4828 4829 4830PyDoc_STRVAR(posix_dup2__doc__, 4831"dup2(fd, fd2)\n\n\ 4832Duplicate file descriptor."); 4833 4834static PyObject * 4835posix_dup2(PyObject *self, PyObject *args) 4836{ 4837 int fd, fd2, res; 4838 if (!PyArg_ParseTuple(args, "ii:dup2", &fd, &fd2)) 4839 return NULL; 4840 Py_BEGIN_ALLOW_THREADS 4841 res = dup2(fd, fd2); 4842 Py_END_ALLOW_THREADS 4843 if (res < 0) 4844 return posix_error(); 4845 Py_INCREF(Py_None); 4846 return Py_None; 4847} 4848 4849 4850PyDoc_STRVAR(posix_lseek__doc__, 4851"lseek(fd, pos, how) -> newpos\n\n\ 4852Set the current position of a file descriptor."); 4853 4854static PyObject * 4855posix_lseek(PyObject *self, PyObject *args) 4856{ 4857 int fd, how; 4858#if defined(MS_WIN64) || defined(MS_WINDOWS) 4859 LONG_LONG pos, res; 4860#else 4861 off_t pos, res; 4862#endif 4863 PyObject *posobj; 4864 if (!PyArg_ParseTuple(args, "iOi:lseek", &fd, &posobj, &how)) 4865 return NULL; 4866#ifdef SEEK_SET 4867 /* Turn 0, 1, 2 into SEEK_{SET,CUR,END} */ 4868 switch (how) { 4869 case 0: how = SEEK_SET; break; 4870 case 1: how = SEEK_CUR; break; 4871 case 2: how = SEEK_END; break; 4872 } 4873#endif /* SEEK_END */ 4874 4875#if !defined(HAVE_LARGEFILE_SUPPORT) 4876 pos = PyInt_AsLong(posobj); 4877#else 4878 pos = PyLong_Check(posobj) ? 4879 PyLong_AsLongLong(posobj) : PyInt_AsLong(posobj); 4880#endif 4881 if (PyErr_Occurred()) 4882 return NULL; 4883 4884 Py_BEGIN_ALLOW_THREADS 4885#if defined(MS_WIN64) || defined(MS_WINDOWS) 4886 res = _lseeki64(fd, pos, how); 4887#else 4888 res = lseek(fd, pos, how); 4889#endif 4890 Py_END_ALLOW_THREADS 4891 if (res < 0) 4892 return posix_error(); 4893 4894#if !defined(HAVE_LARGEFILE_SUPPORT) 4895 return PyInt_FromLong(res); 4896#else 4897 return PyLong_FromLongLong(res); 4898#endif 4899} 4900 4901 4902PyDoc_STRVAR(posix_read__doc__, 4903"read(fd, buffersize) -> string\n\n\ 4904Read a file descriptor."); 4905 4906static PyObject * 4907posix_read(PyObject *self, PyObject *args) 4908{ 4909 int fd, size, n; 4910 PyObject *buffer; 4911 if (!PyArg_ParseTuple(args, "ii:read", &fd, &size)) 4912 return NULL; 4913 buffer = PyString_FromStringAndSize((char *)NULL, size); 4914 if (buffer == NULL) 4915 return NULL; 4916 Py_BEGIN_ALLOW_THREADS 4917 n = read(fd, PyString_AsString(buffer), size); 4918 Py_END_ALLOW_THREADS 4919 if (n < 0) { 4920 Py_DECREF(buffer); 4921 return posix_error(); 4922 } 4923 if (n != size) 4924 _PyString_Resize(&buffer, n); 4925 return buffer; 4926} 4927 4928 4929PyDoc_STRVAR(posix_write__doc__, 4930"write(fd, string) -> byteswritten\n\n\ 4931Write a string to a file descriptor."); 4932 4933static PyObject * 4934posix_write(PyObject *self, PyObject *args) 4935{ 4936 int fd, size; 4937 char *buffer; 4938 if (!PyArg_ParseTuple(args, "is#:write", &fd, &buffer, &size)) 4939 return NULL; 4940 Py_BEGIN_ALLOW_THREADS 4941 size = write(fd, buffer, size); 4942 Py_END_ALLOW_THREADS 4943 if (size < 0) 4944 return posix_error(); 4945 return PyInt_FromLong((long)size); 4946} 4947 4948 4949PyDoc_STRVAR(posix_fstat__doc__, 4950"fstat(fd) -> stat result\n\n\ 4951Like stat(), but for an open file descriptor."); 4952 4953static PyObject * 4954posix_fstat(PyObject *self, PyObject *args) 4955{ 4956 int fd; 4957 STRUCT_STAT st; 4958 int res; 4959 if (!PyArg_ParseTuple(args, "i:fstat", &fd)) 4960 return NULL; 4961 Py_BEGIN_ALLOW_THREADS 4962 res = FSTAT(fd, &st); 4963 Py_END_ALLOW_THREADS 4964 if (res != 0) 4965 return posix_error(); 4966 4967 return _pystat_fromstructstat(st); 4968} 4969 4970 4971PyDoc_STRVAR(posix_fdopen__doc__, 4972"fdopen(fd, [, mode='r' [, bufsize]]) -> file_object\n\n\ 4973Return an open file object connected to a file descriptor."); 4974 4975static PyObject * 4976posix_fdopen(PyObject *self, PyObject *args) 4977{ 4978 int fd; 4979 char *mode = "r"; 4980 int bufsize = -1; 4981 FILE *fp; 4982 PyObject *f; 4983 if (!PyArg_ParseTuple(args, "i|si", &fd, &mode, &bufsize)) 4984 return NULL; 4985 4986 Py_BEGIN_ALLOW_THREADS 4987 fp = fdopen(fd, mode); 4988 Py_END_ALLOW_THREADS 4989 if (fp == NULL) 4990 return posix_error(); 4991 f = PyFile_FromFile(fp, "<fdopen>", mode, fclose); 4992 if (f != NULL) 4993 PyFile_SetBufSize(f, bufsize); 4994 return f; 4995} 4996 4997PyDoc_STRVAR(posix_isatty__doc__, 4998"isatty(fd) -> bool\n\n\ 4999Return True if the file descriptor 'fd' is an open file descriptor\n\ 5000connected to the slave end of a terminal."); 5001 5002static PyObject * 5003posix_isatty(PyObject *self, PyObject *args) 5004{ 5005 int fd; 5006 if (!PyArg_ParseTuple(args, "i:isatty", &fd)) 5007 return NULL; 5008 return PyBool_FromLong(isatty(fd)); 5009} 5010 5011#ifdef HAVE_PIPE 5012PyDoc_STRVAR(posix_pipe__doc__, 5013"pipe() -> (read_end, write_end)\n\n\ 5014Create a pipe."); 5015 5016static PyObject * 5017posix_pipe(PyObject *self, PyObject *args) 5018{ 5019#if defined(PYOS_OS2) 5020 HFILE read, write; 5021 APIRET rc; 5022 5023 if (!PyArg_ParseTuple(args, ":pipe")) 5024 return NULL; 5025 5026 Py_BEGIN_ALLOW_THREADS 5027 rc = DosCreatePipe( &read, &write, 4096); 5028 Py_END_ALLOW_THREADS 5029 if (rc != NO_ERROR) 5030 return os2_error(rc); 5031 5032 return Py_BuildValue("(ii)", read, write); 5033#else 5034#if !defined(MS_WINDOWS) 5035 int fds[2]; 5036 int res; 5037 if (!PyArg_ParseTuple(args, ":pipe")) 5038 return NULL; 5039 Py_BEGIN_ALLOW_THREADS 5040 res = pipe(fds); 5041 Py_END_ALLOW_THREADS 5042 if (res != 0) 5043 return posix_error(); 5044 return Py_BuildValue("(ii)", fds[0], fds[1]); 5045#else /* MS_WINDOWS */ 5046 HANDLE read, write; 5047 int read_fd, write_fd; 5048 BOOL ok; 5049 if (!PyArg_ParseTuple(args, ":pipe")) 5050 return NULL; 5051 Py_BEGIN_ALLOW_THREADS 5052 ok = CreatePipe(&read, &write, NULL, 0); 5053 Py_END_ALLOW_THREADS 5054 if (!ok) 5055 return win32_error("CreatePipe", NULL); 5056 read_fd = _open_osfhandle((Py_intptr_t)read, 0); 5057 write_fd = _open_osfhandle((Py_intptr_t)write, 1); 5058 return Py_BuildValue("(ii)", read_fd, write_fd); 5059#endif /* MS_WINDOWS */ 5060#endif 5061} 5062#endif /* HAVE_PIPE */ 5063 5064 5065#ifdef HAVE_MKFIFO 5066PyDoc_STRVAR(posix_mkfifo__doc__, 5067"mkfifo(filename, [, mode=0666])\n\n\ 5068Create a FIFO (a POSIX named pipe)."); 5069 5070static PyObject * 5071posix_mkfifo(PyObject *self, PyObject *args) 5072{ 5073 char *filename; 5074 int mode = 0666; 5075 int res; 5076 if (!PyArg_ParseTuple(args, "s|i:mkfifo", &filename, &mode)) 5077 return NULL; 5078 Py_BEGIN_ALLOW_THREADS 5079 res = mkfifo(filename, mode); 5080 Py_END_ALLOW_THREADS 5081 if (res < 0) 5082 return posix_error(); 5083 Py_INCREF(Py_None); 5084 return Py_None; 5085} 5086#endif 5087 5088 5089#if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV) 5090PyDoc_STRVAR(posix_mknod__doc__, 5091"mknod(filename, [, mode=0600, device])\n\n\ 5092Create a filesystem node (file, device special file or named pipe)\n\ 5093named filename. mode specifies both the permissions to use and the\n\ 5094type of node to be created, being combined (bitwise OR) with one of\n\ 5095S_IFREG, S_IFCHR, S_IFBLK, and S_IFIFO. For S_IFCHR and S_IFBLK,\n\ 5096device defines the newly created device special file (probably using\n\ 5097os.makedev()), otherwise it is ignored."); 5098 5099 5100static PyObject * 5101posix_mknod(PyObject *self, PyObject *args) 5102{ 5103 char *filename; 5104 int mode = 0600; 5105 int device = 0; 5106 int res; 5107 if (!PyArg_ParseTuple(args, "s|iii:mknod", &filename, &mode, &device)) 5108 return NULL; 5109 Py_BEGIN_ALLOW_THREADS 5110 res = mknod(filename, mode, device); 5111 Py_END_ALLOW_THREADS 5112 if (res < 0) 5113 return posix_error(); 5114 Py_INCREF(Py_None); 5115 return Py_None; 5116} 5117#endif 5118 5119#ifdef HAVE_DEVICE_MACROS 5120PyDoc_STRVAR(posix_major__doc__, 5121"major(device) -> major number\n\ 5122Extracts a device major number from a raw device number."); 5123 5124static PyObject * 5125posix_major(PyObject *self, PyObject *args) 5126{ 5127 int device; 5128 if (!PyArg_ParseTuple(args, "i:major", &device)) 5129 return NULL; 5130 return PyInt_FromLong((long)major(device)); 5131} 5132 5133PyDoc_STRVAR(posix_minor__doc__, 5134"minor(device) -> minor number\n\ 5135Extracts a device minor number from a raw device number."); 5136 5137static PyObject * 5138posix_minor(PyObject *self, PyObject *args) 5139{ 5140 int device; 5141 if (!PyArg_ParseTuple(args, "i:minor", &device)) 5142 return NULL; 5143 return PyInt_FromLong((long)minor(device)); 5144} 5145 5146PyDoc_STRVAR(posix_makedev__doc__, 5147"makedev(major, minor) -> device number\n\ 5148Composes a raw device number from the major and minor device numbers."); 5149 5150static PyObject * 5151posix_makedev(PyObject *self, PyObject *args) 5152{ 5153 int major, minor; 5154 if (!PyArg_ParseTuple(args, "ii:makedev", &major, &minor)) 5155 return NULL; 5156 return PyInt_FromLong((long)makedev(major, minor)); 5157} 5158#endif /* device macros */ 5159 5160 5161#ifdef HAVE_FTRUNCATE 5162PyDoc_STRVAR(posix_ftruncate__doc__, 5163"ftruncate(fd, length)\n\n\ 5164Truncate a file to a specified length."); 5165 5166static PyObject * 5167posix_ftruncate(PyObject *self, PyObject *args) 5168{ 5169 int fd; 5170 off_t length; 5171 int res; 5172 PyObject *lenobj; 5173 5174 if (!PyArg_ParseTuple(args, "iO:ftruncate", &fd, &lenobj)) 5175 return NULL; 5176 5177#if !defined(HAVE_LARGEFILE_SUPPORT) 5178 length = PyInt_AsLong(lenobj); 5179#else 5180 length = PyLong_Check(lenobj) ? 5181 PyLong_AsLongLong(lenobj) : PyInt_AsLong(lenobj); 5182#endif 5183 if (PyErr_Occurred()) 5184 return NULL; 5185 5186 Py_BEGIN_ALLOW_THREADS 5187 res = ftruncate(fd, length); 5188 Py_END_ALLOW_THREADS 5189 if (res < 0) { 5190 PyErr_SetFromErrno(PyExc_IOError); 5191 return NULL; 5192 } 5193 Py_INCREF(Py_None); 5194 return Py_None; 5195} 5196#endif 5197 5198#ifdef HAVE_PUTENV 5199PyDoc_STRVAR(posix_putenv__doc__, 5200"putenv(key, value)\n\n\ 5201Change or add an environment variable."); 5202 5203/* Save putenv() parameters as values here, so we can collect them when they 5204 * get re-set with another call for the same key. */ 5205static PyObject *posix_putenv_garbage; 5206 5207static PyObject * 5208posix_putenv(PyObject *self, PyObject *args) 5209{ 5210 char *s1, *s2; 5211 char *new; 5212 PyObject *newstr; 5213 size_t len; 5214 5215 if (!PyArg_ParseTuple(args, "ss:putenv", &s1, &s2)) 5216 return NULL; 5217 5218#if defined(PYOS_OS2) 5219 if (stricmp(s1, "BEGINLIBPATH") == 0) { 5220 APIRET rc; 5221 5222 if (strlen(s2) == 0) /* If New Value is an Empty String */ 5223 s2 = NULL; /* Then OS/2 API Wants a NULL to Undefine It */ 5224 5225 rc = DosSetExtLIBPATH(s2, BEGIN_LIBPATH); 5226 if (rc != NO_ERROR) 5227 return os2_error(rc); 5228 5229 } else if (stricmp(s1, "ENDLIBPATH") == 0) { 5230 APIRET rc; 5231 5232 if (strlen(s2) == 0) /* If New Value is an Empty String */ 5233 s2 = NULL; /* Then OS/2 API Wants a NULL to Undefine It */ 5234 5235 rc = DosSetExtLIBPATH(s2, END_LIBPATH); 5236 if (rc != NO_ERROR) 5237 return os2_error(rc); 5238 } else { 5239#endif 5240 5241 /* XXX This can leak memory -- not easy to fix :-( */ 5242 len = strlen(s1) + strlen(s2) + 2; 5243 /* len includes space for a trailing \0; the size arg to 5244 PyString_FromStringAndSize does not count that */ 5245 newstr = PyString_FromStringAndSize(NULL, (int)len - 1); 5246 if (newstr == NULL) 5247 return PyErr_NoMemory(); 5248 new = PyString_AS_STRING(newstr); 5249 PyOS_snprintf(new, len, "%s=%s", s1, s2); 5250 if (putenv(new)) { 5251 posix_error(); 5252 return NULL; 5253 } 5254 /* Install the first arg and newstr in posix_putenv_garbage; 5255 * this will cause previous value to be collected. This has to 5256 * happen after the real putenv() call because the old value 5257 * was still accessible until then. */ 5258 if (PyDict_SetItem(posix_putenv_garbage, 5259 PyTuple_GET_ITEM(args, 0), newstr)) { 5260 /* really not much we can do; just leak */ 5261 PyErr_Clear(); 5262 } 5263 else { 5264 Py_DECREF(newstr); 5265 } 5266 5267#if defined(PYOS_OS2) 5268 } 5269#endif 5270 Py_INCREF(Py_None); 5271 return Py_None; 5272} 5273#endif /* putenv */ 5274 5275#ifdef HAVE_UNSETENV 5276PyDoc_STRVAR(posix_unsetenv__doc__, 5277"unsetenv(key)\n\n\ 5278Delete an environment variable."); 5279 5280static PyObject * 5281posix_unsetenv(PyObject *self, PyObject *args) 5282{ 5283 char *s1; 5284 5285 if (!PyArg_ParseTuple(args, "s:unsetenv", &s1)) 5286 return NULL; 5287 5288 unsetenv(s1); 5289 5290 /* Remove the key from posix_putenv_garbage; 5291 * this will cause it to be collected. This has to 5292 * happen after the real unsetenv() call because the 5293 * old value was still accessible until then. 5294 */ 5295 if (PyDict_DelItem(posix_putenv_garbage, 5296 PyTuple_GET_ITEM(args, 0))) { 5297 /* really not much we can do; just leak */ 5298 PyErr_Clear(); 5299 } 5300 5301 Py_INCREF(Py_None); 5302 return Py_None; 5303} 5304#endif /* unsetenv */ 5305 5306#ifdef HAVE_STRERROR 5307PyDoc_STRVAR(posix_strerror__doc__, 5308"strerror(code) -> string\n\n\ 5309Translate an error code to a message string."); 5310 5311static PyObject * 5312posix_strerror(PyObject *self, PyObject *args) 5313{ 5314 int code; 5315 char *message; 5316 if (!PyArg_ParseTuple(args, "i:strerror", &code)) 5317 return NULL; 5318 message = strerror(code); 5319 if (message == NULL) { 5320 PyErr_SetString(PyExc_ValueError, 5321 "strerror() argument out of range"); 5322 return NULL; 5323 } 5324 return PyString_FromString(message); 5325} 5326#endif /* strerror */ 5327 5328 5329#ifdef HAVE_SYS_WAIT_H 5330 5331#ifdef WCOREDUMP 5332PyDoc_STRVAR(posix_WCOREDUMP__doc__, 5333"WCOREDUMP(status) -> bool\n\n\ 5334Return True if the process returning 'status' was dumped to a core file."); 5335 5336static PyObject * 5337posix_WCOREDUMP(PyObject *self, PyObject *args) 5338{ 5339#ifdef UNION_WAIT 5340 union wait status; 5341#define status_i (status.w_status) 5342#else 5343 int status; 5344#define status_i status 5345#endif 5346 status_i = 0; 5347 5348 if (!PyArg_ParseTuple(args, "i:WCOREDUMP", &status_i)) 5349 { 5350 return NULL; 5351 } 5352 5353 return PyBool_FromLong(WCOREDUMP(status)); 5354#undef status_i 5355} 5356#endif /* WCOREDUMP */ 5357 5358#ifdef WIFCONTINUED 5359PyDoc_STRVAR(posix_WIFCONTINUED__doc__, 5360"WIFCONTINUED(status) -> bool\n\n\ 5361Return True if the process returning 'status' was continued from a\n\ 5362job control stop."); 5363 5364static PyObject * 5365posix_WIFCONTINUED(PyObject *self, PyObject *args) 5366{ 5367#ifdef UNION_WAIT 5368 union wait status; 5369#define status_i (status.w_status) 5370#else 5371 int status; 5372#define status_i status 5373#endif 5374 status_i = 0; 5375 5376 if (!PyArg_ParseTuple(args, "i:WCONTINUED", &status_i)) 5377 { 5378 return NULL; 5379 } 5380 5381 return PyBool_FromLong(WIFCONTINUED(status)); 5382#undef status_i 5383} 5384#endif /* WIFCONTINUED */ 5385 5386#ifdef WIFSTOPPED 5387PyDoc_STRVAR(posix_WIFSTOPPED__doc__, 5388"WIFSTOPPED(status) -> bool\n\n\ 5389Return True if the process returning 'status' was stopped."); 5390 5391static PyObject * 5392posix_WIFSTOPPED(PyObject *self, PyObject *args) 5393{ 5394#ifdef UNION_WAIT 5395 union wait status; 5396#define status_i (status.w_status) 5397#else 5398 int status; 5399#define status_i status 5400#endif 5401 status_i = 0; 5402 5403 if (!PyArg_ParseTuple(args, "i:WIFSTOPPED", &status_i)) 5404 { 5405 return NULL; 5406 } 5407 5408 return PyBool_FromLong(WIFSTOPPED(status)); 5409#undef status_i 5410} 5411#endif /* WIFSTOPPED */ 5412 5413#ifdef WIFSIGNALED 5414PyDoc_STRVAR(posix_WIFSIGNALED__doc__, 5415"WIFSIGNALED(status) -> bool\n\n\ 5416Return True if the process returning 'status' was terminated by a signal."); 5417 5418static PyObject * 5419posix_WIFSIGNALED(PyObject *self, PyObject *args) 5420{ 5421#ifdef UNION_WAIT 5422 union wait status; 5423#define status_i (status.w_status) 5424#else 5425 int status; 5426#define status_i status 5427#endif 5428 status_i = 0; 5429 5430 if (!PyArg_ParseTuple(args, "i:WIFSIGNALED", &status_i)) 5431 { 5432 return NULL; 5433 } 5434 5435 return PyBool_FromLong(WIFSIGNALED(status)); 5436#undef status_i 5437} 5438#endif /* WIFSIGNALED */ 5439 5440#ifdef WIFEXITED 5441PyDoc_STRVAR(posix_WIFEXITED__doc__, 5442"WIFEXITED(status) -> bool\n\n\ 5443Return true if the process returning 'status' exited using the exit()\n\ 5444system call."); 5445 5446static PyObject * 5447posix_WIFEXITED(PyObject *self, PyObject *args) 5448{ 5449#ifdef UNION_WAIT 5450 union wait status; 5451#define status_i (status.w_status) 5452#else 5453 int status; 5454#define status_i status 5455#endif 5456 status_i = 0; 5457 5458 if (!PyArg_ParseTuple(args, "i:WIFEXITED", &status_i)) 5459 { 5460 return NULL; 5461 } 5462 5463 return PyBool_FromLong(WIFEXITED(status)); 5464#undef status_i 5465} 5466#endif /* WIFEXITED */ 5467 5468#ifdef WEXITSTATUS 5469PyDoc_STRVAR(posix_WEXITSTATUS__doc__, 5470"WEXITSTATUS(status) -> integer\n\n\ 5471Return the process return code from 'status'."); 5472 5473static PyObject * 5474posix_WEXITSTATUS(PyObject *self, PyObject *args) 5475{ 5476#ifdef UNION_WAIT 5477 union wait status; 5478#define status_i (status.w_status) 5479#else 5480 int status; 5481#define status_i status 5482#endif 5483 status_i = 0; 5484 5485 if (!PyArg_ParseTuple(args, "i:WEXITSTATUS", &status_i)) 5486 { 5487 return NULL; 5488 } 5489 5490 return Py_BuildValue("i", WEXITSTATUS(status)); 5491#undef status_i 5492} 5493#endif /* WEXITSTATUS */ 5494 5495#ifdef WTERMSIG 5496PyDoc_STRVAR(posix_WTERMSIG__doc__, 5497"WTERMSIG(status) -> integer\n\n\ 5498Return the signal that terminated the process that provided the 'status'\n\ 5499value."); 5500 5501static PyObject * 5502posix_WTERMSIG(PyObject *self, PyObject *args) 5503{ 5504#ifdef UNION_WAIT 5505 union wait status; 5506#define status_i (status.w_status) 5507#else 5508 int status; 5509#define status_i status 5510#endif 5511 status_i = 0; 5512 5513 if (!PyArg_ParseTuple(args, "i:WTERMSIG", &status_i)) 5514 { 5515 return NULL; 5516 } 5517 5518 return Py_BuildValue("i", WTERMSIG(status)); 5519#undef status_i 5520} 5521#endif /* WTERMSIG */ 5522 5523#ifdef WSTOPSIG 5524PyDoc_STRVAR(posix_WSTOPSIG__doc__, 5525"WSTOPSIG(status) -> integer\n\n\ 5526Return the signal that stopped the process that provided\n\ 5527the 'status' value."); 5528 5529static PyObject * 5530posix_WSTOPSIG(PyObject *self, PyObject *args) 5531{ 5532#ifdef UNION_WAIT 5533 union wait status; 5534#define status_i (status.w_status) 5535#else 5536 int status; 5537#define status_i status 5538#endif 5539 status_i = 0; 5540 5541 if (!PyArg_ParseTuple(args, "i:WSTOPSIG", &status_i)) 5542 { 5543 return NULL; 5544 } 5545 5546 return Py_BuildValue("i", WSTOPSIG(status)); 5547#undef status_i 5548} 5549#endif /* WSTOPSIG */ 5550 5551#endif /* HAVE_SYS_WAIT_H */ 5552 5553 5554#if defined(HAVE_FSTATVFS) 5555#ifdef _SCO_DS 5556/* SCO OpenServer 5.0 and later requires _SVID3 before it reveals the 5557 needed definitions in sys/statvfs.h */ 5558#define _SVID3 5559#endif 5560#include <sys/statvfs.h> 5561 5562static PyObject* 5563_pystatvfs_fromstructstatvfs(struct statvfs st) { 5564 PyObject *v = PyStructSequence_New(&StatVFSResultType); 5565 if (v == NULL) 5566 return NULL; 5567 5568#if !defined(HAVE_LARGEFILE_SUPPORT) 5569 PyStructSequence_SET_ITEM(v, 0, PyInt_FromLong((long) st.f_bsize)); 5570 PyStructSequence_SET_ITEM(v, 1, PyInt_FromLong((long) st.f_frsize)); 5571 PyStructSequence_SET_ITEM(v, 2, PyInt_FromLong((long) st.f_blocks)); 5572 PyStructSequence_SET_ITEM(v, 3, PyInt_FromLong((long) st.f_bfree)); 5573 PyStructSequence_SET_ITEM(v, 4, PyInt_FromLong((long) st.f_bavail)); 5574 PyStructSequence_SET_ITEM(v, 5, PyInt_FromLong((long) st.f_files)); 5575 PyStructSequence_SET_ITEM(v, 6, PyInt_FromLong((long) st.f_ffree)); 5576 PyStructSequence_SET_ITEM(v, 7, PyInt_FromLong((long) st.f_favail)); 5577 PyStructSequence_SET_ITEM(v, 8, PyInt_FromLong((long) st.f_flag)); 5578 PyStructSequence_SET_ITEM(v, 9, PyInt_FromLong((long) st.f_namemax)); 5579#else 5580 PyStructSequence_SET_ITEM(v, 0, PyInt_FromLong((long) st.f_bsize)); 5581 PyStructSequence_SET_ITEM(v, 1, PyInt_FromLong((long) st.f_frsize)); 5582 PyStructSequence_SET_ITEM(v, 2, 5583 PyLong_FromLongLong((LONG_LONG) st.f_blocks)); 5584 PyStructSequence_SET_ITEM(v, 3, 5585 PyLong_FromLongLong((LONG_LONG) st.f_bfree)); 5586 PyStructSequence_SET_ITEM(v, 4, 5587 PyLong_FromLongLong((LONG_LONG) st.f_bavail)); 5588 PyStructSequence_SET_ITEM(v, 5, 5589 PyLong_FromLongLong((LONG_LONG) st.f_files)); 5590 PyStructSequence_SET_ITEM(v, 6, 5591 PyLong_FromLongLong((LONG_LONG) st.f_ffree)); 5592 PyStructSequence_SET_ITEM(v, 7, 5593 PyLong_FromLongLong((LONG_LONG) st.f_favail)); 5594 PyStructSequence_SET_ITEM(v, 8, PyInt_FromLong((long) st.f_flag)); 5595 PyStructSequence_SET_ITEM(v, 9, PyInt_FromLong((long) st.f_namemax)); 5596#endif 5597 5598 return v; 5599} 5600 5601PyDoc_STRVAR(posix_fstatvfs__doc__, 5602"fstatvfs(fd) -> statvfs result\n\n\ 5603Perform an fstatvfs system call on the given fd."); 5604 5605static PyObject * 5606posix_fstatvfs(PyObject *self, PyObject *args) 5607{ 5608 int fd, res; 5609 struct statvfs st; 5610 5611 if (!PyArg_ParseTuple(args, "i:fstatvfs", &fd)) 5612 return NULL; 5613 Py_BEGIN_ALLOW_THREADS 5614 res = fstatvfs(fd, &st); 5615 Py_END_ALLOW_THREADS 5616 if (res != 0) 5617 return posix_error(); 5618 5619 return _pystatvfs_fromstructstatvfs(st); 5620} 5621#endif /* HAVE_FSTATVFS */ 5622 5623 5624#if defined(HAVE_STATVFS) 5625#include <sys/statvfs.h> 5626 5627PyDoc_STRVAR(posix_statvfs__doc__, 5628"statvfs(path) -> statvfs result\n\n\ 5629Perform a statvfs system call on the given path."); 5630 5631static PyObject * 5632posix_statvfs(PyObject *self, PyObject *args) 5633{ 5634 char *path; 5635 int res; 5636 struct statvfs st; 5637 if (!PyArg_ParseTuple(args, "s:statvfs", &path)) 5638 return NULL; 5639 Py_BEGIN_ALLOW_THREADS 5640 res = statvfs(path, &st); 5641 Py_END_ALLOW_THREADS 5642 if (res != 0) 5643 return posix_error_with_filename(path); 5644 5645 return _pystatvfs_fromstructstatvfs(st); 5646} 5647#endif /* HAVE_STATVFS */ 5648 5649 5650#ifdef HAVE_TEMPNAM 5651PyDoc_STRVAR(posix_tempnam__doc__, 5652"tempnam([dir[, prefix]]) -> string\n\n\ 5653Return a unique name for a temporary file.\n\ 5654The directory and a prefix may be specified as strings; they may be omitted\n\ 5655or None if not needed."); 5656 5657static PyObject * 5658posix_tempnam(PyObject *self, PyObject *args) 5659{ 5660 PyObject *result = NULL; 5661 char *dir = NULL; 5662 char *pfx = NULL; 5663 char *name; 5664 5665 if (!PyArg_ParseTuple(args, "|zz:tempnam", &dir, &pfx)) 5666 return NULL; 5667 5668 if (PyErr_Warn(PyExc_RuntimeWarning, 5669 "tempnam is a potential security risk to your program") < 0) 5670 return NULL; 5671 5672#ifdef MS_WINDOWS 5673 name = _tempnam(dir, pfx); 5674#else 5675 name = tempnam(dir, pfx); 5676#endif 5677 if (name == NULL) 5678 return PyErr_NoMemory(); 5679 result = PyString_FromString(name); 5680 free(name); 5681 return result; 5682} 5683#endif 5684 5685 5686#ifdef HAVE_TMPFILE 5687PyDoc_STRVAR(posix_tmpfile__doc__, 5688"tmpfile() -> file object\n\n\ 5689Create a temporary file with no directory entries."); 5690 5691static PyObject * 5692posix_tmpfile(PyObject *self, PyObject *args) 5693{ 5694 FILE *fp; 5695 5696 if (!PyArg_ParseTuple(args, ":tmpfile")) 5697 return NULL; 5698 fp = tmpfile(); 5699 if (fp == NULL) 5700 return posix_error(); 5701 return PyFile_FromFile(fp, "<tmpfile>", "w+b", fclose); 5702} 5703#endif 5704 5705 5706#ifdef HAVE_TMPNAM 5707PyDoc_STRVAR(posix_tmpnam__doc__, 5708"tmpnam() -> string\n\n\ 5709Return a unique name for a temporary file."); 5710 5711static PyObject * 5712posix_tmpnam(PyObject *self, PyObject *args) 5713{ 5714 char buffer[L_tmpnam]; 5715 char *name; 5716 5717 if (!PyArg_ParseTuple(args, ":tmpnam")) 5718 return NULL; 5719 5720 if (PyErr_Warn(PyExc_RuntimeWarning, 5721 "tmpnam is a potential security risk to your program") < 0) 5722 return NULL; 5723 5724#ifdef USE_TMPNAM_R 5725 name = tmpnam_r(buffer); 5726#else 5727 name = tmpnam(buffer); 5728#endif 5729 if (name == NULL) { 5730 PyErr_SetObject(PyExc_OSError, 5731 Py_BuildValue("is", 0, 5732#ifdef USE_TMPNAM_R 5733 "unexpected NULL from tmpnam_r" 5734#else 5735 "unexpected NULL from tmpnam" 5736#endif 5737 )); 5738 return NULL; 5739 } 5740 return PyString_FromString(buffer); 5741} 5742#endif 5743 5744 5745/* This is used for fpathconf(), pathconf(), confstr() and sysconf(). 5746 * It maps strings representing configuration variable names to 5747 * integer values, allowing those functions to be called with the 5748 * magic names instead of polluting the module's namespace with tons of 5749 * rarely-used constants. There are three separate tables that use 5750 * these definitions. 5751 * 5752 * This code is always included, even if none of the interfaces that 5753 * need it are included. The #if hackery needed to avoid it would be 5754 * sufficiently pervasive that it's not worth the loss of readability. 5755 */ 5756struct constdef { 5757 char *name; 5758 long value; 5759}; 5760 5761static int 5762conv_confname(PyObject *arg, int *valuep, struct constdef *table, 5763 size_t tablesize) 5764{ 5765 if (PyInt_Check(arg)) { 5766 *valuep = PyInt_AS_LONG(arg); 5767 return 1; 5768 } 5769 if (PyString_Check(arg)) { 5770 /* look up the value in the table using a binary search */ 5771 size_t lo = 0; 5772 size_t mid; 5773 size_t hi = tablesize; 5774 int cmp; 5775 char *confname = PyString_AS_STRING(arg); 5776 while (lo < hi) { 5777 mid = (lo + hi) / 2; 5778 cmp = strcmp(confname, table[mid].name); 5779 if (cmp < 0) 5780 hi = mid; 5781 else if (cmp > 0) 5782 lo = mid + 1; 5783 else { 5784 *valuep = table[mid].value; 5785 return 1; 5786 } 5787 } 5788 PyErr_SetString(PyExc_ValueError, "unrecognized configuration name"); 5789 } 5790 else 5791 PyErr_SetString(PyExc_TypeError, 5792 "configuration names must be strings or integers"); 5793 return 0; 5794} 5795 5796 5797#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF) 5798static struct constdef posix_constants_pathconf[] = { 5799#ifdef _PC_ABI_AIO_XFER_MAX 5800 {"PC_ABI_AIO_XFER_MAX", _PC_ABI_AIO_XFER_MAX}, 5801#endif 5802#ifdef _PC_ABI_ASYNC_IO 5803 {"PC_ABI_ASYNC_IO", _PC_ABI_ASYNC_IO}, 5804#endif 5805#ifdef _PC_ASYNC_IO 5806 {"PC_ASYNC_IO", _PC_ASYNC_IO}, 5807#endif 5808#ifdef _PC_CHOWN_RESTRICTED 5809 {"PC_CHOWN_RESTRICTED", _PC_CHOWN_RESTRICTED}, 5810#endif 5811#ifdef _PC_FILESIZEBITS 5812 {"PC_FILESIZEBITS", _PC_FILESIZEBITS}, 5813#endif 5814#ifdef _PC_LAST 5815 {"PC_LAST", _PC_LAST}, 5816#endif 5817#ifdef _PC_LINK_MAX 5818 {"PC_LINK_MAX", _PC_LINK_MAX}, 5819#endif 5820#ifdef _PC_MAX_CANON 5821 {"PC_MAX_CANON", _PC_MAX_CANON}, 5822#endif 5823#ifdef _PC_MAX_INPUT 5824 {"PC_MAX_INPUT", _PC_MAX_INPUT}, 5825#endif 5826#ifdef _PC_NAME_MAX 5827 {"PC_NAME_MAX", _PC_NAME_MAX}, 5828#endif 5829#ifdef _PC_NO_TRUNC 5830 {"PC_NO_TRUNC", _PC_NO_TRUNC}, 5831#endif 5832#ifdef _PC_PATH_MAX 5833 {"PC_PATH_MAX", _PC_PATH_MAX}, 5834#endif 5835#ifdef _PC_PIPE_BUF 5836 {"PC_PIPE_BUF", _PC_PIPE_BUF}, 5837#endif 5838#ifdef _PC_PRIO_IO 5839 {"PC_PRIO_IO", _PC_PRIO_IO}, 5840#endif 5841#ifdef _PC_SOCK_MAXBUF 5842 {"PC_SOCK_MAXBUF", _PC_SOCK_MAXBUF}, 5843#endif 5844#ifdef _PC_SYNC_IO 5845 {"PC_SYNC_IO", _PC_SYNC_IO}, 5846#endif 5847#ifdef _PC_VDISABLE 5848 {"PC_VDISABLE", _PC_VDISABLE}, 5849#endif 5850}; 5851 5852static int 5853conv_path_confname(PyObject *arg, int *valuep) 5854{ 5855 return conv_confname(arg, valuep, posix_constants_pathconf, 5856 sizeof(posix_constants_pathconf) 5857 / sizeof(struct constdef)); 5858} 5859#endif 5860 5861#ifdef HAVE_FPATHCONF 5862PyDoc_STRVAR(posix_fpathconf__doc__, 5863"fpathconf(fd, name) -> integer\n\n\ 5864Return the configuration limit name for the file descriptor fd.\n\ 5865If there is no limit, return -1."); 5866 5867static PyObject * 5868posix_fpathconf(PyObject *self, PyObject *args) 5869{ 5870 PyObject *result = NULL; 5871 int name, fd; 5872 5873 if (PyArg_ParseTuple(args, "iO&:fpathconf", &fd, 5874 conv_path_confname, &name)) { 5875 long limit; 5876 5877 errno = 0; 5878 limit = fpathconf(fd, name); 5879 if (limit == -1 && errno != 0) 5880 posix_error(); 5881 else 5882 result = PyInt_FromLong(limit); 5883 } 5884 return result; 5885} 5886#endif 5887 5888 5889#ifdef HAVE_PATHCONF 5890PyDoc_STRVAR(posix_pathconf__doc__, 5891"pathconf(path, name) -> integer\n\n\ 5892Return the configuration limit name for the file or directory path.\n\ 5893If there is no limit, return -1."); 5894 5895static PyObject * 5896posix_pathconf(PyObject *self, PyObject *args) 5897{ 5898 PyObject *result = NULL; 5899 int name; 5900 char *path; 5901 5902 if (PyArg_ParseTuple(args, "sO&:pathconf", &path, 5903 conv_path_confname, &name)) { 5904 long limit; 5905 5906 errno = 0; 5907 limit = pathconf(path, name); 5908 if (limit == -1 && errno != 0) { 5909 if (errno == EINVAL) 5910 /* could be a path or name problem */ 5911 posix_error(); 5912 else 5913 posix_error_with_filename(path); 5914 } 5915 else 5916 result = PyInt_FromLong(limit); 5917 } 5918 return result; 5919} 5920#endif 5921 5922#ifdef HAVE_CONFSTR 5923static struct constdef posix_constants_confstr[] = { 5924#ifdef _CS_ARCHITECTURE 5925 {"CS_ARCHITECTURE", _CS_ARCHITECTURE}, 5926#endif 5927#ifdef _CS_HOSTNAME 5928 {"CS_HOSTNAME", _CS_HOSTNAME}, 5929#endif 5930#ifdef _CS_HW_PROVIDER 5931 {"CS_HW_PROVIDER", _CS_HW_PROVIDER}, 5932#endif 5933#ifdef _CS_HW_SERIAL 5934 {"CS_HW_SERIAL", _CS_HW_SERIAL}, 5935#endif 5936#ifdef _CS_INITTAB_NAME 5937 {"CS_INITTAB_NAME", _CS_INITTAB_NAME}, 5938#endif 5939#ifdef _CS_LFS64_CFLAGS 5940 {"CS_LFS64_CFLAGS", _CS_LFS64_CFLAGS}, 5941#endif 5942#ifdef _CS_LFS64_LDFLAGS 5943 {"CS_LFS64_LDFLAGS", _CS_LFS64_LDFLAGS}, 5944#endif 5945#ifdef _CS_LFS64_LIBS 5946 {"CS_LFS64_LIBS", _CS_LFS64_LIBS}, 5947#endif 5948#ifdef _CS_LFS64_LINTFLAGS 5949 {"CS_LFS64_LINTFLAGS", _CS_LFS64_LINTFLAGS}, 5950#endif 5951#ifdef _CS_LFS_CFLAGS 5952 {"CS_LFS_CFLAGS", _CS_LFS_CFLAGS}, 5953#endif 5954#ifdef _CS_LFS_LDFLAGS 5955 {"CS_LFS_LDFLAGS", _CS_LFS_LDFLAGS}, 5956#endif 5957#ifdef _CS_LFS_LIBS 5958 {"CS_LFS_LIBS", _CS_LFS_LIBS}, 5959#endif 5960#ifdef _CS_LFS_LINTFLAGS 5961 {"CS_LFS_LINTFLAGS", _CS_LFS_LINTFLAGS}, 5962#endif 5963#ifdef _CS_MACHINE 5964 {"CS_MACHINE", _CS_MACHINE}, 5965#endif 5966#ifdef _CS_PATH 5967 {"CS_PATH", _CS_PATH}, 5968#endif 5969#ifdef _CS_RELEASE 5970 {"CS_RELEASE", _CS_RELEASE}, 5971#endif 5972#ifdef _CS_SRPC_DOMAIN 5973 {"CS_SRPC_DOMAIN", _CS_SRPC_DOMAIN}, 5974#endif 5975#ifdef _CS_SYSNAME 5976 {"CS_SYSNAME", _CS_SYSNAME}, 5977#endif 5978#ifdef _CS_VERSION 5979 {"CS_VERSION", _CS_VERSION}, 5980#endif 5981#ifdef _CS_XBS5_ILP32_OFF32_CFLAGS 5982 {"CS_XBS5_ILP32_OFF32_CFLAGS", _CS_XBS5_ILP32_OFF32_CFLAGS}, 5983#endif 5984#ifdef _CS_XBS5_ILP32_OFF32_LDFLAGS 5985 {"CS_XBS5_ILP32_OFF32_LDFLAGS", _CS_XBS5_ILP32_OFF32_LDFLAGS}, 5986#endif 5987#ifdef _CS_XBS5_ILP32_OFF32_LIBS 5988 {"CS_XBS5_ILP32_OFF32_LIBS", _CS_XBS5_ILP32_OFF32_LIBS}, 5989#endif 5990#ifdef _CS_XBS5_ILP32_OFF32_LINTFLAGS 5991 {"CS_XBS5_ILP32_OFF32_LINTFLAGS", _CS_XBS5_ILP32_OFF32_LINTFLAGS}, 5992#endif 5993#ifdef _CS_XBS5_ILP32_OFFBIG_CFLAGS 5994 {"CS_XBS5_ILP32_OFFBIG_CFLAGS", _CS_XBS5_ILP32_OFFBIG_CFLAGS}, 5995#endif 5996#ifdef _CS_XBS5_ILP32_OFFBIG_LDFLAGS 5997 {"CS_XBS5_ILP32_OFFBIG_LDFLAGS", _CS_XBS5_ILP32_OFFBIG_LDFLAGS}, 5998#endif 5999#ifdef _CS_XBS5_ILP32_OFFBIG_LIBS 6000 {"CS_XBS5_ILP32_OFFBIG_LIBS", _CS_XBS5_ILP32_OFFBIG_LIBS}, 6001#endif 6002#ifdef _CS_XBS5_ILP32_OFFBIG_LINTFLAGS 6003 {"CS_XBS5_ILP32_OFFBIG_LINTFLAGS", _CS_XBS5_ILP32_OFFBIG_LINTFLAGS}, 6004#endif 6005#ifdef _CS_XBS5_LP64_OFF64_CFLAGS 6006 {"CS_XBS5_LP64_OFF64_CFLAGS", _CS_XBS5_LP64_OFF64_CFLAGS}, 6007#endif 6008#ifdef _CS_XBS5_LP64_OFF64_LDFLAGS 6009 {"CS_XBS5_LP64_OFF64_LDFLAGS", _CS_XBS5_LP64_OFF64_LDFLAGS}, 6010#endif 6011#ifdef _CS_XBS5_LP64_OFF64_LIBS 6012 {"CS_XBS5_LP64_OFF64_LIBS", _CS_XBS5_LP64_OFF64_LIBS}, 6013#endif 6014#ifdef _CS_XBS5_LP64_OFF64_LINTFLAGS 6015 {"CS_XBS5_LP64_OFF64_LINTFLAGS", _CS_XBS5_LP64_OFF64_LINTFLAGS}, 6016#endif 6017#ifdef _CS_XBS5_LPBIG_OFFBIG_CFLAGS 6018 {"CS_XBS5_LPBIG_OFFBIG_CFLAGS", _CS_XBS5_LPBIG_OFFBIG_CFLAGS}, 6019#endif 6020#ifdef _CS_XBS5_LPBIG_OFFBIG_LDFLAGS 6021 {"CS_XBS5_LPBIG_OFFBIG_LDFLAGS", _CS_XBS5_LPBIG_OFFBIG_LDFLAGS}, 6022#endif 6023#ifdef _CS_XBS5_LPBIG_OFFBIG_LIBS 6024 {"CS_XBS5_LPBIG_OFFBIG_LIBS", _CS_XBS5_LPBIG_OFFBIG_LIBS}, 6025#endif 6026#ifdef _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS 6027 {"CS_XBS5_LPBIG_OFFBIG_LINTFLAGS", _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS}, 6028#endif 6029#ifdef _MIPS_CS_AVAIL_PROCESSORS 6030 {"MIPS_CS_AVAIL_PROCESSORS", _MIPS_CS_AVAIL_PROCESSORS}, 6031#endif 6032#ifdef _MIPS_CS_BASE 6033 {"MIPS_CS_BASE", _MIPS_CS_BASE}, 6034#endif 6035#ifdef _MIPS_CS_HOSTID 6036 {"MIPS_CS_HOSTID", _MIPS_CS_HOSTID}, 6037#endif 6038#ifdef _MIPS_CS_HW_NAME 6039 {"MIPS_CS_HW_NAME", _MIPS_CS_HW_NAME}, 6040#endif 6041#ifdef _MIPS_CS_NUM_PROCESSORS 6042 {"MIPS_CS_NUM_PROCESSORS", _MIPS_CS_NUM_PROCESSORS}, 6043#endif 6044#ifdef _MIPS_CS_OSREL_MAJ 6045 {"MIPS_CS_OSREL_MAJ", _MIPS_CS_OSREL_MAJ}, 6046#endif 6047#ifdef _MIPS_CS_OSREL_MIN 6048 {"MIPS_CS_OSREL_MIN", _MIPS_CS_OSREL_MIN}, 6049#endif 6050#ifdef _MIPS_CS_OSREL_PATCH 6051 {"MIPS_CS_OSREL_PATCH", _MIPS_CS_OSREL_PATCH}, 6052#endif 6053#ifdef _MIPS_CS_OS_NAME 6054 {"MIPS_CS_OS_NAME", _MIPS_CS_OS_NAME}, 6055#endif 6056#ifdef _MIPS_CS_OS_PROVIDER 6057 {"MIPS_CS_OS_PROVIDER", _MIPS_CS_OS_PROVIDER}, 6058#endif 6059#ifdef _MIPS_CS_PROCESSORS 6060 {"MIPS_CS_PROCESSORS", _MIPS_CS_PROCESSORS}, 6061#endif 6062#ifdef _MIPS_CS_SERIAL 6063 {"MIPS_CS_SERIAL", _MIPS_CS_SERIAL}, 6064#endif 6065#ifdef _MIPS_CS_VENDOR 6066 {"MIPS_CS_VENDOR", _MIPS_CS_VENDOR}, 6067#endif 6068}; 6069 6070static int 6071conv_confstr_confname(PyObject *arg, int *valuep) 6072{ 6073 return conv_confname(arg, valuep, posix_constants_confstr, 6074 sizeof(posix_constants_confstr) 6075 / sizeof(struct constdef)); 6076} 6077 6078PyDoc_STRVAR(posix_confstr__doc__, 6079"confstr(name) -> string\n\n\ 6080Return a string-valued system configuration variable."); 6081 6082static PyObject * 6083posix_confstr(PyObject *self, PyObject *args) 6084{ 6085 PyObject *result = NULL; 6086 int name; 6087 char buffer[64]; 6088 6089 if (PyArg_ParseTuple(args, "O&:confstr", conv_confstr_confname, &name)) { 6090 int len = confstr(name, buffer, sizeof(buffer)); 6091 6092 errno = 0; 6093 if (len == 0) { 6094 if (errno != 0) 6095 posix_error(); 6096 else 6097 result = PyString_FromString(""); 6098 } 6099 else { 6100 if (len >= sizeof(buffer)) { 6101 result = PyString_FromStringAndSize(NULL, len); 6102 if (result != NULL) 6103 confstr(name, PyString_AS_STRING(result), len+1); 6104 } 6105 else 6106 result = PyString_FromString(buffer); 6107 } 6108 } 6109 return result; 6110} 6111#endif 6112 6113 6114#ifdef HAVE_SYSCONF 6115static struct constdef posix_constants_sysconf[] = { 6116#ifdef _SC_2_CHAR_TERM 6117 {"SC_2_CHAR_TERM", _SC_2_CHAR_TERM}, 6118#endif 6119#ifdef _SC_2_C_BIND 6120 {"SC_2_C_BIND", _SC_2_C_BIND}, 6121#endif 6122#ifdef _SC_2_C_DEV 6123 {"SC_2_C_DEV", _SC_2_C_DEV}, 6124#endif 6125#ifdef _SC_2_C_VERSION 6126 {"SC_2_C_VERSION", _SC_2_C_VERSION}, 6127#endif 6128#ifdef _SC_2_FORT_DEV 6129 {"SC_2_FORT_DEV", _SC_2_FORT_DEV}, 6130#endif 6131#ifdef _SC_2_FORT_RUN 6132 {"SC_2_FORT_RUN", _SC_2_FORT_RUN}, 6133#endif 6134#ifdef _SC_2_LOCALEDEF 6135 {"SC_2_LOCALEDEF", _SC_2_LOCALEDEF}, 6136#endif 6137#ifdef _SC_2_SW_DEV 6138 {"SC_2_SW_DEV", _SC_2_SW_DEV}, 6139#endif 6140#ifdef _SC_2_UPE 6141 {"SC_2_UPE", _SC_2_UPE}, 6142#endif 6143#ifdef _SC_2_VERSION 6144 {"SC_2_VERSION", _SC_2_VERSION}, 6145#endif 6146#ifdef _SC_ABI_ASYNCHRONOUS_IO 6147 {"SC_ABI_ASYNCHRONOUS_IO", _SC_ABI_ASYNCHRONOUS_IO}, 6148#endif 6149#ifdef _SC_ACL 6150 {"SC_ACL", _SC_ACL}, 6151#endif 6152#ifdef _SC_AIO_LISTIO_MAX 6153 {"SC_AIO_LISTIO_MAX", _SC_AIO_LISTIO_MAX}, 6154#endif 6155#ifdef _SC_AIO_MAX 6156 {"SC_AIO_MAX", _SC_AIO_MAX}, 6157#endif 6158#ifdef _SC_AIO_PRIO_DELTA_MAX 6159 {"SC_AIO_PRIO_DELTA_MAX", _SC_AIO_PRIO_DELTA_MAX}, 6160#endif 6161#ifdef _SC_ARG_MAX 6162 {"SC_ARG_MAX", _SC_ARG_MAX}, 6163#endif 6164#ifdef _SC_ASYNCHRONOUS_IO 6165 {"SC_ASYNCHRONOUS_IO", _SC_ASYNCHRONOUS_IO}, 6166#endif 6167#ifdef _SC_ATEXIT_MAX 6168 {"SC_ATEXIT_MAX", _SC_ATEXIT_MAX}, 6169#endif 6170#ifdef _SC_AUDIT 6171 {"SC_AUDIT", _SC_AUDIT}, 6172#endif 6173#ifdef _SC_AVPHYS_PAGES 6174 {"SC_AVPHYS_PAGES", _SC_AVPHYS_PAGES}, 6175#endif 6176#ifdef _SC_BC_BASE_MAX 6177 {"SC_BC_BASE_MAX", _SC_BC_BASE_MAX}, 6178#endif 6179#ifdef _SC_BC_DIM_MAX 6180 {"SC_BC_DIM_MAX", _SC_BC_DIM_MAX}, 6181#endif 6182#ifdef _SC_BC_SCALE_MAX 6183 {"SC_BC_SCALE_MAX", _SC_BC_SCALE_MAX}, 6184#endif 6185#ifdef _SC_BC_STRING_MAX 6186 {"SC_BC_STRING_MAX", _SC_BC_STRING_MAX}, 6187#endif 6188#ifdef _SC_CAP 6189 {"SC_CAP", _SC_CAP}, 6190#endif 6191#ifdef _SC_CHARCLASS_NAME_MAX 6192 {"SC_CHARCLASS_NAME_MAX", _SC_CHARCLASS_NAME_MAX}, 6193#endif 6194#ifdef _SC_CHAR_BIT 6195 {"SC_CHAR_BIT", _SC_CHAR_BIT}, 6196#endif 6197#ifdef _SC_CHAR_MAX 6198 {"SC_CHAR_MAX", _SC_CHAR_MAX}, 6199#endif 6200#ifdef _SC_CHAR_MIN 6201 {"SC_CHAR_MIN", _SC_CHAR_MIN}, 6202#endif 6203#ifdef _SC_CHILD_MAX 6204 {"SC_CHILD_MAX", _SC_CHILD_MAX}, 6205#endif 6206#ifdef _SC_CLK_TCK 6207 {"SC_CLK_TCK", _SC_CLK_TCK}, 6208#endif 6209#ifdef _SC_COHER_BLKSZ 6210 {"SC_COHER_BLKSZ", _SC_COHER_BLKSZ}, 6211#endif 6212#ifdef _SC_COLL_WEIGHTS_MAX 6213 {"SC_COLL_WEIGHTS_MAX", _SC_COLL_WEIGHTS_MAX}, 6214#endif 6215#ifdef _SC_DCACHE_ASSOC 6216 {"SC_DCACHE_ASSOC", _SC_DCACHE_ASSOC}, 6217#endif 6218#ifdef _SC_DCACHE_BLKSZ 6219 {"SC_DCACHE_BLKSZ", _SC_DCACHE_BLKSZ}, 6220#endif 6221#ifdef _SC_DCACHE_LINESZ 6222 {"SC_DCACHE_LINESZ", _SC_DCACHE_LINESZ}, 6223#endif 6224#ifdef _SC_DCACHE_SZ 6225 {"SC_DCACHE_SZ", _SC_DCACHE_SZ}, 6226#endif 6227#ifdef _SC_DCACHE_TBLKSZ 6228 {"SC_DCACHE_TBLKSZ", _SC_DCACHE_TBLKSZ}, 6229#endif 6230#ifdef _SC_DELAYTIMER_MAX 6231 {"SC_DELAYTIMER_MAX", _SC_DELAYTIMER_MAX}, 6232#endif 6233#ifdef _SC_EQUIV_CLASS_MAX 6234 {"SC_EQUIV_CLASS_MAX", _SC_EQUIV_CLASS_MAX}, 6235#endif 6236#ifdef _SC_EXPR_NEST_MAX 6237 {"SC_EXPR_NEST_MAX", _SC_EXPR_NEST_MAX}, 6238#endif 6239#ifdef _SC_FSYNC 6240 {"SC_FSYNC", _SC_FSYNC}, 6241#endif 6242#ifdef _SC_GETGR_R_SIZE_MAX 6243 {"SC_GETGR_R_SIZE_MAX", _SC_GETGR_R_SIZE_MAX}, 6244#endif 6245#ifdef _SC_GETPW_R_SIZE_MAX 6246 {"SC_GETPW_R_SIZE_MAX", _SC_GETPW_R_SIZE_MAX}, 6247#endif 6248#ifdef _SC_ICACHE_ASSOC 6249 {"SC_ICACHE_ASSOC", _SC_ICACHE_ASSOC}, 6250#endif 6251#ifdef _SC_ICACHE_BLKSZ 6252 {"SC_ICACHE_BLKSZ", _SC_ICACHE_BLKSZ}, 6253#endif 6254#ifdef _SC_ICACHE_LINESZ 6255 {"SC_ICACHE_LINESZ", _SC_ICACHE_LINESZ}, 6256#endif 6257#ifdef _SC_ICACHE_SZ 6258 {"SC_ICACHE_SZ", _SC_ICACHE_SZ}, 6259#endif 6260#ifdef _SC_INF 6261 {"SC_INF", _SC_INF}, 6262#endif 6263#ifdef _SC_INT_MAX 6264 {"SC_INT_MAX", _SC_INT_MAX}, 6265#endif 6266#ifdef _SC_INT_MIN 6267 {"SC_INT_MIN", _SC_INT_MIN}, 6268#endif 6269#ifdef _SC_IOV_MAX 6270 {"SC_IOV_MAX", _SC_IOV_MAX}, 6271#endif 6272#ifdef _SC_IP_SECOPTS 6273 {"SC_IP_SECOPTS", _SC_IP_SECOPTS}, 6274#endif 6275#ifdef _SC_JOB_CONTROL 6276 {"SC_JOB_CONTROL", _SC_JOB_CONTROL}, 6277#endif 6278#ifdef _SC_KERN_POINTERS 6279 {"SC_KERN_POINTERS", _SC_KERN_POINTERS}, 6280#endif 6281#ifdef _SC_KERN_SIM 6282 {"SC_KERN_SIM", _SC_KERN_SIM}, 6283#endif 6284#ifdef _SC_LINE_MAX 6285 {"SC_LINE_MAX", _SC_LINE_MAX}, 6286#endif 6287#ifdef _SC_LOGIN_NAME_MAX 6288 {"SC_LOGIN_NAME_MAX", _SC_LOGIN_NAME_MAX}, 6289#endif 6290#ifdef _SC_LOGNAME_MAX 6291 {"SC_LOGNAME_MAX", _SC_LOGNAME_MAX}, 6292#endif 6293#ifdef _SC_LONG_BIT 6294 {"SC_LONG_BIT", _SC_LONG_BIT}, 6295#endif 6296#ifdef _SC_MAC 6297 {"SC_MAC", _SC_MAC}, 6298#endif 6299#ifdef _SC_MAPPED_FILES 6300 {"SC_MAPPED_FILES", _SC_MAPPED_FILES}, 6301#endif 6302#ifdef _SC_MAXPID 6303 {"SC_MAXPID", _SC_MAXPID}, 6304#endif 6305#ifdef _SC_MB_LEN_MAX 6306 {"SC_MB_LEN_MAX", _SC_MB_LEN_MAX}, 6307#endif 6308#ifdef _SC_MEMLOCK 6309 {"SC_MEMLOCK", _SC_MEMLOCK}, 6310#endif 6311#ifdef _SC_MEMLOCK_RANGE 6312 {"SC_MEMLOCK_RANGE", _SC_MEMLOCK_RANGE}, 6313#endif 6314#ifdef _SC_MEMORY_PROTECTION 6315 {"SC_MEMORY_PROTECTION", _SC_MEMORY_PROTECTION}, 6316#endif 6317#ifdef _SC_MESSAGE_PASSING 6318 {"SC_MESSAGE_PASSING", _SC_MESSAGE_PASSING}, 6319#endif 6320#ifdef _SC_MMAP_FIXED_ALIGNMENT 6321 {"SC_MMAP_FIXED_ALIGNMENT", _SC_MMAP_FIXED_ALIGNMENT}, 6322#endif 6323#ifdef _SC_MQ_OPEN_MAX 6324 {"SC_MQ_OPEN_MAX", _SC_MQ_OPEN_MAX}, 6325#endif 6326#ifdef _SC_MQ_PRIO_MAX 6327 {"SC_MQ_PRIO_MAX", _SC_MQ_PRIO_MAX}, 6328#endif 6329#ifdef _SC_NACLS_MAX 6330 {"SC_NACLS_MAX", _SC_NACLS_MAX}, 6331#endif 6332#ifdef _SC_NGROUPS_MAX 6333 {"SC_NGROUPS_MAX", _SC_NGROUPS_MAX}, 6334#endif 6335#ifdef _SC_NL_ARGMAX 6336 {"SC_NL_ARGMAX", _SC_NL_ARGMAX}, 6337#endif 6338#ifdef _SC_NL_LANGMAX 6339 {"SC_NL_LANGMAX", _SC_NL_LANGMAX}, 6340#endif 6341#ifdef _SC_NL_MSGMAX 6342 {"SC_NL_MSGMAX", _SC_NL_MSGMAX}, 6343#endif 6344#ifdef _SC_NL_NMAX 6345 {"SC_NL_NMAX", _SC_NL_NMAX}, 6346#endif 6347#ifdef _SC_NL_SETMAX 6348 {"SC_NL_SETMAX", _SC_NL_SETMAX}, 6349#endif 6350#ifdef _SC_NL_TEXTMAX 6351 {"SC_NL_TEXTMAX", _SC_NL_TEXTMAX}, 6352#endif 6353#ifdef _SC_NPROCESSORS_CONF 6354 {"SC_NPROCESSORS_CONF", _SC_NPROCESSORS_CONF}, 6355#endif 6356#ifdef _SC_NPROCESSORS_ONLN 6357 {"SC_NPROCESSORS_ONLN", _SC_NPROCESSORS_ONLN}, 6358#endif 6359#ifdef _SC_NPROC_CONF 6360 {"SC_NPROC_CONF", _SC_NPROC_CONF}, 6361#endif 6362#ifdef _SC_NPROC_ONLN 6363 {"SC_NPROC_ONLN", _SC_NPROC_ONLN}, 6364#endif 6365#ifdef _SC_NZERO 6366 {"SC_NZERO", _SC_NZERO}, 6367#endif 6368#ifdef _SC_OPEN_MAX 6369 {"SC_OPEN_MAX", _SC_OPEN_MAX}, 6370#endif 6371#ifdef _SC_PAGESIZE 6372 {"SC_PAGESIZE", _SC_PAGESIZE}, 6373#endif 6374#ifdef _SC_PAGE_SIZE 6375 {"SC_PAGE_SIZE", _SC_PAGE_SIZE}, 6376#endif 6377#ifdef _SC_PASS_MAX 6378 {"SC_PASS_MAX", _SC_PASS_MAX}, 6379#endif 6380#ifdef _SC_PHYS_PAGES 6381 {"SC_PHYS_PAGES", _SC_PHYS_PAGES}, 6382#endif 6383#ifdef _SC_PII 6384 {"SC_PII", _SC_PII}, 6385#endif 6386#ifdef _SC_PII_INTERNET 6387 {"SC_PII_INTERNET", _SC_PII_INTERNET}, 6388#endif 6389#ifdef _SC_PII_INTERNET_DGRAM 6390 {"SC_PII_INTERNET_DGRAM", _SC_PII_INTERNET_DGRAM}, 6391#endif 6392#ifdef _SC_PII_INTERNET_STREAM 6393 {"SC_PII_INTERNET_STREAM", _SC_PII_INTERNET_STREAM}, 6394#endif 6395#ifdef _SC_PII_OSI 6396 {"SC_PII_OSI", _SC_PII_OSI}, 6397#endif 6398#ifdef _SC_PII_OSI_CLTS 6399 {"SC_PII_OSI_CLTS", _SC_PII_OSI_CLTS}, 6400#endif 6401#ifdef _SC_PII_OSI_COTS 6402 {"SC_PII_OSI_COTS", _SC_PII_OSI_COTS}, 6403#endif 6404#ifdef _SC_PII_OSI_M 6405 {"SC_PII_OSI_M", _SC_PII_OSI_M}, 6406#endif 6407#ifdef _SC_PII_SOCKET 6408 {"SC_PII_SOCKET", _SC_PII_SOCKET}, 6409#endif 6410#ifdef _SC_PII_XTI 6411 {"SC_PII_XTI", _SC_PII_XTI}, 6412#endif 6413#ifdef _SC_POLL 6414 {"SC_POLL", _SC_POLL}, 6415#endif 6416#ifdef _SC_PRIORITIZED_IO 6417 {"SC_PRIORITIZED_IO", _SC_PRIORITIZED_IO}, 6418#endif 6419#ifdef _SC_PRIORITY_SCHEDULING 6420 {"SC_PRIORITY_SCHEDULING", _SC_PRIORITY_SCHEDULING}, 6421#endif 6422#ifdef _SC_REALTIME_SIGNALS 6423 {"SC_REALTIME_SIGNALS", _SC_REALTIME_SIGNALS}, 6424#endif 6425#ifdef _SC_RE_DUP_MAX 6426 {"SC_RE_DUP_MAX", _SC_RE_DUP_MAX}, 6427#endif 6428#ifdef _SC_RTSIG_MAX 6429 {"SC_RTSIG_MAX", _SC_RTSIG_MAX}, 6430#endif 6431#ifdef _SC_SAVED_IDS 6432 {"SC_SAVED_IDS", _SC_SAVED_IDS}, 6433#endif 6434#ifdef _SC_SCHAR_MAX 6435 {"SC_SCHAR_MAX", _SC_SCHAR_MAX}, 6436#endif 6437#ifdef _SC_SCHAR_MIN 6438 {"SC_SCHAR_MIN", _SC_SCHAR_MIN}, 6439#endif 6440#ifdef _SC_SELECT 6441 {"SC_SELECT", _SC_SELECT}, 6442#endif 6443#ifdef _SC_SEMAPHORES 6444 {"SC_SEMAPHORES", _SC_SEMAPHORES}, 6445#endif 6446#ifdef _SC_SEM_NSEMS_MAX 6447 {"SC_SEM_NSEMS_MAX", _SC_SEM_NSEMS_MAX}, 6448#endif 6449#ifdef _SC_SEM_VALUE_MAX 6450 {"SC_SEM_VALUE_MAX", _SC_SEM_VALUE_MAX}, 6451#endif 6452#ifdef _SC_SHARED_MEMORY_OBJECTS 6453 {"SC_SHARED_MEMORY_OBJECTS", _SC_SHARED_MEMORY_OBJECTS}, 6454#endif 6455#ifdef _SC_SHRT_MAX 6456 {"SC_SHRT_MAX", _SC_SHRT_MAX}, 6457#endif 6458#ifdef _SC_SHRT_MIN 6459 {"SC_SHRT_MIN", _SC_SHRT_MIN}, 6460#endif 6461#ifdef _SC_SIGQUEUE_MAX 6462 {"SC_SIGQUEUE_MAX", _SC_SIGQUEUE_MAX}, 6463#endif 6464#ifdef _SC_SIGRT_MAX 6465 {"SC_SIGRT_MAX", _SC_SIGRT_MAX}, 6466#endif 6467#ifdef _SC_SIGRT_MIN 6468 {"SC_SIGRT_MIN", _SC_SIGRT_MIN}, 6469#endif 6470#ifdef _SC_SOFTPOWER 6471 {"SC_SOFTPOWER", _SC_SOFTPOWER}, 6472#endif 6473#ifdef _SC_SPLIT_CACHE 6474 {"SC_SPLIT_CACHE", _SC_SPLIT_CACHE}, 6475#endif 6476#ifdef _SC_SSIZE_MAX 6477 {"SC_SSIZE_MAX", _SC_SSIZE_MAX}, 6478#endif 6479#ifdef _SC_STACK_PROT 6480 {"SC_STACK_PROT", _SC_STACK_PROT}, 6481#endif 6482#ifdef _SC_STREAM_MAX 6483 {"SC_STREAM_MAX", _SC_STREAM_MAX}, 6484#endif 6485#ifdef _SC_SYNCHRONIZED_IO 6486 {"SC_SYNCHRONIZED_IO", _SC_SYNCHRONIZED_IO}, 6487#endif 6488#ifdef _SC_THREADS 6489 {"SC_THREADS", _SC_THREADS}, 6490#endif 6491#ifdef _SC_THREAD_ATTR_STACKADDR 6492 {"SC_THREAD_ATTR_STACKADDR", _SC_THREAD_ATTR_STACKADDR}, 6493#endif 6494#ifdef _SC_THREAD_ATTR_STACKSIZE 6495 {"SC_THREAD_ATTR_STACKSIZE", _SC_THREAD_ATTR_STACKSIZE}, 6496#endif 6497#ifdef _SC_THREAD_DESTRUCTOR_ITERATIONS 6498 {"SC_THREAD_DESTRUCTOR_ITERATIONS", _SC_THREAD_DESTRUCTOR_ITERATIONS}, 6499#endif 6500#ifdef _SC_THREAD_KEYS_MAX 6501 {"SC_THREAD_KEYS_MAX", _SC_THREAD_KEYS_MAX}, 6502#endif 6503#ifdef _SC_THREAD_PRIORITY_SCHEDULING 6504 {"SC_THREAD_PRIORITY_SCHEDULING", _SC_THREAD_PRIORITY_SCHEDULING}, 6505#endif 6506#ifdef _SC_THREAD_PRIO_INHERIT 6507 {"SC_THREAD_PRIO_INHERIT", _SC_THREAD_PRIO_INHERIT}, 6508#endif 6509#ifdef _SC_THREAD_PRIO_PROTECT 6510 {"SC_THREAD_PRIO_PROTECT", _SC_THREAD_PRIO_PROTECT}, 6511#endif 6512#ifdef _SC_THREAD_PROCESS_SHARED 6513 {"SC_THREAD_PROCESS_SHARED", _SC_THREAD_PROCESS_SHARED}, 6514#endif 6515#ifdef _SC_THREAD_SAFE_FUNCTIONS 6516 {"SC_THREAD_SAFE_FUNCTIONS", _SC_THREAD_SAFE_FUNCTIONS}, 6517#endif 6518#ifdef _SC_THREAD_STACK_MIN 6519 {"SC_THREAD_STACK_MIN", _SC_THREAD_STACK_MIN}, 6520#endif 6521#ifdef _SC_THREAD_THREADS_MAX 6522 {"SC_THREAD_THREADS_MAX", _SC_THREAD_THREADS_MAX}, 6523#endif 6524#ifdef _SC_TIMERS 6525 {"SC_TIMERS", _SC_TIMERS}, 6526#endif 6527#ifdef _SC_TIMER_MAX 6528 {"SC_TIMER_MAX", _SC_TIMER_MAX}, 6529#endif 6530#ifdef _SC_TTY_NAME_MAX 6531 {"SC_TTY_NAME_MAX", _SC_TTY_NAME_MAX}, 6532#endif 6533#ifdef _SC_TZNAME_MAX 6534 {"SC_TZNAME_MAX", _SC_TZNAME_MAX}, 6535#endif 6536#ifdef _SC_T_IOV_MAX 6537 {"SC_T_IOV_MAX", _SC_T_IOV_MAX}, 6538#endif 6539#ifdef _SC_UCHAR_MAX 6540 {"SC_UCHAR_MAX", _SC_UCHAR_MAX}, 6541#endif 6542#ifdef _SC_UINT_MAX 6543 {"SC_UINT_MAX", _SC_UINT_MAX}, 6544#endif 6545#ifdef _SC_UIO_MAXIOV 6546 {"SC_UIO_MAXIOV", _SC_UIO_MAXIOV}, 6547#endif 6548#ifdef _SC_ULONG_MAX 6549 {"SC_ULONG_MAX", _SC_ULONG_MAX}, 6550#endif 6551#ifdef _SC_USHRT_MAX 6552 {"SC_USHRT_MAX", _SC_USHRT_MAX}, 6553#endif 6554#ifdef _SC_VERSION 6555 {"SC_VERSION", _SC_VERSION}, 6556#endif 6557#ifdef _SC_WORD_BIT 6558 {"SC_WORD_BIT", _SC_WORD_BIT}, 6559#endif 6560#ifdef _SC_XBS5_ILP32_OFF32 6561 {"SC_XBS5_ILP32_OFF32", _SC_XBS5_ILP32_OFF32}, 6562#endif 6563#ifdef _SC_XBS5_ILP32_OFFBIG 6564 {"SC_XBS5_ILP32_OFFBIG", _SC_XBS5_ILP32_OFFBIG}, 6565#endif 6566#ifdef _SC_XBS5_LP64_OFF64 6567 {"SC_XBS5_LP64_OFF64", _SC_XBS5_LP64_OFF64}, 6568#endif 6569#ifdef _SC_XBS5_LPBIG_OFFBIG 6570 {"SC_XBS5_LPBIG_OFFBIG", _SC_XBS5_LPBIG_OFFBIG}, 6571#endif 6572#ifdef _SC_XOPEN_CRYPT 6573 {"SC_XOPEN_CRYPT", _SC_XOPEN_CRYPT}, 6574#endif 6575#ifdef _SC_XOPEN_ENH_I18N 6576 {"SC_XOPEN_ENH_I18N", _SC_XOPEN_ENH_I18N}, 6577#endif 6578#ifdef _SC_XOPEN_LEGACY 6579 {"SC_XOPEN_LEGACY", _SC_XOPEN_LEGACY}, 6580#endif 6581#ifdef _SC_XOPEN_REALTIME 6582 {"SC_XOPEN_REALTIME", _SC_XOPEN_REALTIME}, 6583#endif 6584#ifdef _SC_XOPEN_REALTIME_THREADS 6585 {"SC_XOPEN_REALTIME_THREADS", _SC_XOPEN_REALTIME_THREADS}, 6586#endif 6587#ifdef _SC_XOPEN_SHM 6588 {"SC_XOPEN_SHM", _SC_XOPEN_SHM}, 6589#endif 6590#ifdef _SC_XOPEN_UNIX 6591 {"SC_XOPEN_UNIX", _SC_XOPEN_UNIX}, 6592#endif 6593#ifdef _SC_XOPEN_VERSION 6594 {"SC_XOPEN_VERSION", _SC_XOPEN_VERSION}, 6595#endif 6596#ifdef _SC_XOPEN_XCU_VERSION 6597 {"SC_XOPEN_XCU_VERSION", _SC_XOPEN_XCU_VERSION}, 6598#endif 6599#ifdef _SC_XOPEN_XPG2 6600 {"SC_XOPEN_XPG2", _SC_XOPEN_XPG2}, 6601#endif 6602#ifdef _SC_XOPEN_XPG3 6603 {"SC_XOPEN_XPG3", _SC_XOPEN_XPG3}, 6604#endif 6605#ifdef _SC_XOPEN_XPG4 6606 {"SC_XOPEN_XPG4", _SC_XOPEN_XPG4}, 6607#endif 6608}; 6609 6610static int 6611conv_sysconf_confname(PyObject *arg, int *valuep) 6612{ 6613 return conv_confname(arg, valuep, posix_constants_sysconf, 6614 sizeof(posix_constants_sysconf) 6615 / sizeof(struct constdef)); 6616} 6617 6618PyDoc_STRVAR(posix_sysconf__doc__, 6619"sysconf(name) -> integer\n\n\ 6620Return an integer-valued system configuration variable."); 6621 6622static PyObject * 6623posix_sysconf(PyObject *self, PyObject *args) 6624{ 6625 PyObject *result = NULL; 6626 int name; 6627 6628 if (PyArg_ParseTuple(args, "O&:sysconf", conv_sysconf_confname, &name)) { 6629 int value; 6630 6631 errno = 0; 6632 value = sysconf(name); 6633 if (value == -1 && errno != 0) 6634 posix_error(); 6635 else 6636 result = PyInt_FromLong(value); 6637 } 6638 return result; 6639} 6640#endif 6641 6642 6643/* This code is used to ensure that the tables of configuration value names 6644 * are in sorted order as required by conv_confname(), and also to build the 6645 * the exported dictionaries that are used to publish information about the 6646 * names available on the host platform. 6647 * 6648 * Sorting the table at runtime ensures that the table is properly ordered 6649 * when used, even for platforms we're not able to test on. It also makes 6650 * it easier to add additional entries to the tables. 6651 */ 6652 6653static int 6654cmp_constdefs(const void *v1, const void *v2) 6655{ 6656 const struct constdef *c1 = 6657 (const struct constdef *) v1; 6658 const struct constdef *c2 = 6659 (const struct constdef *) v2; 6660 6661 return strcmp(c1->name, c2->name); 6662} 6663 6664static int 6665setup_confname_table(struct constdef *table, size_t tablesize, 6666 char *tablename, PyObject *module) 6667{ 6668 PyObject *d = NULL; 6669 size_t i; 6670 6671 qsort(table, tablesize, sizeof(struct constdef), cmp_constdefs); 6672 d = PyDict_New(); 6673 if (d == NULL) 6674 return -1; 6675 6676 for (i=0; i < tablesize; ++i) { 6677 PyObject *o = PyInt_FromLong(table[i].value); 6678 if (o == NULL || PyDict_SetItemString(d, table[i].name, o) == -1) { 6679 Py_XDECREF(o); 6680 Py_DECREF(d); 6681 return -1; 6682 } 6683 Py_DECREF(o); 6684 } 6685 return PyModule_AddObject(module, tablename, d); 6686} 6687 6688/* Return -1 on failure, 0 on success. */ 6689static int 6690setup_confname_tables(PyObject *module) 6691{ 6692#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF) 6693 if (setup_confname_table(posix_constants_pathconf, 6694 sizeof(posix_constants_pathconf) 6695 / sizeof(struct constdef), 6696 "pathconf_names", module)) 6697 return -1; 6698#endif 6699#ifdef HAVE_CONFSTR 6700 if (setup_confname_table(posix_constants_confstr, 6701 sizeof(posix_constants_confstr) 6702 / sizeof(struct constdef), 6703 "confstr_names", module)) 6704 return -1; 6705#endif 6706#ifdef HAVE_SYSCONF 6707 if (setup_confname_table(posix_constants_sysconf, 6708 sizeof(posix_constants_sysconf) 6709 / sizeof(struct constdef), 6710 "sysconf_names", module)) 6711 return -1; 6712#endif 6713 return 0; 6714} 6715 6716 6717PyDoc_STRVAR(posix_abort__doc__, 6718"abort() -> does not return!\n\n\ 6719Abort the interpreter immediately. This 'dumps core' or otherwise fails\n\ 6720in the hardest way possible on the hosting operating system."); 6721 6722static PyObject * 6723posix_abort(PyObject *self, PyObject *args) 6724{ 6725 if (!PyArg_ParseTuple(args, ":abort")) 6726 return NULL; 6727 abort(); 6728 /*NOTREACHED*/ 6729 Py_FatalError("abort() called from Python code didn't abort!"); 6730 return NULL; 6731} 6732 6733#ifdef MS_WINDOWS 6734PyDoc_STRVAR(win32_startfile__doc__, 6735"startfile(filepath) - Start a file with its associated application.\n\ 6736\n\ 6737This acts like double-clicking the file in Explorer, or giving the file\n\ 6738name as an argument to the DOS \"start\" command: the file is opened\n\ 6739with whatever application (if any) its extension is associated.\n\ 6740\n\ 6741startfile returns as soon as the associated application is launched.\n\ 6742There is no option to wait for the application to close, and no way\n\ 6743to retrieve the application's exit status.\n\ 6744\n\ 6745The filepath is relative to the current directory. If you want to use\n\ 6746an absolute path, make sure the first character is not a slash (\"/\");\n\ 6747the underlying Win32 ShellExecute function doesn't work if it is."); 6748 6749static PyObject * 6750win32_startfile(PyObject *self, PyObject *args) 6751{ 6752 char *filepath; 6753 HINSTANCE rc; 6754 if (!PyArg_ParseTuple(args, "s:startfile", &filepath)) 6755 return NULL; 6756 Py_BEGIN_ALLOW_THREADS 6757 rc = ShellExecute((HWND)0, NULL, filepath, NULL, NULL, SW_SHOWNORMAL); 6758 Py_END_ALLOW_THREADS 6759 if (rc <= (HINSTANCE)32) 6760 return win32_error("startfile", filepath); 6761 Py_INCREF(Py_None); 6762 return Py_None; 6763} 6764#endif 6765 6766static PyMethodDef posix_methods[] = { 6767 {"access", posix_access, METH_VARARGS, posix_access__doc__}, 6768#ifdef HAVE_TTYNAME 6769 {"ttyname", posix_ttyname, METH_VARARGS, posix_ttyname__doc__}, 6770#endif 6771 {"chdir", posix_chdir, METH_VARARGS, posix_chdir__doc__}, 6772 {"chmod", posix_chmod, METH_VARARGS, posix_chmod__doc__}, 6773#ifdef HAVE_CHOWN 6774 {"chown", posix_chown, METH_VARARGS, posix_chown__doc__}, 6775#endif /* HAVE_CHOWN */ 6776#ifdef HAVE_LCHOWN 6777 {"lchown", posix_lchown, METH_VARARGS, posix_lchown__doc__}, 6778#endif /* HAVE_LCHOWN */ 6779#ifdef HAVE_CHROOT 6780 {"chroot", posix_chroot, METH_VARARGS, posix_chroot__doc__}, 6781#endif 6782#ifdef HAVE_CTERMID 6783 {"ctermid", posix_ctermid, METH_VARARGS, posix_ctermid__doc__}, 6784#endif 6785#ifdef HAVE_GETCWD 6786 {"getcwd", posix_getcwd, METH_VARARGS, posix_getcwd__doc__}, 6787 {"getcwdu", posix_getcwdu, METH_VARARGS, posix_getcwdu__doc__}, 6788#endif 6789#ifdef HAVE_LINK 6790 {"link", posix_link, METH_VARARGS, posix_link__doc__}, 6791#endif /* HAVE_LINK */ 6792 {"listdir", posix_listdir, METH_VARARGS, posix_listdir__doc__}, 6793 {"lstat", posix_lstat, METH_VARARGS, posix_lstat__doc__}, 6794 {"mkdir", posix_mkdir, METH_VARARGS, posix_mkdir__doc__}, 6795#ifdef HAVE_NICE 6796 {"nice", posix_nice, METH_VARARGS, posix_nice__doc__}, 6797#endif /* HAVE_NICE */ 6798#ifdef HAVE_READLINK 6799 {"readlink", posix_readlink, METH_VARARGS, posix_readlink__doc__}, 6800#endif /* HAVE_READLINK */ 6801 {"rename", posix_rename, METH_VARARGS, posix_rename__doc__}, 6802 {"rmdir", posix_rmdir, METH_VARARGS, posix_rmdir__doc__}, 6803 {"stat", posix_stat, METH_VARARGS, posix_stat__doc__}, 6804#ifdef HAVE_SYMLINK 6805 {"symlink", posix_symlink, METH_VARARGS, posix_symlink__doc__}, 6806#endif /* HAVE_SYMLINK */ 6807#ifdef HAVE_SYSTEM 6808 {"system", posix_system, METH_VARARGS, posix_system__doc__}, 6809#endif 6810 {"umask", posix_umask, METH_VARARGS, posix_umask__doc__}, 6811#ifdef HAVE_UNAME 6812 {"uname", posix_uname, METH_VARARGS, posix_uname__doc__}, 6813#endif /* HAVE_UNAME */ 6814 {"unlink", posix_unlink, METH_VARARGS, posix_unlink__doc__}, 6815 {"remove", posix_unlink, METH_VARARGS, posix_remove__doc__}, 6816 {"utime", posix_utime, METH_VARARGS, posix_utime__doc__}, 6817#ifdef HAVE_TIMES 6818 {"times", posix_times, METH_VARARGS, posix_times__doc__}, 6819#endif /* HAVE_TIMES */ 6820 {"_exit", posix__exit, METH_VARARGS, posix__exit__doc__}, 6821#ifdef HAVE_EXECV 6822 {"execv", posix_execv, METH_VARARGS, posix_execv__doc__}, 6823 {"execve", posix_execve, METH_VARARGS, posix_execve__doc__}, 6824#endif /* HAVE_EXECV */ 6825#ifdef HAVE_SPAWNV 6826 {"spawnv", posix_spawnv, METH_VARARGS, posix_spawnv__doc__}, 6827 {"spawnve", posix_spawnve, METH_VARARGS, posix_spawnve__doc__}, 6828#endif /* HAVE_SPAWNV */ 6829#ifdef HAVE_FORK1 6830 {"fork1", posix_fork1, METH_VARARGS, posix_fork1__doc__}, 6831#endif /* HAVE_FORK1 */ 6832#ifdef HAVE_FORK 6833 {"fork", posix_fork, METH_VARARGS, posix_fork__doc__}, 6834#endif /* HAVE_FORK */ 6835#if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) 6836 {"openpty", posix_openpty, METH_VARARGS, posix_openpty__doc__}, 6837#endif /* HAVE_OPENPTY || HAVE__GETPTY */ 6838#ifdef HAVE_FORKPTY 6839 {"forkpty", posix_forkpty, METH_VARARGS, posix_forkpty__doc__}, 6840#endif /* HAVE_FORKPTY */ 6841#ifdef HAVE_GETEGID 6842 {"getegid", posix_getegid, METH_VARARGS, posix_getegid__doc__}, 6843#endif /* HAVE_GETEGID */ 6844#ifdef HAVE_GETEUID 6845 {"geteuid", posix_geteuid, METH_VARARGS, posix_geteuid__doc__}, 6846#endif /* HAVE_GETEUID */ 6847#ifdef HAVE_GETGID 6848 {"getgid", posix_getgid, METH_VARARGS, posix_getgid__doc__}, 6849#endif /* HAVE_GETGID */ 6850#ifdef HAVE_GETGROUPS 6851 {"getgroups", posix_getgroups, METH_VARARGS, posix_getgroups__doc__}, 6852#endif 6853 {"getpid", posix_getpid, METH_VARARGS, posix_getpid__doc__}, 6854#ifdef HAVE_GETPGRP 6855 {"getpgrp", posix_getpgrp, METH_VARARGS, posix_getpgrp__doc__}, 6856#endif /* HAVE_GETPGRP */ 6857#ifdef HAVE_GETPPID 6858 {"getppid", posix_getppid, METH_VARARGS, posix_getppid__doc__}, 6859#endif /* HAVE_GETPPID */ 6860#ifdef HAVE_GETUID 6861 {"getuid", posix_getuid, METH_VARARGS, posix_getuid__doc__}, 6862#endif /* HAVE_GETUID */ 6863#ifdef HAVE_GETLOGIN 6864 {"getlogin", posix_getlogin, METH_VARARGS, posix_getlogin__doc__}, 6865#endif 6866#ifdef HAVE_KILL 6867 {"kill", posix_kill, METH_VARARGS, posix_kill__doc__}, 6868#endif /* HAVE_KILL */ 6869#ifdef HAVE_KILLPG 6870 {"killpg", posix_killpg, METH_VARARGS, posix_killpg__doc__}, 6871#endif /* HAVE_KILLPG */ 6872#ifdef HAVE_PLOCK 6873 {"plock", posix_plock, METH_VARARGS, posix_plock__doc__}, 6874#endif /* HAVE_PLOCK */ 6875#ifdef HAVE_POPEN 6876 {"popen", posix_popen, METH_VARARGS, posix_popen__doc__}, 6877#ifdef MS_WINDOWS 6878 {"popen2", win32_popen2, METH_VARARGS}, 6879 {"popen3", win32_popen3, METH_VARARGS}, 6880 {"popen4", win32_popen4, METH_VARARGS}, 6881 {"startfile", win32_startfile, METH_VARARGS, win32_startfile__doc__}, 6882#else 6883#if defined(PYOS_OS2) && defined(PYCC_GCC) 6884 {"popen2", os2emx_popen2, METH_VARARGS}, 6885 {"popen3", os2emx_popen3, METH_VARARGS}, 6886 {"popen4", os2emx_popen4, METH_VARARGS}, 6887#endif 6888#endif 6889#endif /* HAVE_POPEN */ 6890#ifdef HAVE_SETUID 6891 {"setuid", posix_setuid, METH_VARARGS, posix_setuid__doc__}, 6892#endif /* HAVE_SETUID */ 6893#ifdef HAVE_SETEUID 6894 {"seteuid", posix_seteuid, METH_VARARGS, posix_seteuid__doc__}, 6895#endif /* HAVE_SETEUID */ 6896#ifdef HAVE_SETEGID 6897 {"setegid", posix_setegid, METH_VARARGS, posix_setegid__doc__}, 6898#endif /* HAVE_SETEGID */ 6899#ifdef HAVE_SETREUID 6900 {"setreuid", posix_setreuid, METH_VARARGS, posix_setreuid__doc__}, 6901#endif /* HAVE_SETREUID */ 6902#ifdef HAVE_SETREGID 6903 {"setregid", posix_setregid, METH_VARARGS, posix_setregid__doc__}, 6904#endif /* HAVE_SETREGID */ 6905#ifdef HAVE_SETGID 6906 {"setgid", posix_setgid, METH_VARARGS, posix_setgid__doc__}, 6907#endif /* HAVE_SETGID */ 6908#ifdef HAVE_SETGROUPS 6909 {"setgroups", posix_setgroups, METH_VARARGS, posix_setgroups__doc__}, 6910#endif /* HAVE_SETGROUPS */ 6911#ifdef HAVE_GETPGID 6912 {"getpgid", posix_getpgid, METH_VARARGS, posix_getpgid__doc__}, 6913#endif /* HAVE_GETPGID */ 6914#ifdef HAVE_SETPGRP 6915 {"setpgrp", posix_setpgrp, METH_VARARGS, posix_setpgrp__doc__}, 6916#endif /* HAVE_SETPGRP */ 6917#ifdef HAVE_WAIT 6918 {"wait", posix_wait, METH_VARARGS, posix_wait__doc__}, 6919#endif /* HAVE_WAIT */ 6920#if defined(HAVE_WAITPID) || defined(HAVE_CWAIT) 6921 {"waitpid", posix_waitpid, METH_VARARGS, posix_waitpid__doc__}, 6922#endif /* HAVE_WAITPID */ 6923#ifdef HAVE_SETSID 6924 {"setsid", posix_setsid, METH_VARARGS, posix_setsid__doc__}, 6925#endif /* HAVE_SETSID */ 6926#ifdef HAVE_SETPGID 6927 {"setpgid", posix_setpgid, METH_VARARGS, posix_setpgid__doc__}, 6928#endif /* HAVE_SETPGID */ 6929#ifdef HAVE_TCGETPGRP 6930 {"tcgetpgrp", posix_tcgetpgrp, METH_VARARGS, posix_tcgetpgrp__doc__}, 6931#endif /* HAVE_TCGETPGRP */ 6932#ifdef HAVE_TCSETPGRP 6933 {"tcsetpgrp", posix_tcsetpgrp, METH_VARARGS, posix_tcsetpgrp__doc__}, 6934#endif /* HAVE_TCSETPGRP */ 6935 {"open", posix_open, METH_VARARGS, posix_open__doc__}, 6936 {"close", posix_close, METH_VARARGS, posix_close__doc__}, 6937 {"dup", posix_dup, METH_VARARGS, posix_dup__doc__}, 6938 {"dup2", posix_dup2, METH_VARARGS, posix_dup2__doc__}, 6939 {"lseek", posix_lseek, METH_VARARGS, posix_lseek__doc__}, 6940 {"read", posix_read, METH_VARARGS, posix_read__doc__}, 6941 {"write", posix_write, METH_VARARGS, posix_write__doc__}, 6942 {"fstat", posix_fstat, METH_VARARGS, posix_fstat__doc__}, 6943 {"fdopen", posix_fdopen, METH_VARARGS, posix_fdopen__doc__}, 6944 {"isatty", posix_isatty, METH_VARARGS, posix_isatty__doc__}, 6945#ifdef HAVE_PIPE 6946 {"pipe", posix_pipe, METH_VARARGS, posix_pipe__doc__}, 6947#endif 6948#ifdef HAVE_MKFIFO 6949 {"mkfifo", posix_mkfifo, METH_VARARGS, posix_mkfifo__doc__}, 6950#endif 6951#if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV) 6952 {"mknod", posix_mknod, METH_VARARGS, posix_mknod__doc__}, 6953#endif 6954#ifdef HAVE_DEVICE_MACROS 6955 {"major", posix_major, METH_VARARGS, posix_major__doc__}, 6956 {"minor", posix_minor, METH_VARARGS, posix_minor__doc__}, 6957 {"makedev", posix_makedev, METH_VARARGS, posix_makedev__doc__}, 6958#endif 6959#ifdef HAVE_FTRUNCATE 6960 {"ftruncate", posix_ftruncate, METH_VARARGS, posix_ftruncate__doc__}, 6961#endif 6962#ifdef HAVE_PUTENV 6963 {"putenv", posix_putenv, METH_VARARGS, posix_putenv__doc__}, 6964#endif 6965#ifdef HAVE_UNSETENV 6966 {"unsetenv", posix_unsetenv, METH_VARARGS, posix_unsetenv__doc__}, 6967#endif 6968#ifdef HAVE_STRERROR 6969 {"strerror", posix_strerror, METH_VARARGS, posix_strerror__doc__}, 6970#endif 6971#ifdef HAVE_FCHDIR 6972 {"fchdir", posix_fchdir, METH_O, posix_fchdir__doc__}, 6973#endif 6974#ifdef HAVE_FSYNC 6975 {"fsync", posix_fsync, METH_O, posix_fsync__doc__}, 6976#endif 6977#ifdef HAVE_FDATASYNC 6978 {"fdatasync", posix_fdatasync, METH_O, posix_fdatasync__doc__}, 6979#endif 6980#ifdef HAVE_SYS_WAIT_H 6981#ifdef WCOREDUMP 6982 {"WCOREDUMP", posix_WCOREDUMP, METH_VARARGS, posix_WCOREDUMP__doc__}, 6983#endif /* WCOREDUMP */ 6984#ifdef WIFCONTINUED 6985 {"WIFCONTINUED",posix_WIFCONTINUED, METH_VARARGS, posix_WIFCONTINUED__doc__}, 6986#endif /* WIFCONTINUED */ 6987#ifdef WIFSTOPPED 6988 {"WIFSTOPPED", posix_WIFSTOPPED, METH_VARARGS, posix_WIFSTOPPED__doc__}, 6989#endif /* WIFSTOPPED */ 6990#ifdef WIFSIGNALED 6991 {"WIFSIGNALED", posix_WIFSIGNALED, METH_VARARGS, posix_WIFSIGNALED__doc__}, 6992#endif /* WIFSIGNALED */ 6993#ifdef WIFEXITED 6994 {"WIFEXITED", posix_WIFEXITED, METH_VARARGS, posix_WIFEXITED__doc__}, 6995#endif /* WIFEXITED */ 6996#ifdef WEXITSTATUS 6997 {"WEXITSTATUS", posix_WEXITSTATUS, METH_VARARGS, posix_WEXITSTATUS__doc__}, 6998#endif /* WEXITSTATUS */ 6999#ifdef WTERMSIG 7000 {"WTERMSIG", posix_WTERMSIG, METH_VARARGS, posix_WTERMSIG__doc__}, 7001#endif /* WTERMSIG */ 7002#ifdef WSTOPSIG 7003 {"WSTOPSIG", posix_WSTOPSIG, METH_VARARGS, posix_WSTOPSIG__doc__}, 7004#endif /* WSTOPSIG */ 7005#endif /* HAVE_SYS_WAIT_H */ 7006#ifdef HAVE_FSTATVFS 7007 {"fstatvfs", posix_fstatvfs, METH_VARARGS, posix_fstatvfs__doc__}, 7008#endif 7009#ifdef HAVE_STATVFS 7010 {"statvfs", posix_statvfs, METH_VARARGS, posix_statvfs__doc__}, 7011#endif 7012#ifdef HAVE_TMPFILE 7013 {"tmpfile", posix_tmpfile, METH_VARARGS, posix_tmpfile__doc__}, 7014#endif 7015#ifdef HAVE_TEMPNAM 7016 {"tempnam", posix_tempnam, METH_VARARGS, posix_tempnam__doc__}, 7017#endif 7018#ifdef HAVE_TMPNAM 7019 {"tmpnam", posix_tmpnam, METH_VARARGS, posix_tmpnam__doc__}, 7020#endif 7021#ifdef HAVE_CONFSTR 7022 {"confstr", posix_confstr, METH_VARARGS, posix_confstr__doc__}, 7023#endif 7024#ifdef HAVE_SYSCONF 7025 {"sysconf", posix_sysconf, METH_VARARGS, posix_sysconf__doc__}, 7026#endif 7027#ifdef HAVE_FPATHCONF 7028 {"fpathconf", posix_fpathconf, METH_VARARGS, posix_fpathconf__doc__}, 7029#endif 7030#ifdef HAVE_PATHCONF 7031 {"pathconf", posix_pathconf, METH_VARARGS, posix_pathconf__doc__}, 7032#endif 7033 {"abort", posix_abort, METH_VARARGS, posix_abort__doc__}, 7034#ifdef MS_WINDOWS 7035 {"_getfullpathname", posix__getfullpathname, METH_VARARGS, NULL}, 7036#endif 7037 {NULL, NULL} /* Sentinel */ 7038}; 7039 7040 7041static int 7042ins(PyObject *module, char *symbol, long value) 7043{ 7044 return PyModule_AddIntConstant(module, symbol, value); 7045} 7046 7047#if defined(PYOS_OS2) 7048/* Insert Platform-Specific Constant Values (Strings & Numbers) of Common Use */ 7049static int insertvalues(PyObject *module) 7050{ 7051 APIRET rc; 7052 ULONG values[QSV_MAX+1]; 7053 PyObject *v; 7054 char *ver, tmp[50]; 7055 7056 Py_BEGIN_ALLOW_THREADS 7057 rc = DosQuerySysInfo(1, QSV_MAX, &values[1], sizeof(values)); 7058 Py_END_ALLOW_THREADS 7059 7060 if (rc != NO_ERROR) { 7061 os2_error(rc); 7062 return -1; 7063 } 7064 7065 if (ins(module, "meminstalled", values[QSV_TOTPHYSMEM])) return -1; 7066 if (ins(module, "memkernel", values[QSV_TOTRESMEM])) return -1; 7067 if (ins(module, "memvirtual", values[QSV_TOTAVAILMEM])) return -1; 7068 if (ins(module, "maxpathlen", values[QSV_MAX_PATH_LENGTH])) return -1; 7069 if (ins(module, "maxnamelen", values[QSV_MAX_COMP_LENGTH])) return -1; 7070 if (ins(module, "revision", values[QSV_VERSION_REVISION])) return -1; 7071 if (ins(module, "timeslice", values[QSV_MIN_SLICE])) return -1; 7072 7073 switch (values[QSV_VERSION_MINOR]) { 7074 case 0: ver = "2.00"; break; 7075 case 10: ver = "2.10"; break; 7076 case 11: ver = "2.11"; break; 7077 case 30: ver = "3.00"; break; 7078 case 40: ver = "4.00"; break; 7079 case 50: ver = "5.00"; break; 7080 default: 7081 PyOS_snprintf(tmp, sizeof(tmp), 7082 "%d-%d", values[QSV_VERSION_MAJOR], 7083 values[QSV_VERSION_MINOR]); 7084 ver = &tmp[0]; 7085 } 7086 7087 /* Add Indicator of the Version of the Operating System */ 7088 if (PyModule_AddStringConstant(module, "version", tmp) < 0) 7089 return -1; 7090 7091 /* Add Indicator of Which Drive was Used to Boot the System */ 7092 tmp[0] = 'A' + values[QSV_BOOT_DRIVE] - 1; 7093 tmp[1] = ':'; 7094 tmp[2] = '\0'; 7095 7096 return PyModule_AddStringConstant(module, "bootdrive", tmp); 7097} 7098#endif 7099 7100static int 7101all_ins(PyObject *d) 7102{ 7103#ifdef F_OK 7104 if (ins(d, "F_OK", (long)F_OK)) return -1; 7105#endif 7106#ifdef R_OK 7107 if (ins(d, "R_OK", (long)R_OK)) return -1; 7108#endif 7109#ifdef W_OK 7110 if (ins(d, "W_OK", (long)W_OK)) return -1; 7111#endif 7112#ifdef X_OK 7113 if (ins(d, "X_OK", (long)X_OK)) return -1; 7114#endif 7115#ifdef NGROUPS_MAX 7116 if (ins(d, "NGROUPS_MAX", (long)NGROUPS_MAX)) return -1; 7117#endif 7118#ifdef TMP_MAX 7119 if (ins(d, "TMP_MAX", (long)TMP_MAX)) return -1; 7120#endif 7121#ifdef WCONTINUED 7122 if (ins(d, "WCONTINUED", (long)WCONTINUED)) return -1; 7123#endif 7124#ifdef WNOHANG 7125 if (ins(d, "WNOHANG", (long)WNOHANG)) return -1; 7126#endif 7127#ifdef WUNTRACED 7128 if (ins(d, "WUNTRACED", (long)WUNTRACED)) return -1; 7129#endif 7130#ifdef O_RDONLY 7131 if (ins(d, "O_RDONLY", (long)O_RDONLY)) return -1; 7132#endif 7133#ifdef O_WRONLY 7134 if (ins(d, "O_WRONLY", (long)O_WRONLY)) return -1; 7135#endif 7136#ifdef O_RDWR 7137 if (ins(d, "O_RDWR", (long)O_RDWR)) return -1; 7138#endif 7139#ifdef O_NDELAY 7140 if (ins(d, "O_NDELAY", (long)O_NDELAY)) return -1; 7141#endif 7142#ifdef O_NONBLOCK 7143 if (ins(d, "O_NONBLOCK", (long)O_NONBLOCK)) return -1; 7144#endif 7145#ifdef O_APPEND 7146 if (ins(d, "O_APPEND", (long)O_APPEND)) return -1; 7147#endif 7148#ifdef O_DSYNC 7149 if (ins(d, "O_DSYNC", (long)O_DSYNC)) return -1; 7150#endif 7151#ifdef O_RSYNC 7152 if (ins(d, "O_RSYNC", (long)O_RSYNC)) return -1; 7153#endif 7154#ifdef O_SYNC 7155 if (ins(d, "O_SYNC", (long)O_SYNC)) return -1; 7156#endif 7157#ifdef O_NOCTTY 7158 if (ins(d, "O_NOCTTY", (long)O_NOCTTY)) return -1; 7159#endif 7160#ifdef O_CREAT 7161 if (ins(d, "O_CREAT", (long)O_CREAT)) return -1; 7162#endif 7163#ifdef O_EXCL 7164 if (ins(d, "O_EXCL", (long)O_EXCL)) return -1; 7165#endif 7166#ifdef O_TRUNC 7167 if (ins(d, "O_TRUNC", (long)O_TRUNC)) return -1; 7168#endif 7169#ifdef O_BINARY 7170 if (ins(d, "O_BINARY", (long)O_BINARY)) return -1; 7171#endif 7172#ifdef O_TEXT 7173 if (ins(d, "O_TEXT", (long)O_TEXT)) return -1; 7174#endif 7175#ifdef O_LARGEFILE 7176 if (ins(d, "O_LARGEFILE", (long)O_LARGEFILE)) return -1; 7177#endif 7178 7179/* MS Windows */ 7180#ifdef O_NOINHERIT 7181 /* Don't inherit in child processes. */ 7182 if (ins(d, "O_NOINHERIT", (long)O_NOINHERIT)) return -1; 7183#endif 7184#ifdef _O_SHORT_LIVED 7185 /* Optimize for short life (keep in memory). */ 7186 /* MS forgot to define this one with a non-underscore form too. */ 7187 if (ins(d, "O_SHORT_LIVED", (long)_O_SHORT_LIVED)) return -1; 7188#endif 7189#ifdef O_TEMPORARY 7190 /* Automatically delete when last handle is closed. */ 7191 if (ins(d, "O_TEMPORARY", (long)O_TEMPORARY)) return -1; 7192#endif 7193#ifdef O_RANDOM 7194 /* Optimize for random access. */ 7195 if (ins(d, "O_RANDOM", (long)O_RANDOM)) return -1; 7196#endif 7197#ifdef O_SEQUENTIAL 7198 /* Optimize for sequential access. */ 7199 if (ins(d, "O_SEQUENTIAL", (long)O_SEQUENTIAL)) return -1; 7200#endif 7201 7202/* GNU extensions. */ 7203#ifdef O_DIRECT 7204 /* Direct disk access. */ 7205 if (ins(d, "O_DIRECT", (long)O_DIRECT)) return -1; 7206#endif 7207#ifdef O_DIRECTORY 7208 /* Must be a directory. */ 7209 if (ins(d, "O_DIRECTORY", (long)O_DIRECTORY)) return -1; 7210#endif 7211#ifdef O_NOFOLLOW 7212 /* Do not follow links. */ 7213 if (ins(d, "O_NOFOLLOW", (long)O_NOFOLLOW)) return -1; 7214#endif 7215 7216#ifdef HAVE_SPAWNV 7217#if defined(PYOS_OS2) && defined(PYCC_GCC) 7218 if (ins(d, "P_WAIT", (long)P_WAIT)) return -1; 7219 if (ins(d, "P_NOWAIT", (long)P_NOWAIT)) return -1; 7220 if (ins(d, "P_OVERLAY", (long)P_OVERLAY)) return -1; 7221 if (ins(d, "P_DEBUG", (long)P_DEBUG)) return -1; 7222 if (ins(d, "P_SESSION", (long)P_SESSION)) return -1; 7223 if (ins(d, "P_DETACH", (long)P_DETACH)) return -1; 7224 if (ins(d, "P_PM", (long)P_PM)) return -1; 7225 if (ins(d, "P_DEFAULT", (long)P_DEFAULT)) return -1; 7226 if (ins(d, "P_MINIMIZE", (long)P_MINIMIZE)) return -1; 7227 if (ins(d, "P_MAXIMIZE", (long)P_MAXIMIZE)) return -1; 7228 if (ins(d, "P_FULLSCREEN", (long)P_FULLSCREEN)) return -1; 7229 if (ins(d, "P_WINDOWED", (long)P_WINDOWED)) return -1; 7230 if (ins(d, "P_FOREGROUND", (long)P_FOREGROUND)) return -1; 7231 if (ins(d, "P_BACKGROUND", (long)P_BACKGROUND)) return -1; 7232 if (ins(d, "P_NOCLOSE", (long)P_NOCLOSE)) return -1; 7233 if (ins(d, "P_NOSESSION", (long)P_NOSESSION)) return -1; 7234 if (ins(d, "P_QUOTE", (long)P_QUOTE)) return -1; 7235 if (ins(d, "P_TILDE", (long)P_TILDE)) return -1; 7236 if (ins(d, "P_UNRELATED", (long)P_UNRELATED)) return -1; 7237 if (ins(d, "P_DEBUGDESC", (long)P_DEBUGDESC)) return -1; 7238#else 7239 if (ins(d, "P_WAIT", (long)_P_WAIT)) return -1; 7240 if (ins(d, "P_NOWAIT", (long)_P_NOWAIT)) return -1; 7241 if (ins(d, "P_OVERLAY", (long)_OLD_P_OVERLAY)) return -1; 7242 if (ins(d, "P_NOWAITO", (long)_P_NOWAITO)) return -1; 7243 if (ins(d, "P_DETACH", (long)_P_DETACH)) return -1; 7244#endif 7245#endif 7246 7247#if defined(PYOS_OS2) 7248 if (insertvalues(d)) return -1; 7249#endif 7250 return 0; 7251} 7252 7253 7254#if (defined(_MSC_VER) || defined(__WATCOMC__) || defined(__BORLANDC__)) && !defined(__QNX__) 7255#define INITFUNC initnt 7256#define MODNAME "nt" 7257 7258#elif defined(PYOS_OS2) 7259#define INITFUNC initos2 7260#define MODNAME "os2" 7261 7262#else 7263#define INITFUNC initposix 7264#define MODNAME "posix" 7265#endif 7266 7267PyMODINIT_FUNC 7268INITFUNC(void) 7269{ 7270 PyObject *m, *v; 7271 7272 m = Py_InitModule3(MODNAME, 7273 posix_methods, 7274 posix__doc__); 7275 7276 /* Initialize environ dictionary */ 7277 v = convertenviron(); 7278 Py_XINCREF(v); 7279 if (v == NULL || PyModule_AddObject(m, "environ", v) != 0) 7280 return; 7281 Py_DECREF(v); 7282 7283 if (all_ins(m)) 7284 return; 7285 7286 if (setup_confname_tables(m)) 7287 return; 7288 7289 Py_INCREF(PyExc_OSError); 7290 PyModule_AddObject(m, "error", PyExc_OSError); 7291 7292#ifdef HAVE_PUTENV 7293 if (posix_putenv_garbage == NULL) 7294 posix_putenv_garbage = PyDict_New(); 7295#endif 7296 7297 stat_result_desc.name = MODNAME ".stat_result"; 7298 PyStructSequence_InitType(&StatResultType, &stat_result_desc); 7299 Py_INCREF((PyObject*) &StatResultType); 7300 PyModule_AddObject(m, "stat_result", (PyObject*) &StatResultType); 7301 7302 statvfs_result_desc.name = MODNAME ".statvfs_result"; 7303 PyStructSequence_InitType(&StatVFSResultType, &statvfs_result_desc); 7304 Py_INCREF((PyObject*) &StatVFSResultType); 7305 PyModule_AddObject(m, "statvfs_result", 7306 (PyObject*) &StatVFSResultType); 7307} 7308