Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .idea/misc.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Binary file modified lib/native/x86_64-Linux/libjruby-cext.so
100644 → 100755
Binary file not shown.
6 changes: 4 additions & 2 deletions src/jruby/kernel/signal.rb
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,11 @@ def trap(sig, cmd = nil, &block)
when 'EXIT'
Signal::__jtrap_kernel(proc{exit}, sig)
when 'SIG_IGN', 'IGNORE'
Signal::__jtrap_kernel(proc{}, sig)
Signal::__jtrap_ignore_kernel(sig)
when 'SIG_DFL', 'DEFAULT'
# do nothing...because I don't think we can return to old default
Signal::__jtrap_platform_kernel(sig)
when 'SYSTEM_DEFAULT'
Signal::__jtrap_osdefault_kernel(sig)
when String
Signal::__jtrap_kernel(proc{eval cmd, TOPLEVEL_BINDING}, sig)
else
Expand Down
15 changes: 15 additions & 0 deletions src/org/jruby/RubySignal.java
Original file line number Diff line number Diff line change
Expand Up @@ -86,4 +86,19 @@ public static IRubyObject list(ThreadContext context, IRubyObject recv) {
public static IRubyObject __jtrap_kernel(final IRubyObject recv, IRubyObject block, IRubyObject sig) {
return SIGNALS.trap(recv, block, sig);
}

@JRubyMethod(name = "__jtrap_platform_kernel", required = 1, module = true)
public static IRubyObject __jtrap_platform_kernel(final IRubyObject recv, IRubyObject sig) {
return SIGNALS.restorePlatformDefault(recv, sig);
}

@JRubyMethod(name = "__jtrap_osdefault_kernel", required = 1, module = true)
public static IRubyObject __jtrap_osdefault_kernel(final IRubyObject recv, IRubyObject sig) {
return SIGNALS.restoreOSDefault(recv, sig);
}

@JRubyMethod(name = "__jtrap_ignore_kernel", required = 1, module = true)
public static IRubyObject __jtrap_restore_kernel(final IRubyObject recv, IRubyObject sig) {
return SIGNALS.ignore(recv, sig);
}
}// RubySignal
12 changes: 12 additions & 0 deletions src/org/jruby/util/NoFunctionalitySignalFacade.java
Original file line number Diff line number Diff line change
Expand Up @@ -42,4 +42,16 @@ public IRubyObject trap(IRubyObject recv, IRubyObject block, IRubyObject sig) {
public IRubyObject trap(Ruby runtime, BlockCallback block, String sig) {
return runtime.getNil();
}

public IRubyObject restorePlatformDefault(IRubyObject recv, IRubyObject sig) {
return recv.getRuntime().getNil();
}

public IRubyObject restoreOSDefault(IRubyObject recv, IRubyObject sig) {
return recv.getRuntime().getNil();
}

public IRubyObject ignore(IRubyObject recv, IRubyObject sig) {
return recv.getRuntime().getNil();
}
}// NoFunctionalitySignalFacade
12 changes: 12 additions & 0 deletions src/org/jruby/util/SignalFacade.java
Original file line number Diff line number Diff line change
Expand Up @@ -37,4 +37,16 @@
public interface SignalFacade {
IRubyObject trap(IRubyObject recv, IRubyObject block, IRubyObject sig);
IRubyObject trap(Ruby runtime, BlockCallback block, String sig);
/**
* Restores the platform (JVM's) default signal handler.
*/
IRubyObject restorePlatformDefault(IRubyObject recv, IRubyObject sig);
/**
* Restores the OS default signal handler.
*/
IRubyObject restoreOSDefault(IRubyObject recv, IRubyObject sig);
/**
* Ignores this signal.
*/
IRubyObject ignore(IRubyObject recv, IRubyObject sig);
}// SignalFacade
44 changes: 42 additions & 2 deletions src/org/jruby/util/SunSignalFacade.java
Original file line number Diff line number Diff line change
Expand Up @@ -43,10 +43,20 @@
import sun.misc.Signal;
import sun.misc.SignalHandler;

import java.util.HashMap;
import java.util.Map;

/**
* @author <a href="mailto:ola.bini@gmail.com">Ola Bini</a>
*/
public class SunSignalFacade implements SignalFacade {
/**
* Remembers the original signal handlers before JRuby started messing around with them,
* to emulate {@code Signal.trap(...,"DEFAULT")} that's supposed to restore the platform
* default handler.
*/
private final Map<Signal,SignalHandler> original = new HashMap<Signal, SignalHandler>();

private final static class JRubySignalHandler implements SignalHandler {
private final Ruby runtime;
private final IRubyObject block;
Expand Down Expand Up @@ -98,11 +108,36 @@ public IRubyObject trap(final Ruby runtime, BlockCallback blk, String sig) {
}

private IRubyObject trap(final Ruby runtime, final JRubySignalHandler handler) {
return trap(runtime,handler.signal,handler);
}

public IRubyObject restorePlatformDefault(IRubyObject recv, IRubyObject sig) {
SignalHandler handler;
synchronized (original) {
handler = original.get(new Signal(sig.toString()));
}
if (handler!=null)
return trap(recv.getRuntime(),sig.toString(),handler);
else {
// JRuby hasn't touched this signal handler, so it should be the platform default already
return recv.getRuntime().getNil();
}
}

public IRubyObject restoreOSDefault(IRubyObject recv, IRubyObject sig) {
return trap(recv.getRuntime(),sig.toString(),SignalHandler.SIG_DFL);
}

public IRubyObject ignore(IRubyObject recv, IRubyObject sig) {
return trap(recv.getRuntime(),sig.toString(),SignalHandler.SIG_IGN);
}

private IRubyObject trap(final Ruby runtime, final String signalName, final SignalHandler handler) {
final SignalHandler oldHandler;
final Signal signal;

try {
signal = new Signal(handler.signal);
signal = new Signal(signalName);
} catch (Throwable e) {
return runtime.getNil();
}
Expand All @@ -112,6 +147,11 @@ private IRubyObject trap(final Ruby runtime, final JRubySignalHandler handler) {
} catch (Exception e) {
throw runtime.newArgumentError(e.getMessage());
}

synchronized (original) {
if (!original.containsKey(signal))
original.put(signal,oldHandler);
}

BlockCallback callback = null;
if (oldHandler instanceof JRubySignalHandler) {
Expand All @@ -125,7 +165,7 @@ private IRubyObject trap(final Ruby runtime, final JRubySignalHandler handler) {
if (callback == null) {
callback = new BlockCallback() {
public IRubyObject call(ThreadContext context, IRubyObject[] args, Block block) {
oldHandler.handle(new Signal(handler.signal));
oldHandler.handle(signal);
return runtime.getNil();
}
};
Expand Down