/** * * @param name the signal, CONT, STOP, etc... * @param handler the callback to run * * @return an object that needs to be passed to the {@link #unregister(String, Object)} * method to unregister the handler */ public static Object register(String name, Runnable handler) { Objects.requireNonNull(handler); return register(name, handler, handler.getClass().getClassLoader()); }
public static Object register(String name, final Runnable handler, ClassLoader loader) { try { Class<?> signalHandlerClass = Class.forName("sun.misc.SignalHandler"); // Implement signal handler Object signalHandler = Proxy.newProxyInstance(loader, new Class<?>[]{signalHandlerClass}, (proxy, method, args) -> { // only method we are proxying is handle() if (method.getDeclaringClass() == Object.class) { if ("toString".equals(method.getName())) { return handler.toString(); } } else if (method.getDeclaringClass() == signalHandlerClass) { Log.trace(() -> "Calling handler " + toString(handler) + " for signal " + name); handler.run(); } return null; }); return doRegister(name, signalHandler); } catch (Exception e) { // Ignore this one too, if the above failed, the signal API is incompatible with what we're expecting Log.debug("Error registering handler for signal ", name, e); return null; } }
@Override public SignalHandler handle(Signal signal, SignalHandler handler) { SignalHandler prev = super.handle(signal, handler); if (prev != handler) { if (handler == SignalHandler.SIG_DFL) { Signals.registerDefault(signal.name()); } else { Signals.register(signal.name(), () -> raise(signal)); } } return prev; }
Object sh = Signals.register("INT", () -> commandThread.interrupt()); try { Object[] args = resolveArgs(method, wordsForArgs); Signals.unregister("INT", sh);
public void close() throws IOException { super.close(); closing = true; pump.interrupt(); ShutdownHooks.remove(closer); for (Map.Entry<Signal, Object> entry : nativeHandlers.entrySet()) { Signals.unregister(entry.getKey().name(), entry.getValue()); } reader.close(); writer.close(); setConsoleMode(originalConsoleMode); }
public static Object registerDefault(String name) { try { Class<?> signalHandlerClass = Class.forName("sun.misc.SignalHandler"); return doRegister(name, signalHandlerClass.getField("SIG_DFL").get(null)); } catch (Exception e) { // Ignore this one too, if the above failed, the signal API is incompatible with what we're expecting Log.debug("Error registering default handler for signal ", name, e); return null; } }
private static Object doRegister(String name, Object handler) throws Exception { Log.trace(() -> "Registering signal " + name + " with handler " + toString(handler)); if ("QUIT".equals(name) || "INFO".equals(name) && "9".equals(System.getProperty("java.specification.version"))) { Log.trace(() -> "Ignoring unsupported signal " + name); return null; } Class<?> signalClass = Class.forName("sun.misc.Signal"); Class<?> signalHandlerClass = Class.forName("sun.misc.SignalHandler"); Object signal = signalClass.getConstructor(String.class).newInstance(name); return signalClass.getMethod("handle", signalClass, signalHandlerClass) .invoke(null, signal, handler); }
@Override public SignalHandler handle(Signal signal, SignalHandler handler) { SignalHandler prev = super.handle(signal, handler); if (prev != handler) { if (handler == SignalHandler.SIG_DFL) { Signals.registerDefault(signal.name()); } else { Signals.register(signal.name(), () -> raise(signal)); } } return prev; }
@Override public void close() throws IOException { ShutdownHooks.remove(closer); for (Map.Entry<Signal, Object> entry : nativeHandlers.entrySet()) { Signals.unregister(entry.getKey().name(), entry.getValue()); } super.close(); // Do not call reader.close() reader.shutdown(); }
public static void unregister(String name, Object previous) { try { // We should make sure the current signal is the one we registered if (previous != null) { doRegister(name, previous); } } catch (Exception e) { // Ignore Log.debug("Error unregistering handler for signal ", name, e); } }
public PosixSysTerminal(String name, String type, Pty pty, Charset encoding, boolean nativeSignals, SignalHandler signalHandler) throws IOException { super(name, type, pty, encoding, signalHandler); this.input = NonBlocking.nonBlocking(getName(), pty.getSlaveInput()); this.output = pty.getSlaveOutput(); this.reader = NonBlocking.nonBlocking(getName(), input, encoding()); this.writer = new PrintWriter(new OutputStreamWriter(output, encoding())); parseInfoCmp(); if (nativeSignals) { for (final Signal signal : Signal.values()) { if (signalHandler == SignalHandler.SIG_DFL) { nativeHandlers.put(signal, Signals.registerDefault(signal.name())); } else { nativeHandlers.put(signal, Signals.register(signal.name(), () -> raise(signal))); } } } closer = PosixSysTerminal.this::close; ShutdownHooks.add(closer); }
for (final Signal signal : Signal.values()) { if (signalHandler == SignalHandler.SIG_DFL) { nativeHandlers.put(signal, Signals.registerDefault(signal.name())); } else { nativeHandlers.put(signal, Signals.register(signal.name(), () -> raise(signal)));