summaryrefslogtreecommitdiff
path: root/package
diff options
context:
space:
mode:
authorWaldemar Brodkorb <wbx@openadk.org>2011-04-03 20:44:34 +0200
committerWaldemar Brodkorb <wbx@openadk.org>2011-04-03 20:44:34 +0200
commit2484b250c93f9cca8e0565223a920d77ca1e571e (patch)
tree5d440cc005f2fd6768e41b661ce23ce2eb863cfd /package
parentc994348c75f154eecb5ff48392b40c45ec80de55 (diff)
parent3fbdaa5995707a0e7398b3b78e7b7c195a143f6d (diff)
Merge branch 'master' of git+ssh://openadk.org/git/openadk
Diffstat (limited to 'package')
-rw-r--r--package/perl/patches/patch-Configure65
-rw-r--r--package/python2/Makefile1
-rw-r--r--package/python2/files/posixmodule.c9365
-rw-r--r--package/python2/patches/patch-Modules_posixmodule_c16
4 files changed, 9431 insertions, 16 deletions
diff --git a/package/perl/patches/patch-Configure b/package/perl/patches/patch-Configure
new file mode 100644
index 000000000..953d03c5e
--- /dev/null
+++ b/package/perl/patches/patch-Configure
@@ -0,0 +1,65 @@
+--- perl-5.12.3.orig/Configure 2011-01-09 21:20:52.000000000 +0100
++++ perl-5.12.3/Configure 2011-03-19 20:44:59.000000000 +0100
+@@ -5164,11 +5164,11 @@ default|recommended)
+ # is to add the flag to the flags passed to the compiler at link time,
+ # as that way the compiler can do the right implementation dependant
+ # thing. (NWC)
+- case "$gccversion" in
+- ?*) set stack-protector -fstack-protector
+- eval $checkccflag
+- ;;
+- esac
++ #case "$gccversion" in
++ #?*) set stack-protector -fstack-protector
++ # eval $checkccflag
++ # ;;
++ #esac
+ ;;
+ esac
+
+@@ -5308,14 +5308,14 @@ case "$ldflags" in
+ *) dflt="$ldflags";;
+ esac
+ # See note above about -fstack-protector
+-case "$ccflags" in
+-*-fstack-protector*)
+- case "$dflt" in
+- *-fstack-protector*) ;; # Don't add it again
+- *) dflt="$dflt -fstack-protector" ;;
+- esac
+- ;;
+-esac
++#case "$ccflags" in
++#*-fstack-protector*)
++# case "$dflt" in
++# *-fstack-protector*) ;; # Don't add it again
++# *) dflt="$dflt -fstack-protector" ;;
++# esac
++# ;;
++#esac
+
+ : Try to guess additional flags to pick up local libraries.
+ for thislibdir in $libpth; do
+@@ -8107,14 +8107,14 @@ EOM
+ ''|' ') dflt='none' ;;
+ esac
+
+- case "$ldflags" in
+- *-fstack-protector*)
+- case "$dflt" in
+- *-fstack-protector*) ;; # Don't add it again
+- *) dflt="$dflt -fstack-protector" ;;
+- esac
+- ;;
+- esac
++# case "$ldflags" in
++# *-fstack-protector*)
++# case "$dflt" in
++# *-fstack-protector*) ;; # Don't add it again
++# *) dflt="$dflt -fstack-protector" ;;
++# esac
++# ;;
++# esac
+
+
+ rp="Any special flags to pass to $ld to create a dynamically loaded library?"
diff --git a/package/python2/Makefile b/package/python2/Makefile
index 4c72c2e1c..200e9d225 100644
--- a/package/python2/Makefile
+++ b/package/python2/Makefile
@@ -36,6 +36,7 @@ CONFIGURE_ARGS:= --with-threads \
--without-cxx-main
post-extract:
+ $(CP) ./files/posixmodule.c ${WRKBUILD}/Modules/posixmodule.c
$(CP) ./files/python-config.in ${WRKBUILD}/Misc/python-config.in
(cd ${WRKBUILD}; rm -rf config.{cache,status} ; \
OPT="$(CFLAGS_FOR_BUILD)" \
diff --git a/package/python2/files/posixmodule.c b/package/python2/files/posixmodule.c
new file mode 100644
index 000000000..312861b65
--- /dev/null
+++ b/package/python2/files/posixmodule.c
@@ -0,0 +1,9365 @@
+
+/* 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_f