Created
May 10, 2012 13:40
-
-
Save mame/2653054 to your computer and use it in GitHub Desktop.
sfx support of ruby
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
From 552877c780545e8b25ededf8fa2f0042597b6bcb Mon Sep 17 00:00:00 2001 | |
From: Yusuke Endoh <mame@tsg.ne.jp> | |
Date: Thu, 10 May 2012 22:38:46 +0900 | |
Subject: [PATCH] * sfx support. | |
--- | |
cygwin/GNUmakefile.in | 11 ++++++--- | |
io.c | 64 +++++++++++++++++++++++++++++++++++++++++++++++++ | |
ruby.c | 16 +++++++++++++ | |
win32/fix-size.rb | 20 ++++++++++++++++ | |
win32/resource.rb | 2 ++ | |
5 files changed, 110 insertions(+), 3 deletions(-) | |
create mode 100644 win32/fix-size.rb | |
diff --git a/cygwin/GNUmakefile.in b/cygwin/GNUmakefile.in | |
index 19d1727..81cdb82 100644 | |
--- a/cygwin/GNUmakefile.in | |
+++ b/cygwin/GNUmakefile.in | |
@@ -48,11 +48,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) \ | |
@@ -60,11 +60,16 @@ $(RCFILES): $(RBCONFIG) $(srcdir)/revision.h $(srcdir)/win32/resource.rb | |
. $(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 $@ | |
@@ -103,5 +108,5 @@ cygwin-$(RUBY_INSTALL_NAME)$(MAJOR)$(MINOR)$(TEENY).dll: $(LIBRUBY_A) $(RUBYDEF) | |
endif | |
clean-local:: | |
- @$(RM) $(RUBY_EXP) $(RCFILES:.rc=.res.@OBJEXT@) | |
+ @$(RM) $(RUBY_EXP) $(RCFILES:.rc=.res.@OBJEXT@) $(RCFILES:.rc=.size) | |
@$(RM) $(RCFILES) | |
diff --git a/io.c b/io.c | |
index 96087d6..9947a75 100644 | |
--- a/io.c | |
+++ b/io.c | |
@@ -7191,6 +7191,70 @@ rb_io_set_autoclose(VALUE io, VALUE autoclose) | |
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 --git a/ruby.c b/ruby.c | |
index 93779a7..677ee82 100644 | |
--- a/ruby.c | |
+++ b/ruby.c | |
@@ -121,6 +121,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) | |
{ | |
@@ -695,6 +700,14 @@ proc_options(long argc, char **argv, struct cmdline_options *opt, int envopt) | |
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; | |
@@ -1512,6 +1525,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__ | |
diff --git a/win32/fix-size.rb b/win32/fix-size.rb | |
new file mode 100644 | |
index 0000000..f8cae8c | |
--- /dev/null | |
+++ b/win32/fix-size.rb | |
@@ -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 --git a/win32/resource.rb b/win32/resource.rb | |
index 786edb0..75a9004 100755 | |
--- a/win32/resource.rb | |
+++ b/win32/resource.rb | |
@@ -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 | |
-- | |
1.7.9.5 |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment