Hi there.I've implemented a somewhat working Signal and Kernel#trap. It just works for a few signals and only on a Sun VM. I do conditional loading of the class, so nothing breaks if it runs on a non-Sun VM, the functionality just disappears.
Anyway, it works for TERM and INT and ABRT which are probably the most common use cases. Signal#list will only returns those that we can have on all Java platforms, but other, like USR1, USR2, CHLD and others can be used on Unix systems, even though Signal#list doesn't return it as an option.
I've tested it with WEBrick and it seems to work allright to shutdown the server, even with the rails script/server-script.
The patch-file may contain parts of the patch for the new StringIO also, sorry about that.
Regards Ola Bini
SunSignalHandler.java
Description: Binary data
DummySignalHandler.java
Description: Binary data
ISignal.java
Description: Binary data
RubySignal.java
Description: Binary data
Index: src/org/jruby/IRuby.java =================================================================== RCS file: /cvsroot/jruby/jruby/src/org/jruby/IRuby.java,v retrieving revision 1.16 diff -u -r1.16 IRuby.java --- src/org/jruby/IRuby.java 6 Jun 2006 02:40:53 -0000 1.16 +++ src/org/jruby/IRuby.java 14 Jun 2006 06:34:58 -0000 @@ -26,6 +26,7 @@ import org.jruby.runtime.builtin.IRubyObject; import org.jruby.runtime.load.LoadService; import org.jruby.util.collections.SinglyLinkedList; +import org.jruby.util.ISignal; public interface IRuby { @@ -351,4 +352,6 @@ public long incrementRandomSeedSequence(); public RubyTime newTime(long milliseconds); -} \ No newline at end of file + + public ISignal getSignalHandler(); +} Index: src/org/jruby/Ruby.java =================================================================== RCS file: /cvsroot/jruby/jruby/src/org/jruby/Ruby.java,v retrieving revision 1.121 diff -u -r1.121 Ruby.java --- src/org/jruby/Ruby.java 6 Jun 2006 02:40:53 -0000 1.121 +++ src/org/jruby/Ruby.java 14 Jun 2006 06:54:11 -0000 @@ -60,6 +60,7 @@ import org.jruby.libraries.JRubyLibrary; import org.jruby.libraries.RbConfigLibrary; import org.jruby.libraries.SocketLibrary; +import org.jruby.libraries.StringIOLibrary; import org.jruby.parser.Parser; import org.jruby.runtime.Block; import org.jruby.runtime.CacheMap; @@ -91,6 +92,7 @@ import org.jruby.util.BuiltinScript; import org.jruby.util.JRubyFile; import org.jruby.util.collections.SinglyLinkedList; +import org.jruby.util.ISignal; /** * The jruby runtime. @@ -124,6 +126,8 @@ */ private int safeLevel = 0; + private ISignal signalHandler; + // Default classes/objects private IRubyObject nilObject; private RubyBoolean trueObject; @@ -162,6 +166,14 @@ this.in = in; this.out = out; this.err = err; + try { + Class.forName("sun.misc.Signal"); // Check if this is a Sun VM... + this.signalHandler = (ISignal)(Class.forName("org.jruby.util.SunSignalHandler").newInstance()); + } catch(final Throwable thre) { + //Not a Sun VM. + this.signalHandler = new org.jruby.util.DummySignalHandler(); + } + init(); } @@ -421,6 +433,7 @@ loadService.registerBuiltin("jruby", new JRubyLibrary()); + loadService.registerBuiltin("stringio", new StringIOLibrary()); } private void initCoreClasses() { @@ -482,6 +495,7 @@ RubyRange.createRangeClass(this); RubyObjectSpace.createObjectSpaceModule(this); RubyGC.createGCModule(this); + RubySignal.createSignalModule(this); new ProcMetaClass(this).initializeClass(); @@ -1226,4 +1240,8 @@ public PrintStream getErr() { return err; } + + public ISignal getSignalHandler() { + return this.signalHandler; + } } Index: src/org/jruby/RubyKernel.java =================================================================== RCS file: /cvsroot/jruby/jruby/src/org/jruby/RubyKernel.java,v retrieving revision 1.53 diff -u -r1.53 RubyKernel.java --- src/org/jruby/RubyKernel.java 24 May 2006 01:34:03 -0000 1.53 +++ src/org/jruby/RubyKernel.java 14 Jun 2006 06:43:19 -0000 @@ -657,8 +657,49 @@ throw je; } + private static class JRubyProcObject implements Runnable { + private final RubyProc proc; + public JRubyProcObject(final RubyProc proc) { + this.proc = proc; + } + public void run() { + try { + proc.call(new IRubyObject[0]); + } catch(final Throwable thre) { + // SWALLOW. + } + + } + } + public static IRubyObject trap(IRubyObject recv, IRubyObject[] args) { - // FIXME: We can probably fake some basic signals, but obviously can't do everything. For now, stub. + String sigName = null; + long sigNum = -1; + if(args[0] instanceof RubyNumeric) { + sigNum = RubyNumeric.num2long(args[0]); + } else { + sigName = args[0].toString(); + if(sigName.startsWith("SIG")) { + sigName = sigName.substring("SIG".length()); + } + } + RubyProc proc = null; + if(args.length>1) { + if(args[1] instanceof RubyString) { + // Handle cases of IGNORE, SIG_IGN, DEFAULT and SIG_DFL + } else if(args[1] instanceof RubyProc) { + proc = (RubyProc)args[1]; + } + } else { + if (recv.getRuntime().getCurrentContext().isBlockGiven()) { + proc = recv.getRuntime().newProc(); + } + } + if(null != sigName) { + recv.getRuntime().getSignalHandler().handleSignal(sigName,new JRubyProcObject(proc)); + } else { + recv.getRuntime().getSignalHandler().handleSignal(sigNum,new JRubyProcObject(proc)); + } return recv.getRuntime().getNil(); } Index: src/builtin/etc.rb =================================================================== RCS file: /cvsroot/jruby/jruby/src/builtin/etc.rb,v retrieving revision 1.3 diff -u -r1.3 etc.rb --- src/builtin/etc.rb 13 Jun 2006 15:26:16 -0000 1.3 +++ src/builtin/etc.rb 14 Jun 2006 06:52:33 -0000 @@ -5,9 +5,3 @@ Struct::Tms.new(0, 0, 0, 0) end end - -module Signal - def self.trap(sig) - # do nothing - end -end \ No newline at end of file
_______________________________________________ Jruby-devel mailing list Jruby-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/jruby-devel