Skip to content

Instantly share code, notes, and snippets.

@aoitaku
Created May 24, 2016 17:06
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save aoitaku/9f90db0080d49a6fbe0e2c32a4030502 to your computer and use it in GitHub Desktop.
Save aoitaku/9f90db0080d49a6fbe0e2c32a4030502 to your computer and use it in GitHub Desktop.
sfx-support
--- a/cygwin/GNUmakefile.in Thu Jan 01 08:38:01 2015
+++ b/cygwin/GNUmakefile.in Mon May 23 01:50:00 2016
@@ -50,11 +50,11 @@
$(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 @@
. $(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 @@
endif
clean-local::
- @$(RM) $(RUBY_EXP) $(RCFILES:.rc=.res.@OBJEXT@)
+ @$(RM) $(RUBY_EXP) $(RCFILES:.rc=.res.@OBJEXT@) $(RCFILES:.rc=.size)
@$(RM) $(RCFILES)
--- a/win32/resource.rb Mon Feb 08 16:23:13 2010
+++ b/win32/resource.rb Mon May 23 01:50:00 2016
@@ -62,6 +62,7 @@
#endif
#{icon || ''}
+RUBY_PAYLOAD_OFFSET RCDATA DISCARDABLE "#{base}.size"
VS_VERSION_INFO VERSIONINFO
FILEVERSION #{nversion}
PRODUCTVERSION #{nversion}
@@ -93,5 +94,6 @@
END
EOF
}
+ open(base + ".size", "wb") {|f| f.print "SiZE" }
end
--- a/io.c Wed Dec 16 03:00:02 2015
+++ b/io.c Mon May 23 01:50:00 2016
@@ -7753,6 +7753,70 @@
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)
{
--- a/ruby.c Tue Dec 09 10:05:18 2014
+++ b/ruby.c Tue May 24 02:39:41 2016
@@ -130,6 +130,11 @@
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)
{
@@ -754,6 +759,14 @@
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;
@@ -1629,7 +1642,12 @@
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;
}
if (!(opt->dump & ~DUMP_BIT(version_v))) {
@@ -1681,6 +1699,10 @@
{
const char *ext = strrchr(fname, '.');
if (ext && STRCASECMP(ext, ".exe") == 0) {
+ if (rb_embedded_payload != Qnil) {
+ f = rb_embedded_payload;
+ goto ready_to_load;
+ }
mode |= O_BINARY;
xflag = 1;
}
@@ -1704,6 +1726,7 @@
f = rb_io_fdopen(fd, mode, fname);
}
+ ready_to_load:
argp->f = f;
argp->xflag = xflag;
tree = (NODE *)rb_protect(load_file_internal2, (VALUE)argp, &state);
@@ -1729,6 +1752,9 @@
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;
--- a/win32/fix-size.rb Thu Jan 01 09:00:00 1970
+++ b/win32/fix-size.rb Mon May 23 01:50:00 2016
@@ -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
--- a/cygwin/GNUmakefile.in Wed Aug 26 14:21:41 2015
+++ b/cygwin/GNUmakefile.in Tue May 24 19:51:24 2016
@@ -50,11 +50,11 @@
$(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 @@
. $(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@ win32/stub.@OBJEXT@
@rm -f $@
$(ECHO) linking $@
@@ -106,5 +111,5 @@
endif
clean-local::
- @$(RM) $(RUBY_EXP) $(RCFILES:.rc=.res.@OBJEXT@)
+ @$(RM) $(RUBY_EXP) $(RCFILES:.rc=.res.@OBJEXT@) $(RCFILES:.rc=.size)
@$(RM) $(RCFILES)
--- a/win32/resource.rb Sun Oct 18 11:10:34 2015
+++ b/win32/resource.rb Tue May 24 19:49:14 2016
@@ -60,6 +60,7 @@
#include <winver.h>
#{icon || ''}
+RUBY_PAYLOAD_OFFSET RCDATA DISCARDABLE "#{base}.size"
VS_VERSION_INFO VERSIONINFO
FILEVERSION #{nversion}
PRODUCTVERSION #{nversion}
@@ -91,5 +92,6 @@
END
EOF
}
+ open(base + ".size", "wb") {|f| f.print "SiZE" }
end
--- a/io.c Wed Dec 23 23:58:47 2015
+++ b/io.c Wed May 25 00:07:36 2016
@@ -7746,6 +7746,63 @@
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)
{
--- a/ruby.c Sun Nov 29 11:25:12 2015
+++ b/ruby.c Wed May 25 00:14:08 2016
@@ -153,6 +153,12 @@
char **argv;
} origarg;
+#if defined(_WIN32)
+static VALUE rb_embedded_payload = Qnil;
+static VALUE rb_embedded_payload_exists = Qfalse;
+extern VALUE rb_io_open_embedded_payload(void);
+#endif
+
static void
show_usage_line(const char *str, unsigned int namelen, unsigned int secondlen, int help)
{
@@ -832,6 +838,17 @@
long n, argc0 = argc;
const char *s;
+#if defined(_WIN32)
+ rb_embedded_payload = rb_io_open_embedded_payload();
+ if (rb_embedded_payload != Qnil) {
+ rb_io_close(rb_embedded_payload);
+ rb_embedded_payload = Qnil;
+ rb_embedded_payload_exists = Qtrue;
+ opt->features = 0U;
+ return 0;
+ }
+#endif
+
if (argc == 0)
return 0;
@@ -1654,6 +1671,7 @@
rb_encoding *enc;
ID set_encoding;
int xflag = argp->xflag;
+ const char* fname = StringValueCStr(orig_fname);
argp->script = 0;
CONST_ID(set_encoding, "set_encoding");
@@ -1730,7 +1748,12 @@
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;
}
if (!(opt->dump & ~DUMP_BIT(version_v))) {
@@ -1786,6 +1809,10 @@
{
const char *ext = strrchr(fname, '.');
if (ext && STRCASECMP(ext, ".exe") == 0) {
+ if (rb_embedded_payload_exists == Qtrue) {
+ f = rb_io_open_embedded_payload();
+ return f;
+ }
mode |= O_BINARY;
*xflag = 1;
}
@@ -1857,6 +1884,9 @@
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 rb_gv_set("$.", lineno);
--- a/win32/fix-size.rb Thu Jan 01 09:00:00 1970
+++ b/win32/fix-size.rb Mon May 23 01:50:00 2016
@@ -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
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment