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 [email protected] https://lists.sourceforge.net/lists/listinfo/jruby-devel
