From ae3d4616ed9c19a29d656193254657f93d612fa2 Mon Sep 17 00:00:00 2001 From: Waldemar Brodkorb Date: Wed, 27 Nov 2013 21:30:43 +0100 Subject: try to fixup mesalib compile, it needs libxml2 python module --- package/python2/files/posixmodule.c | 9365 ----------------------------------- 1 file changed, 9365 deletions(-) delete mode 100644 package/python2/files/posixmodule.c (limited to 'package/python2/files/posixmodule.c') diff --git a/package/python2/files/posixmodule.c b/package/python2/files/posixmodule.c deleted file mode 100644 index 312861b65..000000000 --- a/package/python2/files/posixmodule.c +++ /dev/null @@ -1,9365 +0,0 @@ - -/* POSIX module implementation */ - -/* This file is also used for Windows NT/MS-Win and OS/2. In that case the - module actually calls itself 'nt' or 'os2', not 'posix', and a few - functions are either unimplemented or implemented differently. The source - assumes that for Windows NT, the macro 'MS_WINDOWS' is defined independent - of the compiler used. Different compilers define their own feature - test macro, e.g. '__BORLANDC__' or '_MSC_VER'. For OS/2, the compiler - independent macro PYOS_OS2 should be defined. On OS/2 the default - compiler is assumed to be IBM's VisualAge C++ (VACPP). PYCC_GCC is used - as the compiler specific macro for the EMX port of gcc to OS/2. */ - -/* See also ../Dos/dosmodule.c */ - -#ifdef __APPLE__ - /* - * Step 1 of support for weak-linking a number of symbols existing on - * OSX 10.4 and later, see the comment in the #ifdef __APPLE__ block - * at the end of this file for more information. - */ -# pragma weak lchown -# pragma weak statvfs -# pragma weak fstatvfs - -#endif /* __APPLE__ */ - -#define PY_SSIZE_T_CLEAN - -#include "Python.h" -#include "structseq.h" - -#if defined(__VMS) -# include -#endif /* defined(__VMS) */ - -#ifdef __cplusplus -extern "C" { -#endif - -PyDoc_STRVAR(posix__doc__, -"This module provides access to operating system functionality that is\n\ -standardized by the C Standard and the POSIX standard (a thinly\n\ -disguised Unix interface). Refer to the library manual and\n\ -corresponding Unix manual entries for more information on calls."); - -#ifndef Py_USING_UNICODE -/* This is used in signatures of functions. */ -#define Py_UNICODE void -#endif - -#if defined(PYOS_OS2) -#define INCL_DOS -#define INCL_DOSERRORS -#define INCL_DOSPROCESS -#define INCL_NOPMAPI -#include -#if defined(PYCC_GCC) -#include -#include -#include -#include -#endif -#include "osdefs.h" -#endif - -#ifdef HAVE_SYS_TYPES_H -#include -#endif /* HAVE_SYS_TYPES_H */ - -#ifdef HAVE_SYS_STAT_H -#include -#endif /* HAVE_SYS_STAT_H */ - -#ifdef HAVE_SYS_WAIT_H -#include /* For WNOHANG */ -#endif - -#ifdef HAVE_SIGNAL_H -#include -#endif - -#ifdef HAVE_FCNTL_H -#include -#endif /* HAVE_FCNTL_H */ - -#ifdef HAVE_GRP_H -#include -#endif - -#ifdef HAVE_SYSEXITS_H -#include -#endif /* HAVE_SYSEXITS_H */ - -#ifdef HAVE_SYS_LOADAVG_H -#include -#endif - -/* Various compilers have only certain posix functions */ -/* XXX Gosh I wish these were all moved into pyconfig.h */ -#if defined(PYCC_VACPP) && defined(PYOS_OS2) -#include -#else -#if defined(__WATCOMC__) && !defined(__QNX__) /* Watcom compiler */ -#define HAVE_GETCWD 1 -#define HAVE_OPENDIR 1 -#define HAVE_SYSTEM 1 -#if defined(__OS2__) -#define HAVE_EXECV 1 -#define HAVE_WAIT 1 -#endif -#include -#else -#ifdef __BORLANDC__ /* Borland compiler */ -#define HAVE_EXECV 1 -#define HAVE_GETCWD 1 -#define HAVE_OPENDIR 1 -#define HAVE_PIPE 1 -#define HAVE_POPEN 1 -#define HAVE_SYSTEM 1 -#define HAVE_WAIT 1 -#else -#ifdef _MSC_VER /* Microsoft compiler */ -#define HAVE_GETCWD 1 -#define HAVE_SPAWNV 1 -#define HAVE_EXECV 1 -#define HAVE_PIPE 1 -#define HAVE_POPEN 1 -#define HAVE_SYSTEM 1 -#define HAVE_CWAIT 1 -#define HAVE_FSYNC 1 -#define fsync _commit -#else -#if defined(PYOS_OS2) && defined(PYCC_GCC) || defined(__VMS) -/* Everything needed is defined in PC/os2emx/pyconfig.h or vms/pyconfig.h */ -#else /* all other compilers */ -/* Unix functions that the configure script doesn't check for */ -#define HAVE_EXECV 1 -#define HAVE_FORK 1 -#if defined(__USLC__) && defined(__SCO_VERSION__) /* SCO UDK Compiler */ -#define HAVE_FORK1 1 -#endif -#define HAVE_GETCWD 1 -#define HAVE_GETEGID 1 -#define HAVE_GETEUID 1 -#define HAVE_GETGID 1 -#define HAVE_GETPPID 1 -#define HAVE_GETUID 1 -#define HAVE_KILL 1 -#define HAVE_OPENDIR 1 -#define HAVE_PIPE 1 -#ifndef __rtems__ -#define HAVE_POPEN 1 -#endif -#define HAVE_SYSTEM 1 -#define HAVE_WAIT 1 -#define HAVE_TTYNAME 1 -#endif /* PYOS_OS2 && PYCC_GCC && __VMS */ -#endif /* _MSC_VER */ -#endif /* __BORLANDC__ */ -#endif /* ! __WATCOMC__ || __QNX__ */ -#endif /* ! __IBMC__ */ - -#ifndef _MSC_VER - -#if defined(__sgi)&&_COMPILER_VERSION>=700 -/* declare ctermid_r if compiling with MIPSPro 7.x in ANSI C mode - (default) */ -extern char *ctermid_r(char *); -#endif - -#ifndef HAVE_UNISTD_H -#if defined(PYCC_VACPP) -extern int mkdir(char *); -#else -#if ( defined(__WATCOMC__) || defined(_MSC_VER) ) && !defined(__QNX__) -extern int mkdir(const char *); -#else -extern int mkdir(const char *, mode_t); -#endif -#endif -#if defined(__IBMC__) || defined(__IBMCPP__) -extern int chdir(char *); -extern int rmdir(char *); -#else -extern int chdir(const char *); -extern int rmdir(const char *); -#endif -#ifdef __BORLANDC__ -extern int chmod(const char *, int); -#else -extern int chmod(const char *, mode_t); -#endif -/*#ifdef HAVE_FCHMOD -extern int fchmod(int, mode_t); -#endif*/ -/*#ifdef HAVE_LCHMOD -extern int lchmod(const char *, mode_t); -#endif*/ -extern int chown(const char *, uid_t, gid_t); -extern char *getcwd(char *, int); -extern char *strerror(int); -extern int link(const char *, const char *); -extern int rename(const char *, const char *); -extern int stat(const char *, struct stat *); -extern int unlink(const char *); -extern int pclose(FILE *); -#ifdef HAVE_SYMLINK -extern int symlink(const char *, const char *); -#endif /* HAVE_SYMLINK */ -#ifdef HAVE_LSTAT -extern int lstat(const char *, struct stat *); -#endif /* HAVE_LSTAT */ -#endif /* !HAVE_UNISTD_H */ - -#endif /* !_MSC_VER */ - -#ifdef HAVE_UTIME_H -#include -#endif /* HAVE_UTIME_H */ - -#ifdef HAVE_SYS_UTIME_H -#include -#define HAVE_UTIME_H /* pretend we do for the rest of this file */ -#endif /* HAVE_SYS_UTIME_H */ - -#ifdef HAVE_SYS_TIMES_H -#include -#endif /* HAVE_SYS_TIMES_H */ - -#ifdef HAVE_SYS_PARAM_H -#include -#endif /* HAVE_SYS_PARAM_H */ - -#ifdef HAVE_SYS_UTSNAME_H -#include -#endif /* HAVE_SYS_UTSNAME_H */ - -#ifdef HAVE_DIRENT_H -#include -#define NAMLEN(dirent) strlen((dirent)->d_name) -#else -#if defined(__WATCOMC__) && !defined(__QNX__) -#include -#define NAMLEN(dirent) strlen((dirent)->d_name) -#else -#define dirent direct -#define NAMLEN(dirent) (dirent)->d_namlen -#endif -#ifdef HAVE_SYS_NDIR_H -#include -#endif -#ifdef HAVE_SYS_DIR_H -#include -#endif -#ifdef HAVE_NDIR_H -#include -#endif -#endif - -#ifdef _MSC_VER -#ifdef HAVE_DIRECT_H -#include -#endif -#ifdef HAVE_IO_H -#include -#endif -#ifdef HAVE_PROCESS_H -#include -#endif -#include "osdefs.h" -#include -#include -#include /* for ShellExecute() */ -#define popen _popen -#define pclose _pclose -#endif /* _MSC_VER */ - -#if defined(PYCC_VACPP) && defined(PYOS_OS2) -#include -#endif /* OS2 */ - -#ifndef MAXPATHLEN -#if defined(PATH_MAX) && PATH_MAX > 1024 -#define MAXPATHLEN PATH_MAX -#else -#define MAXPATHLEN 1024 -#endif -#endif /* MAXPATHLEN */ - -#ifdef UNION_WAIT -/* Emulate some macros on systems that have a union instead of macros */ - -#ifndef WIFEXITED -#define WIFEXITED(u_wait) (!(u_wait).w_termsig && !(u_wait).w_coredump) -#endif - -#ifndef WEXITSTATUS -#define WEXITSTATUS(u_wait) (WIFEXITED(u_wait)?((u_wait).w_retcode):-1) -#endif - -#ifndef WTERMSIG -#define WTERMSIG(u_wait) ((u_wait).w_termsig) -#endif - -#define WAIT_TYPE union wait -#define WAIT_STATUS_INT(s) (s.w_status) - -#else /* !UNION_WAIT */ -#define WAIT_TYPE int -#define WAIT_STATUS_INT(s) (s) -#endif /* UNION_WAIT */ - -/* Issue #1983: pid_t can be longer than a C long on some systems */ -#if !defined(SIZEOF_PID_T) || SIZEOF_PID_T == SIZEOF_INT -#define PARSE_PID "i" -#define PyLong_FromPid PyInt_FromLong -#define PyLong_AsPid PyInt_AsLong -#elif SIZEOF_PID_T == SIZEOF_LONG -#define PARSE_PID "l" -#define PyLong_FromPid PyInt_FromLong -#define PyLong_AsPid PyInt_AsLong -#elif defined(SIZEOF_LONG_LONG) && SIZEOF_PID_T == SIZEOF_LONG_LONG -#define PARSE_PID "L" -#define PyLong_FromPid PyLong_FromLongLong -#define PyLong_AsPid PyInt_AsLongLong -#else -#error "sizeof(pid_t) is neither sizeof(int), sizeof(long) or sizeof(long long)" -#endif /* SIZEOF_PID_T */ - -/* Don't use the "_r" form if we don't need it (also, won't have a - prototype for it, at least on Solaris -- maybe others as well?). */ -#if defined(HAVE_CTERMID_R) && defined(WITH_THREAD) -#define USE_CTERMID_R -#endif - -#if defined(HAVE_TMPNAM_R) && defined(WITH_THREAD) -#define USE_TMPNAM_R -#endif - -/* choose the appropriate stat and fstat functions and return structs */ -#undef STAT -#if defined(MS_WIN64) || defined(MS_WINDOWS) -# define STAT win32_stat -# define FSTAT win32_fstat -# define STRUCT_STAT struct win32_stat -#else -# define STAT stat -# define FSTAT fstat -# define STRUCT_STAT struct stat -#endif - -#if defined(MAJOR_IN_MKDEV) -#include -#else -#if defined(MAJOR_IN_SYSMACROS) -#include -#endif -#if defined(HAVE_MKNOD) && defined(HAVE_SYS_MKDEV_H) -#include -#endif -#endif - -#if defined _MSC_VER && _MSC_VER >= 1400 -/* Microsoft CRT in VS2005 and higher will verify that a filehandle is - * valid and throw an assertion if it isn't. - * Normally, an invalid fd is likely to be a C program error and therefore - * an assertion can be useful, but it does contradict the POSIX standard - * which for write(2) states: - * "Otherwise, -1 shall be returned and errno set to indicate the error." - * "[EBADF] The fildes argument is not a valid file descriptor open for - * writing." - * Furthermore, python allows the user to enter any old integer - * as a fd and should merely raise a python exception on error. - * The Microsoft CRT doesn't provide an official way to check for the - * validity of a file descriptor, but we can emulate its internal behaviour - * by using the exported __pinfo data member and knowledge of the - * internal structures involved. - * The structures below must be updated for each version of visual studio - * according to the file internal.h in the CRT source, until MS comes - * up with a less hacky way to do this. - * (all of this is to avoid globally modifying the CRT behaviour using - * _set_invalid_parameter_handler() and _CrtSetReportMode()) - */ -/* The actual size of the structure is determined at runtime. - * Only the first items must be present. - */ -typedef struct { - intptr_t osfhnd; - char osfile; -} my_ioinfo; - -extern __declspec(dllimport) char * __pioinfo[]; -#define IOINFO_L2E 5 -#define IOINFO_ARRAY_ELTS (1 << IOINFO_L2E) -#define IOINFO_ARRAYS 64 -#define _NHANDLE_ (IOINFO_ARRAYS * IOINFO_ARRAY_ELTS) -#define FOPEN 0x01 -#define _NO_CONSOLE_FILENO (intptr_t)-2 - -/* This function emulates what the windows CRT does to validate file handles */ -int -_PyVerify_fd(int fd) -{ - const int i1 = fd >> IOINFO_L2E; - const int i2 = fd & ((1 << IOINFO_L2E) - 1); - - static int sizeof_ioinfo = 0; - - /* Determine the actual size of the ioinfo structure, - * as used by the CRT loaded in memory - */ - if (sizeof_ioinfo == 0 && __pioinfo[0] != NULL) { - sizeof_ioinfo = _msize(__pioinfo[0]) / IOINFO_ARRAY_ELTS; - } - if (sizeof_ioinfo == 0) { - /* This should not happen... */ - goto fail; - } - - /* See that it isn't a special CLEAR fileno */ - if (fd != _NO_CONSOLE_FILENO) { - /* Microsoft CRT would check that 0<=fd<_nhandle but we can't do that. Instead - * we check pointer validity and other info - */ - if (0 <= i1 && i1 < IOINFO_ARRAYS && __pioinfo[i1] != NULL) { - /* finally, check that the file is open */ - my_ioinfo* info = (my_ioinfo*)(__pioinfo[i1] + i2 * sizeof_ioinfo); - if (info->osfile & FOPEN) { - return 1; - } - } - } - fail: - errno = EBADF; - return 0; -} - -/* the special case of checking dup2. The target fd must be in a sensible range */ -static int -_PyVerify_fd_dup2(int fd1, int fd2) -{ - if (!_PyVerify_fd(fd1)) - return 0; - if (fd2 == _NO_CONSOLE_FILENO) - return 0; - if ((unsigned)fd2 < _NHANDLE_) - return 1; - else - return 0; -} -#else -/* dummy version. _PyVerify_fd() is already defined in fileobject.h */ -#define _PyVerify_fd_dup2(A, B) (1) -#endif - -/* Return a dictionary corresponding to the POSIX environment table */ -#ifdef WITH_NEXT_FRAMEWORK -/* On Darwin/MacOSX a shared library or framework has no access to -** environ directly, we must obtain it with _NSGetEnviron(). -*/ -#include -static char **environ; -#elif !defined(_MSC_VER) && ( !defined(__WATCOMC__) || defined(__QNX__) ) -extern char **environ; -#endif /* !_MSC_VER */ - -static PyObject * -convertenviron(void) -{ - PyObject *d; - char **e; -#if defined(PYOS_OS2) - APIRET rc; - char buffer[1024]; /* OS/2 Provides a Documented Max of 1024 Chars */ -#endif - d = PyDict_New(); - if (d == NULL) - return NULL; -#ifdef WITH_NEXT_FRAMEWORK - if (environ == NULL) - environ = *_NSGetEnviron(); -#endif - if (environ == NULL) - return d; - /* This part ignores errors */ - for (e = environ; *e != NULL; e++) { - PyObject *k; - PyObject *v; - char *p = strchr(*e, '='); - if (p == NULL) - continue; - k = PyString_FromStringAndSize(*e, (int)(p-*e)); - if (k == NULL) { - PyErr_Clear(); - continue; - } - v = PyString_FromString(p+1); - if (v == NULL) { - PyErr_Clear(); - Py_DECREF(k); - continue; - } - if (PyDict_GetItem(d, k) == NULL) { - if (PyDict_SetItem(d, k, v) != 0) - PyErr_Clear(); - } - Py_DECREF(k); - Py_DECREF(v); - } -#if defined(PYOS_OS2) - rc = DosQueryExtLIBPATH(buffer, BEGIN_LIBPATH); - if (rc == NO_ERROR) { /* (not a type, envname is NOT 'BEGIN_LIBPATH') */ - PyObject *v = PyString_FromString(buffer); - PyDict_SetItemString(d, "BEGINLIBPATH", v); - Py_DECREF(v); - } - rc = DosQueryExtLIBPATH(buffer, END_LIBPATH); - if (rc == NO_ERROR) { /* (not a typo, envname is NOT 'END_LIBPATH') */ - PyObject *v = PyString_FromString(buffer); - PyDict_SetItemString(d, "ENDLIBPATH", v); - Py_DECREF(v); - } -#endif - return d; -} - - -/* Set a POSIX-specific error from errno, and return NULL */ - -static PyObject * -posix_error(void) -{ - return PyErr_SetFromErrno(PyExc_OSError); -} -static PyObject * -posix_error_with_filename(char* name) -{ - return PyErr_SetFromErrnoWithFilename(PyExc_OSError, name); -} - -#ifdef MS_WINDOWS -static PyObject * -posix_error_with_unicode_filename(Py_UNICODE* name) -{ - return PyErr_SetFromErrnoWithUnicodeFilename(PyExc_OSError, name); -} -#endif /* MS_WINDOWS */ - - -static PyObject * -posix_error_with_allocated_filename(char* name) -{ - PyObject *rc = PyErr_SetFromErrnoWithFilename(PyExc_OSError, name); - PyMem_Free(name); - return rc; -} - -#ifdef MS_WINDOWS -static PyObject * -win32_error(char* function, char* filename) -{ - /* XXX We should pass the function name along in the future. - (_winreg.c also wants to pass the function name.) - This would however require an additional param to the - Windows error object, which is non-trivial. - */ - errno = GetLastError(); - if (filename) - return PyErr_SetFromWindowsErrWithFilename(errno, filename); - else - return PyErr_SetFromWindowsErr(errno); -} - -static PyObject * -win32_error_unicode(char* function, Py_UNICODE* filename) -{ - /* XXX - see win32_error for comments on 'function' */ - errno = GetLastError(); - if (filename) - return PyErr_SetFromWindowsErrWithUnicodeFilename(errno, filename); - else - return PyErr_SetFromWindowsErr(errno); -} - -static int -convert_to_unicode(PyObject **param) -{ - if (PyUnicode_CheckExact(*param)) - Py_INCREF(*param); - else if (PyUnicode_Check(*param)) - /* For a Unicode subtype that's not a Unicode object, - return a true Unicode object with the same data. */ - *param = PyUnicode_FromUnicode(PyUnicode_AS_UNICODE(*param), - PyUnicode_GET_SIZE(*param)); - else - *param = PyUnicode_FromEncodedObject(*param, - Py_FileSystemDefaultEncoding, - "strict"); - return (*param) != NULL; -} - -#endif /* MS_WINDOWS */ - -#if defined(PYOS_OS2) -/********************************************************************** - * Helper Function to Trim and Format OS/2 Messages - **********************************************************************/ -static void -os2_formatmsg(char *msgbuf, int msglen, char *reason) -{ - msgbuf[msglen] = '\0'; /* OS/2 Doesn't Guarantee a Terminator */ - - if (strlen(msgbuf) > 0) { /* If Non-Empty Msg, Trim CRLF */ - char *lastc = &msgbuf[ strlen(msgbuf)-1 ]; - - while (lastc > msgbuf && isspace(Py_CHARMASK(*lastc))) - *lastc-- = '\0'; /* Trim Trailing Whitespace (CRLF) */ - } - - /* Add Optional Reason Text */ - if (reason) { - strcat(msgbuf, " : "); - strcat(msgbuf, reason); - } -} - -/********************************************************************** - * Decode an OS/2 Operating System Error Code - * - * A convenience function to lookup an OS/2 error code and return a - * text message we can use to raise a Python exception. - * - * Notes: - * The messages for errors returned from the OS/2 kernel reside in - * the file OSO001.MSG in the \OS2 directory hierarchy. - * - **********************************************************************/ -static char * -os2_strerror(char *msgbuf, int msgbuflen, int errorcode, char *reason) -{ - APIRET rc; - ULONG msglen; - - /* Retrieve Kernel-Related Error Message from OSO001.MSG File */ - Py_BEGIN_ALLOW_THREADS - rc = DosGetMessage(NULL, 0, msgbuf, msgbuflen, - errorcode, "oso001.msg", &msglen); - Py_END_ALLOW_THREADS - - if (rc == NO_ERROR) - os2_formatmsg(msgbuf, msglen, reason); - else - PyOS_snprintf(msgbuf, msgbuflen, - "unknown OS error #%d", errorcode); - - return msgbuf; -} - -/* Set an OS/2-specific error and return NULL. OS/2 kernel - errors are not in a global variable e.g. 'errno' nor are - they congruent with posix error numbers. */ - -static PyObject * -os2_error(int code) -{ - char text[1024]; - PyObject *v; - - os2_strerror(text, sizeof(text), code, ""); - - v = Py_BuildValue("(is)", code, text); - if (v != NULL) { - PyErr_SetObject(PyExc_OSError, v); - Py_DECREF(v); - } - return NULL; /* Signal to Python that an Exception is Pending */ -} - -#endif /* OS2 */ - -/* POSIX generic methods */ - -static PyObject * -posix_fildes(PyObject *fdobj, int (*func)(int)) -{ - int fd; - int res; - fd = PyObject_AsFileDescriptor(fdobj); - if (fd < 0) - return NULL; - if (!_PyVerify_fd(fd)) - return posix_error(); - Py_BEGIN_ALLOW_THREADS - res = (*func)(fd); - Py_END_ALLOW_THREADS - if (res < 0) - return posix_error(); - Py_INCREF(Py_None); - return Py_None; -} - -static PyObject * -posix_1str(PyObject *args, char *format, int (*func)(const char*)) -{ - char *path1 = NULL; - int res; - if (!PyArg_ParseTuple(args, format, - Py_FileSystemDefaultEncoding, &path1)) - return NULL; - Py_BEGIN_ALLOW_THREADS - res = (*func)(path1); - Py_END_ALLOW_THREADS - if (res < 0) - return posix_error_with_allocated_filename(path1); - PyMem_Free(path1); - Py_INCREF(Py_None); - return Py_None; -} - -static PyObject * -posix_2str(PyObject *args, - char *format, - int (*func)(const char *, const char *)) -{ - char *path1 = NULL, *path2 = NULL; - int res; - if (!PyArg_ParseTuple(args, format, - Py_FileSystemDefaultEncoding, &path1, - Py_FileSystemDefaultEncoding, &path2)) - return NULL; - Py_BEGIN_ALLOW_THREADS - res = (*func)(path1, path2); - Py_END_ALLOW_THREADS - PyMem_Free(path1); - PyMem_Free(path2); - if (res != 0) - /* XXX how to report both path1 and path2??? */ - return posix_error(); - Py_INCREF(Py_None); - return Py_None; -} - -#ifdef MS_WINDOWS -static PyObject* -win32_1str(PyObject* args, char* func, - char* format, BOOL (__stdcall *funcA)(LPCSTR), - char* wformat, BOOL (__stdcall *funcW)(LPWSTR)) -{ - PyObject *uni; - char *ansi; - BOOL result; - - if (!PyArg_ParseTuple(args, wformat, &uni)) - PyErr_Clear(); - else { - Py_BEGIN_ALLOW_THREADS - result = funcW(PyUnicode_AsUnicode(uni)); - Py_END_ALLOW_THREADS - if (!result) - return win32_error_unicode(func, PyUnicode_AsUnicode(uni)); - Py_INCREF(Py_None); - return Py_None; - } - if (!PyArg_ParseTuple(args, format, &ansi)) - return NULL; - Py_BEGIN_ALLOW_THREADS - result = funcA(ansi); - Py_END_ALLOW_THREADS - if (!result) - return win32_error(func, ansi); - Py_INCREF(Py_None); - return Py_None; - -} - -/* This is a reimplementation of the C library's chdir function, - but one that produces Win32 errors instead of DOS error codes. - chdir is essentially a wrapper around SetCurrentDirectory; however, - it also needs to set "magic" environment variables indicating - the per-drive current directory, which are of the form =: */ -static BOOL __stdcall -win32_chdir(LPCSTR path) -{ - char new_path[MAX_PATH+1]; - int result; - char env[4] = "=x:"; - - if(!SetCurrentDirectoryA(path)) - return FALSE; - result = GetCurrentDirectoryA(MAX_PATH+1, new_path); - if (!result) - return FALSE; - /* In the ANSI API, there should not be any paths longer - than MAX_PATH. */ - assert(result <= MAX_PATH+1); - if (strncmp(new_path, "\\\\", 2) == 0 || - strncmp(new_path, "//", 2) == 0) - /* UNC path, nothing to do. */ - return TRUE; - env[1] = new_path[0]; - return SetEnvironmentVariableA(env, new_path); -} - -/* The Unicode version differs from the ANSI version - since the current directory might exceed MAX_PATH characters */ -static BOOL __stdcall -win32_wchdir(LPCWSTR path) -{ - wchar_t _new_path[MAX_PATH+1], *new_path = _new_path; - int result; - wchar_t env[4] = L"=x:"; - - if(!SetCurrentDirectoryW(path)) - return FALSE; - result = GetCurrentDirectoryW(MAX_PATH+1, new_path); - if (!result) - return FALSE; - if (result > MAX_PATH+1) { - new_path = malloc(result * sizeof(wchar_t)); - if (!new_path) { - SetLastError(ERROR_OUTOFMEMORY); - return FALSE; - } - result = GetCurrentDirectoryW(result, new_path); - if (!result) { - free(new_path); - return FALSE; - } - } - if (wcsncmp(new_path, L"\\\\", 2) == 0 || - wcsncmp(new_path, L"//", 2) == 0) - /* UNC path, nothing to do. */ - return TRUE; - env[1] = new_path[0]; - result = SetEnvironmentVariableW(env, new_path); - if (new_path != _new_path) - free(new_path); - return result; -} -#endif - -#ifdef MS_WINDOWS -/* The CRT of Windows has a number of flaws wrt. its stat() implementation: - - time stamps are restricted to second resolution - - file modification times suffer from forth-and-back conversions between - UTC and local time - Therefore, we implement our own stat, based on the Win32 API directly. -*/ -#define HAVE_STAT_NSEC 1 - -struct win32_stat{ - int st_dev; - __int64 st_ino; - unsigned short st_mode; - int st_nlink; - int st_uid; - int st_gid; - int st_rdev; - __int64 st_size; - int st_atime; - int st_atime_nsec; - int st_mtime; - int st_mtime_nsec; - int st_ctime; - int st_ctime_nsec; -}; - -static __int64 secs_between_epochs = 11644473600; /* Seconds between 1.1.1601 and 1.1.1970 */ - -static void -FILE_TIME_to_time_t_nsec(FILETIME *in_ptr, int *time_out, int* nsec_out) -{ - /* XXX endianness. Shouldn't matter, as all Windows implementations are little-endian */ - /* Cannot simply cast and dereference in_ptr, - since it might not be aligned properly */ - __int64 in; - memcpy(&in, in_ptr, sizeof(in)); - *nsec_out = (int)(in % 10000000) * 100; /* FILETIME is in units of 100 nsec. */ - /* XXX Win32 supports time stamps past 2038; we currently don't */ - *time_out = Py_SAFE_DOWNCAST((in / 10000000) - secs_between_epochs, __int64, int); -} - -static void -time_t_to_FILE_TIME(int time_in, int nsec_in, FILETIME *out_ptr) -{ - /* XXX endianness */ - __int64 out; - out = time_in + secs_between_epochs; - out = out * 10000000 + nsec_in / 100; - memcpy(out_ptr, &out, sizeof(out)); -} - -/* Below, we *know* that ugo+r is 0444 */ -#if _S_IREAD != 0400 -#error Unsupported C library -#endif -static int -attributes_to_mode(DWORD attr) -{ - int m = 0; - if (attr & FILE_ATTRIBUTE_DIRECTORY) - m |= _S_IFDIR | 0111; /* IFEXEC for user,group,other */ - else - m |= _S_IFREG; - if (attr & FILE_ATTRIBUTE_READONLY) - m |= 0444; - else - m |= 0666; - return m; -} - -static int -attribute_data_to_stat(WIN32_FILE_ATTRIBUTE_DATA *info, struct win32_stat *result) -{ - memset(result, 0, sizeof(*result)); - result->st_mode = attributes_to_mode(info->dwFileAttributes); - result->st_size = (((__int64)info->nFileSizeHigh)<<32) + info->nFileSizeLow; - FILE_TIME_to_time_t_nsec(&info->ftCreationTime, &result->st_ctime, &result->st_ctime_nsec); - FILE_TIME_to_time_t_nsec(&info->ftLastWriteTime, &result->st_mtime, &result->st_mtime_nsec); - FILE_TIME_to_time_t_nsec(&info->ftLastAccessTime, &result->st_atime, &result->st_atime_nsec); - - return 0; -} - -static BOOL -attributes_from_dir(LPCSTR pszFile, LPWIN32_FILE_ATTRIBUTE_DATA pfad) -{ - HANDLE hFindFile; - WIN32_FIND_DATAA FileData; - hFindFile = FindFirstFileA(pszFile, &FileData); - if (hFindFile == INVALID_HANDLE_VALUE) - return FALSE; - FindClose(hFindFile); - pfad->dwFileAttributes = FileData.dwFileAttributes; - pfad->ftCreationTime = FileData.ftCreationTime; - pfad->ftLastAccessTime = FileData.ftLastAccessTime; - pfad->ftLastWriteTime = FileData.ftLastWriteTime; - pfad->nFileSizeHigh = FileData.nFileSizeHigh; - pfad->nFileSizeLow = FileData.nFileSizeLow; - return TRUE; -} - -static BOOL -attributes_from_dir_w(LPCWSTR pszFile, LPWIN32_FILE_ATTRIBUTE_DATA pfad) -{ - HANDLE hFindFile; - WIN32_FIND_DATAW FileData; - hFindFile = FindFirstFileW(pszFile, &FileData); - if (hFindFile == INVALID_HANDLE_VALUE) - return FALSE; - FindClose(hFindFile); - pfad->dwFileAttributes = FileData.dwFileAttributes; - pfad->ftCreationTime = FileData.ftCreationTime; - pfad->ftLastAccessTime = FileData.ftLastAccessTime; - pfad->ftLastWriteTime = FileData.ftLastWriteTime; - pfad->nFileSizeHigh = FileData.nFileSizeHigh; - pfad->nFileSizeLow = FileData.nFileSizeLow; - return TRUE; -} - -static int -win32_stat(const char* path, struct win32_stat *result) -{ - WIN32_FILE_ATTRIBUTE_DATA info; - int code; - char *dot; - if (!GetFileAttributesExA(path, GetFileExInfoStandard, &info)) { - if (GetLastError() != ERROR_SHARING_VIOLATION) { - /* Protocol violation: we explicitly clear errno, instead of - setting it to a POSIX error. Callers should use GetLastError. */ - errno = 0; - return -1; - } else { - /* Could not get attributes on open file. Fall back to - reading the directory. */ - if (!attributes_from_dir(path, &info)) { - /* Very strange. This should not fail now */ - errno = 0; - return -1; - } - } - } - code = attribute_data_to_stat(&info, result); - if (code != 0) - return code; - /* Set S_IFEXEC if it is an .exe, .bat, ... */ - dot = strrchr(path, '.'); - if (dot) { - if (stricmp(dot, ".bat") == 0 || - stricmp(dot, ".cmd") == 0 || - stricmp(dot, ".exe") == 0 || - stricmp(dot, ".com") == 0) - result->st_mode |= 0111; - } - return code; -} - -static int -win32_wstat(const wchar_t* path, struct win32_stat *result) -{ - int code; - const wchar_t *dot; - WIN32_FILE_ATTRIBUTE_DATA info; - if (!GetFileAttributesExW(path, GetFileExInfoStandard, &info)) { - if (GetLastError() != ERROR_SHARING_VIOLATION) { - /* Protocol violation: we explicitly clear errno, instead of - setting it to a POSIX error. Callers should use GetLastError. */ - errno = 0; - return -1; - } else { - /* Could not get attributes on open file. Fall back to - reading the directory. */ - if (!attributes_from_dir_w(path, &info)) { - /* Very strange. This should not fail now */ - errno = 0; - return -1; - } - } - } - code = attribute_data_to_stat(&info, result); - if (code < 0) - return code; - /* Set IFEXEC if it is an .exe, .bat, ... */ - dot = wcsrchr(path, '.'); - if (dot) { - if (_wcsicmp(dot, L".bat") == 0 || - _wcsicmp(dot, L".cmd") == 0 || - _wcsicmp(dot, L".exe") == 0 || - _wcsicmp(dot, L".com") == 0) - result->st_mode |= 0111; - } - return code; -} - -static int -win32_fstat(int file_number, struct win32_stat *result) -{ - BY_HANDLE_FILE_INFORMATION info; - HANDLE h; - int type; - - h = (HANDLE)_get_osfhandle(file_number); - - /* Protocol violation: we explicitly clear errno, instead of - setting it to a POSIX error. Callers should use GetLastError. */ - errno = 0; - - if (h == INVALID_HANDLE_VALUE) { - /* This is really a C library error (invalid file handle). - We set the Win32 error to the closes one matching. */ - SetLastError(ERROR_INVALID_HANDLE); - return -1; - } - memset(result, 0, sizeof(*result)); - - type = GetFileType(h); - if (type == FILE_TYPE_UNKNOWN) { - DWORD error = GetLastError(); - if (error != 0) { - return -1; - } - /* else: valid but unknown file */ - } - - if (type != FILE_TYPE_DISK) { - if (type == FILE_TYPE_CHAR) - result->st_mode = _S_IFCHR; - else if (type == FILE_TYPE_PIPE) - result->st_mode = _S_IFIFO; - return 0; - } - - if (!GetFileInformationByHandle(h, &info)) { - return -1; - } - - /* similar to stat() */ - result->st_mode = attributes_to_mode(info.dwFileAttributes); - result->st_size = (((__int64)info.nFileSizeHigh)<<32) + info.nFileSizeLow; - FILE_TIME_to_time_t_nsec(&info.ftCreationTime, &result->st_ctime, &result->st_ctime_nsec); - FILE_TIME_to_time_t_nsec(&info.ftLastWriteTime, &result->st_mtime, &result->st_mtime_nsec); - FILE_TIME_to_time_t_nsec(&info.ftLastAccessTime, &result->st_atime, &result->st_atime_nsec); - /* specific to fstat() */ - result->st_nlink = info.nNumberOfLinks; - result->st_ino = (((__int64)info.nFileIndexHigh)<<32) + info.nFileIndexLow; - return 0; -} - -#endif /* MS_WINDOWS */ - -PyDoc_STRVAR(stat_result__doc__, -"stat_result: Result from stat or lstat.\n\n\ -This object may be accessed either as a tuple of\n\ - (mode, ino, dev, nlink, uid, gid, size, atime, mtime, ctime)\n\ -or via the attributes st_mode, st_ino, st_dev, st_nlink, st_uid, and so on.\n\ -\n\ -Posix/windows: If your platform supports st_blksize, st_blocks, st_rdev,\n\ -or st_flags, they are available as attributes only.\n\ -\n\ -See os.stat for more information."); - -static PyStructSequence_Field stat_result_fields[] = { - {"st_mode", "protection bits"}, - {"st_ino", "inode"}, - {"st_dev", "device"}, - {"st_nlink", "number of hard links"}, - {"st_uid", "user ID of owner"}, - {"st_gid", "group ID of owner"}, - {"st_size", "total size, in bytes"}, - /* The NULL is replaced with PyStructSequence_UnnamedField later. */ - {NULL, "integer time of last access"}, - {NULL, "integer time of last modification"}, - {NULL, "integer time of last change"}, - {"st_atime", "time of last access"}, - {"st_mtime", "time of last modification"}, - {"st_ctime", "time of last change"}, -#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE - {"st_blksize", "blocksize for filesystem I/O"}, -#endif -#ifdef HAVE_STRUCT_STAT_ST_BLOCKS - {"st_blocks", "number of blocks allocated"}, -#endif -#ifdef HAVE_STRUCT_STAT_ST_RDEV - {"st_rdev", "device type (if inode device)"}, -#endif -#ifdef HAVE_STRUCT_STAT_ST_FLAGS - {"st_flags", "user defined flags for file"}, -#endif -#ifdef HAVE_STRUCT_STAT_ST_GEN - {"st_gen", "generation number"}, -#endif -#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME - {"st_birthtime", "time of creation"}, -#endif - {0} -}; - -#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE -#define ST_BLKSIZE_IDX 13 -#else -#define ST_BLKSIZE_IDX 12 -#endif - -#ifdef HAVE_STRUCT_STAT_ST_BLOCKS -#define ST_BLOCKS_IDX (ST_BLKSIZE_IDX+1) -#else -#define ST_BLOCKS_IDX ST_BLKSIZE_IDX -#endif - -#ifdef HAVE_STRUCT_STAT_ST_RDEV -#define ST_RDEV_IDX (ST_BLOCKS_IDX+1) -#else -#define ST_RDEV_IDX ST_BLOCKS_IDX -#endif - -#ifdef HAVE_STRUCT_STAT_ST_FLAGS -#define ST_FLAGS_IDX (ST_RDEV_IDX+1) -#else -#define ST_FLAGS_IDX ST_RDEV_IDX -#endif - -#ifdef HAVE_STRUCT_STAT_ST_GEN -#define ST_GEN_IDX (ST_FLAGS_IDX+1) -#else -#define ST_GEN_IDX ST_FLAGS_IDX -#endif - -#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME -#define ST_BIRTHTIME_IDX (ST_GEN_IDX+1) -#else -#define ST_BIRTHTIME_IDX ST_GEN_IDX -#endif - -static PyStructSequence_Desc stat_result_desc = { - "stat_result", /* name */ - stat_result__doc__, /* doc */ - stat_result_fields, - 10 -}; - -PyDoc_STRVAR(statvfs_result__doc__, -"statvfs_result: Result from statvfs or fstatvfs.\n\n\ -This object may be accessed either as a tuple of\n\ - (bsize, frsize, blocks, bfree, bavail, files, ffree, favail, flag, namemax),\n\ -or via the attributes f_bsize, f_frsize, f_blocks, f_bfree, and so on.\n\ -\n\ -See os.statvfs for more information."); - -static PyStructSequence_Field statvfs_result_fields[] = { - {"f_bsize", }, - {"f_frsize", }, - {"f_blocks", }, - {"f_bfree", }, - {"f_bavail", }, - {"f_files", }, - {"f_ffree", }, - {"f_favail", }, - {"f_flag", }, - {"f_namemax",}, - {0} -}; - -static PyStructSequence_Desc statvfs_result_desc = { - "statvfs_result", /* name */ - statvfs_result__doc__, /* doc */ - statvfs_result_fields, - 10 -}; - -static int initialized; -static PyTypeObject StatResultType; -static PyTypeObject StatVFSResultType; -static newfunc structseq_new; - -static PyObject * -statresult_new(PyTypeObject *type, PyObject *args, PyObject *kwds) -{ - PyStructSequence *result; - int i; - - result = (PyStructSequence*)structseq_new(type, args, kwds); - if (!result) - return NULL; - /* If we have been initialized from a tuple, - st_?time might be set to None. Initialize it - from the int slots. */ - for (i = 7; i <= 9; i++) { - if (result->ob_item[i+3] == Py_None) { - Py_DECREF(Py_None); - Py_INCREF(result->ob_item[i]); - result->ob_item[i+3] = result->ob_item[i]; - } - } - return (PyObject*)result; -} - - - -/* If true, st_?time is float. */ -static int _stat_float_times = 1; - -PyDoc_STRVAR(stat_float_times__doc__, -"stat_float_times([newval]) -> oldval\n\n\ -Determine whether os.[lf]stat represents time stamps as float objects.\n\ -If newval is True, future calls to stat() return floats, if it is False,\n\ -future calls return ints. \n\ -If newval is omitted, return the current setting.\n"); - -static PyObject* -stat_float_times(PyObject* self, PyObject *args) -{ - int newval = -1; - if (!PyArg_ParseTuple(args, "|i:stat_float_times", &newval)) - return NULL; - if (newval == -1) - /* Return old value */ - return PyBool_FromLong(_stat_float_times); - _stat_float_times = newval; - Py_INCREF(Py_None); - return Py_None; -} - -static void -fill_time(PyObject *v, int index, time_t sec, unsigned long nsec) -{ - PyObject *fval,*ival; -#if SIZEOF_TIME_T > SIZEOF_LONG - ival = PyLong_FromLongLong((PY_LONG_LONG)sec); -#else - ival = PyInt_FromLong((long)sec); -#endif - if (!ival) - return; - if (_stat_float_times) { - fval = PyFloat_FromDouble(sec + 1e-9*nsec); - } else { - fval = ival; - Py_INCREF(fval); - } - PyStructSequence_SET_ITEM(v, index, ival); - PyStructSequence_SET_ITEM(v, index+3, fval); -} - -/* pack a system stat C structure into the Python stat tuple - (used by posix_stat() and posix_fstat()) */ -static PyObject* -_pystat_fromstructstat(STRUCT_STAT *st) -{ - unsigned long ansec, mnsec, cnsec; - PyObject *v = PyStructSequence_New(&StatResultType); - if (v == NULL) - return NULL; - - PyStructSequence_SET_ITEM(v, 0, PyInt_FromLong((long)st->st_mode)); -#ifdef HAVE_LARGEFILE_SUPPORT - PyStructSequence_SET_ITEM(v, 1, - PyLong_FromLongLong((PY_LONG_LONG)st->st_ino)); -#else - PyStructSequence_SET_ITEM(v, 1, PyInt_FromLong((long)st->st_ino)); -#endif -#if defined(HAVE_LONG_LONG) && !defined(MS_WINDOWS) - PyStructSequence_SET_ITEM(v, 2, - PyLong_FromLongLong((PY_LONG_LONG)st->st_dev)); -#else - PyStructSequence_SET_ITEM(v, 2, PyInt_FromLong((long)st->st_dev)); -#endif - PyStructSequence_SET_ITEM(v, 3, PyInt_FromLong((long)st->st_nlink)); - PyStructSequence_SET_ITEM(v, 4, PyInt_FromLong((long)st->st_uid)); - PyStructSequence_SET_ITEM(v, 5, PyInt_FromLong((long)st->st_gid)); -#ifdef HAVE_LARGEFILE_SUPPORT - PyStructSequence_SET_ITEM(v, 6, - PyLong_FromLongLong((PY_LONG_LONG)st->st_size)); -#else - PyStructSequence_SET_ITEM(v, 6, PyInt_FromLong(st->st_size)); -#endif - -#if defined(HAVE_STAT_TV_NSEC) - ansec = st->st_atim.tv_nsec; - mnsec = st->st_mtim.tv_nsec; - cnsec = st->st_ctim.tv_nsec; -#elif defined(HAVE_STAT_TV_NSEC2) - ansec = st->st_atimespec.tv_nsec; - mnsec = st->st_mtimespec.tv_nsec; - cnsec = st->st_ctimespec.tv_nsec; -#elif defined(HAVE_STAT_NSEC) - ansec = st->st_atime_nsec; - mnsec = st->st_mtime_nsec; - cnsec = st->st_ctime_nsec; -#else - ansec = mnsec = cnsec = 0; -#endif - fill_time(v, 7, st->st_atime, ansec); - fill_time(v, 8, st->st_mtime, mnsec); - fill_time(v, 9, st->st_ctime, cnsec); - -#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE - PyStructSequence_SET_ITEM(v, ST_BLKSIZE_IDX, - PyInt_FromLong((long)st->st_blksize)); -#endif -#ifdef HAVE_STRUCT_STAT_ST_BLOCKS - PyStructSequence_SET_ITEM(v, ST_BLOCKS_IDX, - PyInt_FromLong((long)st->st_blocks)); -#endif -#ifdef HAVE_STRUCT_STAT_ST_RDEV - PyStructSequence_SET_ITEM(v, ST_RDEV_IDX, - PyInt_FromLong((long)st->st_rdev)); -#endif -#ifdef HAVE_STRUCT_STAT_ST_GEN - PyStructSequence_SET_ITEM(v, ST_GEN_IDX, - PyInt_FromLong((long)st->st_gen)); -#endif -#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME - { - PyObject *val; - unsigned long bsec,bnsec; - bsec = (long)st->st_birthtime; -#ifdef HAVE_STAT_TV_NSEC2 - bnsec = st->st_birthtimespec.tv_nsec; -#else - bnsec = 0; -#endif - if (_stat_float_times) { - val = PyFloat_FromDouble(bsec + 1e-9*bnsec); - } else { - val = PyInt_FromLong((long)bsec); - } - PyStructSequence_SET_ITEM(v, ST_BIRTHTIME_IDX, - val); - } -#endif -#ifdef HAVE_STRUCT_STAT_ST_FLAGS - PyStructSequence_SET_ITEM(v, ST_FLAGS_IDX, - PyInt_FromLong((long)st->st_flags)); -#endif - - if (PyErr_Occurred()) { - Py_DECREF(v); - return NULL; - } - - return v; -} - -#ifdef MS_WINDOWS - -/* IsUNCRoot -- test whether the supplied path is of the form \\SERVER\SHARE\, - where / can be used in place of \ and the trailing slash is optional. - Both SERVER and SHARE must have at least one character. -*/ - -#define ISSLASHA(c) ((c) == '\\' || (c) == '/') -#define ISSLASHW(c) ((c) == L'\\' || (c) == L'/') -#ifndef ARRAYSIZE -#define ARRAYSIZE(a) (sizeof(a) / sizeof(a[0])) -#endif - -static BOOL -IsUNCRootA(char *path, int pathlen) -{ - #define ISSLASH ISSLASHA - - int i, share; - - if (pathlen < 5 || !ISSLASH(path[0]) || !ISSLASH(path[1])) - /* minimum UNCRoot is \\x\y */ - return FALSE; - for (i = 2; i < pathlen ; i++) - if (ISSLASH(path[i])) break; - if (i == 2 || i == pathlen) - /* do not allow \\\SHARE or \\SERVER */ - return FALSE; - share = i+1; - for (i = share; i < pathlen; i++) - if (ISSLASH(path[i])) break; - return (i != share && (i == pathlen || i == pathlen-1)); - - #undef ISSLASH -} - -static BOOL -IsUNCRootW(Py_UNICODE *path, int pathlen) -{ - #define ISSLASH ISSLASHW - - int i, share; - - if (pathlen < 5 || !ISSLASH(path[0]) || !ISSLASH(path[1])) - /* minimum UNCRoot is \\x\y */ - return FALSE; - for (i = 2; i < pathlen ; i++) - if (ISSLASH(path[i])) break; - if (i == 2 || i == pathlen) - /* do not allow \\\SHARE or \\SERVER */ - return FALSE; - share = i+1; - for (i = share; i < pathlen; i++) - if (ISSLASH(path[i])) break; - return (i != share && (i == pathlen || i == pathlen-1)); - - #undef ISSLASH -} -#endif /* MS_WINDOWS */ - -static PyObject * -posix_do_stat(PyObject *self, PyObject *args, - char *format, -#ifdef __VMS - int (*statfunc)(const char *, STRUCT_STAT *, ...), -#else - int (*statfunc)(const char *, STRUCT_STAT *), -#endif - char *wformat, - int (*wstatfunc)(const Py_UNICODE *, STRUCT_STAT *)) -{ - STRUCT_STAT st; - char *path = NULL; /* pass this to stat; do not free() it */ - char *pathfree = NULL; /* this memory must be free'd */ - int res; - PyObject *result; - -#ifdef MS_WINDOWS - PyUnicodeObject *po; - if (PyArg_ParseTuple(args, wformat, &po)) { - Py_UNICODE *wpath = PyUnicode_AS_UNICODE(po); - - Py_BEGIN_ALLOW_THREADS - /* PyUnicode_AS_UNICODE result OK without - thread lock as it is a simple dereference. */ - res = wstatfunc(wpath, &st); - Py_END_ALLOW_THREADS - - if (res != 0) - return win32_error_unicode("stat", wpath); - return _pystat_fromstructstat(&st); - } - /* Drop the argument parsing error as narrow strings - are also valid. */ - PyErr_Clear(); -#endif - - if (!PyArg_ParseTuple(args, format, - Py_FileSystemDefaultEncoding, &path)) - return NULL; - pathfree = path; - - Py_BEGIN_ALLOW_THREADS - res = (*statfunc)(path, &st); - Py_END_ALLOW_THREADS - - if (res != 0) { -#ifdef MS_WINDOWS - result = win32_error("stat", pathfree); -#else - result = posix_error_with_filename(pathfree); -#endif - } - else - result = _pystat_fromstructstat(&st); - - PyMem_Free(pathfree); - return result; -} - -/* POSIX methods */ - -PyDoc_STRVAR(posix_access__doc__, -"access(path, mode) -> True if granted, False otherwise\n\n\ -Use the real uid/gid to test for access to a path. Note that most\n\ -operations will use the effective uid/gid, therefore this routine can\n\ -be used in a suid/sgid environment to test if the invoking user has the\n\ -specified access to the path. The mode argument can be F_OK to test\n\ -existence, or the inclusive-OR of R_OK, W_OK, and X_OK."); - -static PyObject * -posix_access(PyObject *self, PyObject *args) -{ - char *path; - int mode; - -#ifdef MS_WINDOWS - DWORD attr; - PyUnicodeObject *po; - if (PyArg_ParseTuple(args, "Ui:access", &po, &mode)) { - Py_BEGIN_ALLOW_THREADS - /* PyUnicode_AS_UNICODE OK without thread lock as - it is a simple dereference. */ - attr = GetFileAttributesW(PyUnicode_AS_UNICODE(po)); - Py_END_ALLOW_THREADS - goto finish; - } - /* Drop the argument parsing error as narrow strings - are also valid. */ - PyErr_Clear(); - if (!PyArg_ParseTuple(args, "eti:access", - Py_FileSystemDefaultEncoding, &path, &mode)) - return NULL; - Py_BEGIN_ALLOW_THREADS - attr = GetFileAttributesA(path); - Py_END_ALLOW_THREADS - PyMem_Free(path); -finish: - if (attr == 0xFFFFFFFF) - /* File does not exist, or cannot read attributes */ - return PyBool_FromLong(0); - /* Access is possible if either write access wasn't requested, or - the file isn't read-only, or if it's a directory, as there are - no read-only directories on Windows. */ - return PyBool_FromLong(!(mode & 2) - || !(attr & FILE_ATTRIBUTE_READONLY) - || (attr & FILE_ATTRIBUTE_DIRECTORY)); -#else /* MS_WINDOWS */ - int res; - if (!PyArg_ParseTuple(args, "eti:access", - Py_FileSystemDefaultEncoding, &path, &mode)) - return NULL; - Py_BEGIN_ALLOW_THREADS - res = access(path, mode); - Py_END_ALLOW_THREADS - PyMem_Free(path); - return PyBool_FromLong(res == 0); -#endif /* MS_WINDOWS */ -} - -#ifndef F_OK -#define F_OK 0 -#endif -#ifndef R_OK -#define R_OK 4 -#endif -#ifndef W_OK -#define W_OK 2 -#endif -#ifndef X_OK -#define X_OK 1 -#endif - -#ifdef HAVE_TTYNAME -PyDoc_STRVAR(posix_ttyname__doc__, -"ttyname(fd) -> string\n\n\ -Return the name of the terminal device connected to 'fd'."); - -static PyObject * -posix_ttyname(PyObject *self, PyObject *args) -{ - int id; - char *ret; - - if (!PyArg_ParseTuple(args, "i:ttyname", &id)) - return NULL; - -#if defined(__VMS) - /* file descriptor 0 only, the default input device (stdin) */ - if (id == 0) { - ret = ttyname(); - } - else { - ret = NULL; - } -#else - ret = ttyname(id); -#endif - if (ret == NULL) - return posix_error(); - return PyString_FromString(ret); -} -#endif - -#ifdef HAVE_CTERMID -PyDoc_STRVAR(posix_ctermid__doc__, -"ctermid() -> string\n\n\ -Return the name of the controlling terminal for this process."); - -static PyObject * -posix_ctermid(PyObject *self, PyObject *noargs) -{ - char *ret; - char buffer[L_ctermid]; - -#ifdef USE_CTERMID_R - ret = ctermid_r(buffer); -#else - ret = ctermid(buffer); -#endif - if (ret == NULL) - return posix_error(); - return PyString_FromString(buffer); -} -#endif - -PyDoc_STRVAR(posix_chdir__doc__, -"chdir(path)\n\n\ -Change the current working directory to the specified path."); - -static PyObject * -posix_chdir(PyObject *self, PyObject *args) -{ -#ifdef MS_WINDOWS - return win32_1str(args, "chdir", "s:chdir", win32_chdir, "U:chdir", win32_wchdir); -#elif defined(PYOS_OS2) && defined(PYCC_GCC) - return posix_1str(args, "et:chdir", _chdir2); -#elif defined(__VMS) - return posix_1str(args, "et:chdir", (int (*)(const char *))chdir); -#else - return posix_1str(args, "et:chdir", chdir); -#endif -} - -#ifdef HAVE_FCHDIR -PyDoc_STRVAR(posix_fchdir__doc__, -"fchdir(fildes)\n\n\ -Change to the directory of the given file descriptor. fildes must be\n\ -opened on a directory, not a file."); - -static PyObject * -posix_fchdir(PyObject *self, PyObject *fdobj) -{ - return posix_fildes(fdobj, fchdir); -} -#endif /* HAVE_FCHDIR */ - - -PyDoc_STRVAR(posix_chmod__doc__, -"chmod(path, mode)\n\n\ -Change the access permissions of a file."); - -static PyObject * -posix_chmod(PyObject *self, PyObject *args) -{ - char *path = NULL; - int i; - int res; -#ifdef MS_WINDOWS - DWORD attr; - PyUnicodeObject *po; - if (PyArg_ParseTuple(args, "Ui|:chmod", &po, &i)) { - Py_BEGIN_ALLOW_THREADS - attr = GetFileAttributesW(PyUnicode_AS_UNICODE(po)); - if (attr != 0xFFFFFFFF) { - if (i & _S_IWRITE) - attr &= ~FILE_ATTRIBUTE_READONLY; - else - attr |= FILE_ATTRIBUTE_READONLY; - res = SetFileAttributesW(PyUnicode_AS_UNICODE(po), attr); - } - else - res = 0; - Py_END_ALLOW_THREADS - if (!res) - return win32_error_unicode("chmod", - PyUnicode_AS_UNICODE(po)); - Py_INCREF(Py_None); - return Py_None; - } - /* Drop the argument parsing error as narrow strings - are also valid. */ - PyErr_Clear(); - - if (!PyArg_ParseTuple(args, "eti:chmod", Py_FileSystemDefaultEncoding, - &path, &i)) - return NULL; - Py_BEGIN_ALLOW_THREADS - attr = GetFileAttributesA(path); - if (attr != 0xFFFFFFFF) { - if (i & _S_IWRITE) - attr &= ~FILE_ATTRIBUTE_READONLY; - else - attr |= FILE_ATTRIBUTE_READONLY; - res = SetFileAttributesA(path, attr); - } - else - res = 0; - Py_END_ALLOW_THREADS - if (!res) { - win32_error("chmod", path); - PyMem_Free(path); - return NULL; - } - PyMem_Free(path); - Py_INCREF(Py_None); - return Py_None; -#else /* MS_WINDOWS */ - if (!PyArg_ParseTuple(args, "eti:chmod", Py_FileSystemDefaultEncoding, - &path, &i)) - return NULL; - Py_BEGIN_ALLOW_THREADS - res = chmod(path, i); - Py_END_ALLOW_THREADS - if (res < 0) - return posix_error_with_allocated_filename(path); - PyMem_Free(path); - Py_INCREF(Py_None); - return Py_None; -#endif -} - -#ifdef HAVE_FCHMOD -PyDoc_STRVAR(posix_fchmod__doc__, -"fchmod(fd, mode)\n\n\ -Change the access permissions of the file given by file\n\ -descriptor fd."); - -static PyObject * -posix_fchmod(PyObject *self, PyObject *args) -{ - int fd, mode, res; - if (!PyArg_ParseTuple(args, "ii:fchmod", &fd, &mode)) - return NULL; - Py_BEGIN_ALLOW_THREADS - res = fchmod(fd, mode); - Py_END_ALLOW_THREADS - if (res < 0) - return posix_error(); - Py_RETURN_NONE; -} -#endif /* HAVE_FCHMOD */ - -#ifdef HAVE_LCHMOD -PyDoc_STRVAR(posix_lchmod__doc__, -"lchmod(path, mode)\n\n\ -Change the access permissions of a file. If path is a symlink, this\n\ -affects the link itself rather than the target."); - -static PyObject * -posix_lchmod(PyObject *self, PyObject *args) -{ - char *path = NULL; - int i; - int res; - if (!PyArg_ParseTuple(args, "eti:lchmod", Py_FileSystemDefaultEncoding, - &path, &i)) - return NULL; - Py_BEGIN_ALLOW_THREADS - res = lchmod(path, i); - Py_END_ALLOW_THREADS - if (res < 0) - return posix_error_with_allocated_filename(path); - PyMem_Free(path); - Py_RETURN_NONE; -} -#endif /* HAVE_LCHMOD */ - - -#ifdef HAVE_CHFLAGS -PyDoc_STRVAR(posix_chflags__doc__, -"chflags(path, flags)\n\n\ -Set file flags."); - -static PyObject * -posix_chflags(PyObject *self, PyObject *args) -{ - char *path; - unsigned long flags; - int res; - if (!PyArg_ParseTuple(args, "etk:chflags", - Py_FileSystemDefaultEncoding, &path, &flags)) - return NULL; - Py_BEGIN_ALLOW_THREADS - res = chflags(path, flags); - Py_END_ALLOW_THREADS - if (res < 0) - return posix_error_with_allocated_filename(path); - PyMem_Free(path); - Py_INCREF(Py_None); - return Py_None; -} -#endif /* HAVE_CHFLAGS */ - -#ifdef HAVE_LCHFLAGS -PyDoc_STRVAR(posix_lchflags__doc__, -"lchflags(path, flags)\n\n\ -Set file flags.\n\ -This function will not follow symbolic links."); - -static PyObject * -posix_lchflags(PyObject *self, PyObject *args) -{ - char *path; - unsigned long flags; - int res; - if (!PyArg_ParseTuple(args, "etk:lchflags", - Py_FileSystemDefaultEncoding, &path, &flags)) - return NULL; - Py_BEGIN_ALLOW_THREADS - res = lchflags(path, flags); - Py_END_ALLOW_THREADS - if (res < 0) - return posix_error_with_allocated_filename(path); - PyMem_Free(path); - Py_INCREF(Py_None); - return Py_None; -} -#endif /* HAVE_LCHFLAGS */ - -#ifdef HAVE_CHROOT -PyDoc_STRVAR(posix_chroot__doc__, -"chroot(path)\n\n\ -Change root directory to path."); - -static PyObject * -posix_chroot(PyObject *self, PyObject *args) -{ - return posix_1str(args, "et:chroot", chroot); -} -#endif - -#ifdef HAVE_FSYNC -PyDoc_STRVAR(posix_fsync__doc__, -"fsync(fildes)\n\n\ -force write of file with filedescriptor to disk."); - -static PyObject * -posix_fsync(PyObject *self, PyObject *fdobj) -{ - return posix_fildes(fdobj, fsync); -} -#endif /* HAVE_FSYNC */ - -#ifdef HAVE_FDATASYNC - -#ifdef __hpux -extern int fdatasync(int); /* On HP-UX, in libc but not in unistd.h */ -#endif - -PyDoc_STRVAR(posix_fdatasync__doc__, -"fdatasync(fildes)\n\n\ -force write of file with filedescriptor to disk.\n\ - does not force update of metadata."); - -static PyObject * -posix_fdatasync(PyObject *self, PyObject *fdobj) -{ - return posix_fildes(fdobj, fdatasync); -} -#endif /* HAVE_FDATASYNC */ - - -#ifdef HAVE_CHOWN -PyDoc_STRVAR(posix_chown__doc__, -"chown(path, uid, gid)\n\n\ -Change the owner and group id of path to the numeric uid and gid."); - -static PyObject * -posix_chown(PyObject *self, PyObject *args) -{ - char *path = NULL; - long uid, gid; - int res; - if (!PyArg_ParseTuple(args, "etll:chown", - Py_FileSystemDefaultEncoding, &path, - &uid, &gid)) - return NULL; - Py_BEGIN_ALLOW_THREADS - res = chown(path, (uid_t) uid, (gid_t) gid); - Py_END_ALLOW_THREADS - if (res < 0) - return posix_error_with_allocated_filename(path); - PyMem_Free(path); - Py_INCREF(Py_None); - return Py_None; -} -#endif /* HAVE_CHOWN */ - -#ifdef HAVE_FCHOWN -PyDoc_STRVAR(posix_fchown__doc__, -"fchown(fd, uid, gid)\n\n\ -Change the owner and group id of the file given by file descriptor\n\ -fd to the numeric uid and gid."); - -static PyObject * -posix_fchown(PyObject *self, PyObject *args) -{ - int fd; - long uid, gid; - int res; - if (!PyArg_ParseTuple(args, "ill:chown", &fd, &uid, &gid)) - return NULL; - Py_BEGIN_ALLOW_THREADS - res = fchown(fd, (uid_t) uid, (gid_t) gid); - Py_END_ALLOW_THREADS - if (res < 0) - return posix_error(); - Py_RETURN_NONE; -} -#endif /* HAVE_FCHOWN */ - -#ifdef HAVE_LCHOWN -PyDoc_STRVAR(posix_lchown__doc__, -"lchown(path, uid, gid)\n\n\ -Change the owner and group id of path to the numeric uid and gid.\n\ -This function will not follow symbolic links."); - -static PyObject * -posix_lchown(PyObject *self, PyObject *args) -{ - char *path = NULL; - long uid, gid; - int res; - if (!PyArg_ParseTuple(args, "etll:lchown", - Py_FileSystemDefaultEncoding, &path, - &uid, &gid)) - return NULL; - Py_BEGIN_ALLOW_THREADS - res = lchown(path, (uid_t) uid, (gid_t) gid); - Py_END_ALLOW_THREADS - if (res < 0) - return posix_error_with_allocated_filename(path); - PyMem_Free(path); - Py_INCREF(Py_None); - return Py_None; -} -#endif /* HAVE_LCHOWN */ - - -#ifdef HAVE_GETCWD -PyDoc_STRVAR(posix_getcwd__doc__, -"getcwd() -> path\n\n\ -Return a string representing the current working directory."); - -#if (defined(__sun) && defined(__SVR4)) || defined(__OpenBSD__) -/* Issue 9185: getcwd() returns NULL/ERANGE indefinitely. */ -static PyObject * -posix_getcwd(PyObject *self, PyObject *noargs) -{ - char buf[PATH_MAX+2]; - char *res; - - Py_BEGIN_ALLOW_THREADS - res = getcwd(buf, sizeof buf); - Py_END_ALLOW_THREADS - - if (res == NULL) - return posix_error(); - - return PyString_FromString(buf); -} -#else -static PyObject * -posix_getcwd(PyObject *self, PyObject *noargs) -{ - int bufsize_incr = 1024; - int bufsize = 0; - char *tmpbuf = NULL; - char *res = NULL; - PyObject *dynamic_return; - - Py_BEGIN_ALLOW_THREADS - do { - bufsize = bufsize + bufsize_incr; - tmpbuf = malloc(bufsize); - if (tmpbuf == NULL) { - break; - } -#if defined(PYOS_OS2) && defined(PYCC_GCC) - res = _getcwd2(tmpbuf, bufsize); -#else - res = getcwd(tmpbuf, bufsize); -#endif - - if (res == NULL) { - free(tmpbuf); - } - } while ((res == NULL) && (errno == ERANGE)); - Py_END_ALLOW_THREADS - - if (res == NULL) - return posix_error(); - - dynamic_return = PyString_FromString(tmpbuf); - free(tmpbuf); - - return dynamic_return; -} -#endif /* getcwd() NULL/ERANGE workaround. */ - -#ifdef Py_USING_UNICODE -PyDoc_STRVAR(posix_getcwdu__doc__, -"getcwdu() -> path\n\n\ -Return a unicode string representing the current working directory."); - -static PyObject * -posix_getcwdu(PyObject *self, PyObject *noargs) -{ - char buf[1026]; - char *res; - -#ifdef MS_WINDOWS - DWORD len; - wchar_t wbuf[1026]; - wchar_t *wbuf2 = wbuf; - PyObject *resobj; - Py_BEGIN_ALLOW_THREADS - len = GetCurrentDirectoryW(sizeof wbuf/ sizeof wbuf[0], wbuf); - /* If the buffer is large enough, len does not include the - terminating \0. If the buffer is too small, len includes - the space needed for the terminator. */ - if (len >= sizeof wbuf/ sizeof wbuf[0]) { - wbuf2 = malloc(len * sizeof(wchar_t)); - if (wbuf2) - len = GetCurrentDirectoryW(len, wbuf2); - } - Py_END_ALLOW_THREADS - if (!wbuf2) { - PyErr_NoMemory(); - return NULL; - } - if (!len) { - if (wbuf2 != wbuf) free(wbuf2); - return win32_error("getcwdu", NULL); - } - resobj = PyUnicode_FromWideChar(wbuf2, len); - if (wbuf2 != wbuf) free(wbuf2); - return resobj; -#endif /* MS_WINDOWS */ - - Py_BEGIN_ALLOW_THREADS -#if defined(PYOS_OS2) && defined(PYCC_GCC) - res = _getcwd2(buf, sizeof buf); -#else - res = getcwd(buf, sizeof buf); -#endif - Py_END_ALLOW_THREADS - if (res == NULL) - return posix_error(); - return PyUnicode_Decode(buf, strlen(buf), Py_FileSystemDefaultEncoding,"strict"); -} -#endif /* Py_USING_UNICODE */ -#endif /* HAVE_GETCWD */ - - -#ifdef HAVE_LINK -PyDoc_STRVAR(posix_link__doc__, -"link(src, dst)\n\n\ -Create a hard link to a file."); - -static PyObject * -posix_link(PyObject *self, PyObject *args) -{ - return posix_2str(args, "etet:link", link); -} -#endif /* HAVE_LINK */ - - -PyDoc_STRVAR(posix_listdir__doc__, -"listdir(path) -> list_of_strings\n\n\ -Return a list containing the names of the entries in the directory.\n\ -\n\ - path: path of directory to list\n\ -\n\ -The list is in arbitrary order. It does not include the special\n\ -entries '.' and '..' even if they are present in the directory."); - -static PyObject * -posix_listdir(PyObject *self, PyObject *args) -{ - /* XXX Should redo this putting the (now four) versions of opendir - in separate files instead of having them all here... */ -#if defined(MS_WINDOWS) && !defined(HAVE_OPENDIR) - - PyObject *d, *v; - HANDLE hFindFile; - BOOL result; - WIN32_FIND_DATA FileData; - char namebuf[MAX_PATH+5]; /* Overallocate for \\*.*\0 */ - char *bufptr = namebuf; - Py_ssize_t len = sizeof(namebuf)-5; /* only claim to have space for MAX_PATH */ - - PyObject *po; - if (PyArg_ParseTuple(args, "U:listdir", &po)) { - WIN32_FIND_DATAW wFileData; - Py_UNICODE *wnamebuf; - /* Overallocate for \\*.*\0 */ - len = PyUnicode_GET_SIZE(po); - wnamebuf = malloc((len + 5) * sizeof(wchar_t)); - if (!wnamebuf) { - PyErr_NoMemory(); - return NULL; - } - wcscpy(wnamebuf, PyUnicode_AS_UNICODE(po)); - if (len > 0) { - Py_UNICODE wch = wnamebuf[len-1]; - if (wch != L'/' && wch != L'\\' && wch != L':') - wnamebuf[len++] = L'\\'; - wcscpy(wnamebuf + len, L"*.*"); - } - if ((d = PyList_New(0)) == NULL) { - free(wnamebuf); - return NULL; - } - Py_BEGIN_ALLOW_THREADS - hFindFile = FindFirstFileW(wnamebuf, &wFileData); - Py_END_ALLOW_THREADS - if (hFindFile == INVALID_HANDLE_VALUE) { - int error = GetLastError(); - if (error == ERROR_FILE_NOT_FOUND) { - free(wnamebuf); - return d; - } - Py_DECREF(d); - win32_error_unicode("FindFirstFileW", wnamebuf); - free(wnamebuf); - return NULL; - } - do { - /* Skip over . and .. */ - if (wcscmp(wFileData.cFileName, L".") != 0 && - wcscmp(wFileData.cFileName, L"..") != 0) { - v = PyUnicode_FromUnicode(wFileData.cFileName, wcslen(wFileData.cFileName)); - if (v == NULL) { - Py_DECREF(d); - d = NULL; - break; - } - if (PyList_Append(d, v) != 0) { - Py_DECREF(v); - Py_DECREF(d); - d = NULL; - break; - } - Py_DECREF(v); - } - Py_BEGIN_ALLOW_THREADS - result = FindNextFileW(hFindFile, &wFileData); - Py_END_ALLOW_THREADS - /* FindNextFile sets error to ERROR_NO_MORE_FILES if - it got to the end of the directory. */ - if (!result && GetLastError() != ERROR_NO_MORE_FILES) { - Py_DECREF(d); - win32_error_unicode("FindNextFileW", wnamebuf); - FindClose(hFindFile); - free(wnamebuf); - return NULL; - } - } while (result == TRUE); - - if (FindClose(hFindFile) == FALSE) { - Py_DECREF(d); - win32_error_unicode("FindClose", wnamebuf); - free(wnamebuf); - return NULL; - } - free(wnamebuf); - return d; - } - /* Drop the argument parsing error as narrow strings - are also valid. */ - PyErr_Clear(); - - if (!PyArg_ParseTuple(args, "et#:listdir", - Py_FileSystemDefaultEncoding, &bufptr, &len)) - return NULL; - if (len > 0) { - char ch = namebuf[len-1]; - if (ch != SEP && ch != ALTSEP && ch != ':') - namebuf[len++] = '/'; - strcpy(namebuf + len, "*.*"); - } - - if ((d = PyList_New(0)) == NULL) - return NULL; - - Py_BEGIN_ALLOW_THREADS - hFindFile = FindFirstFile(namebuf, &FileData); - Py_END_ALLOW_THREADS - if (hFindFile == INVALID_HANDLE_VALUE) { - int error = GetLastError(); - if (error == ERROR_FILE_NOT_FOUND) - return d; - Py_DECREF(d); - return win32_error("FindFirstFile", namebuf); - } - do { - /* Skip over . and .. */ - if (strcmp(FileData.cFileName, ".") != 0 && - strcmp(FileData.cFileName, "..") != 0) { - v = PyString_FromString(FileData