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