posixmodule.c revision 246bc17a8b680fd08af7aeb405e8d0feed3fb9f5
1/*********************************************************** 2Copyright 1991-1995 by Stichting Mathematisch Centrum, Amsterdam, 3The Netherlands. 4 5 All Rights Reserved 6 7Permission to use, copy, modify, and distribute this software and its 8documentation for any purpose and without fee is hereby granted, 9provided that the above copyright notice appear in all copies and that 10both that copyright notice and this permission notice appear in 11supporting documentation, and that the names of Stichting Mathematisch 12Centrum or CWI or Corporation for National Research Initiatives or 13CNRI not be used in advertising or publicity pertaining to 14distribution of the software without specific, written prior 15permission. 16 17While CWI is the initial source for this software, a modified version 18is made available by the Corporation for National Research Initiatives 19(CNRI) at the Internet address ftp://ftp.python.org. 20 21STICHTING MATHEMATISCH CENTRUM AND CNRI DISCLAIM ALL WARRANTIES WITH 22REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF 23MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL STICHTING MATHEMATISCH 24CENTRUM OR CNRI BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL 25DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR 26PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER 27TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 28PERFORMANCE OF THIS SOFTWARE. 29 30******************************************************************/ 31 32/* POSIX module implementation */ 33 34/* This file is also used for Windows NT and MS-Win. In that case the module 35 actually calls itself 'nt', not 'posix', and a few functions are 36 either unimplemented or implemented differently. The source 37 assumes that for Windows NT, the macro 'MS_WIN32' is defined independent 38 of the compiler used. Different compilers define their own feature 39 test macro, e.g. '__BORLANDC__' or '_MSC_VER'. */ 40 41/* See also ../Dos/dosmodule.c */ 42 43static char posix__doc__ [] = 44"This module provides access to operating system functionality that is\n\ 45standardized by the C Standard and the POSIX standard (a thinly\n\ 46disguised Unix interface). Refer to the library manual and\n\ 47corresponding Unix manual entries for more information on calls."; 48 49#include "Python.h" 50 51#if defined(PYOS_OS2) 52#define INCL_DOS 53#define INCL_DOSERRORS 54#define INCL_DOSPROCESS 55#define INCL_NOPMAPI 56#include <os2.h> 57#endif 58 59#include <sys/types.h> 60#include <sys/stat.h> 61#ifdef HAVE_SYS_WAIT_H 62#include <sys/wait.h> /* For WNOHANG */ 63#endif 64 65#ifdef HAVE_SIGNAL_H 66#include <signal.h> 67#endif 68 69#include "mytime.h" /* For clock_t on some systems */ 70 71#ifdef HAVE_FCNTL_H 72#include <fcntl.h> 73#endif /* HAVE_FCNTL_H */ 74 75/* Various compilers have only certain posix functions */ 76/* XXX Gosh I wish these were all moved into config.h */ 77#if defined(PYCC_VACPP) && defined(PYOS_OS2) 78#include <process.h> 79#else 80#if defined(__WATCOMC__) && !defined(__QNX__) /* Watcom compiler */ 81#define HAVE_GETCWD 1 82#define HAVE_OPENDIR 1 83#define HAVE_SYSTEM 1 84#if defined(__OS2__) 85#define HAVE_EXECV 1 86#define HAVE_WAIT 1 87#endif 88#include <process.h> 89#else 90#ifdef __BORLANDC__ /* Borland compiler */ 91#define HAVE_EXECV 1 92#define HAVE_GETCWD 1 93#define HAVE_GETEGID 1 94#define HAVE_GETEUID 1 95#define HAVE_GETGID 1 96#define HAVE_GETPPID 1 97#define HAVE_GETUID 1 98#define HAVE_KILL 1 99#define HAVE_OPENDIR 1 100#define HAVE_PIPE 1 101#define HAVE_POPEN 1 102#define HAVE_SYSTEM 1 103#define HAVE_WAIT 1 104#else 105#ifdef _MSC_VER /* Microsoft compiler */ 106#define HAVE_GETCWD 1 107#ifdef MS_WIN32 108#define HAVE_SPAWNV 1 109#define HAVE_EXECV 1 110#define HAVE_PIPE 1 111#define HAVE_POPEN 1 112#define HAVE_SYSTEM 1 113#else /* 16-bit Windows */ 114#endif /* !MS_WIN32 */ 115#else /* all other compilers */ 116/* Unix functions that the configure script doesn't check for */ 117#define HAVE_EXECV 1 118#define HAVE_FORK 1 119#define HAVE_GETCWD 1 120#define HAVE_GETEGID 1 121#define HAVE_GETEUID 1 122#define HAVE_GETGID 1 123#define HAVE_GETPPID 1 124#define HAVE_GETUID 1 125#define HAVE_KILL 1 126#define HAVE_OPENDIR 1 127#define HAVE_PIPE 1 128#define HAVE_POPEN 1 129#define HAVE_SYSTEM 1 130#define HAVE_WAIT 1 131#define HAVE_TTYNAME 1 132#endif /* _MSC_VER */ 133#endif /* __BORLANDC__ */ 134#endif /* ! __WATCOMC__ || __QNX__ */ 135#endif /* ! __IBMC__ */ 136 137#ifndef _MSC_VER 138 139#ifdef HAVE_UNISTD_H 140#include <unistd.h> 141#endif 142 143#ifdef NeXT 144/* NeXT's <unistd.h> and <utime.h> aren't worth much */ 145#undef HAVE_UNISTD_H 146#undef HAVE_UTIME_H 147#define HAVE_WAITPID 148/* #undef HAVE_GETCWD */ 149#define UNION_WAIT /* This should really be checked for by autoconf */ 150#endif 151 152#ifdef HAVE_UNISTD_H 153/* XXX These are for SunOS4.1.3 but shouldn't hurt elsewhere */ 154extern int rename(); 155extern int pclose(); 156extern int lstat(); 157extern int symlink(); 158#else /* !HAVE_UNISTD_H */ 159#if defined(PYCC_VACPP) 160extern int mkdir Py_PROTO((char *)); 161#else 162#if ( defined(__WATCOMC__) || defined(_MSC_VER) ) && !defined(__QNX__) 163extern int mkdir Py_PROTO((const char *)); 164#else 165extern int mkdir Py_PROTO((const char *, mode_t)); 166#endif 167#endif 168#if defined(__IBMC__) || defined(__IBMCPP__) 169extern int chdir Py_PROTO((char *)); 170extern int rmdir Py_PROTO((char *)); 171#else 172extern int chdir Py_PROTO((const char *)); 173extern int rmdir Py_PROTO((const char *)); 174#endif 175extern int chmod Py_PROTO((const char *, mode_t)); 176extern int chown Py_PROTO((const char *, uid_t, gid_t)); 177extern char *getcwd Py_PROTO((char *, int)); 178extern char *strerror Py_PROTO((int)); 179extern int link Py_PROTO((const char *, const char *)); 180extern int rename Py_PROTO((const char *, const char *)); 181extern int stat Py_PROTO((const char *, struct stat *)); 182extern int unlink Py_PROTO((const char *)); 183extern int pclose Py_PROTO((FILE *)); 184#ifdef HAVE_SYMLINK 185extern int symlink Py_PROTO((const char *, const char *)); 186#endif /* HAVE_SYMLINK */ 187#ifdef HAVE_LSTAT 188extern int lstat Py_PROTO((const char *, struct stat *)); 189#endif /* HAVE_LSTAT */ 190#endif /* !HAVE_UNISTD_H */ 191 192#endif /* !_MSC_VER */ 193 194#ifdef HAVE_UTIME_H 195#include <utime.h> 196#endif /* HAVE_UTIME_H */ 197 198#ifdef HAVE_SYS_UTIME_H 199#include <sys/utime.h> 200#define HAVE_UTIME_H /* pretend we do for the rest of this file */ 201#endif /* HAVE_SYS_UTIME_H */ 202 203#ifdef HAVE_SYS_TIMES_H 204#include <sys/times.h> 205#endif /* HAVE_SYS_TIMES_H */ 206 207#ifdef HAVE_SYS_PARAM_H 208#include <sys/param.h> 209#endif /* HAVE_SYS_PARAM_H */ 210 211#ifdef HAVE_SYS_UTSNAME_H 212#include <sys/utsname.h> 213#endif /* HAVE_SYS_UTSNAME_H */ 214 215#ifndef MAXPATHLEN 216#define MAXPATHLEN 1024 217#endif /* MAXPATHLEN */ 218 219#ifdef HAVE_DIRENT_H 220#include <dirent.h> 221#define NAMLEN(dirent) strlen((dirent)->d_name) 222#else 223#if defined(__WATCOMC__) && !defined(__QNX__) 224#include <direct.h> 225#define NAMLEN(dirent) strlen((dirent)->d_name) 226#else 227#define dirent direct 228#define NAMLEN(dirent) (dirent)->d_namlen 229#endif 230#ifdef HAVE_SYS_NDIR_H 231#include <sys/ndir.h> 232#endif 233#ifdef HAVE_SYS_DIR_H 234#include <sys/dir.h> 235#endif 236#ifdef HAVE_NDIR_H 237#include <ndir.h> 238#endif 239#endif 240 241#ifdef _MSC_VER 242#include <direct.h> 243#include <io.h> 244#include <process.h> 245#include <windows.h> 246#ifdef MS_WIN32 247#define popen _popen 248#define pclose _pclose 249#else /* 16-bit Windows */ 250#include <dos.h> 251#include <ctype.h> 252#endif /* MS_WIN32 */ 253#endif /* _MSC_VER */ 254 255#if defined(PYCC_VACPP) && defined(PYOS_OS2) 256#include <io.h> 257#endif /* OS2 */ 258 259#ifdef UNION_WAIT 260/* Emulate some macros on systems that have a union instead of macros */ 261 262#ifndef WIFEXITED 263#define WIFEXITED(u_wait) (!(u_wait).w_termsig && !(u_wait).w_coredump) 264#endif 265 266#ifndef WEXITSTATUS 267#define WEXITSTATUS(u_wait) (WIFEXITED(u_wait)?((u_wait).w_retcode):-1) 268#endif 269 270#ifndef WTERMSIG 271#define WTERMSIG(u_wait) ((u_wait).w_termsig) 272#endif 273 274#endif /* UNION_WAIT */ 275 276/* Return a dictionary corresponding to the POSIX environment table */ 277 278#if !defined(_MSC_VER) && ( !defined(__WATCOMC__) || defined(__QNX__) ) 279extern char **environ; 280#endif /* !_MSC_VER */ 281 282static PyObject * 283convertenviron() 284{ 285 PyObject *d; 286 char **e; 287 d = PyDict_New(); 288 if (d == NULL) 289 return NULL; 290 if (environ == NULL) 291 return d; 292 /* XXX This part ignores errors */ 293 for (e = environ; *e != NULL; e++) { 294 PyObject *v; 295 char *p = strchr(*e, '='); 296 if (p == NULL) 297 continue; 298 v = PyString_FromString(p+1); 299 if (v == NULL) 300 continue; 301 *p = '\0'; 302 (void) PyDict_SetItemString(d, *e, v); 303 *p = '='; 304 Py_DECREF(v); 305 } 306#if defined(PYOS_OS2) 307 { 308 APIRET rc; 309 char buffer[1024]; /* OS/2 Provides a Documented Max of 1024 Chars */ 310 311 rc = DosQueryExtLIBPATH(buffer, BEGIN_LIBPATH); 312 if (rc == NO_ERROR) { /* (not a type, envname is NOT 'BEGIN_LIBPATH') */ 313 PyObject *v = PyString_FromString(buffer); 314 PyDict_SetItemString(d, "BEGINLIBPATH", v); 315 Py_DECREF(v); 316 } 317 rc = DosQueryExtLIBPATH(buffer, END_LIBPATH); 318 if (rc == NO_ERROR) { /* (not a typo, envname is NOT 'END_LIBPATH') */ 319 PyObject *v = PyString_FromString(buffer); 320 PyDict_SetItemString(d, "ENDLIBPATH", v); 321 Py_DECREF(v); 322 } 323 } 324#endif 325 return d; 326} 327 328 329static PyObject *PosixError; /* Exception posix.error */ 330 331/* Set a POSIX-specific error from errno, and return NULL */ 332 333static PyObject * 334posix_error() 335{ 336 return PyErr_SetFromErrno(PosixError); 337} 338static PyObject * 339posix_error_with_filename(name) 340 char* name; 341{ 342 return PyErr_SetFromErrnoWithFilename(PosixError, name); 343} 344 345 346#if defined(PYOS_OS2) 347/********************************************************************** 348 * Helper Function to Trim and Format OS/2 Messages 349 **********************************************************************/ 350 static void 351os2_formatmsg(char *msgbuf, int msglen, char *reason) 352{ 353 msgbuf[msglen] = '\0'; /* OS/2 Doesn't Guarantee a Terminator */ 354 355 if (strlen(msgbuf) > 0) { /* If Non-Empty Msg, Trim CRLF */ 356 char *lastc = &msgbuf[ strlen(msgbuf)-1 ]; 357 358 while (lastc > msgbuf && isspace(*lastc)) 359 *lastc-- = '\0'; /* Trim Trailing Whitespace (CRLF) */ 360 } 361 362 /* Add Optional Reason Text */ 363 if (reason) { 364 strcat(msgbuf, " : "); 365 strcat(msgbuf, reason); 366 } 367} 368 369/********************************************************************** 370 * Decode an OS/2 Operating System Error Code 371 * 372 * A convenience function to lookup an OS/2 error code and return a 373 * text message we can use to raise a Python exception. 374 * 375 * Notes: 376 * The messages for errors returned from the OS/2 kernel reside in 377 * the file OSO001.MSG in the \OS2 directory hierarchy. 378 * 379 **********************************************************************/ 380 static char * 381os2_strerror(char *msgbuf, int msgbuflen, int errorcode, char *reason) 382{ 383 APIRET rc; 384 ULONG msglen; 385 386 /* Retrieve Kernel-Related Error Message from OSO001.MSG File */ 387 Py_BEGIN_ALLOW_THREADS 388 rc = DosGetMessage(NULL, 0, msgbuf, msgbuflen, 389 errorcode, "oso001.msg", &msglen); 390 Py_END_ALLOW_THREADS 391 392 if (rc == NO_ERROR) 393 os2_formatmsg(msgbuf, msglen, reason); 394 else 395 sprintf(msgbuf, "unknown OS error #%d", errorcode); 396 397 return msgbuf; 398} 399 400/* Set an OS/2-specific error and return NULL. OS/2 kernel 401 errors are not in a global variable e.g. 'errno' nor are 402 they congruent with posix error numbers. */ 403 404static PyObject * os2_error(int code) 405{ 406 char text[1024]; 407 PyObject *v; 408 409 os2_strerror(text, sizeof(text), code, ""); 410 411 v = Py_BuildValue("(is)", code, text); 412 if (v != NULL) { 413 PyErr_SetObject(PosixError, v); 414 Py_DECREF(v); 415 } 416 return NULL; /* Signal to Python that an Exception is Pending */ 417} 418 419#endif /* OS2 */ 420 421/* POSIX generic methods */ 422 423static PyObject * 424posix_int(args, func) 425 PyObject *args; 426 int (*func) Py_FPROTO((int)); 427{ 428 int fd; 429 int res; 430 if (!PyArg_Parse(args, "i", &fd)) 431 return NULL; 432 Py_BEGIN_ALLOW_THREADS 433 res = (*func)(fd); 434 Py_END_ALLOW_THREADS 435 if (res < 0) 436 return posix_error(); 437 Py_INCREF(Py_None); 438 return Py_None; 439} 440 441 442static PyObject * 443posix_1str(args, func) 444 PyObject *args; 445 int (*func) Py_FPROTO((const char *)); 446{ 447 char *path1; 448 int res; 449 if (!PyArg_Parse(args, "s", &path1)) 450 return NULL; 451 Py_BEGIN_ALLOW_THREADS 452 res = (*func)(path1); 453 Py_END_ALLOW_THREADS 454 if (res < 0) 455 return posix_error_with_filename(path1); 456 Py_INCREF(Py_None); 457 return Py_None; 458} 459 460static PyObject * 461posix_2str(args, func) 462 PyObject *args; 463 int (*func) Py_FPROTO((const char *, const char *)); 464{ 465 char *path1, *path2; 466 int res; 467 if (!PyArg_Parse(args, "(ss)", &path1, &path2)) 468 return NULL; 469 Py_BEGIN_ALLOW_THREADS 470 res = (*func)(path1, path2); 471 Py_END_ALLOW_THREADS 472 if (res != 0) 473 /* XXX how to report both path1 and path2??? */ 474 return posix_error(); 475 Py_INCREF(Py_None); 476 return Py_None; 477} 478 479static PyObject * 480posix_strint(args, func) 481 PyObject *args; 482 int (*func) Py_FPROTO((const char *, int)); 483{ 484 char *path; 485 int i; 486 int res; 487 if (!PyArg_Parse(args, "(si)", &path, &i)) 488 return NULL; 489 Py_BEGIN_ALLOW_THREADS 490 res = (*func)(path, i); 491 Py_END_ALLOW_THREADS 492 if (res < 0) 493 return posix_error_with_filename(path); 494 Py_INCREF(Py_None); 495 return Py_None; 496} 497 498static PyObject * 499posix_strintint(args, func) 500 PyObject *args; 501 int (*func) Py_FPROTO((const char *, int, int)); 502{ 503 char *path; 504 int i,i2; 505 int res; 506 if (!PyArg_Parse(args, "(sii)", &path, &i, &i2)) 507 return NULL; 508 Py_BEGIN_ALLOW_THREADS 509 res = (*func)(path, i, i2); 510 Py_END_ALLOW_THREADS 511 if (res < 0) 512 return posix_error_with_filename(path); 513 Py_INCREF(Py_None); 514 return Py_None; 515} 516 517static PyObject * 518posix_do_stat(self, args, statfunc) 519 PyObject *self; 520 PyObject *args; 521 int (*statfunc) Py_FPROTO((const char *, struct stat *)); 522{ 523 struct stat st; 524 char *path; 525 int res; 526 if (!PyArg_Parse(args, "s", &path)) 527 return NULL; 528 Py_BEGIN_ALLOW_THREADS 529 res = (*statfunc)(path, &st); 530 Py_END_ALLOW_THREADS 531 if (res != 0) 532 return posix_error_with_filename(path); 533#if !defined(HAVE_LARGEFILE_SUPPORT) 534 return Py_BuildValue("(llllllllll)", 535 (long)st.st_mode, 536 (long)st.st_ino, 537 (long)st.st_dev, 538 (long)st.st_nlink, 539 (long)st.st_uid, 540 (long)st.st_gid, 541 (long)st.st_size, 542 (long)st.st_atime, 543 (long)st.st_mtime, 544 (long)st.st_ctime); 545#else 546 return Py_BuildValue("(lLllllLlll)", 547 (long)st.st_mode, 548 (LONG_LONG)st.st_ino, 549 (long)st.st_dev, 550 (long)st.st_nlink, 551 (long)st.st_uid, 552 (long)st.st_gid, 553 (LONG_LONG)st.st_size, 554 (long)st.st_atime, 555 (long)st.st_mtime, 556 (long)st.st_ctime); 557#endif 558} 559 560 561/* POSIX methods */ 562 563static char posix_access__doc__[] = 564"access(path, mode) -> 1 if granted, 0 otherwise\n\ 565Test for access to a file."; 566 567static PyObject * 568posix_access(self, args) 569 PyObject *self; 570 PyObject *args; 571{ 572 char *path; 573 int mode; 574 int res; 575 576 if (!PyArg_Parse(args, "(si)", &path, &mode)) 577 return NULL; 578 Py_BEGIN_ALLOW_THREADS 579 res = access(path, mode); 580 Py_END_ALLOW_THREADS 581 return(PyInt_FromLong(res == 0 ? 1L : 0L)); 582} 583 584#ifndef F_OK 585#define F_OK 0 586#endif 587#ifndef R_OK 588#define R_OK 4 589#endif 590#ifndef W_OK 591#define W_OK 2 592#endif 593#ifndef X_OK 594#define X_OK 1 595#endif 596 597#ifdef HAVE_TTYNAME 598static char posix_ttyname__doc__[] = 599"ttyname(fd, mode) -> String\n\ 600Return the name of the terminal device connected to 'fd'."; 601 602static PyObject * 603posix_ttyname(self, args) 604 PyObject *self; 605 PyObject *args; 606{ 607 PyObject *file; 608 int id; 609 char *ret; 610 611 if (!PyArg_Parse(args, "i", &id)) 612 return NULL; 613 614 ret = ttyname(id); 615 if (ret == NULL) 616 return(posix_error()); 617 return(PyString_FromString(ret)); 618} 619#endif 620 621static char posix_chdir__doc__[] = 622"chdir(path) -> None\n\ 623Change the current working directory to the specified path."; 624 625static PyObject * 626posix_chdir(self, args) 627 PyObject *self; 628 PyObject *args; 629{ 630 return posix_1str(args, chdir); 631} 632 633 634static char posix_chmod__doc__[] = 635"chmod(path, mode) -> None\n\ 636Change the access permissions of a file."; 637 638static PyObject * 639posix_chmod(self, args) 640 PyObject *self; 641 PyObject *args; 642{ 643 return posix_strint(args, chmod); 644} 645 646 647#ifdef HAVE_FSYNC 648static char posix_fsync__doc__[] = 649"fsync(fildes) -> None\n\ 650force write of file with filedescriptor to disk."; 651 652static PyObject * 653posix_fsync(self, args) 654 PyObject *self; 655 PyObject *args; 656{ 657 return posix_int(args, fsync); 658} 659#endif /* HAVE_FSYNC */ 660 661#ifdef HAVE_FDATASYNC 662static char posix_fdatasync__doc__[] = 663"fdatasync(fildes) -> None\n\ 664force write of file with filedescriptor to disk.\n\ 665 does not force update of metadata."; 666 667extern int fdatasync(int); /* Prototype just in case */ 668 669static PyObject * 670posix_fdatasync(self, args) 671 PyObject *self; 672 PyObject *args; 673{ 674 return posix_int(args, fdatasync); 675} 676#endif /* HAVE_FDATASYNC */ 677 678 679#ifdef HAVE_CHOWN 680static char posix_chown__doc__[] = 681"chown(path, uid, gid) -> None\n\ 682Change the owner and group id of path to the numeric uid and gid."; 683 684static PyObject * 685posix_chown(self, args) 686 PyObject *self; 687 PyObject *args; 688{ 689 return posix_strintint(args, chown); 690} 691#endif /* HAVE_CHOWN */ 692 693 694#ifdef HAVE_GETCWD 695static char posix_getcwd__doc__[] = 696"getcwd() -> path\n\ 697Return a string representing the current working directory."; 698 699static PyObject * 700posix_getcwd(self, args) 701 PyObject *self; 702 PyObject *args; 703{ 704 char buf[1026]; 705 char *res; 706 if (!PyArg_NoArgs(args)) 707 return NULL; 708 Py_BEGIN_ALLOW_THREADS 709 res = getcwd(buf, sizeof buf); 710 Py_END_ALLOW_THREADS 711 if (res == NULL) 712 return posix_error(); 713 return PyString_FromString(buf); 714} 715#endif 716 717 718#ifdef HAVE_LINK 719static char posix_link__doc__[] = 720"link(src, dst) -> None\n\ 721Create a hard link to a file."; 722 723static PyObject * 724posix_link(self, args) 725 PyObject *self; 726 PyObject *args; 727{ 728 return posix_2str(args, link); 729} 730#endif /* HAVE_LINK */ 731 732 733static char posix_listdir__doc__[] = 734"listdir(path) -> list_of_strings\n\ 735Return a list containing the names of the entries in the directory.\n\ 736\n\ 737 path: path of directory to list\n\ 738\n\ 739The list is in arbitrary order. It does not include the special\n\ 740entries '.' and '..' even if they are present in the directory."; 741 742static PyObject * 743posix_listdir(self, args) 744 PyObject *self; 745 PyObject *args; 746{ 747 /* XXX Should redo this putting the (now four) versions of opendir 748 in separate files instead of having them all here... */ 749#if defined(MS_WIN32) && !defined(HAVE_OPENDIR) 750 751 char *name; 752 int len; 753 PyObject *d, *v; 754 HANDLE hFindFile; 755 WIN32_FIND_DATA FileData; 756 char namebuf[MAX_PATH+5]; 757 758 if (!PyArg_Parse(args, "t#", &name, &len)) 759 return NULL; 760 if (len >= MAX_PATH) { 761 PyErr_SetString(PyExc_ValueError, "path too long"); 762 return NULL; 763 } 764 strcpy(namebuf, name); 765 if (namebuf[len-1] != '/' && namebuf[len-1] != '\\') 766 namebuf[len++] = '/'; 767 strcpy(namebuf + len, "*.*"); 768 769 if ((d = PyList_New(0)) == NULL) 770 return NULL; 771 772 hFindFile = FindFirstFile(namebuf, &FileData); 773 if (hFindFile == INVALID_HANDLE_VALUE) { 774 errno = GetLastError(); 775 if (errno == ERROR_FILE_NOT_FOUND) 776 return PyList_New(0); 777 return posix_error(); 778 } 779 do { 780 if (FileData.cFileName[0] == '.' && 781 (FileData.cFileName[1] == '\0' || 782 FileData.cFileName[1] == '.' && 783 FileData.cFileName[2] == '\0')) 784 continue; 785 v = PyString_FromString(FileData.cFileName); 786 if (v == NULL) { 787 Py_DECREF(d); 788 d = NULL; 789 break; 790 } 791 if (PyList_Append(d, v) != 0) { 792 Py_DECREF(v); 793 Py_DECREF(d); 794 d = NULL; 795 break; 796 } 797 Py_DECREF(v); 798 } while (FindNextFile(hFindFile, &FileData) == TRUE); 799 800 if (FindClose(hFindFile) == FALSE) { 801 errno = GetLastError(); 802 return posix_error(); 803 } 804 805 return d; 806 807#else /* !MS_WIN32 */ 808#ifdef _MSC_VER /* 16-bit Windows */ 809 810#ifndef MAX_PATH 811#define MAX_PATH 250 812#endif 813 char *name, *pt; 814 int len; 815 PyObject *d, *v; 816 char namebuf[MAX_PATH+5]; 817 struct _find_t ep; 818 819 if (!PyArg_Parse(args, "t#", &name, &len)) 820 return NULL; 821 if (len >= MAX_PATH) { 822 PyErr_SetString(PyExc_ValueError, "path too long"); 823 return NULL; 824 } 825 strcpy(namebuf, name); 826 for (pt = namebuf; *pt; pt++) 827 if (*pt == '/') 828 *pt = '\\'; 829 if (namebuf[len-1] != '\\') 830 namebuf[len++] = '\\'; 831 strcpy(namebuf + len, "*.*"); 832 833 if ((d = PyList_New(0)) == NULL) 834 return NULL; 835 836 if (_dos_findfirst(namebuf, _A_RDONLY | 837 _A_HIDDEN | _A_SYSTEM | _A_SUBDIR, &ep) != 0) 838 { 839 errno = ENOENT; 840 return posix_error(); 841 } 842 do { 843 if (ep.name[0] == '.' && 844 (ep.name[1] == '\0' || 845 ep.name[1] == '.' && 846 ep.name[2] == '\0')) 847 continue; 848 strcpy(namebuf, ep.name); 849 for (pt = namebuf; *pt; pt++) 850 if (isupper(*pt)) 851 *pt = tolower(*pt); 852 v = PyString_FromString(namebuf); 853 if (v == NULL) { 854 Py_DECREF(d); 855 d = NULL; 856 break; 857 } 858 if (PyList_Append(d, v) != 0) { 859 Py_DECREF(v); 860 Py_DECREF(d); 861 d = NULL; 862 break; 863 } 864 Py_DECREF(v); 865 } while (_dos_findnext(&ep) == 0); 866 867 return d; 868 869#else 870#if defined(PYOS_OS2) 871 872#ifndef MAX_PATH 873#define MAX_PATH CCHMAXPATH 874#endif 875 char *name, *pt; 876 int len; 877 PyObject *d, *v; 878 char namebuf[MAX_PATH+5]; 879 HDIR hdir = 1; 880 ULONG srchcnt = 1; 881 FILEFINDBUF3 ep; 882 APIRET rc; 883 884 if (!PyArg_Parse(args, "t#", &name, &len)) 885 return NULL; 886 if (len >= MAX_PATH) { 887 PyErr_SetString(PyExc_ValueError, "path too long"); 888 return NULL; 889 } 890 strcpy(namebuf, name); 891 for (pt = namebuf; *pt; pt++) 892 if (*pt == '/') 893 *pt = '\\'; 894 if (namebuf[len-1] != '\\') 895 namebuf[len++] = '\\'; 896 strcpy(namebuf + len, "*.*"); 897 898 if ((d = PyList_New(0)) == NULL) 899 return NULL; 900 901 rc = DosFindFirst(namebuf, /* Wildcard Pattern to Match */ 902 &hdir, /* Handle to Use While Search Directory */ 903 FILE_READONLY | FILE_HIDDEN | FILE_SYSTEM | FILE_DIRECTORY, 904 &ep, sizeof(ep), /* Structure to Receive Directory Entry */ 905 &srchcnt, /* Max and Actual Count of Entries Per Iteration */ 906 FIL_STANDARD); /* Format of Entry (EAs or Not) */ 907 908 if (rc != NO_ERROR) { 909 errno = ENOENT; 910 return posix_error(); 911 } 912 913 if (srchcnt > 0) { /* If Directory is NOT Totally Empty, */ 914 do { 915 if (ep.achName[0] == '.' 916 && (ep.achName[1] == '\0' || ep.achName[1] == '.' && ep.achName[2] == '\0')) 917 continue; /* Skip Over "." and ".." Names */ 918 919 strcpy(namebuf, ep.achName); 920 921 /* Leave Case of Name Alone -- In Native Form */ 922 /* (Removed Forced Lowercasing Code) */ 923 924 v = PyString_FromString(namebuf); 925 if (v == NULL) { 926 Py_DECREF(d); 927 d = NULL; 928 break; 929 } 930 if (PyList_Append(d, v) != 0) { 931 Py_DECREF(v); 932 Py_DECREF(d); 933 d = NULL; 934 break; 935 } 936 Py_DECREF(v); 937 } while (DosFindNext(hdir, &ep, sizeof(ep), &srchcnt) == NO_ERROR && srchcnt > 0); 938 } 939 940 return d; 941#else 942 943 char *name; 944 PyObject *d, *v; 945 DIR *dirp; 946 struct dirent *ep; 947 if (!PyArg_Parse(args, "s", &name)) 948 return NULL; 949 Py_BEGIN_ALLOW_THREADS 950 if ((dirp = opendir(name)) == NULL) { 951 Py_BLOCK_THREADS 952 return posix_error(); 953 } 954 if ((d = PyList_New(0)) == NULL) { 955 closedir(dirp); 956 Py_BLOCK_THREADS 957 return NULL; 958 } 959 while ((ep = readdir(dirp)) != NULL) { 960 if (ep->d_name[0] == '.' && 961 (NAMLEN(ep) == 1 || 962 (ep->d_name[1] == '.' && NAMLEN(ep) == 2))) 963 continue; 964 v = PyString_FromStringAndSize(ep->d_name, NAMLEN(ep)); 965 if (v == NULL) { 966 Py_DECREF(d); 967 d = NULL; 968 break; 969 } 970 if (PyList_Append(d, v) != 0) { 971 Py_DECREF(v); 972 Py_DECREF(d); 973 d = NULL; 974 break; 975 } 976 Py_DECREF(v); 977 } 978 closedir(dirp); 979 Py_END_ALLOW_THREADS 980 981 return d; 982 983#endif /* !PYOS_OS2 */ 984#endif /* !_MSC_VER */ 985#endif /* !MS_WIN32 */ 986} 987 988static char posix_mkdir__doc__[] = 989"mkdir(path [, mode=0777]) -> None\n\ 990Create a directory."; 991 992static PyObject * 993posix_mkdir(self, args) 994 PyObject *self; 995 PyObject *args; 996{ 997 int res; 998 char *path; 999 int mode = 0777; 1000 if (!PyArg_ParseTuple(args, "s|i", &path, &mode)) 1001 return NULL; 1002 Py_BEGIN_ALLOW_THREADS 1003#if ( defined(__WATCOMC__) || defined(_MSC_VER) || defined(PYCC_VACPP) ) && !defined(__QNX__) 1004 res = mkdir(path); 1005#else 1006 res = mkdir(path, mode); 1007#endif 1008 Py_END_ALLOW_THREADS 1009 if (res < 0) 1010 return posix_error_with_filename(path); 1011 Py_INCREF(Py_None); 1012 return Py_None; 1013} 1014 1015 1016#ifdef HAVE_NICE 1017static char posix_nice__doc__[] = 1018"nice(inc) -> new_priority\n\ 1019Decrease the priority of process and return new priority."; 1020 1021static PyObject * 1022posix_nice(self, args) 1023 PyObject *self; 1024 PyObject *args; 1025{ 1026 int increment, value; 1027 1028 if (!PyArg_Parse(args, "i", &increment)) 1029 return NULL; 1030 value = nice(increment); 1031 if (value == -1) 1032 return posix_error(); 1033 return PyInt_FromLong((long) value); 1034} 1035#endif /* HAVE_NICE */ 1036 1037 1038static char posix_rename__doc__[] = 1039"rename(old, new) -> None\n\ 1040Rename a file or directory."; 1041 1042static PyObject * 1043posix_rename(self, args) 1044 PyObject *self; 1045 PyObject *args; 1046{ 1047 return posix_2str(args, rename); 1048} 1049 1050 1051static char posix_rmdir__doc__[] = 1052"rmdir(path) -> None\n\ 1053Remove a directory."; 1054 1055static PyObject * 1056posix_rmdir(self, args) 1057 PyObject *self; 1058 PyObject *args; 1059{ 1060 return posix_1str(args, rmdir); 1061} 1062 1063 1064static char posix_stat__doc__[] = 1065"stat(path) -> (mode,ino,dev,nlink,uid,gid,size,atime,mtime,ctime)\n\ 1066Perform a stat system call on the given path."; 1067 1068static PyObject * 1069posix_stat(self, args) 1070 PyObject *self; 1071 PyObject *args; 1072{ 1073 return posix_do_stat(self, args, stat); 1074} 1075 1076 1077#ifdef HAVE_SYSTEM 1078static char posix_system__doc__[] = 1079"system(command) -> exit_status\n\ 1080Execute the command (a string) in a subshell."; 1081 1082static PyObject * 1083posix_system(self, args) 1084 PyObject *self; 1085 PyObject *args; 1086{ 1087 char *command; 1088 long sts; 1089 if (!PyArg_Parse(args, "s", &command)) 1090 return NULL; 1091 Py_BEGIN_ALLOW_THREADS 1092 sts = system(command); 1093 Py_END_ALLOW_THREADS 1094 return PyInt_FromLong(sts); 1095} 1096#endif 1097 1098 1099static char posix_umask__doc__[] = 1100"umask(new_mask) -> old_mask\n\ 1101Set the current numeric umask and return the previous umask."; 1102 1103static PyObject * 1104posix_umask(self, args) 1105 PyObject *self; 1106 PyObject *args; 1107{ 1108 int i; 1109 if (!PyArg_Parse(args, "i", &i)) 1110 return NULL; 1111 i = umask(i); 1112 if (i < 0) 1113 return posix_error(); 1114 return PyInt_FromLong((long)i); 1115} 1116 1117 1118static char posix_unlink__doc__[] = 1119"unlink(path) -> None\n\ 1120Remove a file (same as remove(path))."; 1121 1122static char posix_remove__doc__[] = 1123"remove(path) -> None\n\ 1124Remove a file (same as unlink(path))."; 1125 1126static PyObject * 1127posix_unlink(self, args) 1128 PyObject *self; 1129 PyObject *args; 1130{ 1131 return posix_1str(args, unlink); 1132} 1133 1134 1135#ifdef HAVE_UNAME 1136static char posix_uname__doc__[] = 1137"uname() -> (sysname, nodename, release, version, machine)\n\ 1138Return a tuple identifying the current operating system."; 1139 1140static PyObject * 1141posix_uname(self, args) 1142 PyObject *self; 1143 PyObject *args; 1144{ 1145 struct utsname u; 1146 int res; 1147 if (!PyArg_NoArgs(args)) 1148 return NULL; 1149 Py_BEGIN_ALLOW_THREADS 1150 res = uname(&u); 1151 Py_END_ALLOW_THREADS 1152 if (res < 0) 1153 return posix_error(); 1154 return Py_BuildValue("(sssss)", 1155 u.sysname, 1156 u.nodename, 1157 u.release, 1158 u.version, 1159 u.machine); 1160} 1161#endif /* HAVE_UNAME */ 1162 1163 1164static char posix_utime__doc__[] = 1165"utime(path, (atime, utime)) -> None\n\ 1166Set the access and modified time of the file to the given values."; 1167 1168static PyObject * 1169posix_utime(self, args) 1170 PyObject *self; 1171 PyObject *args; 1172{ 1173 char *path; 1174 long atime, mtime; 1175 int res; 1176 1177/* XXX should define struct utimbuf instead, above */ 1178#ifdef HAVE_UTIME_H 1179 struct utimbuf buf; 1180#define ATIME buf.actime 1181#define MTIME buf.modtime 1182#define UTIME_ARG &buf 1183#else /* HAVE_UTIME_H */ 1184 time_t buf[2]; 1185#define ATIME buf[0] 1186#define MTIME buf[1] 1187#define UTIME_ARG buf 1188#endif /* HAVE_UTIME_H */ 1189 1190 if (!PyArg_Parse(args, "(s(ll))", &path, &atime, &mtime)) 1191 return NULL; 1192 ATIME = atime; 1193 MTIME = mtime; 1194 Py_BEGIN_ALLOW_THREADS 1195 res = utime(path, UTIME_ARG); 1196 Py_END_ALLOW_THREADS 1197 if (res < 0) 1198 return posix_error_with_filename(path); 1199 Py_INCREF(Py_None); 1200 return Py_None; 1201#undef UTIME_ARG 1202#undef ATIME 1203#undef MTIME 1204} 1205 1206 1207/* Process operations */ 1208 1209static char posix__exit__doc__[] = 1210"_exit(status)\n\ 1211Exit to the system with specified status, without normal exit processing."; 1212 1213static PyObject * 1214posix__exit(self, args) 1215 PyObject *self; 1216 PyObject *args; 1217{ 1218 int sts; 1219 if (!PyArg_Parse(args, "i", &sts)) 1220 return NULL; 1221 _exit(sts); 1222 return NULL; /* Make gcc -Wall happy */ 1223} 1224 1225 1226#ifdef HAVE_EXECV 1227static char posix_execv__doc__[] = 1228"execv(path, args)\n\ 1229Execute an executable path with arguments, replacing current process.\n\ 1230\n\ 1231 path: path of executable file\n\ 1232 args: tuple or list of strings"; 1233 1234static PyObject * 1235posix_execv(self, args) 1236 PyObject *self; 1237 PyObject *args; 1238{ 1239 char *path; 1240 PyObject *argv; 1241 char **argvlist; 1242 int i, argc; 1243 PyObject *(*getitem) Py_PROTO((PyObject *, int)); 1244 1245 /* execv has two arguments: (path, argv), where 1246 argv is a list or tuple of strings. */ 1247 1248 if (!PyArg_Parse(args, "(sO)", &path, &argv)) 1249 return NULL; 1250 if (PyList_Check(argv)) { 1251 argc = PyList_Size(argv); 1252 getitem = PyList_GetItem; 1253 } 1254 else if (PyTuple_Check(argv)) { 1255 argc = PyTuple_Size(argv); 1256 getitem = PyTuple_GetItem; 1257 } 1258 else { 1259 badarg: 1260 PyErr_BadArgument(); 1261 return NULL; 1262 } 1263 1264 argvlist = PyMem_NEW(char *, argc+1); 1265 if (argvlist == NULL) 1266 return NULL; 1267 for (i = 0; i < argc; i++) { 1268 if (!PyArg_Parse((*getitem)(argv, i), "s", &argvlist[i])) { 1269 PyMem_DEL(argvlist); 1270 goto badarg; 1271 } 1272 } 1273 argvlist[argc] = NULL; 1274 1275#ifdef BAD_EXEC_PROTOTYPES 1276 execv(path, (const char **) argvlist); 1277#else /* BAD_EXEC_PROTOTYPES */ 1278 execv(path, argvlist); 1279#endif /* BAD_EXEC_PROTOTYPES */ 1280 1281 /* If we get here it's definitely an error */ 1282 1283 PyMem_DEL(argvlist); 1284 return posix_error(); 1285} 1286 1287 1288static char posix_execve__doc__[] = 1289"execve(path, args, env)\n\ 1290Execute a path with arguments and environment, replacing current process.\n\ 1291\n\ 1292 path: path of executable file\n\ 1293 args: tuple or list of arguments\n\ 1294 env: dictonary of strings mapping to strings"; 1295 1296static PyObject * 1297posix_execve(self, args) 1298 PyObject *self; 1299 PyObject *args; 1300{ 1301 char *path; 1302 PyObject *argv, *env; 1303 char **argvlist; 1304 char **envlist; 1305 PyObject *key, *val, *keys=NULL, *vals=NULL; 1306 int i, pos, argc, envc; 1307 PyObject *(*getitem) Py_PROTO((PyObject *, int)); 1308 1309 /* execve has three arguments: (path, argv, env), where 1310 argv is a list or tuple of strings and env is a dictionary 1311 like posix.environ. */ 1312 1313 if (!PyArg_Parse(args, "(sOO)", &path, &argv, &env)) 1314 return NULL; 1315 if (PyList_Check(argv)) { 1316 argc = PyList_Size(argv); 1317 getitem = PyList_GetItem; 1318 } 1319 else if (PyTuple_Check(argv)) { 1320 argc = PyTuple_Size(argv); 1321 getitem = PyTuple_GetItem; 1322 } 1323 else { 1324 PyErr_SetString(PyExc_TypeError, "argv must be tuple or list"); 1325 return NULL; 1326 } 1327 if (!PyMapping_Check(env)) { 1328 PyErr_SetString(PyExc_TypeError, "env must be mapping object"); 1329 return NULL; 1330 } 1331 1332 argvlist = PyMem_NEW(char *, argc+1); 1333 if (argvlist == NULL) { 1334 PyErr_NoMemory(); 1335 return NULL; 1336 } 1337 for (i = 0; i < argc; i++) { 1338 if (!PyArg_Parse((*getitem)(argv, i), 1339 "s;argv must be list of strings", 1340 &argvlist[i])) 1341 { 1342 goto fail_1; 1343 } 1344 } 1345 argvlist[argc] = NULL; 1346 1347 i = PyMapping_Length(env); 1348 envlist = PyMem_NEW(char *, i + 1); 1349 if (envlist == NULL) { 1350 PyErr_NoMemory(); 1351 goto fail_1; 1352 } 1353 envc = 0; 1354 keys = PyMapping_Keys(env); 1355 vals = PyMapping_Values(env); 1356 if (!keys || !vals) 1357 goto fail_2; 1358 1359 for (pos = 0; pos < i; pos++) { 1360 char *p, *k, *v; 1361 1362 key = PyList_GetItem(keys, pos); 1363 val = PyList_GetItem(vals, pos); 1364 if (!key || !val) 1365 goto fail_2; 1366 1367 if (!PyArg_Parse(key, "s;non-string key in env", &k) || 1368 !PyArg_Parse(val, "s;non-string value in env", &v)) 1369 { 1370 goto fail_2; 1371 } 1372 1373#if defined(PYOS_OS2) 1374 /* Omit Pseudo-Env Vars that Would Confuse Programs if Passed On */ 1375 if (stricmp(k, "BEGINLIBPATH") != 0 && stricmp(k, "ENDLIBPATH") != 0) { 1376#endif 1377 p = PyMem_NEW(char, PyString_Size(key)+PyString_Size(val) + 2); 1378 if (p == NULL) { 1379 PyErr_NoMemory(); 1380 goto fail_2; 1381 } 1382 sprintf(p, "%s=%s", k, v); 1383 envlist[envc++] = p; 1384#if defined(PYOS_OS2) 1385 } 1386#endif 1387 } 1388 envlist[envc] = 0; 1389 1390 1391#ifdef BAD_EXEC_PROTOTYPES 1392 execve(path, (const char **)argvlist, envlist); 1393#else /* BAD_EXEC_PROTOTYPES */ 1394 execve(path, argvlist, envlist); 1395#endif /* BAD_EXEC_PROTOTYPES */ 1396 1397 /* If we get here it's definitely an error */ 1398 1399 (void) posix_error(); 1400 1401 fail_2: 1402 while (--envc >= 0) 1403 PyMem_DEL(envlist[envc]); 1404 PyMem_DEL(envlist); 1405 fail_1: 1406 PyMem_DEL(argvlist); 1407 Py_XDECREF(vals); 1408 Py_XDECREF(keys); 1409 return NULL; 1410} 1411#endif /* HAVE_EXECV */ 1412 1413 1414#ifdef HAVE_SPAWNV 1415static char posix_spawnv__doc__[] = 1416"spawnv(mode, path, args)\n\ 1417Execute an executable path with arguments, replacing current process.\n\ 1418\n\ 1419 mode: mode of process creation\n\ 1420 path: path of executable file\n\ 1421 args: tuple or list of strings"; 1422 1423static PyObject * 1424posix_spawnv(self, args) 1425 PyObject *self; 1426 PyObject *args; 1427{ 1428 char *path; 1429 PyObject *argv; 1430 char **argvlist; 1431 int mode, i, argc; 1432 PyObject *(*getitem) Py_PROTO((PyObject *, int)); 1433 1434 /* spawnv has three arguments: (mode, path, argv), where 1435 argv is a list or tuple of strings. */ 1436 1437 if (!PyArg_Parse(args, "(isO)", &mode, &path, &argv)) 1438 return NULL; 1439 if (PyList_Check(argv)) { 1440 argc = PyList_Size(argv); 1441 getitem = PyList_GetItem; 1442 } 1443 else if (PyTuple_Check(argv)) { 1444 argc = PyTuple_Size(argv); 1445 getitem = PyTuple_GetItem; 1446 } 1447 else { 1448 badarg: 1449 PyErr_BadArgument(); 1450 return NULL; 1451 } 1452 1453 argvlist = PyMem_NEW(char *, argc+1); 1454 if (argvlist == NULL) 1455 return NULL; 1456 for (i = 0; i < argc; i++) { 1457 if (!PyArg_Parse((*getitem)(argv, i), "s", &argvlist[i])) { 1458 PyMem_DEL(argvlist); 1459 goto badarg; 1460 } 1461 } 1462 argvlist[argc] = NULL; 1463 1464 if (mode == _OLD_P_OVERLAY) 1465 mode = _P_OVERLAY; 1466 i = _spawnv(mode, path, argvlist); 1467 1468 PyMem_DEL(argvlist); 1469 1470 if (i == -1) 1471 return posix_error(); 1472 else 1473 return Py_BuildValue("i", i); 1474} 1475 1476 1477static char posix_spawnve__doc__[] = 1478"spawnve(mode, path, args, env)\n\ 1479Execute a path with arguments and environment, replacing current process.\n\ 1480\n\ 1481 mode: mode of process creation\n\ 1482 path: path of executable file\n\ 1483 args: tuple or list of arguments\n\ 1484 env: dictonary of strings mapping to strings"; 1485 1486static PyObject * 1487posix_spawnve(self, args) 1488 PyObject *self; 1489 PyObject *args; 1490{ 1491 char *path; 1492 PyObject *argv, *env; 1493 char **argvlist; 1494 char **envlist; 1495 PyObject *key, *val, *keys=NULL, *vals=NULL, *res=NULL; 1496 int mode, i, pos, argc, envc; 1497 PyObject *(*getitem) Py_PROTO((PyObject *, int)); 1498 1499 /* spawnve has four arguments: (mode, path, argv, env), where 1500 argv is a list or tuple of strings and env is a dictionary 1501 like posix.environ. */ 1502 1503 if (!PyArg_Parse(args, "(isOO)", &mode, &path, &argv, &env)) 1504 return NULL; 1505 if (PyList_Check(argv)) { 1506 argc = PyList_Size(argv); 1507 getitem = PyList_GetItem; 1508 } 1509 else if (PyTuple_Check(argv)) { 1510 argc = PyTuple_Size(argv); 1511 getitem = PyTuple_GetItem; 1512 } 1513 else { 1514 PyErr_SetString(PyExc_TypeError, "argv must be tuple or list"); 1515 return NULL; 1516 } 1517 if (!PyMapping_Check(env)) { 1518 PyErr_SetString(PyExc_TypeError, "env must be mapping object"); 1519 return NULL; 1520 } 1521 1522 argvlist = PyMem_NEW(char *, argc+1); 1523 if (argvlist == NULL) { 1524 PyErr_NoMemory(); 1525 return NULL; 1526 } 1527 for (i = 0; i < argc; i++) { 1528 if (!PyArg_Parse((*getitem)(argv, i), 1529 "s;argv must be list of strings", 1530 &argvlist[i])) 1531 { 1532 goto fail_1; 1533 } 1534 } 1535 argvlist[argc] = NULL; 1536 1537 i = PyMapping_Length(env); 1538 envlist = PyMem_NEW(char *, i + 1); 1539 if (envlist == NULL) { 1540 PyErr_NoMemory(); 1541 goto fail_1; 1542 } 1543 envc = 0; 1544 keys = PyMapping_Keys(env); 1545 vals = PyMapping_Values(env); 1546 if (!keys || !vals) 1547 goto fail_2; 1548 1549 for (pos = 0; pos < i; pos++) { 1550 char *p, *k, *v; 1551 1552 key = PyList_GetItem(keys, pos); 1553 val = PyList_GetItem(vals, pos); 1554 if (!key || !val) 1555 goto fail_2; 1556 1557 if (!PyArg_Parse(key, "s;non-string key in env", &k) || 1558 !PyArg_Parse(val, "s;non-string value in env", &v)) 1559 { 1560 goto fail_2; 1561 } 1562 p = PyMem_NEW(char, PyString_Size(key)+PyString_Size(val) + 2); 1563 if (p == NULL) { 1564 PyErr_NoMemory(); 1565 goto fail_2; 1566 } 1567 sprintf(p, "%s=%s", k, v); 1568 envlist[envc++] = p; 1569 } 1570 envlist[envc] = 0; 1571 1572 if (mode == _OLD_P_OVERLAY) 1573 mode = _P_OVERLAY; 1574 i = _spawnve(mode, path, argvlist, envlist); 1575 if (i == -1) 1576 (void) posix_error(); 1577 else 1578 res = Py_BuildValue("i", i); 1579 1580 fail_2: 1581 while (--envc >= 0) 1582 PyMem_DEL(envlist[envc]); 1583 PyMem_DEL(envlist); 1584 fail_1: 1585 PyMem_DEL(argvlist); 1586 Py_XDECREF(vals); 1587 Py_XDECREF(keys); 1588 return res; 1589} 1590#endif /* HAVE_SPAWNV */ 1591 1592 1593#ifdef HAVE_FORK 1594static char posix_fork__doc__[] = 1595"fork() -> pid\n\ 1596Fork a child process.\n\ 1597\n\ 1598Return 0 to child process and PID of child to parent process."; 1599 1600static PyObject * 1601posix_fork(self, args) 1602 PyObject *self; 1603 PyObject *args; 1604{ 1605 int pid; 1606 if (!PyArg_NoArgs(args)) 1607 return NULL; 1608 pid = fork(); 1609 if (pid == -1) 1610 return posix_error(); 1611 PyOS_AfterFork(); 1612 return PyInt_FromLong((long)pid); 1613} 1614#endif 1615 1616 1617#ifdef HAVE_GETEGID 1618static char posix_getegid__doc__[] = 1619"getegid() -> egid\n\ 1620Return the current process's effective group id."; 1621 1622static PyObject * 1623posix_getegid(self, args) 1624 PyObject *self; 1625 PyObject *args; 1626{ 1627 if (!PyArg_NoArgs(args)) 1628 return NULL; 1629 return PyInt_FromLong((long)getegid()); 1630} 1631#endif 1632 1633 1634#ifdef HAVE_GETEUID 1635static char posix_geteuid__doc__[] = 1636"geteuid() -> euid\n\ 1637Return the current process's effective user id."; 1638 1639static PyObject * 1640posix_geteuid(self, args) 1641 PyObject *self; 1642 PyObject *args; 1643{ 1644 if (!PyArg_NoArgs(args)) 1645 return NULL; 1646 return PyInt_FromLong((long)geteuid()); 1647} 1648#endif 1649 1650 1651#ifdef HAVE_GETGID 1652static char posix_getgid__doc__[] = 1653"getgid() -> gid\n\ 1654Return the current process's group id."; 1655 1656static PyObject * 1657posix_getgid(self, args) 1658 PyObject *self; 1659 PyObject *args; 1660{ 1661 if (!PyArg_NoArgs(args)) 1662 return NULL; 1663 return PyInt_FromLong((long)getgid()); 1664} 1665#endif 1666 1667 1668static char posix_getpid__doc__[] = 1669"getpid() -> pid\n\ 1670Return the current process id"; 1671 1672static PyObject * 1673posix_getpid(self, args) 1674 PyObject *self; 1675 PyObject *args; 1676{ 1677 if (!PyArg_NoArgs(args)) 1678 return NULL; 1679 return PyInt_FromLong((long)getpid()); 1680} 1681 1682 1683#ifdef HAVE_GETPGRP 1684static char posix_getpgrp__doc__[] = 1685"getpgrp() -> pgrp\n\ 1686Return the current process group id."; 1687 1688static PyObject * 1689posix_getpgrp(self, args) 1690 PyObject *self; 1691 PyObject *args; 1692{ 1693 if (!PyArg_NoArgs(args)) 1694 return NULL; 1695#ifdef GETPGRP_HAVE_ARG 1696 return PyInt_FromLong((long)getpgrp(0)); 1697#else /* GETPGRP_HAVE_ARG */ 1698 return PyInt_FromLong((long)getpgrp()); 1699#endif /* GETPGRP_HAVE_ARG */ 1700} 1701#endif /* HAVE_GETPGRP */ 1702 1703 1704#ifdef HAVE_SETPGRP 1705static char posix_setpgrp__doc__[] = 1706"setpgrp() -> None\n\ 1707Make this process a session leader."; 1708 1709static PyObject * 1710posix_setpgrp(self, args) 1711 PyObject *self; 1712 PyObject *args; 1713{ 1714 if (!PyArg_NoArgs(args)) 1715 return NULL; 1716#ifdef SETPGRP_HAVE_ARG 1717 if (setpgrp(0, 0) < 0) 1718#else /* SETPGRP_HAVE_ARG */ 1719 if (setpgrp() < 0) 1720#endif /* SETPGRP_HAVE_ARG */ 1721 return posix_error(); 1722 Py_INCREF(Py_None); 1723 return Py_None; 1724} 1725 1726#endif /* HAVE_SETPGRP */ 1727 1728#ifdef HAVE_GETPPID 1729static char posix_getppid__doc__[] = 1730"getppid() -> ppid\n\ 1731Return the parent's process id."; 1732 1733static PyObject * 1734posix_getppid(self, args) 1735 PyObject *self; 1736 PyObject *args; 1737{ 1738 if (!PyArg_NoArgs(args)) 1739 return NULL; 1740 return PyInt_FromLong((long)getppid()); 1741} 1742#endif 1743 1744 1745#ifdef HAVE_GETUID 1746static char posix_getuid__doc__[] = 1747"getuid() -> uid\n\ 1748Return the current process's user id."; 1749 1750static PyObject * 1751posix_getuid(self, args) 1752 PyObject *self; 1753 PyObject *args; 1754{ 1755 if (!PyArg_NoArgs(args)) 1756 return NULL; 1757 return PyInt_FromLong((long)getuid()); 1758} 1759#endif 1760 1761 1762#ifdef HAVE_KILL 1763static char posix_kill__doc__[] = 1764"kill(pid, sig) -> None\n\ 1765Kill a process with a signal."; 1766 1767static PyObject * 1768posix_kill(self, args) 1769 PyObject *self; 1770 PyObject *args; 1771{ 1772 int pid, sig; 1773 if (!PyArg_Parse(args, "(ii)", &pid, &sig)) 1774 return NULL; 1775#if defined(PYOS_OS2) 1776 if (sig == XCPT_SIGNAL_INTR || sig == XCPT_SIGNAL_BREAK) { 1777 APIRET rc; 1778 if ((rc = DosSendSignalException(pid, sig)) != NO_ERROR) 1779 return os2_error(rc); 1780 1781 } else if (sig == XCPT_SIGNAL_KILLPROC) { 1782 APIRET rc; 1783 if ((rc = DosKillProcess(DKP_PROCESS, pid)) != NO_ERROR) 1784 return os2_error(rc); 1785 1786 } else 1787 return NULL; /* Unrecognized Signal Requested */ 1788#else 1789 if (kill(pid, sig) == -1) 1790 return posix_error(); 1791#endif 1792 Py_INCREF(Py_None); 1793 return Py_None; 1794} 1795#endif 1796 1797#ifdef HAVE_PLOCK 1798 1799#ifdef HAVE_SYS_LOCK_H 1800#include <sys/lock.h> 1801#endif 1802 1803static char posix_plock__doc__[] = 1804"plock(op) -> None\n\ 1805Lock program segments into memory."; 1806 1807static PyObject * 1808posix_plock(self, args) 1809 PyObject *self; 1810 PyObject *args; 1811{ 1812 int op; 1813 if (!PyArg_Parse(args, "i", &op)) 1814 return NULL; 1815 if (plock(op) == -1) 1816 return posix_error(); 1817 Py_INCREF(Py_None); 1818 return Py_None; 1819} 1820#endif 1821 1822 1823#ifdef HAVE_POPEN 1824static char posix_popen__doc__[] = 1825"popen(command [, mode='r' [, bufsize]]) -> pipe\n\ 1826Open a pipe to/from a command returning a file object."; 1827 1828#if defined(PYOS_OS2) 1829static int 1830async_system(const char *command) 1831{ 1832 char *p, errormsg[256], args[1024]; 1833 RESULTCODES rcodes; 1834 APIRET rc; 1835 char *shell = getenv("COMSPEC"); 1836 if (!shell) 1837 shell = "cmd"; 1838 1839 strcpy(args, shell); 1840 p = &args[ strlen(args)+1 ]; 1841 strcpy(p, "/c "); 1842 strcat(p, command); 1843 p += strlen(p) + 1; 1844 *p = '\0'; 1845 1846 rc = DosExecPgm(errormsg, sizeof(errormsg), 1847 EXEC_ASYNC, /* Execute Async w/o Wait for Results */ 1848 args, 1849 NULL, /* Inherit Parent's Environment */ 1850 &rcodes, shell); 1851 return rc; 1852} 1853 1854static FILE * 1855popen(const char *command, const char *mode, int pipesize, int *err) 1856{ 1857 HFILE rhan, whan; 1858 FILE *retfd = NULL; 1859 APIRET rc = DosCreatePipe(&rhan, &whan, pipesize); 1860 1861 if (rc != NO_ERROR) { 1862 *err = rc; 1863 return NULL; /* ERROR - Unable to Create Anon Pipe */ 1864 } 1865 1866 if (strchr(mode, 'r') != NULL) { /* Treat Command as a Data Source */ 1867 int oldfd = dup(1); /* Save STDOUT Handle in Another Handle */ 1868 1869 DosEnterCritSec(); /* Stop Other Threads While Changing Handles */ 1870 close(1); /* Make STDOUT Available for Reallocation */ 1871 1872 if (dup2(whan, 1) == 0) { /* Connect STDOUT to Pipe Write Side */ 1873 DosClose(whan); /* Close Now-Unused Pipe Write Handle */ 1874 1875 if (async_system(command) == NO_ERROR) 1876 retfd = fdopen(rhan, mode); /* And Return Pipe Read Handle */ 1877 } 1878 1879 dup2(oldfd, 1); /* Reconnect STDOUT to Original Handle */ 1880 DosExitCritSec(); /* Now Allow Other Threads to Run */ 1881 1882 close(oldfd); /* And Close Saved STDOUT Handle */ 1883 return retfd; /* Return fd of Pipe or NULL if Error */ 1884 1885 } else if (strchr(mode, 'w')) { /* Treat Command as a Data Sink */ 1886 int oldfd = dup(0); /* Save STDIN Handle in Another Handle */ 1887 1888 DosEnterCritSec(); /* Stop Other Threads While Changing Handles */ 1889 close(0); /* Make STDIN Available for Reallocation */ 1890 1891 if (dup2(rhan, 0) == 0) { /* Connect STDIN to Pipe Read Side */ 1892 DosClose(rhan); /* Close Now-Unused Pipe Read Handle */ 1893 1894 if (async_system(command) == NO_ERROR) 1895 retfd = fdopen(whan, mode); /* And Return Pipe Write Handle */ 1896 } 1897 1898 dup2(oldfd, 0); /* Reconnect STDIN to Original Handle */ 1899 DosExitCritSec(); /* Now Allow Other Threads to Run */ 1900 1901 close(oldfd); /* And Close Saved STDIN Handle */ 1902 return retfd; /* Return fd of Pipe or NULL if Error */ 1903 1904 } else { 1905 *err = ERROR_INVALID_ACCESS; 1906 return NULL; /* ERROR - Invalid Mode (Neither Read nor Write) */ 1907 } 1908} 1909 1910static PyObject * 1911posix_popen(self, args) 1912 PyObject *self; 1913 PyObject *args; 1914{ 1915 char *name; 1916 char *mode = "r"; 1917 int err, bufsize = -1; 1918 FILE *fp; 1919 PyObject *f; 1920 if (!PyArg_ParseTuple(args, "s|si", &name, &mode, &bufsize)) 1921 return NULL; 1922 Py_BEGIN_ALLOW_THREADS 1923 fp = popen(name, mode, (bufsize > 0) ? bufsize : 4096, &err); 1924 Py_END_ALLOW_THREADS 1925 if (fp == NULL) 1926 return os2_error(err); 1927 1928 f = PyFile_FromFile(fp, name, mode, fclose); 1929 if (f != NULL) 1930 PyFile_SetBufSize(f, bufsize); 1931 return f; 1932} 1933 1934#else 1935static PyObject * 1936posix_popen(self, args) 1937 PyObject *self; 1938 PyObject *args; 1939{ 1940 char *name; 1941 char *mode = "r"; 1942 int bufsize = -1; 1943 FILE *fp; 1944 PyObject *f; 1945 if (!PyArg_ParseTuple(args, "s|si", &name, &mode, &bufsize)) 1946 return NULL; 1947 Py_BEGIN_ALLOW_THREADS 1948 fp = popen(name, mode); 1949 Py_END_ALLOW_THREADS 1950 if (fp == NULL) 1951 return posix_error(); 1952 f = PyFile_FromFile(fp, name, mode, pclose); 1953 if (f != NULL) 1954 PyFile_SetBufSize(f, bufsize); 1955 return f; 1956} 1957#endif 1958 1959#endif /* HAVE_POPEN */ 1960 1961 1962#ifdef HAVE_SETUID 1963static char posix_setuid__doc__[] = 1964"setuid(uid) -> None\n\ 1965Set the current process's user id."; 1966static PyObject * 1967posix_setuid(self, args) 1968 PyObject *self; 1969 PyObject *args; 1970{ 1971 int uid; 1972 if (!PyArg_Parse(args, "i", &uid)) 1973 return NULL; 1974 if (setuid(uid) < 0) 1975 return posix_error(); 1976 Py_INCREF(Py_None); 1977 return Py_None; 1978} 1979#endif /* HAVE_SETUID */ 1980 1981 1982#ifdef HAVE_SETGID 1983static char posix_setgid__doc__[] = 1984"setgid(gid) -> None\n\ 1985Set the current process's group id."; 1986 1987static PyObject * 1988posix_setgid(self, args) 1989 PyObject *self; 1990 PyObject *args; 1991{ 1992 int gid; 1993 if (!PyArg_Parse(args, "i", &gid)) 1994 return NULL; 1995 if (setgid(gid) < 0) 1996 return posix_error(); 1997 Py_INCREF(Py_None); 1998 return Py_None; 1999} 2000#endif /* HAVE_SETGID */ 2001 2002 2003#ifdef HAVE_WAITPID 2004static char posix_waitpid__doc__[] = 2005"waitpid(pid, options) -> (pid, status)\n\ 2006Wait for completion of a give child process."; 2007 2008static PyObject * 2009posix_waitpid(self, args) 2010 PyObject *self; 2011 PyObject *args; 2012{ 2013 int pid, options; 2014#ifdef UNION_WAIT 2015 union wait status; 2016#define status_i (status.w_status) 2017#else 2018 int status; 2019#define status_i status 2020#endif 2021 status_i = 0; 2022 2023 if (!PyArg_Parse(args, "(ii)", &pid, &options)) 2024 return NULL; 2025 Py_BEGIN_ALLOW_THREADS 2026#ifdef NeXT 2027 pid = wait4(pid, &status, options, NULL); 2028#else 2029 pid = waitpid(pid, &status, options); 2030#endif 2031 Py_END_ALLOW_THREADS 2032 if (pid == -1) 2033 return posix_error(); 2034 else 2035 return Py_BuildValue("ii", pid, status_i); 2036} 2037#endif /* HAVE_WAITPID */ 2038 2039 2040#ifdef HAVE_WAIT 2041static char posix_wait__doc__[] = 2042"wait() -> (pid, status)\n\ 2043Wait for completion of a child process."; 2044 2045static PyObject * 2046posix_wait(self, args) 2047 PyObject *self; 2048 PyObject *args; 2049{ 2050 int pid, sts; 2051#ifdef UNION_WAIT 2052 union wait status; 2053#define status_i (status.w_status) 2054#else 2055 int status; 2056#define status_i status 2057#endif 2058 status_i = 0; 2059 Py_BEGIN_ALLOW_THREADS 2060 pid = wait(&status); 2061 Py_END_ALLOW_THREADS 2062 if (pid == -1) 2063 return posix_error(); 2064 else 2065 return Py_BuildValue("ii", pid, status_i); 2066} 2067#endif 2068 2069 2070static char posix_lstat__doc__[] = 2071"lstat(path) -> (mode,ino,dev,nlink,uid,gid,size,atime,mtime,ctime)\n\ 2072Like stat(path), but do not follow symbolic links."; 2073 2074static PyObject * 2075posix_lstat(self, args) 2076 PyObject *self; 2077 PyObject *args; 2078{ 2079#ifdef HAVE_LSTAT 2080 return posix_do_stat(self, args, lstat); 2081#else /* !HAVE_LSTAT */ 2082 return posix_do_stat(self, args, stat); 2083#endif /* !HAVE_LSTAT */ 2084} 2085 2086 2087#ifdef HAVE_READLINK 2088static char posix_readlink__doc__[] = 2089"readlink(path) -> path\n\ 2090Return a string representing the path to which the symbolic link points."; 2091 2092static PyObject * 2093posix_readlink(self, args) 2094 PyObject *self; 2095 PyObject *args; 2096{ 2097 char buf[MAXPATHLEN]; 2098 char *path; 2099 int n; 2100 if (!PyArg_Parse(args, "s", &path)) 2101 return NULL; 2102 Py_BEGIN_ALLOW_THREADS 2103 n = readlink(path, buf, (int) sizeof buf); 2104 Py_END_ALLOW_THREADS 2105 if (n < 0) 2106 return posix_error_with_filename(path); 2107 return PyString_FromStringAndSize(buf, n); 2108} 2109#endif /* HAVE_READLINK */ 2110 2111 2112#ifdef HAVE_SYMLINK 2113static char posix_symlink__doc__[] = 2114"symlink(src, dst) -> None\n\ 2115Create a symbolic link."; 2116 2117static PyObject * 2118posix_symlink(self, args) 2119 PyObject *self; 2120 PyObject *args; 2121{ 2122 return posix_2str(args, symlink); 2123} 2124#endif /* HAVE_SYMLINK */ 2125 2126 2127#ifdef HAVE_TIMES 2128#ifndef HZ 2129#define HZ 60 /* Universal constant :-) */ 2130#endif /* HZ */ 2131 2132#if defined(PYCC_VACPP) && defined(PYOS_OS2) 2133static long 2134system_uptime() 2135{ 2136 ULONG value = 0; 2137 2138 Py_BEGIN_ALLOW_THREADS 2139 DosQuerySysInfo(QSV_MS_COUNT, QSV_MS_COUNT, &value, sizeof(value)); 2140 Py_END_ALLOW_THREADS 2141 2142 return value; 2143} 2144 2145static PyObject * 2146posix_times(self, args) 2147 PyObject *self; 2148 PyObject *args; 2149{ 2150 if (!PyArg_NoArgs(args)) 2151 return NULL; 2152 2153 /* Currently Only Uptime is Provided -- Others Later */ 2154 return Py_BuildValue("ddddd", 2155 (double)0 /* t.tms_utime / HZ */, 2156 (double)0 /* t.tms_stime / HZ */, 2157 (double)0 /* t.tms_cutime / HZ */, 2158 (double)0 /* t.tms_cstime / HZ */, 2159 (double)system_uptime() / 1000); 2160} 2161#else /* not OS2 */ 2162static PyObject * 2163posix_times(self, args) 2164 PyObject *self; 2165 PyObject *args; 2166{ 2167 struct tms t; 2168 clock_t c; 2169 if (!PyArg_NoArgs(args)) 2170 return NULL; 2171 errno = 0; 2172 c = times(&t); 2173 if (c == (clock_t) -1) 2174 return posix_error(); 2175 return Py_BuildValue("ddddd", 2176 (double)t.tms_utime / HZ, 2177 (double)t.tms_stime / HZ, 2178 (double)t.tms_cutime / HZ, 2179 (double)t.tms_cstime / HZ, 2180 (double)c / HZ); 2181} 2182#endif /* not OS2 */ 2183#endif /* HAVE_TIMES */ 2184 2185 2186#ifdef MS_WIN32 2187#define HAVE_TIMES /* so the method table will pick it up */ 2188static PyObject * 2189posix_times(self, args) 2190 PyObject *self; 2191 PyObject *args; 2192{ 2193 FILETIME create, exit, kernel, user; 2194 HANDLE hProc; 2195 if (!PyArg_NoArgs(args)) 2196 return NULL; 2197 hProc = GetCurrentProcess(); 2198 GetProcessTimes(hProc,&create, &exit, &kernel, &user); 2199 return Py_BuildValue( 2200 "ddddd", 2201 (double)(kernel.dwHighDateTime*2E32+kernel.dwLowDateTime)/2E6, 2202 (double)(user.dwHighDateTime*2E32+user.dwLowDateTime) / 2E6, 2203 (double)0, 2204 (double)0, 2205 (double)0); 2206} 2207#endif /* MS_WIN32 */ 2208 2209#ifdef HAVE_TIMES 2210static char posix_times__doc__[] = 2211"times() -> (utime, stime, cutime, cstime, elapsed_time)\n\ 2212Return a tuple of floating point numbers indicating process times."; 2213#endif 2214 2215 2216#ifdef HAVE_SETSID 2217static char posix_setsid__doc__[] = 2218"setsid() -> None\n\ 2219Call the system call setsid()."; 2220 2221static PyObject * 2222posix_setsid(self, args) 2223 PyObject *self; 2224 PyObject *args; 2225{ 2226 if (!PyArg_NoArgs(args)) 2227 return NULL; 2228 if (setsid() < 0) 2229 return posix_error(); 2230 Py_INCREF(Py_None); 2231 return Py_None; 2232} 2233#endif /* HAVE_SETSID */ 2234 2235#ifdef HAVE_SETPGID 2236static char posix_setpgid__doc__[] = 2237"setpgid(pid, pgrp) -> None\n\ 2238Call the system call setpgid()."; 2239 2240static PyObject * 2241posix_setpgid(self, args) 2242 PyObject *self; 2243 PyObject *args; 2244{ 2245 int pid, pgrp; 2246 if (!PyArg_Parse(args, "(ii)", &pid, &pgrp)) 2247 return NULL; 2248 if (setpgid(pid, pgrp) < 0) 2249 return posix_error(); 2250 Py_INCREF(Py_None); 2251 return Py_None; 2252} 2253#endif /* HAVE_SETPGID */ 2254 2255 2256#ifdef HAVE_TCGETPGRP 2257static char posix_tcgetpgrp__doc__[] = 2258"tcgetpgrp(fd) -> pgid\n\ 2259Return the process group associated with the terminal given by a fd."; 2260 2261static PyObject * 2262posix_tcgetpgrp(self, args) 2263 PyObject *self; 2264 PyObject *args; 2265{ 2266 int fd, pgid; 2267 if (!PyArg_Parse(args, "i", &fd)) 2268 return NULL; 2269 pgid = tcgetpgrp(fd); 2270 if (pgid < 0) 2271 return posix_error(); 2272 return PyInt_FromLong((long)pgid); 2273} 2274#endif /* HAVE_TCGETPGRP */ 2275 2276 2277#ifdef HAVE_TCSETPGRP 2278static char posix_tcsetpgrp__doc__[] = 2279"tcsetpgrp(fd, pgid) -> None\n\ 2280Set the process group associated with the terminal given by a fd."; 2281 2282static PyObject * 2283posix_tcsetpgrp(self, args) 2284 PyObject *self; 2285 PyObject *args; 2286{ 2287 int fd, pgid; 2288 if (!PyArg_Parse(args, "(ii)", &fd, &pgid)) 2289 return NULL; 2290 if (tcsetpgrp(fd, pgid) < 0) 2291 return posix_error(); 2292 Py_INCREF(Py_None); 2293 return Py_None; 2294} 2295#endif /* HAVE_TCSETPGRP */ 2296 2297/* Functions acting on file descriptors */ 2298 2299static char posix_open__doc__[] = 2300"open(filename, flag [, mode=0777]) -> fd\n\ 2301Open a file (for low level IO)."; 2302 2303static PyObject * 2304posix_open(self, args) 2305 PyObject *self; 2306 PyObject *args; 2307{ 2308 char *file; 2309 int flag; 2310 int mode = 0777; 2311 int fd; 2312 if (!PyArg_ParseTuple(args, "si|i", &file, &flag, &mode)) 2313 return NULL; 2314 2315 Py_BEGIN_ALLOW_THREADS 2316 fd = open(file, flag, mode); 2317 Py_END_ALLOW_THREADS 2318 if (fd < 0) 2319 return posix_error_with_filename(file); 2320 return PyInt_FromLong((long)fd); 2321} 2322 2323 2324static char posix_close__doc__[] = 2325"close(fd) -> None\n\ 2326Close a file descriptor (for low level IO)."; 2327 2328static PyObject * 2329posix_close(self, args) 2330 PyObject *self; 2331 PyObject *args; 2332{ 2333 int fd, res; 2334 if (!PyArg_Parse(args, "i", &fd)) 2335 return NULL; 2336 Py_BEGIN_ALLOW_THREADS 2337 res = close(fd); 2338 Py_END_ALLOW_THREADS 2339 if (res < 0) 2340 return posix_error(); 2341 Py_INCREF(Py_None); 2342 return Py_None; 2343} 2344 2345 2346static char posix_dup__doc__[] = 2347"dup(fd) -> fd2\n\ 2348Return a duplicate of a file descriptor."; 2349 2350static PyObject * 2351posix_dup(self, args) 2352 PyObject *self; 2353 PyObject *args; 2354{ 2355 int fd; 2356 if (!PyArg_Parse(args, "i", &fd)) 2357 return NULL; 2358 Py_BEGIN_ALLOW_THREADS 2359 fd = dup(fd); 2360 Py_END_ALLOW_THREADS 2361 if (fd < 0) 2362 return posix_error(); 2363 return PyInt_FromLong((long)fd); 2364} 2365 2366 2367static char posix_dup2__doc__[] = 2368"dup2(fd, fd2) -> None\n\ 2369Duplicate file descriptor."; 2370 2371static PyObject * 2372posix_dup2(self, args) 2373 PyObject *self; 2374 PyObject *args; 2375{ 2376 int fd, fd2, res; 2377 if (!PyArg_Parse(args, "(ii)", &fd, &fd2)) 2378 return NULL; 2379 Py_BEGIN_ALLOW_THREADS 2380 res = dup2(fd, fd2); 2381 Py_END_ALLOW_THREADS 2382 if (res < 0) 2383 return posix_error(); 2384 Py_INCREF(Py_None); 2385 return Py_None; 2386} 2387 2388 2389static char posix_lseek__doc__[] = 2390"lseek(fd, pos, how) -> newpos\n\ 2391Set the current position of a file descriptor."; 2392 2393static PyObject * 2394posix_lseek(self, args) 2395 PyObject *self; 2396 PyObject *args; 2397{ 2398 int fd, how; 2399 off_t pos, res; 2400 PyObject *posobj; 2401 if (!PyArg_Parse(args, "(iOi)", &fd, &posobj, &how)) 2402 return NULL; 2403#ifdef SEEK_SET 2404 /* Turn 0, 1, 2 into SEEK_{SET,CUR,END} */ 2405 switch (how) { 2406 case 0: how = SEEK_SET; break; 2407 case 1: how = SEEK_CUR; break; 2408 case 2: how = SEEK_END; break; 2409 } 2410#endif /* SEEK_END */ 2411 2412#if !defined(HAVE_LARGEFILE_SUPPORT) 2413 pos = PyInt_AsLong(posobj); 2414#else 2415 pos = PyLong_Check(posobj) ? 2416 PyLong_AsLongLong(posobj) : PyInt_AsLong(posobj); 2417#endif 2418 if (PyErr_Occurred()) 2419 return NULL; 2420 2421 Py_BEGIN_ALLOW_THREADS 2422 res = lseek(fd, pos, how); 2423 Py_END_ALLOW_THREADS 2424 if (res < 0) 2425 return posix_error(); 2426 2427#if !defined(HAVE_LARGEFILE_SUPPORT) 2428 return PyInt_FromLong(res); 2429#else 2430 return PyLong_FromLongLong(res); 2431#endif 2432} 2433 2434 2435static char posix_read__doc__[] = 2436"read(fd, buffersize) -> string\n\ 2437Read a file descriptor."; 2438 2439static PyObject * 2440posix_read(self, args) 2441 PyObject *self; 2442 PyObject *args; 2443{ 2444 int fd, size, n; 2445 PyObject *buffer; 2446 if (!PyArg_Parse(args, "(ii)", &fd, &size)) 2447 return NULL; 2448 buffer = PyString_FromStringAndSize((char *)NULL, size); 2449 if (buffer == NULL) 2450 return NULL; 2451 Py_BEGIN_ALLOW_THREADS 2452 n = read(fd, PyString_AsString(buffer), size); 2453 Py_END_ALLOW_THREADS 2454 if (n < 0) { 2455 Py_DECREF(buffer); 2456 return posix_error(); 2457 } 2458 if (n != size) 2459 _PyString_Resize(&buffer, n); 2460 return buffer; 2461} 2462 2463 2464static char posix_write__doc__[] = 2465"write(fd, string) -> byteswritten\n\ 2466Write a string to a file descriptor."; 2467 2468static PyObject * 2469posix_write(self, args) 2470 PyObject *self; 2471 PyObject *args; 2472{ 2473 int fd, size; 2474 char *buffer; 2475 if (!PyArg_Parse(args, "(is#)", &fd, &buffer, &size)) 2476 return NULL; 2477 Py_BEGIN_ALLOW_THREADS 2478 size = write(fd, buffer, size); 2479 Py_END_ALLOW_THREADS 2480 if (size < 0) 2481 return posix_error(); 2482 return PyInt_FromLong((long)size); 2483} 2484 2485 2486static char posix_fstat__doc__[]= 2487"fstat(fd) -> (mode, ino, dev, nlink, uid, gid, size, atime, mtime, ctime)\n\ 2488Like stat(), but for an open file descriptor."; 2489 2490static PyObject * 2491posix_fstat(self, args) 2492 PyObject *self; 2493 PyObject *args; 2494{ 2495 int fd; 2496 struct stat st; 2497 int res; 2498 if (!PyArg_Parse(args, "i", &fd)) 2499 return NULL; 2500 Py_BEGIN_ALLOW_THREADS 2501 res = fstat(fd, &st); 2502 Py_END_ALLOW_THREADS 2503 if (res != 0) 2504 return posix_error(); 2505#if !defined(HAVE_LARGEFILE_SUPPORT) 2506 return Py_BuildValue("(llllllllll)", 2507 (long)st.st_mode, 2508 (long)st.st_ino, 2509 (long)st.st_dev, 2510 (long)st.st_nlink, 2511 (long)st.st_uid, 2512 (long)st.st_gid, 2513 (long)st.st_size, 2514 (long)st.st_atime, 2515 (long)st.st_mtime, 2516 (long)st.st_ctime); 2517#else 2518 return Py_BuildValue("(lLllllLlll)", 2519 (long)st.st_mode, 2520 (LONG_LONG)st.st_ino, 2521 (long)st.st_dev, 2522 (long)st.st_nlink, 2523 (long)st.st_uid, 2524 (long)st.st_gid, 2525 (LONG_LONG)st.st_size, 2526 (long)st.st_atime, 2527 (long)st.st_mtime, 2528 (long)st.st_ctime); 2529#endif 2530} 2531 2532 2533static char posix_fdopen__doc__[] = 2534"fdopen(fd, [, mode='r' [, bufsize]]) -> file_object\n\ 2535Return an open file object connected to a file descriptor."; 2536 2537static PyObject * 2538posix_fdopen(self, args) 2539 PyObject *self; 2540 PyObject *args; 2541{ 2542 extern int fclose Py_PROTO((FILE *)); 2543 int fd; 2544 char *mode = "r"; 2545 int bufsize = -1; 2546 FILE *fp; 2547 PyObject *f; 2548 if (!PyArg_ParseTuple(args, "i|si", &fd, &mode, &bufsize)) 2549 return NULL; 2550 2551 Py_BEGIN_ALLOW_THREADS 2552 fp = fdopen(fd, mode); 2553 Py_END_ALLOW_THREADS 2554 if (fp == NULL) 2555 return posix_error(); 2556 f = PyFile_FromFile(fp, "(fdopen)", mode, fclose); 2557 if (f != NULL) 2558 PyFile_SetBufSize(f, bufsize); 2559 return f; 2560} 2561 2562 2563#ifdef HAVE_PIPE 2564static char posix_pipe__doc__[] = 2565"pipe() -> (read_end, write_end)\n\ 2566Create a pipe."; 2567 2568static PyObject * 2569posix_pipe(self, args) 2570 PyObject *self; 2571 PyObject *args; 2572{ 2573#if defined(PYOS_OS2) 2574 HFILE read, write; 2575 APIRET rc; 2576 2577 if (!PyArg_Parse(args, "")) 2578 return NULL; 2579 2580 Py_BEGIN_ALLOW_THREADS 2581 rc = DosCreatePipe( &read, &write, 4096); 2582 Py_END_ALLOW_THREADS 2583 if (rc != NO_ERROR) 2584 return os2_error(rc); 2585 2586 return Py_BuildValue("(ii)", read, write); 2587#else 2588#if !defined(MS_WIN32) 2589 int fds[2]; 2590 int res; 2591 if (!PyArg_Parse(args, "")) 2592 return NULL; 2593 Py_BEGIN_ALLOW_THREADS 2594 res = pipe(fds); 2595 Py_END_ALLOW_THREADS 2596 if (res != 0) 2597 return posix_error(); 2598 return Py_BuildValue("(ii)", fds[0], fds[1]); 2599#else /* MS_WIN32 */ 2600 HANDLE read, write; 2601 int read_fd, write_fd; 2602 BOOL ok; 2603 if (!PyArg_Parse(args, "")) 2604 return NULL; 2605 Py_BEGIN_ALLOW_THREADS 2606 ok = CreatePipe(&read, &write, NULL, 0); 2607 Py_END_ALLOW_THREADS 2608 if (!ok) 2609 return posix_error(); 2610 read_fd = _open_osfhandle((long)read, 0); 2611 write_fd = _open_osfhandle((long)write, 1); 2612 return Py_BuildValue("(ii)", read_fd, write_fd); 2613#endif /* MS_WIN32 */ 2614#endif 2615} 2616#endif /* HAVE_PIPE */ 2617 2618 2619#ifdef HAVE_MKFIFO 2620static char posix_mkfifo__doc__[] = 2621"mkfifo(file, [, mode=0666]) -> None\n\ 2622Create a FIFO (a POSIX named pipe)."; 2623 2624static PyObject * 2625posix_mkfifo(self, args) 2626 PyObject *self; 2627 PyObject *args; 2628{ 2629 char *file; 2630 int mode = 0666; 2631 int res; 2632 if (!PyArg_ParseTuple(args, "s|i", &file, &mode)) 2633 return NULL; 2634 Py_BEGIN_ALLOW_THREADS 2635 res = mkfifo(file, mode); 2636 Py_END_ALLOW_THREADS 2637 if (res < 0) 2638 return posix_error(); 2639 Py_INCREF(Py_None); 2640 return Py_None; 2641} 2642#endif 2643 2644 2645#ifdef HAVE_FTRUNCATE 2646static char posix_ftruncate__doc__[] = 2647"ftruncate(fd, length) -> None\n\ 2648Truncate a file to a specified length."; 2649 2650static PyObject * 2651posix_ftruncate(self, args) 2652 PyObject *self; /* Not used */ 2653 PyObject *args; 2654{ 2655 int fd; 2656 off_t length; 2657 int res; 2658 PyObject *lenobj; 2659 2660 if (!PyArg_Parse(args, "(iO)", &fd, &lenobj)) 2661 return NULL; 2662 2663#if !defined(HAVE_LARGEFILE_SUPPORT) 2664 length = PyInt_AsLong(lenobj); 2665#else 2666 length = PyLong_Check(lenobj) ? 2667 PyLong_AsLongLong(lenobj) : PyInt_AsLong(lenobj); 2668#endif 2669 if (PyErr_Occurred()) 2670 return NULL; 2671 2672 Py_BEGIN_ALLOW_THREADS 2673 res = ftruncate(fd, length); 2674 Py_END_ALLOW_THREADS 2675 if (res < 0) { 2676 PyErr_SetFromErrno(PyExc_IOError); 2677 return NULL; 2678 } 2679 Py_INCREF(Py_None); 2680 return Py_None; 2681} 2682#endif 2683 2684#ifdef NeXT 2685#define HAVE_PUTENV 2686/* Steve Spicklemire got this putenv from NeXTAnswers */ 2687static int 2688putenv(char *newval) 2689{ 2690 extern char **environ; 2691 2692 static int firstTime = 1; 2693 char **ep; 2694 char *cp; 2695 int esiz; 2696 char *np; 2697 2698 if (!(np = strchr(newval, '='))) 2699 return 1; 2700 *np = '\0'; 2701 2702 /* look it up */ 2703 for (ep=environ ; *ep ; ep++) 2704 { 2705 /* this should always be true... */ 2706 if (cp = strchr(*ep, '=')) 2707 { 2708 *cp = '\0'; 2709 if (!strcmp(*ep, newval)) 2710 { 2711 /* got it! */ 2712 *cp = '='; 2713 break; 2714 } 2715 *cp = '='; 2716 } 2717 else 2718 { 2719 *np = '='; 2720 return 1; 2721 } 2722 } 2723 2724 *np = '='; 2725 if (*ep) 2726 { 2727 /* the string was already there: 2728 just replace it with the new one */ 2729 *ep = newval; 2730 return 0; 2731 } 2732 2733 /* expand environ by one */ 2734 for (esiz=2, ep=environ ; *ep ; ep++) 2735 esiz++; 2736 if (firstTime) 2737 { 2738 char **epp; 2739 char **newenv; 2740 if (!(newenv = malloc(esiz * sizeof(char *)))) 2741 return 1; 2742 2743 for (ep=environ, epp=newenv ; *ep ;) 2744 *epp++ = *ep++; 2745 *epp++ = newval; 2746 *epp = (char *) 0; 2747 environ = newenv; 2748 } 2749 else 2750 { 2751 if (!(environ = realloc(environ, esiz * sizeof(char *)))) 2752 return 1; 2753 environ[esiz - 2] = newval; 2754 environ[esiz - 1] = (char *) 0; 2755 firstTime = 0; 2756 } 2757 2758 return 0; 2759} 2760#endif /* NeXT */ 2761 2762 2763#ifdef HAVE_PUTENV 2764static char posix_putenv__doc__[] = 2765"putenv(key, value) -> None\n\ 2766Change or add an environment variable."; 2767 2768#ifdef __BEOS__ 2769/* We have putenv(), but not in the headers (as of PR2). - [cjh] */ 2770int putenv( const char *str ); 2771#endif 2772 2773static PyObject * 2774posix_putenv(self, args) 2775 PyObject *self; 2776 PyObject *args; 2777{ 2778 char *s1, *s2; 2779 char *new; 2780 2781 if (!PyArg_ParseTuple(args, "ss", &s1, &s2)) 2782 return NULL; 2783 2784#if defined(PYOS_OS2) 2785 if (stricmp(s1, "BEGINLIBPATH") == 0) { 2786 APIRET rc; 2787 2788 if (strlen(s2) == 0) /* If New Value is an Empty String */ 2789 s2 = NULL; /* Then OS/2 API Wants a NULL to Undefine It */ 2790 2791 rc = DosSetExtLIBPATH(s2, BEGIN_LIBPATH); 2792 if (rc != NO_ERROR) 2793 return os2_error(rc); 2794 2795 } else if (stricmp(s1, "ENDLIBPATH") == 0) { 2796 APIRET rc; 2797 2798 if (strlen(s2) == 0) /* If New Value is an Empty String */ 2799 s2 = NULL; /* Then OS/2 API Wants a NULL to Undefine It */ 2800 2801 rc = DosSetExtLIBPATH(s2, END_LIBPATH); 2802 if (rc != NO_ERROR) 2803 return os2_error(rc); 2804 } else { 2805#endif 2806 2807 /* XXX This leaks memory -- not easy to fix :-( */ 2808 if ((new = malloc(strlen(s1) + strlen(s2) + 2)) == NULL) 2809 return PyErr_NoMemory(); 2810 (void) sprintf(new, "%s=%s", s1, s2); 2811 if (putenv(new)) { 2812 posix_error(); 2813 return NULL; 2814 } 2815 2816#if defined(PYOS_OS2) 2817 } 2818#endif 2819 Py_INCREF(Py_None); 2820 return Py_None; 2821} 2822#endif /* putenv */ 2823 2824#ifdef HAVE_STRERROR 2825static char posix_strerror__doc__[] = 2826"strerror(code) -> string\n\ 2827Translate an error code to a message string."; 2828 2829PyObject * 2830posix_strerror(self, args) 2831 PyObject *self; 2832 PyObject *args; 2833{ 2834 int code; 2835 char *message; 2836 if (!PyArg_ParseTuple(args, "i", &code)) 2837 return NULL; 2838 message = strerror(code); 2839 if (message == NULL) { 2840 PyErr_SetString(PyExc_ValueError, 2841 "strerror code out of range"); 2842 return NULL; 2843 } 2844 return PyString_FromString(message); 2845} 2846#endif /* strerror */ 2847 2848 2849#ifdef HAVE_SYS_WAIT_H 2850 2851#ifdef WIFSTOPPED 2852static char posix_WIFSTOPPED__doc__[] = 2853"WIFSTOPPED(status) -> Boolean\n\ 2854See Unix documentation."; 2855 2856static PyObject * 2857posix_WIFSTOPPED(self, args) 2858 PyObject *self; 2859 PyObject *args; 2860{ 2861#ifdef UNION_WAIT 2862 union wait status; 2863#define status_i (status.w_status) 2864#else 2865 int status; 2866#define status_i status 2867#endif 2868 status_i = 0; 2869 2870 if (!PyArg_Parse(args, "i", &status_i)) 2871 { 2872 return NULL; 2873 } 2874 2875 return Py_BuildValue("i", WIFSTOPPED(status)); 2876} 2877#endif /* WIFSTOPPED */ 2878 2879#ifdef WIFSIGNALED 2880static char posix_WIFSIGNALED__doc__[] = 2881"WIFSIGNALED(status) -> Boolean\n\ 2882See Unix documentation."; 2883 2884static PyObject * 2885posix_WIFSIGNALED(self, args) 2886 PyObject *self; 2887 PyObject *args; 2888{ 2889#ifdef UNION_WAIT 2890 union wait status; 2891#define status_i (status.w_status) 2892#else 2893 int status; 2894#define status_i status 2895#endif 2896 status_i = 0; 2897 2898 if (!PyArg_Parse(args, "i", &status_i)) 2899 { 2900 return NULL; 2901 } 2902 2903 return Py_BuildValue("i", WIFSIGNALED(status)); 2904} 2905#endif /* WIFSIGNALED */ 2906 2907#ifdef WIFEXITED 2908static char posix_WIFEXITED__doc__[] = 2909"WIFEXITED(status) -> Boolean\n\ 2910See Unix documentation."; 2911 2912static PyObject * 2913posix_WIFEXITED(self, args) 2914 PyObject *self; 2915 PyObject *args; 2916{ 2917#ifdef UNION_WAIT 2918 union wait status; 2919#define status_i (status.w_status) 2920#else 2921 int status; 2922#define status_i status 2923#endif 2924 status_i = 0; 2925 2926 if (!PyArg_Parse(args, "i", &status_i)) 2927 { 2928 return NULL; 2929 } 2930 2931 return Py_BuildValue("i", WIFEXITED(status)); 2932} 2933#endif /* WIFEXITED */ 2934 2935#ifdef WEXITSTATUS 2936static char posix_WEXITSTATUS__doc__[] = 2937"WEXITSTATUS(status) -> integer\n\ 2938See Unix documentation."; 2939 2940static PyObject * 2941posix_WEXITSTATUS(self, args) 2942 PyObject *self; 2943 PyObject *args; 2944{ 2945#ifdef UNION_WAIT 2946 union wait status; 2947#define status_i (status.w_status) 2948#else 2949 int status; 2950#define status_i status 2951#endif 2952 status_i = 0; 2953 2954 if (!PyArg_Parse(args, "i", &status_i)) 2955 { 2956 return NULL; 2957 } 2958 2959 return Py_BuildValue("i", WEXITSTATUS(status)); 2960} 2961#endif /* WEXITSTATUS */ 2962 2963#ifdef WTERMSIG 2964static char posix_WTERMSIG__doc__[] = 2965"WTERMSIG(status) -> integer\n\ 2966See Unix documentation."; 2967 2968static PyObject * 2969posix_WTERMSIG(self, args) 2970 PyObject *self; 2971 PyObject *args; 2972{ 2973#ifdef UNION_WAIT 2974 union wait status; 2975#define status_i (status.w_status) 2976#else 2977 int status; 2978#define status_i status 2979#endif 2980 status_i = 0; 2981 2982 if (!PyArg_Parse(args, "i", &status_i)) 2983 { 2984 return NULL; 2985 } 2986 2987 return Py_BuildValue("i", WTERMSIG(status)); 2988} 2989#endif /* WTERMSIG */ 2990 2991#ifdef WSTOPSIG 2992static char posix_WSTOPSIG__doc__[] = 2993"WSTOPSIG(status) -> integer\n\ 2994See Unix documentation."; 2995 2996static PyObject * 2997posix_WSTOPSIG(self, args) 2998 PyObject *self; 2999 PyObject *args; 3000{ 3001#ifdef UNION_WAIT 3002 union wait status; 3003#define status_i (status.w_status) 3004#else 3005 int status; 3006#define status_i status 3007#endif 3008 status_i = 0; 3009 3010 if (!PyArg_Parse(args, "i", &status_i)) 3011 { 3012 return NULL; 3013 } 3014 3015 return Py_BuildValue("i", WSTOPSIG(status)); 3016} 3017#endif /* WSTOPSIG */ 3018 3019#endif /* HAVE_SYS_WAIT_H */ 3020 3021 3022#if defined(HAVE_FSTATVFS) 3023#include <sys/statvfs.h> 3024 3025static char posix_fstatvfs__doc__[] = 3026"fstatvfs(fd) -> \ 3027(bsize,frsize,blocks,bfree,bavail,files,ffree,favail,fsid,flag, namemax)\n\ 3028Perform an fstatvfs system call on the given fd."; 3029 3030static PyObject * 3031posix_fstatvfs(self, args) 3032 PyObject *self; 3033 PyObject *args; 3034{ 3035 int fd, res; 3036 struct statvfs st; 3037 if (!PyArg_ParseTuple(args, "i", &fd)) 3038 return NULL; 3039 Py_BEGIN_ALLOW_THREADS 3040 res = fstatvfs(fd, &st); 3041 Py_END_ALLOW_THREADS 3042 if (res != 0) 3043 return posix_error(); 3044#if !defined(HAVE_LARGEFILE_SUPPORT) 3045 return Py_BuildValue("(lllllllllll)", 3046 (long) st.f_bsize, 3047 (long) st.f_frsize, 3048 (long) st.f_blocks, 3049 (long) st.f_bfree, 3050 (long) st.f_bavail, 3051 (long) st.f_files, 3052 (long) st.f_ffree, 3053 (long) st.f_favail, 3054 (long) st.f_fsid, 3055 (long) st.f_flag, 3056 (long) st.f_namemax); 3057#else 3058 return Py_BuildValue("(llLLLLLLlll)", 3059 (long) st.f_bsize, 3060 (long) st.f_frsize, 3061 (LONG_LONG) st.f_blocks, 3062 (LONG_LONG) st.f_bfree, 3063 (LONG_LONG) st.f_bavail, 3064 (LONG_LONG) st.f_files, 3065 (LONG_LONG) st.f_ffree, 3066 (LONG_LONG) st.f_favail, 3067 (long) st.f_fsid, 3068 (long) st.f_flag, 3069 (long) st.f_namemax); 3070#endif 3071} 3072#endif /* HAVE_FSTATVFS */ 3073 3074 3075#if defined(HAVE_STATVFS) 3076#include <sys/statvfs.h> 3077 3078static char posix_statvfs__doc__[] = 3079"statvfs(path) -> \ 3080(bsize,frsize,blocks,bfree,bavail,files,ffree,favail,fsid,flag, namemax)\n\ 3081Perform a statvfs system call on the given path."; 3082 3083static PyObject * 3084posix_statvfs(self, args) 3085 PyObject *self; 3086 PyObject *args; 3087{ 3088 char *path; 3089 int res; 3090 struct statvfs st; 3091 if (!PyArg_ParseTuple(args, "s", &path)) 3092 return NULL; 3093 Py_BEGIN_ALLOW_THREADS 3094 res = statvfs(path, &st); 3095 Py_END_ALLOW_THREADS 3096 if (res != 0) 3097 return posix_error_with_filename(path); 3098#if !defined(HAVE_LARGEFILE_SUPPORT) 3099 return Py_BuildValue("(lllllllllll)", 3100 (long) st.f_bsize, 3101 (long) st.f_frsize, 3102 (long) st.f_blocks, 3103 (long) st.f_bfree, 3104 (long) st.f_bavail, 3105 (long) st.f_files, 3106 (long) st.f_ffree, 3107 (long) st.f_favail, 3108 (long) st.f_fsid, 3109 (long) st.f_flag, 3110 (long) st.f_namemax); 3111#else /* HAVE_LARGEFILE_SUPPORT */ 3112 return Py_BuildValue("(llLLLLLLlll)", 3113 (long) st.f_bsize, 3114 (long) st.f_frsize, 3115 (LONG_LONG) st.f_blocks, 3116 (LONG_LONG) st.f_bfree, 3117 (LONG_LONG) st.f_bavail, 3118 (LONG_LONG) st.f_files, 3119 (LONG_LONG) st.f_ffree, 3120 (LONG_LONG) st.f_favail, 3121 (long) st.f_fsid, 3122 (long) st.f_flag, 3123 (long) st.f_namemax); 3124#endif 3125} 3126#endif /* HAVE_STATVFS */ 3127 3128 3129static PyMethodDef posix_methods[] = { 3130 {"access", posix_access, 0, posix_access__doc__}, 3131#ifdef HAVE_TTYNAME 3132 {"ttyname", posix_ttyname, 0, posix_ttyname__doc__}, 3133#endif 3134 {"chdir", posix_chdir, 0, posix_chdir__doc__}, 3135 {"chmod", posix_chmod, 0, posix_chmod__doc__}, 3136#ifdef HAVE_CHOWN 3137 {"chown", posix_chown, 0, posix_chown__doc__}, 3138#endif /* HAVE_CHOWN */ 3139#ifdef HAVE_GETCWD 3140 {"getcwd", posix_getcwd, 0, posix_getcwd__doc__}, 3141#endif 3142#ifdef HAVE_LINK 3143 {"link", posix_link, 0, posix_link__doc__}, 3144#endif /* HAVE_LINK */ 3145 {"listdir", posix_listdir, 0, posix_listdir__doc__}, 3146 {"lstat", posix_lstat, 0, posix_lstat__doc__}, 3147 {"mkdir", posix_mkdir, 1, posix_mkdir__doc__}, 3148#ifdef HAVE_NICE 3149 {"nice", posix_nice, 0, posix_nice__doc__}, 3150#endif /* HAVE_NICE */ 3151#ifdef HAVE_READLINK 3152 {"readlink", posix_readlink, 0, posix_readlink__doc__}, 3153#endif /* HAVE_READLINK */ 3154 {"rename", posix_rename, 0, posix_rename__doc__}, 3155 {"rmdir", posix_rmdir, 0, posix_rmdir__doc__}, 3156 {"stat", posix_stat, 0, posix_stat__doc__}, 3157#ifdef HAVE_SYMLINK 3158 {"symlink", posix_symlink, 0, posix_symlink__doc__}, 3159#endif /* HAVE_SYMLINK */ 3160#ifdef HAVE_SYSTEM 3161 {"system", posix_system, 0, posix_system__doc__}, 3162#endif 3163 {"umask", posix_umask, 0, posix_umask__doc__}, 3164#ifdef HAVE_UNAME 3165 {"uname", posix_uname, 0, posix_uname__doc__}, 3166#endif /* HAVE_UNAME */ 3167 {"unlink", posix_unlink, 0, posix_unlink__doc__}, 3168 {"remove", posix_unlink, 0, posix_remove__doc__}, 3169 {"utime", posix_utime, 0, posix_utime__doc__}, 3170#ifdef HAVE_TIMES 3171 {"times", posix_times, 0, posix_times__doc__}, 3172#endif /* HAVE_TIMES */ 3173 {"_exit", posix__exit, 0, posix__exit__doc__}, 3174#ifdef HAVE_EXECV 3175 {"execv", posix_execv, 0, posix_execv__doc__}, 3176 {"execve", posix_execve, 0, posix_execve__doc__}, 3177#endif /* HAVE_EXECV */ 3178#ifdef HAVE_SPAWNV 3179 {"spawnv", posix_spawnv, 0, posix_spawnv__doc__}, 3180 {"spawnve", posix_spawnve, 0, posix_spawnve__doc__}, 3181#endif /* HAVE_SPAWNV */ 3182#ifdef HAVE_FORK 3183 {"fork", posix_fork, 0, posix_fork__doc__}, 3184#endif /* HAVE_FORK */ 3185#ifdef HAVE_GETEGID 3186 {"getegid", posix_getegid, 0, posix_getegid__doc__}, 3187#endif /* HAVE_GETEGID */ 3188#ifdef HAVE_GETEUID 3189 {"geteuid", posix_geteuid, 0, posix_geteuid__doc__}, 3190#endif /* HAVE_GETEUID */ 3191#ifdef HAVE_GETGID 3192 {"getgid", posix_getgid, 0, posix_getgid__doc__}, 3193#endif /* HAVE_GETGID */ 3194 {"getpid", posix_getpid, 0, posix_getpid__doc__}, 3195#ifdef HAVE_GETPGRP 3196 {"getpgrp", posix_getpgrp, 0, posix_getpgrp__doc__}, 3197#endif /* HAVE_GETPGRP */ 3198#ifdef HAVE_GETPPID 3199 {"getppid", posix_getppid, 0, posix_getppid__doc__}, 3200#endif /* HAVE_GETPPID */ 3201#ifdef HAVE_GETUID 3202 {"getuid", posix_getuid, 0, posix_getuid__doc__}, 3203#endif /* HAVE_GETUID */ 3204#ifdef HAVE_KILL 3205 {"kill", posix_kill, 0, posix_kill__doc__}, 3206#endif /* HAVE_KILL */ 3207#ifdef HAVE_PLOCK 3208 {"plock", posix_plock, 0, posix_plock__doc__}, 3209#endif /* HAVE_PLOCK */ 3210#ifdef HAVE_POPEN 3211 {"popen", posix_popen, 1, posix_popen__doc__}, 3212#endif /* HAVE_POPEN */ 3213#ifdef HAVE_SETUID 3214 {"setuid", posix_setuid, 0, posix_setuid__doc__}, 3215#endif /* HAVE_SETUID */ 3216#ifdef HAVE_SETGID 3217 {"setgid", posix_setgid, 0, posix_setgid__doc__}, 3218#endif /* HAVE_SETGID */ 3219#ifdef HAVE_SETPGRP 3220 {"setpgrp", posix_setpgrp, 0, posix_setpgrp__doc__}, 3221#endif /* HAVE_SETPGRP */ 3222#ifdef HAVE_WAIT 3223 {"wait", posix_wait, 0, posix_wait__doc__}, 3224#endif /* HAVE_WAIT */ 3225#ifdef HAVE_WAITPID 3226 {"waitpid", posix_waitpid, 0, posix_waitpid__doc__}, 3227#endif /* HAVE_WAITPID */ 3228#ifdef HAVE_SETSID 3229 {"setsid", posix_setsid, 0, posix_setsid__doc__}, 3230#endif /* HAVE_SETSID */ 3231#ifdef HAVE_SETPGID 3232 {"setpgid", posix_setpgid, 0, posix_setpgid__doc__}, 3233#endif /* HAVE_SETPGID */ 3234#ifdef HAVE_TCGETPGRP 3235 {"tcgetpgrp", posix_tcgetpgrp, 0, posix_tcgetpgrp__doc__}, 3236#endif /* HAVE_TCGETPGRP */ 3237#ifdef HAVE_TCSETPGRP 3238 {"tcsetpgrp", posix_tcsetpgrp, 0, posix_tcsetpgrp__doc__}, 3239#endif /* HAVE_TCSETPGRP */ 3240 {"open", posix_open, 1, posix_open__doc__}, 3241 {"close", posix_close, 0, posix_close__doc__}, 3242 {"dup", posix_dup, 0, posix_dup__doc__}, 3243 {"dup2", posix_dup2, 0, posix_dup2__doc__}, 3244 {"lseek", posix_lseek, 0, posix_lseek__doc__}, 3245 {"read", posix_read, 0, posix_read__doc__}, 3246 {"write", posix_write, 0, posix_write__doc__}, 3247 {"fstat", posix_fstat, 0, posix_fstat__doc__}, 3248 {"fdopen", posix_fdopen, 1, posix_fdopen__doc__}, 3249#ifdef HAVE_PIPE 3250 {"pipe", posix_pipe, 0, posix_pipe__doc__}, 3251#endif 3252#ifdef HAVE_MKFIFO 3253 {"mkfifo", posix_mkfifo, 1, posix_mkfifo__doc__}, 3254#endif 3255#ifdef HAVE_FTRUNCATE 3256 {"ftruncate", posix_ftruncate, 1, posix_ftruncate__doc__}, 3257#endif 3258#ifdef HAVE_PUTENV 3259 {"putenv", posix_putenv, 1, posix_putenv__doc__}, 3260#endif 3261#ifdef HAVE_STRERROR 3262 {"strerror", posix_strerror, 1, posix_strerror__doc__}, 3263#endif 3264#ifdef HAVE_FSYNC 3265 {"fsync", posix_fsync, 0, posix_fsync__doc__}, 3266#endif 3267#ifdef HAVE_FDATASYNC 3268 {"fdatasync", posix_fdatasync, 0, posix_fdatasync__doc__}, 3269#endif 3270#ifdef HAVE_SYS_WAIT_H 3271#ifdef WIFSTOPPED 3272 {"WIFSTOPPED", posix_WIFSTOPPED, 0, posix_WIFSTOPPED__doc__}, 3273#endif /* WIFSTOPPED */ 3274#ifdef WIFSIGNALED 3275 {"WIFSIGNALED", posix_WIFSIGNALED, 0, posix_WIFSIGNALED__doc__}, 3276#endif /* WIFSIGNALED */ 3277#ifdef WIFEXITED 3278 {"WIFEXITED", posix_WIFEXITED, 0, posix_WIFEXITED__doc__}, 3279#endif /* WIFEXITED */ 3280#ifdef WEXITSTATUS 3281 {"WEXITSTATUS", posix_WEXITSTATUS, 0, posix_WEXITSTATUS__doc__}, 3282#endif /* WEXITSTATUS */ 3283#ifdef WTERMSIG 3284 {"WTERMSIG", posix_WTERMSIG, 0, posix_WTERMSIG__doc__}, 3285#endif /* WTERMSIG */ 3286#ifdef WSTOPSIG 3287 {"WSTOPSIG", posix_WSTOPSIG, 0, posix_WSTOPSIG__doc__}, 3288#endif /* WSTOPSIG */ 3289#endif /* HAVE_SYS_WAIT_H */ 3290#ifdef HAVE_FSTATVFS 3291 {"fstatvfs", posix_fstatvfs, 1, posix_fstatvfs__doc__}, 3292#endif 3293#ifdef HAVE_STATVFS 3294 {"statvfs", posix_statvfs, 1, posix_statvfs__doc__}, 3295#endif 3296 {NULL, NULL} /* Sentinel */ 3297}; 3298 3299 3300static int 3301ins(d, symbol, value) 3302 PyObject* d; 3303 char* symbol; 3304 long value; 3305{ 3306 PyObject* v = PyInt_FromLong(value); 3307 if (!v || PyDict_SetItemString(d, symbol, v) < 0) 3308 return -1; /* triggers fatal error */ 3309 3310 Py_DECREF(v); 3311 return 0; 3312} 3313 3314#if defined(PYOS_OS2) 3315/* Insert Platform-Specific Constant Values (Strings & Numbers) of Common Use */ 3316static int insertvalues(PyObject *d) 3317{ 3318 APIRET rc; 3319 ULONG values[QSV_MAX+1]; 3320 PyObject *v; 3321 char *ver, tmp[10]; 3322 3323 Py_BEGIN_ALLOW_THREADS 3324 rc = DosQuerySysInfo(1, QSV_MAX, &values[1], sizeof(values)); 3325 Py_END_ALLOW_THREADS 3326 3327 if (rc != NO_ERROR) { 3328 os2_error(rc); 3329 return -1; 3330 } 3331 3332 if (ins(d, "meminstalled", values[QSV_TOTPHYSMEM])) return -1; 3333 if (ins(d, "memkernel", values[QSV_TOTRESMEM])) return -1; 3334 if (ins(d, "memvirtual", values[QSV_TOTAVAILMEM])) return -1; 3335 if (ins(d, "maxpathlen", values[QSV_MAX_PATH_LENGTH])) return -1; 3336 if (ins(d, "maxnamelen", values[QSV_MAX_COMP_LENGTH])) return -1; 3337 if (ins(d, "revision", values[QSV_VERSION_REVISION])) return -1; 3338 if (ins(d, "timeslice", values[QSV_MIN_SLICE])) return -1; 3339 3340 switch (values[QSV_VERSION_MINOR]) { 3341 case 0: ver = "2.00"; break; 3342 case 10: ver = "2.10"; break; 3343 case 11: ver = "2.11"; break; 3344 case 30: ver = "3.00"; break; 3345 case 40: ver = "4.00"; break; 3346 case 50: ver = "5.00"; break; 3347 default: 3348 sprintf(tmp, "%d-%d", values[QSV_VERSION_MAJOR], 3349 values[QSV_VERSION_MINOR]); 3350 ver = &tmp[0]; 3351 } 3352 3353 /* Add Indicator of the Version of the Operating System */ 3354 v = PyString_FromString(ver); 3355 if (!v || PyDict_SetItemString(d, "version", v) < 0) 3356 return -1; 3357 Py_DECREF(v); 3358 3359 /* Add Indicator of Which Drive was Used to Boot the System */ 3360 tmp[0] = 'A' + values[QSV_BOOT_DRIVE] - 1; 3361 tmp[1] = ':'; 3362 tmp[2] = '\0'; 3363 3364 v = PyString_FromString(tmp); 3365 if (!v || PyDict_SetItemString(d, "bootdrive", v) < 0) 3366 return -1; 3367 Py_DECREF(v); 3368 3369 return 0; 3370} 3371#endif 3372 3373static int 3374all_ins(d) 3375 PyObject* d; 3376{ 3377#ifdef F_OK 3378 if (ins(d, "F_OK", (long)F_OK)) return -1; 3379#endif 3380#ifdef R_OK 3381 if (ins(d, "R_OK", (long)R_OK)) return -1; 3382#endif 3383#ifdef W_OK 3384 if (ins(d, "W_OK", (long)W_OK)) return -1; 3385#endif 3386#ifdef X_OK 3387 if (ins(d, "X_OK", (long)X_OK)) return -1; 3388#endif 3389#ifdef WNOHANG 3390 if (ins(d, "WNOHANG", (long)WNOHANG)) return -1; 3391#endif 3392#ifdef O_RDONLY 3393 if (ins(d, "O_RDONLY", (long)O_RDONLY)) return -1; 3394#endif 3395#ifdef O_WRONLY 3396 if (ins(d, "O_WRONLY", (long)O_WRONLY)) return -1; 3397#endif 3398#ifdef O_RDWR 3399 if (ins(d, "O_RDWR", (long)O_RDWR)) return -1; 3400#endif 3401#ifdef O_NDELAY 3402 if (ins(d, "O_NDELAY", (long)O_NDELAY)) return -1; 3403#endif 3404#ifdef O_NONBLOCK 3405 if (ins(d, "O_NONBLOCK", (long)O_NONBLOCK)) return -1; 3406#endif 3407#ifdef O_APPEND 3408 if (ins(d, "O_APPEND", (long)O_APPEND)) return -1; 3409#endif 3410#ifdef O_DSYNC 3411 if (ins(d, "O_DSYNC", (long)O_DSYNC)) return -1; 3412#endif 3413#ifdef O_RSYNC 3414 if (ins(d, "O_RSYNC", (long)O_RSYNC)) return -1; 3415#endif 3416#ifdef O_SYNC 3417 if (ins(d, "O_SYNC", (long)O_SYNC)) return -1; 3418#endif 3419#ifdef O_NOCTTY 3420 if (ins(d, "O_NOCTTY", (long)O_NOCTTY)) return -1; 3421#endif 3422#ifdef O_CREAT 3423 if (ins(d, "O_CREAT", (long)O_CREAT)) return -1; 3424#endif 3425#ifdef O_EXCL 3426 if (ins(d, "O_EXCL", (long)O_EXCL)) return -1; 3427#endif 3428#ifdef O_TRUNC 3429 if (ins(d, "O_TRUNC", (long)O_TRUNC)) return -1; 3430#endif 3431#ifdef O_BINARY 3432 if (ins(d, "O_BINARY", (long)O_BINARY)) return -1; 3433#endif 3434#ifdef O_TEXT 3435 if (ins(d, "O_TEXT", (long)O_TEXT)) return -1; 3436#endif 3437 3438#ifdef HAVE_SPAWNV 3439 if (ins(d, "_P_WAIT", (long)_P_WAIT)) return -1; 3440 if (ins(d, "_P_NOWAIT", (long)_P_NOWAIT)) return -1; 3441 if (ins(d, "_P_OVERLAY", (long)_OLD_P_OVERLAY)) return -1; 3442 if (ins(d, "_P_NOWAITO", (long)_P_NOWAITO)) return -1; 3443 if (ins(d, "_P_DETACH", (long)_P_DETACH)) return -1; 3444#endif 3445 3446#if defined(PYOS_OS2) 3447 if (insertvalues(d)) return -1; 3448#endif 3449 return 0; 3450} 3451 3452 3453#if ( defined(_MSC_VER) || defined(__WATCOMC__) ) && !defined(__QNX__) 3454#define INITFUNC initnt 3455#define MODNAME "nt" 3456#else 3457#if defined(PYOS_OS2) 3458#define INITFUNC initos2 3459#define MODNAME "os2" 3460#else 3461#define INITFUNC initposix 3462#define MODNAME "posix" 3463#endif 3464#endif 3465 3466DL_EXPORT(void) 3467INITFUNC() 3468{ 3469 PyObject *m, *d, *v; 3470 3471 m = Py_InitModule4(MODNAME, 3472 posix_methods, 3473 posix__doc__, 3474 (PyObject *)NULL, 3475 PYTHON_API_VERSION); 3476 d = PyModule_GetDict(m); 3477 3478 /* Initialize environ dictionary */ 3479 v = convertenviron(); 3480 if (v == NULL || PyDict_SetItemString(d, "environ", v) != 0) 3481 return; 3482 Py_DECREF(v); 3483 3484 if (all_ins(d)) 3485 return; 3486 3487 Py_INCREF(PyExc_OSError); 3488 PosixError = PyExc_OSError; 3489 PyDict_SetItemString(d, "error", PosixError); 3490} 3491