Python-2.7.3/Modules/posixmodule.c

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