Skip to content

Instantly share code, notes, and snippets.

@aoitaku
Created August 30, 2015 17:57
Show Gist options
  • Save aoitaku/303ca4da30d6c681ec9a to your computer and use it in GitHub Desktop.
Save aoitaku/303ca4da30d6c681ec9a to your computer and use it in GitHub Desktop.
sfx-support.patch
diff -uprN a/cygwin/GNUMakefile.in b/cygwin/GNUMakefile.in
--- a/cygwin/GNUMakefile.in 2012-11-05 23:00:35 +0900
+++ b/cygwin/GNUMakefile.in 2015-08-24 13:32:16 +0900
@@ -50,11 +50,11 @@ scriptbin: $(SCRIPTPROGRAMS)
$(LIBRUBY): $(RUBY_EXP) $(LIBRUBY_SO)
$(RUBY_EXP) $(LIBRUBY_SO): $(DLL_BASE_NAME).res.@OBJEXT@
-%.res.@OBJEXT@: %.rc
+%.res.@OBJEXT@: %.rc %.size
$(ECHO) compiling $@
$(Q) $(WINDRES) --include-dir . --include-dir $(<D) --include-dir $(srcdir)/win32 $< $@
-$(RCFILES): $(RBCONFIG) $(srcdir)/revision.h $(srcdir)/win32/resource.rb
+$(RCFILES) $(RCFILES:.rc=.size): $(RBCONFIG) $(srcdir)/revision.h $(srcdir)/win32/resource.rb
$(ECHO) generating $@
$(Q) $(MINIRUBY) $(srcdir)/win32/resource.rb \
-ruby_name=$(RUBY_INSTALL_NAME) -rubyw_name=$(RUBYW_INSTALL_NAME) \
@@ -62,11 +62,16 @@ $(RCFILES): $(RBCONFIG) $(srcdir)/revisi
. $(icondirs) $(srcdir)/win32
$(PROGRAM): $(RUBY_INSTALL_NAME).res.@OBJEXT@
+ @rm -f $@
+ $(ECHO) linking $@
+ $(Q) $(PURIFY) $(CC) $(LDFLAGS) $(XLDFLAGS) $(MAINLIBS) $(MAINOBJ) $(EXTOBJS) $(LIBRUBYARG) $(LIBS) $(OUTFLAG)$@
+ $(Q) $(MINIRUBY) "$(srcdir)/win32/fix-size.rb" $@ $(RUBY_INSTALL_NAME).size
$(WPROGRAM): $(RUBYW_INSTALL_NAME).res.@OBJEXT@
@rm -f $@
$(ECHO) linking $@
$(Q) $(PURIFY) $(CC) -mwindows -e $(SYMBOL_PREFIX)mainCRTStartup $(LDFLAGS) $(XLDFLAGS) \
$(MAINOBJ) $(EXTOBJS) $(LIBRUBYARG) $(LIBS) -o $@
+ $(Q) $(MINIRUBY) "$(srcdir)/win32/fix-size.rb" $@ $(RUBYW_INSTALL_NAME).size
$(STUBPROGRAM): $(RUBY_INSTALL_NAME).res.@OBJEXT@ stub.@OBJEXT@
@rm -f $@
$(ECHO) linking $@
@@ -105,5 +110,5 @@ cygwin-$(RUBY_INSTALL_NAME)$(MAJOR)$(MIN
endif
clean-local::
- @$(RM) $(RUBY_EXP) $(RCFILES:.rc=.res.@OBJEXT@)
+ @$(RM) $(RUBY_EXP) $(RCFILES:.rc=.res.@OBJEXT@) $(RCFILES:.rc=.size)
@$(RM) $(RCFILES)
diff -uprN a/io.c b/io.c
--- a/io.c 2014-09-10 03:47:25 +0900
+++ b/io.c 2015-08-24 13:32:16 +0900
@@ -7573,6 +7573,70 @@ rb_io_set_autoclose(VALUE io, VALUE auto
return io;
}
+#if defined(_WIN32)
+static long
+get_embedded_payload_offset(void)
+{
+ HINSTANCE hInstance;
+ HRSRC hRes;
+ HGLOBAL hGlobal = NULL;
+ DWORD size;
+ unsigned char *buf;
+ long offset;
+
+ hInstance = (HINSTANCE)GetModuleHandle(0);
+ hRes = FindResource(hInstance, "RUBY_PAYLOAD_OFFSET", RT_RCDATA);
+ if (hRes == NULL) goto err;
+ hGlobal = LoadResource(hInstance, hRes);
+ if (hGlobal == NULL) goto err;
+ size = SizeofResource(hInstance, hRes);
+ if (size != 4) goto err;
+ buf = (unsigned char *) LockResource(hGlobal);
+ if (buf == NULL) goto err;
+ offset = ((long) buf[0]);
+ offset |= ((long) buf[1]) << 8;
+ offset |= ((long) buf[2]) << 16;
+ offset |= ((long) buf[3]) << 24;
+ if (offset < 0) goto err;
+ FreeResource(hGlobal);
+
+ return offset;
+
+err:
+ if (hGlobal) FreeResource(hGlobal);
+ return -1;
+}
+
+VALUE
+rb_io_open_embedded_payload(void)
+{
+ VALUE f;
+ int fd, mode = O_RDONLY;
+ char fname[_MAX_PATH+1];
+ struct stat buf;
+ long offset;
+
+ offset = get_embedded_payload_offset();
+ if (offset < 0) return Qnil;
+
+ GetModuleFileName((HINSTANCE)GetModuleHandle(0), fname, _MAX_PATH);
+ if ((fd = rb_cloexec_open(fname, mode, 0)) < 0) {
+ rb_load_fail(Qnil, strerror(errno));
+ }
+ rb_update_max_fd(fd);
+ if (fstat(fd, &buf) != 0) goto err;
+ if (buf.st_size <= offset) goto err;
+ f = rb_io_fdopen(fd, mode, fname);
+ rb_io_seek(f, LONG2NUM(offset), SEEK_SET);
+
+ return f;
+
+err:
+ close(fd);
+ return Qnil;
+}
+#endif
+
static void
argf_mark(void *ptr)
{
diff -uprN a/ruby.c b/ruby.c
--- a/ruby.c 2013-12-05 09:19:13 +0900
+++ b/ruby.c 2015-08-25 10:32:27 +0900
@@ -132,6 +132,11 @@ static struct {
char **argv;
} origarg;
+#if defined(_WIN32)
+static VALUE rb_embedded_payload = Qnil;
+extern VALUE rb_io_open_embedded_payload(void);
+#endif
+
static void
usage(const char *name, int help)
{
@@ -785,6 +790,14 @@ proc_options(long argc, char **argv, str
long n, argc0 = argc;
const char *s;
+#if defined(_WIN32)
+ rb_embedded_payload = rb_io_open_embedded_payload();
+ if (rb_embedded_payload != Qnil) {
+ opt->disable = ~0U;
+ return 0;
+ }
+#endif
+
if (argc == 0)
return 0;
@@ -1601,6 +1614,9 @@ load_file_internal(VALUE arg)
if (strcmp(fname, "-") == 0) {
f = rb_stdin;
}
+ else if (rb_embedded_payload != Qnil) {
+ f = rb_embedded_payload;
+ }
else {
int fd, mode = O_RDONLY;
#if defined DOSISH || defined __CYGWIN__
@@ -1704,7 +1720,12 @@ load_file_internal(VALUE arg)
rb_io_ungetbyte(f, c);
}
else {
- if (f != rb_stdin) rb_io_close(f);
+ if (f != rb_stdin) {
+ rb_io_close(f);
+ if (f == rb_embedded_payload) {
+ rb_embedded_payload = Qnil;
+ }
+ }
f = Qnil;
}
ruby_set_script_name(opt->script_name);
@@ -1743,6 +1764,9 @@ load_file_internal(VALUE arg)
rb_define_global_const("DATA", f);
}
else if (f != rb_stdin) {
+ if (f == rb_embedded_payload) {
+ rb_embedded_payload = Qnil;
+ }
rb_io_close(f);
}
return (VALUE)tree;
diff -uprN a/win32/fix-size.rb b/win32/fix-size.rb
--- a/win32/fix-size.rb 1970-01-01 09:00:00 +0900
+++ b/win32/fix-size.rb 2015-08-24 13:32:16 +0900
@@ -0,0 +1,20 @@
+#!./miniruby -sI.
+
+magic = open(ARGV[1], "rb") {|f| f.read }
+size = [File.size(ARGV[0])].pack("V")
+exit if size == magic
+
+open(ARGV[1], "wb") {|f| f.write size }
+exe_image = open(ARGV[0], "rb") {|f| f.read }
+count = exe_image.scan(magic).size
+
+if count == 1
+ exe_image.sub!(magic) { size }
+ open(ARGV[0], "wb") {|f| f.write exe_image }
+else
+ puts
+ puts "*************************"
+ puts "** Please re-run make! **"
+ puts "*************************"
+ puts
+end
diff -uprN a/win32/resource.rb b/win32/resource.rb
--- a/win32/resource.rb 2010-02-08 16:23:13 +0900
+++ b/win32/resource.rb 2015-08-24 13:32:22 +0900
@@ -62,6 +62,7 @@ end
#endif
#{icon || ''}
+RUBY_PAYLOAD_OFFSET RCDATA DISCARDABLE "#{base}.size"
VS_VERSION_INFO VERSIONINFO
FILEVERSION #{nversion}
PRODUCTVERSION #{nversion}
@@ -93,5 +94,6 @@ BEGIN
END
EOF
}
+ open(base + ".size", "wb") {|f| f.print "SiZE" }
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment