diff options
author | Steve Hay <steve.m.hay@googlemail.com> | 2017-02-19 13:33:37 +0000 |
---|---|---|
committer | Steve Hay <steve.m.hay@googlemail.com> | 2017-02-19 15:30:26 +0000 |
commit | 1f664ef5314fb6e438137c44c95cf5ecdbdb5e9b (patch) | |
tree | 0c788a9cfa8bc4f6e1561230cfaf8e85a421ab99 /win32 | |
parent | b3dc9cf3c7fae44f9823063eb1c1a3d593421b03 (diff) | |
download | perl-1f664ef5314fb6e438137c44c95cf5ecdbdb5e9b.tar.gz |
Add support for VS2015 (VC++ 14.0)
Due to the rewritten CRT in this version of Visual C++ it is no longer
possible (or at least not at all easy) to make use of the ioinfo struct,
which commit b47a847f62 (re-)introduced in order to fix RT#120091/118059.
Therefore, we effectively revert commit b47a847f62 for VS2015 onwards on
the basis that being able to build with VS2015 onwards is more important
than the RT#120091/118059 bug fix. This does unfortunately mean that perls
built with <=VS2013 will not be compatible with perls built with >=VS2015,
but they may well not have been compatible anyway because of the CRT
rewrite, and certainly wouldn't be compatible if perl builds with VS2015
were not supported!
See RT#125714 for more discussion about this.
Diffstat (limited to 'win32')
-rw-r--r-- | win32/GNUmakefile | 58 | ||||
-rw-r--r-- | win32/Makefile | 36 | ||||
-rw-r--r-- | win32/config_sh.PL | 14 | ||||
-rw-r--r-- | win32/makefile.mk | 36 | ||||
-rw-r--r-- | win32/perlhost.h | 6 | ||||
-rw-r--r-- | win32/win32.c | 6 | ||||
-rw-r--r-- | win32/win32.h | 95 | ||||
-rw-r--r-- | win32/win32sck.c | 10 |
8 files changed, 241 insertions, 20 deletions
diff --git a/win32/GNUmakefile b/win32/GNUmakefile index 5db9ba89ca..7a2e761e93 100644 --- a/win32/GNUmakefile +++ b/win32/GNUmakefile @@ -173,6 +173,10 @@ USE_LARGE_FILES := define #CCTYPE := MSVC120 # Visual C++ 2013 Express Edition (aka Visual C++ 12.0) (free version) #CCTYPE := MSVC120FREE +# Visual C++ 2015 (aka Visual C++ 14.0) (full version) +#CCTYPE := MSVC140 +# Visual C++ 2015 Express Edition (aka Visual C++ 14.0) (free version) +#CCTYPE := MSVC140FREE # MinGW or mingw-w64 with gcc-3.4.5 or later #CCTYPE := GCC @@ -619,7 +623,13 @@ DEFINES = -DWIN32 -D_CONSOLE -DNO_STRICT LOCDEFS = -DPERLDLL -DPERL_CORE CXX_FLAG = -TP -EHsc +ifeq ($(CCTYPE),MSVC140) +LIBC = ucrt.lib +else ifeq ($(CCTYPE),MSVC140FREE) +LIBC = ucrt.lib +else LIBC = msvcrt.lib +endif ifeq ($(CFG),Debug) OPTIMIZE = -Od -MD -Zi -DDEBUGGING @@ -628,7 +638,13 @@ else ifeq ($(CFG),DebugSymbols) OPTIMIZE = -Od -MD -Zi LINK_DBG = -debug else ifeq ($(CFG),DebugFull) +ifeq ($(CCTYPE),MSVC140) +LIBC = ucrtd.lib +else ifeq ($(CCTYPE),MSVC140FREE) +LIBC = ucrtd.lib +else LIBC = msvcrtd.lib +endif OPTIMIZE = -Od -MDd -Zi -D_DEBUG -DDEBUGGING LINK_DBG = -debug else @@ -661,6 +677,13 @@ ifeq ($(PREMSVC80),undef) DEFINES += -D_CRT_SECURE_NO_DEPRECATE -D_CRT_NONSTDC_NO_DEPRECATE endif +# Likewise for deprecated Winsock APIs in VC++ 14.0 for now. +ifeq ($(CCTYPE),MSVC140) +DEFINES = $(DEFINES) -D_WINSOCK_DEPRECATED_NO_WARNINGS +else ifeq ($(CCTYPE),MSVC140FREE) +DEFINES = $(DEFINES) -D_WINSOCK_DEPRECATED_NO_WARNINGS +endif + # In VS 2005 (VC++ 8.0) Microsoft changes time_t from 32-bit to # 64-bit, even in 32-bit mode. It also provides the _USE_32BIT_TIME_T # preprocessor option to revert back to the old functionality for @@ -680,6 +703,20 @@ LIBBASEFILES = oldnames.lib kernel32.lib user32.lib gdi32.lib winspool.lib \ netapi32.lib uuid.lib ws2_32.lib mpr.lib winmm.lib version.lib \ odbc32.lib odbccp32.lib comctl32.lib +ifeq ($(CCTYPE),MSVC140) +ifeq ($(CFG),DebugFull) +LIBBASEFILES += msvcrtd.lib vcruntimed.lib +else +LIBBASEFILES += msvcrt.lib vcruntime.lib +endif +else ifeq ($(CCTYPE),MSVC140FREE) +ifeq ($(CFG),DebugFull) +LIBBASEFILES += msvcrtd.lib vcruntimed.lib +else +LIBBASEFILES += msvcrt.lib vcruntime.lib +endif +endif + # Avoid __intel_new_proc_init link error for libircmt. # libmmd is /MD equivelent, other variants exist. # libmmd is Intel C's math addon funcs to MS CRT, contains long doubles, C99, @@ -1240,6 +1277,27 @@ $(MINIDIR)\.exists : $(CFGH_TMPL) echo #undef NVff&& \ echo #undef NVgf&& \ echo #undef USE_LONG_DOUBLE)>> config.h +ifeq ($(CCTYPE),MSVC140) + @(echo #undef FILE_ptr&& \ + echo #undef FILE_cnt&& \ + echo #undef FILE_base&& \ + echo #undef FILE_bufsiz&& \ + echo #define FILE_ptr(fp) PERLIO_FILE_ptr(fp)&& \ + echo #define FILE_cnt(fp) PERLIO_FILE_cnt(fp)&& \ + echo #define FILE_base(fp) PERLIO_FILE_base(fp)&& \ + echo #define FILE_bufsiz(fp) (PERLIO_FILE_cnt(fp) + PERLIO_FILE_ptr(fp) - PERLIO_FILE_base(fp))&& \ + echo #define I_STDBOOL)>> config.h +else ifeq ($(CCTYPE),MSVC140FREE) + @(echo #undef FILE_ptr&& \ + echo #undef FILE_cnt&& \ + echo #undef FILE_base&& \ + echo #undef FILE_bufsiz&& \ + echo #define FILE_ptr(fp) PERLIO_FILE_ptr(fp)&& \ + echo #define FILE_cnt(fp) PERLIO_FILE_cnt(fp)&& \ + echo #define FILE_base(fp) PERLIO_FILE_base(fp)&& \ + echo #define FILE_bufsiz(fp) (PERLIO_FILE_cnt(fp) + PERLIO_FILE_ptr(fp) - PERLIO_FILE_base(fp))&& \ + echo #define I_STDBOOL)>> config.h +endif ifeq ($(USE_LARGE_FILES),define) @(echo #define Off_t $(INT64)&& \ echo #define LSEEKSIZE ^8&& \ diff --git a/win32/Makefile b/win32/Makefile index 676e7f6943..6c8f7f6eec 100644 --- a/win32/Makefile +++ b/win32/Makefile @@ -133,6 +133,10 @@ CCTYPE = MSVC60 #CCTYPE = MSVC120 # Visual C++ 2013 Express Edition (aka Visual C++ 12.0) (free version) #CCTYPE = MSVC120FREE +# Visual C++ 2015 (aka Visual C++ 14.0) (full version) +#CCTYPE = MSVC140 +# Visual C++ 2015 Express Edition (aka Visual C++ 14.0) (free version) +#CCTYPE = MSVC140FREE # # If you are using Intel C++ Compiler uncomment this @@ -467,7 +471,11 @@ DEFINES = -DWIN32 -D_CONSOLE -DNO_STRICT LOCDEFS = -DPERLDLL -DPERL_CORE CXX_FLAG = -TP -EHsc +!IF "$(CCTYPE)" == "MSVC140" || "$(CCTYPE)" == "MSVC140FREE" +LIBC = ucrt.lib +!ELSE LIBC = msvcrt.lib +!ENDIF !IF "$(CFG)" == "Debug" OPTIMIZE = -Od -MD -Zi -DDEBUGGING @@ -478,7 +486,11 @@ OPTIMIZE = -Od -MD -Zi LINK_DBG = -debug !ELSE !IF "$(CFG)" == "DebugFull" +!IF "$(CCTYPE)" == "MSVC140" || "$(CCTYPE)" == "MSVC140FREE" +LIBC = ucrtd.lib +!ELSE LIBC = msvcrtd.lib +!ENDIF OPTIMIZE = -Od -MDd -Zi -D_DEBUG -DDEBUGGING LINK_DBG = -debug !ELSE @@ -513,6 +525,11 @@ OPTIMIZE = $(OPTIMIZE) -fp:precise DEFINES = $(DEFINES) -D_CRT_SECURE_NO_DEPRECATE -D_CRT_NONSTDC_NO_DEPRECATE !ENDIF +# Likewise for deprecated Winsock APIs in VC++ 14.0 for now. +!IF "$(CCTYPE)" == "MSVC140" || "$(CCTYPE)" == "MSVC140FREE" +DEFINES = $(DEFINES) -D_WINSOCK_DEPRECATED_NO_WARNINGS +!ENDIF + # In VS 2005 (VC++ 8.0) Microsoft changes time_t from 32-bit to # 64-bit, even in 32-bit mode. It also provides the _USE_32BIT_TIME_T # preprocessor option to revert back to the old functionality for @@ -533,6 +550,14 @@ LIBBASEFILES = \ netapi32.lib uuid.lib ws2_32.lib mpr.lib winmm.lib \ version.lib odbc32.lib odbccp32.lib comctl32.lib +!IF "$(CCTYPE)" == "MSVC140" || "$(CCTYPE)" == "MSVC140FREE" +! IF "$(CFG)" == "DebugFull" +LIBBASEFILES = $(LIBBASEFILES) msvcrtd.lib vcruntimed.lib +! ELSE +LIBBASEFILES = $(LIBBASEFILES) msvcrt.lib vcruntime.lib +! ENDIF +!ENDIF + # Avoid __intel_new_proc_init link error for libircmt. # libmmd is /MD equivelent, other variants exist. # libmmd is Intel C's math addon funcs to MS CRT, contains long doubles, C99, @@ -928,6 +953,17 @@ perlglob$(o) : perlglob.c @echo.>>$@ @echo #ifndef _config_h_footer_>>$@ @echo #define _config_h_footer_>>$@ +!IF "$(CCTYPE)" == "MSVC140" || "$(CCTYPE)" == "MSVC140FREE" + @echo #undef FILE_ptr>>$@ + @echo #define FILE_ptr(fp) PERLIO_FILE_ptr(fp)>>$@ + @echo #undef FILE_cnt>>$@ + @echo #define FILE_cnt(fp) PERLIO_FILE_cnt(fp)>>$@ + @echo #undef FILE_base>>$@ + @echo #define FILE_base(fp) PERLIO_FILE_base(fp)>>$@ + @echo #undef FILE_bufsiz>>$@ + @echo #define FILE_bufsiz(fp) (PERLIO_FILE_cnt(fp) + PERLIO_FILE_ptr(fp) - PERLIO_FILE_base(fp))>>$@ + @echo #define I_STDBOOL>>$@ +!ENDIF @echo #undef Off_t>>$@ @echo #undef LSEEKSIZE>>$@ @echo #undef Off_t_size>>$@ diff --git a/win32/config_sh.PL b/win32/config_sh.PL index c4a311266d..8d6f7383fa 100644 --- a/win32/config_sh.PL +++ b/win32/config_sh.PL @@ -277,6 +277,13 @@ if ($opt{cc} =~ /\bcl/ and $opt{ccversion} =~ /^(\d+)/) { if($ccversion < 13) { #VC6 $opt{ar} ='lib'; } + if ($ccversion >= 19) { # VC14 + $opt{stdio_base} = 'PERLIO_FILE_base(fp)'; + $opt{stdio_bufsiz} = '(PERLIO_FILE_cnt(fp) + PERLIO_FILE_ptr(fp) - PERLIO_FILE_base(fp))'; + $opt{stdio_cnt} = 'PERLIO_FILE_cnt(fp)'; + $opt{stdio_ptr} = 'PERLIO_FILE_ptr(fp)'; + $opt{i_stdbool} = 'define'; + } } #find out which MSVC this ICC is using elsif ($opt{cc} =~ /\bicl/) { @@ -286,6 +293,13 @@ elsif ($opt{cc} =~ /\bicl/) { $opt{sGMTIME_max} = 32535291599; $opt{sLOCALTIME_max} = 32535244799; } + if ($num_ver =~ /^(\d+)/ && $1 >= 19) { # VC14 + $opt{stdio_base} = 'PERLIO_FILE_base(fp)'; + $opt{stdio_bufsiz} = '(PERLIO_FILE_cnt(fp) + PERLIO_FILE_ptr(fp) - PERLIO_FILE_base(fp))'; + $opt{stdio_cnt} = 'PERLIO_FILE_cnt(fp)'; + $opt{stdio_ptr} = 'PERLIO_FILE_ptr(fp)'; + $opt{i_stdbool} = 'define'; + } $opt{ar} ='xilib'; } diff --git a/win32/makefile.mk b/win32/makefile.mk index 3864e361ee..318b13f688 100644 --- a/win32/makefile.mk +++ b/win32/makefile.mk @@ -145,6 +145,10 @@ USE_LARGE_FILES *= define #CCTYPE = MSVC120 # Visual C++ 2013 Express Edition (aka Visual C++ 12.0) (free version) #CCTYPE = MSVC120FREE +# Visual C++ 2015 (aka Visual C++ 14.0) (full version) +#CCTYPE = MSVC140 +# Visual C++ 2015 Express Edition (aka Visual C++ 14.0) (free version) +#CCTYPE = MSVC140FREE # MinGW or mingw-w64 with gcc-3.4.5 or later #CCTYPE = GCC @@ -606,7 +610,11 @@ DEFINES = -DWIN32 -D_CONSOLE -DNO_STRICT LOCDEFS = -DPERLDLL -DPERL_CORE CXX_FLAG = -TP -EHsc +.IF "$(CCTYPE)" == "MSVC140" || "$(CCTYPE)" == "MSVC140FREE" +LIBC = ucrt.lib +.ELSE LIBC = msvcrt.lib +.ENDIF .IF "$(CFG)" == "Debug" OPTIMIZE = -Od -MD -Zi -DDEBUGGING @@ -615,7 +623,11 @@ LINK_DBG = -debug OPTIMIZE = -Od -MD -Zi LINK_DBG = -debug .ELIF "$(CFG)" == "DebugFull" +.IF "$(CCTYPE)" == "MSVC140" || "$(CCTYPE)" == "MSVC140FREE" +LIBC = ucrtd.lib +.ELSE LIBC = msvcrtd.lib +.ENDIF OPTIMIZE = -Od -MDd -Zi -D_DEBUG -DDEBUGGING LINK_DBG = -debug .ELSE @@ -648,6 +660,11 @@ OPTIMIZE += -fp:precise DEFINES += -D_CRT_SECURE_NO_DEPRECATE -D_CRT_NONSTDC_NO_DEPRECATE .ENDIF +# Likewise for deprecated Winsock APIs in VC++ 14.0 for now. +.IF "$(CCTYPE)" == "MSVC140" || "$(CCTYPE)" == "MSVC140FREE" +DEFINES = $(DEFINES) -D_WINSOCK_DEPRECATED_NO_WARNINGS +.ENDIF + # In VS 2005 (VC++ 8.0) Microsoft changes time_t from 32-bit to # 64-bit, even in 32-bit mode. It also provides the _USE_32BIT_TIME_T # preprocessor option to revert back to the old functionality for @@ -667,6 +684,14 @@ LIBBASEFILES = oldnames.lib kernel32.lib user32.lib gdi32.lib winspool.lib \ netapi32.lib uuid.lib ws2_32.lib mpr.lib winmm.lib version.lib \ odbc32.lib odbccp32.lib comctl32.lib +.IF "$(CCTYPE)" == "MSVC140" || "$(CCTYPE)" == "MSVC140FREE" +.IF "$(CFG)" == "DebugFull" +LIBBASEFILES += msvcrtd.lib vcruntimed.lib +.ELSE +LIBBASEFILES += msvcrt.lib vcruntime.lib +.ENDIF +.ENDIF + # Avoid __intel_new_proc_init link error for libircmt. # libmmd is /MD equivelent, other variants exist. # libmmd is Intel C's math addon funcs to MS CRT, contains long doubles, C99, @@ -1208,6 +1233,17 @@ $(MINIDIR)\.exists : $(CFGH_TMPL) echo #undef NVgf&& \ echo #undef USE_LONG_DOUBLE&& \ echo #undef USE_CPLUSPLUS)>> config.h +.IF "$(CCTYPE)" == "MSVC140" || "$(CCTYPE)" == "MSVC140FREE" + @(echo #undef FILE_ptr&& \ + echo #undef FILE_cnt&& \ + echo #undef FILE_base&& \ + echo #undef FILE_bufsiz&& \ + echo #define FILE_ptr(fp) PERLIO_FILE_ptr(fp)&& \ + echo #define FILE_cnt(fp) PERLIO_FILE_cnt(fp)&& \ + echo #define FILE_base(fp) PERLIO_FILE_base(fp)&& \ + echo #define FILE_bufsiz(fp) (PERLIO_FILE_cnt(fp) + PERLIO_FILE_ptr(fp) - PERLIO_FILE_base(fp))&& \ + echo #define I_STDBOOL)>> config.h +.ENDIF .IF "$(USE_LARGE_FILES)"=="define" @(echo #define Off_t $(INT64)&& \ echo #define LSEEKSIZE ^8&& \ diff --git a/win32/perlhost.h b/win32/perlhost.h index 9963319a92..84b08c9b90 100644 --- a/win32/perlhost.h +++ b/win32/perlhost.h @@ -836,15 +836,15 @@ PerlStdIOFdupopen(struct IPerlStdIO* piPerl, FILE* pf) int fileno = win32_dup(win32_fileno(pf)); /* open the file in the same mode */ - if((pf)->_flag & _IOREAD) { + if (PERLIO_FILE_flag(pf) & PERLIO_FILE_flag_RD) { mode[0] = 'r'; mode[1] = 0; } - else if((pf)->_flag & _IOWRT) { + else if (PERLIO_FILE_flag(pf) & PERLIO_FILE_flag_WR) { mode[0] = 'a'; mode[1] = 0; } - else if((pf)->_flag & _IORW) { + else if (PERLIO_FILE_flag(pf) & PERLIO_FILE_flag_RW) { mode[0] = 'r'; mode[1] = '+'; mode[2] = 0; diff --git a/win32/win32.c b/win32/win32.c index 6ac73e2af0..39819212d2 100644 --- a/win32/win32.c +++ b/win32/win32.c @@ -4161,15 +4161,15 @@ win32_fdupopen(FILE *pf) int fileno = win32_dup(win32_fileno(pf)); /* open the file in the same mode */ - if((pf)->_flag & _IOREAD) { + if (PERLIO_FILE_flag(pf) & PERLIO_FILE_flag_RD) { mode[0] = 'r'; mode[1] = 0; } - else if((pf)->_flag & _IOWRT) { + else if (PERLIO_FILE_flag(pf) & PERLIO_FILE_flag_WR) { mode[0] = 'a'; mode[1] = 0; } - else if((pf)->_flag & _IORW) { + else if (PERLIO_FILE_flag(pf) & PERLIO_FILE_flag_RW) { mode[0] = 'r'; mode[1] = '+'; mode[2] = 0; diff --git a/win32/win32.h b/win32/win32.h index 9b79e009f1..6de9c9b726 100644 --- a/win32/win32.h +++ b/win32/win32.h @@ -262,13 +262,13 @@ typedef unsigned short mode_t; #define snprintf _snprintf #define vsnprintf _vsnprintf -/* on VC2003, msvcrt.lib is missing these symbols */ +/* on VS2003, msvcrt.lib is missing these symbols */ #if _MSC_VER >= 1300 && _MSC_VER < 1400 # pragma intrinsic(_rotl64,_rotr64) #endif -# pragma warning(push) -# pragma warning(disable:4756;disable:4056) +#pragma warning(push) +#pragma warning(disable:4756;disable:4056) PERL_STATIC_INLINE double S_Infinity() { /* this is a real C literal which can get further constant folded @@ -277,8 +277,8 @@ double S_Infinity() { folding INF is creating -INF */ return (DBL_MAX+DBL_MAX); } -# pragma warning(pop) -# define NV_INF S_Infinity() +#pragma warning(pop) +#define NV_INF S_Infinity() /* selectany allows duplicate and unused data symbols to be removed by VC linker, if this were static, each translation unit will have its own, @@ -290,10 +290,64 @@ double S_Infinity() { that DLL actually uses __PL_nan_u */ extern const __declspec(selectany) union { unsigned __int64 __q; double __d; } __PL_nan_u = { 0x7FF8000000000000UI64 }; -# define NV_NAN ((NV)__PL_nan_u.__d) +#define NV_NAN ((NV)__PL_nan_u.__d) + +/* The CRT was rewritten in VS2015. */ +#if _MSC_VER >= 1900 + +/* No longer declared in stdio.h */ +char *gets(char* buffer); + +#define tzname _tzname + +/* From corecrt_internal_stdio.h: */ +typedef struct +{ + union + { + FILE _public_file; + char* _ptr; + }; + + char* _base; + int _cnt; + long _flags; + long _file; + int _charbuf; + int _bufsiz; + char* _tmpfname; + CRITICAL_SECTION _lock; +} __crt_stdio_stream_data; + +#define PERLIO_FILE_flag_RD 0x0001 /* _IOREAD */ +#define PERLIO_FILE_flag_WR 0x0002 /* _IOWRITE */ +#define PERLIO_FILE_flag_RW 0x0004 /* _IOUPDATE */ +#define PERLIO_FILE_ptr(f) (((__crt_stdio_stream_data*)(f))->_ptr) +#define PERLIO_FILE_base(f) (((__crt_stdio_stream_data*)(f))->_base) +#define PERLIO_FILE_cnt(f) (((__crt_stdio_stream_data*)(f))->_cnt) +#define PERLIO_FILE_flag(f) ((int)(((__crt_stdio_stream_data*)(f))->_flags)) +#define PERLIO_FILE_file(f) ((int)(((__crt_stdio_stream_data*)(f))->_file)) + +#endif #endif /* _MSC_VER */ +#if (!defined(_MSC_VER)) || (defined(_MSC_VER) && _MSC_VER < 1900) + +/* Note: PERLIO_FILE_ptr/base/cnt are not actually used for GCC or <VS2015 + * since FILE_ptr/base/cnt do the same thing anyway but it doesn't hurt to + * define them all here for completeness. */ +#define PERLIO_FILE_flag_RD _IOREAD /* 0x001 */ +#define PERLIO_FILE_flag_WR _IOWRT /* 0x002 */ +#define PERLIO_FILE_flag_RW _IORW /* 0x080 */ +#define PERLIO_FILE_ptr(f) ((f)->_ptr) +#define PERLIO_FILE_base(f) ((f)->_base) +#define PERLIO_FILE_cnt(f) ((f)->_cnt) +#define PERLIO_FILE_flag(f) ((f)->_flag) +#define PERLIO_FILE_file(f) ((f)->_file) + +#endif + #ifdef __MINGW32__ /* Minimal Gnu-Win32 */ typedef long uid_t; @@ -545,21 +599,31 @@ void win32_wait_for_children(pTHX); # define PERL_WAIT_FOR_CHILDREN win32_wait_for_children(aTHX) #endif +/* The following ioinfo struct manipulations had been removed but were + * reinstated to fix RT#120091/118059. However, they do not work with + * the rewritten CRT in VS2015 so they are removed once again for VS2015 + * onwards, which will therefore suffer from the reintroduction of the + * close socket bug. */ +#if (!defined(_MSC_VER)) || (defined(_MSC_VER) && _MSC_VER < 1900) + #ifdef PERL_CORE + /* C doesn't like repeat struct definitions */ #if defined(__MINGW32__) && (__MINGW32_MAJOR_VERSION>=3) -#undef _CRTIMP +# undef _CRTIMP #endif #ifndef _CRTIMP -#define _CRTIMP __declspec(dllimport) +# define _CRTIMP __declspec(dllimport) #endif -/* VV 2005 has multiple ioinfo struct definitions through VC 2005's release life - * VC 2008-2012 have been stable but do not assume future VCs will have the +/* VS2005 has multiple ioinfo struct definitions through VS2005's release life + * VS2008-2012 have been stable but do not assume future VSs will have the * same ioinfo struct, just because past struct stability. If research is done - * on the CRTs of future VS, the version check can be bumped up so the newer - * VC uses a fixed ioinfo size. + * on the CRTs of future VSs, the version check can be bumped up so the newer + * VS uses a fixed ioinfo size. (Actually, only VS2013 (_MSC_VER 1800) hasn't + * been looked at; after that we cannot use the ioinfo struct anyway (see the + * #if above).) */ #if ! (_MSC_VER < 1400 || (_MSC_VER >= 1500 && _MSC_VER <= 1700) \ || defined(__MINGW32__)) @@ -582,7 +646,7 @@ typedef struct { # if _MSC_VER >= 1400 && _MSC_VER < 1500 # error "This ioinfo struct is incomplete for Visual C 2005" # endif -/* VC 2005 CRT has at least 3 different definitions of this struct based on the +/* VS2005 CRT has at least 3 different definitions of this struct based on the * CRT DLL's build number. */ # if _MSC_VER >= 1500 # ifndef _SAFECRT_IMPL @@ -636,9 +700,12 @@ EXTERN_C _CRTIMP ioinfo* __pioinfo[]; #endif /* since we are not doing a dup2(), this works fine */ -# define _set_osfhnd(fh, osfh) (void)(_osfhnd(fh) = (intptr_t)osfh) +#define _set_osfhnd(fh, osfh) (void)(_osfhnd(fh) = (intptr_t)osfh) + #endif /* PERL_CORE */ +#endif /* !defined(_MSC_VER) || _MSC_VER<1900 */ + /* IO.xs and POSIX.xs define PERLIO_NOT_STDIO to 1 */ #if defined(PERL_EXT_IO) || defined(PERL_EXT_POSIX) #undef PERLIO_NOT_STDIO diff --git a/win32/win32sck.c b/win32/win32sck.c index 8eba4cd186..d9d7f3692b 100644 --- a/win32/win32sck.c +++ b/win32/win32sck.c @@ -694,10 +694,15 @@ int my_close(int fd) int err; err = closesocket(osf); if (err == 0) { +#ifdef _set_osfhnd assert(_osfhnd(fd) == osf); /* catch a bad ioinfo struct def */ /* don't close freed handle */ _set_osfhnd(fd, INVALID_HANDLE_VALUE); return close(fd); +#else + (void)close(fd); /* handle already closed, ignore error */ + return 0; +#endif } else if (err == SOCKET_ERROR) { int wsaerr = WSAGetLastError(); @@ -726,10 +731,15 @@ my_fclose (FILE *pf) win32_fflush(pf); err = closesocket(osf); if (err == 0) { +#ifdef _set_osfhnd assert(_osfhnd(win32_fileno(pf)) == osf); /* catch a bad ioinfo struct def */ /* don't close freed handle */ _set_osfhnd(win32_fileno(pf), INVALID_HANDLE_VALUE); return fclose(pf); +#else + (void)fclose(pf); /* handle already closed, ignore error */ + return 0; +#endif } else if (err == SOCKET_ERROR) { int wsaerr = WSAGetLastError(); |