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