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