summaryrefslogtreecommitdiff
path: root/package/python2/files/posixmodule.c
diff options
context:
space:
mode:
Diffstat (limited to 'package/python2/files/posixmodule.c')
-rw-r--r--package/python2/files/posixmodule.c9365
1 files changed, 0 insertions, 9365 deletions
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 <unixio.h>
-#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 <os2.h>
-#if defined(PYCC_GCC)
-#include <ctype.h>
-#include <io.h>
-#include <stdio.h>
-#include <process.h>
-#endif
-#include "osdefs.h"
-#endif
-
-#ifdef HAVE_SYS_TYPES_H
-#include <sys/types.h>
-#endif /* HAVE_SYS_TYPES_H */
-
-#ifdef HAVE_SYS_STAT_H
-#include <sys/stat.h>
-#endif /* HAVE_SYS_STAT_H */
-
-#ifdef HAVE_SYS_WAIT_H
-#include <sys/wait.h> /* For WNOHANG */
-#endif
-
-#ifdef HAVE_SIGNAL_H
-#include <signal.h>
-#endif
-
-#ifdef HAVE_FCNTL_H
-#include <fcntl.h>
-#endif /* HAVE_FCNTL_H */
-
-#ifdef HAVE_GRP_H
-#include <grp.h>
-#endif
-
-#ifdef HAVE_SYSEXITS_H
-#include <sysexits.h>
-#endif /* HAVE_SYSEXITS_H */
-
-#ifdef HAVE_SYS_LOADAVG_H
-#include <sys/loadavg.h>
-#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 <process.h>
-#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 <process.h>
-#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 <utime.h>
-#endif /* HAVE_UTIME_H */
-
-#ifdef HAVE_SYS_UTIME_H
-#include <sys/utime.h>
-#define HAVE_UTIME_H /* pretend we do for the rest of this file */
-#endif /* HAVE_SYS_UTIME_H */
-
-#ifdef HAVE_SYS_TIMES_H
-#include <sys/times.h>
-#endif /* HAVE_SYS_TIMES_H */
-
-#ifdef HAVE_SYS_PARAM_H
-#include <sys/param.h>
-#endif /* HAVE_SYS_PARAM_H */
-
-#ifdef HAVE_SYS_UTSNAME_H
-#include <sys/utsname.h>
-#endif /* HAVE_SYS_UTSNAME_H */
-
-#ifdef HAVE_DIRENT_H
-#include <dirent.h>
-#define NAMLEN(dirent) strlen((dirent)->d_name)
-#else
-#if defined(__WATCOMC__) && !defined(__QNX__)
-#include <direct.h>
-#define NAMLEN(dirent) strlen((dirent)->d_name)
-#else
-#define dirent direct
-#define NAMLEN(dirent) (dirent)->d_namlen
-#endif
-#ifdef HAVE_SYS_NDIR_H
-#include <sys/ndir.h>
-#endif
-#ifdef HAVE_SYS_DIR_H
-#include <sys/dir.h>
-#endif
-#ifdef HAVE_NDIR_H
-#include <ndir.h>
-#endif
-#endif
-
-#ifdef _MSC_VER
-#ifdef HAVE_DIRECT_H
-#include <direct.h>
-#endif
-#ifdef HAVE_IO_H
-#include <io.h>
-#endif
-#ifdef HAVE_PROCESS_H
-#include <process.h>
-#endif
-#include "osdefs.h"
-#include <malloc.h>
-#include <windows.h>
-#include <shellapi.h> /* for ShellExecute() */
-#define popen _popen
-#define pclose _pclose
-#endif /* _MSC_VER */
-
-#if defined(PYCC_VACPP) && defined(PYOS_OS2)
-#include <io.h>
-#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 <sys/mkdev.h>
-#else
-#if defined(MAJOR_IN_SYSMACROS)
-#include <sys/sysmacros.h>
-#endif
-#if defined(HAVE_MKNOD) && defined(HAVE_SYS_MKDEV_H)
-#include <sys/mkdev.h>
-#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 <crt_externs.h>
-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 =<drive>: */
-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