posixmodule.c revision f3f33dcf03eaed3c4e720178f9d69205a66d6a91
1/*********************************************************** 2Copyright (c) 2000, BeOpen.com. 3Copyright (c) 1995-2000, Corporation for National Research Initiatives. 4Copyright (c) 1990-1995, Stichting Mathematisch Centrum. 5All rights reserved. 6 7See the file "Misc/COPYRIGHT" for information on usage and 8redistribution of this file, and for a DISCLAIMER OF ALL WARRANTIES. 9******************************************************************/ 10 11/* POSIX module implementation */ 12 13/* This file is also used for Windows NT and MS-Win. In that case the module 14 actually calls itself 'nt', not 'posix', and a few functions are 15 either unimplemented or implemented differently. The source 16 assumes that for Windows NT, the macro 'MS_WIN32' is defined independent 17 of the compiler used. Different compilers define their own feature 18 test macro, e.g. '__BORLANDC__' or '_MSC_VER'. */ 19 20/* See also ../Dos/dosmodule.c */ 21 22static char posix__doc__ [] = 23"This module provides access to operating system functionality that is\n\ 24standardized by the C Standard and the POSIX standard (a thinly\n\ 25disguised Unix interface). Refer to the library manual and\n\ 26corresponding Unix manual entries for more information on calls."; 27 28#include "Python.h" 29 30#if defined(PYOS_OS2) 31#define INCL_DOS 32#define INCL_DOSERRORS 33#define INCL_DOSPROCESS 34#define INCL_NOPMAPI 35#include <os2.h> 36#endif 37 38#include <sys/types.h> 39#include <sys/stat.h> 40#ifdef HAVE_SYS_WAIT_H 41#include <sys/wait.h> /* For WNOHANG */ 42#endif 43 44#ifdef HAVE_SIGNAL_H 45#include <signal.h> 46#endif 47 48#include "mytime.h" /* For clock_t on some systems */ 49 50#ifdef HAVE_FCNTL_H 51#include <fcntl.h> 52#endif /* HAVE_FCNTL_H */ 53 54/* Various compilers have only certain posix functions */ 55/* XXX Gosh I wish these were all moved into config.h */ 56#if defined(PYCC_VACPP) && defined(PYOS_OS2) 57#include <process.h> 58#else 59#if defined(__WATCOMC__) && !defined(__QNX__) /* Watcom compiler */ 60#define HAVE_GETCWD 1 61#define HAVE_OPENDIR 1 62#define HAVE_SYSTEM 1 63#if defined(__OS2__) 64#define HAVE_EXECV 1 65#define HAVE_WAIT 1 66#endif 67#include <process.h> 68#else 69#ifdef __BORLANDC__ /* Borland compiler */ 70#define HAVE_EXECV 1 71#define HAVE_GETCWD 1 72#define HAVE_GETEGID 1 73#define HAVE_GETEUID 1 74#define HAVE_GETGID 1 75#define HAVE_GETPPID 1 76#define HAVE_GETUID 1 77#define HAVE_KILL 1 78#define HAVE_OPENDIR 1 79#define HAVE_PIPE 1 80#define HAVE_POPEN 1 81#define HAVE_SYSTEM 1 82#define HAVE_WAIT 1 83#else 84#ifdef _MSC_VER /* Microsoft compiler */ 85#define HAVE_GETCWD 1 86#ifdef MS_WIN32 87#define HAVE_SPAWNV 1 88#define HAVE_EXECV 1 89#define HAVE_PIPE 1 90#define HAVE_POPEN 1 91#define HAVE_SYSTEM 1 92#else /* 16-bit Windows */ 93#endif /* !MS_WIN32 */ 94#else /* all other compilers */ 95/* Unix functions that the configure script doesn't check for */ 96#define HAVE_EXECV 1 97#define HAVE_FORK 1 98#define HAVE_GETCWD 1 99#define HAVE_GETEGID 1 100#define HAVE_GETEUID 1 101#define HAVE_GETGID 1 102#define HAVE_GETPPID 1 103#define HAVE_GETUID 1 104#define HAVE_KILL 1 105#define HAVE_OPENDIR 1 106#define HAVE_PIPE 1 107#define HAVE_POPEN 1 108#define HAVE_SYSTEM 1 109#define HAVE_WAIT 1 110#define HAVE_TTYNAME 1 111#endif /* _MSC_VER */ 112#endif /* __BORLANDC__ */ 113#endif /* ! __WATCOMC__ || __QNX__ */ 114#endif /* ! __IBMC__ */ 115 116#ifndef _MSC_VER 117 118#ifdef HAVE_UNISTD_H 119#include <unistd.h> 120#endif 121 122#ifdef NeXT 123/* NeXT's <unistd.h> and <utime.h> aren't worth much */ 124#undef HAVE_UNISTD_H 125#undef HAVE_UTIME_H 126#define HAVE_WAITPID 127/* #undef HAVE_GETCWD */ 128#define UNION_WAIT /* This should really be checked for by autoconf */ 129#endif 130 131#ifdef HAVE_UNISTD_H 132/* XXX These are for SunOS4.1.3 but shouldn't hurt elsewhere */ 133extern int rename(); 134extern int pclose(); 135extern int lstat(); 136extern int symlink(); 137extern int fsync(); 138#else /* !HAVE_UNISTD_H */ 139#if defined(PYCC_VACPP) 140extern int mkdir(char *); 141#else 142#if ( defined(__WATCOMC__) || defined(_MSC_VER) ) && !defined(__QNX__) 143extern int mkdir(const char *); 144#else 145extern int mkdir(const char *, mode_t); 146#endif 147#endif 148#if defined(__IBMC__) || defined(__IBMCPP__) 149extern int chdir(char *); 150extern int rmdir(char *); 151#else 152extern int chdir(const char *); 153extern int rmdir(const char *); 154#endif 155extern int chmod(const char *, mode_t); 156extern int chown(const char *, uid_t, gid_t); 157extern char *getcwd(char *, int); 158extern char *strerror(int); 159extern int link(const char *, const char *); 160extern int rename(const char *, const char *); 161extern int stat(const char *, struct stat *); 162extern int unlink(const char *); 163extern int pclose(FILE *); 164#ifdef HAVE_SYMLINK 165extern int symlink(const char *, const char *); 166#endif /* HAVE_SYMLINK */ 167#ifdef HAVE_LSTAT 168extern int lstat(const char *, struct stat *); 169#endif /* HAVE_LSTAT */ 170#endif /* !HAVE_UNISTD_H */ 171 172#endif /* !_MSC_VER */ 173 174#ifdef HAVE_UTIME_H 175#include <utime.h> 176#endif /* HAVE_UTIME_H */ 177 178#ifdef HAVE_SYS_UTIME_H 179#include <sys/utime.h> 180#define HAVE_UTIME_H /* pretend we do for the rest of this file */ 181#endif /* HAVE_SYS_UTIME_H */ 182 183#ifdef HAVE_SYS_TIMES_H 184#include <sys/times.h> 185#endif /* HAVE_SYS_TIMES_H */ 186 187#ifdef HAVE_SYS_PARAM_H 188#include <sys/param.h> 189#endif /* HAVE_SYS_PARAM_H */ 190 191#ifdef HAVE_SYS_UTSNAME_H 192#include <sys/utsname.h> 193#endif /* HAVE_SYS_UTSNAME_H */ 194 195#ifndef MAXPATHLEN 196#define MAXPATHLEN 1024 197#endif /* MAXPATHLEN */ 198 199#ifdef HAVE_DIRENT_H 200#include <dirent.h> 201#define NAMLEN(dirent) strlen((dirent)->d_name) 202#else 203#if defined(__WATCOMC__) && !defined(__QNX__) 204#include <direct.h> 205#define NAMLEN(dirent) strlen((dirent)->d_name) 206#else 207#define dirent direct 208#define NAMLEN(dirent) (dirent)->d_namlen 209#endif 210#ifdef HAVE_SYS_NDIR_H 211#include <sys/ndir.h> 212#endif 213#ifdef HAVE_SYS_DIR_H 214#include <sys/dir.h> 215#endif 216#ifdef HAVE_NDIR_H 217#include <ndir.h> 218#endif 219#endif 220 221#ifdef _MSC_VER 222#include <direct.h> 223#include <io.h> 224#include <process.h> 225#define WINDOWS_LEAN_AND_MEAN 226#include <windows.h> 227#ifdef MS_WIN32 228#define popen _popen 229#define pclose _pclose 230#else /* 16-bit Windows */ 231#include <dos.h> 232#include <ctype.h> 233#endif /* MS_WIN32 */ 234#endif /* _MSC_VER */ 235 236#if defined(PYCC_VACPP) && defined(PYOS_OS2) 237#include <io.h> 238#endif /* OS2 */ 239 240#ifdef UNION_WAIT 241/* Emulate some macros on systems that have a union instead of macros */ 242 243#ifndef WIFEXITED 244#define WIFEXITED(u_wait) (!(u_wait).w_termsig && !(u_wait).w_coredump) 245#endif 246 247#ifndef WEXITSTATUS 248#define WEXITSTATUS(u_wait) (WIFEXITED(u_wait)?((u_wait).w_retcode):-1) 249#endif 250 251#ifndef WTERMSIG 252#define WTERMSIG(u_wait) ((u_wait).w_termsig) 253#endif 254 255#endif /* UNION_WAIT */ 256 257/* Don't use the "_r" form if we don't need it (also, won't have a 258 prototype for it, at least on Solaris -- maybe others as well?). */ 259#if defined(HAVE_CTERMID_R) && defined(WITH_THREAD) 260#define USE_CTERMID_R 261#endif 262 263#if defined(HAVE_TMPNAM_R) && defined(WITH_THREAD) 264#define USE_TMPNAM_R 265#endif 266 267/* choose the appropriate stat and fstat functions and return structs */ 268#undef STAT 269#ifdef MS_WIN64 270# define STAT _stati64 271# define FSTAT _fstati64 272# define STRUCT_STAT struct _stati64 273#else 274# define STAT stat 275# define FSTAT fstat 276# define STRUCT_STAT struct stat 277#endif 278 279 280/* Return a dictionary corresponding to the POSIX environment table */ 281 282#if !defined(_MSC_VER) && ( !defined(__WATCOMC__) || defined(__QNX__) ) 283extern char **environ; 284#endif /* !_MSC_VER */ 285 286static PyObject * 287convertenviron(void) 288{ 289 PyObject *d; 290 char **e; 291 d = PyDict_New(); 292 if (d == NULL) 293 return NULL; 294 if (environ == NULL) 295 return d; 296 /* This part ignores errors */ 297 for (e = environ; *e != NULL; e++) { 298 PyObject *k; 299 PyObject *v; 300 char *p = strchr(*e, '='); 301 if (p == NULL) 302 continue; 303 k = PyString_FromStringAndSize(*e, (int)(p-*e)); 304 if (k == NULL) { 305 PyErr_Clear(); 306 continue; 307 } 308 v = PyString_FromString(p+1); 309 if (v == NULL) { 310 PyErr_Clear(); 311 Py_DECREF(k); 312 continue; 313 } 314 if (PyDict_GetItem(d, k) == NULL) { 315 if (PyDict_SetItem(d, k, v) != 0) 316 PyErr_Clear(); 317 } 318 Py_DECREF(k); 319 Py_DECREF(v); 320 } 321#if defined(PYOS_OS2) 322 { 323 APIRET rc; 324 char buffer[1024]; /* OS/2 Provides a Documented Max of 1024 Chars */ 325 326 rc = DosQueryExtLIBPATH(buffer, BEGIN_LIBPATH); 327 if (rc == NO_ERROR) { /* (not a type, envname is NOT 'BEGIN_LIBPATH') */ 328 PyObject *v = PyString_FromString(buffer); 329 PyDict_SetItemString(d, "BEGINLIBPATH", v); 330 Py_DECREF(v); 331 } 332 rc = DosQueryExtLIBPATH(buffer, END_LIBPATH); 333 if (rc == NO_ERROR) { /* (not a typo, envname is NOT 'END_LIBPATH') */ 334 PyObject *v = PyString_FromString(buffer); 335 PyDict_SetItemString(d, "ENDLIBPATH", v); 336 Py_DECREF(v); 337 } 338 } 339#endif 340 return d; 341} 342 343 344/* Set a POSIX-specific error from errno, and return NULL */ 345 346static PyObject * 347posix_error(void) 348{ 349 return PyErr_SetFromErrno(PyExc_OSError); 350} 351static PyObject * 352posix_error_with_filename(char* name) 353{ 354 return PyErr_SetFromErrnoWithFilename(PyExc_OSError, name); 355} 356 357#ifdef MS_WIN32 358static PyObject * 359win32_error(char* function, char* filename) 360{ 361 /* XXX this could be improved */ 362 errno = GetLastError(); 363 if (filename) 364 return PyErr_SetFromErrnoWithFilename(PyExc_OSError, filename); 365 else 366 return PyErr_SetFromErrno(PyExc_OSError); 367} 368#endif 369 370#if defined(PYOS_OS2) 371/********************************************************************** 372 * Helper Function to Trim and Format OS/2 Messages 373 **********************************************************************/ 374 static void 375os2_formatmsg(char *msgbuf, int msglen, char *reason) 376{ 377 msgbuf[msglen] = '\0'; /* OS/2 Doesn't Guarantee a Terminator */ 378 379 if (strlen(msgbuf) > 0) { /* If Non-Empty Msg, Trim CRLF */ 380 char *lastc = &msgbuf[ strlen(msgbuf)-1 ]; 381 382 while (lastc > msgbuf && isspace(*lastc)) 383 *lastc-- = '\0'; /* Trim Trailing Whitespace (CRLF) */ 384 } 385 386 /* Add Optional Reason Text */ 387 if (reason) { 388 strcat(msgbuf, " : "); 389 strcat(msgbuf, reason); 390 } 391} 392 393/********************************************************************** 394 * Decode an OS/2 Operating System Error Code 395 * 396 * A convenience function to lookup an OS/2 error code and return a 397 * text message we can use to raise a Python exception. 398 * 399 * Notes: 400 * The messages for errors returned from the OS/2 kernel reside in 401 * the file OSO001.MSG in the \OS2 directory hierarchy. 402 * 403 **********************************************************************/ 404 static char * 405os2_strerror(char *msgbuf, int msgbuflen, int errorcode, char *reason) 406{ 407 APIRET rc; 408 ULONG msglen; 409 410 /* Retrieve Kernel-Related Error Message from OSO001.MSG File */ 411 Py_BEGIN_ALLOW_THREADS 412 rc = DosGetMessage(NULL, 0, msgbuf, msgbuflen, 413 errorcode, "oso001.msg", &msglen); 414 Py_END_ALLOW_THREADS 415 416 if (rc == NO_ERROR) 417 os2_formatmsg(msgbuf, msglen, reason); 418 else 419 sprintf(msgbuf, "unknown OS error #%d", errorcode); 420 421 return msgbuf; 422} 423 424/* Set an OS/2-specific error and return NULL. OS/2 kernel 425 errors are not in a global variable e.g. 'errno' nor are 426 they congruent with posix error numbers. */ 427 428static PyObject * os2_error(int code) 429{ 430 char text[1024]; 431 PyObject *v; 432 433 os2_strerror(text, sizeof(text), code, ""); 434 435 v = Py_BuildValue("(is)", code, text); 436 if (v != NULL) { 437 PyErr_SetObject(PyExc_OSError, v); 438 Py_DECREF(v); 439 } 440 return NULL; /* Signal to Python that an Exception is Pending */ 441} 442 443#endif /* OS2 */ 444 445/* POSIX generic methods */ 446 447static PyObject * 448posix_int(PyObject *args, char *format, int (*func)(int)) 449{ 450 int fd; 451 int res; 452 if (!PyArg_ParseTuple(args, format, &fd)) 453 return NULL; 454 Py_BEGIN_ALLOW_THREADS 455 res = (*func)(fd); 456 Py_END_ALLOW_THREADS 457 if (res < 0) 458 return posix_error(); 459 Py_INCREF(Py_None); 460 return Py_None; 461} 462 463 464static PyObject * 465posix_1str(PyObject *args, char *format, int (*func)(const char*)) 466{ 467 char *path1; 468 int res; 469 if (!PyArg_ParseTuple(args, format, &path1)) 470 return NULL; 471 Py_BEGIN_ALLOW_THREADS 472 res = (*func)(path1); 473 Py_END_ALLOW_THREADS 474 if (res < 0) 475 return posix_error_with_filename(path1); 476 Py_INCREF(Py_None); 477 return Py_None; 478} 479 480static PyObject * 481posix_2str(PyObject *args, char *format, 482 int (*func)(const char *, const char *)) 483{ 484 char *path1, *path2; 485 int res; 486 if (!PyArg_ParseTuple(args, format, &path1, &path2)) 487 return NULL; 488 Py_BEGIN_ALLOW_THREADS 489 res = (*func)(path1, path2); 490 Py_END_ALLOW_THREADS 491 if (res != 0) 492 /* XXX how to report both path1 and path2??? */ 493 return posix_error(); 494 Py_INCREF(Py_None); 495 return Py_None; 496} 497 498static PyObject * 499posix_strint(PyObject *args, char *format, int (*func)(const char *, int)) 500{ 501 char *path; 502 int i; 503 int res; 504 if (!PyArg_ParseTuple(args, format, &path, &i)) 505 return NULL; 506 Py_BEGIN_ALLOW_THREADS 507 res = (*func)(path, i); 508 Py_END_ALLOW_THREADS 509 if (res < 0) 510 return posix_error_with_filename(path); 511 Py_INCREF(Py_None); 512 return Py_None; 513} 514 515 516/* pack a system stat C structure into the Python stat tuple 517 (used by posix_stat() and posix_fstat()) */ 518static PyObject* 519_pystat_fromstructstat(STRUCT_STAT st) 520{ 521 PyObject *v = PyTuple_New(10); 522 if (v == NULL) 523 return NULL; 524 525 PyTuple_SetItem(v, 0, PyInt_FromLong((long)st.st_mode)); 526#ifdef HAVE_LARGEFILE_SUPPORT 527 PyTuple_SetItem(v, 1, PyLong_FromLongLong((LONG_LONG)st.st_ino)); 528#else 529 PyTuple_SetItem(v, 1, PyInt_FromLong((long)st.st_ino)); 530#endif 531#if defined(HAVE_LONG_LONG) && !defined(MS_WINDOWS) 532 PyTuple_SetItem(v, 2, PyLong_FromLongLong((LONG_LONG)st.st_dev)); 533#else 534 PyTuple_SetItem(v, 2, PyInt_FromLong((long)st.st_dev)); 535#endif 536 PyTuple_SetItem(v, 3, PyInt_FromLong((long)st.st_nlink)); 537 PyTuple_SetItem(v, 4, PyInt_FromLong((long)st.st_uid)); 538 PyTuple_SetItem(v, 5, PyInt_FromLong((long)st.st_gid)); 539#ifdef HAVE_LARGEFILE_SUPPORT 540 PyTuple_SetItem(v, 6, PyLong_FromLongLong((LONG_LONG)st.st_size)); 541#else 542 PyTuple_SetItem(v, 6, PyInt_FromLong(st.st_size)); 543#endif 544#if SIZEOF_TIME_T > SIZEOF_LONG 545 PyTuple_SetItem(v, 7, PyLong_FromLongLong((LONG_LONG)st.st_atime)); 546 PyTuple_SetItem(v, 8, PyLong_FromLongLong((LONG_LONG)st.st_mtime)); 547 PyTuple_SetItem(v, 9, PyLong_FromLongLong((LONG_LONG)st.st_ctime)); 548#else 549 PyTuple_SetItem(v, 7, PyInt_FromLong((long)st.st_atime)); 550 PyTuple_SetItem(v, 8, PyInt_FromLong((long)st.st_mtime)); 551 PyTuple_SetItem(v, 9, PyInt_FromLong((long)st.st_ctime)); 552#endif 553 554 if (PyErr_Occurred()) { 555 Py_DECREF(v); 556 return NULL; 557 } 558 559 return v; 560} 561 562 563static PyObject * 564posix_do_stat(PyObject *self, PyObject *args, char *format, 565 int (*statfunc)(const char *, STRUCT_STAT *)) 566{ 567 STRUCT_STAT st; 568 char *path; 569 int res; 570 571#ifdef MS_WIN32 572 int pathlen; 573 char pathcopy[MAX_PATH]; 574#endif /* MS_WIN32 */ 575 576 if (!PyArg_ParseTuple(args, format, &path)) 577 return NULL; 578 579#ifdef MS_WIN32 580 pathlen = strlen(path); 581 /* the library call can blow up if the file name is too long! */ 582 if (pathlen > MAX_PATH) { 583 errno = ENAMETOOLONG; 584 return posix_error(); 585 } 586 587 if ((pathlen > 0) && (path[pathlen-1] == '\\' || path[pathlen-1] == '/')) { 588 /* exception for specific or current drive root */ 589 if (!((pathlen == 1) || 590 ((pathlen == 3) && 591 (path[1] == ':') && 592 (path[2] == '\\' || path[2] == '/')))) 593 { 594 strncpy(pathcopy, path, pathlen); 595 pathcopy[pathlen-1] = '\0'; /* nuke the trailing backslash */ 596 path = pathcopy; 597 } 598 } 599#endif /* MS_WIN32 */ 600 601 Py_BEGIN_ALLOW_THREADS 602 res = (*statfunc)(path, &st); 603 Py_END_ALLOW_THREADS 604 if (res != 0) 605 return posix_error_with_filename(path); 606 607 return _pystat_fromstructstat(st); 608} 609 610 611/* POSIX methods */ 612 613static char posix_access__doc__[] = 614"access(path, mode) -> 1 if granted, 0 otherwise\n\ 615Test for access to a file."; 616 617static PyObject * 618posix_access(PyObject *self, PyObject *args) 619{ 620 char *path; 621 int mode; 622 int res; 623 624 if (!PyArg_ParseTuple(args, "si:access", &path, &mode)) 625 return NULL; 626 Py_BEGIN_ALLOW_THREADS 627 res = access(path, mode); 628 Py_END_ALLOW_THREADS 629 return(PyInt_FromLong(res == 0 ? 1L : 0L)); 630} 631 632#ifndef F_OK 633#define F_OK 0 634#endif 635#ifndef R_OK 636#define R_OK 4 637#endif 638#ifndef W_OK 639#define W_OK 2 640#endif 641#ifndef X_OK 642#define X_OK 1 643#endif 644 645#ifdef HAVE_TTYNAME 646static char posix_ttyname__doc__[] = 647"ttyname(fd) -> String\n\ 648Return the name of the terminal device connected to 'fd'."; 649 650static PyObject * 651posix_ttyname(PyObject *self, PyObject *args) 652{ 653 int id; 654 char *ret; 655 656 if (!PyArg_ParseTuple(args, "i:ttyname", &id)) 657 return NULL; 658 659 ret = ttyname(id); 660 if (ret == NULL) 661 return(posix_error()); 662 return(PyString_FromString(ret)); 663} 664#endif 665 666#ifdef HAVE_CTERMID 667static char posix_ctermid__doc__[] = 668"ctermid() -> String\n\ 669Return the name of the controlling terminal for this process."; 670 671static PyObject * 672posix_ctermid(PyObject *self, PyObject *args) 673{ 674 char *ret; 675 char buffer[L_ctermid]; 676 677 if (!PyArg_ParseTuple(args, ":ctermid")) 678 return NULL; 679 680#ifdef USE_CTERMID_R 681 ret = ctermid_r(buffer); 682#else 683 ret = ctermid(buffer); 684#endif 685 if (ret == NULL) 686 return(posix_error()); 687 return(PyString_FromString(buffer)); 688} 689#endif 690 691static char posix_chdir__doc__[] = 692"chdir(path) -> None\n\ 693Change the current working directory to the specified path."; 694 695static PyObject * 696posix_chdir(PyObject *self, PyObject *args) 697{ 698 return posix_1str(args, "s:chdir", chdir); 699} 700 701 702static char posix_chmod__doc__[] = 703"chmod(path, mode) -> None\n\ 704Change the access permissions of a file."; 705 706static PyObject * 707posix_chmod(PyObject *self, PyObject *args) 708{ 709 char *path; 710 int i; 711 int res; 712 if (!PyArg_ParseTuple(args, "si", &path, &i)) 713 return NULL; 714 Py_BEGIN_ALLOW_THREADS 715 res = chmod(path, i); 716 Py_END_ALLOW_THREADS 717 if (res < 0) 718 return posix_error_with_filename(path); 719 Py_INCREF(Py_None); 720 return Py_None; 721} 722 723 724#ifdef HAVE_FSYNC 725static char posix_fsync__doc__[] = 726"fsync(fildes) -> None\n\ 727force write of file with filedescriptor to disk."; 728 729static PyObject * 730posix_fsync(PyObject *self, PyObject *args) 731{ 732 return posix_int(args, "i:fsync", fsync); 733} 734#endif /* HAVE_FSYNC */ 735 736#ifdef HAVE_FDATASYNC 737static char posix_fdatasync__doc__[] = 738"fdatasync(fildes) -> None\n\ 739force write of file with filedescriptor to disk.\n\ 740 does not force update of metadata."; 741 742extern int fdatasync(int); /* Prototype just in case */ 743 744static PyObject * 745posix_fdatasync(PyObject *self, PyObject *args) 746{ 747 return posix_int(args, "i:fdatasync", fdatasync); 748} 749#endif /* HAVE_FDATASYNC */ 750 751 752#ifdef HAVE_CHOWN 753static char posix_chown__doc__[] = 754"chown(path, uid, gid) -> None\n\ 755Change the owner and group id of path to the numeric uid and gid."; 756 757static PyObject * 758posix_chown(PyObject *self, PyObject *args) 759{ 760 char *path; 761 int uid, gid; 762 int res; 763 if (!PyArg_ParseTuple(args, "sii:chown", &path, &uid, &gid)) 764 return NULL; 765 Py_BEGIN_ALLOW_THREADS 766 res = chown(path, (uid_t) uid, (gid_t) gid); 767 Py_END_ALLOW_THREADS 768 if (res < 0) 769 return posix_error_with_filename(path); 770 Py_INCREF(Py_None); 771 return Py_None; 772} 773#endif /* HAVE_CHOWN */ 774 775 776#ifdef HAVE_GETCWD 777static char posix_getcwd__doc__[] = 778"getcwd() -> path\n\ 779Return a string representing the current working directory."; 780 781static PyObject * 782posix_getcwd(PyObject *self, PyObject *args) 783{ 784 char buf[1026]; 785 char *res; 786 if (!PyArg_ParseTuple(args, ":getcwd")) 787 return NULL; 788 Py_BEGIN_ALLOW_THREADS 789 res = getcwd(buf, sizeof buf); 790 Py_END_ALLOW_THREADS 791 if (res == NULL) 792 return posix_error(); 793 return PyString_FromString(buf); 794} 795#endif 796 797 798#ifdef HAVE_LINK 799static char posix_link__doc__[] = 800"link(src, dst) -> None\n\ 801Create a hard link to a file."; 802 803static PyObject * 804posix_link(PyObject *self, PyObject *args) 805{ 806 return posix_2str(args, "ss:link", link); 807} 808#endif /* HAVE_LINK */ 809 810 811static char posix_listdir__doc__[] = 812"listdir(path) -> list_of_strings\n\ 813Return a list containing the names of the entries in the directory.\n\ 814\n\ 815 path: path of directory to list\n\ 816\n\ 817The list is in arbitrary order. It does not include the special\n\ 818entries '.' and '..' even if they are present in the directory."; 819 820static PyObject * 821posix_listdir(PyObject *self, PyObject *args) 822{ 823 /* XXX Should redo this putting the (now four) versions of opendir 824 in separate files instead of having them all here... */ 825#if defined(MS_WIN32) && !defined(HAVE_OPENDIR) 826 827 char *name; 828 int len; 829 PyObject *d, *v; 830 HANDLE hFindFile; 831 WIN32_FIND_DATA FileData; 832 char namebuf[MAX_PATH+5]; 833 834 if (!PyArg_ParseTuple(args, "t#:listdir", &name, &len)) 835 return NULL; 836 if (len >= MAX_PATH) { 837 PyErr_SetString(PyExc_ValueError, "path too long"); 838 return NULL; 839 } 840 strcpy(namebuf, name); 841 if (namebuf[len-1] != '/' && namebuf[len-1] != '\\') 842 namebuf[len++] = '/'; 843 strcpy(namebuf + len, "*.*"); 844 845 if ((d = PyList_New(0)) == NULL) 846 return NULL; 847 848 hFindFile = FindFirstFile(namebuf, &FileData); 849 if (hFindFile == INVALID_HANDLE_VALUE) { 850 errno = GetLastError(); 851 if (errno == ERROR_FILE_NOT_FOUND) 852 return PyList_New(0); 853 return win32_error("FindFirstFile", name); 854 } 855 do { 856 if (FileData.cFileName[0] == '.' && 857 (FileData.cFileName[1] == '\0' || 858 FileData.cFileName[1] == '.' && 859 FileData.cFileName[2] == '\0')) 860 continue; 861 v = PyString_FromString(FileData.cFileName); 862 if (v == NULL) { 863 Py_DECREF(d); 864 d = NULL; 865 break; 866 } 867 if (PyList_Append(d, v) != 0) { 868 Py_DECREF(v); 869 Py_DECREF(d); 870 d = NULL; 871 break; 872 } 873 Py_DECREF(v); 874 } while (FindNextFile(hFindFile, &FileData) == TRUE); 875 876 if (FindClose(hFindFile) == FALSE) 877 return win32_error("FindClose", name); 878 879 return d; 880 881#else /* !MS_WIN32 */ 882#ifdef _MSC_VER /* 16-bit Windows */ 883 884#ifndef MAX_PATH 885#define MAX_PATH 250 886#endif 887 char *name, *pt; 888 int len; 889 PyObject *d, *v; 890 char namebuf[MAX_PATH+5]; 891 struct _find_t ep; 892 893 if (!PyArg_ParseTuple(args, "t#:listdir", &name, &len)) 894 return NULL; 895 if (len >= MAX_PATH) { 896 PyErr_SetString(PyExc_ValueError, "path too long"); 897 return NULL; 898 } 899 strcpy(namebuf, name); 900 for (pt = namebuf; *pt; pt++) 901 if (*pt == '/') 902 *pt = '\\'; 903 if (namebuf[len-1] != '\\') 904 namebuf[len++] = '\\'; 905 strcpy(namebuf + len, "*.*"); 906 907 if ((d = PyList_New(0)) == NULL) 908 return NULL; 909 910 if (_dos_findfirst(namebuf, _A_RDONLY | 911 _A_HIDDEN | _A_SYSTEM | _A_SUBDIR, &ep) != 0) 912 { 913 errno = ENOENT; 914 return posix_error_with_filename(name); 915 } 916 do { 917 if (ep.name[0] == '.' && 918 (ep.name[1] == '\0' || 919 ep.name[1] == '.' && 920 ep.name[2] == '\0')) 921 continue; 922 strcpy(namebuf, ep.name); 923 for (pt = namebuf; *pt; pt++) 924 if (isupper(*pt)) 925 *pt = tolower(*pt); 926 v = PyString_FromString(namebuf); 927 if (v == NULL) { 928 Py_DECREF(d); 929 d = NULL; 930 break; 931 } 932 if (PyList_Append(d, v) != 0) { 933 Py_DECREF(v); 934 Py_DECREF(d); 935 d = NULL; 936 break; 937 } 938 Py_DECREF(v); 939 } while (_dos_findnext(&ep) == 0); 940 941 return d; 942 943#else 944#if defined(PYOS_OS2) 945 946#ifndef MAX_PATH 947#define MAX_PATH CCHMAXPATH 948#endif 949 char *name, *pt; 950 int len; 951 PyObject *d, *v; 952 char namebuf[MAX_PATH+5]; 953 HDIR hdir = 1; 954 ULONG srchcnt = 1; 955 FILEFINDBUF3 ep; 956 APIRET rc; 957 958 if (!PyArg_ParseTuple(args, "t#:listdir", &name, &len)) 959 return NULL; 960 if (len >= MAX_PATH) { 961 PyErr_SetString(PyExc_ValueError, "path too long"); 962 return NULL; 963 } 964 strcpy(namebuf, name); 965 for (pt = namebuf; *pt; pt++) 966 if (*pt == '/') 967 *pt = '\\'; 968 if (namebuf[len-1] != '\\') 969 namebuf[len++] = '\\'; 970 strcpy(namebuf + len, "*.*"); 971 972 if ((d = PyList_New(0)) == NULL) 973 return NULL; 974 975 rc = DosFindFirst(namebuf, /* Wildcard Pattern to Match */ 976 &hdir, /* Handle to Use While Search Directory */ 977 FILE_READONLY | FILE_HIDDEN | FILE_SYSTEM | FILE_DIRECTORY, 978 &ep, sizeof(ep), /* Structure to Receive Directory Entry */ 979 &srchcnt, /* Max and Actual Count of Entries Per Iteration */ 980 FIL_STANDARD); /* Format of Entry (EAs or Not) */ 981 982 if (rc != NO_ERROR) { 983 errno = ENOENT; 984 return posix_error_with_filename(name); 985 } 986 987 if (srchcnt > 0) { /* If Directory is NOT Totally Empty, */ 988 do { 989 if (ep.achName[0] == '.' 990 && (ep.achName[1] == '\0' || ep.achName[1] == '.' && ep.achName[2] == '\0')) 991 continue; /* Skip Over "." and ".." Names */ 992 993 strcpy(namebuf, ep.achName); 994 995 /* Leave Case of Name Alone -- In Native Form */ 996 /* (Removed Forced Lowercasing Code) */ 997 998 v = PyString_FromString(namebuf); 999 if (v == NULL) { 1000 Py_DECREF(d); 1001 d = NULL; 1002 break; 1003 } 1004 if (PyList_Append(d, v) != 0) { 1005 Py_DECREF(v); 1006 Py_DECREF(d); 1007 d = NULL; 1008 break; 1009 } 1010 Py_DECREF(v); 1011 } while (DosFindNext(hdir, &ep, sizeof(ep), &srchcnt) == NO_ERROR && srchcnt > 0); 1012 } 1013 1014 return d; 1015#else 1016 1017 char *name; 1018 PyObject *d, *v; 1019 DIR *dirp; 1020 struct dirent *ep; 1021 if (!PyArg_ParseTuple(args, "s:listdir", &name)) 1022 return NULL; 1023 if ((dirp = opendir(name)) == NULL) { 1024 return posix_error_with_filename(name); 1025 } 1026 if ((d = PyList_New(0)) == NULL) { 1027 closedir(dirp); 1028 return NULL; 1029 } 1030 while ((ep = readdir(dirp)) != NULL) { 1031 if (ep->d_name[0] == '.' && 1032 (NAMLEN(ep) == 1 || 1033 (ep->d_name[1] == '.' && NAMLEN(ep) == 2))) 1034 continue; 1035 v = PyString_FromStringAndSize(ep->d_name, NAMLEN(ep)); 1036 if (v == NULL) { 1037 Py_DECREF(d); 1038 d = NULL; 1039 break; 1040 } 1041 if (PyList_Append(d, v) != 0) { 1042 Py_DECREF(v); 1043 Py_DECREF(d); 1044 d = NULL; 1045 break; 1046 } 1047 Py_DECREF(v); 1048 } 1049 closedir(dirp); 1050 1051 return d; 1052 1053#endif /* !PYOS_OS2 */ 1054#endif /* !_MSC_VER */ 1055#endif /* !MS_WIN32 */ 1056} 1057 1058static char posix_mkdir__doc__[] = 1059"mkdir(path [, mode=0777]) -> None\n\ 1060Create a directory."; 1061 1062static PyObject * 1063posix_mkdir(PyObject *self, PyObject *args) 1064{ 1065 int res; 1066 char *path; 1067 int mode = 0777; 1068 if (!PyArg_ParseTuple(args, "s|i:mkdir", &path, &mode)) 1069 return NULL; 1070 Py_BEGIN_ALLOW_THREADS 1071#if ( defined(__WATCOMC__) || defined(_MSC_VER) || defined(PYCC_VACPP) ) && !defined(__QNX__) 1072 res = mkdir(path); 1073#else 1074 res = mkdir(path, mode); 1075#endif 1076 Py_END_ALLOW_THREADS 1077 if (res < 0) 1078 return posix_error_with_filename(path); 1079 Py_INCREF(Py_None); 1080 return Py_None; 1081} 1082 1083 1084#ifdef HAVE_NICE 1085static char posix_nice__doc__[] = 1086"nice(inc) -> new_priority\n\ 1087Decrease the priority of process and return new priority."; 1088 1089static PyObject * 1090posix_nice(PyObject *self, PyObject *args) 1091{ 1092 int increment, value; 1093 1094 if (!PyArg_ParseTuple(args, "i:nice", &increment)) 1095 return NULL; 1096 value = nice(increment); 1097 if (value == -1) 1098 return posix_error(); 1099 return PyInt_FromLong((long) value); 1100} 1101#endif /* HAVE_NICE */ 1102 1103 1104static char posix_rename__doc__[] = 1105"rename(old, new) -> None\n\ 1106Rename a file or directory."; 1107 1108static PyObject * 1109posix_rename(PyObject *self, PyObject *args) 1110{ 1111 return posix_2str(args, "ss:rename", rename); 1112} 1113 1114 1115static char posix_rmdir__doc__[] = 1116"rmdir(path) -> None\n\ 1117Remove a directory."; 1118 1119static PyObject * 1120posix_rmdir(PyObject *self, PyObject *args) 1121{ 1122 return posix_1str(args, "s:rmdir", rmdir); 1123} 1124 1125 1126static char posix_stat__doc__[] = 1127"stat(path) -> (mode,ino,dev,nlink,uid,gid,size,atime,mtime,ctime)\n\ 1128Perform a stat system call on the given path."; 1129 1130static PyObject * 1131posix_stat(PyObject *self, PyObject *args) 1132{ 1133 return posix_do_stat(self, args, "s:stat", STAT); 1134} 1135 1136 1137#ifdef HAVE_SYSTEM 1138static char posix_system__doc__[] = 1139"system(command) -> exit_status\n\ 1140Execute the command (a string) in a subshell."; 1141 1142static PyObject * 1143posix_system(PyObject *self, PyObject *args) 1144{ 1145 char *command; 1146 long sts; 1147 if (!PyArg_ParseTuple(args, "s:system", &command)) 1148 return NULL; 1149 Py_BEGIN_ALLOW_THREADS 1150 sts = system(command); 1151 Py_END_ALLOW_THREADS 1152 return PyInt_FromLong(sts); 1153} 1154#endif 1155 1156 1157static char posix_umask__doc__[] = 1158"umask(new_mask) -> old_mask\n\ 1159Set the current numeric umask and return the previous umask."; 1160 1161static PyObject * 1162posix_umask(PyObject *self, PyObject *args) 1163{ 1164 int i; 1165 if (!PyArg_ParseTuple(args, "i:umask", &i)) 1166 return NULL; 1167 i = umask(i); 1168 if (i < 0) 1169 return posix_error(); 1170 return PyInt_FromLong((long)i); 1171} 1172 1173 1174static char posix_unlink__doc__[] = 1175"unlink(path) -> None\n\ 1176Remove a file (same as remove(path))."; 1177 1178static char posix_remove__doc__[] = 1179"remove(path) -> None\n\ 1180Remove a file (same as unlink(path))."; 1181 1182static PyObject * 1183posix_unlink(PyObject *self, PyObject *args) 1184{ 1185 return posix_1str(args, "s:remove", unlink); 1186} 1187 1188 1189#ifdef HAVE_UNAME 1190static char posix_uname__doc__[] = 1191"uname() -> (sysname, nodename, release, version, machine)\n\ 1192Return a tuple identifying the current operating system."; 1193 1194static PyObject * 1195posix_uname(PyObject *self, PyObject *args) 1196{ 1197 struct utsname u; 1198 int res; 1199 if (!PyArg_ParseTuple(args, ":uname")) 1200 return NULL; 1201 Py_BEGIN_ALLOW_THREADS 1202 res = uname(&u); 1203 Py_END_ALLOW_THREADS 1204 if (res < 0) 1205 return posix_error(); 1206 return Py_BuildValue("(sssss)", 1207 u.sysname, 1208 u.nodename, 1209 u.release, 1210 u.version, 1211 u.machine); 1212} 1213#endif /* HAVE_UNAME */ 1214 1215 1216static char posix_utime__doc__[] = 1217"utime(path, (atime, utime)) -> None\n\ 1218utime(path, None) -> None\n\ 1219Set the access and modified time of the file to the given values. If the\n\ 1220second form is used, set the access and modified times to the current time."; 1221 1222static PyObject * 1223posix_utime(PyObject *self, PyObject *args) 1224{ 1225 char *path; 1226 long atime, mtime; 1227 int res; 1228 PyObject* arg; 1229 1230/* XXX should define struct utimbuf instead, above */ 1231#ifdef HAVE_UTIME_H 1232 struct utimbuf buf; 1233#define ATIME buf.actime 1234#define MTIME buf.modtime 1235#define UTIME_ARG &buf 1236#else /* HAVE_UTIME_H */ 1237 time_t buf[2]; 1238#define ATIME buf[0] 1239#define MTIME buf[1] 1240#define UTIME_ARG buf 1241#endif /* HAVE_UTIME_H */ 1242 1243 if (!PyArg_ParseTuple(args, "sO:utime", &path, &arg)) 1244 return NULL; 1245 if (arg == Py_None) { 1246 /* optional time values not given */ 1247 Py_BEGIN_ALLOW_THREADS 1248 res = utime(path, NULL); 1249 Py_END_ALLOW_THREADS 1250 } 1251 else if (!PyArg_Parse(arg, "(ll)", &atime, &mtime)) { 1252 PyErr_SetString(PyExc_TypeError, 1253 "Second argument must be a 2-tuple of numbers."); 1254 return NULL; 1255 } 1256 else { 1257 ATIME = atime; 1258 MTIME = mtime; 1259 Py_BEGIN_ALLOW_THREADS 1260 res = utime(path, UTIME_ARG); 1261 Py_END_ALLOW_THREADS 1262 } 1263 if (res < 0) 1264 return posix_error_with_filename(path); 1265 Py_INCREF(Py_None); 1266 return Py_None; 1267#undef UTIME_ARG 1268#undef ATIME 1269#undef MTIME 1270} 1271 1272 1273/* Process operations */ 1274 1275static char posix__exit__doc__[] = 1276"_exit(status)\n\ 1277Exit to the system with specified status, without normal exit processing."; 1278 1279static PyObject * 1280posix__exit(PyObject *self, PyObject *args) 1281{ 1282 int sts; 1283 if (!PyArg_ParseTuple(args, "i:_exit", &sts)) 1284 return NULL; 1285 _exit(sts); 1286 return NULL; /* Make gcc -Wall happy */ 1287} 1288 1289 1290#ifdef HAVE_EXECV 1291static char posix_execv__doc__[] = 1292"execv(path, args)\n\ 1293Execute an executable path with arguments, replacing current process.\n\ 1294\n\ 1295 path: path of executable file\n\ 1296 args: tuple or list of strings"; 1297 1298static PyObject * 1299posix_execv(PyObject *self, PyObject *args) 1300{ 1301 char *path; 1302 PyObject *argv; 1303 char **argvlist; 1304 int i, argc; 1305 PyObject *(*getitem)(PyObject *, int); 1306 1307 /* execv has two arguments: (path, argv), where 1308 argv is a list or tuple of strings. */ 1309 1310 if (!PyArg_ParseTuple(args, "sO:execv", &path, &argv)) 1311 return NULL; 1312 if (PyList_Check(argv)) { 1313 argc = PyList_Size(argv); 1314 getitem = PyList_GetItem; 1315 } 1316 else if (PyTuple_Check(argv)) { 1317 argc = PyTuple_Size(argv); 1318 getitem = PyTuple_GetItem; 1319 } 1320 else { 1321 PyErr_SetString(PyExc_TypeError, "argv must be tuple or list"); 1322 return NULL; 1323 } 1324 1325 if (argc == 0) { 1326 PyErr_SetString(PyExc_ValueError, "empty argument list"); 1327 return NULL; 1328 } 1329 1330 argvlist = PyMem_NEW(char *, argc+1); 1331 if (argvlist == NULL) 1332 return NULL; 1333 for (i = 0; i < argc; i++) { 1334 if (!PyArg_Parse((*getitem)(argv, i), "s", &argvlist[i])) { 1335 PyMem_DEL(argvlist); 1336 PyErr_SetString(PyExc_TypeError, 1337 "all arguments must be strings"); 1338 return NULL; 1339 1340 } 1341 } 1342 argvlist[argc] = NULL; 1343 1344#ifdef BAD_EXEC_PROTOTYPES 1345 execv(path, (const char **) argvlist); 1346#else /* BAD_EXEC_PROTOTYPES */ 1347 execv(path, argvlist); 1348#endif /* BAD_EXEC_PROTOTYPES */ 1349 1350 /* If we get here it's definitely an error */ 1351 1352 PyMem_DEL(argvlist); 1353 return posix_error(); 1354} 1355 1356 1357static char posix_execve__doc__[] = 1358"execve(path, args, env)\n\ 1359Execute a path with arguments and environment, replacing current process.\n\ 1360\n\ 1361 path: path of executable file\n\ 1362 args: tuple or list of arguments\n\ 1363 env: dictionary of strings mapping to strings"; 1364 1365static PyObject * 1366posix_execve(PyObject *self, PyObject *args) 1367{ 1368 char *path; 1369 PyObject *argv, *env; 1370 char **argvlist; 1371 char **envlist; 1372 PyObject *key, *val, *keys=NULL, *vals=NULL; 1373 int i, pos, argc, envc; 1374 PyObject *(*getitem)(PyObject *, int); 1375 1376 /* execve has three arguments: (path, argv, env), where 1377 argv is a list or tuple of strings and env is a dictionary 1378 like posix.environ. */ 1379 1380 if (!PyArg_ParseTuple(args, "sOO:execve", &path, &argv, &env)) 1381 return NULL; 1382 if (PyList_Check(argv)) { 1383 argc = PyList_Size(argv); 1384 getitem = PyList_GetItem; 1385 } 1386 else if (PyTuple_Check(argv)) { 1387 argc = PyTuple_Size(argv); 1388 getitem = PyTuple_GetItem; 1389 } 1390 else { 1391 PyErr_SetString(PyExc_TypeError, "argv must be tuple or list"); 1392 return NULL; 1393 } 1394 if (!PyMapping_Check(env)) { 1395 PyErr_SetString(PyExc_TypeError, "env must be mapping object"); 1396 return NULL; 1397 } 1398 1399 if (argc == 0) { 1400 PyErr_SetString(PyExc_ValueError, 1401 "empty argument list"); 1402 return NULL; 1403 } 1404 1405 argvlist = PyMem_NEW(char *, argc+1); 1406 if (argvlist == NULL) { 1407 PyErr_NoMemory(); 1408 return NULL; 1409 } 1410 for (i = 0; i < argc; i++) { 1411 if (!PyArg_Parse((*getitem)(argv, i), 1412 "s;argv must be list of strings", 1413 &argvlist[i])) 1414 { 1415 goto fail_1; 1416 } 1417 } 1418 argvlist[argc] = NULL; 1419 1420 i = PyMapping_Size(env); 1421 envlist = PyMem_NEW(char *, i + 1); 1422 if (envlist == NULL) { 1423 PyErr_NoMemory(); 1424 goto fail_1; 1425 } 1426 envc = 0; 1427 keys = PyMapping_Keys(env); 1428 vals = PyMapping_Values(env); 1429 if (!keys || !vals) 1430 goto fail_2; 1431 1432 for (pos = 0; pos < i; pos++) { 1433 char *p, *k, *v; 1434 1435 key = PyList_GetItem(keys, pos); 1436 val = PyList_GetItem(vals, pos); 1437 if (!key || !val) 1438 goto fail_2; 1439 1440 if (!PyArg_Parse(key, "s;non-string key in env", &k) || 1441 !PyArg_Parse(val, "s;non-string value in env", &v)) 1442 { 1443 goto fail_2; 1444 } 1445 1446#if defined(PYOS_OS2) 1447 /* Omit Pseudo-Env Vars that Would Confuse Programs if Passed On */ 1448 if (stricmp(k, "BEGINLIBPATH") != 0 && stricmp(k, "ENDLIBPATH") != 0) { 1449#endif 1450 p = PyMem_NEW(char, PyString_Size(key)+PyString_Size(val) + 2); 1451 if (p == NULL) { 1452 PyErr_NoMemory(); 1453 goto fail_2; 1454 } 1455 sprintf(p, "%s=%s", k, v); 1456 envlist[envc++] = p; 1457#if defined(PYOS_OS2) 1458 } 1459#endif 1460 } 1461 envlist[envc] = 0; 1462 1463 1464#ifdef BAD_EXEC_PROTOTYPES 1465 execve(path, (const char **)argvlist, envlist); 1466#else /* BAD_EXEC_PROTOTYPES */ 1467 execve(path, argvlist, envlist); 1468#endif /* BAD_EXEC_PROTOTYPES */ 1469 1470 /* If we get here it's definitely an error */ 1471 1472 (void) posix_error(); 1473 1474 fail_2: 1475 while (--envc >= 0) 1476 PyMem_DEL(envlist[envc]); 1477 PyMem_DEL(envlist); 1478 fail_1: 1479 PyMem_DEL(argvlist); 1480 Py_XDECREF(vals); 1481 Py_XDECREF(keys); 1482 return NULL; 1483} 1484#endif /* HAVE_EXECV */ 1485 1486 1487#ifdef HAVE_SPAWNV 1488static char posix_spawnv__doc__[] = 1489"spawnv(mode, path, args)\n\ 1490Execute an executable path with arguments, replacing current process.\n\ 1491\n\ 1492 mode: mode of process creation\n\ 1493 path: path of executable file\n\ 1494 args: tuple or list of strings"; 1495 1496static PyObject * 1497posix_spawnv(PyObject *self, PyObject *args) 1498{ 1499 char *path; 1500 PyObject *argv; 1501 char **argvlist; 1502 int mode, i, argc; 1503 intptr_t spawnval; 1504 PyObject *(*getitem)(PyObject *, int); 1505 1506 /* spawnv has three arguments: (mode, path, argv), where 1507 argv is a list or tuple of strings. */ 1508 1509 if (!PyArg_ParseTuple(args, "isO:spawnv", &mode, &path, &argv)) 1510 return NULL; 1511 if (PyList_Check(argv)) { 1512 argc = PyList_Size(argv); 1513 getitem = PyList_GetItem; 1514 } 1515 else if (PyTuple_Check(argv)) { 1516 argc = PyTuple_Size(argv); 1517 getitem = PyTuple_GetItem; 1518 } 1519 else { 1520 PyErr_SetString(PyExc_TypeError, "argv must be tuple or list"); 1521 return NULL; 1522 } 1523 1524 argvlist = PyMem_NEW(char *, argc+1); 1525 if (argvlist == NULL) 1526 return NULL; 1527 for (i = 0; i < argc; i++) { 1528 if (!PyArg_Parse((*getitem)(argv, i), "s", &argvlist[i])) { 1529 PyMem_DEL(argvlist); 1530 PyErr_SetString(PyExc_TypeError, 1531 "all arguments must be strings"); 1532 return NULL; 1533 } 1534 } 1535 argvlist[argc] = NULL; 1536 1537 if (mode == _OLD_P_OVERLAY) 1538 mode = _P_OVERLAY; 1539 spawnval = _spawnv(mode, path, argvlist); 1540 1541 PyMem_DEL(argvlist); 1542 1543 if (spawnval == -1) 1544 return posix_error(); 1545 else 1546#if SIZEOF_LONG == SIZEOF_VOID_P 1547 return Py_BuildValue("l", (long) spawnval); 1548#else 1549 return Py_BuildValue("L", (LONG_LONG) spawnval); 1550#endif 1551} 1552 1553 1554static char posix_spawnve__doc__[] = 1555"spawnve(mode, path, args, env)\n\ 1556Execute a path with arguments and environment, replacing current process.\n\ 1557\n\ 1558 mode: mode of process creation\n\ 1559 path: path of executable file\n\ 1560 args: tuple or list of arguments\n\ 1561 env: dictionary of strings mapping to strings"; 1562 1563static PyObject * 1564posix_spawnve(PyObject *self, PyObject *args) 1565{ 1566 char *path; 1567 PyObject *argv, *env; 1568 char **argvlist; 1569 char **envlist; 1570 PyObject *key, *val, *keys=NULL, *vals=NULL, *res=NULL; 1571 int mode, i, pos, argc, envc; 1572 intptr_t spawnval; 1573 PyObject *(*getitem)(PyObject *, int); 1574 1575 /* spawnve has four arguments: (mode, path, argv, env), where 1576 argv is a list or tuple of strings and env is a dictionary 1577 like posix.environ. */ 1578 1579 if (!PyArg_ParseTuple(args, "isOO:spawnve", &mode, &path, &argv, &env)) 1580 return NULL; 1581 if (PyList_Check(argv)) { 1582 argc = PyList_Size(argv); 1583 getitem = PyList_GetItem; 1584 } 1585 else if (PyTuple_Check(argv)) { 1586 argc = PyTuple_Size(argv); 1587 getitem = PyTuple_GetItem; 1588 } 1589 else { 1590 PyErr_SetString(PyExc_TypeError, "argv must be tuple or list"); 1591 return NULL; 1592 } 1593 if (!PyMapping_Check(env)) { 1594 PyErr_SetString(PyExc_TypeError, "env must be mapping object"); 1595 return NULL; 1596 } 1597 1598 argvlist = PyMem_NEW(char *, argc+1); 1599 if (argvlist == NULL) { 1600 PyErr_NoMemory(); 1601 return NULL; 1602 } 1603 for (i = 0; i < argc; i++) { 1604 if (!PyArg_Parse((*getitem)(argv, i), 1605 "s;argv must be list of strings", 1606 &argvlist[i])) 1607 { 1608 goto fail_1; 1609 } 1610 } 1611 argvlist[argc] = NULL; 1612 1613 i = PyMapping_Size(env); 1614 envlist = PyMem_NEW(char *, i + 1); 1615 if (envlist == NULL) { 1616 PyErr_NoMemory(); 1617 goto fail_1; 1618 } 1619 envc = 0; 1620 keys = PyMapping_Keys(env); 1621 vals = PyMapping_Values(env); 1622 if (!keys || !vals) 1623 goto fail_2; 1624 1625 for (pos = 0; pos < i; pos++) { 1626 char *p, *k, *v; 1627 1628 key = PyList_GetItem(keys, pos); 1629 val = PyList_GetItem(vals, pos); 1630 if (!key || !val) 1631 goto fail_2; 1632 1633 if (!PyArg_Parse(key, "s;non-string key in env", &k) || 1634 !PyArg_Parse(val, "s;non-string value in env", &v)) 1635 { 1636 goto fail_2; 1637 } 1638 p = PyMem_NEW(char, PyString_Size(key)+PyString_Size(val) + 2); 1639 if (p == NULL) { 1640 PyErr_NoMemory(); 1641 goto fail_2; 1642 } 1643 sprintf(p, "%s=%s", k, v); 1644 envlist[envc++] = p; 1645 } 1646 envlist[envc] = 0; 1647 1648 if (mode == _OLD_P_OVERLAY) 1649 mode = _P_OVERLAY; 1650 spawnval = _spawnve(mode, path, argvlist, envlist); 1651 if (spawnval == -1) 1652 (void) posix_error(); 1653 else 1654#if SIZEOF_LONG == SIZEOF_VOID_P 1655 res = Py_BuildValue("l", (long) spawnval); 1656#else 1657 res = Py_BuildValue("L", (LONG_LONG) spawnval); 1658#endif 1659 1660 fail_2: 1661 while (--envc >= 0) 1662 PyMem_DEL(envlist[envc]); 1663 PyMem_DEL(envlist); 1664 fail_1: 1665 PyMem_DEL(argvlist); 1666 Py_XDECREF(vals); 1667 Py_XDECREF(keys); 1668 return res; 1669} 1670#endif /* HAVE_SPAWNV */ 1671 1672 1673#ifdef HAVE_FORK 1674static char posix_fork__doc__[] = 1675"fork() -> pid\n\ 1676Fork a child process.\n\ 1677\n\ 1678Return 0 to child process and PID of child to parent process."; 1679 1680static PyObject * 1681posix_fork(PyObject *self, PyObject *args) 1682{ 1683 int pid; 1684 if (!PyArg_ParseTuple(args, ":fork")) 1685 return NULL; 1686 pid = fork(); 1687 if (pid == -1) 1688 return posix_error(); 1689 if (pid == 0) 1690 PyOS_AfterFork(); 1691 return PyInt_FromLong((long)pid); 1692} 1693#endif 1694 1695#if defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) 1696#ifdef HAVE_PTY_H 1697#include <pty.h> 1698#else 1699#ifdef HAVE_LIBUTIL_H 1700#include <libutil.h> 1701#else 1702/* BSDI does not supply a prototype for the 'openpty' and 'forkpty' 1703 functions, even though they are included in libutil. */ 1704#include <termios.h> 1705extern int openpty(int *, int *, char *, struct termios *, struct winsize *); 1706extern int forkpty(int *, char *, struct termios *, struct winsize *); 1707#endif /* HAVE_LIBUTIL_H */ 1708#endif /* HAVE_PTY_H */ 1709#endif /* defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) */ 1710 1711#if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) 1712static char posix_openpty__doc__[] = 1713"openpty() -> (master_fd, slave_fd)\n\ 1714Open a pseudo-terminal, returning open fd's for both master and slave end.\n"; 1715 1716static PyObject * 1717posix_openpty(PyObject *self, PyObject *args) 1718{ 1719 int master_fd, slave_fd; 1720#ifndef HAVE_OPENPTY 1721 char * slave_name; 1722 /* SGI apparently needs this forward declaration */ 1723 extern char * _getpty(int *, int, mode_t, int); 1724#endif 1725 1726 if (!PyArg_ParseTuple(args, ":openpty")) 1727 return NULL; 1728 1729#ifdef HAVE_OPENPTY 1730 if (openpty(&master_fd, &slave_fd, NULL, NULL, NULL) != 0) 1731 return posix_error(); 1732#else 1733 slave_name = _getpty(&master_fd, O_RDWR, 0666, 0); 1734 if (slave_name == NULL) 1735 return posix_error(); 1736 1737 slave_fd = open(slave_name, O_RDWR); 1738 if (slave_fd < 0) 1739 return posix_error(); 1740#endif /* defined(HAVE_OPENPTY) */ 1741 1742 return Py_BuildValue("(ii)", master_fd, slave_fd); 1743 1744} 1745#endif /* defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) */ 1746 1747#ifdef HAVE_FORKPTY 1748static char posix_forkpty__doc__[] = 1749"forkpty() -> (pid, master_fd)\n\ 1750Fork a new process with a new pseudo-terminal as controlling tty.\n\n\ 1751Like fork(), return 0 as pid to child process, and PID of child to parent.\n\ 1752To both, return fd of newly opened pseudo-terminal.\n"; 1753 1754static PyObject * 1755posix_forkpty(PyObject *self, PyObject *args) 1756{ 1757 int master_fd, pid; 1758 1759 if (!PyArg_ParseTuple(args, ":forkpty")) 1760 return NULL; 1761 pid = forkpty(&master_fd, NULL, NULL, NULL); 1762 if (pid == -1) 1763 return posix_error(); 1764 if (pid == 0) 1765 PyOS_AfterFork(); 1766 return Py_BuildValue("(ii)", pid, master_fd); 1767} 1768#endif 1769 1770#ifdef HAVE_GETEGID 1771static char posix_getegid__doc__[] = 1772"getegid() -> egid\n\ 1773Return the current process's effective group id."; 1774 1775static PyObject * 1776posix_getegid(PyObject *self, PyObject *args) 1777{ 1778 if (!PyArg_ParseTuple(args, ":getegid")) 1779 return NULL; 1780 return PyInt_FromLong((long)getegid()); 1781} 1782#endif 1783 1784 1785#ifdef HAVE_GETEUID 1786static char posix_geteuid__doc__[] = 1787"geteuid() -> euid\n\ 1788Return the current process's effective user id."; 1789 1790static PyObject * 1791posix_geteuid(PyObject *self, PyObject *args) 1792{ 1793 if (!PyArg_ParseTuple(args, ":geteuid")) 1794 return NULL; 1795 return PyInt_FromLong((long)geteuid()); 1796} 1797#endif 1798 1799 1800#ifdef HAVE_GETGID 1801static char posix_getgid__doc__[] = 1802"getgid() -> gid\n\ 1803Return the current process's group id."; 1804 1805static PyObject * 1806posix_getgid(PyObject *self, PyObject *args) 1807{ 1808 if (!PyArg_ParseTuple(args, ":getgid")) 1809 return NULL; 1810 return PyInt_FromLong((long)getgid()); 1811} 1812#endif 1813 1814 1815static char posix_getpid__doc__[] = 1816"getpid() -> pid\n\ 1817Return the current process id"; 1818 1819static PyObject * 1820posix_getpid(PyObject *self, PyObject *args) 1821{ 1822 if (!PyArg_ParseTuple(args, ":getpid")) 1823 return NULL; 1824 return PyInt_FromLong((long)getpid()); 1825} 1826 1827 1828#ifdef HAVE_GETGROUPS 1829static char posix_getgroups__doc__[] = "\ 1830getgroups() -> list of group IDs\n\ 1831Return list of supplemental group IDs for the process."; 1832 1833static PyObject * 1834posix_getgroups(PyObject *self, PyObject *args) 1835{ 1836 PyObject *result = NULL; 1837 1838 if (PyArg_ParseTuple(args, ":getgroups")) { 1839#ifdef NGROUPS_MAX 1840#define MAX_GROUPS NGROUPS_MAX 1841#else 1842 /* defined to be 16 on Solaris7, so this should be a small number */ 1843#define MAX_GROUPS 64 1844#endif 1845 gid_t grouplist[MAX_GROUPS]; 1846 int n; 1847 1848 n = getgroups(MAX_GROUPS, grouplist); 1849 if (n < 0) 1850 posix_error(); 1851 else { 1852 result = PyList_New(n); 1853 if (result != NULL) { 1854 PyObject *o; 1855 int i; 1856 for (i = 0; i < n; ++i) { 1857 o = PyInt_FromLong((long)grouplist[i]); 1858 if (o == NULL) { 1859 Py_DECREF(result); 1860 result = NULL; 1861 break; 1862 } 1863 PyList_SET_ITEM(result, i, o); 1864 } 1865 } 1866 } 1867 } 1868 return result; 1869} 1870#endif 1871 1872#ifdef HAVE_GETPGRP 1873static char posix_getpgrp__doc__[] = 1874"getpgrp() -> pgrp\n\ 1875Return the current process group id."; 1876 1877static PyObject * 1878posix_getpgrp(PyObject *self, PyObject *args) 1879{ 1880 if (!PyArg_ParseTuple(args, ":getpgrp")) 1881 return NULL; 1882#ifdef GETPGRP_HAVE_ARG 1883 return PyInt_FromLong((long)getpgrp(0)); 1884#else /* GETPGRP_HAVE_ARG */ 1885 return PyInt_FromLong((long)getpgrp()); 1886#endif /* GETPGRP_HAVE_ARG */ 1887} 1888#endif /* HAVE_GETPGRP */ 1889 1890 1891#ifdef HAVE_SETPGRP 1892static char posix_setpgrp__doc__[] = 1893"setpgrp() -> None\n\ 1894Make this process a session leader."; 1895 1896static PyObject * 1897posix_setpgrp(PyObject *self, PyObject *args) 1898{ 1899 if (!PyArg_ParseTuple(args, ":setpgrp")) 1900 return NULL; 1901#ifdef SETPGRP_HAVE_ARG 1902 if (setpgrp(0, 0) < 0) 1903#else /* SETPGRP_HAVE_ARG */ 1904 if (setpgrp() < 0) 1905#endif /* SETPGRP_HAVE_ARG */ 1906 return posix_error(); 1907 Py_INCREF(Py_None); 1908 return Py_None; 1909} 1910 1911#endif /* HAVE_SETPGRP */ 1912 1913#ifdef HAVE_GETPPID 1914static char posix_getppid__doc__[] = 1915"getppid() -> ppid\n\ 1916Return the parent's process id."; 1917 1918static PyObject * 1919posix_getppid(PyObject *self, PyObject *args) 1920{ 1921 if (!PyArg_ParseTuple(args, ":getppid")) 1922 return NULL; 1923 return PyInt_FromLong((long)getppid()); 1924} 1925#endif 1926 1927 1928#ifdef HAVE_GETLOGIN 1929static char posix_getlogin__doc__[] = "\ 1930getlogin() -> string\n\ 1931Return the actual login name."; 1932 1933static PyObject * 1934posix_getlogin(PyObject *self, PyObject *args) 1935{ 1936 PyObject *result = NULL; 1937 1938 if (PyArg_ParseTuple(args, ":getlogin")) { 1939 char *name = getlogin(); 1940 1941 if (name == NULL) 1942 posix_error(); 1943 else 1944 result = PyString_FromString(name); 1945 } 1946 return result; 1947} 1948#endif 1949 1950#ifdef HAVE_GETUID 1951static char posix_getuid__doc__[] = 1952"getuid() -> uid\n\ 1953Return the current process's user id."; 1954 1955static PyObject * 1956posix_getuid(PyObject *self, PyObject *args) 1957{ 1958 if (!PyArg_ParseTuple(args, ":getuid")) 1959 return NULL; 1960 return PyInt_FromLong((long)getuid()); 1961} 1962#endif 1963 1964 1965#ifdef HAVE_KILL 1966static char posix_kill__doc__[] = 1967"kill(pid, sig) -> None\n\ 1968Kill a process with a signal."; 1969 1970static PyObject * 1971posix_kill(PyObject *self, PyObject *args) 1972{ 1973 int pid, sig; 1974 if (!PyArg_ParseTuple(args, "ii:kill", &pid, &sig)) 1975 return NULL; 1976#if defined(PYOS_OS2) 1977 if (sig == XCPT_SIGNAL_INTR || sig == XCPT_SIGNAL_BREAK) { 1978 APIRET rc; 1979 if ((rc = DosSendSignalException(pid, sig)) != NO_ERROR) 1980 return os2_error(rc); 1981 1982 } else if (sig == XCPT_SIGNAL_KILLPROC) { 1983 APIRET rc; 1984 if ((rc = DosKillProcess(DKP_PROCESS, pid)) != NO_ERROR) 1985 return os2_error(rc); 1986 1987 } else 1988 return NULL; /* Unrecognized Signal Requested */ 1989#else 1990 if (kill(pid, sig) == -1) 1991 return posix_error(); 1992#endif 1993 Py_INCREF(Py_None); 1994 return Py_None; 1995} 1996#endif 1997 1998#ifdef HAVE_PLOCK 1999 2000#ifdef HAVE_SYS_LOCK_H 2001#include <sys/lock.h> 2002#endif 2003 2004static char posix_plock__doc__[] = 2005"plock(op) -> None\n\ 2006Lock program segments into memory."; 2007 2008static PyObject * 2009posix_plock(PyObject *self, PyObject *args) 2010{ 2011 int op; 2012 if (!PyArg_ParseTuple(args, "i:plock", &op)) 2013 return NULL; 2014 if (plock(op) == -1) 2015 return posix_error(); 2016 Py_INCREF(Py_None); 2017 return Py_None; 2018} 2019#endif 2020 2021 2022#ifdef HAVE_POPEN 2023static char posix_popen__doc__[] = 2024"popen(command [, mode='r' [, bufsize]]) -> pipe\n\ 2025Open a pipe to/from a command returning a file object."; 2026 2027#if defined(PYOS_OS2) 2028static int 2029async_system(const char *command) 2030{ 2031 char *p, errormsg[256], args[1024]; 2032 RESULTCODES rcodes; 2033 APIRET rc; 2034 char *shell = getenv("COMSPEC"); 2035 if (!shell) 2036 shell = "cmd"; 2037 2038 strcpy(args, shell); 2039 p = &args[ strlen(args)+1 ]; 2040 strcpy(p, "/c "); 2041 strcat(p, command); 2042 p += strlen(p) + 1; 2043 *p = '\0'; 2044 2045 rc = DosExecPgm(errormsg, sizeof(errormsg), 2046 EXEC_ASYNC, /* Execute Async w/o Wait for Results */ 2047 args, 2048 NULL, /* Inherit Parent's Environment */ 2049 &rcodes, shell); 2050 return rc; 2051} 2052 2053static FILE * 2054popen(const char *command, const char *mode, int pipesize, int *err) 2055{ 2056 HFILE rhan, whan; 2057 FILE *retfd = NULL; 2058 APIRET rc = DosCreatePipe(&rhan, &whan, pipesize); 2059 2060 if (rc != NO_ERROR) { 2061 *err = rc; 2062 return NULL; /* ERROR - Unable to Create Anon Pipe */ 2063 } 2064 2065 if (strchr(mode, 'r') != NULL) { /* Treat Command as a Data Source */ 2066 int oldfd = dup(1); /* Save STDOUT Handle in Another Handle */ 2067 2068 DosEnterCritSec(); /* Stop Other Threads While Changing Handles */ 2069 close(1); /* Make STDOUT Available for Reallocation */ 2070 2071 if (dup2(whan, 1) == 0) { /* Connect STDOUT to Pipe Write Side */ 2072 DosClose(whan); /* Close Now-Unused Pipe Write Handle */ 2073 2074 if (async_system(command) == NO_ERROR) 2075 retfd = fdopen(rhan, mode); /* And Return Pipe Read Handle */ 2076 } 2077 2078 dup2(oldfd, 1); /* Reconnect STDOUT to Original Handle */ 2079 DosExitCritSec(); /* Now Allow Other Threads to Run */ 2080 2081 close(oldfd); /* And Close Saved STDOUT Handle */ 2082 return retfd; /* Return fd of Pipe or NULL if Error */ 2083 2084 } else if (strchr(mode, 'w')) { /* Treat Command as a Data Sink */ 2085 int oldfd = dup(0); /* Save STDIN Handle in Another Handle */ 2086 2087 DosEnterCritSec(); /* Stop Other Threads While Changing Handles */ 2088 close(0); /* Make STDIN Available for Reallocation */ 2089 2090 if (dup2(rhan, 0) == 0) { /* Connect STDIN to Pipe Read Side */ 2091 DosClose(rhan); /* Close Now-Unused Pipe Read Handle */ 2092 2093 if (async_system(command) == NO_ERROR) 2094 retfd = fdopen(whan, mode); /* And Return Pipe Write Handle */ 2095 } 2096 2097 dup2(oldfd, 0); /* Reconnect STDIN to Original Handle */ 2098 DosExitCritSec(); /* Now Allow Other Threads to Run */ 2099 2100 close(oldfd); /* And Close Saved STDIN Handle */ 2101 return retfd; /* Return fd of Pipe or NULL if Error */ 2102 2103 } else { 2104 *err = ERROR_INVALID_ACCESS; 2105 return NULL; /* ERROR - Invalid Mode (Neither Read nor Write) */ 2106 } 2107} 2108 2109static PyObject * 2110posix_popen(PyObject *self, PyObject *args) 2111{ 2112 char *name; 2113 char *mode = "r"; 2114 int err, bufsize = -1; 2115 FILE *fp; 2116 PyObject *f; 2117 if (!PyArg_ParseTuple(args, "s|si:popen", &name, &mode, &bufsize)) 2118 return NULL; 2119 Py_BEGIN_ALLOW_THREADS 2120 fp = popen(name, mode, (bufsize > 0) ? bufsize : 4096, &err); 2121 Py_END_ALLOW_THREADS 2122 if (fp == NULL) 2123 return os2_error(err); 2124 2125 f = PyFile_FromFile(fp, name, mode, fclose); 2126 if (f != NULL) 2127 PyFile_SetBufSize(f, bufsize); 2128 return f; 2129} 2130 2131#elif defined(MS_WIN32) 2132 2133/* 2134 * Portable 'popen' replacement for Win32. 2135 * 2136 * Written by Bill Tutt <billtut@microsoft.com>. Minor tweaks 2137 * and 2.0 integration by Fredrik Lundh <fredrik@pythonware.com> 2138 */ 2139 2140#include <malloc.h> 2141#include <io.h> 2142#include <fcntl.h> 2143 2144/* These tell _PyPopen() wether to return 1, 2, or 3 file objects. */ 2145#define POPEN_1 1 2146#define POPEN_2 2 2147#define POPEN_3 3 2148#define POPEN_4 4 2149 2150static PyObject *_PyPopen(char *, int, int); 2151 2152/* popen that works from a GUI. 2153 * 2154 * The result of this function is a pipe (file) connected to the 2155 * processes stdin or stdout, depending on the requested mode. 2156 */ 2157 2158static PyObject * 2159posix_popen(PyObject *self, PyObject *args) 2160{ 2161 PyObject *f, *s; 2162 int tm = 0; 2163 2164 char *cmdstring; 2165 char *mode = "r"; 2166 int bufsize = -1; 2167 if (!PyArg_ParseTuple(args, "s|si:popen", &cmdstring, &mode, &bufsize)) 2168 return NULL; 2169 2170 s = PyTuple_New(0); 2171 2172 if (*mode == 'r') 2173 tm = _O_RDONLY; 2174 else if (*mode != 'w') { 2175 PyErr_SetString(PyExc_ValueError, "mode must be 'r' or 'w'"); 2176 return NULL; 2177 } else 2178 tm = _O_WRONLY; 2179 2180 if (bufsize != -1) { 2181 PyErr_SetString(PyExc_ValueError, "bufsize must be -1"); 2182 return NULL; 2183 } 2184 2185 if (*(mode+1) == 't') 2186 f = _PyPopen(cmdstring, tm | _O_TEXT, POPEN_1); 2187 else if (*(mode+1) == 'b') 2188 f = _PyPopen(cmdstring, tm | _O_BINARY, POPEN_1); 2189 else 2190 f = _PyPopen(cmdstring, tm | _O_TEXT, POPEN_1); 2191 2192 return f; 2193} 2194 2195/* Variation on win32pipe.popen 2196 * 2197 * The result of this function is a pipe (file) connected to the 2198 * process's stdin, and a pipe connected to the process's stdout. 2199 */ 2200 2201static PyObject * 2202win32_popen2(PyObject *self, PyObject *args) 2203{ 2204 PyObject *f; 2205 int tm=0; 2206 2207 char *cmdstring; 2208 char *mode = "t"; 2209 int bufsize = -1; 2210 if (!PyArg_ParseTuple(args, "s|si:popen2", &cmdstring, &mode, &bufsize)) 2211 return NULL; 2212 2213 if (*mode == 't') 2214 tm = _O_TEXT; 2215 else if (*mode != 'b') { 2216 PyErr_SetString(PyExc_ValueError, "mode must be 't' or 'b'"); 2217 return NULL; 2218 } else 2219 tm = _O_BINARY; 2220 2221 if (bufsize != -1) { 2222 PyErr_SetString(PyExc_ValueError, "bufsize must be -1"); 2223 return NULL; 2224 } 2225 2226 f = _PyPopen(cmdstring, tm, POPEN_2); 2227 2228 return f; 2229} 2230 2231/* 2232 * Variation on <om win32pipe.popen> 2233 * 2234 * The result of this function is 3 pipes - the process's stdin, 2235 * stdout and stderr 2236 */ 2237 2238static PyObject * 2239win32_popen3(PyObject *self, PyObject *args) 2240{ 2241 PyObject *f; 2242 int tm = 0; 2243 2244 char *cmdstring; 2245 char *mode = "t"; 2246 int bufsize = -1; 2247 if (!PyArg_ParseTuple(args, "s|si:popen3", &cmdstring, &mode, &bufsize)) 2248 return NULL; 2249 2250 if (*mode == 't') 2251 tm = _O_TEXT; 2252 else if (*mode != 'b') { 2253 PyErr_SetString(PyExc_ValueError, "mode must be 't' or 'b'"); 2254 return NULL; 2255 } else 2256 tm = _O_BINARY; 2257 2258 if (bufsize != -1) { 2259 PyErr_SetString(PyExc_ValueError, "bufsize must be -1"); 2260 return NULL; 2261 } 2262 2263 f = _PyPopen(cmdstring, tm, POPEN_3); 2264 2265 return f; 2266} 2267 2268/* 2269 * Variation on win32pipe.popen 2270 * 2271 * The result of this function is 2 pipes - the processes stdin, 2272 * and stdout+stderr combined as a single pipe. 2273 */ 2274 2275static PyObject * 2276win32_popen4(PyObject *self, PyObject *args) 2277{ 2278 PyObject *f; 2279 int tm = 0; 2280 2281 char *cmdstring; 2282 char *mode = "t"; 2283 int bufsize = -1; 2284 if (!PyArg_ParseTuple(args, "s|si:popen4", &cmdstring, &mode, &bufsize)) 2285 return NULL; 2286 2287 if (*mode == 't') 2288 tm = _O_TEXT; 2289 else if (*mode != 'b') { 2290 PyErr_SetString(PyExc_ValueError, "mode must be 't' or 'b'"); 2291 return NULL; 2292 } else 2293 tm = _O_BINARY; 2294 2295 if (bufsize != -1) { 2296 PyErr_SetString(PyExc_ValueError, "bufsize must be -1"); 2297 return NULL; 2298 } 2299 2300 f = _PyPopen(cmdstring, tm, POPEN_4); 2301 2302 return f; 2303} 2304 2305static int 2306_PyPopenCreateProcess(char *cmdstring, 2307 HANDLE hStdin, 2308 HANDLE hStdout, 2309 HANDLE hStderr) 2310{ 2311 PROCESS_INFORMATION piProcInfo; 2312 STARTUPINFO siStartInfo; 2313 char *s1,*s2, *s3 = " /c "; 2314 const char *szConsoleSpawn = "w9xpopen.exe \""; 2315 int i; 2316 int x; 2317 2318 if (i = GetEnvironmentVariable("COMSPEC",NULL,0)) { 2319 s1 = (char *)_alloca(i); 2320 if (!(x = GetEnvironmentVariable("COMSPEC", s1, i))) 2321 return x; 2322 if (GetVersion() < 0x80000000) { 2323 /* 2324 * NT/2000 2325 */ 2326 x = i + strlen(s3) + strlen(cmdstring) + 1; 2327 s2 = (char *)_alloca(x); 2328 ZeroMemory(s2, x); 2329 sprintf(s2, "%s%s%s", s1, s3, cmdstring); 2330 } 2331 else { 2332 /* 2333 * Oh gag, we're on Win9x. Use the workaround listed in 2334 * KB: Q150956 2335 */ 2336 char modulepath[256]; 2337 GetModuleFileName(NULL, modulepath, sizeof(modulepath)); 2338 for (i = x = 0; modulepath[i]; i++) 2339 if (modulepath[i] == '\\') 2340 x = i+1; 2341 modulepath[x] = '\0'; 2342 x = i + strlen(s3) + strlen(cmdstring) + 1 + 2343 strlen(modulepath) + 2344 strlen(szConsoleSpawn) + 1; 2345 s2 = (char *)_alloca(x); 2346 ZeroMemory(s2, x); 2347 sprintf( 2348 s2, 2349 "%s%s%s%s%s\"", 2350 modulepath, 2351 szConsoleSpawn, 2352 s1, 2353 s3, 2354 cmdstring); 2355 } 2356 } 2357 2358 /* Could be an else here to try cmd.exe / command.com in the path 2359 Now we'll just error out.. */ 2360 else 2361 return -1; 2362 2363 ZeroMemory(&siStartInfo, sizeof(STARTUPINFO)); 2364 siStartInfo.cb = sizeof(STARTUPINFO); 2365 siStartInfo.dwFlags = STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW; 2366 siStartInfo.hStdInput = hStdin; 2367 siStartInfo.hStdOutput = hStdout; 2368 siStartInfo.hStdError = hStderr; 2369 siStartInfo.wShowWindow = SW_HIDE; 2370 2371 if (CreateProcess(NULL, 2372 s2, 2373 NULL, 2374 NULL, 2375 TRUE, 2376 CREATE_NEW_CONSOLE, 2377 NULL, 2378 NULL, 2379 &siStartInfo, 2380 &piProcInfo) ) { 2381 /* Close the handles now so anyone waiting is woken. */ 2382 CloseHandle(piProcInfo.hProcess); 2383 CloseHandle(piProcInfo.hThread); 2384 return TRUE; 2385 } 2386 return FALSE; 2387} 2388 2389/* The following code is based off of KB: Q190351 */ 2390 2391static PyObject * 2392_PyPopen(char *cmdstring, int mode, int n) 2393{ 2394 HANDLE hChildStdinRd, hChildStdinWr, hChildStdoutRd, hChildStdoutWr, 2395 hChildStderrRd, hChildStderrWr, hChildStdinWrDup, hChildStdoutRdDup, 2396 hChildStderrRdDup; /* hChildStdoutWrDup; */ 2397 2398 SECURITY_ATTRIBUTES saAttr; 2399 BOOL fSuccess; 2400 int fd1, fd2, fd3; 2401 FILE *f1, *f2, *f3; 2402 PyObject *f; 2403 2404 saAttr.nLength = sizeof(SECURITY_ATTRIBUTES); 2405 saAttr.bInheritHandle = TRUE; 2406 saAttr.lpSecurityDescriptor = NULL; 2407 2408 if (!CreatePipe(&hChildStdinRd, &hChildStdinWr, &saAttr, 0)) 2409 return win32_error("CreatePipe", NULL); 2410 2411 /* Create new output read handle and the input write handle. Set 2412 * the inheritance properties to FALSE. Otherwise, the child inherits 2413 * the these handles; resulting in non-closeable handles to the pipes 2414 * being created. */ 2415 fSuccess = DuplicateHandle(GetCurrentProcess(), hChildStdinWr, 2416 GetCurrentProcess(), &hChildStdinWrDup, 0, 2417 FALSE, 2418 DUPLICATE_SAME_ACCESS); 2419 if (!fSuccess) 2420 return win32_error("DuplicateHandle", NULL); 2421 2422 /* Close the inheritable version of ChildStdin 2423 that we're using. */ 2424 CloseHandle(hChildStdinWr); 2425 2426 if (!CreatePipe(&hChildStdoutRd, &hChildStdoutWr, &saAttr, 0)) 2427 return win32_error("CreatePipe", NULL); 2428 2429 fSuccess = DuplicateHandle(GetCurrentProcess(), hChildStdoutRd, 2430 GetCurrentProcess(), &hChildStdoutRdDup, 0, 2431 FALSE, DUPLICATE_SAME_ACCESS); 2432 if (!fSuccess) 2433 return win32_error("DuplicateHandle", NULL); 2434 2435 /* Close the inheritable version of ChildStdout 2436 that we're using. */ 2437 CloseHandle(hChildStdoutRd); 2438 2439 if (n != POPEN_4) { 2440 if (!CreatePipe(&hChildStderrRd, &hChildStderrWr, &saAttr, 0)) 2441 return win32_error("CreatePipe", NULL); 2442 fSuccess = DuplicateHandle(GetCurrentProcess(), 2443 hChildStderrRd, 2444 GetCurrentProcess(), 2445 &hChildStderrRdDup, 0, 2446 FALSE, DUPLICATE_SAME_ACCESS); 2447 if (!fSuccess) 2448 return win32_error("DuplicateHandle", NULL); 2449 /* Close the inheritable version of ChildStdErr that we're using. */ 2450 CloseHandle(hChildStderrRd); 2451 } 2452 2453 switch (n) { 2454 case POPEN_1: 2455 switch (mode & (_O_RDONLY | _O_TEXT | _O_BINARY | _O_WRONLY)) { 2456 case _O_WRONLY | _O_TEXT: 2457 /* Case for writing to child Stdin in text mode. */ 2458 fd1 = _open_osfhandle((long)hChildStdinWrDup, mode); 2459 f1 = _fdopen(fd1, "w"); 2460 f = PyFile_FromFile(f1, cmdstring, "w", fclose); 2461 PyFile_SetBufSize(f, 0); 2462 /* We don't care about these pipes anymore, so close them. */ 2463 CloseHandle(hChildStdoutRdDup); 2464 CloseHandle(hChildStderrRdDup); 2465 break; 2466 2467 case _O_RDONLY | _O_TEXT: 2468 /* Case for reading from child Stdout in text mode. */ 2469 fd1 = _open_osfhandle((long)hChildStdoutRdDup, mode); 2470 f1 = _fdopen(fd1, "r"); 2471 f = PyFile_FromFile(f1, cmdstring, "r", fclose); 2472 PyFile_SetBufSize(f, 0); 2473 /* We don't care about these pipes anymore, so close them. */ 2474 CloseHandle(hChildStdinWrDup); 2475 CloseHandle(hChildStderrRdDup); 2476 break; 2477 2478 case _O_RDONLY | _O_BINARY: 2479 /* Case for readinig from child Stdout in binary mode. */ 2480 fd1 = _open_osfhandle((long)hChildStdoutRdDup, mode); 2481 f1 = _fdopen(fd1, "rb"); 2482 f = PyFile_FromFile(f1, cmdstring, "rb", fclose); 2483 PyFile_SetBufSize(f, 0); 2484 /* We don't care about these pipes anymore, so close them. */ 2485 CloseHandle(hChildStdinWrDup); 2486 CloseHandle(hChildStderrRdDup); 2487 break; 2488 2489 case _O_WRONLY | _O_BINARY: 2490 /* Case for writing to child Stdin in binary mode. */ 2491 fd1 = _open_osfhandle((long)hChildStdinWrDup, mode); 2492 f1 = _fdopen(fd1, "wb"); 2493 f = PyFile_FromFile(f1, cmdstring, "wb", fclose); 2494 PyFile_SetBufSize(f, 0); 2495 /* We don't care about these pipes anymore, so close them. */ 2496 CloseHandle(hChildStdoutRdDup); 2497 CloseHandle(hChildStderrRdDup); 2498 break; 2499 } 2500 break; 2501 2502 case POPEN_2: 2503 case POPEN_4: 2504 { 2505 char *m1, *m2; 2506 PyObject *p1, *p2; 2507 2508 if (mode && _O_TEXT) { 2509 m1 = "r"; 2510 m2 = "w"; 2511 } else { 2512 m1 = "rb"; 2513 m2 = "wb"; 2514 } 2515 2516 fd1 = _open_osfhandle((long)hChildStdinWrDup, mode); 2517 f1 = _fdopen(fd1, m2); 2518 fd2 = _open_osfhandle((long)hChildStdoutRdDup, mode); 2519 f2 = _fdopen(fd2, m1); 2520 p1 = PyFile_FromFile(f1, cmdstring, m2, fclose); 2521 PyFile_SetBufSize(p1, 0); 2522 p2 = PyFile_FromFile(f2, cmdstring, m1, fclose); 2523 PyFile_SetBufSize(p2, 0); 2524 2525 if (n != 4) 2526 CloseHandle(hChildStderrRdDup); 2527 2528 f = Py_BuildValue("OO",p1,p2); 2529 break; 2530 } 2531 2532 case POPEN_3: 2533 { 2534 char *m1, *m2; 2535 PyObject *p1, *p2, *p3; 2536 2537 if (mode && _O_TEXT) { 2538 m1 = "r"; 2539 m2 = "w"; 2540 } else { 2541 m1 = "rb"; 2542 m2 = "wb"; 2543 } 2544 2545 fd1 = _open_osfhandle((long)hChildStdinWrDup, mode); 2546 f1 = _fdopen(fd1, m2); 2547 fd2 = _open_osfhandle((long)hChildStdoutRdDup, mode); 2548 f2 = _fdopen(fd2, m1); 2549 fd3 = _open_osfhandle((long)hChildStderrRdDup, mode); 2550 f3 = _fdopen(fd3, m1); 2551 p1 = PyFile_FromFile(f1, cmdstring, m2, fclose); 2552 p2 = PyFile_FromFile(f2, cmdstring, m1, fclose); 2553 p3 = PyFile_FromFile(f3, cmdstring, m1, fclose); 2554 PyFile_SetBufSize(p1, 0); 2555 PyFile_SetBufSize(p2, 0); 2556 PyFile_SetBufSize(p3, 0); 2557 f = Py_BuildValue("OOO",p1,p2,p3); 2558 break; 2559 } 2560 } 2561 2562 if (n == POPEN_4) { 2563 if (!_PyPopenCreateProcess(cmdstring, 2564 hChildStdinRd, 2565 hChildStdoutWr, 2566 hChildStdoutWr)) 2567 return win32_error("CreateProcess", NULL); 2568 } 2569 else { 2570 if (!_PyPopenCreateProcess(cmdstring, 2571 hChildStdinRd, 2572 hChildStdoutWr, 2573 hChildStderrWr)) 2574 return win32_error("CreateProcess", NULL); 2575 } 2576 2577 /* Child is launched. Close the parents copy of those pipe 2578 * handles that only the child should have open. You need to 2579 * make sure that no handles to the write end of the output pipe 2580 * are maintained in this process or else the pipe will not close 2581 * when the child process exits and the ReadFile will hang. */ 2582 2583 if (!CloseHandle(hChildStdinRd)) 2584 return win32_error("CloseHandle", NULL); 2585 2586 if (!CloseHandle(hChildStdoutWr)) 2587 return win32_error("CloseHandle", NULL); 2588 2589 if ((n != 4) && (!CloseHandle(hChildStderrWr))) 2590 return win32_error("CloseHandle", NULL); 2591 2592 return f; 2593} 2594#else 2595static PyObject * 2596posix_popen(PyObject *self, PyObject *args) 2597{ 2598 char *name; 2599 char *mode = "r"; 2600 int bufsize = -1; 2601 FILE *fp; 2602 PyObject *f; 2603 if (!PyArg_ParseTuple(args, "s|si:popen", &name, &mode, &bufsize)) 2604 return NULL; 2605 Py_BEGIN_ALLOW_THREADS 2606 fp = popen(name, mode); 2607 Py_END_ALLOW_THREADS 2608 if (fp == NULL) 2609 return posix_error(); 2610 f = PyFile_FromFile(fp, name, mode, pclose); 2611 if (f != NULL) 2612 PyFile_SetBufSize(f, bufsize); 2613 return f; 2614} 2615#endif 2616 2617#endif /* HAVE_POPEN */ 2618 2619 2620#ifdef HAVE_SETUID 2621static char posix_setuid__doc__[] = 2622"setuid(uid) -> None\n\ 2623Set the current process's user id."; 2624static PyObject * 2625posix_setuid(PyObject *self, PyObject *args) 2626{ 2627 int uid; 2628 if (!PyArg_ParseTuple(args, "i:setuid", &uid)) 2629 return NULL; 2630 if (setuid(uid) < 0) 2631 return posix_error(); 2632 Py_INCREF(Py_None); 2633 return Py_None; 2634} 2635#endif /* HAVE_SETUID */ 2636 2637 2638#ifdef HAVE_SETEUID 2639static char posix_seteuid__doc__[] = 2640"seteuid(uid) -> None\n\ 2641Set the current process's effective user id."; 2642static PyObject * 2643posix_seteuid (PyObject *self, PyObject *args) 2644{ 2645 int euid; 2646 if (!PyArg_ParseTuple(args, "i", &euid)) { 2647 return NULL; 2648 } else if (seteuid(euid) < 0) { 2649 return posix_error(); 2650 } else { 2651 Py_INCREF(Py_None); 2652 return Py_None; 2653 } 2654} 2655#endif /* HAVE_SETEUID */ 2656 2657#ifdef HAVE_SETEGID 2658static char posix_setegid__doc__[] = 2659"setegid(gid) -> None\n\ 2660Set the current process's effective group id."; 2661static PyObject * 2662posix_setegid (PyObject *self, PyObject *args) 2663{ 2664 int egid; 2665 if (!PyArg_ParseTuple(args, "i", &egid)) { 2666 return NULL; 2667 } else if (setegid(egid) < 0) { 2668 return posix_error(); 2669 } else { 2670 Py_INCREF(Py_None); 2671 return Py_None; 2672 } 2673} 2674#endif /* HAVE_SETEGID */ 2675 2676#ifdef HAVE_SETREUID 2677static char posix_setreuid__doc__[] = 2678"seteuid(ruid, euid) -> None\n\ 2679Set the current process's real and effective user ids."; 2680static PyObject * 2681posix_setreuid (PyObject *self, PyObject *args) 2682{ 2683 int ruid, euid; 2684 if (!PyArg_ParseTuple(args, "ii", &ruid, &euid)) { 2685 return NULL; 2686 } else if (setreuid(ruid, euid) < 0) { 2687 return posix_error(); 2688 } else { 2689 Py_INCREF(Py_None); 2690 return Py_None; 2691 } 2692} 2693#endif /* HAVE_SETREUID */ 2694 2695#ifdef HAVE_SETREGID 2696static char posix_setregid__doc__[] = 2697"setegid(rgid, egid) -> None\n\ 2698Set the current process's real and effective group ids."; 2699static PyObject * 2700posix_setregid (PyObject *self, PyObject *args) 2701{ 2702 int rgid, egid; 2703 if (!PyArg_ParseTuple(args, "ii", &rgid, &egid)) { 2704 return NULL; 2705 } else if (setregid(rgid, egid) < 0) { 2706 return posix_error(); 2707 } else { 2708 Py_INCREF(Py_None); 2709 return Py_None; 2710 } 2711} 2712#endif /* HAVE_SETREGID */ 2713 2714#ifdef HAVE_SETGID 2715static char posix_setgid__doc__[] = 2716"setgid(gid) -> None\n\ 2717Set the current process's group id."; 2718 2719static PyObject * 2720posix_setgid(PyObject *self, PyObject *args) 2721{ 2722 int gid; 2723 if (!PyArg_ParseTuple(args, "i:setgid", &gid)) 2724 return NULL; 2725 if (setgid(gid) < 0) 2726 return posix_error(); 2727 Py_INCREF(Py_None); 2728 return Py_None; 2729} 2730#endif /* HAVE_SETGID */ 2731 2732 2733#ifdef HAVE_WAITPID 2734static char posix_waitpid__doc__[] = 2735"waitpid(pid, options) -> (pid, status)\n\ 2736Wait for completion of a give child process."; 2737 2738static PyObject * 2739posix_waitpid(PyObject *self, PyObject *args) 2740{ 2741 int pid, options; 2742#ifdef UNION_WAIT 2743 union wait status; 2744#define status_i (status.w_status) 2745#else 2746 int status; 2747#define status_i status 2748#endif 2749 status_i = 0; 2750 2751 if (!PyArg_ParseTuple(args, "ii:waitpid", &pid, &options)) 2752 return NULL; 2753 Py_BEGIN_ALLOW_THREADS 2754#ifdef NeXT 2755 pid = wait4(pid, &status, options, NULL); 2756#else 2757 pid = waitpid(pid, &status, options); 2758#endif 2759 Py_END_ALLOW_THREADS 2760 if (pid == -1) 2761 return posix_error(); 2762 else 2763 return Py_BuildValue("ii", pid, status_i); 2764} 2765#endif /* HAVE_WAITPID */ 2766 2767 2768#ifdef HAVE_WAIT 2769static char posix_wait__doc__[] = 2770"wait() -> (pid, status)\n\ 2771Wait for completion of a child process."; 2772 2773static PyObject * 2774posix_wait(PyObject *self, PyObject *args) 2775{ 2776 int pid; 2777#ifdef UNION_WAIT 2778 union wait status; 2779#define status_i (status.w_status) 2780#else 2781 int status; 2782#define status_i status 2783#endif 2784 if (!PyArg_ParseTuple(args, ":wait")) 2785 return NULL; 2786 status_i = 0; 2787 Py_BEGIN_ALLOW_THREADS 2788 pid = wait(&status); 2789 Py_END_ALLOW_THREADS 2790 if (pid == -1) 2791 return posix_error(); 2792 else 2793 return Py_BuildValue("ii", pid, status_i); 2794#undef status_i 2795} 2796#endif 2797 2798 2799static char posix_lstat__doc__[] = 2800"lstat(path) -> (mode,ino,dev,nlink,uid,gid,size,atime,mtime,ctime)\n\ 2801Like stat(path), but do not follow symbolic links."; 2802 2803static PyObject * 2804posix_lstat(PyObject *self, PyObject *args) 2805{ 2806#ifdef HAVE_LSTAT 2807 return posix_do_stat(self, args, "s:lstat", lstat); 2808#else /* !HAVE_LSTAT */ 2809 return posix_do_stat(self, args, "s:lstat", STAT); 2810#endif /* !HAVE_LSTAT */ 2811} 2812 2813 2814#ifdef HAVE_READLINK 2815static char posix_readlink__doc__[] = 2816"readlink(path) -> path\n\ 2817Return a string representing the path to which the symbolic link points."; 2818 2819static PyObject * 2820posix_readlink(PyObject *self, PyObject *args) 2821{ 2822 char buf[MAXPATHLEN]; 2823 char *path; 2824 int n; 2825 if (!PyArg_ParseTuple(args, "s:readlink", &path)) 2826 return NULL; 2827 Py_BEGIN_ALLOW_THREADS 2828 n = readlink(path, buf, (int) sizeof buf); 2829 Py_END_ALLOW_THREADS 2830 if (n < 0) 2831 return posix_error_with_filename(path); 2832 return PyString_FromStringAndSize(buf, n); 2833} 2834#endif /* HAVE_READLINK */ 2835 2836 2837#ifdef HAVE_SYMLINK 2838static char posix_symlink__doc__[] = 2839"symlink(src, dst) -> None\n\ 2840Create a symbolic link."; 2841 2842static PyObject * 2843posix_symlink(PyObject *self, PyObject *args) 2844{ 2845 return posix_2str(args, "ss:symlink", symlink); 2846} 2847#endif /* HAVE_SYMLINK */ 2848 2849 2850#ifdef HAVE_TIMES 2851#ifndef HZ 2852#define HZ 60 /* Universal constant :-) */ 2853#endif /* HZ */ 2854 2855#if defined(PYCC_VACPP) && defined(PYOS_OS2) 2856static long 2857system_uptime(void) 2858{ 2859 ULONG value = 0; 2860 2861 Py_BEGIN_ALLOW_THREADS 2862 DosQuerySysInfo(QSV_MS_COUNT, QSV_MS_COUNT, &value, sizeof(value)); 2863 Py_END_ALLOW_THREADS 2864 2865 return value; 2866} 2867 2868static PyObject * 2869posix_times(PyObject *self, PyObject *args) 2870{ 2871 if (!PyArg_ParseTuple(args, ":times")) 2872 return NULL; 2873 2874 /* Currently Only Uptime is Provided -- Others Later */ 2875 return Py_BuildValue("ddddd", 2876 (double)0 /* t.tms_utime / HZ */, 2877 (double)0 /* t.tms_stime / HZ */, 2878 (double)0 /* t.tms_cutime / HZ */, 2879 (double)0 /* t.tms_cstime / HZ */, 2880 (double)system_uptime() / 1000); 2881} 2882#else /* not OS2 */ 2883static PyObject * 2884posix_times(PyObject *self, PyObject *args) 2885{ 2886 struct tms t; 2887 clock_t c; 2888 if (!PyArg_ParseTuple(args, ":times")) 2889 return NULL; 2890 errno = 0; 2891 c = times(&t); 2892 if (c == (clock_t) -1) 2893 return posix_error(); 2894 return Py_BuildValue("ddddd", 2895 (double)t.tms_utime / HZ, 2896 (double)t.tms_stime / HZ, 2897 (double)t.tms_cutime / HZ, 2898 (double)t.tms_cstime / HZ, 2899 (double)c / HZ); 2900} 2901#endif /* not OS2 */ 2902#endif /* HAVE_TIMES */ 2903 2904 2905#ifdef MS_WIN32 2906#define HAVE_TIMES /* so the method table will pick it up */ 2907static PyObject * 2908posix_times(PyObject *self, PyObject *args) 2909{ 2910 FILETIME create, exit, kernel, user; 2911 HANDLE hProc; 2912 if (!PyArg_ParseTuple(args, ":times")) 2913 return NULL; 2914 hProc = GetCurrentProcess(); 2915 GetProcessTimes(hProc, &create, &exit, &kernel, &user); 2916 /* The fields of a FILETIME structure are the hi and lo part 2917 of a 64-bit value expressed in 100 nanosecond units. 2918 1e7 is one second in such units; 1e-7 the inverse. 2919 429.4967296 is 2**32 / 1e7 or 2**32 * 1e-7. 2920 */ 2921 return Py_BuildValue( 2922 "ddddd", 2923 (double)(kernel.dwHighDateTime*429.4967296 + 2924 kernel.dwLowDateTime*1e-7), 2925 (double)(user.dwHighDateTime*429.4967296 + 2926 user.dwLowDateTime*1e-7), 2927 (double)0, 2928 (double)0, 2929 (double)0); 2930} 2931#endif /* MS_WIN32 */ 2932 2933#ifdef HAVE_TIMES 2934static char posix_times__doc__[] = 2935"times() -> (utime, stime, cutime, cstime, elapsed_time)\n\ 2936Return a tuple of floating point numbers indicating process times."; 2937#endif 2938 2939 2940#ifdef HAVE_SETSID 2941static char posix_setsid__doc__[] = 2942"setsid() -> None\n\ 2943Call the system call setsid()."; 2944 2945static PyObject * 2946posix_setsid(PyObject *self, PyObject *args) 2947{ 2948 if (!PyArg_ParseTuple(args, ":setsid")) 2949 return NULL; 2950 if (setsid() < 0) 2951 return posix_error(); 2952 Py_INCREF(Py_None); 2953 return Py_None; 2954} 2955#endif /* HAVE_SETSID */ 2956 2957#ifdef HAVE_SETPGID 2958static char posix_setpgid__doc__[] = 2959"setpgid(pid, pgrp) -> None\n\ 2960Call the system call setpgid()."; 2961 2962static PyObject * 2963posix_setpgid(PyObject *self, PyObject *args) 2964{ 2965 int pid, pgrp; 2966 if (!PyArg_ParseTuple(args, "ii:setpgid", &pid, &pgrp)) 2967 return NULL; 2968 if (setpgid(pid, pgrp) < 0) 2969 return posix_error(); 2970 Py_INCREF(Py_None); 2971 return Py_None; 2972} 2973#endif /* HAVE_SETPGID */ 2974 2975 2976#ifdef HAVE_TCGETPGRP 2977static char posix_tcgetpgrp__doc__[] = 2978"tcgetpgrp(fd) -> pgid\n\ 2979Return the process group associated with the terminal given by a fd."; 2980 2981static PyObject * 2982posix_tcgetpgrp(PyObject *self, PyObject *args) 2983{ 2984 int fd, pgid; 2985 if (!PyArg_ParseTuple(args, "i:tcgetpgrp", &fd)) 2986 return NULL; 2987 pgid = tcgetpgrp(fd); 2988 if (pgid < 0) 2989 return posix_error(); 2990 return PyInt_FromLong((long)pgid); 2991} 2992#endif /* HAVE_TCGETPGRP */ 2993 2994 2995#ifdef HAVE_TCSETPGRP 2996static char posix_tcsetpgrp__doc__[] = 2997"tcsetpgrp(fd, pgid) -> None\n\ 2998Set the process group associated with the terminal given by a fd."; 2999 3000static PyObject * 3001posix_tcsetpgrp(PyObject *self, PyObject *args) 3002{ 3003 int fd, pgid; 3004 if (!PyArg_ParseTuple(args, "ii:tcsetpgrp", &fd, &pgid)) 3005 return NULL; 3006 if (tcsetpgrp(fd, pgid) < 0) 3007 return posix_error(); 3008 Py_INCREF(Py_None); 3009 return Py_None; 3010} 3011#endif /* HAVE_TCSETPGRP */ 3012 3013/* Functions acting on file descriptors */ 3014 3015static char posix_open__doc__[] = 3016"open(filename, flag [, mode=0777]) -> fd\n\ 3017Open a file (for low level IO)."; 3018 3019static PyObject * 3020posix_open(PyObject *self, PyObject *args) 3021{ 3022 char *file; 3023 int flag; 3024 int mode = 0777; 3025 int fd; 3026 if (!PyArg_ParseTuple(args, "si|i", &file, &flag, &mode)) 3027 return NULL; 3028 3029 Py_BEGIN_ALLOW_THREADS 3030 fd = open(file, flag, mode); 3031 Py_END_ALLOW_THREADS 3032 if (fd < 0) 3033 return posix_error_with_filename(file); 3034 return PyInt_FromLong((long)fd); 3035} 3036 3037 3038static char posix_close__doc__[] = 3039"close(fd) -> None\n\ 3040Close a file descriptor (for low level IO)."; 3041 3042static PyObject * 3043posix_close(PyObject *self, PyObject *args) 3044{ 3045 int fd, res; 3046 if (!PyArg_ParseTuple(args, "i:close", &fd)) 3047 return NULL; 3048 Py_BEGIN_ALLOW_THREADS 3049 res = close(fd); 3050 Py_END_ALLOW_THREADS 3051 if (res < 0) 3052 return posix_error(); 3053 Py_INCREF(Py_None); 3054 return Py_None; 3055} 3056 3057 3058static char posix_dup__doc__[] = 3059"dup(fd) -> fd2\n\ 3060Return a duplicate of a file descriptor."; 3061 3062static PyObject * 3063posix_dup(PyObject *self, PyObject *args) 3064{ 3065 int fd; 3066 if (!PyArg_ParseTuple(args, "i:dup", &fd)) 3067 return NULL; 3068 Py_BEGIN_ALLOW_THREADS 3069 fd = dup(fd); 3070 Py_END_ALLOW_THREADS 3071 if (fd < 0) 3072 return posix_error(); 3073 return PyInt_FromLong((long)fd); 3074} 3075 3076 3077static char posix_dup2__doc__[] = 3078"dup2(fd, fd2) -> None\n\ 3079Duplicate file descriptor."; 3080 3081static PyObject * 3082posix_dup2(PyObject *self, PyObject *args) 3083{ 3084 int fd, fd2, res; 3085 if (!PyArg_ParseTuple(args, "ii:dup2", &fd, &fd2)) 3086 return NULL; 3087 Py_BEGIN_ALLOW_THREADS 3088 res = dup2(fd, fd2); 3089 Py_END_ALLOW_THREADS 3090 if (res < 0) 3091 return posix_error(); 3092 Py_INCREF(Py_None); 3093 return Py_None; 3094} 3095 3096 3097static char posix_lseek__doc__[] = 3098"lseek(fd, pos, how) -> newpos\n\ 3099Set the current position of a file descriptor."; 3100 3101static PyObject * 3102posix_lseek(PyObject *self, PyObject *args) 3103{ 3104 int fd, how; 3105#ifdef MS_WIN64 3106 LONG_LONG pos, res; 3107#else 3108 off_t pos, res; 3109#endif 3110 PyObject *posobj; 3111 if (!PyArg_ParseTuple(args, "iOi:lseek", &fd, &posobj, &how)) 3112 return NULL; 3113#ifdef SEEK_SET 3114 /* Turn 0, 1, 2 into SEEK_{SET,CUR,END} */ 3115 switch (how) { 3116 case 0: how = SEEK_SET; break; 3117 case 1: how = SEEK_CUR; break; 3118 case 2: how = SEEK_END; break; 3119 } 3120#endif /* SEEK_END */ 3121 3122#if !defined(HAVE_LARGEFILE_SUPPORT) 3123 pos = PyInt_AsLong(posobj); 3124#else 3125 pos = PyLong_Check(posobj) ? 3126 PyLong_AsLongLong(posobj) : PyInt_AsLong(posobj); 3127#endif 3128 if (PyErr_Occurred()) 3129 return NULL; 3130 3131 Py_BEGIN_ALLOW_THREADS 3132#ifdef MS_WIN64 3133 res = _lseeki64(fd, pos, how); 3134#else 3135 res = lseek(fd, pos, how); 3136#endif 3137 Py_END_ALLOW_THREADS 3138 if (res < 0) 3139 return posix_error(); 3140 3141#if !defined(HAVE_LARGEFILE_SUPPORT) 3142 return PyInt_FromLong(res); 3143#else 3144 return PyLong_FromLongLong(res); 3145#endif 3146} 3147 3148 3149static char posix_read__doc__[] = 3150"read(fd, buffersize) -> string\n\ 3151Read a file descriptor."; 3152 3153static PyObject * 3154posix_read(PyObject *self, PyObject *args) 3155{ 3156 int fd, size, n; 3157 PyObject *buffer; 3158 if (!PyArg_ParseTuple(args, "ii:read", &fd, &size)) 3159 return NULL; 3160 buffer = PyString_FromStringAndSize((char *)NULL, size); 3161 if (buffer == NULL) 3162 return NULL; 3163 Py_BEGIN_ALLOW_THREADS 3164 n = read(fd, PyString_AsString(buffer), size); 3165 Py_END_ALLOW_THREADS 3166 if (n < 0) { 3167 Py_DECREF(buffer); 3168 return posix_error(); 3169 } 3170 if (n != size) 3171 _PyString_Resize(&buffer, n); 3172 return buffer; 3173} 3174 3175 3176static char posix_write__doc__[] = 3177"write(fd, string) -> byteswritten\n\ 3178Write a string to a file descriptor."; 3179 3180static PyObject * 3181posix_write(PyObject *self, PyObject *args) 3182{ 3183 int fd, size; 3184 char *buffer; 3185 if (!PyArg_ParseTuple(args, "is#:write", &fd, &buffer, &size)) 3186 return NULL; 3187 Py_BEGIN_ALLOW_THREADS 3188 size = write(fd, buffer, size); 3189 Py_END_ALLOW_THREADS 3190 if (size < 0) 3191 return posix_error(); 3192 return PyInt_FromLong((long)size); 3193} 3194 3195 3196static char posix_fstat__doc__[]= 3197"fstat(fd) -> (mode, ino, dev, nlink, uid, gid, size, atime, mtime, ctime)\n\ 3198Like stat(), but for an open file descriptor."; 3199 3200static PyObject * 3201posix_fstat(PyObject *self, PyObject *args) 3202{ 3203 int fd; 3204 STRUCT_STAT st; 3205 int res; 3206 if (!PyArg_ParseTuple(args, "i:fstat", &fd)) 3207 return NULL; 3208 Py_BEGIN_ALLOW_THREADS 3209 res = FSTAT(fd, &st); 3210 Py_END_ALLOW_THREADS 3211 if (res != 0) 3212 return posix_error(); 3213 3214 return _pystat_fromstructstat(st); 3215} 3216 3217 3218static char posix_fdopen__doc__[] = 3219"fdopen(fd, [, mode='r' [, bufsize]]) -> file_object\n\ 3220Return an open file object connected to a file descriptor."; 3221 3222static PyObject * 3223posix_fdopen(PyObject *self, PyObject *args) 3224{ 3225 extern int fclose(FILE *); 3226 int fd; 3227 char *mode = "r"; 3228 int bufsize = -1; 3229 FILE *fp; 3230 PyObject *f; 3231 if (!PyArg_ParseTuple(args, "i|si", &fd, &mode, &bufsize)) 3232 return NULL; 3233 3234 Py_BEGIN_ALLOW_THREADS 3235 fp = fdopen(fd, mode); 3236 Py_END_ALLOW_THREADS 3237 if (fp == NULL) 3238 return posix_error(); 3239 f = PyFile_FromFile(fp, "(fdopen)", mode, fclose); 3240 if (f != NULL) 3241 PyFile_SetBufSize(f, bufsize); 3242 return f; 3243} 3244 3245static char posix_isatty__doc__[] = 3246"isatty(fd) -> Boolean\n\ 3247Return true if the file descriptor 'fd' is an open file descriptor\n\ 3248connected to a terminal."; 3249 3250static PyObject * 3251posix_isatty(PyObject *self, PyObject *args) 3252{ 3253 int fd; 3254 if (!PyArg_ParseTuple(args, "i:isatty", &fd)) 3255 return NULL; 3256 return Py_BuildValue("i", isatty(fd)); 3257} 3258 3259#ifdef HAVE_PIPE 3260static char posix_pipe__doc__[] = 3261"pipe() -> (read_end, write_end)\n\ 3262Create a pipe."; 3263 3264static PyObject * 3265posix_pipe(PyObject *self, PyObject *args) 3266{ 3267#if defined(PYOS_OS2) 3268 HFILE read, write; 3269 APIRET rc; 3270 3271 if (!PyArg_ParseTuple(args, ":pipe")) 3272 return NULL; 3273 3274 Py_BEGIN_ALLOW_THREADS 3275 rc = DosCreatePipe( &read, &write, 4096); 3276 Py_END_ALLOW_THREADS 3277 if (rc != NO_ERROR) 3278 return os2_error(rc); 3279 3280 return Py_BuildValue("(ii)", read, write); 3281#else 3282#if !defined(MS_WIN32) 3283 int fds[2]; 3284 int res; 3285 if (!PyArg_ParseTuple(args, ":pipe")) 3286 return NULL; 3287 Py_BEGIN_ALLOW_THREADS 3288 res = pipe(fds); 3289 Py_END_ALLOW_THREADS 3290 if (res != 0) 3291 return posix_error(); 3292 return Py_BuildValue("(ii)", fds[0], fds[1]); 3293#else /* MS_WIN32 */ 3294 HANDLE read, write; 3295 int read_fd, write_fd; 3296 BOOL ok; 3297 if (!PyArg_ParseTuple(args, ":pipe")) 3298 return NULL; 3299 Py_BEGIN_ALLOW_THREADS 3300 ok = CreatePipe(&read, &write, NULL, 0); 3301 Py_END_ALLOW_THREADS 3302 if (!ok) 3303 return win32_error("CreatePipe", NULL); 3304 read_fd = _open_osfhandle((intptr_t)read, 0); 3305 write_fd = _open_osfhandle((intptr_t)write, 1); 3306 return Py_BuildValue("(ii)", read_fd, write_fd); 3307#endif /* MS_WIN32 */ 3308#endif 3309} 3310#endif /* HAVE_PIPE */ 3311 3312 3313#ifdef HAVE_MKFIFO 3314static char posix_mkfifo__doc__[] = 3315"mkfifo(file, [, mode=0666]) -> None\n\ 3316Create a FIFO (a POSIX named pipe)."; 3317 3318static PyObject * 3319posix_mkfifo(PyObject *self, PyObject *args) 3320{ 3321 char *file; 3322 int mode = 0666; 3323 int res; 3324 if (!PyArg_ParseTuple(args, "s|i:mkfifo", &file, &mode)) 3325 return NULL; 3326 Py_BEGIN_ALLOW_THREADS 3327 res = mkfifo(file, mode); 3328 Py_END_ALLOW_THREADS 3329 if (res < 0) 3330 return posix_error(); 3331 Py_INCREF(Py_None); 3332 return Py_None; 3333} 3334#endif 3335 3336 3337#ifdef HAVE_FTRUNCATE 3338static char posix_ftruncate__doc__[] = 3339"ftruncate(fd, length) -> None\n\ 3340Truncate a file to a specified length."; 3341 3342static PyObject * 3343posix_ftruncate(PyObject *self, PyObject *args) 3344{ 3345 int fd; 3346 off_t length; 3347 int res; 3348 PyObject *lenobj; 3349 3350 if (!PyArg_ParseTuple(args, "iO:ftruncate", &fd, &lenobj)) 3351 return NULL; 3352 3353#if !defined(HAVE_LARGEFILE_SUPPORT) 3354 length = PyInt_AsLong(lenobj); 3355#else 3356 length = PyLong_Check(lenobj) ? 3357 PyLong_AsLongLong(lenobj) : PyInt_AsLong(lenobj); 3358#endif 3359 if (PyErr_Occurred()) 3360 return NULL; 3361 3362 Py_BEGIN_ALLOW_THREADS 3363 res = ftruncate(fd, length); 3364 Py_END_ALLOW_THREADS 3365 if (res < 0) { 3366 PyErr_SetFromErrno(PyExc_IOError); 3367 return NULL; 3368 } 3369 Py_INCREF(Py_None); 3370 return Py_None; 3371} 3372#endif 3373 3374#ifdef NeXT 3375#define HAVE_PUTENV 3376/* Steve Spicklemire got this putenv from NeXTAnswers */ 3377static int 3378putenv(char *newval) 3379{ 3380 extern char **environ; 3381 3382 static int firstTime = 1; 3383 char **ep; 3384 char *cp; 3385 int esiz; 3386 char *np; 3387 3388 if (!(np = strchr(newval, '='))) 3389 return 1; 3390 *np = '\0'; 3391 3392 /* look it up */ 3393 for (ep=environ ; *ep ; ep++) 3394 { 3395 /* this should always be true... */ 3396 if (cp = strchr(*ep, '=')) 3397 { 3398 *cp = '\0'; 3399 if (!strcmp(*ep, newval)) 3400 { 3401 /* got it! */ 3402 *cp = '='; 3403 break; 3404 } 3405 *cp = '='; 3406 } 3407 else 3408 { 3409 *np = '='; 3410 return 1; 3411 } 3412 } 3413 3414 *np = '='; 3415 if (*ep) 3416 { 3417 /* the string was already there: 3418 just replace it with the new one */ 3419 *ep = newval; 3420 return 0; 3421 } 3422 3423 /* expand environ by one */ 3424 for (esiz=2, ep=environ ; *ep ; ep++) 3425 esiz++; 3426 if (firstTime) 3427 { 3428 char **epp; 3429 char **newenv; 3430 if (!(newenv = malloc(esiz * sizeof(char *)))) 3431 return 1; 3432 3433 for (ep=environ, epp=newenv ; *ep ;) 3434 *epp++ = *ep++; 3435 *epp++ = newval; 3436 *epp = (char *) 0; 3437 environ = newenv; 3438 } 3439 else 3440 { 3441 if (!(environ = realloc(environ, esiz * sizeof(char *)))) 3442 return 1; 3443 environ[esiz - 2] = newval; 3444 environ[esiz - 1] = (char *) 0; 3445 firstTime = 0; 3446 } 3447 3448 return 0; 3449} 3450#endif /* NeXT */ 3451 3452 3453#ifdef HAVE_PUTENV 3454static char posix_putenv__doc__[] = 3455"putenv(key, value) -> None\n\ 3456Change or add an environment variable."; 3457 3458#ifdef __BEOS__ 3459/* We have putenv(), but not in the headers (as of PR2). - [cjh] */ 3460int putenv( const char *str ); 3461#endif 3462 3463/* Save putenv() parameters as values here, so we can collect them when they 3464 * get re-set with another call for the same key. */ 3465static PyObject *posix_putenv_garbage; 3466 3467static PyObject * 3468posix_putenv(PyObject *self, PyObject *args) 3469{ 3470 char *s1, *s2; 3471 char *new; 3472 PyObject *newstr; 3473 3474 if (!PyArg_ParseTuple(args, "ss:putenv", &s1, &s2)) 3475 return NULL; 3476 3477#if defined(PYOS_OS2) 3478 if (stricmp(s1, "BEGINLIBPATH") == 0) { 3479 APIRET rc; 3480 3481 if (strlen(s2) == 0) /* If New Value is an Empty String */ 3482 s2 = NULL; /* Then OS/2 API Wants a NULL to Undefine It */ 3483 3484 rc = DosSetExtLIBPATH(s2, BEGIN_LIBPATH); 3485 if (rc != NO_ERROR) 3486 return os2_error(rc); 3487 3488 } else if (stricmp(s1, "ENDLIBPATH") == 0) { 3489 APIRET rc; 3490 3491 if (strlen(s2) == 0) /* If New Value is an Empty String */ 3492 s2 = NULL; /* Then OS/2 API Wants a NULL to Undefine It */ 3493 3494 rc = DosSetExtLIBPATH(s2, END_LIBPATH); 3495 if (rc != NO_ERROR) 3496 return os2_error(rc); 3497 } else { 3498#endif 3499 3500 /* XXX This can leak memory -- not easy to fix :-( */ 3501 newstr = PyString_FromStringAndSize(NULL, strlen(s1) + strlen(s2) + 2); 3502 if (newstr == NULL) 3503 return PyErr_NoMemory(); 3504 new = PyString_AS_STRING(newstr); 3505 (void) sprintf(new, "%s=%s", s1, s2); 3506 if (putenv(new)) { 3507 posix_error(); 3508 return NULL; 3509 } 3510 /* Install the first arg and newstr in posix_putenv_garbage; 3511 * this will cause previous value to be collected. This has to 3512 * happen after the real putenv() call because the old value 3513 * was still accessible until then. */ 3514 if (PyDict_SetItem(posix_putenv_garbage, 3515 PyTuple_GET_ITEM(args, 0), newstr)) { 3516 /* really not much we can do; just leak */ 3517 PyErr_Clear(); 3518 } 3519 else { 3520 Py_DECREF(newstr); 3521 } 3522 3523#if defined(PYOS_OS2) 3524 } 3525#endif 3526 Py_INCREF(Py_None); 3527 return Py_None; 3528} 3529#endif /* putenv */ 3530 3531#ifdef HAVE_STRERROR 3532static char posix_strerror__doc__[] = 3533"strerror(code) -> string\n\ 3534Translate an error code to a message string."; 3535 3536PyObject * 3537posix_strerror(PyObject *self, PyObject *args) 3538{ 3539 int code; 3540 char *message; 3541 if (!PyArg_ParseTuple(args, "i:strerror", &code)) 3542 return NULL; 3543 message = strerror(code); 3544 if (message == NULL) { 3545 PyErr_SetString(PyExc_ValueError, 3546 "strerror code out of range"); 3547 return NULL; 3548 } 3549 return PyString_FromString(message); 3550} 3551#endif /* strerror */ 3552 3553 3554#ifdef HAVE_SYS_WAIT_H 3555 3556#ifdef WIFSTOPPED 3557static char posix_WIFSTOPPED__doc__[] = 3558"WIFSTOPPED(status) -> Boolean\n\ 3559Return true if the process returning 'status' was stopped."; 3560 3561static PyObject * 3562posix_WIFSTOPPED(PyObject *self, PyObject *args) 3563{ 3564#ifdef UNION_WAIT 3565 union wait status; 3566#define status_i (status.w_status) 3567#else 3568 int status; 3569#define status_i status 3570#endif 3571 status_i = 0; 3572 3573 if (!PyArg_ParseTuple(args, "i:WIFSTOPPED", &status_i)) 3574 { 3575 return NULL; 3576 } 3577 3578 return Py_BuildValue("i", WIFSTOPPED(status)); 3579#undef status_i 3580} 3581#endif /* WIFSTOPPED */ 3582 3583#ifdef WIFSIGNALED 3584static char posix_WIFSIGNALED__doc__[] = 3585"WIFSIGNALED(status) -> Boolean\n\ 3586Return true if the process returning 'status' was terminated by a signal."; 3587 3588static PyObject * 3589posix_WIFSIGNALED(PyObject *self, PyObject *args) 3590{ 3591#ifdef UNION_WAIT 3592 union wait status; 3593#define status_i (status.w_status) 3594#else 3595 int status; 3596#define status_i status 3597#endif 3598 status_i = 0; 3599 3600 if (!PyArg_ParseTuple(args, "i:WIFSIGNALED", &status_i)) 3601 { 3602 return NULL; 3603 } 3604 3605 return Py_BuildValue("i", WIFSIGNALED(status)); 3606#undef status_i 3607} 3608#endif /* WIFSIGNALED */ 3609 3610#ifdef WIFEXITED 3611static char posix_WIFEXITED__doc__[] = 3612"WIFEXITED(status) -> Boolean\n\ 3613Return true if the process returning 'status' exited using the exit()\n\ 3614system call."; 3615 3616static PyObject * 3617posix_WIFEXITED(PyObject *self, PyObject *args) 3618{ 3619#ifdef UNION_WAIT 3620 union wait status; 3621#define status_i (status.w_status) 3622#else 3623 int status; 3624#define status_i status 3625#endif 3626 status_i = 0; 3627 3628 if (!PyArg_ParseTuple(args, "i:WIFEXITED", &status_i)) 3629 { 3630 return NULL; 3631 } 3632 3633 return Py_BuildValue("i", WIFEXITED(status)); 3634#undef status_i 3635} 3636#endif /* WIFEXITED */ 3637 3638#ifdef WEXITSTATUS 3639static char posix_WEXITSTATUS__doc__[] = 3640"WEXITSTATUS(status) -> integer\n\ 3641Return the process return code from 'status'."; 3642 3643static PyObject * 3644posix_WEXITSTATUS(PyObject *self, PyObject *args) 3645{ 3646#ifdef UNION_WAIT 3647 union wait status; 3648#define status_i (status.w_status) 3649#else 3650 int status; 3651#define status_i status 3652#endif 3653 status_i = 0; 3654 3655 if (!PyArg_ParseTuple(args, "i:WEXITSTATUS", &status_i)) 3656 { 3657 return NULL; 3658 } 3659 3660 return Py_BuildValue("i", WEXITSTATUS(status)); 3661#undef status_i 3662} 3663#endif /* WEXITSTATUS */ 3664 3665#ifdef WTERMSIG 3666static char posix_WTERMSIG__doc__[] = 3667"WTERMSIG(status) -> integer\n\ 3668Return the signal that terminated the process that provided the 'status'\n\ 3669value."; 3670 3671static PyObject * 3672posix_WTERMSIG(PyObject *self, PyObject *args) 3673{ 3674#ifdef UNION_WAIT 3675 union wait status; 3676#define status_i (status.w_status) 3677#else 3678 int status; 3679#define status_i status 3680#endif 3681 status_i = 0; 3682 3683 if (!PyArg_ParseTuple(args, "i:WTERMSIG", &status_i)) 3684 { 3685 return NULL; 3686 } 3687 3688 return Py_BuildValue("i", WTERMSIG(status)); 3689#undef status_i 3690} 3691#endif /* WTERMSIG */ 3692 3693#ifdef WSTOPSIG 3694static char posix_WSTOPSIG__doc__[] = 3695"WSTOPSIG(status) -> integer\n\ 3696Return the signal that stopped the process that provided the 'status' value."; 3697 3698static PyObject * 3699posix_WSTOPSIG(PyObject *self, PyObject *args) 3700{ 3701#ifdef UNION_WAIT 3702 union wait status; 3703#define status_i (status.w_status) 3704#else 3705 int status; 3706#define status_i status 3707#endif 3708 status_i = 0; 3709 3710 if (!PyArg_ParseTuple(args, "i:WSTOPSIG", &status_i)) 3711 { 3712 return NULL; 3713 } 3714 3715 return Py_BuildValue("i", WSTOPSIG(status)); 3716#undef status_i 3717} 3718#endif /* WSTOPSIG */ 3719 3720#endif /* HAVE_SYS_WAIT_H */ 3721 3722 3723#if defined(HAVE_FSTATVFS) 3724#ifdef _SCO_DS 3725/* SCO OpenServer 5.0 and later requires _SVID3 before it reveals the 3726 needed definitions in sys/statvfs.h */ 3727#define _SVID3 3728#endif 3729#include <sys/statvfs.h> 3730 3731static char posix_fstatvfs__doc__[] = 3732"fstatvfs(fd) -> \n\ 3733 (bsize, frsize, blocks, bfree, bavail, files, ffree, favail, flag, namemax)\n\ 3734Perform an fstatvfs system call on the given fd."; 3735 3736static PyObject * 3737posix_fstatvfs(PyObject *self, PyObject *args) 3738{ 3739 int fd, res; 3740 struct statvfs st; 3741 if (!PyArg_ParseTuple(args, "i:fstatvfs", &fd)) 3742 return NULL; 3743 Py_BEGIN_ALLOW_THREADS 3744 res = fstatvfs(fd, &st); 3745 Py_END_ALLOW_THREADS 3746 if (res != 0) 3747 return posix_error(); 3748#if !defined(HAVE_LARGEFILE_SUPPORT) 3749 return Py_BuildValue("(llllllllll)", 3750 (long) st.f_bsize, 3751 (long) st.f_frsize, 3752 (long) st.f_blocks, 3753 (long) st.f_bfree, 3754 (long) st.f_bavail, 3755 (long) st.f_files, 3756 (long) st.f_ffree, 3757 (long) st.f_favail, 3758 (long) st.f_flag, 3759 (long) st.f_namemax); 3760#else 3761 return Py_BuildValue("(llLLLLLLll)", 3762 (long) st.f_bsize, 3763 (long) st.f_frsize, 3764 (LONG_LONG) st.f_blocks, 3765 (LONG_LONG) st.f_bfree, 3766 (LONG_LONG) st.f_bavail, 3767 (LONG_LONG) st.f_files, 3768 (LONG_LONG) st.f_ffree, 3769 (LONG_LONG) st.f_favail, 3770 (long) st.f_flag, 3771 (long) st.f_namemax); 3772#endif 3773} 3774#endif /* HAVE_FSTATVFS */ 3775 3776 3777#if defined(HAVE_STATVFS) 3778#include <sys/statvfs.h> 3779 3780static char posix_statvfs__doc__[] = 3781"statvfs(path) -> \n\ 3782 (bsize, frsize, blocks, bfree, bavail, files, ffree, favail, flag, namemax)\n\ 3783Perform a statvfs system call on the given path."; 3784 3785static PyObject * 3786posix_statvfs(PyObject *self, PyObject *args) 3787{ 3788 char *path; 3789 int res; 3790 struct statvfs st; 3791 if (!PyArg_ParseTuple(args, "s:statvfs", &path)) 3792 return NULL; 3793 Py_BEGIN_ALLOW_THREADS 3794 res = statvfs(path, &st); 3795 Py_END_ALLOW_THREADS 3796 if (res != 0) 3797 return posix_error_with_filename(path); 3798#if !defined(HAVE_LARGEFILE_SUPPORT) 3799 return Py_BuildValue("(llllllllll)", 3800 (long) st.f_bsize, 3801 (long) st.f_frsize, 3802 (long) st.f_blocks, 3803 (long) st.f_bfree, 3804 (long) st.f_bavail, 3805 (long) st.f_files, 3806 (long) st.f_ffree, 3807 (long) st.f_favail, 3808 (long) st.f_flag, 3809 (long) st.f_namemax); 3810#else /* HAVE_LARGEFILE_SUPPORT */ 3811 return Py_BuildValue("(llLLLLLLll)", 3812 (long) st.f_bsize, 3813 (long) st.f_frsize, 3814 (LONG_LONG) st.f_blocks, 3815 (LONG_LONG) st.f_bfree, 3816 (LONG_LONG) st.f_bavail, 3817 (LONG_LONG) st.f_files, 3818 (LONG_LONG) st.f_ffree, 3819 (LONG_LONG) st.f_favail, 3820 (long) st.f_flag, 3821 (long) st.f_namemax); 3822#endif 3823} 3824#endif /* HAVE_STATVFS */ 3825 3826 3827#ifdef HAVE_TEMPNAM 3828static char posix_tempnam__doc__[] = "\ 3829tempnam([dir[, prefix]]) -> string\n\ 3830Return a unique name for a temporary file.\n\ 3831The directory and a short may be specified as strings; they may be omitted\n\ 3832or None if not needed."; 3833 3834static PyObject * 3835posix_tempnam(PyObject *self, PyObject *args) 3836{ 3837 PyObject *result = NULL; 3838 char *dir = NULL; 3839 char *pfx = NULL; 3840 char *name; 3841 3842 if (!PyArg_ParseTuple(args, "|zz:tempnam", &dir, &pfx)) 3843 return NULL; 3844 name = tempnam(dir, pfx); 3845 if (name == NULL) 3846 return PyErr_NoMemory(); 3847 result = PyString_FromString(name); 3848 free(name); 3849 return result; 3850} 3851#endif 3852 3853 3854#ifdef HAVE_TMPFILE 3855static char posix_tmpfile__doc__[] = "\ 3856tmpfile() -> file object\n\ 3857Create a temporary file with no directory entries."; 3858 3859static PyObject * 3860posix_tmpfile(PyObject *self, PyObject *args) 3861{ 3862 FILE *fp; 3863 3864 if (!PyArg_ParseTuple(args, ":tmpfile")) 3865 return NULL; 3866 fp = tmpfile(); 3867 if (fp == NULL) 3868 return posix_error(); 3869 return PyFile_FromFile(fp, "<tmpfile>", "w+", fclose); 3870} 3871#endif 3872 3873 3874#ifdef HAVE_TMPNAM 3875static char posix_tmpnam__doc__[] = "\ 3876tmpnam() -> string\n\ 3877Return a unique name for a temporary file."; 3878 3879static PyObject * 3880posix_tmpnam(PyObject *self, PyObject *args) 3881{ 3882 char buffer[L_tmpnam]; 3883 char *name; 3884 3885 if (!PyArg_ParseTuple(args, ":tmpnam")) 3886 return NULL; 3887#ifdef USE_TMPNAM_R 3888 name = tmpnam_r(buffer); 3889#else 3890 name = tmpnam(buffer); 3891#endif 3892 if (name == NULL) { 3893 PyErr_SetObject(PyExc_OSError, 3894 Py_BuildValue("is", 0, 3895#ifdef USE_TMPNAM_R 3896 "unexpected NULL from tmpnam_r" 3897#else 3898 "unexpected NULL from tmpnam" 3899#endif 3900 )); 3901 return NULL; 3902 } 3903 return PyString_FromString(buffer); 3904} 3905#endif 3906 3907 3908/* This is used for fpathconf(), pathconf(), confstr() and sysconf(). 3909 * It maps strings representing configuration variable names to 3910 * integer values, allowing those functions to be called with the 3911 * magic names instead of polluting the module's namespace with tons of 3912 * rarely-used constants. There are three separate tables that use 3913 * these definitions. 3914 * 3915 * This code is always included, even if none of the interfaces that 3916 * need it are included. The #if hackery needed to avoid it would be 3917 * sufficiently pervasive that it's not worth the loss of readability. 3918 */ 3919struct constdef { 3920 char *name; 3921 long value; 3922}; 3923 3924static int 3925conv_confname(PyObject *arg, int *valuep, struct constdef *table, 3926 size_t tablesize) 3927{ 3928 if (PyInt_Check(arg)) { 3929 *valuep = PyInt_AS_LONG(arg); 3930 return 1; 3931 } 3932 if (PyString_Check(arg)) { 3933 /* look up the value in the table using a binary search */ 3934 size_t lo = 0; 3935 size_t mid; 3936 size_t hi = tablesize; 3937 int cmp; 3938 char *confname = PyString_AS_STRING(arg); 3939 while (lo < hi) { 3940 mid = (lo + hi) / 2; 3941 cmp = strcmp(confname, table[mid].name); 3942 if (cmp < 0) 3943 hi = mid; 3944 else if (cmp > 0) 3945 lo = mid + 1; 3946 else { 3947 *valuep = table[mid].value; 3948 return 1; 3949 } 3950 } 3951 PyErr_SetString(PyExc_ValueError, "unrecognized configuration name"); 3952 } 3953 else 3954 PyErr_SetString(PyExc_TypeError, 3955 "configuration names must be strings or integers"); 3956 return 0; 3957} 3958 3959 3960#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF) 3961static struct constdef posix_constants_pathconf[] = { 3962#ifdef _PC_ABI_AIO_XFER_MAX 3963 {"PC_ABI_AIO_XFER_MAX", _PC_ABI_AIO_XFER_MAX}, 3964#endif 3965#ifdef _PC_ABI_ASYNC_IO 3966 {"PC_ABI_ASYNC_IO", _PC_ABI_ASYNC_IO}, 3967#endif 3968#ifdef _PC_ASYNC_IO 3969 {"PC_ASYNC_IO", _PC_ASYNC_IO}, 3970#endif 3971#ifdef _PC_CHOWN_RESTRICTED 3972 {"PC_CHOWN_RESTRICTED", _PC_CHOWN_RESTRICTED}, 3973#endif 3974#ifdef _PC_FILESIZEBITS 3975 {"PC_FILESIZEBITS", _PC_FILESIZEBITS}, 3976#endif 3977#ifdef _PC_LAST 3978 {"PC_LAST", _PC_LAST}, 3979#endif 3980#ifdef _PC_LINK_MAX 3981 {"PC_LINK_MAX", _PC_LINK_MAX}, 3982#endif 3983#ifdef _PC_MAX_CANON 3984 {"PC_MAX_CANON", _PC_MAX_CANON}, 3985#endif 3986#ifdef _PC_MAX_INPUT 3987 {"PC_MAX_INPUT", _PC_MAX_INPUT}, 3988#endif 3989#ifdef _PC_NAME_MAX 3990 {"PC_NAME_MAX", _PC_NAME_MAX}, 3991#endif 3992#ifdef _PC_NO_TRUNC 3993 {"PC_NO_TRUNC", _PC_NO_TRUNC}, 3994#endif 3995#ifdef _PC_PATH_MAX 3996 {"PC_PATH_MAX", _PC_PATH_MAX}, 3997#endif 3998#ifdef _PC_PIPE_BUF 3999 {"PC_PIPE_BUF", _PC_PIPE_BUF}, 4000#endif 4001#ifdef _PC_PRIO_IO 4002 {"PC_PRIO_IO", _PC_PRIO_IO}, 4003#endif 4004#ifdef _PC_SOCK_MAXBUF 4005 {"PC_SOCK_MAXBUF", _PC_SOCK_MAXBUF}, 4006#endif 4007#ifdef _PC_SYNC_IO 4008 {"PC_SYNC_IO", _PC_SYNC_IO}, 4009#endif 4010#ifdef _PC_VDISABLE 4011 {"PC_VDISABLE", _PC_VDISABLE}, 4012#endif 4013}; 4014 4015static int 4016conv_path_confname(PyObject *arg, int *valuep) 4017{ 4018 return conv_confname(arg, valuep, posix_constants_pathconf, 4019 sizeof(posix_constants_pathconf) 4020 / sizeof(struct constdef)); 4021} 4022#endif 4023 4024#ifdef HAVE_FPATHCONF 4025static char posix_fpathconf__doc__[] = "\ 4026fpathconf(fd, name) -> integer\n\ 4027Return the configuration limit name for the file descriptor fd.\n\ 4028If there is no limit, return -1."; 4029 4030static PyObject * 4031posix_fpathconf(PyObject *self, PyObject *args) 4032{ 4033 PyObject *result = NULL; 4034 int name, fd; 4035 4036 if (PyArg_ParseTuple(args, "iO&:fpathconf", &fd, 4037 conv_path_confname, &name)) { 4038 long limit; 4039 4040 errno = 0; 4041 limit = fpathconf(fd, name); 4042 if (limit == -1 && errno != 0) 4043 posix_error(); 4044 else 4045 result = PyInt_FromLong(limit); 4046 } 4047 return result; 4048} 4049#endif 4050 4051 4052#ifdef HAVE_PATHCONF 4053static char posix_pathconf__doc__[] = "\ 4054pathconf(path, name) -> integer\n\ 4055Return the configuration limit name for the file or directory path.\n\ 4056If there is no limit, return -1."; 4057 4058static PyObject * 4059posix_pathconf(PyObject *self, PyObject *args) 4060{ 4061 PyObject *result = NULL; 4062 int name; 4063 char *path; 4064 4065 if (PyArg_ParseTuple(args, "sO&:pathconf", &path, 4066 conv_path_confname, &name)) { 4067 long limit; 4068 4069 errno = 0; 4070 limit = pathconf(path, name); 4071 if (limit == -1 && errno != 0) { 4072 if (errno == EINVAL) 4073 /* could be a path or name problem */ 4074 posix_error(); 4075 else 4076 posix_error_with_filename(path); 4077 } 4078 else 4079 result = PyInt_FromLong(limit); 4080 } 4081 return result; 4082} 4083#endif 4084 4085#ifdef HAVE_CONFSTR 4086static struct constdef posix_constants_confstr[] = { 4087#ifdef _CS_ARCHITECTURE 4088 {"CS_ARCHITECTURE", _CS_ARCHITECTURE}, 4089#endif 4090#ifdef _CS_HOSTNAME 4091 {"CS_HOSTNAME", _CS_HOSTNAME}, 4092#endif 4093#ifdef _CS_HW_PROVIDER 4094 {"CS_HW_PROVIDER", _CS_HW_PROVIDER}, 4095#endif 4096#ifdef _CS_HW_SERIAL 4097 {"CS_HW_SERIAL", _CS_HW_SERIAL}, 4098#endif 4099#ifdef _CS_INITTAB_NAME 4100 {"CS_INITTAB_NAME", _CS_INITTAB_NAME}, 4101#endif 4102#ifdef _CS_LFS64_CFLAGS 4103 {"CS_LFS64_CFLAGS", _CS_LFS64_CFLAGS}, 4104#endif 4105#ifdef _CS_LFS64_LDFLAGS 4106 {"CS_LFS64_LDFLAGS", _CS_LFS64_LDFLAGS}, 4107#endif 4108#ifdef _CS_LFS64_LIBS 4109 {"CS_LFS64_LIBS", _CS_LFS64_LIBS}, 4110#endif 4111#ifdef _CS_LFS64_LINTFLAGS 4112 {"CS_LFS64_LINTFLAGS", _CS_LFS64_LINTFLAGS}, 4113#endif 4114#ifdef _CS_LFS_CFLAGS 4115 {"CS_LFS_CFLAGS", _CS_LFS_CFLAGS}, 4116#endif 4117#ifdef _CS_LFS_LDFLAGS 4118 {"CS_LFS_LDFLAGS", _CS_LFS_LDFLAGS}, 4119#endif 4120#ifdef _CS_LFS_LIBS 4121 {"CS_LFS_LIBS", _CS_LFS_LIBS}, 4122#endif 4123#ifdef _CS_LFS_LINTFLAGS 4124 {"CS_LFS_LINTFLAGS", _CS_LFS_LINTFLAGS}, 4125#endif 4126#ifdef _CS_MACHINE 4127 {"CS_MACHINE", _CS_MACHINE}, 4128#endif 4129#ifdef _CS_PATH 4130 {"CS_PATH", _CS_PATH}, 4131#endif 4132#ifdef _CS_RELEASE 4133 {"CS_RELEASE", _CS_RELEASE}, 4134#endif 4135#ifdef _CS_SRPC_DOMAIN 4136 {"CS_SRPC_DOMAIN", _CS_SRPC_DOMAIN}, 4137#endif 4138#ifdef _CS_SYSNAME 4139 {"CS_SYSNAME", _CS_SYSNAME}, 4140#endif 4141#ifdef _CS_VERSION 4142 {"CS_VERSION", _CS_VERSION}, 4143#endif 4144#ifdef _CS_XBS5_ILP32_OFF32_CFLAGS 4145 {"CS_XBS5_ILP32_OFF32_CFLAGS", _CS_XBS5_ILP32_OFF32_CFLAGS}, 4146#endif 4147#ifdef _CS_XBS5_ILP32_OFF32_LDFLAGS 4148 {"CS_XBS5_ILP32_OFF32_LDFLAGS", _CS_XBS5_ILP32_OFF32_LDFLAGS}, 4149#endif 4150#ifdef _CS_XBS5_ILP32_OFF32_LIBS 4151 {"CS_XBS5_ILP32_OFF32_LIBS", _CS_XBS5_ILP32_OFF32_LIBS}, 4152#endif 4153#ifdef _CS_XBS5_ILP32_OFF32_LINTFLAGS 4154 {"CS_XBS5_ILP32_OFF32_LINTFLAGS", _CS_XBS5_ILP32_OFF32_LINTFLAGS}, 4155#endif 4156#ifdef _CS_XBS5_ILP32_OFFBIG_CFLAGS 4157 {"CS_XBS5_ILP32_OFFBIG_CFLAGS", _CS_XBS5_ILP32_OFFBIG_CFLAGS}, 4158#endif 4159#ifdef _CS_XBS5_ILP32_OFFBIG_LDFLAGS 4160 {"CS_XBS5_ILP32_OFFBIG_LDFLAGS", _CS_XBS5_ILP32_OFFBIG_LDFLAGS}, 4161#endif 4162#ifdef _CS_XBS5_ILP32_OFFBIG_LIBS 4163 {"CS_XBS5_ILP32_OFFBIG_LIBS", _CS_XBS5_ILP32_OFFBIG_LIBS}, 4164#endif 4165#ifdef _CS_XBS5_ILP32_OFFBIG_LINTFLAGS 4166 {"CS_XBS5_ILP32_OFFBIG_LINTFLAGS", _CS_XBS5_ILP32_OFFBIG_LINTFLAGS}, 4167#endif 4168#ifdef _CS_XBS5_LP64_OFF64_CFLAGS 4169 {"CS_XBS5_LP64_OFF64_CFLAGS", _CS_XBS5_LP64_OFF64_CFLAGS}, 4170#endif 4171#ifdef _CS_XBS5_LP64_OFF64_LDFLAGS 4172 {"CS_XBS5_LP64_OFF64_LDFLAGS", _CS_XBS5_LP64_OFF64_LDFLAGS}, 4173#endif 4174#ifdef _CS_XBS5_LP64_OFF64_LIBS 4175 {"CS_XBS5_LP64_OFF64_LIBS", _CS_XBS5_LP64_OFF64_LIBS}, 4176#endif 4177#ifdef _CS_XBS5_LP64_OFF64_LINTFLAGS 4178 {"CS_XBS5_LP64_OFF64_LINTFLAGS", _CS_XBS5_LP64_OFF64_LINTFLAGS}, 4179#endif 4180#ifdef _CS_XBS5_LPBIG_OFFBIG_CFLAGS 4181 {"CS_XBS5_LPBIG_OFFBIG_CFLAGS", _CS_XBS5_LPBIG_OFFBIG_CFLAGS}, 4182#endif 4183#ifdef _CS_XBS5_LPBIG_OFFBIG_LDFLAGS 4184 {"CS_XBS5_LPBIG_OFFBIG_LDFLAGS", _CS_XBS5_LPBIG_OFFBIG_LDFLAGS}, 4185#endif 4186#ifdef _CS_XBS5_LPBIG_OFFBIG_LIBS 4187 {"CS_XBS5_LPBIG_OFFBIG_LIBS", _CS_XBS5_LPBIG_OFFBIG_LIBS}, 4188#endif 4189#ifdef _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS 4190 {"CS_XBS5_LPBIG_OFFBIG_LINTFLAGS", _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS}, 4191#endif 4192#ifdef _MIPS_CS_AVAIL_PROCESSORS 4193 {"MIPS_CS_AVAIL_PROCESSORS", _MIPS_CS_AVAIL_PROCESSORS}, 4194#endif 4195#ifdef _MIPS_CS_BASE 4196 {"MIPS_CS_BASE", _MIPS_CS_BASE}, 4197#endif 4198#ifdef _MIPS_CS_HOSTID 4199 {"MIPS_CS_HOSTID", _MIPS_CS_HOSTID}, 4200#endif 4201#ifdef _MIPS_CS_HW_NAME 4202 {"MIPS_CS_HW_NAME", _MIPS_CS_HW_NAME}, 4203#endif 4204#ifdef _MIPS_CS_NUM_PROCESSORS 4205 {"MIPS_CS_NUM_PROCESSORS", _MIPS_CS_NUM_PROCESSORS}, 4206#endif 4207#ifdef _MIPS_CS_OSREL_MAJ 4208 {"MIPS_CS_OSREL_MAJ", _MIPS_CS_OSREL_MAJ}, 4209#endif 4210#ifdef _MIPS_CS_OSREL_MIN 4211 {"MIPS_CS_OSREL_MIN", _MIPS_CS_OSREL_MIN}, 4212#endif 4213#ifdef _MIPS_CS_OSREL_PATCH 4214 {"MIPS_CS_OSREL_PATCH", _MIPS_CS_OSREL_PATCH}, 4215#endif 4216#ifdef _MIPS_CS_OS_NAME 4217 {"MIPS_CS_OS_NAME", _MIPS_CS_OS_NAME}, 4218#endif 4219#ifdef _MIPS_CS_OS_PROVIDER 4220 {"MIPS_CS_OS_PROVIDER", _MIPS_CS_OS_PROVIDER}, 4221#endif 4222#ifdef _MIPS_CS_PROCESSORS 4223 {"MIPS_CS_PROCESSORS", _MIPS_CS_PROCESSORS}, 4224#endif 4225#ifdef _MIPS_CS_SERIAL 4226 {"MIPS_CS_SERIAL", _MIPS_CS_SERIAL}, 4227#endif 4228#ifdef _MIPS_CS_VENDOR 4229 {"MIPS_CS_VENDOR", _MIPS_CS_VENDOR}, 4230#endif 4231}; 4232 4233static int 4234conv_confstr_confname(PyObject *arg, int *valuep) 4235{ 4236 return conv_confname(arg, valuep, posix_constants_confstr, 4237 sizeof(posix_constants_confstr) 4238 / sizeof(struct constdef)); 4239} 4240 4241static char posix_confstr__doc__[] = "\ 4242confstr(name) -> string\n\ 4243Return a string-valued system configuration variable."; 4244 4245static PyObject * 4246posix_confstr(PyObject *self, PyObject *args) 4247{ 4248 PyObject *result = NULL; 4249 int name; 4250 char buffer[64]; 4251 4252 if (PyArg_ParseTuple(args, "O&:confstr", conv_confstr_confname, &name)) { 4253 int len = confstr(name, buffer, sizeof(buffer)); 4254 4255 errno = 0; 4256 if (len == 0) { 4257 if (errno != 0) 4258 posix_error(); 4259 else 4260 result = PyString_FromString(""); 4261 } 4262 else { 4263 if (len >= sizeof(buffer)) { 4264 result = PyString_FromStringAndSize(NULL, len); 4265 if (result != NULL) 4266 confstr(name, PyString_AS_STRING(result), len+1); 4267 } 4268 else 4269 result = PyString_FromString(buffer); 4270 } 4271 } 4272 return result; 4273} 4274#endif 4275 4276 4277#ifdef HAVE_SYSCONF 4278static struct constdef posix_constants_sysconf[] = { 4279#ifdef _SC_2_CHAR_TERM 4280 {"SC_2_CHAR_TERM", _SC_2_CHAR_TERM}, 4281#endif 4282#ifdef _SC_2_C_BIND 4283 {"SC_2_C_BIND", _SC_2_C_BIND}, 4284#endif 4285#ifdef _SC_2_C_DEV 4286 {"SC_2_C_DEV", _SC_2_C_DEV}, 4287#endif 4288#ifdef _SC_2_C_VERSION 4289 {"SC_2_C_VERSION", _SC_2_C_VERSION}, 4290#endif 4291#ifdef _SC_2_FORT_DEV 4292 {"SC_2_FORT_DEV", _SC_2_FORT_DEV}, 4293#endif 4294#ifdef _SC_2_FORT_RUN 4295 {"SC_2_FORT_RUN", _SC_2_FORT_RUN}, 4296#endif 4297#ifdef _SC_2_LOCALEDEF 4298 {"SC_2_LOCALEDEF", _SC_2_LOCALEDEF}, 4299#endif 4300#ifdef _SC_2_SW_DEV 4301 {"SC_2_SW_DEV", _SC_2_SW_DEV}, 4302#endif 4303#ifdef _SC_2_UPE 4304 {"SC_2_UPE", _SC_2_UPE}, 4305#endif 4306#ifdef _SC_2_VERSION 4307 {"SC_2_VERSION", _SC_2_VERSION}, 4308#endif 4309#ifdef _SC_ABI_ASYNCHRONOUS_IO 4310 {"SC_ABI_ASYNCHRONOUS_IO", _SC_ABI_ASYNCHRONOUS_IO}, 4311#endif 4312#ifdef _SC_ACL 4313 {"SC_ACL", _SC_ACL}, 4314#endif 4315#ifdef _SC_AIO_LISTIO_MAX 4316 {"SC_AIO_LISTIO_MAX", _SC_AIO_LISTIO_MAX}, 4317#endif 4318#ifdef _SC_AIO_MAX 4319 {"SC_AIO_MAX", _SC_AIO_MAX}, 4320#endif 4321#ifdef _SC_AIO_PRIO_DELTA_MAX 4322 {"SC_AIO_PRIO_DELTA_MAX", _SC_AIO_PRIO_DELTA_MAX}, 4323#endif 4324#ifdef _SC_ARG_MAX 4325 {"SC_ARG_MAX", _SC_ARG_MAX}, 4326#endif 4327#ifdef _SC_ASYNCHRONOUS_IO 4328 {"SC_ASYNCHRONOUS_IO", _SC_ASYNCHRONOUS_IO}, 4329#endif 4330#ifdef _SC_ATEXIT_MAX 4331 {"SC_ATEXIT_MAX", _SC_ATEXIT_MAX}, 4332#endif 4333#ifdef _SC_AUDIT 4334 {"SC_AUDIT", _SC_AUDIT}, 4335#endif 4336#ifdef _SC_AVPHYS_PAGES 4337 {"SC_AVPHYS_PAGES", _SC_AVPHYS_PAGES}, 4338#endif 4339#ifdef _SC_BC_BASE_MAX 4340 {"SC_BC_BASE_MAX", _SC_BC_BASE_MAX}, 4341#endif 4342#ifdef _SC_BC_DIM_MAX 4343 {"SC_BC_DIM_MAX", _SC_BC_DIM_MAX}, 4344#endif 4345#ifdef _SC_BC_SCALE_MAX 4346 {"SC_BC_SCALE_MAX", _SC_BC_SCALE_MAX}, 4347#endif 4348#ifdef _SC_BC_STRING_MAX 4349 {"SC_BC_STRING_MAX", _SC_BC_STRING_MAX}, 4350#endif 4351#ifdef _SC_CAP 4352 {"SC_CAP", _SC_CAP}, 4353#endif 4354#ifdef _SC_CHARCLASS_NAME_MAX 4355 {"SC_CHARCLASS_NAME_MAX", _SC_CHARCLASS_NAME_MAX}, 4356#endif 4357#ifdef _SC_CHAR_BIT 4358 {"SC_CHAR_BIT", _SC_CHAR_BIT}, 4359#endif 4360#ifdef _SC_CHAR_MAX 4361 {"SC_CHAR_MAX", _SC_CHAR_MAX}, 4362#endif 4363#ifdef _SC_CHAR_MIN 4364 {"SC_CHAR_MIN", _SC_CHAR_MIN}, 4365#endif 4366#ifdef _SC_CHILD_MAX 4367 {"SC_CHILD_MAX", _SC_CHILD_MAX}, 4368#endif 4369#ifdef _SC_CLK_TCK 4370 {"SC_CLK_TCK", _SC_CLK_TCK}, 4371#endif 4372#ifdef _SC_COHER_BLKSZ 4373 {"SC_COHER_BLKSZ", _SC_COHER_BLKSZ}, 4374#endif 4375#ifdef _SC_COLL_WEIGHTS_MAX 4376 {"SC_COLL_WEIGHTS_MAX", _SC_COLL_WEIGHTS_MAX}, 4377#endif 4378#ifdef _SC_DCACHE_ASSOC 4379 {"SC_DCACHE_ASSOC", _SC_DCACHE_ASSOC}, 4380#endif 4381#ifdef _SC_DCACHE_BLKSZ 4382 {"SC_DCACHE_BLKSZ", _SC_DCACHE_BLKSZ}, 4383#endif 4384#ifdef _SC_DCACHE_LINESZ 4385 {"SC_DCACHE_LINESZ", _SC_DCACHE_LINESZ}, 4386#endif 4387#ifdef _SC_DCACHE_SZ 4388 {"SC_DCACHE_SZ", _SC_DCACHE_SZ}, 4389#endif 4390#ifdef _SC_DCACHE_TBLKSZ 4391 {"SC_DCACHE_TBLKSZ", _SC_DCACHE_TBLKSZ}, 4392#endif 4393#ifdef _SC_DELAYTIMER_MAX 4394 {"SC_DELAYTIMER_MAX", _SC_DELAYTIMER_MAX}, 4395#endif 4396#ifdef _SC_EQUIV_CLASS_MAX 4397 {"SC_EQUIV_CLASS_MAX", _SC_EQUIV_CLASS_MAX}, 4398#endif 4399#ifdef _SC_EXPR_NEST_MAX 4400 {"SC_EXPR_NEST_MAX", _SC_EXPR_NEST_MAX}, 4401#endif 4402#ifdef _SC_FSYNC 4403 {"SC_FSYNC", _SC_FSYNC}, 4404#endif 4405#ifdef _SC_GETGR_R_SIZE_MAX 4406 {"SC_GETGR_R_SIZE_MAX", _SC_GETGR_R_SIZE_MAX}, 4407#endif 4408#ifdef _SC_GETPW_R_SIZE_MAX 4409 {"SC_GETPW_R_SIZE_MAX", _SC_GETPW_R_SIZE_MAX}, 4410#endif 4411#ifdef _SC_ICACHE_ASSOC 4412 {"SC_ICACHE_ASSOC", _SC_ICACHE_ASSOC}, 4413#endif 4414#ifdef _SC_ICACHE_BLKSZ 4415 {"SC_ICACHE_BLKSZ", _SC_ICACHE_BLKSZ}, 4416#endif 4417#ifdef _SC_ICACHE_LINESZ 4418 {"SC_ICACHE_LINESZ", _SC_ICACHE_LINESZ}, 4419#endif 4420#ifdef _SC_ICACHE_SZ 4421 {"SC_ICACHE_SZ", _SC_ICACHE_SZ}, 4422#endif 4423#ifdef _SC_INF 4424 {"SC_INF", _SC_INF}, 4425#endif 4426#ifdef _SC_INT_MAX 4427 {"SC_INT_MAX", _SC_INT_MAX}, 4428#endif 4429#ifdef _SC_INT_MIN 4430 {"SC_INT_MIN", _SC_INT_MIN}, 4431#endif 4432#ifdef _SC_IOV_MAX 4433 {"SC_IOV_MAX", _SC_IOV_MAX}, 4434#endif 4435#ifdef _SC_IP_SECOPTS 4436 {"SC_IP_SECOPTS", _SC_IP_SECOPTS}, 4437#endif 4438#ifdef _SC_JOB_CONTROL 4439 {"SC_JOB_CONTROL", _SC_JOB_CONTROL}, 4440#endif 4441#ifdef _SC_KERN_POINTERS 4442 {"SC_KERN_POINTERS", _SC_KERN_POINTERS}, 4443#endif 4444#ifdef _SC_KERN_SIM 4445 {"SC_KERN_SIM", _SC_KERN_SIM}, 4446#endif 4447#ifdef _SC_LINE_MAX 4448 {"SC_LINE_MAX", _SC_LINE_MAX}, 4449#endif 4450#ifdef _SC_LOGIN_NAME_MAX 4451 {"SC_LOGIN_NAME_MAX", _SC_LOGIN_NAME_MAX}, 4452#endif 4453#ifdef _SC_LOGNAME_MAX 4454 {"SC_LOGNAME_MAX", _SC_LOGNAME_MAX}, 4455#endif 4456#ifdef _SC_LONG_BIT 4457 {"SC_LONG_BIT", _SC_LONG_BIT}, 4458#endif 4459#ifdef _SC_MAC 4460 {"SC_MAC", _SC_MAC}, 4461#endif 4462#ifdef _SC_MAPPED_FILES 4463 {"SC_MAPPED_FILES", _SC_MAPPED_FILES}, 4464#endif 4465#ifdef _SC_MAXPID 4466 {"SC_MAXPID", _SC_MAXPID}, 4467#endif 4468#ifdef _SC_MB_LEN_MAX 4469 {"SC_MB_LEN_MAX", _SC_MB_LEN_MAX}, 4470#endif 4471#ifdef _SC_MEMLOCK 4472 {"SC_MEMLOCK", _SC_MEMLOCK}, 4473#endif 4474#ifdef _SC_MEMLOCK_RANGE 4475 {"SC_MEMLOCK_RANGE", _SC_MEMLOCK_RANGE}, 4476#endif 4477#ifdef _SC_MEMORY_PROTECTION 4478 {"SC_MEMORY_PROTECTION", _SC_MEMORY_PROTECTION}, 4479#endif 4480#ifdef _SC_MESSAGE_PASSING 4481 {"SC_MESSAGE_PASSING", _SC_MESSAGE_PASSING}, 4482#endif 4483#ifdef _SC_MMAP_FIXED_ALIGNMENT 4484 {"SC_MMAP_FIXED_ALIGNMENT", _SC_MMAP_FIXED_ALIGNMENT}, 4485#endif 4486#ifdef _SC_MQ_OPEN_MAX 4487 {"SC_MQ_OPEN_MAX", _SC_MQ_OPEN_MAX}, 4488#endif 4489#ifdef _SC_MQ_PRIO_MAX 4490 {"SC_MQ_PRIO_MAX", _SC_MQ_PRIO_MAX}, 4491#endif 4492#ifdef _SC_NACLS_MAX 4493 {"SC_NACLS_MAX", _SC_NACLS_MAX}, 4494#endif 4495#ifdef _SC_NGROUPS_MAX 4496 {"SC_NGROUPS_MAX", _SC_NGROUPS_MAX}, 4497#endif 4498#ifdef _SC_NL_ARGMAX 4499 {"SC_NL_ARGMAX", _SC_NL_ARGMAX}, 4500#endif 4501#ifdef _SC_NL_LANGMAX 4502 {"SC_NL_LANGMAX", _SC_NL_LANGMAX}, 4503#endif 4504#ifdef _SC_NL_MSGMAX 4505 {"SC_NL_MSGMAX", _SC_NL_MSGMAX}, 4506#endif 4507#ifdef _SC_NL_NMAX 4508 {"SC_NL_NMAX", _SC_NL_NMAX}, 4509#endif 4510#ifdef _SC_NL_SETMAX 4511 {"SC_NL_SETMAX", _SC_NL_SETMAX}, 4512#endif 4513#ifdef _SC_NL_TEXTMAX 4514 {"SC_NL_TEXTMAX", _SC_NL_TEXTMAX}, 4515#endif 4516#ifdef _SC_NPROCESSORS_CONF 4517 {"SC_NPROCESSORS_CONF", _SC_NPROCESSORS_CONF}, 4518#endif 4519#ifdef _SC_NPROCESSORS_ONLN 4520 {"SC_NPROCESSORS_ONLN", _SC_NPROCESSORS_ONLN}, 4521#endif 4522#ifdef _SC_NPROC_CONF 4523 {"SC_NPROC_CONF", _SC_NPROC_CONF}, 4524#endif 4525#ifdef _SC_NPROC_ONLN 4526 {"SC_NPROC_ONLN", _SC_NPROC_ONLN}, 4527#endif 4528#ifdef _SC_NZERO 4529 {"SC_NZERO", _SC_NZERO}, 4530#endif 4531#ifdef _SC_OPEN_MAX 4532 {"SC_OPEN_MAX", _SC_OPEN_MAX}, 4533#endif 4534#ifdef _SC_PAGESIZE 4535 {"SC_PAGESIZE", _SC_PAGESIZE}, 4536#endif 4537#ifdef _SC_PAGE_SIZE 4538 {"SC_PAGE_SIZE", _SC_PAGE_SIZE}, 4539#endif 4540#ifdef _SC_PASS_MAX 4541 {"SC_PASS_MAX", _SC_PASS_MAX}, 4542#endif 4543#ifdef _SC_PHYS_PAGES 4544 {"SC_PHYS_PAGES", _SC_PHYS_PAGES}, 4545#endif 4546#ifdef _SC_PII 4547 {"SC_PII", _SC_PII}, 4548#endif 4549#ifdef _SC_PII_INTERNET 4550 {"SC_PII_INTERNET", _SC_PII_INTERNET}, 4551#endif 4552#ifdef _SC_PII_INTERNET_DGRAM 4553 {"SC_PII_INTERNET_DGRAM", _SC_PII_INTERNET_DGRAM}, 4554#endif 4555#ifdef _SC_PII_INTERNET_STREAM 4556 {"SC_PII_INTERNET_STREAM", _SC_PII_INTERNET_STREAM}, 4557#endif 4558#ifdef _SC_PII_OSI 4559 {"SC_PII_OSI", _SC_PII_OSI}, 4560#endif 4561#ifdef _SC_PII_OSI_CLTS 4562 {"SC_PII_OSI_CLTS", _SC_PII_OSI_CLTS}, 4563#endif 4564#ifdef _SC_PII_OSI_COTS 4565 {"SC_PII_OSI_COTS", _SC_PII_OSI_COTS}, 4566#endif 4567#ifdef _SC_PII_OSI_M 4568 {"SC_PII_OSI_M", _SC_PII_OSI_M}, 4569#endif 4570#ifdef _SC_PII_SOCKET 4571 {"SC_PII_SOCKET", _SC_PII_SOCKET}, 4572#endif 4573#ifdef _SC_PII_XTI 4574 {"SC_PII_XTI", _SC_PII_XTI}, 4575#endif 4576#ifdef _SC_POLL 4577 {"SC_POLL", _SC_POLL}, 4578#endif 4579#ifdef _SC_PRIORITIZED_IO 4580 {"SC_PRIORITIZED_IO", _SC_PRIORITIZED_IO}, 4581#endif 4582#ifdef _SC_PRIORITY_SCHEDULING 4583 {"SC_PRIORITY_SCHEDULING", _SC_PRIORITY_SCHEDULING}, 4584#endif 4585#ifdef _SC_REALTIME_SIGNALS 4586 {"SC_REALTIME_SIGNALS", _SC_REALTIME_SIGNALS}, 4587#endif 4588#ifdef _SC_RE_DUP_MAX 4589 {"SC_RE_DUP_MAX", _SC_RE_DUP_MAX}, 4590#endif 4591#ifdef _SC_RTSIG_MAX 4592 {"SC_RTSIG_MAX", _SC_RTSIG_MAX}, 4593#endif 4594#ifdef _SC_SAVED_IDS 4595 {"SC_SAVED_IDS", _SC_SAVED_IDS}, 4596#endif 4597#ifdef _SC_SCHAR_MAX 4598 {"SC_SCHAR_MAX", _SC_SCHAR_MAX}, 4599#endif 4600#ifdef _SC_SCHAR_MIN 4601 {"SC_SCHAR_MIN", _SC_SCHAR_MIN}, 4602#endif 4603#ifdef _SC_SELECT 4604 {"SC_SELECT", _SC_SELECT}, 4605#endif 4606#ifdef _SC_SEMAPHORES 4607 {"SC_SEMAPHORES", _SC_SEMAPHORES}, 4608#endif 4609#ifdef _SC_SEM_NSEMS_MAX 4610 {"SC_SEM_NSEMS_MAX", _SC_SEM_NSEMS_MAX}, 4611#endif 4612#ifdef _SC_SEM_VALUE_MAX 4613 {"SC_SEM_VALUE_MAX", _SC_SEM_VALUE_MAX}, 4614#endif 4615#ifdef _SC_SHARED_MEMORY_OBJECTS 4616 {"SC_SHARED_MEMORY_OBJECTS", _SC_SHARED_MEMORY_OBJECTS}, 4617#endif 4618#ifdef _SC_SHRT_MAX 4619 {"SC_SHRT_MAX", _SC_SHRT_MAX}, 4620#endif 4621#ifdef _SC_SHRT_MIN 4622 {"SC_SHRT_MIN", _SC_SHRT_MIN}, 4623#endif 4624#ifdef _SC_SIGQUEUE_MAX 4625 {"SC_SIGQUEUE_MAX", _SC_SIGQUEUE_MAX}, 4626#endif 4627#ifdef _SC_SIGRT_MAX 4628 {"SC_SIGRT_MAX", _SC_SIGRT_MAX}, 4629#endif 4630#ifdef _SC_SIGRT_MIN 4631 {"SC_SIGRT_MIN", _SC_SIGRT_MIN}, 4632#endif 4633#ifdef _SC_SOFTPOWER 4634 {"SC_SOFTPOWER", _SC_SOFTPOWER}, 4635#endif 4636#ifdef _SC_SPLIT_CACHE 4637 {"SC_SPLIT_CACHE", _SC_SPLIT_CACHE}, 4638#endif 4639#ifdef _SC_SSIZE_MAX 4640 {"SC_SSIZE_MAX", _SC_SSIZE_MAX}, 4641#endif 4642#ifdef _SC_STACK_PROT 4643 {"SC_STACK_PROT", _SC_STACK_PROT}, 4644#endif 4645#ifdef _SC_STREAM_MAX 4646 {"SC_STREAM_MAX", _SC_STREAM_MAX}, 4647#endif 4648#ifdef _SC_SYNCHRONIZED_IO 4649 {"SC_SYNCHRONIZED_IO", _SC_SYNCHRONIZED_IO}, 4650#endif 4651#ifdef _SC_THREADS 4652 {"SC_THREADS", _SC_THREADS}, 4653#endif 4654#ifdef _SC_THREAD_ATTR_STACKADDR 4655 {"SC_THREAD_ATTR_STACKADDR", _SC_THREAD_ATTR_STACKADDR}, 4656#endif 4657#ifdef _SC_THREAD_ATTR_STACKSIZE 4658 {"SC_THREAD_ATTR_STACKSIZE", _SC_THREAD_ATTR_STACKSIZE}, 4659#endif 4660#ifdef _SC_THREAD_DESTRUCTOR_ITERATIONS 4661 {"SC_THREAD_DESTRUCTOR_ITERATIONS", _SC_THREAD_DESTRUCTOR_ITERATIONS}, 4662#endif 4663#ifdef _SC_THREAD_KEYS_MAX 4664 {"SC_THREAD_KEYS_MAX", _SC_THREAD_KEYS_MAX}, 4665#endif 4666#ifdef _SC_THREAD_PRIORITY_SCHEDULING 4667 {"SC_THREAD_PRIORITY_SCHEDULING", _SC_THREAD_PRIORITY_SCHEDULING}, 4668#endif 4669#ifdef _SC_THREAD_PRIO_INHERIT 4670 {"SC_THREAD_PRIO_INHERIT", _SC_THREAD_PRIO_INHERIT}, 4671#endif 4672#ifdef _SC_THREAD_PRIO_PROTECT 4673 {"SC_THREAD_PRIO_PROTECT", _SC_THREAD_PRIO_PROTECT}, 4674#endif 4675#ifdef _SC_THREAD_PROCESS_SHARED 4676 {"SC_THREAD_PROCESS_SHARED", _SC_THREAD_PROCESS_SHARED}, 4677#endif 4678#ifdef _SC_THREAD_SAFE_FUNCTIONS 4679 {"SC_THREAD_SAFE_FUNCTIONS", _SC_THREAD_SAFE_FUNCTIONS}, 4680#endif 4681#ifdef _SC_THREAD_STACK_MIN 4682 {"SC_THREAD_STACK_MIN", _SC_THREAD_STACK_MIN}, 4683#endif 4684#ifdef _SC_THREAD_THREADS_MAX 4685 {"SC_THREAD_THREADS_MAX", _SC_THREAD_THREADS_MAX}, 4686#endif 4687#ifdef _SC_TIMERS 4688 {"SC_TIMERS", _SC_TIMERS}, 4689#endif 4690#ifdef _SC_TIMER_MAX 4691 {"SC_TIMER_MAX", _SC_TIMER_MAX}, 4692#endif 4693#ifdef _SC_TTY_NAME_MAX 4694 {"SC_TTY_NAME_MAX", _SC_TTY_NAME_MAX}, 4695#endif 4696#ifdef _SC_TZNAME_MAX 4697 {"SC_TZNAME_MAX", _SC_TZNAME_MAX}, 4698#endif 4699#ifdef _SC_T_IOV_MAX 4700 {"SC_T_IOV_MAX", _SC_T_IOV_MAX}, 4701#endif 4702#ifdef _SC_UCHAR_MAX 4703 {"SC_UCHAR_MAX", _SC_UCHAR_MAX}, 4704#endif 4705#ifdef _SC_UINT_MAX 4706 {"SC_UINT_MAX", _SC_UINT_MAX}, 4707#endif 4708#ifdef _SC_UIO_MAXIOV 4709 {"SC_UIO_MAXIOV", _SC_UIO_MAXIOV}, 4710#endif 4711#ifdef _SC_ULONG_MAX 4712 {"SC_ULONG_MAX", _SC_ULONG_MAX}, 4713#endif 4714#ifdef _SC_USHRT_MAX 4715 {"SC_USHRT_MAX", _SC_USHRT_MAX}, 4716#endif 4717#ifdef _SC_VERSION 4718 {"SC_VERSION", _SC_VERSION}, 4719#endif 4720#ifdef _SC_WORD_BIT 4721 {"SC_WORD_BIT", _SC_WORD_BIT}, 4722#endif 4723#ifdef _SC_XBS5_ILP32_OFF32 4724 {"SC_XBS5_ILP32_OFF32", _SC_XBS5_ILP32_OFF32}, 4725#endif 4726#ifdef _SC_XBS5_ILP32_OFFBIG 4727 {"SC_XBS5_ILP32_OFFBIG", _SC_XBS5_ILP32_OFFBIG}, 4728#endif 4729#ifdef _SC_XBS5_LP64_OFF64 4730 {"SC_XBS5_LP64_OFF64", _SC_XBS5_LP64_OFF64}, 4731#endif 4732#ifdef _SC_XBS5_LPBIG_OFFBIG 4733 {"SC_XBS5_LPBIG_OFFBIG", _SC_XBS5_LPBIG_OFFBIG}, 4734#endif 4735#ifdef _SC_XOPEN_CRYPT 4736 {"SC_XOPEN_CRYPT", _SC_XOPEN_CRYPT}, 4737#endif 4738#ifdef _SC_XOPEN_ENH_I18N 4739 {"SC_XOPEN_ENH_I18N", _SC_XOPEN_ENH_I18N}, 4740#endif 4741#ifdef _SC_XOPEN_LEGACY 4742 {"SC_XOPEN_LEGACY", _SC_XOPEN_LEGACY}, 4743#endif 4744#ifdef _SC_XOPEN_REALTIME 4745 {"SC_XOPEN_REALTIME", _SC_XOPEN_REALTIME}, 4746#endif 4747#ifdef _SC_XOPEN_REALTIME_THREADS 4748 {"SC_XOPEN_REALTIME_THREADS", _SC_XOPEN_REALTIME_THREADS}, 4749#endif 4750#ifdef _SC_XOPEN_SHM 4751 {"SC_XOPEN_SHM", _SC_XOPEN_SHM}, 4752#endif 4753#ifdef _SC_XOPEN_UNIX 4754 {"SC_XOPEN_UNIX", _SC_XOPEN_UNIX}, 4755#endif 4756#ifdef _SC_XOPEN_VERSION 4757 {"SC_XOPEN_VERSION", _SC_XOPEN_VERSION}, 4758#endif 4759#ifdef _SC_XOPEN_XCU_VERSION 4760 {"SC_XOPEN_XCU_VERSION", _SC_XOPEN_XCU_VERSION}, 4761#endif 4762#ifdef _SC_XOPEN_XPG2 4763 {"SC_XOPEN_XPG2", _SC_XOPEN_XPG2}, 4764#endif 4765#ifdef _SC_XOPEN_XPG3 4766 {"SC_XOPEN_XPG3", _SC_XOPEN_XPG3}, 4767#endif 4768#ifdef _SC_XOPEN_XPG4 4769 {"SC_XOPEN_XPG4", _SC_XOPEN_XPG4}, 4770#endif 4771}; 4772 4773static int 4774conv_sysconf_confname(PyObject *arg, int *valuep) 4775{ 4776 return conv_confname(arg, valuep, posix_constants_sysconf, 4777 sizeof(posix_constants_sysconf) 4778 / sizeof(struct constdef)); 4779} 4780 4781static char posix_sysconf__doc__[] = "\ 4782sysconf(name) -> integer\n\ 4783Return an integer-valued system configuration variable."; 4784 4785static PyObject * 4786posix_sysconf(PyObject *self, PyObject *args) 4787{ 4788 PyObject *result = NULL; 4789 int name; 4790 4791 if (PyArg_ParseTuple(args, "O&:sysconf", conv_sysconf_confname, &name)) { 4792 int value; 4793 4794 errno = 0; 4795 value = sysconf(name); 4796 if (value == -1 && errno != 0) 4797 posix_error(); 4798 else 4799 result = PyInt_FromLong(value); 4800 } 4801 return result; 4802} 4803#endif 4804 4805 4806/* This code is used to ensure that the tables of configuration value names 4807 * are in sorted order as required by conv_confname(), and also to build the 4808 * the exported dictionaries that are used to publish information about the 4809 * names available on the host platform. 4810 * 4811 * Sorting the table at runtime ensures that the table is properly ordered 4812 * when used, even for platforms we're not able to test on. It also makes 4813 * it easier to add additional entries to the tables. 4814 */ 4815 4816static int 4817cmp_constdefs(const void *v1, const void *v2) 4818{ 4819 const struct constdef *c1 = 4820 (const struct constdef *) v1; 4821 const struct constdef *c2 = 4822 (const struct constdef *) v2; 4823 4824 return strcmp(c1->name, c2->name); 4825} 4826 4827static int 4828setup_confname_table(struct constdef *table, size_t tablesize, 4829 char *tablename, PyObject *moddict) 4830{ 4831 PyObject *d = NULL; 4832 size_t i; 4833 int status; 4834 4835 qsort(table, tablesize, sizeof(struct constdef), cmp_constdefs); 4836 d = PyDict_New(); 4837 if (d == NULL) 4838 return -1; 4839 4840 for (i=0; i < tablesize; ++i) { 4841 PyObject *o = PyInt_FromLong(table[i].value); 4842 if (o == NULL || PyDict_SetItemString(d, table[i].name, o) == -1) { 4843 Py_XDECREF(o); 4844 Py_DECREF(d); 4845 return -1; 4846 } 4847 Py_DECREF(o); 4848 } 4849 status = PyDict_SetItemString(moddict, tablename, d); 4850 Py_DECREF(d); 4851 return status; 4852} 4853 4854/* Return -1 on failure, 0 on success. */ 4855static int 4856setup_confname_tables(PyObject *moddict) 4857{ 4858#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF) 4859 if (setup_confname_table(posix_constants_pathconf, 4860 sizeof(posix_constants_pathconf) 4861 / sizeof(struct constdef), 4862 "pathconf_names", moddict)) 4863 return -1; 4864#endif 4865#ifdef HAVE_CONFSTR 4866 if (setup_confname_table(posix_constants_confstr, 4867 sizeof(posix_constants_confstr) 4868 / sizeof(struct constdef), 4869 "confstr_names", moddict)) 4870 return -1; 4871#endif 4872#ifdef HAVE_SYSCONF 4873 if (setup_confname_table(posix_constants_sysconf, 4874 sizeof(posix_constants_sysconf) 4875 / sizeof(struct constdef), 4876 "sysconf_names", moddict)) 4877 return -1; 4878#endif 4879 return 0; 4880} 4881 4882 4883static char posix_abort__doc__[] = "\ 4884abort() -> does not return!\n\ 4885Abort the interpreter immediately. This 'dumps core' or otherwise fails\n\ 4886in the hardest way possible on the hosting operating system."; 4887 4888static PyObject * 4889posix_abort(PyObject *self, PyObject *args) 4890{ 4891 if (!PyArg_ParseTuple(args, ":abort")) 4892 return NULL; 4893 abort(); 4894 /*NOTREACHED*/ 4895 Py_FatalError("abort() called from Python code didn't abort!"); 4896 return NULL; 4897} 4898 4899 4900static PyMethodDef posix_methods[] = { 4901 {"access", posix_access, METH_VARARGS, posix_access__doc__}, 4902#ifdef HAVE_TTYNAME 4903 {"ttyname", posix_ttyname, METH_VARARGS, posix_ttyname__doc__}, 4904#endif 4905 {"chdir", posix_chdir, METH_VARARGS, posix_chdir__doc__}, 4906 {"chmod", posix_chmod, METH_VARARGS, posix_chmod__doc__}, 4907#ifdef HAVE_CHOWN 4908 {"chown", posix_chown, METH_VARARGS, posix_chown__doc__}, 4909#endif /* HAVE_CHOWN */ 4910#ifdef HAVE_CTERMID 4911 {"ctermid", posix_ctermid, METH_VARARGS, posix_ctermid__doc__}, 4912#endif 4913#ifdef HAVE_GETCWD 4914 {"getcwd", posix_getcwd, METH_VARARGS, posix_getcwd__doc__}, 4915#endif 4916#ifdef HAVE_LINK 4917 {"link", posix_link, METH_VARARGS, posix_link__doc__}, 4918#endif /* HAVE_LINK */ 4919 {"listdir", posix_listdir, METH_VARARGS, posix_listdir__doc__}, 4920 {"lstat", posix_lstat, METH_VARARGS, posix_lstat__doc__}, 4921 {"mkdir", posix_mkdir, METH_VARARGS, posix_mkdir__doc__}, 4922#ifdef HAVE_NICE 4923 {"nice", posix_nice, METH_VARARGS, posix_nice__doc__}, 4924#endif /* HAVE_NICE */ 4925#ifdef HAVE_READLINK 4926 {"readlink", posix_readlink, METH_VARARGS, posix_readlink__doc__}, 4927#endif /* HAVE_READLINK */ 4928 {"rename", posix_rename, METH_VARARGS, posix_rename__doc__}, 4929 {"rmdir", posix_rmdir, METH_VARARGS, posix_rmdir__doc__}, 4930 {"stat", posix_stat, METH_VARARGS, posix_stat__doc__}, 4931#ifdef HAVE_SYMLINK 4932 {"symlink", posix_symlink, METH_VARARGS, posix_symlink__doc__}, 4933#endif /* HAVE_SYMLINK */ 4934#ifdef HAVE_SYSTEM 4935 {"system", posix_system, METH_VARARGS, posix_system__doc__}, 4936#endif 4937 {"umask", posix_umask, METH_VARARGS, posix_umask__doc__}, 4938#ifdef HAVE_UNAME 4939 {"uname", posix_uname, METH_VARARGS, posix_uname__doc__}, 4940#endif /* HAVE_UNAME */ 4941 {"unlink", posix_unlink, METH_VARARGS, posix_unlink__doc__}, 4942 {"remove", posix_unlink, METH_VARARGS, posix_remove__doc__}, 4943 {"utime", posix_utime, METH_VARARGS, posix_utime__doc__}, 4944#ifdef HAVE_TIMES 4945 {"times", posix_times, METH_VARARGS, posix_times__doc__}, 4946#endif /* HAVE_TIMES */ 4947 {"_exit", posix__exit, METH_VARARGS, posix__exit__doc__}, 4948#ifdef HAVE_EXECV 4949 {"execv", posix_execv, METH_VARARGS, posix_execv__doc__}, 4950 {"execve", posix_execve, METH_VARARGS, posix_execve__doc__}, 4951#endif /* HAVE_EXECV */ 4952#ifdef HAVE_SPAWNV 4953 {"spawnv", posix_spawnv, METH_VARARGS, posix_spawnv__doc__}, 4954 {"spawnve", posix_spawnve, METH_VARARGS, posix_spawnve__doc__}, 4955#endif /* HAVE_SPAWNV */ 4956#ifdef HAVE_FORK 4957 {"fork", posix_fork, METH_VARARGS, posix_fork__doc__}, 4958#endif /* HAVE_FORK */ 4959#if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) 4960 {"openpty", posix_openpty, METH_VARARGS, posix_openpty__doc__}, 4961#endif /* HAVE_OPENPTY || HAVE__GETPTY */ 4962#ifdef HAVE_FORKPTY 4963 {"forkpty", posix_forkpty, METH_VARARGS, posix_forkpty__doc__}, 4964#endif /* HAVE_FORKPTY */ 4965#ifdef HAVE_GETEGID 4966 {"getegid", posix_getegid, METH_VARARGS, posix_getegid__doc__}, 4967#endif /* HAVE_GETEGID */ 4968#ifdef HAVE_GETEUID 4969 {"geteuid", posix_geteuid, METH_VARARGS, posix_geteuid__doc__}, 4970#endif /* HAVE_GETEUID */ 4971#ifdef HAVE_GETGID 4972 {"getgid", posix_getgid, METH_VARARGS, posix_getgid__doc__}, 4973#endif /* HAVE_GETGID */ 4974#ifdef HAVE_GETGROUPS 4975 {"getgroups", posix_getgroups, METH_VARARGS, posix_getgroups__doc__}, 4976#endif 4977 {"getpid", posix_getpid, METH_VARARGS, posix_getpid__doc__}, 4978#ifdef HAVE_GETPGRP 4979 {"getpgrp", posix_getpgrp, METH_VARARGS, posix_getpgrp__doc__}, 4980#endif /* HAVE_GETPGRP */ 4981#ifdef HAVE_GETPPID 4982 {"getppid", posix_getppid, METH_VARARGS, posix_getppid__doc__}, 4983#endif /* HAVE_GETPPID */ 4984#ifdef HAVE_GETUID 4985 {"getuid", posix_getuid, METH_VARARGS, posix_getuid__doc__}, 4986#endif /* HAVE_GETUID */ 4987#ifdef HAVE_GETLOGIN 4988 {"getlogin", posix_getlogin, METH_VARARGS, posix_getlogin__doc__}, 4989#endif 4990#ifdef HAVE_KILL 4991 {"kill", posix_kill, METH_VARARGS, posix_kill__doc__}, 4992#endif /* HAVE_KILL */ 4993#ifdef HAVE_PLOCK 4994 {"plock", posix_plock, METH_VARARGS, posix_plock__doc__}, 4995#endif /* HAVE_PLOCK */ 4996#ifdef HAVE_POPEN 4997 {"popen", posix_popen, METH_VARARGS, posix_popen__doc__}, 4998#ifdef MS_WIN32 4999 {"popen2", win32_popen2, METH_VARARGS}, 5000 {"popen3", win32_popen3, METH_VARARGS}, 5001 {"popen4", win32_popen4, METH_VARARGS}, 5002#endif 5003#endif /* HAVE_POPEN */ 5004#ifdef HAVE_SETUID 5005 {"setuid", posix_setuid, METH_VARARGS, posix_setuid__doc__}, 5006#endif /* HAVE_SETUID */ 5007#ifdef HAVE_SETEUID 5008 {"seteuid", posix_seteuid, METH_VARARGS, posix_seteuid__doc__}, 5009#endif /* HAVE_SETEUID */ 5010#ifdef HAVE_SETEGID 5011 {"setegid", posix_setegid, METH_VARARGS, posix_setegid__doc__}, 5012#endif /* HAVE_SETEGID */ 5013#ifdef HAVE_SETREUID 5014 {"setreuid", posix_setreuid, METH_VARARGS, posix_setreuid__doc__}, 5015#endif /* HAVE_SETREUID */ 5016#ifdef HAVE_SETREGID 5017 {"setregid", posix_setregid, METH_VARARGS, posix_setregid__doc__}, 5018#endif /* HAVE_SETREGID */ 5019#ifdef HAVE_SETGID 5020 {"setgid", posix_setgid, METH_VARARGS, posix_setgid__doc__}, 5021#endif /* HAVE_SETGID */ 5022#ifdef HAVE_SETPGRP 5023 {"setpgrp", posix_setpgrp, METH_VARARGS, posix_setpgrp__doc__}, 5024#endif /* HAVE_SETPGRP */ 5025#ifdef HAVE_WAIT 5026 {"wait", posix_wait, METH_VARARGS, posix_wait__doc__}, 5027#endif /* HAVE_WAIT */ 5028#ifdef HAVE_WAITPID 5029 {"waitpid", posix_waitpid, METH_VARARGS, posix_waitpid__doc__}, 5030#endif /* HAVE_WAITPID */ 5031#ifdef HAVE_SETSID 5032 {"setsid", posix_setsid, METH_VARARGS, posix_setsid__doc__}, 5033#endif /* HAVE_SETSID */ 5034#ifdef HAVE_SETPGID 5035 {"setpgid", posix_setpgid, METH_VARARGS, posix_setpgid__doc__}, 5036#endif /* HAVE_SETPGID */ 5037#ifdef HAVE_TCGETPGRP 5038 {"tcgetpgrp", posix_tcgetpgrp, METH_VARARGS, posix_tcgetpgrp__doc__}, 5039#endif /* HAVE_TCGETPGRP */ 5040#ifdef HAVE_TCSETPGRP 5041 {"tcsetpgrp", posix_tcsetpgrp, METH_VARARGS, posix_tcsetpgrp__doc__}, 5042#endif /* HAVE_TCSETPGRP */ 5043 {"open", posix_open, METH_VARARGS, posix_open__doc__}, 5044 {"close", posix_close, METH_VARARGS, posix_close__doc__}, 5045 {"dup", posix_dup, METH_VARARGS, posix_dup__doc__}, 5046 {"dup2", posix_dup2, METH_VARARGS, posix_dup2__doc__}, 5047 {"lseek", posix_lseek, METH_VARARGS, posix_lseek__doc__}, 5048 {"read", posix_read, METH_VARARGS, posix_read__doc__}, 5049 {"write", posix_write, METH_VARARGS, posix_write__doc__}, 5050 {"fstat", posix_fstat, METH_VARARGS, posix_fstat__doc__}, 5051 {"fdopen", posix_fdopen, METH_VARARGS, posix_fdopen__doc__}, 5052 {"isatty", posix_isatty, METH_VARARGS, posix_isatty__doc__}, 5053#ifdef HAVE_PIPE 5054 {"pipe", posix_pipe, METH_VARARGS, posix_pipe__doc__}, 5055#endif 5056#ifdef HAVE_MKFIFO 5057 {"mkfifo", posix_mkfifo, METH_VARARGS, posix_mkfifo__doc__}, 5058#endif 5059#ifdef HAVE_FTRUNCATE 5060 {"ftruncate", posix_ftruncate, METH_VARARGS, posix_ftruncate__doc__}, 5061#endif 5062#ifdef HAVE_PUTENV 5063 {"putenv", posix_putenv, METH_VARARGS, posix_putenv__doc__}, 5064#endif 5065#ifdef HAVE_STRERROR 5066 {"strerror", posix_strerror, METH_VARARGS, posix_strerror__doc__}, 5067#endif 5068#ifdef HAVE_FSYNC 5069 {"fsync", posix_fsync, METH_VARARGS, posix_fsync__doc__}, 5070#endif 5071#ifdef HAVE_FDATASYNC 5072 {"fdatasync", posix_fdatasync, METH_VARARGS, posix_fdatasync__doc__}, 5073#endif 5074#ifdef HAVE_SYS_WAIT_H 5075#ifdef WIFSTOPPED 5076 {"WIFSTOPPED", posix_WIFSTOPPED, METH_VARARGS, posix_WIFSTOPPED__doc__}, 5077#endif /* WIFSTOPPED */ 5078#ifdef WIFSIGNALED 5079 {"WIFSIGNALED", posix_WIFSIGNALED, METH_VARARGS, posix_WIFSIGNALED__doc__}, 5080#endif /* WIFSIGNALED */ 5081#ifdef WIFEXITED 5082 {"WIFEXITED", posix_WIFEXITED, METH_VARARGS, posix_WIFEXITED__doc__}, 5083#endif /* WIFEXITED */ 5084#ifdef WEXITSTATUS 5085 {"WEXITSTATUS", posix_WEXITSTATUS, METH_VARARGS, posix_WEXITSTATUS__doc__}, 5086#endif /* WEXITSTATUS */ 5087#ifdef WTERMSIG 5088 {"WTERMSIG", posix_WTERMSIG, METH_VARARGS, posix_WTERMSIG__doc__}, 5089#endif /* WTERMSIG */ 5090#ifdef WSTOPSIG 5091 {"WSTOPSIG", posix_WSTOPSIG, METH_VARARGS, posix_WSTOPSIG__doc__}, 5092#endif /* WSTOPSIG */ 5093#endif /* HAVE_SYS_WAIT_H */ 5094#ifdef HAVE_FSTATVFS 5095 {"fstatvfs", posix_fstatvfs, METH_VARARGS, posix_fstatvfs__doc__}, 5096#endif 5097#ifdef HAVE_STATVFS 5098 {"statvfs", posix_statvfs, METH_VARARGS, posix_statvfs__doc__}, 5099#endif 5100#ifdef HAVE_TMPNAM 5101 {"tmpfile", posix_tmpfile, METH_VARARGS, posix_tmpfile__doc__}, 5102#endif 5103#ifdef HAVE_TEMPNAM 5104 {"tempnam", posix_tempnam, METH_VARARGS, posix_tempnam__doc__}, 5105#endif 5106#ifdef HAVE_TMPNAM 5107 {"tmpnam", posix_tmpnam, METH_VARARGS, posix_tmpnam__doc__}, 5108#endif 5109#ifdef HAVE_CONFSTR 5110 {"confstr", posix_confstr, METH_VARARGS, posix_confstr__doc__}, 5111#endif 5112#ifdef HAVE_SYSCONF 5113 {"sysconf", posix_sysconf, METH_VARARGS, posix_sysconf__doc__}, 5114#endif 5115#ifdef HAVE_FPATHCONF 5116 {"fpathconf", posix_fpathconf, METH_VARARGS, posix_fpathconf__doc__}, 5117#endif 5118#ifdef HAVE_PATHCONF 5119 {"pathconf", posix_pathconf, METH_VARARGS, posix_pathconf__doc__}, 5120#endif 5121 {"abort", posix_abort, METH_VARARGS, posix_abort__doc__}, 5122 {NULL, NULL} /* Sentinel */ 5123}; 5124 5125 5126static int 5127ins(PyObject *d, char *symbol, long value) 5128{ 5129 PyObject* v = PyInt_FromLong(value); 5130 if (!v || PyDict_SetItemString(d, symbol, v) < 0) 5131 return -1; /* triggers fatal error */ 5132 5133 Py_DECREF(v); 5134 return 0; 5135} 5136 5137#if defined(PYOS_OS2) 5138/* Insert Platform-Specific Constant Values (Strings & Numbers) of Common Use */ 5139static int insertvalues(PyObject *d) 5140{ 5141 APIRET rc; 5142 ULONG values[QSV_MAX+1]; 5143 PyObject *v; 5144 char *ver, tmp[10]; 5145 5146 Py_BEGIN_ALLOW_THREADS 5147 rc = DosQuerySysInfo(1, QSV_MAX, &values[1], sizeof(values)); 5148 Py_END_ALLOW_THREADS 5149 5150 if (rc != NO_ERROR) { 5151 os2_error(rc); 5152 return -1; 5153 } 5154 5155 if (ins(d, "meminstalled", values[QSV_TOTPHYSMEM])) return -1; 5156 if (ins(d, "memkernel", values[QSV_TOTRESMEM])) return -1; 5157 if (ins(d, "memvirtual", values[QSV_TOTAVAILMEM])) return -1; 5158 if (ins(d, "maxpathlen", values[QSV_MAX_PATH_LENGTH])) return -1; 5159 if (ins(d, "maxnamelen", values[QSV_MAX_COMP_LENGTH])) return -1; 5160 if (ins(d, "revision", values[QSV_VERSION_REVISION])) return -1; 5161 if (ins(d, "timeslice", values[QSV_MIN_SLICE])) return -1; 5162 5163 switch (values[QSV_VERSION_MINOR]) { 5164 case 0: ver = "2.00"; break; 5165 case 10: ver = "2.10"; break; 5166 case 11: ver = "2.11"; break; 5167 case 30: ver = "3.00"; break; 5168 case 40: ver = "4.00"; break; 5169 case 50: ver = "5.00"; break; 5170 default: 5171 sprintf(tmp, "%d-%d", values[QSV_VERSION_MAJOR], 5172 values[QSV_VERSION_MINOR]); 5173 ver = &tmp[0]; 5174 } 5175 5176 /* Add Indicator of the Version of the Operating System */ 5177 v = PyString_FromString(ver); 5178 if (!v || PyDict_SetItemString(d, "version", v) < 0) 5179 return -1; 5180 Py_DECREF(v); 5181 5182 /* Add Indicator of Which Drive was Used to Boot the System */ 5183 tmp[0] = 'A' + values[QSV_BOOT_DRIVE] - 1; 5184 tmp[1] = ':'; 5185 tmp[2] = '\0'; 5186 5187 v = PyString_FromString(tmp); 5188 if (!v || PyDict_SetItemString(d, "bootdrive", v) < 0) 5189 return -1; 5190 Py_DECREF(v); 5191 5192 return 0; 5193} 5194#endif 5195 5196static int 5197all_ins(PyObject *d) 5198{ 5199#ifdef F_OK 5200 if (ins(d, "F_OK", (long)F_OK)) return -1; 5201#endif 5202#ifdef R_OK 5203 if (ins(d, "R_OK", (long)R_OK)) return -1; 5204#endif 5205#ifdef W_OK 5206 if (ins(d, "W_OK", (long)W_OK)) return -1; 5207#endif 5208#ifdef X_OK 5209 if (ins(d, "X_OK", (long)X_OK)) return -1; 5210#endif 5211#ifdef NGROUPS_MAX 5212 if (ins(d, "NGROUPS_MAX", (long)NGROUPS_MAX)) return -1; 5213#endif 5214#ifdef TMP_MAX 5215 if (ins(d, "TMP_MAX", (long)TMP_MAX)) return -1; 5216#endif 5217#ifdef WNOHANG 5218 if (ins(d, "WNOHANG", (long)WNOHANG)) return -1; 5219#endif 5220#ifdef O_RDONLY 5221 if (ins(d, "O_RDONLY", (long)O_RDONLY)) return -1; 5222#endif 5223#ifdef O_WRONLY 5224 if (ins(d, "O_WRONLY", (long)O_WRONLY)) return -1; 5225#endif 5226#ifdef O_RDWR 5227 if (ins(d, "O_RDWR", (long)O_RDWR)) return -1; 5228#endif 5229#ifdef O_NDELAY 5230 if (ins(d, "O_NDELAY", (long)O_NDELAY)) return -1; 5231#endif 5232#ifdef O_NONBLOCK 5233 if (ins(d, "O_NONBLOCK", (long)O_NONBLOCK)) return -1; 5234#endif 5235#ifdef O_APPEND 5236 if (ins(d, "O_APPEND", (long)O_APPEND)) return -1; 5237#endif 5238#ifdef O_DSYNC 5239 if (ins(d, "O_DSYNC", (long)O_DSYNC)) return -1; 5240#endif 5241#ifdef O_RSYNC 5242 if (ins(d, "O_RSYNC", (long)O_RSYNC)) return -1; 5243#endif 5244#ifdef O_SYNC 5245 if (ins(d, "O_SYNC", (long)O_SYNC)) return -1; 5246#endif 5247#ifdef O_NOCTTY 5248 if (ins(d, "O_NOCTTY", (long)O_NOCTTY)) return -1; 5249#endif 5250#ifdef O_CREAT 5251 if (ins(d, "O_CREAT", (long)O_CREAT)) return -1; 5252#endif 5253#ifdef O_EXCL 5254 if (ins(d, "O_EXCL", (long)O_EXCL)) return -1; 5255#endif 5256#ifdef O_TRUNC 5257 if (ins(d, "O_TRUNC", (long)O_TRUNC)) return -1; 5258#endif 5259#ifdef O_BINARY 5260 if (ins(d, "O_BINARY", (long)O_BINARY)) return -1; 5261#endif 5262#ifdef O_TEXT 5263 if (ins(d, "O_TEXT", (long)O_TEXT)) return -1; 5264#endif 5265 5266#ifdef HAVE_SPAWNV 5267 if (ins(d, "P_WAIT", (long)_P_WAIT)) return -1; 5268 if (ins(d, "P_NOWAIT", (long)_P_NOWAIT)) return -1; 5269 if (ins(d, "P_OVERLAY", (long)_OLD_P_OVERLAY)) return -1; 5270 if (ins(d, "P_NOWAITO", (long)_P_NOWAITO)) return -1; 5271 if (ins(d, "P_DETACH", (long)_P_DETACH)) return -1; 5272#endif 5273 5274#if defined(PYOS_OS2) 5275 if (insertvalues(d)) return -1; 5276#endif 5277 return 0; 5278} 5279 5280 5281#if ( defined(_MSC_VER) || defined(__WATCOMC__) ) && !defined(__QNX__) 5282#define INITFUNC initnt 5283#define MODNAME "nt" 5284#else 5285#if defined(PYOS_OS2) 5286#define INITFUNC initos2 5287#define MODNAME "os2" 5288#else 5289#define INITFUNC initposix 5290#define MODNAME "posix" 5291#endif 5292#endif 5293 5294DL_EXPORT(void) 5295INITFUNC(void) 5296{ 5297 PyObject *m, *d, *v; 5298 5299 m = Py_InitModule4(MODNAME, 5300 posix_methods, 5301 posix__doc__, 5302 (PyObject *)NULL, 5303 PYTHON_API_VERSION); 5304 d = PyModule_GetDict(m); 5305 5306 /* Initialize environ dictionary */ 5307 v = convertenviron(); 5308 if (v == NULL || PyDict_SetItemString(d, "environ", v) != 0) 5309 return; 5310 Py_DECREF(v); 5311 5312 if (all_ins(d)) 5313 return; 5314 5315 if (setup_confname_tables(d)) 5316 return; 5317 5318 PyDict_SetItemString(d, "error", PyExc_OSError); 5319 5320#ifdef HAVE_PUTENV 5321 posix_putenv_garbage = PyDict_New(); 5322#endif 5323} 5324