Zond:fix: StackOverflow под linux
Пришлось переписывать алгоритм работы ShellStdOut, что бы заработало как надо под Linux-based системами
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
group = 'asys'
|
||||
version = '0.7.13-SNAPSHOT'
|
||||
version = '0.7.14-SNAPSHOT'
|
||||
|
||||
apply plugin: 'application'
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* DmitriyMX <d.mihailov@samson-rus.com>
|
||||
* DmitriyMX <dimon550@gmail.com>
|
||||
* 2017-06-15
|
||||
*/
|
||||
package asys.zond.shell;
|
||||
@@ -11,12 +11,10 @@ import java.io.IOException;
|
||||
public class CommandLooper implements Runnable {
|
||||
private ConsoleReader consoleReader;
|
||||
private CommandHandler commandHandler;
|
||||
private ShellStdOut output;
|
||||
|
||||
CommandLooper(ConsoleReader consoleReader, CommandHandler commandHandler) {
|
||||
this.consoleReader = consoleReader;
|
||||
this.commandHandler = commandHandler;
|
||||
this.output = (ShellStdOut) Shell.getInstance().getOutput();
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -24,9 +22,7 @@ public class CommandLooper implements Runnable {
|
||||
while (!Thread.currentThread().isInterrupted()) {
|
||||
String line;
|
||||
try {
|
||||
output.needDrawLine = true;
|
||||
line = consoleReader.readLine();
|
||||
output.needDrawLine = false;
|
||||
} catch (IOException e) {
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -1,14 +1,12 @@
|
||||
/*
|
||||
* DmitriyMX <d.mihailov@samson-rus.com>
|
||||
* DmitriyMX <dimon550@gmail.com>
|
||||
* 2017-06-15
|
||||
*/
|
||||
package asys.zond.shell;
|
||||
|
||||
import jline.console.ConsoleReader;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.PrintStream;
|
||||
import java.io.*;
|
||||
|
||||
public class Shell {
|
||||
private static final String DEFAULT_PROMPT = ":";
|
||||
@@ -27,7 +25,7 @@ public class Shell {
|
||||
}
|
||||
|
||||
public void start(InputStream inputStream) throws IOException {
|
||||
consoleReader = new ConsoleReader(inputStream, (shellStdOut = new ShellStdOut()));
|
||||
consoleReader = new ConsoleReader(inputStream, (shellStdOut = new ShellStdOut(System.out)));
|
||||
shellStdOut.setConsoleReader(consoleReader);
|
||||
consoleReader.setPrompt(DEFAULT_PROMPT);
|
||||
|
||||
@@ -56,10 +54,6 @@ public class Shell {
|
||||
return shellStdOut;
|
||||
}
|
||||
|
||||
public void setOutputHook(ShellOutputHook outputHook) {
|
||||
shellStdOut.setOutputHook(outputHook);
|
||||
}
|
||||
|
||||
public void setCommandHandler(CommandHandler commandHandler) {
|
||||
this.commandHandler = commandHandler;
|
||||
}
|
||||
|
||||
@@ -1,9 +0,0 @@
|
||||
/*
|
||||
* DmitriyMX <d.mihailov@samson-rus.com>
|
||||
* 2017-06-15
|
||||
*/
|
||||
package asys.zond.shell;
|
||||
|
||||
public interface ShellOutputHook {
|
||||
String handle(String line);
|
||||
}
|
||||
@@ -1,83 +1,93 @@
|
||||
/*
|
||||
* DmitriyMX <d.mihailov@samson-rus.com>
|
||||
* 2017-06-15
|
||||
* DmitriyMX <dimon550@gmail.com>
|
||||
* 2017-07-23
|
||||
*/
|
||||
package asys.zond.shell;
|
||||
|
||||
import jline.console.ConsoleReader;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
import java.io.PrintStream;
|
||||
import java.io.PrintWriter;
|
||||
|
||||
public class ShellStdOut extends PrintStream {
|
||||
private ConsoleReader consoleReader;
|
||||
private PrintWriter writer;
|
||||
private ShellOutputHook shellOutputHook;
|
||||
boolean needDrawLine = false;
|
||||
|
||||
ShellStdOut() {
|
||||
super(System.out, true);
|
||||
ShellStdOut(OutputStream out) {
|
||||
super(out);
|
||||
}
|
||||
|
||||
void setConsoleReader(ConsoleReader consoleReader) {
|
||||
this.consoleReader = consoleReader;
|
||||
this.writer = new PrintWriter(consoleReader.getOutput());
|
||||
}
|
||||
|
||||
private void _print(String line) {
|
||||
String newLine;
|
||||
if (shellOutputHook != null) {
|
||||
private void _write(char c) {
|
||||
try {
|
||||
newLine = shellOutputHook.handle(line);
|
||||
if (newLine == null) return;
|
||||
else line = newLine;
|
||||
} catch (Exception ignore) {
|
||||
this.out.write(c);
|
||||
} catch (IOException ignore) {
|
||||
}
|
||||
}
|
||||
|
||||
writer.print(ConsoleReader.RESET_LINE);
|
||||
writer.print(line);
|
||||
cleanTrashLine(line);
|
||||
writer.println();
|
||||
if (needDrawLine) {
|
||||
private void _write(byte[] buf) {
|
||||
try {
|
||||
consoleReader.drawLine();
|
||||
} catch (Throwable ignore) {
|
||||
this.out.write(buf);
|
||||
} catch (IOException ignore) {
|
||||
}
|
||||
}
|
||||
writer.flush();
|
||||
|
||||
private void _write(byte[] buf, int off, int len) {
|
||||
try {
|
||||
this.out.write(buf, off, len);
|
||||
} catch (IOException ignore) {
|
||||
}
|
||||
}
|
||||
|
||||
private void _flush() {
|
||||
try {
|
||||
this.out.flush();
|
||||
} catch (IOException ignore) {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Очистка печатной строки от мусора
|
||||
*/
|
||||
private void cleanTrashLine(String string) {
|
||||
private void cleanTrashLine(int len) throws IOException {
|
||||
// очищает полностью строку
|
||||
if (consoleReader.getCursorBuffer().buffer.length() + consoleReader.getPrompt().length() > string.length()) {
|
||||
for (int i = string.length(); i <= consoleReader.getCursorBuffer().buffer.length() + 2; i++) {
|
||||
writer.print(' ');
|
||||
if (consoleReader.getCursorBuffer().buffer.length() + consoleReader.getPrompt().length() > len) {
|
||||
for (int i = len; i <= consoleReader.getCursorBuffer().buffer.length() + 2; i++) {
|
||||
this.out.write(' ');
|
||||
}
|
||||
this.out.flush();
|
||||
}
|
||||
}
|
||||
|
||||
void setOutputHook(ShellOutputHook shellOutputHook) {
|
||||
this.shellOutputHook = shellOutputHook;
|
||||
public void printEx(byte[] buf, int len) {
|
||||
_write(ConsoleReader.RESET_LINE);
|
||||
_write(buf, 0, len);
|
||||
try {
|
||||
cleanTrashLine(len);
|
||||
consoleReader.drawLine();
|
||||
consoleReader.flush();
|
||||
} catch (Throwable ignore) {
|
||||
}
|
||||
_flush();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(byte[] buf, int off, int len) {
|
||||
if ((char)buf[len-1] == '\n') len--;
|
||||
if ((char)buf[len-1] == '\r') len--;
|
||||
_print(new String(buf, off, len));
|
||||
_write(buf, off, len);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void print(String s) {
|
||||
_print(s);
|
||||
_write(ConsoleReader.RESET_LINE);
|
||||
_write(s.getBytes());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void println(String x) {
|
||||
_print(x);
|
||||
print(x.concat("\n"));
|
||||
_flush();
|
||||
}
|
||||
|
||||
void setConsoleReader(ConsoleReader consoleReader) {
|
||||
this.consoleReader = consoleReader;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -22,6 +22,7 @@ import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
|
||||
import asys.zond.shell.ShellStdOut;
|
||||
import org.apache.commons.exec.util.DebugUtils;
|
||||
|
||||
/**
|
||||
@@ -106,7 +107,11 @@ public class StreamPumper implements Runnable {
|
||||
try {
|
||||
//hack: пропатчили алгоритм
|
||||
while (!Thread.currentThread().isInterrupted() && (length = is.read(buf)) > 0) {
|
||||
if (os instanceof ShellStdOut) {
|
||||
((ShellStdOut)os).printEx(buf, length);
|
||||
} else {
|
||||
os.write(buf, 0, length);
|
||||
}
|
||||
os.flush();
|
||||
}
|
||||
} catch (final Exception e) {
|
||||
|
||||
Reference in New Issue
Block a user