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

Attachment: SunSignalHandler.java
Description: Binary data

Attachment: DummySignalHandler.java
Description: Binary data

Attachment: ISignal.java
Description: Binary data

Attachment: 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

Reply via email to