summaryrefslogtreecommitdiff
path: root/win32
diff options
context:
space:
mode:
authorSteve Hay <steve.m.hay@googlemail.com>2017-02-19 13:33:37 +0000
committerSteve Hay <steve.m.hay@googlemail.com>2017-02-19 15:30:26 +0000
commit1f664ef5314fb6e438137c44c95cf5ecdbdb5e9b (patch)
tree0c788a9cfa8bc4f6e1561230cfaf8e85a421ab99 /win32
parentb3dc9cf3c7fae44f9823063eb1c1a3d593421b03 (diff)
downloadperl-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/GNUmakefile58
-rw-r--r--win32/Makefile36
-rw-r--r--win32/config_sh.PL14
-rw-r--r--win32/makefile.mk36
-rw-r--r--win32/perlhost.h6
-rw-r--r--win32/win32.c6
-rw-r--r--win32/win32.h95
-rw-r--r--win32/win32sck.c10
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();