posixmodule.c revision 44328e60df37993f7342742e25b89a09979e9ed9
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() 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() 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#if 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: dictonary 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_Length(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: dictonary 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_Length(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, eventhough 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) or defined(HAVE_FORKPTY) */ 1710 1711#ifdef HAVE_OPENPTY 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 if (!PyArg_ParseTuple(args, ":openpty")) 1721 return NULL; 1722 if (openpty(&master_fd, &slave_fd, NULL, NULL, NULL) != 0) 1723 return posix_error(); 1724 return Py_BuildValue("(ii)", master_fd, slave_fd); 1725} 1726#endif 1727 1728#ifdef HAVE_FORKPTY 1729static char posix_forkpty__doc__[] = 1730"forkpty() -> (pid, master_fd)\n\ 1731Fork a new process with a new pseudo-terminal as controlling tty.\n\n\ 1732Like fork(), return 0 as pid to child process, and PID of child to parent.\n\ 1733To both, return fd of newly opened pseudo-terminal.\n"; 1734 1735static PyObject * 1736posix_forkpty(PyObject *self, PyObject *args) 1737{ 1738 int master_fd, pid; 1739 1740 if (!PyArg_ParseTuple(args, ":forkpty")) 1741 return NULL; 1742 pid = forkpty(&master_fd, NULL, NULL, NULL); 1743 if (pid == -1) 1744 return posix_error(); 1745 if (pid == 0) 1746 PyOS_AfterFork(); 1747 return Py_BuildValue("(ii)", pid, master_fd); 1748} 1749#endif 1750 1751#ifdef HAVE_GETEGID 1752static char posix_getegid__doc__[] = 1753"getegid() -> egid\n\ 1754Return the current process's effective group id."; 1755 1756static PyObject * 1757posix_getegid(PyObject *self, PyObject *args) 1758{ 1759 if (!PyArg_ParseTuple(args, ":getegid")) 1760 return NULL; 1761 return PyInt_FromLong((long)getegid()); 1762} 1763#endif 1764 1765 1766#ifdef HAVE_GETEUID 1767static char posix_geteuid__doc__[] = 1768"geteuid() -> euid\n\ 1769Return the current process's effective user id."; 1770 1771static PyObject * 1772posix_geteuid(PyObject *self, PyObject *args) 1773{ 1774 if (!PyArg_ParseTuple(args, ":geteuid")) 1775 return NULL; 1776 return PyInt_FromLong((long)geteuid()); 1777} 1778#endif 1779 1780 1781#ifdef HAVE_GETGID 1782static char posix_getgid__doc__[] = 1783"getgid() -> gid\n\ 1784Return the current process's group id."; 1785 1786static PyObject * 1787posix_getgid(PyObject *self, PyObject *args) 1788{ 1789 if (!PyArg_ParseTuple(args, ":getgid")) 1790 return NULL; 1791 return PyInt_FromLong((long)getgid()); 1792} 1793#endif 1794 1795 1796static char posix_getpid__doc__[] = 1797"getpid() -> pid\n\ 1798Return the current process id"; 1799 1800static PyObject * 1801posix_getpid(PyObject *self, PyObject *args) 1802{ 1803 if (!PyArg_ParseTuple(args, ":getpid")) 1804 return NULL; 1805 return PyInt_FromLong((long)getpid()); 1806} 1807 1808 1809#ifdef HAVE_GETGROUPS 1810static char posix_getgroups__doc__[] = "\ 1811getgroups() -> list of group IDs\n\ 1812Return list of supplemental group IDs for the process."; 1813 1814static PyObject * 1815posix_getgroups(PyObject *self, PyObject *args) 1816{ 1817 PyObject *result = NULL; 1818 1819 if (PyArg_ParseTuple(args, ":getgroups")) { 1820#ifdef NGROUPS_MAX 1821#define MAX_GROUPS NGROUPS_MAX 1822#else 1823 /* defined to be 16 on Solaris7, so this should be a small number */ 1824#define MAX_GROUPS 64 1825#endif 1826 gid_t grouplist[MAX_GROUPS]; 1827 int n; 1828 1829 n = getgroups(MAX_GROUPS, grouplist); 1830 if (n < 0) 1831 posix_error(); 1832 else { 1833 result = PyList_New(n); 1834 if (result != NULL) { 1835 PyObject *o; 1836 int i; 1837 for (i = 0; i < n; ++i) { 1838 o = PyInt_FromLong((long)grouplist[i]); 1839 if (o == NULL) { 1840 Py_DECREF(result); 1841 result = NULL; 1842 break; 1843 } 1844 PyList_SET_ITEM(result, i, o); 1845 } 1846 } 1847 } 1848 } 1849 return result; 1850} 1851#endif 1852 1853#ifdef HAVE_GETPGRP 1854static char posix_getpgrp__doc__[] = 1855"getpgrp() -> pgrp\n\ 1856Return the current process group id."; 1857 1858static PyObject * 1859posix_getpgrp(PyObject *self, PyObject *args) 1860{ 1861 if (!PyArg_ParseTuple(args, ":getpgrp")) 1862 return NULL; 1863#ifdef GETPGRP_HAVE_ARG 1864 return PyInt_FromLong((long)getpgrp(0)); 1865#else /* GETPGRP_HAVE_ARG */ 1866 return PyInt_FromLong((long)getpgrp()); 1867#endif /* GETPGRP_HAVE_ARG */ 1868} 1869#endif /* HAVE_GETPGRP */ 1870 1871 1872#ifdef HAVE_SETPGRP 1873static char posix_setpgrp__doc__[] = 1874"setpgrp() -> None\n\ 1875Make this process a session leader."; 1876 1877static PyObject * 1878posix_setpgrp(PyObject *self, PyObject *args) 1879{ 1880 if (!PyArg_ParseTuple(args, ":setpgrp")) 1881 return NULL; 1882#ifdef SETPGRP_HAVE_ARG 1883 if (setpgrp(0, 0) < 0) 1884#else /* SETPGRP_HAVE_ARG */ 1885 if (setpgrp() < 0) 1886#endif /* SETPGRP_HAVE_ARG */ 1887 return posix_error(); 1888 Py_INCREF(Py_None); 1889 return Py_None; 1890} 1891 1892#endif /* HAVE_SETPGRP */ 1893 1894#ifdef HAVE_GETPPID 1895static char posix_getppid__doc__[] = 1896"getppid() -> ppid\n\ 1897Return the parent's process id."; 1898 1899static PyObject * 1900posix_getppid(self, args) 1901 PyObject *self; 1902 PyObject *args; 1903{ 1904 if (!PyArg_ParseTuple(args, ":getppid")) 1905 return NULL; 1906 return PyInt_FromLong((long)getppid()); 1907} 1908#endif 1909 1910 1911#ifdef HAVE_GETLOGIN 1912static char posix_getlogin__doc__[] = "\ 1913getlogin() -> string\n\ 1914Return the actual login name."; 1915 1916static PyObject * 1917posix_getlogin(PyObject *self, PyObject *args) 1918{ 1919 PyObject *result = NULL; 1920 1921 if (PyArg_ParseTuple(args, ":getlogin")) { 1922 char *name = getlogin(); 1923 1924 if (name == NULL) 1925 posix_error(); 1926 else 1927 result = PyString_FromString(name); 1928 } 1929 return result; 1930} 1931#endif 1932 1933#ifdef HAVE_GETUID 1934static char posix_getuid__doc__[] = 1935"getuid() -> uid\n\ 1936Return the current process's user id."; 1937 1938static PyObject * 1939posix_getuid(PyObject *self, PyObject *args) 1940{ 1941 if (!PyArg_ParseTuple(args, ":getuid")) 1942 return NULL; 1943 return PyInt_FromLong((long)getuid()); 1944} 1945#endif 1946 1947 1948#ifdef HAVE_KILL 1949static char posix_kill__doc__[] = 1950"kill(pid, sig) -> None\n\ 1951Kill a process with a signal."; 1952 1953static PyObject * 1954posix_kill(PyObject *self, PyObject *args) 1955{ 1956 int pid, sig; 1957 if (!PyArg_ParseTuple(args, "ii:kill", &pid, &sig)) 1958 return NULL; 1959#if defined(PYOS_OS2) 1960 if (sig == XCPT_SIGNAL_INTR || sig == XCPT_SIGNAL_BREAK) { 1961 APIRET rc; 1962 if ((rc = DosSendSignalException(pid, sig)) != NO_ERROR) 1963 return os2_error(rc); 1964 1965 } else if (sig == XCPT_SIGNAL_KILLPROC) { 1966 APIRET rc; 1967 if ((rc = DosKillProcess(DKP_PROCESS, pid)) != NO_ERROR) 1968 return os2_error(rc); 1969 1970 } else 1971 return NULL; /* Unrecognized Signal Requested */ 1972#else 1973 if (kill(pid, sig) == -1) 1974 return posix_error(); 1975#endif 1976 Py_INCREF(Py_None); 1977 return Py_None; 1978} 1979#endif 1980 1981#ifdef HAVE_PLOCK 1982 1983#ifdef HAVE_SYS_LOCK_H 1984#include <sys/lock.h> 1985#endif 1986 1987static char posix_plock__doc__[] = 1988"plock(op) -> None\n\ 1989Lock program segments into memory."; 1990 1991static PyObject * 1992posix_plock(PyObject *self, PyObject *args) 1993{ 1994 int op; 1995 if (!PyArg_ParseTuple(args, "i:plock", &op)) 1996 return NULL; 1997 if (plock(op) == -1) 1998 return posix_error(); 1999 Py_INCREF(Py_None); 2000 return Py_None; 2001} 2002#endif 2003 2004 2005#ifdef HAVE_POPEN 2006static char posix_popen__doc__[] = 2007"popen(command [, mode='r' [, bufsize]]) -> pipe\n\ 2008Open a pipe to/from a command returning a file object."; 2009 2010#if defined(PYOS_OS2) 2011static int 2012async_system(const char *command) 2013{ 2014 char *p, errormsg[256], args[1024]; 2015 RESULTCODES rcodes; 2016 APIRET rc; 2017 char *shell = getenv("COMSPEC"); 2018 if (!shell) 2019 shell = "cmd"; 2020 2021 strcpy(args, shell); 2022 p = &args[ strlen(args)+1 ]; 2023 strcpy(p, "/c "); 2024 strcat(p, command); 2025 p += strlen(p) + 1; 2026 *p = '\0'; 2027 2028 rc = DosExecPgm(errormsg, sizeof(errormsg), 2029 EXEC_ASYNC, /* Execute Async w/o Wait for Results */ 2030 args, 2031 NULL, /* Inherit Parent's Environment */ 2032 &rcodes, shell); 2033 return rc; 2034} 2035 2036static FILE * 2037popen(const char *command, const char *mode, int pipesize, int *err) 2038{ 2039 HFILE rhan, whan; 2040 FILE *retfd = NULL; 2041 APIRET rc = DosCreatePipe(&rhan, &whan, pipesize); 2042 2043 if (rc != NO_ERROR) { 2044 *err = rc; 2045 return NULL; /* ERROR - Unable to Create Anon Pipe */ 2046 } 2047 2048 if (strchr(mode, 'r') != NULL) { /* Treat Command as a Data Source */ 2049 int oldfd = dup(1); /* Save STDOUT Handle in Another Handle */ 2050 2051 DosEnterCritSec(); /* Stop Other Threads While Changing Handles */ 2052 close(1); /* Make STDOUT Available for Reallocation */ 2053 2054 if (dup2(whan, 1) == 0) { /* Connect STDOUT to Pipe Write Side */ 2055 DosClose(whan); /* Close Now-Unused Pipe Write Handle */ 2056 2057 if (async_system(command) == NO_ERROR) 2058 retfd = fdopen(rhan, mode); /* And Return Pipe Read Handle */ 2059 } 2060 2061 dup2(oldfd, 1); /* Reconnect STDOUT to Original Handle */ 2062 DosExitCritSec(); /* Now Allow Other Threads to Run */ 2063 2064 close(oldfd); /* And Close Saved STDOUT Handle */ 2065 return retfd; /* Return fd of Pipe or NULL if Error */ 2066 2067 } else if (strchr(mode, 'w')) { /* Treat Command as a Data Sink */ 2068 int oldfd = dup(0); /* Save STDIN Handle in Another Handle */ 2069 2070 DosEnterCritSec(); /* Stop Other Threads While Changing Handles */ 2071 close(0); /* Make STDIN Available for Reallocation */ 2072 2073 if (dup2(rhan, 0) == 0) { /* Connect STDIN to Pipe Read Side */ 2074 DosClose(rhan); /* Close Now-Unused Pipe Read Handle */ 2075 2076 if (async_system(command) == NO_ERROR) 2077 retfd = fdopen(whan, mode); /* And Return Pipe Write Handle */ 2078 } 2079 2080 dup2(oldfd, 0); /* Reconnect STDIN to Original Handle */ 2081 DosExitCritSec(); /* Now Allow Other Threads to Run */ 2082 2083 close(oldfd); /* And Close Saved STDIN Handle */ 2084 return retfd; /* Return fd of Pipe or NULL if Error */ 2085 2086 } else { 2087 *err = ERROR_INVALID_ACCESS; 2088 return NULL; /* ERROR - Invalid Mode (Neither Read nor Write) */ 2089 } 2090} 2091 2092static PyObject * 2093posix_popen(PyObject *self, PyObject *args) 2094{ 2095 char *name; 2096 char *mode = "r"; 2097 int err, bufsize = -1; 2098 FILE *fp; 2099 PyObject *f; 2100 if (!PyArg_ParseTuple(args, "s|si:popen", &name, &mode, &bufsize)) 2101 return NULL; 2102 Py_BEGIN_ALLOW_THREADS 2103 fp = popen(name, mode, (bufsize > 0) ? bufsize : 4096, &err); 2104 Py_END_ALLOW_THREADS 2105 if (fp == NULL) 2106 return os2_error(err); 2107 2108 f = PyFile_FromFile(fp, name, mode, fclose); 2109 if (f != NULL) 2110 PyFile_SetBufSize(f, bufsize); 2111 return f; 2112} 2113 2114#elif defined(MS_WIN32) 2115 2116/* 2117 * Portable 'popen' replacement for Win32. 2118 * 2119 * Written by Bill Tutt <billtut@microsoft.com>. Minor tweaks 2120 * and 2.0 integration by Fredrik Lundh <fredrik@pythonware.com> 2121 */ 2122 2123#include <malloc.h> 2124#include <io.h> 2125#include <fcntl.h> 2126 2127/* These tell _PyPopen() wether to return 1, 2, or 3 file objects. */ 2128#define POPEN_1 1 2129#define POPEN_2 2 2130#define POPEN_3 3 2131#define POPEN_4 4 2132 2133static PyObject *_PyPopen(char *, int, int); 2134 2135/* popen that works from a GUI. 2136 * 2137 * The result of this function is a pipe (file) connected to the 2138 * processes stdin or stdout, depending on the requested mode. 2139 */ 2140 2141static PyObject * 2142posix_popen(PyObject *self, PyObject *args) 2143{ 2144 PyObject *f, *s; 2145 int tm = 0; 2146 2147 char *cmdstring; 2148 char *mode = "r"; 2149 int bufsize = -1; 2150 if (!PyArg_ParseTuple(args, "s|si:popen", &cmdstring, &mode, &bufsize)) 2151 return NULL; 2152 2153 s = PyTuple_New(0); 2154 2155 if (*mode == 'r') 2156 tm = _O_RDONLY; 2157 else if (*mode != 'w') { 2158 PyErr_SetString(PyExc_ValueError, "mode must be 'r' or 'w'"); 2159 return NULL; 2160 } else 2161 tm = _O_WRONLY; 2162 2163 if (bufsize != -1) { 2164 PyErr_SetString(PyExc_ValueError, "bufsize must be -1"); 2165 return NULL; 2166 } 2167 2168 if (*(mode+1) == 't') 2169 f = _PyPopen(cmdstring, tm | _O_TEXT, POPEN_1); 2170 else if (*(mode+1) == 'b') 2171 f = _PyPopen(cmdstring, tm | _O_BINARY, POPEN_1); 2172 else 2173 f = _PyPopen(cmdstring, tm | _O_TEXT, POPEN_1); 2174 2175 return f; 2176} 2177 2178/* Variation on win32pipe.popen 2179 * 2180 * The result of this function is a pipe (file) connected to the 2181 * process's stdin, and a pipe connected to the process's stdout. 2182 */ 2183 2184static PyObject * 2185win32_popen2(PyObject *self, PyObject *args) 2186{ 2187 PyObject *f; 2188 int tm=0; 2189 2190 char *cmdstring; 2191 char *mode = "t"; 2192 int bufsize = -1; 2193 if (!PyArg_ParseTuple(args, "s|si:popen2", &cmdstring, &mode, &bufsize)) 2194 return NULL; 2195 2196 if (*mode == 't') 2197 tm = _O_TEXT; 2198 else if (*mode != 'b') { 2199 PyErr_SetString(PyExc_ValueError, "mode must be 't' or 'b'"); 2200 return NULL; 2201 } else 2202 tm = _O_BINARY; 2203 2204 if (bufsize != -1) { 2205 PyErr_SetString(PyExc_ValueError, "bufsize must be -1"); 2206 return NULL; 2207 } 2208 2209 f = _PyPopen(cmdstring, tm, POPEN_2); 2210 2211 return f; 2212} 2213 2214/* 2215 * Variation on <om win32pipe.popen> 2216 * 2217 * The result of this function is 3 pipes - the process's stdin, 2218 * stdout and stderr 2219 */ 2220 2221static PyObject * 2222win32_popen3(PyObject *self, PyObject *args) 2223{ 2224 PyObject *f; 2225 int tm = 0; 2226 2227 char *cmdstring; 2228 char *mode = "t"; 2229 int bufsize = -1; 2230 if (!PyArg_ParseTuple(args, "s|si:popen3", &cmdstring, &mode, &bufsize)) 2231 return NULL; 2232 2233 if (*mode == 't') 2234 tm = _O_TEXT; 2235 else if (*mode != 'b') { 2236 PyErr_SetString(PyExc_ValueError, "mode must be 't' or 'b'"); 2237 return NULL; 2238 } else 2239 tm = _O_BINARY; 2240 2241 if (bufsize != -1) { 2242 PyErr_SetString(PyExc_ValueError, "bufsize must be -1"); 2243 return NULL; 2244 } 2245 2246 f = _PyPopen(cmdstring, tm, POPEN_3); 2247 2248 return f; 2249} 2250 2251/* 2252 * Variation on win32pipe.popen 2253 * 2254 * The result of this function is 2 pipes - the processes stdin, 2255 * and stdout+stderr combined as a single pipe. 2256 */ 2257 2258static PyObject * 2259win32_popen4(PyObject *self, PyObject *args) 2260{ 2261 PyObject *f; 2262 int tm = 0; 2263 2264 char *cmdstring; 2265 char *mode = "t"; 2266 int bufsize = -1; 2267 if (!PyArg_ParseTuple(args, "s|si:popen4", &cmdstring, &mode, &bufsize)) 2268 return NULL; 2269 2270 if (*mode == 't') 2271 tm = _O_TEXT; 2272 else if (*mode != 'b') { 2273 PyErr_SetString(PyExc_ValueError, "mode must be 't' or 'b'"); 2274 return NULL; 2275 } else 2276 tm = _O_BINARY; 2277 2278 if (bufsize != -1) { 2279 PyErr_SetString(PyExc_ValueError, "bufsize must be -1"); 2280 return NULL; 2281 } 2282 2283 f = _PyPopen(cmdstring, tm, POPEN_4); 2284 2285 return f; 2286} 2287 2288static int 2289_PyPopenCreateProcess(char *cmdstring, 2290 HANDLE hStdin, 2291 HANDLE hStdout, 2292 HANDLE hStderr) 2293{ 2294 PROCESS_INFORMATION piProcInfo; 2295 STARTUPINFO siStartInfo; 2296 char *s1,*s2, *s3 = " /c "; 2297 const char *szConsoleSpawn = "w9xpopen.exe \""; 2298 int i; 2299 int x; 2300 2301 if (i = GetEnvironmentVariable("COMSPEC",NULL,0)) { 2302 s1 = (char *)_alloca(i); 2303 if (!(x = GetEnvironmentVariable("COMSPEC", s1, i))) 2304 return x; 2305 if (GetVersion() < 0x80000000) { 2306 /* 2307 * NT/2000 2308 */ 2309 x = i + strlen(s3) + strlen(cmdstring) + 1; 2310 s2 = (char *)_alloca(x); 2311 ZeroMemory(s2, x); 2312 sprintf(s2, "%s%s%s", s1, s3, cmdstring); 2313 } 2314 else { 2315 /* 2316 * Oh gag, we're on Win9x. Use the workaround listed in 2317 * KB: Q150956 2318 */ 2319 char modulepath[256]; 2320 GetModuleFileName(NULL, modulepath, sizeof(modulepath)); 2321 for (i = x = 0; modulepath[i]; i++) 2322 if (modulepath[i] == '\\') 2323 x = i+1; 2324 modulepath[x] = '\0'; 2325 x = i + strlen(s3) + strlen(cmdstring) + 1 + 2326 strlen(modulepath) + 2327 strlen(szConsoleSpawn) + 1; 2328 s2 = (char *)_alloca(x); 2329 ZeroMemory(s2, x); 2330 sprintf( 2331 s2, 2332 "%s%s%s%s%s\"", 2333 modulepath, 2334 szConsoleSpawn, 2335 s1, 2336 s3, 2337 cmdstring); 2338 } 2339 } 2340 2341 /* Could be an else here to try cmd.exe / command.com in the path 2342 Now we'll just error out.. */ 2343 else 2344 return -1; 2345 2346 ZeroMemory(&siStartInfo, sizeof(STARTUPINFO)); 2347 siStartInfo.cb = sizeof(STARTUPINFO); 2348 siStartInfo.dwFlags = STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW; 2349 siStartInfo.hStdInput = hStdin; 2350 siStartInfo.hStdOutput = hStdout; 2351 siStartInfo.hStdError = hStderr; 2352 siStartInfo.wShowWindow = SW_HIDE; 2353 2354 if (CreateProcess(NULL, 2355 s2, 2356 NULL, 2357 NULL, 2358 TRUE, 2359 CREATE_NEW_CONSOLE, 2360 NULL, 2361 NULL, 2362 &siStartInfo, 2363 &piProcInfo) ) { 2364 /* Close the handles now so anyone waiting is woken. */ 2365 CloseHandle(piProcInfo.hProcess); 2366 CloseHandle(piProcInfo.hThread); 2367 return TRUE; 2368 } 2369 return FALSE; 2370} 2371 2372/* The following code is based off of KB: Q190351 */ 2373 2374static PyObject * 2375_PyPopen(char *cmdstring, int mode, int n) 2376{ 2377 HANDLE hChildStdinRd, hChildStdinWr, hChildStdoutRd, hChildStdoutWr, 2378 hChildStderrRd, hChildStderrWr, hChildStdinWrDup, hChildStdoutRdDup, 2379 hChildStderrRdDup; /* hChildStdoutWrDup; */ 2380 2381 SECURITY_ATTRIBUTES saAttr; 2382 BOOL fSuccess; 2383 int fd1, fd2, fd3; 2384 FILE *f1, *f2, *f3; 2385 PyObject *f; 2386 2387 saAttr.nLength = sizeof(SECURITY_ATTRIBUTES); 2388 saAttr.bInheritHandle = TRUE; 2389 saAttr.lpSecurityDescriptor = NULL; 2390 2391 if (!CreatePipe(&hChildStdinRd, &hChildStdinWr, &saAttr, 0)) 2392 return win32_error("CreatePipe", NULL); 2393 2394 /* Create new output read handle and the input write handle. Set 2395 * the inheritance properties to FALSE. Otherwise, the child inherits 2396 * the these handles; resulting in non-closeable handles to the pipes 2397 * being created. */ 2398 fSuccess = DuplicateHandle(GetCurrentProcess(), hChildStdinWr, 2399 GetCurrentProcess(), &hChildStdinWrDup, 0, 2400 FALSE, 2401 DUPLICATE_SAME_ACCESS); 2402 if (!fSuccess) 2403 return win32_error("DuplicateHandle", NULL); 2404 2405 /* Close the inheritable version of ChildStdin 2406 that we're using. */ 2407 CloseHandle(hChildStdinWr); 2408 2409 if (!CreatePipe(&hChildStdoutRd, &hChildStdoutWr, &saAttr, 0)) 2410 return win32_error("CreatePipe", NULL); 2411 2412 fSuccess = DuplicateHandle(GetCurrentProcess(), hChildStdoutRd, 2413 GetCurrentProcess(), &hChildStdoutRdDup, 0, 2414 FALSE, DUPLICATE_SAME_ACCESS); 2415 if (!fSuccess) 2416 return win32_error("DuplicateHandle", NULL); 2417 2418 /* Close the inheritable version of ChildStdout 2419 that we're using. */ 2420 CloseHandle(hChildStdoutRd); 2421 2422 if (n != POPEN_4) { 2423 if (!CreatePipe(&hChildStderrRd, &hChildStderrWr, &saAttr, 0)) 2424 return win32_error("CreatePipe", NULL); 2425 fSuccess = DuplicateHandle(GetCurrentProcess(), 2426 hChildStderrRd, 2427 GetCurrentProcess(), 2428 &hChildStderrRdDup, 0, 2429 FALSE, DUPLICATE_SAME_ACCESS); 2430 if (!fSuccess) 2431 return win32_error("DuplicateHandle", NULL); 2432 /* Close the inheritable version of ChildStdErr that we're using. */ 2433 CloseHandle(hChildStderrRd); 2434 } 2435 2436 switch (n) { 2437 case POPEN_1: 2438 switch (mode & (_O_RDONLY | _O_TEXT | _O_BINARY | _O_WRONLY)) { 2439 case _O_WRONLY | _O_TEXT: 2440 /* Case for writing to child Stdin in text mode. */ 2441 fd1 = _open_osfhandle((long)hChildStdinWrDup, mode); 2442 f1 = _fdopen(fd1, "w"); 2443 f = PyFile_FromFile(f1, cmdstring, "w", fclose); 2444 PyFile_SetBufSize(f, 0); 2445 /* We don't care about these pipes anymore, so close them. */ 2446 CloseHandle(hChildStdoutRdDup); 2447 CloseHandle(hChildStderrRdDup); 2448 break; 2449 2450 case _O_RDONLY | _O_TEXT: 2451 /* Case for reading from child Stdout in text mode. */ 2452 fd1 = _open_osfhandle((long)hChildStdoutRdDup, mode); 2453 f1 = _fdopen(fd1, "r"); 2454 f = PyFile_FromFile(f1, cmdstring, "r", fclose); 2455 PyFile_SetBufSize(f, 0); 2456 /* We don't care about these pipes anymore, so close them. */ 2457 CloseHandle(hChildStdinWrDup); 2458 CloseHandle(hChildStderrRdDup); 2459 break; 2460 2461 case _O_RDONLY | _O_BINARY: 2462 /* Case for readinig from child Stdout in binary mode. */ 2463 fd1 = _open_osfhandle((long)hChildStdoutRdDup, mode); 2464 f1 = _fdopen(fd1, "rb"); 2465 f = PyFile_FromFile(f1, cmdstring, "rb", fclose); 2466 PyFile_SetBufSize(f, 0); 2467 /* We don't care about these pipes anymore, so close them. */ 2468 CloseHandle(hChildStdinWrDup); 2469 CloseHandle(hChildStderrRdDup); 2470 break; 2471 2472 case _O_WRONLY | _O_BINARY: 2473 /* Case for writing to child Stdin in binary mode. */ 2474 fd1 = _open_osfhandle((long)hChildStdinWrDup, mode); 2475 f1 = _fdopen(fd1, "wb"); 2476 f = PyFile_FromFile(f1, cmdstring, "wb", fclose); 2477 PyFile_SetBufSize(f, 0); 2478 /* We don't care about these pipes anymore, so close them. */ 2479 CloseHandle(hChildStdoutRdDup); 2480 CloseHandle(hChildStderrRdDup); 2481 break; 2482 } 2483 break; 2484 2485 case POPEN_2: 2486 case POPEN_4: 2487 { 2488 char *m1, *m2; 2489 PyObject *p1, *p2; 2490 2491 if (mode && _O_TEXT) { 2492 m1 = "r"; 2493 m2 = "w"; 2494 } else { 2495 m1 = "rb"; 2496 m2 = "wb"; 2497 } 2498 2499 fd1 = _open_osfhandle((long)hChildStdinWrDup, mode); 2500 f1 = _fdopen(fd1, m2); 2501 fd2 = _open_osfhandle((long)hChildStdoutRdDup, mode); 2502 f2 = _fdopen(fd2, m1); 2503 p1 = PyFile_FromFile(f1, cmdstring, m2, fclose); 2504 PyFile_SetBufSize(p1, 0); 2505 p2 = PyFile_FromFile(f2, cmdstring, m1, fclose); 2506 PyFile_SetBufSize(p2, 0); 2507 2508 if (n != 4) 2509 CloseHandle(hChildStderrRdDup); 2510 2511 f = Py_BuildValue("OO",p1,p2); 2512 break; 2513 } 2514 2515 case POPEN_3: 2516 { 2517 char *m1, *m2; 2518 PyObject *p1, *p2, *p3; 2519 2520 if (mode && _O_TEXT) { 2521 m1 = "r"; 2522 m2 = "w"; 2523 } else { 2524 m1 = "rb"; 2525 m2 = "wb"; 2526 } 2527 2528 fd1 = _open_osfhandle((long)hChildStdinWrDup, mode); 2529 f1 = _fdopen(fd1, m2); 2530 fd2 = _open_osfhandle((long)hChildStdoutRdDup, mode); 2531 f2 = _fdopen(fd2, m1); 2532 fd3 = _open_osfhandle((long)hChildStderrRdDup, mode); 2533 f3 = _fdopen(fd3, m1); 2534 p1 = PyFile_FromFile(f1, cmdstring, m2, fclose); 2535 p2 = PyFile_FromFile(f2, cmdstring, m1, fclose); 2536 p3 = PyFile_FromFile(f3, cmdstring, m1, fclose); 2537 PyFile_SetBufSize(p1, 0); 2538 PyFile_SetBufSize(p2, 0); 2539 PyFile_SetBufSize(p3, 0); 2540 f = Py_BuildValue("OOO",p1,p2,p3); 2541 break; 2542 } 2543 } 2544 2545 if (n == POPEN_4) { 2546 if (!_PyPopenCreateProcess(cmdstring, 2547 hChildStdinRd, 2548 hChildStdoutWr, 2549 hChildStdoutWr)) 2550 return win32_error("CreateProcess", NULL); 2551 } 2552 else { 2553 if (!_PyPopenCreateProcess(cmdstring, 2554 hChildStdinRd, 2555 hChildStdoutWr, 2556 hChildStderrWr)) 2557 return win32_error("CreateProcess", NULL); 2558 } 2559 2560 /* Child is launched. Close the parents copy of those pipe 2561 * handles that only the child should have open. You need to 2562 * make sure that no handles to the write end of the output pipe 2563 * are maintained in this process or else the pipe will not close 2564 * when the child process exits and the ReadFile will hang. */ 2565 2566 if (!CloseHandle(hChildStdinRd)) 2567 return win32_error("CloseHandle", NULL); 2568 2569 if (!CloseHandle(hChildStdoutWr)) 2570 return win32_error("CloseHandle", NULL); 2571 2572 if ((n != 4) && (!CloseHandle(hChildStderrWr))) 2573 return win32_error("CloseHandle", NULL); 2574 2575 return f; 2576} 2577#else 2578static PyObject * 2579posix_popen(PyObject *self, PyObject *args) 2580{ 2581 char *name; 2582 char *mode = "r"; 2583 int bufsize = -1; 2584 FILE *fp; 2585 PyObject *f; 2586 if (!PyArg_ParseTuple(args, "s|si:popen", &name, &mode, &bufsize)) 2587 return NULL; 2588 Py_BEGIN_ALLOW_THREADS 2589 fp = popen(name, mode); 2590 Py_END_ALLOW_THREADS 2591 if (fp == NULL) 2592 return posix_error(); 2593 f = PyFile_FromFile(fp, name, mode, pclose); 2594 if (f != NULL) 2595 PyFile_SetBufSize(f, bufsize); 2596 return f; 2597} 2598#endif 2599 2600#endif /* HAVE_POPEN */ 2601 2602 2603#ifdef HAVE_SETUID 2604static char posix_setuid__doc__[] = 2605"setuid(uid) -> None\n\ 2606Set the current process's user id."; 2607static PyObject * 2608posix_setuid(PyObject *self, PyObject *args) 2609{ 2610 int uid; 2611 if (!PyArg_ParseTuple(args, "i:setuid", &uid)) 2612 return NULL; 2613 if (setuid(uid) < 0) 2614 return posix_error(); 2615 Py_INCREF(Py_None); 2616 return Py_None; 2617} 2618#endif /* HAVE_SETUID */ 2619 2620 2621#ifdef HAVE_SETGID 2622static char posix_setgid__doc__[] = 2623"setgid(gid) -> None\n\ 2624Set the current process's group id."; 2625 2626static PyObject * 2627posix_setgid(PyObject *self, PyObject *args) 2628{ 2629 int gid; 2630 if (!PyArg_ParseTuple(args, "i:setgid", &gid)) 2631 return NULL; 2632 if (setgid(gid) < 0) 2633 return posix_error(); 2634 Py_INCREF(Py_None); 2635 return Py_None; 2636} 2637#endif /* HAVE_SETGID */ 2638 2639 2640#ifdef HAVE_WAITPID 2641static char posix_waitpid__doc__[] = 2642"waitpid(pid, options) -> (pid, status)\n\ 2643Wait for completion of a give child process."; 2644 2645static PyObject * 2646posix_waitpid(PyObject *self, PyObject *args) 2647{ 2648 int pid, options; 2649#ifdef UNION_WAIT 2650 union wait status; 2651#define status_i (status.w_status) 2652#else 2653 int status; 2654#define status_i status 2655#endif 2656 status_i = 0; 2657 2658 if (!PyArg_ParseTuple(args, "ii:waitpid", &pid, &options)) 2659 return NULL; 2660 Py_BEGIN_ALLOW_THREADS 2661#ifdef NeXT 2662 pid = wait4(pid, &status, options, NULL); 2663#else 2664 pid = waitpid(pid, &status, options); 2665#endif 2666 Py_END_ALLOW_THREADS 2667 if (pid == -1) 2668 return posix_error(); 2669 else 2670 return Py_BuildValue("ii", pid, status_i); 2671} 2672#endif /* HAVE_WAITPID */ 2673 2674 2675#ifdef HAVE_WAIT 2676static char posix_wait__doc__[] = 2677"wait() -> (pid, status)\n\ 2678Wait for completion of a child process."; 2679 2680static PyObject * 2681posix_wait(PyObject *self, PyObject *args) 2682{ 2683 int pid; 2684#ifdef UNION_WAIT 2685 union wait status; 2686#define status_i (status.w_status) 2687#else 2688 int status; 2689#define status_i status 2690#endif 2691 if (!PyArg_ParseTuple(args, ":wait")) 2692 return NULL; 2693 status_i = 0; 2694 Py_BEGIN_ALLOW_THREADS 2695 pid = wait(&status); 2696 Py_END_ALLOW_THREADS 2697 if (pid == -1) 2698 return posix_error(); 2699 else 2700 return Py_BuildValue("ii", pid, status_i); 2701#undef status_i 2702} 2703#endif 2704 2705 2706static char posix_lstat__doc__[] = 2707"lstat(path) -> (mode,ino,dev,nlink,uid,gid,size,atime,mtime,ctime)\n\ 2708Like stat(path), but do not follow symbolic links."; 2709 2710static PyObject * 2711posix_lstat(PyObject *self, PyObject *args) 2712{ 2713#ifdef HAVE_LSTAT 2714 return posix_do_stat(self, args, "s:lstat", lstat); 2715#else /* !HAVE_LSTAT */ 2716 return posix_do_stat(self, args, "s:lstat", STAT); 2717#endif /* !HAVE_LSTAT */ 2718} 2719 2720 2721#ifdef HAVE_READLINK 2722static char posix_readlink__doc__[] = 2723"readlink(path) -> path\n\ 2724Return a string representing the path to which the symbolic link points."; 2725 2726static PyObject * 2727posix_readlink(PyObject *self, PyObject *args) 2728{ 2729 char buf[MAXPATHLEN]; 2730 char *path; 2731 int n; 2732 if (!PyArg_ParseTuple(args, "s:readlink", &path)) 2733 return NULL; 2734 Py_BEGIN_ALLOW_THREADS 2735 n = readlink(path, buf, (int) sizeof buf); 2736 Py_END_ALLOW_THREADS 2737 if (n < 0) 2738 return posix_error_with_filename(path); 2739 return PyString_FromStringAndSize(buf, n); 2740} 2741#endif /* HAVE_READLINK */ 2742 2743 2744#ifdef HAVE_SYMLINK 2745static char posix_symlink__doc__[] = 2746"symlink(src, dst) -> None\n\ 2747Create a symbolic link."; 2748 2749static PyObject * 2750posix_symlink(PyObject *self, PyObject *args) 2751{ 2752 return posix_2str(args, "ss:symlink", symlink); 2753} 2754#endif /* HAVE_SYMLINK */ 2755 2756 2757#ifdef HAVE_TIMES 2758#ifndef HZ 2759#define HZ 60 /* Universal constant :-) */ 2760#endif /* HZ */ 2761 2762#if defined(PYCC_VACPP) && defined(PYOS_OS2) 2763static long 2764system_uptime() 2765{ 2766 ULONG value = 0; 2767 2768 Py_BEGIN_ALLOW_THREADS 2769 DosQuerySysInfo(QSV_MS_COUNT, QSV_MS_COUNT, &value, sizeof(value)); 2770 Py_END_ALLOW_THREADS 2771 2772 return value; 2773} 2774 2775static PyObject * 2776posix_times(PyObject *self, PyObject *args) 2777{ 2778 if (!PyArg_ParseTuple(args, ":times")) 2779 return NULL; 2780 2781 /* Currently Only Uptime is Provided -- Others Later */ 2782 return Py_BuildValue("ddddd", 2783 (double)0 /* t.tms_utime / HZ */, 2784 (double)0 /* t.tms_stime / HZ */, 2785 (double)0 /* t.tms_cutime / HZ */, 2786 (double)0 /* t.tms_cstime / HZ */, 2787 (double)system_uptime() / 1000); 2788} 2789#else /* not OS2 */ 2790static PyObject * 2791posix_times(PyObject *self, PyObject *args) 2792{ 2793 struct tms t; 2794 clock_t c; 2795 if (!PyArg_ParseTuple(args, ":times")) 2796 return NULL; 2797 errno = 0; 2798 c = times(&t); 2799 if (c == (clock_t) -1) 2800 return posix_error(); 2801 return Py_BuildValue("ddddd", 2802 (double)t.tms_utime / HZ, 2803 (double)t.tms_stime / HZ, 2804 (double)t.tms_cutime / HZ, 2805 (double)t.tms_cstime / HZ, 2806 (double)c / HZ); 2807} 2808#endif /* not OS2 */ 2809#endif /* HAVE_TIMES */ 2810 2811 2812#ifdef MS_WIN32 2813#define HAVE_TIMES /* so the method table will pick it up */ 2814static PyObject * 2815posix_times(PyObject *self, PyObject *args) 2816{ 2817 FILETIME create, exit, kernel, user; 2818 HANDLE hProc; 2819 if (!PyArg_ParseTuple(args, ":times")) 2820 return NULL; 2821 hProc = GetCurrentProcess(); 2822 GetProcessTimes(hProc, &create, &exit, &kernel, &user); 2823 /* The fields of a FILETIME structure are the hi and lo part 2824 of a 64-bit value expressed in 100 nanosecond units. 2825 1e7 is one second in such units; 1e-7 the inverse. 2826 429.4967296 is 2**32 / 1e7 or 2**32 * 1e-7. 2827 */ 2828 return Py_BuildValue( 2829 "ddddd", 2830 (double)(kernel.dwHighDateTime*429.4967296 + 2831 kernel.dwLowDateTime*1e-7), 2832 (double)(user.dwHighDateTime*429.4967296 + 2833 user.dwLowDateTime*1e-7), 2834 (double)0, 2835 (double)0, 2836 (double)0); 2837} 2838#endif /* MS_WIN32 */ 2839 2840#ifdef HAVE_TIMES 2841static char posix_times__doc__[] = 2842"times() -> (utime, stime, cutime, cstime, elapsed_time)\n\ 2843Return a tuple of floating point numbers indicating process times."; 2844#endif 2845 2846 2847#ifdef HAVE_SETSID 2848static char posix_setsid__doc__[] = 2849"setsid() -> None\n\ 2850Call the system call setsid()."; 2851 2852static PyObject * 2853posix_setsid(PyObject *self, PyObject *args) 2854{ 2855 if (!PyArg_ParseTuple(args, ":setsid")) 2856 return NULL; 2857 if (setsid() < 0) 2858 return posix_error(); 2859 Py_INCREF(Py_None); 2860 return Py_None; 2861} 2862#endif /* HAVE_SETSID */ 2863 2864#ifdef HAVE_SETPGID 2865static char posix_setpgid__doc__[] = 2866"setpgid(pid, pgrp) -> None\n\ 2867Call the system call setpgid()."; 2868 2869static PyObject * 2870posix_setpgid(PyObject *self, PyObject *args) 2871{ 2872 int pid, pgrp; 2873 if (!PyArg_ParseTuple(args, "ii:setpgid", &pid, &pgrp)) 2874 return NULL; 2875 if (setpgid(pid, pgrp) < 0) 2876 return posix_error(); 2877 Py_INCREF(Py_None); 2878 return Py_None; 2879} 2880#endif /* HAVE_SETPGID */ 2881 2882 2883#ifdef HAVE_TCGETPGRP 2884static char posix_tcgetpgrp__doc__[] = 2885"tcgetpgrp(fd) -> pgid\n\ 2886Return the process group associated with the terminal given by a fd."; 2887 2888static PyObject * 2889posix_tcgetpgrp(PyObject *self, PyObject *args) 2890{ 2891 int fd, pgid; 2892 if (!PyArg_ParseTuple(args, "i:tcgetpgrp", &fd)) 2893 return NULL; 2894 pgid = tcgetpgrp(fd); 2895 if (pgid < 0) 2896 return posix_error(); 2897 return PyInt_FromLong((long)pgid); 2898} 2899#endif /* HAVE_TCGETPGRP */ 2900 2901 2902#ifdef HAVE_TCSETPGRP 2903static char posix_tcsetpgrp__doc__[] = 2904"tcsetpgrp(fd, pgid) -> None\n\ 2905Set the process group associated with the terminal given by a fd."; 2906 2907static PyObject * 2908posix_tcsetpgrp(PyObject *self, PyObject *args) 2909{ 2910 int fd, pgid; 2911 if (!PyArg_ParseTuple(args, "ii:tcsetpgrp", &fd, &pgid)) 2912 return NULL; 2913 if (tcsetpgrp(fd, pgid) < 0) 2914 return posix_error(); 2915 Py_INCREF(Py_None); 2916 return Py_None; 2917} 2918#endif /* HAVE_TCSETPGRP */ 2919 2920/* Functions acting on file descriptors */ 2921 2922static char posix_open__doc__[] = 2923"open(filename, flag [, mode=0777]) -> fd\n\ 2924Open a file (for low level IO)."; 2925 2926static PyObject * 2927posix_open(PyObject *self, PyObject *args) 2928{ 2929 char *file; 2930 int flag; 2931 int mode = 0777; 2932 int fd; 2933 if (!PyArg_ParseTuple(args, "si|i", &file, &flag, &mode)) 2934 return NULL; 2935 2936 Py_BEGIN_ALLOW_THREADS 2937 fd = open(file, flag, mode); 2938 Py_END_ALLOW_THREADS 2939 if (fd < 0) 2940 return posix_error_with_filename(file); 2941 return PyInt_FromLong((long)fd); 2942} 2943 2944 2945static char posix_close__doc__[] = 2946"close(fd) -> None\n\ 2947Close a file descriptor (for low level IO)."; 2948 2949static PyObject * 2950posix_close(PyObject *self, PyObject *args) 2951{ 2952 int fd, res; 2953 if (!PyArg_ParseTuple(args, "i:close", &fd)) 2954 return NULL; 2955 Py_BEGIN_ALLOW_THREADS 2956 res = close(fd); 2957 Py_END_ALLOW_THREADS 2958 if (res < 0) 2959 return posix_error(); 2960 Py_INCREF(Py_None); 2961 return Py_None; 2962} 2963 2964 2965static char posix_dup__doc__[] = 2966"dup(fd) -> fd2\n\ 2967Return a duplicate of a file descriptor."; 2968 2969static PyObject * 2970posix_dup(PyObject *self, PyObject *args) 2971{ 2972 int fd; 2973 if (!PyArg_ParseTuple(args, "i:dup", &fd)) 2974 return NULL; 2975 Py_BEGIN_ALLOW_THREADS 2976 fd = dup(fd); 2977 Py_END_ALLOW_THREADS 2978 if (fd < 0) 2979 return posix_error(); 2980 return PyInt_FromLong((long)fd); 2981} 2982 2983 2984static char posix_dup2__doc__[] = 2985"dup2(fd, fd2) -> None\n\ 2986Duplicate file descriptor."; 2987 2988static PyObject * 2989posix_dup2(PyObject *self, PyObject *args) 2990{ 2991 int fd, fd2, res; 2992 if (!PyArg_ParseTuple(args, "ii:dup2", &fd, &fd2)) 2993 return NULL; 2994 Py_BEGIN_ALLOW_THREADS 2995 res = dup2(fd, fd2); 2996 Py_END_ALLOW_THREADS 2997 if (res < 0) 2998 return posix_error(); 2999 Py_INCREF(Py_None); 3000 return Py_None; 3001} 3002 3003 3004static char posix_lseek__doc__[] = 3005"lseek(fd, pos, how) -> newpos\n\ 3006Set the current position of a file descriptor."; 3007 3008static PyObject * 3009posix_lseek(PyObject *self, PyObject *args) 3010{ 3011 int fd, how; 3012#ifdef MS_WIN64 3013 LONG_LONG pos, res; 3014#else 3015 off_t pos, res; 3016#endif 3017 PyObject *posobj; 3018 if (!PyArg_ParseTuple(args, "iOi:lseek", &fd, &posobj, &how)) 3019 return NULL; 3020#ifdef SEEK_SET 3021 /* Turn 0, 1, 2 into SEEK_{SET,CUR,END} */ 3022 switch (how) { 3023 case 0: how = SEEK_SET; break; 3024 case 1: how = SEEK_CUR; break; 3025 case 2: how = SEEK_END; break; 3026 } 3027#endif /* SEEK_END */ 3028 3029#if !defined(HAVE_LARGEFILE_SUPPORT) 3030 pos = PyInt_AsLong(posobj); 3031#else 3032 pos = PyLong_Check(posobj) ? 3033 PyLong_AsLongLong(posobj) : PyInt_AsLong(posobj); 3034#endif 3035 if (PyErr_Occurred()) 3036 return NULL; 3037 3038 Py_BEGIN_ALLOW_THREADS 3039#ifdef MS_WIN64 3040 res = _lseeki64(fd, pos, how); 3041#else 3042 res = lseek(fd, pos, how); 3043#endif 3044 Py_END_ALLOW_THREADS 3045 if (res < 0) 3046 return posix_error(); 3047 3048#if !defined(HAVE_LARGEFILE_SUPPORT) 3049 return PyInt_FromLong(res); 3050#else 3051 return PyLong_FromLongLong(res); 3052#endif 3053} 3054 3055 3056static char posix_read__doc__[] = 3057"read(fd, buffersize) -> string\n\ 3058Read a file descriptor."; 3059 3060static PyObject * 3061posix_read(PyObject *self, PyObject *args) 3062{ 3063 int fd, size, n; 3064 PyObject *buffer; 3065 if (!PyArg_ParseTuple(args, "ii:read", &fd, &size)) 3066 return NULL; 3067 buffer = PyString_FromStringAndSize((char *)NULL, size); 3068 if (buffer == NULL) 3069 return NULL; 3070 Py_BEGIN_ALLOW_THREADS 3071 n = read(fd, PyString_AsString(buffer), size); 3072 Py_END_ALLOW_THREADS 3073 if (n < 0) { 3074 Py_DECREF(buffer); 3075 return posix_error(); 3076 } 3077 if (n != size) 3078 _PyString_Resize(&buffer, n); 3079 return buffer; 3080} 3081 3082 3083static char posix_write__doc__[] = 3084"write(fd, string) -> byteswritten\n\ 3085Write a string to a file descriptor."; 3086 3087static PyObject * 3088posix_write(PyObject *self, PyObject *args) 3089{ 3090 int fd, size; 3091 char *buffer; 3092 if (!PyArg_ParseTuple(args, "is#:write", &fd, &buffer, &size)) 3093 return NULL; 3094 Py_BEGIN_ALLOW_THREADS 3095 size = write(fd, buffer, size); 3096 Py_END_ALLOW_THREADS 3097 if (size < 0) 3098 return posix_error(); 3099 return PyInt_FromLong((long)size); 3100} 3101 3102 3103static char posix_fstat__doc__[]= 3104"fstat(fd) -> (mode, ino, dev, nlink, uid, gid, size, atime, mtime, ctime)\n\ 3105Like stat(), but for an open file descriptor."; 3106 3107static PyObject * 3108posix_fstat(PyObject *self, PyObject *args) 3109{ 3110 int fd; 3111 STRUCT_STAT st; 3112 int res; 3113 if (!PyArg_ParseTuple(args, "i:fstat", &fd)) 3114 return NULL; 3115 Py_BEGIN_ALLOW_THREADS 3116 res = FSTAT(fd, &st); 3117 Py_END_ALLOW_THREADS 3118 if (res != 0) 3119 return posix_error(); 3120 3121 return _pystat_fromstructstat(st); 3122} 3123 3124 3125static char posix_fdopen__doc__[] = 3126"fdopen(fd, [, mode='r' [, bufsize]]) -> file_object\n\ 3127Return an open file object connected to a file descriptor."; 3128 3129static PyObject * 3130posix_fdopen(PyObject *self, PyObject *args) 3131{ 3132 extern int fclose(FILE *); 3133 int fd; 3134 char *mode = "r"; 3135 int bufsize = -1; 3136 FILE *fp; 3137 PyObject *f; 3138 if (!PyArg_ParseTuple(args, "i|si", &fd, &mode, &bufsize)) 3139 return NULL; 3140 3141 Py_BEGIN_ALLOW_THREADS 3142 fp = fdopen(fd, mode); 3143 Py_END_ALLOW_THREADS 3144 if (fp == NULL) 3145 return posix_error(); 3146 f = PyFile_FromFile(fp, "(fdopen)", mode, fclose); 3147 if (f != NULL) 3148 PyFile_SetBufSize(f, bufsize); 3149 return f; 3150} 3151 3152 3153#ifdef HAVE_PIPE 3154static char posix_pipe__doc__[] = 3155"pipe() -> (read_end, write_end)\n\ 3156Create a pipe."; 3157 3158static PyObject * 3159posix_pipe(PyObject *self, PyObject *args) 3160{ 3161#if defined(PYOS_OS2) 3162 HFILE read, write; 3163 APIRET rc; 3164 3165 if (!PyArg_ParseTuple(args, ":pipe")) 3166 return NULL; 3167 3168 Py_BEGIN_ALLOW_THREADS 3169 rc = DosCreatePipe( &read, &write, 4096); 3170 Py_END_ALLOW_THREADS 3171 if (rc != NO_ERROR) 3172 return os2_error(rc); 3173 3174 return Py_BuildValue("(ii)", read, write); 3175#else 3176#if !defined(MS_WIN32) 3177 int fds[2]; 3178 int res; 3179 if (!PyArg_ParseTuple(args, ":pipe")) 3180 return NULL; 3181 Py_BEGIN_ALLOW_THREADS 3182 res = pipe(fds); 3183 Py_END_ALLOW_THREADS 3184 if (res != 0) 3185 return posix_error(); 3186 return Py_BuildValue("(ii)", fds[0], fds[1]); 3187#else /* MS_WIN32 */ 3188 HANDLE read, write; 3189 int read_fd, write_fd; 3190 BOOL ok; 3191 if (!PyArg_ParseTuple(args, ":pipe")) 3192 return NULL; 3193 Py_BEGIN_ALLOW_THREADS 3194 ok = CreatePipe(&read, &write, NULL, 0); 3195 Py_END_ALLOW_THREADS 3196 if (!ok) 3197 return win32_error("CreatePipe", NULL); 3198 read_fd = _open_osfhandle((intptr_t)read, 0); 3199 write_fd = _open_osfhandle((intptr_t)write, 1); 3200 return Py_BuildValue("(ii)", read_fd, write_fd); 3201#endif /* MS_WIN32 */ 3202#endif 3203} 3204#endif /* HAVE_PIPE */ 3205 3206 3207#ifdef HAVE_MKFIFO 3208static char posix_mkfifo__doc__[] = 3209"mkfifo(file, [, mode=0666]) -> None\n\ 3210Create a FIFO (a POSIX named pipe)."; 3211 3212static PyObject * 3213posix_mkfifo(PyObject *self, PyObject *args) 3214{ 3215 char *file; 3216 int mode = 0666; 3217 int res; 3218 if (!PyArg_ParseTuple(args, "s|i:mkfifo", &file, &mode)) 3219 return NULL; 3220 Py_BEGIN_ALLOW_THREADS 3221 res = mkfifo(file, mode); 3222 Py_END_ALLOW_THREADS 3223 if (res < 0) 3224 return posix_error(); 3225 Py_INCREF(Py_None); 3226 return Py_None; 3227} 3228#endif 3229 3230 3231#ifdef HAVE_FTRUNCATE 3232static char posix_ftruncate__doc__[] = 3233"ftruncate(fd, length) -> None\n\ 3234Truncate a file to a specified length."; 3235 3236static PyObject * 3237posix_ftruncate(PyObject *self, PyObject *args) 3238{ 3239 int fd; 3240 off_t length; 3241 int res; 3242 PyObject *lenobj; 3243 3244 if (!PyArg_ParseTuple(args, "iO:ftruncate", &fd, &lenobj)) 3245 return NULL; 3246 3247#if !defined(HAVE_LARGEFILE_SUPPORT) 3248 length = PyInt_AsLong(lenobj); 3249#else 3250 length = PyLong_Check(lenobj) ? 3251 PyLong_AsLongLong(lenobj) : PyInt_AsLong(lenobj); 3252#endif 3253 if (PyErr_Occurred()) 3254 return NULL; 3255 3256 Py_BEGIN_ALLOW_THREADS 3257 res = ftruncate(fd, length); 3258 Py_END_ALLOW_THREADS 3259 if (res < 0) { 3260 PyErr_SetFromErrno(PyExc_IOError); 3261 return NULL; 3262 } 3263 Py_INCREF(Py_None); 3264 return Py_None; 3265} 3266#endif 3267 3268#ifdef NeXT 3269#define HAVE_PUTENV 3270/* Steve Spicklemire got this putenv from NeXTAnswers */ 3271static int 3272putenv(char *newval) 3273{ 3274 extern char **environ; 3275 3276 static int firstTime = 1; 3277 char **ep; 3278 char *cp; 3279 int esiz; 3280 char *np; 3281 3282 if (!(np = strchr(newval, '='))) 3283 return 1; 3284 *np = '\0'; 3285 3286 /* look it up */ 3287 for (ep=environ ; *ep ; ep++) 3288 { 3289 /* this should always be true... */ 3290 if (cp = strchr(*ep, '=')) 3291 { 3292 *cp = '\0'; 3293 if (!strcmp(*ep, newval)) 3294 { 3295 /* got it! */ 3296 *cp = '='; 3297 break; 3298 } 3299 *cp = '='; 3300 } 3301 else 3302 { 3303 *np = '='; 3304 return 1; 3305 } 3306 } 3307 3308 *np = '='; 3309 if (*ep) 3310 { 3311 /* the string was already there: 3312 just replace it with the new one */ 3313 *ep = newval; 3314 return 0; 3315 } 3316 3317 /* expand environ by one */ 3318 for (esiz=2, ep=environ ; *ep ; ep++) 3319 esiz++; 3320 if (firstTime) 3321 { 3322 char **epp; 3323 char **newenv; 3324 if (!(newenv = malloc(esiz * sizeof(char *)))) 3325 return 1; 3326 3327 for (ep=environ, epp=newenv ; *ep ;) 3328 *epp++ = *ep++; 3329 *epp++ = newval; 3330 *epp = (char *) 0; 3331 environ = newenv; 3332 } 3333 else 3334 { 3335 if (!(environ = realloc(environ, esiz * sizeof(char *)))) 3336 return 1; 3337 environ[esiz - 2] = newval; 3338 environ[esiz - 1] = (char *) 0; 3339 firstTime = 0; 3340 } 3341 3342 return 0; 3343} 3344#endif /* NeXT */ 3345 3346 3347#ifdef HAVE_PUTENV 3348static char posix_putenv__doc__[] = 3349"putenv(key, value) -> None\n\ 3350Change or add an environment variable."; 3351 3352#ifdef __BEOS__ 3353/* We have putenv(), but not in the headers (as of PR2). - [cjh] */ 3354int putenv( const char *str ); 3355#endif 3356 3357/* Save putenv() parameters as values here, so we can collect them when they 3358 * get re-set with another call for the same key. */ 3359static PyObject *posix_putenv_garbage; 3360 3361static PyObject * 3362posix_putenv(PyObject *self, PyObject *args) 3363{ 3364 char *s1, *s2; 3365 char *new; 3366 PyObject *newstr; 3367 3368 if (!PyArg_ParseTuple(args, "ss:putenv", &s1, &s2)) 3369 return NULL; 3370 3371#if defined(PYOS_OS2) 3372 if (stricmp(s1, "BEGINLIBPATH") == 0) { 3373 APIRET rc; 3374 3375 if (strlen(s2) == 0) /* If New Value is an Empty String */ 3376 s2 = NULL; /* Then OS/2 API Wants a NULL to Undefine It */ 3377 3378 rc = DosSetExtLIBPATH(s2, BEGIN_LIBPATH); 3379 if (rc != NO_ERROR) 3380 return os2_error(rc); 3381 3382 } else if (stricmp(s1, "ENDLIBPATH") == 0) { 3383 APIRET rc; 3384 3385 if (strlen(s2) == 0) /* If New Value is an Empty String */ 3386 s2 = NULL; /* Then OS/2 API Wants a NULL to Undefine It */ 3387 3388 rc = DosSetExtLIBPATH(s2, END_LIBPATH); 3389 if (rc != NO_ERROR) 3390 return os2_error(rc); 3391 } else { 3392#endif 3393 3394 /* XXX This can leak memory -- not easy to fix :-( */ 3395 newstr = PyString_FromStringAndSize(NULL, strlen(s1) + strlen(s2) + 2); 3396 if (newstr == NULL) 3397 return PyErr_NoMemory(); 3398 new = PyString_AS_STRING(newstr); 3399 (void) sprintf(new, "%s=%s", s1, s2); 3400 if (putenv(new)) { 3401 posix_error(); 3402 return NULL; 3403 } 3404 /* Install the first arg and newstr in posix_putenv_garbage; 3405 * this will cause previous value to be collected. This has to 3406 * happen after the real putenv() call because the old value 3407 * was still accessible until then. */ 3408 if (PyDict_SetItem(posix_putenv_garbage, 3409 PyTuple_GET_ITEM(args, 0), newstr)) { 3410 /* really not much we can do; just leak */ 3411 PyErr_Clear(); 3412 } 3413 else { 3414 Py_DECREF(newstr); 3415 } 3416 3417#if defined(PYOS_OS2) 3418 } 3419#endif 3420 Py_INCREF(Py_None); 3421 return Py_None; 3422} 3423#endif /* putenv */ 3424 3425#ifdef HAVE_STRERROR 3426static char posix_strerror__doc__[] = 3427"strerror(code) -> string\n\ 3428Translate an error code to a message string."; 3429 3430PyObject * 3431posix_strerror(PyObject *self, PyObject *args) 3432{ 3433 int code; 3434 char *message; 3435 if (!PyArg_ParseTuple(args, "i:strerror", &code)) 3436 return NULL; 3437 message = strerror(code); 3438 if (message == NULL) { 3439 PyErr_SetString(PyExc_ValueError, 3440 "strerror code out of range"); 3441 return NULL; 3442 } 3443 return PyString_FromString(message); 3444} 3445#endif /* strerror */ 3446 3447 3448#ifdef HAVE_SYS_WAIT_H 3449 3450#ifdef WIFSTOPPED 3451static char posix_WIFSTOPPED__doc__[] = 3452"WIFSTOPPED(status) -> Boolean\n\ 3453Return true if the process returning 'status' was stopped."; 3454 3455static PyObject * 3456posix_WIFSTOPPED(PyObject *self, PyObject *args) 3457{ 3458#ifdef UNION_WAIT 3459 union wait status; 3460#define status_i (status.w_status) 3461#else 3462 int status; 3463#define status_i status 3464#endif 3465 status_i = 0; 3466 3467 if (!PyArg_ParseTuple(args, "i:WIFSTOPPED", &status_i)) 3468 { 3469 return NULL; 3470 } 3471 3472 return Py_BuildValue("i", WIFSTOPPED(status)); 3473#undef status_i 3474} 3475#endif /* WIFSTOPPED */ 3476 3477#ifdef WIFSIGNALED 3478static char posix_WIFSIGNALED__doc__[] = 3479"WIFSIGNALED(status) -> Boolean\n\ 3480Return true if the process returning 'status' was terminated by a signal."; 3481 3482static PyObject * 3483posix_WIFSIGNALED(PyObject *self, PyObject *args) 3484{ 3485#ifdef UNION_WAIT 3486 union wait status; 3487#define status_i (status.w_status) 3488#else 3489 int status; 3490#define status_i status 3491#endif 3492 status_i = 0; 3493 3494 if (!PyArg_ParseTuple(args, "i:WIFSIGNALED", &status_i)) 3495 { 3496 return NULL; 3497 } 3498 3499 return Py_BuildValue("i", WIFSIGNALED(status)); 3500#undef status_i 3501} 3502#endif /* WIFSIGNALED */ 3503 3504#ifdef WIFEXITED 3505static char posix_WIFEXITED__doc__[] = 3506"WIFEXITED(status) -> Boolean\n\ 3507Return true if the process returning 'status' exited using the exit()\n\ 3508system call."; 3509 3510static PyObject * 3511posix_WIFEXITED(PyObject *self, PyObject *args) 3512{ 3513#ifdef UNION_WAIT 3514 union wait status; 3515#define status_i (status.w_status) 3516#else 3517 int status; 3518#define status_i status 3519#endif 3520 status_i = 0; 3521 3522 if (!PyArg_ParseTuple(args, "i:WIFEXITED", &status_i)) 3523 { 3524 return NULL; 3525 } 3526 3527 return Py_BuildValue("i", WIFEXITED(status)); 3528#undef status_i 3529} 3530#endif /* WIFEXITED */ 3531 3532#ifdef WEXITSTATUS 3533static char posix_WEXITSTATUS__doc__[] = 3534"WEXITSTATUS(status) -> integer\n\ 3535Return the process return code from 'status'."; 3536 3537static PyObject * 3538posix_WEXITSTATUS(PyObject *self, PyObject *args) 3539{ 3540#ifdef UNION_WAIT 3541 union wait status; 3542#define status_i (status.w_status) 3543#else 3544 int status; 3545#define status_i status 3546#endif 3547 status_i = 0; 3548 3549 if (!PyArg_ParseTuple(args, "i:WEXITSTATUS", &status_i)) 3550 { 3551 return NULL; 3552 } 3553 3554 return Py_BuildValue("i", WEXITSTATUS(status)); 3555#undef status_i 3556} 3557#endif /* WEXITSTATUS */ 3558 3559#ifdef WTERMSIG 3560static char posix_WTERMSIG__doc__[] = 3561"WTERMSIG(status) -> integer\n\ 3562Return the signal that terminated the process that provided the 'status'\n\ 3563value."; 3564 3565static PyObject * 3566posix_WTERMSIG(PyObject *self, PyObject *args) 3567{ 3568#ifdef UNION_WAIT 3569 union wait status; 3570#define status_i (status.w_status) 3571#else 3572 int status; 3573#define status_i status 3574#endif 3575 status_i = 0; 3576 3577 if (!PyArg_ParseTuple(args, "i:WTERMSIG", &status_i)) 3578 { 3579 return NULL; 3580 } 3581 3582 return Py_BuildValue("i", WTERMSIG(status)); 3583#undef status_i 3584} 3585#endif /* WTERMSIG */ 3586 3587#ifdef WSTOPSIG 3588static char posix_WSTOPSIG__doc__[] = 3589"WSTOPSIG(status) -> integer\n\ 3590Return the signal that stopped the process that provided the 'status' value."; 3591 3592static PyObject * 3593posix_WSTOPSIG(PyObject *self, PyObject *args) 3594{ 3595#ifdef UNION_WAIT 3596 union wait status; 3597#define status_i (status.w_status) 3598#else 3599 int status; 3600#define status_i status 3601#endif 3602 status_i = 0; 3603 3604 if (!PyArg_ParseTuple(args, "i:WSTOPSIG", &status_i)) 3605 { 3606 return NULL; 3607 } 3608 3609 return Py_BuildValue("i", WSTOPSIG(status)); 3610#undef status_i 3611} 3612#endif /* WSTOPSIG */ 3613 3614#endif /* HAVE_SYS_WAIT_H */ 3615 3616 3617#if defined(HAVE_FSTATVFS) 3618#ifdef _SCO_DS 3619/* SCO OpenServer 5.0 and later requires _SVID3 before it reveals the 3620 needed definitions in sys/statvfs.h */ 3621#define _SVID3 3622#endif 3623#include <sys/statvfs.h> 3624 3625static char posix_fstatvfs__doc__[] = 3626"fstatvfs(fd) -> \n\ 3627 (bsize, frsize, blocks, bfree, bavail, files, ffree, favail, flag, namemax)\n\ 3628Perform an fstatvfs system call on the given fd."; 3629 3630static PyObject * 3631posix_fstatvfs(PyObject *self, PyObject *args) 3632{ 3633 int fd, res; 3634 struct statvfs st; 3635 if (!PyArg_ParseTuple(args, "i:fstatvfs", &fd)) 3636 return NULL; 3637 Py_BEGIN_ALLOW_THREADS 3638 res = fstatvfs(fd, &st); 3639 Py_END_ALLOW_THREADS 3640 if (res != 0) 3641 return posix_error(); 3642#if !defined(HAVE_LARGEFILE_SUPPORT) 3643 return Py_BuildValue("(llllllllll)", 3644 (long) st.f_bsize, 3645 (long) st.f_frsize, 3646 (long) st.f_blocks, 3647 (long) st.f_bfree, 3648 (long) st.f_bavail, 3649 (long) st.f_files, 3650 (long) st.f_ffree, 3651 (long) st.f_favail, 3652 (long) st.f_flag, 3653 (long) st.f_namemax); 3654#else 3655 return Py_BuildValue("(llLLLLLLll)", 3656 (long) st.f_bsize, 3657 (long) st.f_frsize, 3658 (LONG_LONG) st.f_blocks, 3659 (LONG_LONG) st.f_bfree, 3660 (LONG_LONG) st.f_bavail, 3661 (LONG_LONG) st.f_files, 3662 (LONG_LONG) st.f_ffree, 3663 (LONG_LONG) st.f_favail, 3664 (long) st.f_flag, 3665 (long) st.f_namemax); 3666#endif 3667} 3668#endif /* HAVE_FSTATVFS */ 3669 3670 3671#if defined(HAVE_STATVFS) 3672#include <sys/statvfs.h> 3673 3674static char posix_statvfs__doc__[] = 3675"statvfs(path) -> \n\ 3676 (bsize, frsize, blocks, bfree, bavail, files, ffree, favail, flag, namemax)\n\ 3677Perform a statvfs system call on the given path."; 3678 3679static PyObject * 3680posix_statvfs(PyObject *self, PyObject *args) 3681{ 3682 char *path; 3683 int res; 3684 struct statvfs st; 3685 if (!PyArg_ParseTuple(args, "s:statvfs", &path)) 3686 return NULL; 3687 Py_BEGIN_ALLOW_THREADS 3688 res = statvfs(path, &st); 3689 Py_END_ALLOW_THREADS 3690 if (res != 0) 3691 return posix_error_with_filename(path); 3692#if !defined(HAVE_LARGEFILE_SUPPORT) 3693 return Py_BuildValue("(llllllllll)", 3694 (long) st.f_bsize, 3695 (long) st.f_frsize, 3696 (long) st.f_blocks, 3697 (long) st.f_bfree, 3698 (long) st.f_bavail, 3699 (long) st.f_files, 3700 (long) st.f_ffree, 3701 (long) st.f_favail, 3702 (long) st.f_flag, 3703 (long) st.f_namemax); 3704#else /* HAVE_LARGEFILE_SUPPORT */ 3705 return Py_BuildValue("(llLLLLLLll)", 3706 (long) st.f_bsize, 3707 (long) st.f_frsize, 3708 (LONG_LONG) st.f_blocks, 3709 (LONG_LONG) st.f_bfree, 3710 (LONG_LONG) st.f_bavail, 3711 (LONG_LONG) st.f_files, 3712 (LONG_LONG) st.f_ffree, 3713 (LONG_LONG) st.f_favail, 3714 (long) st.f_flag, 3715 (long) st.f_namemax); 3716#endif 3717} 3718#endif /* HAVE_STATVFS */ 3719 3720 3721#ifdef HAVE_TEMPNAM 3722static char posix_tempnam__doc__[] = "\ 3723tempnam([dir[, prefix]]) -> string\n\ 3724Return a unique name for a temporary file.\n\ 3725The directory and a short may be specified as strings; they may be omitted\n\ 3726or None if not needed."; 3727 3728static PyObject * 3729posix_tempnam(PyObject *self, PyObject *args) 3730{ 3731 PyObject *result = NULL; 3732 char *dir = NULL; 3733 char *pfx = NULL; 3734 char *name; 3735 3736 if (!PyArg_ParseTuple(args, "|zz:tempnam", &dir, &pfx)) 3737 return NULL; 3738 name = tempnam(dir, pfx); 3739 if (name == NULL) 3740 return PyErr_NoMemory(); 3741 result = PyString_FromString(name); 3742 free(name); 3743 return result; 3744} 3745#endif 3746 3747 3748#ifdef HAVE_TMPFILE 3749static char posix_tmpfile__doc__[] = "\ 3750tmpfile() -> file object\n\ 3751Create a temporary file with no directory entries."; 3752 3753static PyObject * 3754posix_tmpfile(PyObject *self, PyObject *args) 3755{ 3756 FILE *fp; 3757 3758 if (!PyArg_ParseTuple(args, ":tmpfile")) 3759 return NULL; 3760 fp = tmpfile(); 3761 if (fp == NULL) 3762 return posix_error(); 3763 return PyFile_FromFile(fp, "<tmpfile>", "w+", fclose); 3764} 3765#endif 3766 3767 3768#ifdef HAVE_TMPNAM 3769static char posix_tmpnam__doc__[] = "\ 3770tmpnam() -> string\n\ 3771Return a unique name for a temporary file."; 3772 3773static PyObject * 3774posix_tmpnam(PyObject *self, PyObject *args) 3775{ 3776 char buffer[L_tmpnam]; 3777 char *name; 3778 3779 if (!PyArg_ParseTuple(args, ":tmpnam")) 3780 return NULL; 3781#ifdef USE_TMPNAM_R 3782 name = tmpnam_r(buffer); 3783#else 3784 name = tmpnam(buffer); 3785#endif 3786 if (name == NULL) { 3787 PyErr_SetObject(PyExc_OSError, 3788 Py_BuildValue("is", 0, 3789#ifdef USE_TMPNAM_R 3790 "unexpected NULL from tmpnam_r" 3791#else 3792 "unexpected NULL from tmpnam" 3793#endif 3794 )); 3795 return NULL; 3796 } 3797 return PyString_FromString(buffer); 3798} 3799#endif 3800 3801 3802/* This is used for fpathconf(), pathconf(), confstr() and sysconf(). 3803 * It maps strings representing configuration variable names to 3804 * integer values, allowing those functions to be called with the 3805 * magic names instead of poluting the module's namespace with tons of 3806 * rarely-used constants. There are three separate tables that use 3807 * these definitions. 3808 * 3809 * This code is always included, even if none of the interfaces that 3810 * need it are included. The #if hackery needed to avoid it would be 3811 * sufficiently pervasive that it's not worth the loss of readability. 3812 */ 3813struct constdef { 3814 char *name; 3815 long value; 3816}; 3817 3818static int 3819conv_confname(PyObject *arg, int *valuep, struct constdef *table, 3820 size_t tablesize) 3821{ 3822 if (PyInt_Check(arg)) { 3823 *valuep = PyInt_AS_LONG(arg); 3824 return 1; 3825 } 3826 if (PyString_Check(arg)) { 3827 /* look up the value in the table using a binary search */ 3828 size_t lo = 0; 3829 size_t mid; 3830 size_t hi = tablesize; 3831 int cmp; 3832 char *confname = PyString_AS_STRING(arg); 3833 while (lo < hi) { 3834 mid = (lo + hi) / 2; 3835 cmp = strcmp(confname, table[mid].name); 3836 if (cmp < 0) 3837 hi = mid; 3838 else if (cmp > 0) 3839 lo = mid + 1; 3840 else { 3841 *valuep = table[mid].value; 3842 return 1; 3843 } 3844 } 3845 PyErr_SetString(PyExc_ValueError, "unrecognized configuration name"); 3846 } 3847 else 3848 PyErr_SetString(PyExc_TypeError, 3849 "configuration names must be strings or integers"); 3850 return 0; 3851} 3852 3853 3854#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF) 3855static struct constdef posix_constants_pathconf[] = { 3856#ifdef _PC_ABI_AIO_XFER_MAX 3857 {"PC_ABI_AIO_XFER_MAX", _PC_ABI_AIO_XFER_MAX}, 3858#endif 3859#ifdef _PC_ABI_ASYNC_IO 3860 {"PC_ABI_ASYNC_IO", _PC_ABI_ASYNC_IO}, 3861#endif 3862#ifdef _PC_ASYNC_IO 3863 {"PC_ASYNC_IO", _PC_ASYNC_IO}, 3864#endif 3865#ifdef _PC_CHOWN_RESTRICTED 3866 {"PC_CHOWN_RESTRICTED", _PC_CHOWN_RESTRICTED}, 3867#endif 3868#ifdef _PC_FILESIZEBITS 3869 {"PC_FILESIZEBITS", _PC_FILESIZEBITS}, 3870#endif 3871#ifdef _PC_LAST 3872 {"PC_LAST", _PC_LAST}, 3873#endif 3874#ifdef _PC_LINK_MAX 3875 {"PC_LINK_MAX", _PC_LINK_MAX}, 3876#endif 3877#ifdef _PC_MAX_CANON 3878 {"PC_MAX_CANON", _PC_MAX_CANON}, 3879#endif 3880#ifdef _PC_MAX_INPUT 3881 {"PC_MAX_INPUT", _PC_MAX_INPUT}, 3882#endif 3883#ifdef _PC_NAME_MAX 3884 {"PC_NAME_MAX", _PC_NAME_MAX}, 3885#endif 3886#ifdef _PC_NO_TRUNC 3887 {"PC_NO_TRUNC", _PC_NO_TRUNC}, 3888#endif 3889#ifdef _PC_PATH_MAX 3890 {"PC_PATH_MAX", _PC_PATH_MAX}, 3891#endif 3892#ifdef _PC_PIPE_BUF 3893 {"PC_PIPE_BUF", _PC_PIPE_BUF}, 3894#endif 3895#ifdef _PC_PRIO_IO 3896 {"PC_PRIO_IO", _PC_PRIO_IO}, 3897#endif 3898#ifdef _PC_SOCK_MAXBUF 3899 {"PC_SOCK_MAXBUF", _PC_SOCK_MAXBUF}, 3900#endif 3901#ifdef _PC_SYNC_IO 3902 {"PC_SYNC_IO", _PC_SYNC_IO}, 3903#endif 3904#ifdef _PC_VDISABLE 3905 {"PC_VDISABLE", _PC_VDISABLE}, 3906#endif 3907}; 3908 3909static int 3910conv_path_confname(PyObject *arg, int *valuep) 3911{ 3912 return conv_confname(arg, valuep, posix_constants_pathconf, 3913 sizeof(posix_constants_pathconf) 3914 / sizeof(struct constdef)); 3915} 3916#endif 3917 3918#ifdef HAVE_FPATHCONF 3919static char posix_fpathconf__doc__[] = "\ 3920fpathconf(fd, name) -> integer\n\ 3921Return the configuration limit name for the file descriptor fd.\n\ 3922If there is no limit, return -1."; 3923 3924static PyObject * 3925posix_fpathconf(PyObject *self, PyObject *args) 3926{ 3927 PyObject *result = NULL; 3928 int name, fd; 3929 3930 if (PyArg_ParseTuple(args, "iO&:fpathconf", &fd, 3931 conv_path_confname, &name)) { 3932 long limit; 3933 3934 errno = 0; 3935 limit = fpathconf(fd, name); 3936 if (limit == -1 && errno != 0) 3937 posix_error(); 3938 else 3939 result = PyInt_FromLong(limit); 3940 } 3941 return result; 3942} 3943#endif 3944 3945 3946#ifdef HAVE_PATHCONF 3947static char posix_pathconf__doc__[] = "\ 3948pathconf(path, name) -> integer\n\ 3949Return the configuration limit name for the file or directory path.\n\ 3950If there is no limit, return -1."; 3951 3952static PyObject * 3953posix_pathconf(PyObject *self, PyObject *args) 3954{ 3955 PyObject *result = NULL; 3956 int name; 3957 char *path; 3958 3959 if (PyArg_ParseTuple(args, "sO&:pathconf", &path, 3960 conv_path_confname, &name)) { 3961 long limit; 3962 3963 errno = 0; 3964 limit = pathconf(path, name); 3965 if (limit == -1 && errno != 0) { 3966 if (errno == EINVAL) 3967 /* could be a path or name problem */ 3968 posix_error(); 3969 else 3970 posix_error_with_filename(path); 3971 } 3972 else 3973 result = PyInt_FromLong(limit); 3974 } 3975 return result; 3976} 3977#endif 3978 3979#ifdef HAVE_CONFSTR 3980static struct constdef posix_constants_confstr[] = { 3981#ifdef _CS_ARCHITECTURE 3982 {"CS_ARCHITECTURE", _CS_ARCHITECTURE}, 3983#endif 3984#ifdef _CS_HOSTNAME 3985 {"CS_HOSTNAME", _CS_HOSTNAME}, 3986#endif 3987#ifdef _CS_HW_PROVIDER 3988 {"CS_HW_PROVIDER", _CS_HW_PROVIDER}, 3989#endif 3990#ifdef _CS_HW_SERIAL 3991 {"CS_HW_SERIAL", _CS_HW_SERIAL}, 3992#endif 3993#ifdef _CS_INITTAB_NAME 3994 {"CS_INITTAB_NAME", _CS_INITTAB_NAME}, 3995#endif 3996#ifdef _CS_LFS64_CFLAGS 3997 {"CS_LFS64_CFLAGS", _CS_LFS64_CFLAGS}, 3998#endif 3999#ifdef _CS_LFS64_LDFLAGS 4000 {"CS_LFS64_LDFLAGS", _CS_LFS64_LDFLAGS}, 4001#endif 4002#ifdef _CS_LFS64_LIBS 4003 {"CS_LFS64_LIBS", _CS_LFS64_LIBS}, 4004#endif 4005#ifdef _CS_LFS64_LINTFLAGS 4006 {"CS_LFS64_LINTFLAGS", _CS_LFS64_LINTFLAGS}, 4007#endif 4008#ifdef _CS_LFS_CFLAGS 4009 {"CS_LFS_CFLAGS", _CS_LFS_CFLAGS}, 4010#endif 4011#ifdef _CS_LFS_LDFLAGS 4012 {"CS_LFS_LDFLAGS", _CS_LFS_LDFLAGS}, 4013#endif 4014#ifdef _CS_LFS_LIBS 4015 {"CS_LFS_LIBS", _CS_LFS_LIBS}, 4016#endif 4017#ifdef _CS_LFS_LINTFLAGS 4018 {"CS_LFS_LINTFLAGS", _CS_LFS_LINTFLAGS}, 4019#endif 4020#ifdef _CS_MACHINE 4021 {"CS_MACHINE", _CS_MACHINE}, 4022#endif 4023#ifdef _CS_PATH 4024 {"CS_PATH", _CS_PATH}, 4025#endif 4026#ifdef _CS_RELEASE 4027 {"CS_RELEASE", _CS_RELEASE}, 4028#endif 4029#ifdef _CS_SRPC_DOMAIN 4030 {"CS_SRPC_DOMAIN", _CS_SRPC_DOMAIN}, 4031#endif 4032#ifdef _CS_SYSNAME 4033 {"CS_SYSNAME", _CS_SYSNAME}, 4034#endif 4035#ifdef _CS_VERSION 4036 {"CS_VERSION", _CS_VERSION}, 4037#endif 4038#ifdef _CS_XBS5_ILP32_OFF32_CFLAGS 4039 {"CS_XBS5_ILP32_OFF32_CFLAGS", _CS_XBS5_ILP32_OFF32_CFLAGS}, 4040#endif 4041#ifdef _CS_XBS5_ILP32_OFF32_LDFLAGS 4042 {"CS_XBS5_ILP32_OFF32_LDFLAGS", _CS_XBS5_ILP32_OFF32_LDFLAGS}, 4043#endif 4044#ifdef _CS_XBS5_ILP32_OFF32_LIBS 4045 {"CS_XBS5_ILP32_OFF32_LIBS", _CS_XBS5_ILP32_OFF32_LIBS}, 4046#endif 4047#ifdef _CS_XBS5_ILP32_OFF32_LINTFLAGS 4048 {"CS_XBS5_ILP32_OFF32_LINTFLAGS", _CS_XBS5_ILP32_OFF32_LINTFLAGS}, 4049#endif 4050#ifdef _CS_XBS5_ILP32_OFFBIG_CFLAGS 4051 {"CS_XBS5_ILP32_OFFBIG_CFLAGS", _CS_XBS5_ILP32_OFFBIG_CFLAGS}, 4052#endif 4053#ifdef _CS_XBS5_ILP32_OFFBIG_LDFLAGS 4054 {"CS_XBS5_ILP32_OFFBIG_LDFLAGS", _CS_XBS5_ILP32_OFFBIG_LDFLAGS}, 4055#endif 4056#ifdef _CS_XBS5_ILP32_OFFBIG_LIBS 4057 {"CS_XBS5_ILP32_OFFBIG_LIBS", _CS_XBS5_ILP32_OFFBIG_LIBS}, 4058#endif 4059#ifdef _CS_XBS5_ILP32_OFFBIG_LINTFLAGS 4060 {"CS_XBS5_ILP32_OFFBIG_LINTFLAGS", _CS_XBS5_ILP32_OFFBIG_LINTFLAGS}, 4061#endif 4062#ifdef _CS_XBS5_LP64_OFF64_CFLAGS 4063 {"CS_XBS5_LP64_OFF64_CFLAGS", _CS_XBS5_LP64_OFF64_CFLAGS}, 4064#endif 4065#ifdef _CS_XBS5_LP64_OFF64_LDFLAGS 4066 {"CS_XBS5_LP64_OFF64_LDFLAGS", _CS_XBS5_LP64_OFF64_LDFLAGS}, 4067#endif 4068#ifdef _CS_XBS5_LP64_OFF64_LIBS 4069 {"CS_XBS5_LP64_OFF64_LIBS", _CS_XBS5_LP64_OFF64_LIBS}, 4070#endif 4071#ifdef _CS_XBS5_LP64_OFF64_LINTFLAGS 4072 {"CS_XBS5_LP64_OFF64_LINTFLAGS", _CS_XBS5_LP64_OFF64_LINTFLAGS}, 4073#endif 4074#ifdef _CS_XBS5_LPBIG_OFFBIG_CFLAGS 4075 {"CS_XBS5_LPBIG_OFFBIG_CFLAGS", _CS_XBS5_LPBIG_OFFBIG_CFLAGS}, 4076#endif 4077#ifdef _CS_XBS5_LPBIG_OFFBIG_LDFLAGS 4078 {"CS_XBS5_LPBIG_OFFBIG_LDFLAGS", _CS_XBS5_LPBIG_OFFBIG_LDFLAGS}, 4079#endif 4080#ifdef _CS_XBS5_LPBIG_OFFBIG_LIBS 4081 {"CS_XBS5_LPBIG_OFFBIG_LIBS", _CS_XBS5_LPBIG_OFFBIG_LIBS}, 4082#endif 4083#ifdef _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS 4084 {"CS_XBS5_LPBIG_OFFBIG_LINTFLAGS", _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS}, 4085#endif 4086#ifdef _MIPS_CS_AVAIL_PROCESSORS 4087 {"MIPS_CS_AVAIL_PROCESSORS", _MIPS_CS_AVAIL_PROCESSORS}, 4088#endif 4089#ifdef _MIPS_CS_BASE 4090 {"MIPS_CS_BASE", _MIPS_CS_BASE}, 4091#endif 4092#ifdef _MIPS_CS_HOSTID 4093 {"MIPS_CS_HOSTID", _MIPS_CS_HOSTID}, 4094#endif 4095#ifdef _MIPS_CS_HW_NAME 4096 {"MIPS_CS_HW_NAME", _MIPS_CS_HW_NAME}, 4097#endif 4098#ifdef _MIPS_CS_NUM_PROCESSORS 4099 {"MIPS_CS_NUM_PROCESSORS", _MIPS_CS_NUM_PROCESSORS}, 4100#endif 4101#ifdef _MIPS_CS_OSREL_MAJ 4102 {"MIPS_CS_OSREL_MAJ", _MIPS_CS_OSREL_MAJ}, 4103#endif 4104#ifdef _MIPS_CS_OSREL_MIN 4105 {"MIPS_CS_OSREL_MIN", _MIPS_CS_OSREL_MIN}, 4106#endif 4107#ifdef _MIPS_CS_OSREL_PATCH 4108 {"MIPS_CS_OSREL_PATCH", _MIPS_CS_OSREL_PATCH}, 4109#endif 4110#ifdef _MIPS_CS_OS_NAME 4111 {"MIPS_CS_OS_NAME", _MIPS_CS_OS_NAME}, 4112#endif 4113#ifdef _MIPS_CS_OS_PROVIDER 4114 {"MIPS_CS_OS_PROVIDER", _MIPS_CS_OS_PROVIDER}, 4115#endif 4116#ifdef _MIPS_CS_PROCESSORS 4117 {"MIPS_CS_PROCESSORS", _MIPS_CS_PROCESSORS}, 4118#endif 4119#ifdef _MIPS_CS_SERIAL 4120 {"MIPS_CS_SERIAL", _MIPS_CS_SERIAL}, 4121#endif 4122#ifdef _MIPS_CS_VENDOR 4123 {"MIPS_CS_VENDOR", _MIPS_CS_VENDOR}, 4124#endif 4125}; 4126 4127static int 4128conv_confstr_confname(PyObject *arg, int *valuep) 4129{ 4130 return conv_confname(arg, valuep, posix_constants_confstr, 4131 sizeof(posix_constants_confstr) 4132 / sizeof(struct constdef)); 4133} 4134 4135static char posix_confstr__doc__[] = "\ 4136confstr(name) -> string\n\ 4137Return a string-valued system configuration variable."; 4138 4139static PyObject * 4140posix_confstr(PyObject *self, PyObject *args) 4141{ 4142 PyObject *result = NULL; 4143 int name; 4144 char buffer[64]; 4145 4146 if (PyArg_ParseTuple(args, "O&:confstr", conv_confstr_confname, &name)) { 4147 int len = confstr(name, buffer, sizeof(buffer)); 4148 4149 errno = 0; 4150 if (len == 0) { 4151 if (errno != 0) 4152 posix_error(); 4153 else 4154 result = PyString_FromString(""); 4155 } 4156 else { 4157 if (len >= sizeof(buffer)) { 4158 result = PyString_FromStringAndSize(NULL, len); 4159 if (result != NULL) 4160 confstr(name, PyString_AS_STRING(result), len+1); 4161 } 4162 else 4163 result = PyString_FromString(buffer); 4164 } 4165 } 4166 return result; 4167} 4168#endif 4169 4170 4171#ifdef HAVE_SYSCONF 4172static struct constdef posix_constants_sysconf[] = { 4173#ifdef _SC_2_CHAR_TERM 4174 {"SC_2_CHAR_TERM", _SC_2_CHAR_TERM}, 4175#endif 4176#ifdef _SC_2_C_BIND 4177 {"SC_2_C_BIND", _SC_2_C_BIND}, 4178#endif 4179#ifdef _SC_2_C_DEV 4180 {"SC_2_C_DEV", _SC_2_C_DEV}, 4181#endif 4182#ifdef _SC_2_C_VERSION 4183 {"SC_2_C_VERSION", _SC_2_C_VERSION}, 4184#endif 4185#ifdef _SC_2_FORT_DEV 4186 {"SC_2_FORT_DEV", _SC_2_FORT_DEV}, 4187#endif 4188#ifdef _SC_2_FORT_RUN 4189 {"SC_2_FORT_RUN", _SC_2_FORT_RUN}, 4190#endif 4191#ifdef _SC_2_LOCALEDEF 4192 {"SC_2_LOCALEDEF", _SC_2_LOCALEDEF}, 4193#endif 4194#ifdef _SC_2_SW_DEV 4195 {"SC_2_SW_DEV", _SC_2_SW_DEV}, 4196#endif 4197#ifdef _SC_2_UPE 4198 {"SC_2_UPE", _SC_2_UPE}, 4199#endif 4200#ifdef _SC_2_VERSION 4201 {"SC_2_VERSION", _SC_2_VERSION}, 4202#endif 4203#ifdef _SC_ABI_ASYNCHRONOUS_IO 4204 {"SC_ABI_ASYNCHRONOUS_IO", _SC_ABI_ASYNCHRONOUS_IO}, 4205#endif 4206#ifdef _SC_ACL 4207 {"SC_ACL", _SC_ACL}, 4208#endif 4209#ifdef _SC_AIO_LISTIO_MAX 4210 {"SC_AIO_LISTIO_MAX", _SC_AIO_LISTIO_MAX}, 4211#endif 4212#ifdef _SC_AIO_MAX 4213 {"SC_AIO_MAX", _SC_AIO_MAX}, 4214#endif 4215#ifdef _SC_AIO_PRIO_DELTA_MAX 4216 {"SC_AIO_PRIO_DELTA_MAX", _SC_AIO_PRIO_DELTA_MAX}, 4217#endif 4218#ifdef _SC_ARG_MAX 4219 {"SC_ARG_MAX", _SC_ARG_MAX}, 4220#endif 4221#ifdef _SC_ASYNCHRONOUS_IO 4222 {"SC_ASYNCHRONOUS_IO", _SC_ASYNCHRONOUS_IO}, 4223#endif 4224#ifdef _SC_ATEXIT_MAX 4225 {"SC_ATEXIT_MAX", _SC_ATEXIT_MAX}, 4226#endif 4227#ifdef _SC_AUDIT 4228 {"SC_AUDIT", _SC_AUDIT}, 4229#endif 4230#ifdef _SC_AVPHYS_PAGES 4231 {"SC_AVPHYS_PAGES", _SC_AVPHYS_PAGES}, 4232#endif 4233#ifdef _SC_BC_BASE_MAX 4234 {"SC_BC_BASE_MAX", _SC_BC_BASE_MAX}, 4235#endif 4236#ifdef _SC_BC_DIM_MAX 4237 {"SC_BC_DIM_MAX", _SC_BC_DIM_MAX}, 4238#endif 4239#ifdef _SC_BC_SCALE_MAX 4240 {"SC_BC_SCALE_MAX", _SC_BC_SCALE_MAX}, 4241#endif 4242#ifdef _SC_BC_STRING_MAX 4243 {"SC_BC_STRING_MAX", _SC_BC_STRING_MAX}, 4244#endif 4245#ifdef _SC_CAP 4246 {"SC_CAP", _SC_CAP}, 4247#endif 4248#ifdef _SC_CHARCLASS_NAME_MAX 4249 {"SC_CHARCLASS_NAME_MAX", _SC_CHARCLASS_NAME_MAX}, 4250#endif 4251#ifdef _SC_CHAR_BIT 4252 {"SC_CHAR_BIT", _SC_CHAR_BIT}, 4253#endif 4254#ifdef _SC_CHAR_MAX 4255 {"SC_CHAR_MAX", _SC_CHAR_MAX}, 4256#endif 4257#ifdef _SC_CHAR_MIN 4258 {"SC_CHAR_MIN", _SC_CHAR_MIN}, 4259#endif 4260#ifdef _SC_CHILD_MAX 4261 {"SC_CHILD_MAX", _SC_CHILD_MAX}, 4262#endif 4263#ifdef _SC_CLK_TCK 4264 {"SC_CLK_TCK", _SC_CLK_TCK}, 4265#endif 4266#ifdef _SC_COHER_BLKSZ 4267 {"SC_COHER_BLKSZ", _SC_COHER_BLKSZ}, 4268#endif 4269#ifdef _SC_COLL_WEIGHTS_MAX 4270 {"SC_COLL_WEIGHTS_MAX", _SC_COLL_WEIGHTS_MAX}, 4271#endif 4272#ifdef _SC_DCACHE_ASSOC 4273 {"SC_DCACHE_ASSOC", _SC_DCACHE_ASSOC}, 4274#endif 4275#ifdef _SC_DCACHE_BLKSZ 4276 {"SC_DCACHE_BLKSZ", _SC_DCACHE_BLKSZ}, 4277#endif 4278#ifdef _SC_DCACHE_LINESZ 4279 {"SC_DCACHE_LINESZ", _SC_DCACHE_LINESZ}, 4280#endif 4281#ifdef _SC_DCACHE_SZ 4282 {"SC_DCACHE_SZ", _SC_DCACHE_SZ}, 4283#endif 4284#ifdef _SC_DCACHE_TBLKSZ 4285 {"SC_DCACHE_TBLKSZ", _SC_DCACHE_TBLKSZ}, 4286#endif 4287#ifdef _SC_DELAYTIMER_MAX 4288 {"SC_DELAYTIMER_MAX", _SC_DELAYTIMER_MAX}, 4289#endif 4290#ifdef _SC_EQUIV_CLASS_MAX 4291 {"SC_EQUIV_CLASS_MAX", _SC_EQUIV_CLASS_MAX}, 4292#endif 4293#ifdef _SC_EXPR_NEST_MAX 4294 {"SC_EXPR_NEST_MAX", _SC_EXPR_NEST_MAX}, 4295#endif 4296#ifdef _SC_FSYNC 4297 {"SC_FSYNC", _SC_FSYNC}, 4298#endif 4299#ifdef _SC_GETGR_R_SIZE_MAX 4300 {"SC_GETGR_R_SIZE_MAX", _SC_GETGR_R_SIZE_MAX}, 4301#endif 4302#ifdef _SC_GETPW_R_SIZE_MAX 4303 {"SC_GETPW_R_SIZE_MAX", _SC_GETPW_R_SIZE_MAX}, 4304#endif 4305#ifdef _SC_ICACHE_ASSOC 4306 {"SC_ICACHE_ASSOC", _SC_ICACHE_ASSOC}, 4307#endif 4308#ifdef _SC_ICACHE_BLKSZ 4309 {"SC_ICACHE_BLKSZ", _SC_ICACHE_BLKSZ}, 4310#endif 4311#ifdef _SC_ICACHE_LINESZ 4312 {"SC_ICACHE_LINESZ", _SC_ICACHE_LINESZ}, 4313#endif 4314#ifdef _SC_ICACHE_SZ 4315 {"SC_ICACHE_SZ", _SC_ICACHE_SZ}, 4316#endif 4317#ifdef _SC_INF 4318 {"SC_INF", _SC_INF}, 4319#endif 4320#ifdef _SC_INT_MAX 4321 {"SC_INT_MAX", _SC_INT_MAX}, 4322#endif 4323#ifdef _SC_INT_MIN 4324 {"SC_INT_MIN", _SC_INT_MIN}, 4325#endif 4326#ifdef _SC_IOV_MAX 4327 {"SC_IOV_MAX", _SC_IOV_MAX}, 4328#endif 4329#ifdef _SC_IP_SECOPTS 4330 {"SC_IP_SECOPTS", _SC_IP_SECOPTS}, 4331#endif 4332#ifdef _SC_JOB_CONTROL 4333 {"SC_JOB_CONTROL", _SC_JOB_CONTROL}, 4334#endif 4335#ifdef _SC_KERN_POINTERS 4336 {"SC_KERN_POINTERS", _SC_KERN_POINTERS}, 4337#endif 4338#ifdef _SC_KERN_SIM 4339 {"SC_KERN_SIM", _SC_KERN_SIM}, 4340#endif 4341#ifdef _SC_LINE_MAX 4342 {"SC_LINE_MAX", _SC_LINE_MAX}, 4343#endif 4344#ifdef _SC_LOGIN_NAME_MAX 4345 {"SC_LOGIN_NAME_MAX", _SC_LOGIN_NAME_MAX}, 4346#endif 4347#ifdef _SC_LOGNAME_MAX 4348 {"SC_LOGNAME_MAX", _SC_LOGNAME_MAX}, 4349#endif 4350#ifdef _SC_LONG_BIT 4351 {"SC_LONG_BIT", _SC_LONG_BIT}, 4352#endif 4353#ifdef _SC_MAC 4354 {"SC_MAC", _SC_MAC}, 4355#endif 4356#ifdef _SC_MAPPED_FILES 4357 {"SC_MAPPED_FILES", _SC_MAPPED_FILES}, 4358#endif 4359#ifdef _SC_MAXPID 4360 {"SC_MAXPID", _SC_MAXPID}, 4361#endif 4362#ifdef _SC_MB_LEN_MAX 4363 {"SC_MB_LEN_MAX", _SC_MB_LEN_MAX}, 4364#endif 4365#ifdef _SC_MEMLOCK 4366 {"SC_MEMLOCK", _SC_MEMLOCK}, 4367#endif 4368#ifdef _SC_MEMLOCK_RANGE 4369 {"SC_MEMLOCK_RANGE", _SC_MEMLOCK_RANGE}, 4370#endif 4371#ifdef _SC_MEMORY_PROTECTION 4372 {"SC_MEMORY_PROTECTION", _SC_MEMORY_PROTECTION}, 4373#endif 4374#ifdef _SC_MESSAGE_PASSING 4375 {"SC_MESSAGE_PASSING", _SC_MESSAGE_PASSING}, 4376#endif 4377#ifdef _SC_MMAP_FIXED_ALIGNMENT 4378 {"SC_MMAP_FIXED_ALIGNMENT", _SC_MMAP_FIXED_ALIGNMENT}, 4379#endif 4380#ifdef _SC_MQ_OPEN_MAX 4381 {"SC_MQ_OPEN_MAX", _SC_MQ_OPEN_MAX}, 4382#endif 4383#ifdef _SC_MQ_PRIO_MAX 4384 {"SC_MQ_PRIO_MAX", _SC_MQ_PRIO_MAX}, 4385#endif 4386#ifdef _SC_NACLS_MAX 4387 {"SC_NACLS_MAX", _SC_NACLS_MAX}, 4388#endif 4389#ifdef _SC_NGROUPS_MAX 4390 {"SC_NGROUPS_MAX", _SC_NGROUPS_MAX}, 4391#endif 4392#ifdef _SC_NL_ARGMAX 4393 {"SC_NL_ARGMAX", _SC_NL_ARGMAX}, 4394#endif 4395#ifdef _SC_NL_LANGMAX 4396 {"SC_NL_LANGMAX", _SC_NL_LANGMAX}, 4397#endif 4398#ifdef _SC_NL_MSGMAX 4399 {"SC_NL_MSGMAX", _SC_NL_MSGMAX}, 4400#endif 4401#ifdef _SC_NL_NMAX 4402 {"SC_NL_NMAX", _SC_NL_NMAX}, 4403#endif 4404#ifdef _SC_NL_SETMAX 4405 {"SC_NL_SETMAX", _SC_NL_SETMAX}, 4406#endif 4407#ifdef _SC_NL_TEXTMAX 4408 {"SC_NL_TEXTMAX", _SC_NL_TEXTMAX}, 4409#endif 4410#ifdef _SC_NPROCESSORS_CONF 4411 {"SC_NPROCESSORS_CONF", _SC_NPROCESSORS_CONF}, 4412#endif 4413#ifdef _SC_NPROCESSORS_ONLN 4414 {"SC_NPROCESSORS_ONLN", _SC_NPROCESSORS_ONLN}, 4415#endif 4416#ifdef _SC_NPROC_CONF 4417 {"SC_NPROC_CONF", _SC_NPROC_CONF}, 4418#endif 4419#ifdef _SC_NPROC_ONLN 4420 {"SC_NPROC_ONLN", _SC_NPROC_ONLN}, 4421#endif 4422#ifdef _SC_NZERO 4423 {"SC_NZERO", _SC_NZERO}, 4424#endif 4425#ifdef _SC_OPEN_MAX 4426 {"SC_OPEN_MAX", _SC_OPEN_MAX}, 4427#endif 4428#ifdef _SC_PAGESIZE 4429 {"SC_PAGESIZE", _SC_PAGESIZE}, 4430#endif 4431#ifdef _SC_PAGE_SIZE 4432 {"SC_PAGE_SIZE", _SC_PAGE_SIZE}, 4433#endif 4434#ifdef _SC_PASS_MAX 4435 {"SC_PASS_MAX", _SC_PASS_MAX}, 4436#endif 4437#ifdef _SC_PHYS_PAGES 4438 {"SC_PHYS_PAGES", _SC_PHYS_PAGES}, 4439#endif 4440#ifdef _SC_PII 4441 {"SC_PII", _SC_PII}, 4442#endif 4443#ifdef _SC_PII_INTERNET 4444 {"SC_PII_INTERNET", _SC_PII_INTERNET}, 4445#endif 4446#ifdef _SC_PII_INTERNET_DGRAM 4447 {"SC_PII_INTERNET_DGRAM", _SC_PII_INTERNET_DGRAM}, 4448#endif 4449#ifdef _SC_PII_INTERNET_STREAM 4450 {"SC_PII_INTERNET_STREAM", _SC_PII_INTERNET_STREAM}, 4451#endif 4452#ifdef _SC_PII_OSI 4453 {"SC_PII_OSI", _SC_PII_OSI}, 4454#endif 4455#ifdef _SC_PII_OSI_CLTS 4456 {"SC_PII_OSI_CLTS", _SC_PII_OSI_CLTS}, 4457#endif 4458#ifdef _SC_PII_OSI_COTS 4459 {"SC_PII_OSI_COTS", _SC_PII_OSI_COTS}, 4460#endif 4461#ifdef _SC_PII_OSI_M 4462 {"SC_PII_OSI_M", _SC_PII_OSI_M}, 4463#endif 4464#ifdef _SC_PII_SOCKET 4465 {"SC_PII_SOCKET", _SC_PII_SOCKET}, 4466#endif 4467#ifdef _SC_PII_XTI 4468 {"SC_PII_XTI", _SC_PII_XTI}, 4469#endif 4470#ifdef _SC_POLL 4471 {"SC_POLL", _SC_POLL}, 4472#endif 4473#ifdef _SC_PRIORITIZED_IO 4474 {"SC_PRIORITIZED_IO", _SC_PRIORITIZED_IO}, 4475#endif 4476#ifdef _SC_PRIORITY_SCHEDULING 4477 {"SC_PRIORITY_SCHEDULING", _SC_PRIORITY_SCHEDULING}, 4478#endif 4479#ifdef _SC_REALTIME_SIGNALS 4480 {"SC_REALTIME_SIGNALS", _SC_REALTIME_SIGNALS}, 4481#endif 4482#ifdef _SC_RE_DUP_MAX 4483 {"SC_RE_DUP_MAX", _SC_RE_DUP_MAX}, 4484#endif 4485#ifdef _SC_RTSIG_MAX 4486 {"SC_RTSIG_MAX", _SC_RTSIG_MAX}, 4487#endif 4488#ifdef _SC_SAVED_IDS 4489 {"SC_SAVED_IDS", _SC_SAVED_IDS}, 4490#endif 4491#ifdef _SC_SCHAR_MAX 4492 {"SC_SCHAR_MAX", _SC_SCHAR_MAX}, 4493#endif 4494#ifdef _SC_SCHAR_MIN 4495 {"SC_SCHAR_MIN", _SC_SCHAR_MIN}, 4496#endif 4497#ifdef _SC_SELECT 4498 {"SC_SELECT", _SC_SELECT}, 4499#endif 4500#ifdef _SC_SEMAPHORES 4501 {"SC_SEMAPHORES", _SC_SEMAPHORES}, 4502#endif 4503#ifdef _SC_SEM_NSEMS_MAX 4504 {"SC_SEM_NSEMS_MAX", _SC_SEM_NSEMS_MAX}, 4505#endif 4506#ifdef _SC_SEM_VALUE_MAX 4507 {"SC_SEM_VALUE_MAX", _SC_SEM_VALUE_MAX}, 4508#endif 4509#ifdef _SC_SHARED_MEMORY_OBJECTS 4510 {"SC_SHARED_MEMORY_OBJECTS", _SC_SHARED_MEMORY_OBJECTS}, 4511#endif 4512#ifdef _SC_SHRT_MAX 4513 {"SC_SHRT_MAX", _SC_SHRT_MAX}, 4514#endif 4515#ifdef _SC_SHRT_MIN 4516 {"SC_SHRT_MIN", _SC_SHRT_MIN}, 4517#endif 4518#ifdef _SC_SIGQUEUE_MAX 4519 {"SC_SIGQUEUE_MAX", _SC_SIGQUEUE_MAX}, 4520#endif 4521#ifdef _SC_SIGRT_MAX 4522 {"SC_SIGRT_MAX", _SC_SIGRT_MAX}, 4523#endif 4524#ifdef _SC_SIGRT_MIN 4525 {"SC_SIGRT_MIN", _SC_SIGRT_MIN}, 4526#endif 4527#ifdef _SC_SOFTPOWER 4528 {"SC_SOFTPOWER", _SC_SOFTPOWER}, 4529#endif 4530#ifdef _SC_SPLIT_CACHE 4531 {"SC_SPLIT_CACHE", _SC_SPLIT_CACHE}, 4532#endif 4533#ifdef _SC_SSIZE_MAX 4534 {"SC_SSIZE_MAX", _SC_SSIZE_MAX}, 4535#endif 4536#ifdef _SC_STACK_PROT 4537 {"SC_STACK_PROT", _SC_STACK_PROT}, 4538#endif 4539#ifdef _SC_STREAM_MAX 4540 {"SC_STREAM_MAX", _SC_STREAM_MAX}, 4541#endif 4542#ifdef _SC_SYNCHRONIZED_IO 4543 {"SC_SYNCHRONIZED_IO", _SC_SYNCHRONIZED_IO}, 4544#endif 4545#ifdef _SC_THREADS 4546 {"SC_THREADS", _SC_THREADS}, 4547#endif 4548#ifdef _SC_THREAD_ATTR_STACKADDR 4549 {"SC_THREAD_ATTR_STACKADDR", _SC_THREAD_ATTR_STACKADDR}, 4550#endif 4551#ifdef _SC_THREAD_ATTR_STACKSIZE 4552 {"SC_THREAD_ATTR_STACKSIZE", _SC_THREAD_ATTR_STACKSIZE}, 4553#endif 4554#ifdef _SC_THREAD_DESTRUCTOR_ITERATIONS 4555 {"SC_THREAD_DESTRUCTOR_ITERATIONS", _SC_THREAD_DESTRUCTOR_ITERATIONS}, 4556#endif 4557#ifdef _SC_THREAD_KEYS_MAX 4558 {"SC_THREAD_KEYS_MAX", _SC_THREAD_KEYS_MAX}, 4559#endif 4560#ifdef _SC_THREAD_PRIORITY_SCHEDULING 4561 {"SC_THREAD_PRIORITY_SCHEDULING", _SC_THREAD_PRIORITY_SCHEDULING}, 4562#endif 4563#ifdef _SC_THREAD_PRIO_INHERIT 4564 {"SC_THREAD_PRIO_INHERIT", _SC_THREAD_PRIO_INHERIT}, 4565#endif 4566#ifdef _SC_THREAD_PRIO_PROTECT 4567 {"SC_THREAD_PRIO_PROTECT", _SC_THREAD_PRIO_PROTECT}, 4568#endif 4569#ifdef _SC_THREAD_PROCESS_SHARED 4570 {"SC_THREAD_PROCESS_SHARED", _SC_THREAD_PROCESS_SHARED}, 4571#endif 4572#ifdef _SC_THREAD_SAFE_FUNCTIONS 4573 {"SC_THREAD_SAFE_FUNCTIONS", _SC_THREAD_SAFE_FUNCTIONS}, 4574#endif 4575#ifdef _SC_THREAD_STACK_MIN 4576 {"SC_THREAD_STACK_MIN", _SC_THREAD_STACK_MIN}, 4577#endif 4578#ifdef _SC_THREAD_THREADS_MAX 4579 {"SC_THREAD_THREADS_MAX", _SC_THREAD_THREADS_MAX}, 4580#endif 4581#ifdef _SC_TIMERS 4582 {"SC_TIMERS", _SC_TIMERS}, 4583#endif 4584#ifdef _SC_TIMER_MAX 4585 {"SC_TIMER_MAX", _SC_TIMER_MAX}, 4586#endif 4587#ifdef _SC_TTY_NAME_MAX 4588 {"SC_TTY_NAME_MAX", _SC_TTY_NAME_MAX}, 4589#endif 4590#ifdef _SC_TZNAME_MAX 4591 {"SC_TZNAME_MAX", _SC_TZNAME_MAX}, 4592#endif 4593#ifdef _SC_T_IOV_MAX 4594 {"SC_T_IOV_MAX", _SC_T_IOV_MAX}, 4595#endif 4596#ifdef _SC_UCHAR_MAX 4597 {"SC_UCHAR_MAX", _SC_UCHAR_MAX}, 4598#endif 4599#ifdef _SC_UINT_MAX 4600 {"SC_UINT_MAX", _SC_UINT_MAX}, 4601#endif 4602#ifdef _SC_UIO_MAXIOV 4603 {"SC_UIO_MAXIOV", _SC_UIO_MAXIOV}, 4604#endif 4605#ifdef _SC_ULONG_MAX 4606 {"SC_ULONG_MAX", _SC_ULONG_MAX}, 4607#endif 4608#ifdef _SC_USHRT_MAX 4609 {"SC_USHRT_MAX", _SC_USHRT_MAX}, 4610#endif 4611#ifdef _SC_VERSION 4612 {"SC_VERSION", _SC_VERSION}, 4613#endif 4614#ifdef _SC_WORD_BIT 4615 {"SC_WORD_BIT", _SC_WORD_BIT}, 4616#endif 4617#ifdef _SC_XBS5_ILP32_OFF32 4618 {"SC_XBS5_ILP32_OFF32", _SC_XBS5_ILP32_OFF32}, 4619#endif 4620#ifdef _SC_XBS5_ILP32_OFFBIG 4621 {"SC_XBS5_ILP32_OFFBIG", _SC_XBS5_ILP32_OFFBIG}, 4622#endif 4623#ifdef _SC_XBS5_LP64_OFF64 4624 {"SC_XBS5_LP64_OFF64", _SC_XBS5_LP64_OFF64}, 4625#endif 4626#ifdef _SC_XBS5_LPBIG_OFFBIG 4627 {"SC_XBS5_LPBIG_OFFBIG", _SC_XBS5_LPBIG_OFFBIG}, 4628#endif 4629#ifdef _SC_XOPEN_CRYPT 4630 {"SC_XOPEN_CRYPT", _SC_XOPEN_CRYPT}, 4631#endif 4632#ifdef _SC_XOPEN_ENH_I18N 4633 {"SC_XOPEN_ENH_I18N", _SC_XOPEN_ENH_I18N}, 4634#endif 4635#ifdef _SC_XOPEN_LEGACY 4636 {"SC_XOPEN_LEGACY", _SC_XOPEN_LEGACY}, 4637#endif 4638#ifdef _SC_XOPEN_REALTIME 4639 {"SC_XOPEN_REALTIME", _SC_XOPEN_REALTIME}, 4640#endif 4641#ifdef _SC_XOPEN_REALTIME_THREADS 4642 {"SC_XOPEN_REALTIME_THREADS", _SC_XOPEN_REALTIME_THREADS}, 4643#endif 4644#ifdef _SC_XOPEN_SHM 4645 {"SC_XOPEN_SHM", _SC_XOPEN_SHM}, 4646#endif 4647#ifdef _SC_XOPEN_UNIX 4648 {"SC_XOPEN_UNIX", _SC_XOPEN_UNIX}, 4649#endif 4650#ifdef _SC_XOPEN_VERSION 4651 {"SC_XOPEN_VERSION", _SC_XOPEN_VERSION}, 4652#endif 4653#ifdef _SC_XOPEN_XCU_VERSION 4654 {"SC_XOPEN_XCU_VERSION", _SC_XOPEN_XCU_VERSION}, 4655#endif 4656#ifdef _SC_XOPEN_XPG2 4657 {"SC_XOPEN_XPG2", _SC_XOPEN_XPG2}, 4658#endif 4659#ifdef _SC_XOPEN_XPG3 4660 {"SC_XOPEN_XPG3", _SC_XOPEN_XPG3}, 4661#endif 4662#ifdef _SC_XOPEN_XPG4 4663 {"SC_XOPEN_XPG4", _SC_XOPEN_XPG4}, 4664#endif 4665}; 4666 4667static int 4668conv_sysconf_confname(PyObject *arg, int *valuep) 4669{ 4670 return conv_confname(arg, valuep, posix_constants_sysconf, 4671 sizeof(posix_constants_sysconf) 4672 / sizeof(struct constdef)); 4673} 4674 4675static char posix_sysconf__doc__[] = "\ 4676sysconf(name) -> integer\n\ 4677Return an integer-valued system configuration variable."; 4678 4679static PyObject * 4680posix_sysconf(PyObject *self, PyObject *args) 4681{ 4682 PyObject *result = NULL; 4683 int name; 4684 4685 if (PyArg_ParseTuple(args, "O&:sysconf", conv_sysconf_confname, &name)) { 4686 int value; 4687 4688 errno = 0; 4689 value = sysconf(name); 4690 if (value == -1 && errno != 0) 4691 posix_error(); 4692 else 4693 result = PyInt_FromLong(value); 4694 } 4695 return result; 4696} 4697#endif 4698 4699 4700/* This code is used to ensure that the tables of configuration value names 4701 * are in sorted order as required by conv_confname(), and also to build the 4702 * the exported dictionaries that are used to publish information about the 4703 * names available on the host platform. 4704 * 4705 * Sorting the table at runtime ensures that the table is properly ordered 4706 * when used, even for platforms we're not able to test on. It also makes 4707 * it easier to add additional entries to the tables. 4708 */ 4709 4710static int 4711cmp_constdefs(const void *v1, const void *v2) 4712{ 4713 const struct constdef *c1 = 4714 (const struct constdef *) v1; 4715 const struct constdef *c2 = 4716 (const struct constdef *) v2; 4717 4718 return strcmp(c1->name, c2->name); 4719} 4720 4721static int 4722setup_confname_table(struct constdef *table, size_t tablesize, 4723 char *tablename, PyObject *moddict) 4724{ 4725 PyObject *d = NULL; 4726 size_t i; 4727 int status; 4728 4729 qsort(table, tablesize, sizeof(struct constdef), cmp_constdefs); 4730 d = PyDict_New(); 4731 if (d == NULL) 4732 return -1; 4733 4734 for (i=0; i < tablesize; ++i) { 4735 PyObject *o = PyInt_FromLong(table[i].value); 4736 if (o == NULL || PyDict_SetItemString(d, table[i].name, o) == -1) { 4737 Py_XDECREF(o); 4738 Py_DECREF(d); 4739 return -1; 4740 } 4741 Py_DECREF(o); 4742 } 4743 status = PyDict_SetItemString(moddict, tablename, d); 4744 Py_DECREF(d); 4745 return status; 4746} 4747 4748/* Return -1 on failure, 0 on success. */ 4749static int 4750setup_confname_tables(PyObject *moddict) 4751{ 4752#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF) 4753 if (setup_confname_table(posix_constants_pathconf, 4754 sizeof(posix_constants_pathconf) 4755 / sizeof(struct constdef), 4756 "pathconf_names", moddict)) 4757 return -1; 4758#endif 4759#ifdef HAVE_CONFSTR 4760 if (setup_confname_table(posix_constants_confstr, 4761 sizeof(posix_constants_confstr) 4762 / sizeof(struct constdef), 4763 "confstr_names", moddict)) 4764 return -1; 4765#endif 4766#ifdef HAVE_SYSCONF 4767 if (setup_confname_table(posix_constants_sysconf, 4768 sizeof(posix_constants_sysconf) 4769 / sizeof(struct constdef), 4770 "sysconf_names", moddict)) 4771 return -1; 4772#endif 4773 return 0; 4774} 4775 4776 4777static char posix_abort__doc__[] = "\ 4778abort() -> does not return!\n\ 4779Abort the interpreter immediately. This 'dumps core' or otherwise fails\n\ 4780in the hardest way possible on the hosting operating system."; 4781 4782static PyObject * 4783posix_abort(PyObject *self, PyObject *args) 4784{ 4785 if (!PyArg_ParseTuple(args, ":abort")) 4786 return NULL; 4787 abort(); 4788 /*NOTREACHED*/ 4789 Py_FatalError("abort() called from Python code didn't abort!"); 4790 return NULL; 4791} 4792 4793 4794static PyMethodDef posix_methods[] = { 4795 {"access", posix_access, METH_VARARGS, posix_access__doc__}, 4796#ifdef HAVE_TTYNAME 4797 {"ttyname", posix_ttyname, METH_VARARGS, posix_ttyname__doc__}, 4798#endif 4799 {"chdir", posix_chdir, METH_VARARGS, posix_chdir__doc__}, 4800 {"chmod", posix_chmod, METH_VARARGS, posix_chmod__doc__}, 4801#ifdef HAVE_CHOWN 4802 {"chown", posix_chown, METH_VARARGS, posix_chown__doc__}, 4803#endif /* HAVE_CHOWN */ 4804#ifdef HAVE_CTERMID 4805 {"ctermid", posix_ctermid, METH_VARARGS, posix_ctermid__doc__}, 4806#endif 4807#ifdef HAVE_GETCWD 4808 {"getcwd", posix_getcwd, METH_VARARGS, posix_getcwd__doc__}, 4809#endif 4810#ifdef HAVE_LINK 4811 {"link", posix_link, METH_VARARGS, posix_link__doc__}, 4812#endif /* HAVE_LINK */ 4813 {"listdir", posix_listdir, METH_VARARGS, posix_listdir__doc__}, 4814 {"lstat", posix_lstat, METH_VARARGS, posix_lstat__doc__}, 4815 {"mkdir", posix_mkdir, METH_VARARGS, posix_mkdir__doc__}, 4816#ifdef HAVE_NICE 4817 {"nice", posix_nice, METH_VARARGS, posix_nice__doc__}, 4818#endif /* HAVE_NICE */ 4819#ifdef HAVE_READLINK 4820 {"readlink", posix_readlink, METH_VARARGS, posix_readlink__doc__}, 4821#endif /* HAVE_READLINK */ 4822 {"rename", posix_rename, METH_VARARGS, posix_rename__doc__}, 4823 {"rmdir", posix_rmdir, METH_VARARGS, posix_rmdir__doc__}, 4824 {"stat", posix_stat, METH_VARARGS, posix_stat__doc__}, 4825#ifdef HAVE_SYMLINK 4826 {"symlink", posix_symlink, METH_VARARGS, posix_symlink__doc__}, 4827#endif /* HAVE_SYMLINK */ 4828#ifdef HAVE_SYSTEM 4829 {"system", posix_system, METH_VARARGS, posix_system__doc__}, 4830#endif 4831 {"umask", posix_umask, METH_VARARGS, posix_umask__doc__}, 4832#ifdef HAVE_UNAME 4833 {"uname", posix_uname, METH_VARARGS, posix_uname__doc__}, 4834#endif /* HAVE_UNAME */ 4835 {"unlink", posix_unlink, METH_VARARGS, posix_unlink__doc__}, 4836 {"remove", posix_unlink, METH_VARARGS, posix_remove__doc__}, 4837 {"utime", posix_utime, METH_VARARGS, posix_utime__doc__}, 4838#ifdef HAVE_TIMES 4839 {"times", posix_times, METH_VARARGS, posix_times__doc__}, 4840#endif /* HAVE_TIMES */ 4841 {"_exit", posix__exit, METH_VARARGS, posix__exit__doc__}, 4842#ifdef HAVE_EXECV 4843 {"execv", posix_execv, METH_VARARGS, posix_execv__doc__}, 4844 {"execve", posix_execve, METH_VARARGS, posix_execve__doc__}, 4845#endif /* HAVE_EXECV */ 4846#ifdef HAVE_SPAWNV 4847 {"spawnv", posix_spawnv, METH_VARARGS, posix_spawnv__doc__}, 4848 {"spawnve", posix_spawnve, METH_VARARGS, posix_spawnve__doc__}, 4849#endif /* HAVE_SPAWNV */ 4850#ifdef HAVE_FORK 4851 {"fork", posix_fork, METH_VARARGS, posix_fork__doc__}, 4852#endif /* HAVE_FORK */ 4853#ifdef HAVE_OPENPTY 4854 {"openpty", posix_openpty, METH_VARARGS, posix_openpty__doc__}, 4855#endif /* HAVE_OPENPTY */ 4856#ifdef HAVE_FORKPTY 4857 {"forkpty", posix_forkpty, METH_VARARGS, posix_forkpty__doc__}, 4858#endif /* HAVE_FORKPTY */ 4859#ifdef HAVE_GETEGID 4860 {"getegid", posix_getegid, METH_VARARGS, posix_getegid__doc__}, 4861#endif /* HAVE_GETEGID */ 4862#ifdef HAVE_GETEUID 4863 {"geteuid", posix_geteuid, METH_VARARGS, posix_geteuid__doc__}, 4864#endif /* HAVE_GETEUID */ 4865#ifdef HAVE_GETGID 4866 {"getgid", posix_getgid, METH_VARARGS, posix_getgid__doc__}, 4867#endif /* HAVE_GETGID */ 4868#ifdef HAVE_GETGROUPS 4869 {"getgroups", posix_getgroups, METH_VARARGS, posix_getgroups__doc__}, 4870#endif 4871 {"getpid", posix_getpid, METH_VARARGS, posix_getpid__doc__}, 4872#ifdef HAVE_GETPGRP 4873 {"getpgrp", posix_getpgrp, METH_VARARGS, posix_getpgrp__doc__}, 4874#endif /* HAVE_GETPGRP */ 4875#ifdef HAVE_GETPPID 4876 {"getppid", posix_getppid, METH_VARARGS, posix_getppid__doc__}, 4877#endif /* HAVE_GETPPID */ 4878#ifdef HAVE_GETUID 4879 {"getuid", posix_getuid, METH_VARARGS, posix_getuid__doc__}, 4880#endif /* HAVE_GETUID */ 4881#ifdef HAVE_GETLOGIN 4882 {"getlogin", posix_getlogin, METH_VARARGS, posix_getlogin__doc__}, 4883#endif 4884#ifdef HAVE_KILL 4885 {"kill", posix_kill, METH_VARARGS, posix_kill__doc__}, 4886#endif /* HAVE_KILL */ 4887#ifdef HAVE_PLOCK 4888 {"plock", posix_plock, METH_VARARGS, posix_plock__doc__}, 4889#endif /* HAVE_PLOCK */ 4890#ifdef HAVE_POPEN 4891 {"popen", posix_popen, METH_VARARGS, posix_popen__doc__}, 4892#ifdef MS_WIN32 4893 {"popen2", win32_popen2, METH_VARARGS}, 4894 {"popen3", win32_popen3, METH_VARARGS}, 4895 {"popen4", win32_popen4, METH_VARARGS}, 4896#endif 4897#endif /* HAVE_POPEN */ 4898#ifdef HAVE_SETUID 4899 {"setuid", posix_setuid, METH_VARARGS, posix_setuid__doc__}, 4900#endif /* HAVE_SETUID */ 4901#ifdef HAVE_SETGID 4902 {"setgid", posix_setgid, METH_VARARGS, posix_setgid__doc__}, 4903#endif /* HAVE_SETGID */ 4904#ifdef HAVE_SETPGRP 4905 {"setpgrp", posix_setpgrp, METH_VARARGS, posix_setpgrp__doc__}, 4906#endif /* HAVE_SETPGRP */ 4907#ifdef HAVE_WAIT 4908 {"wait", posix_wait, METH_VARARGS, posix_wait__doc__}, 4909#endif /* HAVE_WAIT */ 4910#ifdef HAVE_WAITPID 4911 {"waitpid", posix_waitpid, METH_VARARGS, posix_waitpid__doc__}, 4912#endif /* HAVE_WAITPID */ 4913#ifdef HAVE_SETSID 4914 {"setsid", posix_setsid, METH_VARARGS, posix_setsid__doc__}, 4915#endif /* HAVE_SETSID */ 4916#ifdef HAVE_SETPGID 4917 {"setpgid", posix_setpgid, METH_VARARGS, posix_setpgid__doc__}, 4918#endif /* HAVE_SETPGID */ 4919#ifdef HAVE_TCGETPGRP 4920 {"tcgetpgrp", posix_tcgetpgrp, METH_VARARGS, posix_tcgetpgrp__doc__}, 4921#endif /* HAVE_TCGETPGRP */ 4922#ifdef HAVE_TCSETPGRP 4923 {"tcsetpgrp", posix_tcsetpgrp, METH_VARARGS, posix_tcsetpgrp__doc__}, 4924#endif /* HAVE_TCSETPGRP */ 4925 {"open", posix_open, METH_VARARGS, posix_open__doc__}, 4926 {"close", posix_close, METH_VARARGS, posix_close__doc__}, 4927 {"dup", posix_dup, METH_VARARGS, posix_dup__doc__}, 4928 {"dup2", posix_dup2, METH_VARARGS, posix_dup2__doc__}, 4929 {"lseek", posix_lseek, METH_VARARGS, posix_lseek__doc__}, 4930 {"read", posix_read, METH_VARARGS, posix_read__doc__}, 4931 {"write", posix_write, METH_VARARGS, posix_write__doc__}, 4932 {"fstat", posix_fstat, METH_VARARGS, posix_fstat__doc__}, 4933 {"fdopen", posix_fdopen, METH_VARARGS, posix_fdopen__doc__}, 4934#ifdef HAVE_PIPE 4935 {"pipe", posix_pipe, METH_VARARGS, posix_pipe__doc__}, 4936#endif 4937#ifdef HAVE_MKFIFO 4938 {"mkfifo", posix_mkfifo, METH_VARARGS, posix_mkfifo__doc__}, 4939#endif 4940#ifdef HAVE_FTRUNCATE 4941 {"ftruncate", posix_ftruncate, METH_VARARGS, posix_ftruncate__doc__}, 4942#endif 4943#ifdef HAVE_PUTENV 4944 {"putenv", posix_putenv, METH_VARARGS, posix_putenv__doc__}, 4945#endif 4946#ifdef HAVE_STRERROR 4947 {"strerror", posix_strerror, METH_VARARGS, posix_strerror__doc__}, 4948#endif 4949#ifdef HAVE_FSYNC 4950 {"fsync", posix_fsync, METH_VARARGS, posix_fsync__doc__}, 4951#endif 4952#ifdef HAVE_FDATASYNC 4953 {"fdatasync", posix_fdatasync, METH_VARARGS, posix_fdatasync__doc__}, 4954#endif 4955#ifdef HAVE_SYS_WAIT_H 4956#ifdef WIFSTOPPED 4957 {"WIFSTOPPED", posix_WIFSTOPPED, METH_VARARGS, posix_WIFSTOPPED__doc__}, 4958#endif /* WIFSTOPPED */ 4959#ifdef WIFSIGNALED 4960 {"WIFSIGNALED", posix_WIFSIGNALED, METH_VARARGS, posix_WIFSIGNALED__doc__}, 4961#endif /* WIFSIGNALED */ 4962#ifdef WIFEXITED 4963 {"WIFEXITED", posix_WIFEXITED, METH_VARARGS, posix_WIFEXITED__doc__}, 4964#endif /* WIFEXITED */ 4965#ifdef WEXITSTATUS 4966 {"WEXITSTATUS", posix_WEXITSTATUS, METH_VARARGS, posix_WEXITSTATUS__doc__}, 4967#endif /* WEXITSTATUS */ 4968#ifdef WTERMSIG 4969 {"WTERMSIG", posix_WTERMSIG, METH_VARARGS, posix_WTERMSIG__doc__}, 4970#endif /* WTERMSIG */ 4971#ifdef WSTOPSIG 4972 {"WSTOPSIG", posix_WSTOPSIG, METH_VARARGS, posix_WSTOPSIG__doc__}, 4973#endif /* WSTOPSIG */ 4974#endif /* HAVE_SYS_WAIT_H */ 4975#ifdef HAVE_FSTATVFS 4976 {"fstatvfs", posix_fstatvfs, METH_VARARGS, posix_fstatvfs__doc__}, 4977#endif 4978#ifdef HAVE_STATVFS 4979 {"statvfs", posix_statvfs, METH_VARARGS, posix_statvfs__doc__}, 4980#endif 4981#ifdef HAVE_TMPNAM 4982 {"tmpfile", posix_tmpfile, METH_VARARGS, posix_tmpfile__doc__}, 4983#endif 4984#ifdef HAVE_TEMPNAM 4985 {"tempnam", posix_tempnam, METH_VARARGS, posix_tempnam__doc__}, 4986#endif 4987#ifdef HAVE_TMPNAM 4988 {"tmpnam", posix_tmpnam, METH_VARARGS, posix_tmpnam__doc__}, 4989#endif 4990#ifdef HAVE_CONFSTR 4991 {"confstr", posix_confstr, METH_VARARGS, posix_confstr__doc__}, 4992#endif 4993#ifdef HAVE_SYSCONF 4994 {"sysconf", posix_sysconf, METH_VARARGS, posix_sysconf__doc__}, 4995#endif 4996#ifdef HAVE_FPATHCONF 4997 {"fpathconf", posix_fpathconf, METH_VARARGS, posix_fpathconf__doc__}, 4998#endif 4999#ifdef HAVE_PATHCONF 5000 {"pathconf", posix_pathconf, METH_VARARGS, posix_pathconf__doc__}, 5001#endif 5002 {"abort", posix_abort, METH_VARARGS, posix_abort__doc__}, 5003 {NULL, NULL} /* Sentinel */ 5004}; 5005 5006 5007static int 5008ins(PyObject *d, char *symbol, long value) 5009{ 5010 PyObject* v = PyInt_FromLong(value); 5011 if (!v || PyDict_SetItemString(d, symbol, v) < 0) 5012 return -1; /* triggers fatal error */ 5013 5014 Py_DECREF(v); 5015 return 0; 5016} 5017 5018#if defined(PYOS_OS2) 5019/* Insert Platform-Specific Constant Values (Strings & Numbers) of Common Use */ 5020static int insertvalues(PyObject *d) 5021{ 5022 APIRET rc; 5023 ULONG values[QSV_MAX+1]; 5024 PyObject *v; 5025 char *ver, tmp[10]; 5026 5027 Py_BEGIN_ALLOW_THREADS 5028 rc = DosQuerySysInfo(1, QSV_MAX, &values[1], sizeof(values)); 5029 Py_END_ALLOW_THREADS 5030 5031 if (rc != NO_ERROR) { 5032 os2_error(rc); 5033 return -1; 5034 } 5035 5036 if (ins(d, "meminstalled", values[QSV_TOTPHYSMEM])) return -1; 5037 if (ins(d, "memkernel", values[QSV_TOTRESMEM])) return -1; 5038 if (ins(d, "memvirtual", values[QSV_TOTAVAILMEM])) return -1; 5039 if (ins(d, "maxpathlen", values[QSV_MAX_PATH_LENGTH])) return -1; 5040 if (ins(d, "maxnamelen", values[QSV_MAX_COMP_LENGTH])) return -1; 5041 if (ins(d, "revision", values[QSV_VERSION_REVISION])) return -1; 5042 if (ins(d, "timeslice", values[QSV_MIN_SLICE])) return -1; 5043 5044 switch (values[QSV_VERSION_MINOR]) { 5045 case 0: ver = "2.00"; break; 5046 case 10: ver = "2.10"; break; 5047 case 11: ver = "2.11"; break; 5048 case 30: ver = "3.00"; break; 5049 case 40: ver = "4.00"; break; 5050 case 50: ver = "5.00"; break; 5051 default: 5052 sprintf(tmp, "%d-%d", values[QSV_VERSION_MAJOR], 5053 values[QSV_VERSION_MINOR]); 5054 ver = &tmp[0]; 5055 } 5056 5057 /* Add Indicator of the Version of the Operating System */ 5058 v = PyString_FromString(ver); 5059 if (!v || PyDict_SetItemString(d, "version", v) < 0) 5060 return -1; 5061 Py_DECREF(v); 5062 5063 /* Add Indicator of Which Drive was Used to Boot the System */ 5064 tmp[0] = 'A' + values[QSV_BOOT_DRIVE] - 1; 5065 tmp[1] = ':'; 5066 tmp[2] = '\0'; 5067 5068 v = PyString_FromString(tmp); 5069 if (!v || PyDict_SetItemString(d, "bootdrive", v) < 0) 5070 return -1; 5071 Py_DECREF(v); 5072 5073 return 0; 5074} 5075#endif 5076 5077static int 5078all_ins(d) 5079 PyObject* d; 5080{ 5081#ifdef F_OK 5082 if (ins(d, "F_OK", (long)F_OK)) return -1; 5083#endif 5084#ifdef R_OK 5085 if (ins(d, "R_OK", (long)R_OK)) return -1; 5086#endif 5087#ifdef W_OK 5088 if (ins(d, "W_OK", (long)W_OK)) return -1; 5089#endif 5090#ifdef X_OK 5091 if (ins(d, "X_OK", (long)X_OK)) return -1; 5092#endif 5093#ifdef NGROUPS_MAX 5094 if (ins(d, "NGROUPS_MAX", (long)NGROUPS_MAX)) return -1; 5095#endif 5096#ifdef TMP_MAX 5097 if (ins(d, "TMP_MAX", (long)TMP_MAX)) return -1; 5098#endif 5099#ifdef WNOHANG 5100 if (ins(d, "WNOHANG", (long)WNOHANG)) return -1; 5101#endif 5102#ifdef O_RDONLY 5103 if (ins(d, "O_RDONLY", (long)O_RDONLY)) return -1; 5104#endif 5105#ifdef O_WRONLY 5106 if (ins(d, "O_WRONLY", (long)O_WRONLY)) return -1; 5107#endif 5108#ifdef O_RDWR 5109 if (ins(d, "O_RDWR", (long)O_RDWR)) return -1; 5110#endif 5111#ifdef O_NDELAY 5112 if (ins(d, "O_NDELAY", (long)O_NDELAY)) return -1; 5113#endif 5114#ifdef O_NONBLOCK 5115 if (ins(d, "O_NONBLOCK", (long)O_NONBLOCK)) return -1; 5116#endif 5117#ifdef O_APPEND 5118 if (ins(d, "O_APPEND", (long)O_APPEND)) return -1; 5119#endif 5120#ifdef O_DSYNC 5121 if (ins(d, "O_DSYNC", (long)O_DSYNC)) return -1; 5122#endif 5123#ifdef O_RSYNC 5124 if (ins(d, "O_RSYNC", (long)O_RSYNC)) return -1; 5125#endif 5126#ifdef O_SYNC 5127 if (ins(d, "O_SYNC", (long)O_SYNC)) return -1; 5128#endif 5129#ifdef O_NOCTTY 5130 if (ins(d, "O_NOCTTY", (long)O_NOCTTY)) return -1; 5131#endif 5132#ifdef O_CREAT 5133 if (ins(d, "O_CREAT", (long)O_CREAT)) return -1; 5134#endif 5135#ifdef O_EXCL 5136 if (ins(d, "O_EXCL", (long)O_EXCL)) return -1; 5137#endif 5138#ifdef O_TRUNC 5139 if (ins(d, "O_TRUNC", (long)O_TRUNC)) return -1; 5140#endif 5141#ifdef O_BINARY 5142 if (ins(d, "O_BINARY", (long)O_BINARY)) return -1; 5143#endif 5144#ifdef O_TEXT 5145 if (ins(d, "O_TEXT", (long)O_TEXT)) return -1; 5146#endif 5147 5148#ifdef HAVE_SPAWNV 5149 if (ins(d, "P_WAIT", (long)_P_WAIT)) return -1; 5150 if (ins(d, "P_NOWAIT", (long)_P_NOWAIT)) return -1; 5151 if (ins(d, "P_OVERLAY", (long)_OLD_P_OVERLAY)) return -1; 5152 if (ins(d, "P_NOWAITO", (long)_P_NOWAITO)) return -1; 5153 if (ins(d, "P_DETACH", (long)_P_DETACH)) return -1; 5154#endif 5155 5156#if defined(PYOS_OS2) 5157 if (insertvalues(d)) return -1; 5158#endif 5159 return 0; 5160} 5161 5162 5163#if ( defined(_MSC_VER) || defined(__WATCOMC__) ) && !defined(__QNX__) 5164#define INITFUNC initnt 5165#define MODNAME "nt" 5166#else 5167#if defined(PYOS_OS2) 5168#define INITFUNC initos2 5169#define MODNAME "os2" 5170#else 5171#define INITFUNC initposix 5172#define MODNAME "posix" 5173#endif 5174#endif 5175 5176DL_EXPORT(void) 5177INITFUNC() 5178{ 5179 PyObject *m, *d, *v; 5180 5181 m = Py_InitModule4(MODNAME, 5182 posix_methods, 5183 posix__doc__, 5184 (PyObject *)NULL, 5185 PYTHON_API_VERSION); 5186 d = PyModule_GetDict(m); 5187 5188 /* Initialize environ dictionary */ 5189 v = convertenviron(); 5190 if (v == NULL || PyDict_SetItemString(d, "environ", v) != 0) 5191 return; 5192 Py_DECREF(v); 5193 5194 if (all_ins(d)) 5195 return; 5196 5197 if (setup_confname_tables(d)) 5198 return; 5199 5200 PyDict_SetItemString(d, "error", PyExc_OSError); 5201 5202#ifdef HAVE_PUTENV 5203 posix_putenv_garbage = PyDict_New(); 5204#endif 5205} 5206