Index: Modules/posixmodule.c =================================================================== --- Modules/posixmodule.c (revision 69275) +++ Modules/posixmodule.c (working copy) @@ -343,6 +343,35 @@ #endif #endif +#ifdef _MSC_VER /* touch MSVCRT internal */ +typedef struct { + long osfhnd; + char osfile; + char pipech; +#ifdef _MT + int lockinitflag; + CRITICAL_SECTION lock; +#endif /* _MT */ + } ioinfo; +extern __declspec(dllimport) ioinfo * __pioinfo[]; +#define IOINFO_ARRAYS 64 +#define IOINFO_L2E 5 +#define FOPEN 0x01 +static int +check_fd(int fd) +{ + const int i1 = fd >> IOINFO_L2E; + const int i2 = fd & ((1 << IOINFO_L2E) - 1); + + if (0 <= i1 && i1 < IOINFO_ARRAYS && __pioinfo[i1] && (__pioinfo[i1][i2].osfile & FOPEN)) + return 1; + else { + errno = EBADF; + return 0; + } +} +#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 @@ -581,6 +610,10 @@ fd = PyObject_AsFileDescriptor(fdobj); if (fd < 0) return NULL; +#ifdef _MSC_VER + if (!check_fd(fd)) + return posix_error(); +#endif Py_BEGIN_ALLOW_THREADS res = (*func)(fd); Py_END_ALLOW_THREADS @@ -6188,6 +6221,10 @@ int fd, res; if (!PyArg_ParseTuple(args, "i:close", &fd)) return NULL; +#ifdef _MSC_VER + if (!check_fd(fd)) + return posix_error(); +#endif Py_BEGIN_ALLOW_THREADS res = close(fd); Py_END_ALLOW_THREADS @@ -6210,6 +6247,9 @@ return NULL; Py_BEGIN_ALLOW_THREADS for (i = fd_from; i < fd_to; i++) +#ifdef _MSC_VER + if (check_fd(i)) +#endif close(i); Py_END_ALLOW_THREADS Py_RETURN_NONE; @@ -6226,6 +6266,10 @@ int fd; if (!PyArg_ParseTuple(args, "i:dup", &fd)) return NULL; +#ifdef _MSC_VER + if (!check_fd(fd)) + return posix_error(); +#endif Py_BEGIN_ALLOW_THREADS fd = dup(fd); Py_END_ALLOW_THREADS @@ -6245,6 +6289,10 @@ int fd, fd2, res; if (!PyArg_ParseTuple(args, "ii:dup2", &fd, &fd2)) return NULL; +#ifdef _MSC_VER + if (!check_fd(fd) || !check_fd(fd2)) + return posix_error(); +#endif Py_BEGIN_ALLOW_THREADS res = dup2(fd, fd2); Py_END_ALLOW_THREADS @@ -6289,6 +6337,10 @@ if (PyErr_Occurred()) return NULL; +#ifdef _MSC_VER + if (!check_fd(fd)) + return posix_error(); +#endif Py_BEGIN_ALLOW_THREADS #if defined(MS_WIN64) || defined(MS_WINDOWS) res = _lseeki64(fd, pos, how); @@ -6325,6 +6377,10 @@ buffer = PyString_FromStringAndSize((char *)NULL, size); if (buffer == NULL) return NULL; +#ifdef _MSC_VER + if (!check_fd(fd)) + return posix_error(); +#endif Py_BEGIN_ALLOW_THREADS n = read(fd, PyString_AsString(buffer), size); Py_END_ALLOW_THREADS @@ -6351,6 +6407,10 @@ if (!PyArg_ParseTuple(args, "is*:write", &fd, &pbuf)) return NULL; +#ifdef _MSC_VER + if (!check_fd(fd)) + return posix_error(); +#endif Py_BEGIN_ALLOW_THREADS size = write(fd, pbuf.buf, (size_t)pbuf.len); Py_END_ALLOW_THREADS @@ -6377,6 +6437,10 @@ /* on OpenVMS we must ensure that all bytes are written to the file */ fsync(fd); #endif +#ifdef _MSC_VER + if (!check_fd(fd)) + return posix_error(); +#endif Py_BEGIN_ALLOW_THREADS res = FSTAT(fd, &st); Py_END_ALLOW_THREADS @@ -6419,6 +6483,10 @@ PyMem_FREE(mode); return NULL; } +#ifdef _MSC_VER + if (!check_fd(fd)) + return posix_error(); +#endif Py_BEGIN_ALLOW_THREADS #if !defined(MS_WINDOWS) && defined(HAVE_FCNTL_H) if (mode[0] == 'a') { @@ -6458,6 +6526,10 @@ int fd; if (!PyArg_ParseTuple(args, "i:isatty", &fd)) return NULL; +#ifdef _MSC_VER + if (!check_fd(fd)) + return PyBool_FromLong(0); +#endif return PyBool_FromLong(isatty(fd)); }