| /* |
| * Copyright (c) 2002-2018, the original author or authors. |
| * |
| * This software is distributable under the BSD license. See the terms of the |
| * BSD license in the documentation provided with this software. |
| * |
| * https://opensource.org/licenses/BSD-3-Clause |
| */ |
| package jdk.internal.org.jline.terminal.impl; |
| |
| import java.io.IOException; |
| import java.io.InputStream; |
| import java.io.OutputStream; |
| import java.io.OutputStreamWriter; |
| import java.io.PrintWriter; |
| import java.nio.charset.Charset; |
| import java.util.HashMap; |
| import java.util.Map; |
| |
| import jdk.internal.org.jline.utils.NonBlocking; |
| import jdk.internal.org.jline.terminal.spi.Pty; |
| import jdk.internal.org.jline.utils.NonBlockingInputStream; |
| import jdk.internal.org.jline.utils.NonBlockingReader; |
| import jdk.internal.org.jline.utils.ShutdownHooks; |
| import jdk.internal.org.jline.utils.ShutdownHooks.Task; |
| import jdk.internal.org.jline.utils.Signals; |
| |
| public class PosixSysTerminal extends AbstractPosixTerminal { |
| |
| protected final NonBlockingInputStream input; |
| protected final OutputStream output; |
| protected final NonBlockingReader reader; |
| protected final PrintWriter writer; |
| protected final Map<Signal, Object> nativeHandlers = new HashMap<>(); |
| protected final Task closer; |
| |
| public PosixSysTerminal(String name, String type, Pty pty, InputStream in, OutputStream out, Charset encoding, |
| boolean nativeSignals, SignalHandler signalHandler) throws IOException { |
| super(name, type, pty, encoding, signalHandler); |
| this.input = NonBlocking.nonBlocking(getName(), in); |
| this.output = out; |
| 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); |
| } |
| |
| @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; |
| } |
| |
| public NonBlockingReader reader() { |
| return reader; |
| } |
| |
| public PrintWriter writer() { |
| return writer; |
| } |
| |
| @Override |
| public InputStream input() { |
| return input; |
| } |
| |
| @Override |
| public OutputStream output() { |
| return output; |
| } |
| |
| @Override |
| protected void doClose() throws IOException { |
| ShutdownHooks.remove(closer); |
| for (Map.Entry<Signal, Object> entry : nativeHandlers.entrySet()) { |
| Signals.unregister(entry.getKey().name(), entry.getValue()); |
| } |
| super.doClose(); |
| // Do not call reader.close() |
| reader.shutdown(); |
| } |
| |
| } |