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