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