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