@@ -277,6 +277,7 @@ extern int lstat(const char *, struct stat *);
277
277
#include "osdefs.h"
278
278
#include <malloc.h>
279
279
#include <windows.h>
280
+ #include <malloc.h>
280
281
#include <shellapi.h> /* for ShellExecute() */
281
282
#define popen _popen
282
283
#define pclose _pclose
@@ -533,8 +534,28 @@ _PyInt_FromDev(PY_LONG_LONG v)
533
534
# define _PyInt_FromDev PyInt_FromLong
534
535
#endif
535
536
537
+ #ifdef _MSC_VER
538
+ #if _MSC_VER >= 1900
539
+
540
+ /* This function lets the Windows CRT validate the file handle without
541
+ terminating the process if it's invalid. */
542
+ int
543
+ _PyVerify_fd (int fd )
544
+ {
545
+ intptr_t osh ;
546
+ /* Fast check for the only condition we know */
547
+ if (fd < 0 ) {
548
+ _set_errno (EBADF );
549
+ return 0 ;
550
+ }
551
+ osh = _get_osfhandle (fd );
552
+ return osh != (intptr_t )-1 ;
553
+ }
554
+
555
+ #define _PyVerify_fd_dup2 (fd1 , fd2 ) (_PyVerify_fd(fd1) && (fd2) >= 0)
556
+
557
+ #elif _MSC_VER >= 1400
536
558
537
- #if defined _MSC_VER && _MSC_VER >= 1400
538
559
/* Microsoft CRT in VS2005 and higher will verify that a filehandle is
539
560
* valid and raise an assertion if it isn't.
540
561
* Normally, an invalid fd is likely to be a C program error and therefore
@@ -559,35 +580,18 @@ _PyInt_FromDev(PY_LONG_LONG v)
559
580
* Only the first items must be present.
560
581
*/
561
582
562
- #if _MSC_VER >= 1900
563
-
564
- typedef struct {
565
- CRITICAL_SECTION lock ;
566
- intptr_t osfhnd ;
567
- __int64 startpos ;
568
- char osfile ;
569
- } my_ioinfo ;
570
-
571
- #define IOINFO_L2E 6
572
- #define IOINFO_ARRAYS 128
573
-
574
- #else
575
-
576
583
typedef struct {
577
584
intptr_t osfhnd ;
578
585
char osfile ;
579
586
} my_ioinfo ;
580
587
581
- #define IOINFO_L2E 5
582
- #define IOINFO_ARRAYS 64
583
-
584
- #endif
585
-
586
588
extern __declspec(dllimport ) char * __pioinfo [];
587
589
#define IOINFO_ARRAY_ELTS (1 << IOINFO_L2E)
588
590
#define _NHANDLE_ (IOINFO_ARRAYS * IOINFO_ARRAY_ELTS)
589
591
#define FOPEN 0x01
590
592
#define _NO_CONSOLE_FILENO (intptr_t)-2
593
+ #define IOINFO_L2E 5
594
+ #define IOINFO_ARRAYS 64
591
595
592
596
/* This function emulates what the windows CRT does to validate file handles */
593
597
int
@@ -645,6 +649,8 @@ _PyVerify_fd_dup2(int fd1, int fd2)
645
649
#define _PyVerify_fd_dup2 (A , B ) (1)
646
650
#endif
647
651
652
+ #endif /* defined _MSC_VER */
653
+
648
654
/* Return a dictionary corresponding to the POSIX environment table */
649
655
#if defined(WITH_NEXT_FRAMEWORK ) || (defined(__APPLE__ ) && defined(Py_ENABLE_SHARED ))
650
656
/* On Darwin/MacOSX a shared library or framework has no access to
@@ -1248,14 +1254,10 @@ win32_fstat(int file_number, struct win32_stat *result)
1248
1254
1249
1255
h = (HANDLE )_get_osfhandle (file_number );
1250
1256
1251
- /* Protocol violation: we explicitly clear errno, instead of
1252
- setting it to a POSIX error. Callers should use GetLastError. */
1253
1257
errno = 0 ;
1254
1258
1255
1259
if (h == INVALID_HANDLE_VALUE ) {
1256
- /* This is really a C library error (invalid file handle).
1257
- We set the Win32 error to the closes one matching. */
1258
- SetLastError (ERROR_INVALID_HANDLE );
1260
+ errno = EBADF ;
1259
1261
return -1 ;
1260
1262
}
1261
1263
memset (result , 0 , sizeof (* result ));
@@ -1264,6 +1266,7 @@ win32_fstat(int file_number, struct win32_stat *result)
1264
1266
if (type == FILE_TYPE_UNKNOWN ) {
1265
1267
DWORD error = GetLastError ();
1266
1268
if (error != 0 ) {
1269
+ errno = EINVAL ;
1267
1270
return -1 ;
1268
1271
}
1269
1272
/* else: valid but unknown file */
@@ -1278,6 +1281,7 @@ win32_fstat(int file_number, struct win32_stat *result)
1278
1281
}
1279
1282
1280
1283
if (!GetFileInformationByHandle (h , & info )) {
1284
+ errno = EINVAL ;
1281
1285
return -1 ;
1282
1286
}
1283
1287
0 commit comments