summaryrefslogtreecommitdiff
path: root/win32
diff options
context:
space:
mode:
Diffstat (limited to 'win32')
-rw-r--r--win32/Makefile.sub73
-rwxr-xr-xwin32/configure.bat11
-rw-r--r--win32/file.c33
-rw-r--r--win32/file.h3
-rwxr-xr-xwin32/mkexports.rb2
-rw-r--r--win32/setup.mak17
-rw-r--r--win32/win32.c157
7 files changed, 215 insertions, 81 deletions
diff --git a/win32/Makefile.sub b/win32/Makefile.sub
index 7b56e43511..c73a8a4ba5 100644
--- a/win32/Makefile.sub
+++ b/win32/Makefile.sub
@@ -11,13 +11,15 @@ PATH_SEPARATOR = ;
TZ = # skip timezone tests
PWD = $(MAKEDIR)
empty =
+tooldir = $(srcdir)/tool
!ifndef MFLAGS
MFLAGS=-l
!endif
!if "$(BASERUBY)" == ""
-! if [for %I in (ruby.exe) do @echo BASERUBY = %~s$$PATH:I > baseruby.mk]
+! if [ruby $(tooldir)/missing-baseruby.bat 2> nul]
+! else if [for %I in (ruby.exe) do @echo BASERUBY = %~s$$PATH:I > baseruby.mk]
! else
! include baseruby.mk
! endif
@@ -27,7 +29,7 @@ MFLAGS=-l
BASERUBY =
!endif
!if "$(BASERUBY)" == ""
-BASERUBY = echo executable host ruby is required. use --with-baseruby option.^& exit 1
+BASERUBY = $(tooldir:/=\)\missing-baseruby.bat
HAVE_BASERUBY = no
!else
HAVE_BASERUBY = yes
@@ -158,6 +160,9 @@ OPTFLAGS = -O2b2xg-
OPTFLAGS = -O2sy-
!endif
!endif
+!if !defined(incflags)
+incflags =
+!endif
!if !defined(PLATFORM)
PLATFORM = mswin32
!endif
@@ -292,9 +297,7 @@ CXXFLAGS = $(CFLAGS)
!if !defined(LDFLAGS)
LDFLAGS = -incremental:no -debug -opt:ref -opt:icf
!endif
-!if !defined(XLDFLAGS)
-XLDFLAGS = -stack:$(STACK)
-!endif
+XLDFLAGS = -stack:$(STACK) $(XLDFLAGS)
!if !defined(RFLAGS)
RFLAGS = -r
!endif
@@ -330,8 +333,7 @@ COROUTINE_SRC = $(COROUTINE_OBJ:.obj=.asm)
COROUTINE_OBJ = coroutine/win32/Context.obj
COROUTINE_SRC = $(COROUTINE_OBJ:.obj=.asm)
!else
-COROUTINE_OBJ = coroutine/copy/Context.obj
-COROUTINE_SRC = $(COROUTINE_OBJ:.obj=.c)
+!error copy coroutine has been replaced with pthread implementation at 42130a64f02294dc8025af3a51bda518c67ab33d
!endif
COROUTINE_H = $(COROUTINE_OBJ:.obj=.h)
@@ -339,7 +341,9 @@ ARFLAGS = -machine:$(MACHINE) -out:
LD = $(CC)
LDSHARED = $(LD) -LD
XCFLAGS = -DRUBY_EXPORT $(INCFLAGS) $(XCFLAGS)
-!if $(MSC_VER) >= 1400
+!if $(MSC_VER) >= 1800
+LDFLAGS = $(LDFLAGS) -manifest:embed,ID=2
+!elseif $(MSC_VER) >= 1400
# Prevents VC++ 2005 (cl ver 14) warnings
MANIFESTTOOL = mt -nologo
LDSHARED_0 = @if exist $(@).manifest $(MINIRUBY) -run -e wait_writable -- -n 10 $@
@@ -433,8 +437,10 @@ THREAD_IMPL_SRC = thread_$(THREAD_MODEL).c
!if "$(CROSS_COMPILING)" == "yes"
PREP = $(arch)-fake.rb
+BUILTIN_BINARY = no
!else
PREP = miniruby$(EXEEXT)
+BUILTIN_BINARY = yes
!endif
!if !defined(EXTSTATIC)
@@ -482,7 +488,6 @@ EXTOBJS = dmyext.$(OBJEXT)
arch_hdrdir = $(EXTOUT)/include/$(arch)
top_srcdir = $(srcdir)
hdrdir = $(srcdir)/include
-tooldir = $(srcdir)/tool
VPATH = $(arch_hdrdir)/ruby;$(hdrdir)/ruby;$(srcdir);$(srcdir)/missing;$(win_srcdir)
!ifndef GIT
@@ -545,8 +550,9 @@ GOLF_PRELUDE_C = golf_prelude.c
RBCONFIG = ./.rbconfig.time
!if "$(GITHUB_ACTIONS)" == "true"
-ACTIONS_GROUP = @echo ^#^#[group]$(@:yes-=)
-ACTIONS_ENDGROUP = @echo ^#^#[endgroup]
+# 93(bright yellow) is copied from .github/workflows/mingw.yml
+ACTIONS_GROUP = @echo ::group::$(@:yes-=)
+ACTIONS_ENDGROUP = @echo ::endgroup::
!else
ACTIONS_GROUP = @:: $(empty)
ACTIONS_ENDGROUP = @::
@@ -678,7 +684,7 @@ $(CONFIG_H): $(MKFILES) $(srcdir)/win32/Makefile.sub $(win_srcdir)/Makefile.sub
#define _INTEGRAL_MAX_BITS 64
#endif
#define SIZEOF_OFF_T 8
-!if "$(ARCH)" == "x64"
+!if "$(TARGET_OS)" == "mswin64"
#define SIZEOF_VOIDP 8
!else
#define SIZEOF_VOIDP 4
@@ -700,7 +706,7 @@ $(CONFIG_H): $(MKFILES) $(srcdir)/win32/Makefile.sub $(win_srcdir)/Makefile.sub
#define NUM2CLOCKID(v) NUM2INT(v)
#define SIZEOF_CLOCK_T 4
#define SIZEOF_RLIM_T 0
-!if "$(ARCH)" == "x64"
+!if "$(TARGET_OS)" == "mswin64"
#define SIZEOF_SIZE_T 8
#define SIZEOF_PTRDIFF_T 8
#define SIZEOF_INTPTR_T 8
@@ -740,6 +746,7 @@ $(CONFIG_H): $(MKFILES) $(srcdir)/win32/Makefile.sub $(win_srcdir)/Makefile.sub
#define RBIMPL_ATTR_PACKED_STRUCT_END() __pragma(pack(pop))
!endif
#define RUBY_EXTERN extern __declspec(dllimport)
+#define RUBY_FUNC_EXPORTED extern __declspec(dllexport)
#define RUBY_ALIGNAS(n) __declspec(align(n))
#define RUBY_ALIGNOF __alignof
#define HAVE_DECL_SYS_NERR 1
@@ -757,6 +764,7 @@ $(CONFIG_H): $(MKFILES) $(srcdir)/win32/Makefile.sub $(win_srcdir)/Makefile.sub
#define HAVE_STRUCT_TIMESPEC
!endif
!if $(MSC_VER) >= 1600
+#define HAVE_INTTYPES_H 1
#define HAVE_STDINT_H 1
!else
#define int8_t signed char
@@ -799,7 +807,7 @@ $(CONFIG_H): $(MKFILES) $(srcdir)/win32/Makefile.sub $(win_srcdir)/Makefile.sub
#define HAVE_INTPTR_T 1
#define HAVE_UINTPTR_T 1
#define HAVE_SSIZE_T 1
-!if "$(ARCH)" == "x64"
+!if "$(TARGET_OS)" == "mswin64"
#define ssize_t __int64
#define PRI_PTR_PREFIX "I64"
!else
@@ -964,6 +972,7 @@ s,@WERRORFLAG@,$(WERRORFLAG),;t t
s,@DEFS@,$(DEFS),;t t
s,@CPPFLAGS@,$(CPPFLAGS),;t t
s,@CXXFLAGS@,$(CXXFLAGS),;t t
+s,@incflags@,$(incflags),;t t
s,@FFLAGS@,$(FFLAGS),;t t
s,@LDFLAGS@,$(LDFLAGS),;t t
s,@LIBS@,user32.lib,;t t
@@ -1071,7 +1080,7 @@ s,@LIBPATHFLAG@, -libpath:%s,;t t
s,@RPATHFLAG@,,;t t
s,@LIBARG@,%s.lib,;t t
s,@LINK_SO@,$$(LDSHARED) -Fe$$(@) $$(OBJS) $$(LIBS) $$(LOCAL_LIBS) -link $$(DLDFLAGS) -implib:$$(*F:.so=)-$$(arch).lib -pdb:$$(*F:.so=)-$$(arch).pdb -def:$$(DEFFILE),;t t
-!if $(MSC_VER) >= 1400
+!if $(MSC_VER) >= 1400 && $(MSC_VER) < 1800
s,@LINK_SO@,@if exist $$(@).manifest $$(RUBY) -run -e wait_writable -- -n 10 $$(@),;t t
s,@LINK_SO@,@if exist $$(@).manifest $(MANIFESTTOOL) -manifest $$(@).manifest -outputresource:$$(@);2,;t t
s,@LINK_SO@,@if exist $$(@).manifest $$(RM) $$(@:/=\).manifest,;t t
@@ -1137,7 +1146,8 @@ miniruby: miniruby$(EXEEXT)
miniruby$(EXEEXT):
@echo $(LIBS)
$(ECHO) linking $(@:\=/)
- $(Q) $(PURIFY) $(CC) $(MAINOBJ) $(MINIOBJS) $(COMMONOBJS) $(LIBS) -Fe$@ -link $(LDFLAGS)
+ $(Q) $(PURIFY) $(CC) $(MAINOBJ) $(MINIOBJS) $(COMMONOBJS) $(LIBS) \
+ $(OUTFLAG)$@ -link $(LDFLAGS) $(XLDFLAGS)
@$(RM) miniruby.lib miniruby.exp
$(Q) miniruby.exe -v
$(Q) $(LDSHARED_1)
@@ -1151,9 +1161,11 @@ $(PROGRAM): $(MAINOBJ) $(LIBRUBY_SO) $(RUBY_INSTALL_NAME).res
$(ECHO) linking $(@:\=/)
$(Q) $(PURIFY) $(CC) $(MAINOBJ) $(EXTOBJS) $(RUBY_INSTALL_NAME).res \
$(OUTFLAG)$@ $(LIBRUBYARG) -link $(LDFLAGS) $(XLDFLAGS)
+! if defined(LDSHARED_0)
$(Q) $(LDSHARED_0)
$(Q) $(LDSHARED_1)
$(Q) $(LDSHARED_2)
+! endif
!endif
!if "$(WPROGRAM)" != ""
@@ -1162,9 +1174,11 @@ $(WPROGRAM): $(MAINOBJ) $(WINMAINOBJ) $(LIBRUBY_SO) $(RUBYW_INSTALL_NAME).res
$(Q) $(PURIFY) $(CC) $(MAINOBJ) $(WINMAINOBJ) \
$(RUBYW_INSTALL_NAME).res $(OUTFLAG)$@ $(LIBRUBYARG) \
-link $(LDFLAGS) $(XLDFLAGS) -subsystem:Windows
+! if defined(LDSHARED_0)
$(Q) $(LDSHARED_0)
$(Q) $(LDSHARED_1)
$(Q) $(LDSHARED_2)
+! endif
!endif
!if "$(STUBPROGRAM)" != ""
@@ -1172,9 +1186,11 @@ $(STUBPROGRAM): rubystub.$(OBJEXT) $(LIBRUBY) $(LIBRUBY_SO) $(RUBY_INSTALL_NAME)
$(ECHO) linking $(@:\=/)
$(Q) $(PURIFY) $(CC) rubystub.$(OBJEXT) $(RUBY_INSTALL_NAME).res \
$(OUTFLAG)$@ $(LIBRUBYARG) -link $(LDFLAGS) $(XLDFLAGS)
+! if defined(LDSHARED_0)
$(Q) $(LDSHARED_0)
$(Q) $(LDSHARED_1)
$(Q) $(LDSHARED_2)
+! endif
!endif
!if "$(LIBRUBY_SO_UPDATE)" == ""
@@ -1201,13 +1217,16 @@ $(LIBRUBY_SO): $(LIBRUBY_A) $(DLDOBJS) $(RUBYDEF) $(RUBY_SO_NAME).res
!endif
$(ECHO) linking shared-library $(@:\=/)
$(Q) $(LDSHARED) $(DLDOBJS) $(LIBRUBY_A) \
- $(RUBY_SO_NAME).res $(SOLIBS) $(EXTSOLIBS) $(LIBS) -Fe$@ -link $(LDFLAGS) \
+ $(RUBY_SO_NAME).res $(SOLIBS) $(EXTSOLIBS) $(LIBS) \
+ $(OUTFLAG)$@ -link $(LDFLAGS) $(XLDFLAGS) \
$(LIBRUBY_DLDFLAGS)
@$(RM) dummy.lib dummy.exp
+!if defined(LDSHARED_0)
$(Q) $(LDSHARED_0)
$(Q) $(LDSHARED_1)
$(Q) $(LDSHARED_2)
# | findstr -v -c:LNK4049 -c:LNK4217
+!endif
$(RUBYDEF): $(LIBRUBY_A) $(RBCONFIG)
$(ECHO) generating $(@:\=/)
@@ -1278,6 +1297,15 @@ $(ruby_pc): $(RBCONFIG)
$(ECHO) assembling $(<:\=/)
$(Q) $(AS) $(ASFLAGS) $(XCFLAGS) $(CPPFLAGS) $(COUTFLAG)$@ -c $(<:\=/)
+{$(srcdir)/prism}.c.obj:
+ $(ECHO) compiling $(<:\=/)
+ $(Q) $(CC) $(CFLAGS) $(XCFLAGS) $(CPPFLAGS) $(COUTFLAG)$@ -c $(CSRCFLAG)$(<:\=/)
+{$(srcdir)/prism/enc}.c.obj:
+ $(ECHO) compiling $(<:\=/)
+ $(Q) $(CC) $(CFLAGS) $(XCFLAGS) $(CPPFLAGS) $(COUTFLAG)$@ -c $(CSRCFLAG)$(<:\=/)
+{$(srcdir)/prism/util}.c.obj:
+ $(ECHO) compiling $(<:\=/)
+ $(Q) $(CC) $(CFLAGS) $(XCFLAGS) $(CPPFLAGS) $(COUTFLAG)$@ -c $(CSRCFLAG)$(<:\=/)
{$(srcdir)/enc/trans}.c.obj:
$(ECHO) compiling $(<:\=/)
$(Q) $(CC) $(CFLAGS) $(XCFLAGS) $(CPPFLAGS) $(COUTFLAG)$@ -c $(CSRCFLAG)$(<:\=/)
@@ -1354,7 +1382,7 @@ probes.h: {$(VPATH)}probes.dmyh
#include "$(*F).dmyh"
<<KEEP
-INSNS = opt_sc.inc optinsn.inc optunifs.inc insns.inc insns_info.inc \
+INSNS = optinsn.inc optunifs.inc insns.inc insns_info.inc \
vmtc.inc vm.inc
!if [exit > insns_rules.mk]
@@ -1403,9 +1431,16 @@ rubyspec-capiext: $(RUBYSPEC_CAPIEXT_EXTS)
$(Q)$(MAKEDIRS) $(@D)
$(Q)echo> $*.def EXPORTS
$(Q)echo>> $*.def Init_$(*F)
- $(Q)$(LDSHARED) -Fe$(@) $(INCFLAGS) $(CFLAGS) $(CPPFLAGS) $< $(LIBRUBYARG) -link $(DLDFLAGS) $(LIBS) $(LOCAL_LIBS) -implib:$*.lib -pdb:$*.pdb -def:$*.def
+ $(Q)$(LDSHARED) -Fe$(@) $(INCFLAGS) $(CFLAGS) $(CPPFLAGS) $< $(LIBRUBYARG) -link $(DLDFLAGS) $(XLDFLAGS) $(LIBS) $(LOCAL_LIBS) -implib:$*.lib -pdb:$*.pdb -def:$*.def
+!if defined(LDSHARED_0)
$(Q)$(LDSHARED_0)
$(Q)$(LDSHARED_1)
$(Q)$(LDSHARED_2)
+!endif
exts: rubyspec-capiext
+
+yesterday:
+ for /f "usebackq" %H in \
+ (`$(GIT) -C $(srcdir) log -1 "--before=00:00+0900" "--format=%H"`) do \
+ $(GIT) -C $(srcdir) reset --hard %%H
diff --git a/win32/configure.bat b/win32/configure.bat
index 7253ade28b..dd1a917adc 100755
--- a/win32/configure.bat
+++ b/win32/configure.bat
@@ -7,6 +7,9 @@ for %%I in (%0) do if /%%~dpI/ == /%CD%\/ (
exit /b 999
)
+set XINCFLAGS=
+set XLDFLAGS=
+
echo> ~tmp~.mak ####
echo>> ~tmp~.mak conf = %0
echo>> ~tmp~.mak $(conf): nul
@@ -48,7 +51,9 @@ if "%1" == "--with-git" goto :git
if "%1" == "--without-git" goto :nogit
if "%1" == "--without-ext" goto :witharg
if "%1" == "--without-extensions" goto :witharg
+if "%1" == "--with-opt-dir" goto :opt-dir
if "%1" == "--with-gmp" goto :gmp
+if "%1" == "--with-gmp-dir" goto :gmp-dir
if "%opt:~0,10%" == "--without-" goto :withoutarg
if "%opt:~0,7%" == "--with-" goto :witharg
if "%1" == "-h" goto :help
@@ -217,6 +222,10 @@ goto :loop ;
shift
shift
goto :loop ;
+:gmp-dir
+:opt-dir
+ set XINCFLAGS=%XINCFLAGS% -I%2/include
+ set XLDFLAGS=%XLDFLAGS% -libpath:%2/lib
:witharg
echo>>confargs.tmp %1=%2\
set witharg=1
@@ -263,6 +272,8 @@ cl -EP confargs.c > ~setup~.mak 2>nul
if exist pathlist.tmp echo>>~setup~.mak PATH = $(pathlist:;=/bin;)$(PATH)
if exist pathlist.tmp echo>>~setup~.mak INCLUDE = $(pathlist:;=/include;)
if exist pathlist.tmp echo>>~setup~.mak LIB = $(pathlist:;=/lib;)
+echo>>~setup~.mak XINCFLAGS = %XINCFLAGS%
+echo>>~setup~.mak XLDFLAGS = %XLDFLAGS%
type>>~setup~.mak ~tmp~.mak
del *.tmp > nul
del ~tmp~.mak > nul
diff --git a/win32/file.c b/win32/file.c
index 31cc1aff6e..5f5590d3c8 100644
--- a/win32/file.c
+++ b/win32/file.c
@@ -263,7 +263,7 @@ rb_default_home_dir(VALUE result)
{
WCHAR *dir = rb_w32_home_dir();
if (!dir) {
- rb_raise(rb_eArgError, "couldn't find HOME environment -- expanding `~'");
+ rb_raise(rb_eArgError, "couldn't find HOME environment -- expanding '~'");
}
append_wstr(result, dir, -1,
CP_UTF8, rb_utf8_encoding());
@@ -326,7 +326,7 @@ rb_file_expand_path_internal(VALUE fname, VALUE dname, int abs_mode, int long_na
whome = rb_w32_home_dir();
if (whome == NULL) {
free(wpath);
- rb_raise(rb_eArgError, "couldn't find HOME environment -- expanding `~'");
+ rb_raise(rb_eArgError, "couldn't find HOME environment -- expanding '~'");
}
whome_len = wcslen(whome);
@@ -372,8 +372,7 @@ rb_file_expand_path_internal(VALUE fname, VALUE dname, int abs_mode, int long_na
result = append_wstr(result, wpath_pos + 1, user_length_in_path(wpath_pos + 1, wpath_len - 1),
path_cp, path_encoding);
- if (wpath)
- free(wpath);
+ free(wpath);
rb_exc_raise(rb_exc_new_str(rb_eArgError, result));
}
@@ -390,7 +389,7 @@ rb_file_expand_path_internal(VALUE fname, VALUE dname, int abs_mode, int long_na
const long dir_len = RSTRING_LEN(dir);
#if SIZEOF_INT < SIZEOF_LONG
if ((long)(int)dir_len != dir_len) {
- if (wpath) free(wpath);
+ free(wpath);
rb_raise(rb_eRangeError, "base directory (%ld bytes) is too long",
dir_len);
}
@@ -405,7 +404,7 @@ rb_file_expand_path_internal(VALUE fname, VALUE dname, int abs_mode, int long_na
if (whome == NULL) {
free(wpath);
free(wdir);
- rb_raise(rb_eArgError, "couldn't find HOME environment -- expanding `~'");
+ rb_raise(rb_eArgError, "couldn't find HOME environment -- expanding '~'");
}
whome_len = wcslen(whome);
@@ -452,11 +451,8 @@ rb_file_expand_path_internal(VALUE fname, VALUE dname, int abs_mode, int long_na
result = rb_str_new_cstr("can't find user ");
result = append_wstr(result, wdir_pos + 1, user_length_in_path(wdir_pos + 1, wdir_len - 1),
path_cp, path_encoding);
- if (wpath)
- free(wpath);
-
- if (wdir)
- free(wdir);
+ free(wpath);
+ free(wdir);
rb_exc_raise(rb_exc_new_str(rb_eArgError, result));
}
@@ -573,17 +569,10 @@ rb_file_expand_path_internal(VALUE fname, VALUE dname, int abs_mode, int long_na
result = append_wstr(result, wfullpath, size, path_cp, path_encoding);
/* TODO: better cleanup */
- if (buffer)
- xfree(buffer);
-
- if (wpath)
- free(wpath);
-
- if (wdir)
- free(wdir);
-
- if (whome)
- xfree(whome);
+ xfree(buffer);
+ free(wpath);
+ free(wdir);
+ xfree(whome);
if (wfullpath != wfullpath_buffer)
xfree(wfullpath);
diff --git a/win32/file.h b/win32/file.h
index 4f1f36a75c..7bf9868e7d 100644
--- a/win32/file.h
+++ b/win32/file.h
@@ -47,4 +47,7 @@ int fchmod(int fd, int mode);
UINT rb_w32_filecp(void);
WCHAR *rb_w32_home_dir(void);
+rb_pid_t rb_w32_uspawn_process(int mode, const char *prog, char *const *argv,
+ int in_fd, int out_fd, int err_fd, DWORD flags);
+
#endif /* RUBY_WIN32_FILE_H */
diff --git a/win32/mkexports.rb b/win32/mkexports.rb
index 2889908942..dd0fbf6313 100755
--- a/win32/mkexports.rb
+++ b/win32/mkexports.rb
@@ -151,7 +151,7 @@ class Exports::Cygwin < Exports
end
def each_line(objs, &block)
- IO.foreach("|#{self.class.nm} --extern --defined #{objs.join(' ')}", &block)
+ IO.foreach("|#{self.class.nm} --extern-only --defined-only #{objs.join(' ')}", &block)
end
def each_export(objs)
diff --git a/win32/setup.mak b/win32/setup.mak
index c0074bf963..3b822a33c0 100644
--- a/win32/setup.mak
+++ b/win32/setup.mak
@@ -62,10 +62,17 @@ ENABLE_DEBUG_ENV = $(ENABLE_DEBUG_ENV)
!if defined(RJIT_SUPPORT)
RJIT_SUPPORT = $(RJIT_SUPPORT)
!endif
+!if defined(XINCFLAGS)
+CPPFLAGS = $(XINCFLAGS)
+!endif
+!if defined(XLDFLAGS)
+XLDFLAGS = $(XLDFLAGS)
+!endif
# TOOLS
<<
!if defined(BASERUBY)
+ $(BASERUBY:/=\) "$(srcdir)/tool/missing-baseruby.bat"
@echo BASERUBY = $(BASERUBY:/=\)>> $(MAKEFILE)
!endif
!if "$(RUBY_DEVEL)" == "yes"
@@ -78,8 +85,13 @@ RJIT_SUPPORT = $(RJIT_SUPPORT)
@echo HAVE_GIT = $(HAVE_GIT)>> $(MAKEFILE)
!endif
-!if "$(WITH_GMP)" == "yes"
- @echo>>$(MAKEFILE) USE_GMP = 1
+!if "$(WITH_GMP)" != "no"
+ @($(CC) $(XINCFLAGS) <<conftest.c -link $(XLDFLAGS) gmp.lib > nul && (echo USE_GMP = yes) || exit /b 0) >>$(MAKEFILE)
+#include <gmp.h>
+mpz_t x;
+int main(void) {mpz_init(x); return 0;}
+<<
+ @$(WIN32DIR:/=\)\rm.bat conftest.*
!endif
-osname-section-:
@@ -129,6 +141,7 @@ vs2022-fp-bug:
/* compile with -O2 */
#include <math.h>
#include <float.h>
+#include <stdio.h>
#define value_finite(d) 'f'
#define value_infinity() 'i'
diff --git a/win32/win32.c b/win32/win32.c
index c2d12a79f4..0d9cc087dc 100644
--- a/win32/win32.c
+++ b/win32/win32.c
@@ -622,21 +622,24 @@ init_env(void)
if (!GetEnvironmentVariableW(L"HOME", env, numberof(env))) {
f = FALSE;
- if (GetEnvironmentVariableW(L"HOMEDRIVE", env, numberof(env)))
- len = lstrlenW(env);
- else
- len = 0;
- if (GetEnvironmentVariableW(L"HOMEPATH", env + len, numberof(env) - len) || len) {
- f = TRUE;
- }
- else if (GetEnvironmentVariableW(L"USERPROFILE", env, numberof(env))) {
- f = TRUE;
- }
- else if (get_special_folder(CSIDL_PROFILE, env, numberof(env))) {
+ if (GetEnvironmentVariableW(L"USERPROFILE", env, numberof(env))) {
f = TRUE;
}
- else if (get_special_folder(CSIDL_PERSONAL, env, numberof(env))) {
- f = TRUE;
+ else {
+ if (GetEnvironmentVariableW(L"HOMEDRIVE", env, numberof(env)))
+ len = lstrlenW(env);
+ else
+ len = 0;
+
+ if (GetEnvironmentVariableW(L"HOMEPATH", env + len, numberof(env) - len) || len) {
+ f = TRUE;
+ }
+ else if (get_special_folder(CSIDL_PROFILE, env, numberof(env))) {
+ f = TRUE;
+ }
+ else if (get_special_folder(CSIDL_PERSONAL, env, numberof(env))) {
+ f = TRUE;
+ }
}
if (f) {
regulate_path(env);
@@ -1537,7 +1540,8 @@ rb_w32_uspawn(int mode, const char *cmd, const char *prog)
/* License: Artistic or GPL */
static rb_pid_t
-w32_aspawn_flags(int mode, const char *prog, char *const *argv, DWORD flags, UINT cp)
+w32_spawn_process(int mode, const char *prog, char *const *argv,
+ int in_fd, int out_fd, int err_fd, DWORD flags, UINT cp)
{
int c_switch = 0;
size_t len;
@@ -1548,9 +1552,20 @@ w32_aspawn_flags(int mode, const char *prog, char *const *argv, DWORD flags, UIN
int e = 0;
rb_pid_t ret = -1;
VALUE v = 0;
+ HANDLE in_handle = NULL, out_handle = NULL, err_handle = NULL;
if (check_spawn_mode(mode)) return -1;
+ if (in_fd >= 0) {
+ in_handle = (HANDLE)rb_w32_get_osfhandle(in_fd);
+ }
+ if (out_fd >= 0) {
+ out_handle = (HANDLE)rb_w32_get_osfhandle(out_fd);
+ }
+ if (err_fd >= 0) {
+ err_handle = (HANDLE)rb_w32_get_osfhandle(err_fd);
+ }
+
if (!prog) prog = argv[0];
if ((shell = w32_getenv("COMSPEC", cp)) &&
internal_cmd_match(prog, tmpnt = !is_command_com(shell))) {
@@ -1598,7 +1613,7 @@ w32_aspawn_flags(int mode, const char *prog, char *const *argv, DWORD flags, UIN
if (!e) {
struct ChildRecord *child = FindFreeChildSlot();
- if (CreateChild(child, wcmd, wprog, NULL, NULL, NULL, flags)) {
+ if (CreateChild(child, wcmd, wprog, in_handle, out_handle, err_handle, flags)) {
ret = child_result(child, mode);
}
}
@@ -1613,21 +1628,21 @@ rb_pid_t
rb_w32_aspawn_flags(int mode, const char *prog, char *const *argv, DWORD flags)
{
/* assume ACP */
- return w32_aspawn_flags(mode, prog, argv, flags, filecp());
+ return w32_spawn_process(mode, prog, argv, -1, -1, -1, flags, filecp());
}
/* License: Ruby's */
rb_pid_t
rb_w32_uaspawn_flags(int mode, const char *prog, char *const *argv, DWORD flags)
{
- return w32_aspawn_flags(mode, prog, argv, flags, CP_UTF8);
+ return w32_spawn_process(mode, prog, argv, -1, -1, -1, flags, CP_UTF8);
}
/* License: Ruby's */
rb_pid_t
rb_w32_aspawn(int mode, const char *prog, char *const *argv)
{
- return w32_aspawn_flags(mode, prog, argv, 0, filecp());
+ return w32_spawn_process(mode, prog, argv, -1, -1, -1, 0, filecp());
}
/* License: Ruby's */
@@ -1637,6 +1652,15 @@ rb_w32_uaspawn(int mode, const char *prog, char *const *argv)
return rb_w32_uaspawn_flags(mode, prog, argv, 0);
}
+/* License: Ruby's */
+rb_pid_t
+rb_w32_uspawn_process(int mode, const char *prog, char *const *argv,
+ int in_fd, int out_fd, int err_fd, DWORD flags)
+{
+ return w32_spawn_process(mode, prog, argv, in_fd, out_fd, err_fd,
+ flags, CP_UTF8);
+}
+
/* License: Artistic or GPL */
typedef struct _NtCmdLineElement {
struct _NtCmdLineElement *next;
@@ -1926,7 +1950,7 @@ w32_cmdvector(const WCHAR *cmd, char ***vec, UINT cp, rb_encoding *enc)
}
}
- curr = (NtCmdLineElement *)calloc(sizeof(NtCmdLineElement), 1);
+ curr = (NtCmdLineElement *)calloc(1, sizeof(NtCmdLineElement));
if (!curr) goto do_nothing;
curr->str = rb_w32_wstr_to_mbstr(cp, base, len, &curr->len);
curr->flags |= NTMALLOC;
@@ -2132,7 +2156,7 @@ w32_wopendir(const WCHAR *wpath)
//
// Get us a DIR structure
//
- p = calloc(sizeof(DIR), 1);
+ p = calloc(1, sizeof(DIR));
if (p == NULL)
return NULL;
@@ -2369,10 +2393,8 @@ readdir_internal(DIR *dirp, BOOL (*conv)(const WCHAR *, const WCHAR *, struct di
//
// first set up the structure to return
//
- if (dirp->dirstr.d_name)
- free(dirp->dirstr.d_name);
- if (dirp->dirstr.d_altname)
- free(dirp->dirstr.d_altname);
+ free(dirp->dirstr.d_name);
+ free(dirp->dirstr.d_altname);
dirp->dirstr.d_altname = 0;
dirp->dirstr.d_altlen = 0;
conv(dirp->curr, dirp->curr + lstrlenW(dirp->curr) + 1, &dirp->dirstr, enc);
@@ -2478,14 +2500,10 @@ void
rb_w32_closedir(DIR *dirp)
{
if (dirp) {
- if (dirp->dirstr.d_name)
- free(dirp->dirstr.d_name);
- if (dirp->dirstr.d_altname)
- free(dirp->dirstr.d_altname);
- if (dirp->start)
- free(dirp->start);
- if (dirp->bits)
- free(dirp->bits);
+ free(dirp->dirstr.d_name);
+ free(dirp->dirstr.d_altname);
+ free(dirp->start);
+ free(dirp->bits);
free(dirp);
}
}
@@ -2597,9 +2615,73 @@ set_pioinfo_extra(void)
* * https://bugs.ruby-lang.org/issues/18605
*/
char *p = (char*)get_proc_address(UCRTBASE, "_isatty", NULL);
- char *pend = p;
/* _osfile(fh) & FDEV */
+#ifdef _M_ARM64
+#define IS_INSN(pc, name) ((*(pc) & name##_mask) == name##_id)
+ const int max_num_inst = 500;
+ uint32_t *start = (uint32_t*)p;
+ uint32_t *end_limit = (start + max_num_inst);
+ uint32_t *pc = start;
+
+ if (!p) {
+ fprintf(stderr, "_isatty proc not found in " UCRTBASE "\n");
+ _exit(1);
+ }
+
+ /* end of function */
+ const uint32_t ret_id = 0xd65f0000;
+ const uint32_t ret_mask = 0xfffffc1f;
+ for(; pc < end_limit; pc++) {
+ if (IS_INSN(pc, ret)) {
+ break;
+ }
+ }
+ if (pc == end_limit) {
+ fprintf(stderr, "end of _isatty not found in " UCRTBASE "\n");
+ _exit(1);
+ }
+
+ /* pioinfo instruction mark */
+ const uint32_t adrp_id = 0x90000000;
+ const uint32_t adrp_mask = 0x9f000000;
+ const uint32_t add_id = 0x11000000;
+ const uint32_t add_mask = 0x3fc00000;
+ for(; pc > start; pc--) {
+ if (IS_INSN(pc, adrp) && IS_INSN(pc + 1, add)) {
+ break;
+ }
+ }
+ if(pc == start) {
+ fprintf(stderr, "pioinfo mark not found in " UCRTBASE "\n");
+ _exit(1);
+ }
+
+ /* We now point to instructions that load address of __pioinfo:
+ * adrp x8, 0x1801d8000
+ * add x8, x8, #0xdb0
+ * https://devblogs.microsoft.com/oldnewthing/20220809-00/?p=106955
+ * The last adrp/add sequence before ret is what we are looking for.
+ */
+ const uint32_t adrp_insn = *pc;
+ const uint32_t adrp_immhi = (adrp_insn & 0x00ffffe0) >> 5;
+ const uint32_t adrp_immlo = (adrp_insn & 0x60000000) >> (5 + 19 + 5);
+ /* imm = immhi:immlo:Zeros(12), 64 */
+ const uint64_t adrp_imm = ((adrp_immhi << 2) | adrp_immlo) << 12;
+ /* base = PC64<63:12>:Zeros(12) */
+ const uint64_t adrp_base = (uint64_t)pc & 0xfffffffffffff000;
+
+ const uint32_t add_insn = *(pc + 1);
+ const uint32_t add_sh = (add_insn & 0x400000) >> (12 + 5 + 5);
+ /* case sh of
+ when '0' imm = ZeroExtend(imm12, datasize);
+ when '1' imm = ZeroExtend(imm12:Zeros(12), datasize); */
+ const uint64_t add_imm = ((add_insn & 0x3ffc00) >> (5 + 5)) << (add_sh ? 12 : 0);
+
+ __pioinfo = (ioinfo**)(adrp_base + adrp_imm + add_imm);
+#else /* _M_ARM64 */
+ char *pend = p;
+
# ifdef _WIN64
int32_t rel;
char *rip;
@@ -2649,7 +2731,8 @@ set_pioinfo_extra(void)
#else
__pioinfo = *(ioinfo***)(p);
#endif
-#endif
+#endif /* _M_ARM64 */
+#endif /* RUBY_MSVCRT_VERSION */
int fd;
fd = _open("NUL", O_RDONLY);
@@ -4378,8 +4461,8 @@ freeifaddrs(struct ifaddrs *ifp)
{
while (ifp) {
struct ifaddrs *next = ifp->ifa_next;
- if (ifp->ifa_addr) ruby_xfree(ifp->ifa_addr);
- if (ifp->ifa_name) ruby_xfree(ifp->ifa_name);
+ ruby_xfree(ifp->ifa_addr);
+ ruby_xfree(ifp->ifa_name);
ruby_xfree(ifp);
ifp = next;
}
@@ -7593,7 +7676,7 @@ rb_w32_write_console(uintptr_t strarg, int fd)
}
}
RB_GC_GUARD(str);
- if (wbuffer) free(wbuffer);
+ free(wbuffer);
return (long)reslen;
}