|
|
|
@ -44,7 +44,7 @@ _Py_device_encoding(int fd) |
|
|
|
#endif |
|
|
|
int valid; |
|
|
|
_Py_BEGIN_SUPPRESS_IPH |
|
|
|
valid = _PyVerify_fd(fd) && isatty(fd); |
|
|
|
valid = isatty(fd); |
|
|
|
_Py_END_SUPPRESS_IPH |
|
|
|
if (!valid) |
|
|
|
Py_RETURN_NONE; |
|
|
|
@ -613,13 +613,9 @@ _Py_fstat_noraise(int fd, struct _Py_stat_struct *status) |
|
|
|
HANDLE h; |
|
|
|
int type; |
|
|
|
|
|
|
|
if (!_PyVerify_fd(fd)) |
|
|
|
h = INVALID_HANDLE_VALUE; |
|
|
|
else { |
|
|
|
_Py_BEGIN_SUPPRESS_IPH |
|
|
|
h = (HANDLE)_get_osfhandle(fd); |
|
|
|
_Py_END_SUPPRESS_IPH |
|
|
|
} |
|
|
|
_Py_BEGIN_SUPPRESS_IPH |
|
|
|
h = (HANDLE)_get_osfhandle(fd); |
|
|
|
_Py_END_SUPPRESS_IPH |
|
|
|
|
|
|
|
if (h == INVALID_HANDLE_VALUE) { |
|
|
|
/* errno is already set by _get_osfhandle, but we also set |
|
|
|
@ -742,12 +738,6 @@ get_inheritable(int fd, int raise) |
|
|
|
HANDLE handle; |
|
|
|
DWORD flags; |
|
|
|
|
|
|
|
if (!_PyVerify_fd(fd)) { |
|
|
|
if (raise) |
|
|
|
PyErr_SetFromErrno(PyExc_OSError); |
|
|
|
return -1; |
|
|
|
} |
|
|
|
|
|
|
|
_Py_BEGIN_SUPPRESS_IPH |
|
|
|
handle = (HANDLE)_get_osfhandle(fd); |
|
|
|
_Py_END_SUPPRESS_IPH |
|
|
|
@ -819,12 +809,6 @@ set_inheritable(int fd, int inheritable, int raise, int *atomic_flag_works) |
|
|
|
} |
|
|
|
|
|
|
|
#ifdef MS_WINDOWS |
|
|
|
if (!_PyVerify_fd(fd)) { |
|
|
|
if (raise) |
|
|
|
PyErr_SetFromErrno(PyExc_OSError); |
|
|
|
return -1; |
|
|
|
} |
|
|
|
|
|
|
|
_Py_BEGIN_SUPPRESS_IPH |
|
|
|
handle = (HANDLE)_get_osfhandle(fd); |
|
|
|
_Py_END_SUPPRESS_IPH |
|
|
|
@ -1190,14 +1174,6 @@ _Py_read(int fd, void *buf, size_t count) |
|
|
|
* handler raised an exception. */ |
|
|
|
assert(!PyErr_Occurred()); |
|
|
|
|
|
|
|
if (!_PyVerify_fd(fd)) { |
|
|
|
/* save/restore errno because PyErr_SetFromErrno() can modify it */ |
|
|
|
err = errno; |
|
|
|
PyErr_SetFromErrno(PyExc_OSError); |
|
|
|
errno = err; |
|
|
|
return -1; |
|
|
|
} |
|
|
|
|
|
|
|
#ifdef MS_WINDOWS |
|
|
|
if (count > INT_MAX) { |
|
|
|
/* On Windows, the count parameter of read() is an int */ |
|
|
|
@ -1251,16 +1227,6 @@ _Py_write_impl(int fd, const void *buf, size_t count, int gil_held) |
|
|
|
int err; |
|
|
|
int async_err = 0; |
|
|
|
|
|
|
|
if (!_PyVerify_fd(fd)) { |
|
|
|
if (gil_held) { |
|
|
|
/* save/restore errno because PyErr_SetFromErrno() can modify it */ |
|
|
|
err = errno; |
|
|
|
PyErr_SetFromErrno(PyExc_OSError); |
|
|
|
errno = err; |
|
|
|
} |
|
|
|
return -1; |
|
|
|
} |
|
|
|
|
|
|
|
_Py_BEGIN_SUPPRESS_IPH |
|
|
|
#ifdef MS_WINDOWS |
|
|
|
if (count > 32767 && isatty(fd)) { |
|
|
|
@ -1497,11 +1463,6 @@ _Py_dup(int fd) |
|
|
|
assert(PyGILState_Check()); |
|
|
|
#endif |
|
|
|
|
|
|
|
if (!_PyVerify_fd(fd)) { |
|
|
|
PyErr_SetFromErrno(PyExc_OSError); |
|
|
|
return -1; |
|
|
|
} |
|
|
|
|
|
|
|
#ifdef MS_WINDOWS |
|
|
|
_Py_BEGIN_SUPPRESS_IPH |
|
|
|
handle = (HANDLE)_get_osfhandle(fd); |
|
|
|
@ -1624,84 +1585,3 @@ error: |
|
|
|
return -1; |
|
|
|
} |
|
|
|
#endif |
|
|
|
|
|
|
|
#if defined _MSC_VER && _MSC_VER >= 1400 && _MSC_VER < 1900 |
|
|
|
/* Legacy implementation of _PyVerify_fd while transitioning to |
|
|
|
* MSVC 14.0. This should eventually be removed. (issue23524) |
|
|
|
*/ |
|
|
|
|
|
|
|
/* Microsoft CRT in VS2005 and higher will verify that a filehandle is |
|
|
|
* valid and raise 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_ARRAYS 64 |
|
|
|
#define IOINFO_ARRAY_ELTS (1 << IOINFO_L2E) |
|
|
|
#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 size_t 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; |
|
|
|
} |
|
|
|
|
|
|
|
#endif /* defined _MSC_VER && _MSC_VER >= 1400 && _MSC_VER < 1900 */ |