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