Clean a bit the Job, introduce a Process interface
ThreadIO becomes optional, as the current streams can be obtained using Process.current().in/out/err()
git-svn-id: https://svn.apache.org/repos/asf/felix/trunk@1736052 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/gogo/jline/src/main/java/org/apache/felix/gogo/jline/Builtin.java b/gogo/jline/src/main/java/org/apache/felix/gogo/jline/Builtin.java
index 1d7051f..4bcdd4f 100644
--- a/gogo/jline/src/main/java/org/apache/felix/gogo/jline/Builtin.java
+++ b/gogo/jline/src/main/java/org/apache/felix/gogo/jline/Builtin.java
@@ -49,8 +49,9 @@
import java.util.regex.Matcher;
import java.util.regex.Pattern;
+import org.apache.felix.gogo.api.Job;
+import org.apache.felix.gogo.api.Process;
import org.apache.felix.gogo.runtime.CommandSessionImpl;
-import org.apache.felix.gogo.runtime.Job;
import org.apache.felix.service.command.CommandSession;
import org.apache.felix.service.command.Converter;
import org.apache.felix.service.command.Function;
@@ -95,8 +96,9 @@
}
public CharSequence format(CommandSession session, Object arg) {
+ Process process = Process.current();
CharSequence result = session.format(arg, Converter.INSPECT);
- System.out.println(result);
+ process.out().println(result);
return result;
}
@@ -182,10 +184,11 @@
" +x unset xtrace option",
"If PREFIX given, then only show variable(s) starting with PREFIX"};
+ Process process = Process.current();
Options opt = Options.compile(usage).parse(argv);
if (opt.isSet("help")) {
- opt.usage(System.err);
+ opt.usage(process.err());
return;
}
@@ -216,7 +219,7 @@
}
String trunc = value == null || value.length() < 55 ? "" : "...";
- System.out.println(String.format("%-15.15s %-15s %.45s%s", type, key,
+ process.out().println(String.format("%-15.15s %-15s %.45s%s", type, key,
value, trunc));
}
}
@@ -235,10 +238,11 @@
" -l --list return List<String>",
" -? --help show help"};
+ Process process = Process.current();
Options opt = Options.compile(usage).parse(argv);
if (opt.isSet("help")) {
- opt.usage(System.err);
+ opt.usage(process.err());
return null;
}
@@ -259,7 +263,7 @@
}
StringWriter sw = new StringWriter();
- BufferedReader rdr = new BufferedReader(new InputStreamReader(System.in));
+ BufferedReader rdr = new BufferedReader(new InputStreamReader(process.in()));
ArrayList<String> list = null;
@@ -305,11 +309,12 @@
" -s --scope=NAME list all commands in named scope",
" -t --types show full java type names"};
+ Process process = Process.current();
Options opt = Options.compile(usage).parse(argv);
List<String> args = opt.args();
if (opt.isSet("help")) {
- opt.usage(System.err);
+ opt.usage(process.err());
return true;
}
@@ -337,7 +342,7 @@
}
for (String sname : snames) {
- System.out.println(sname);
+ process.out().println(sname);
}
return true;
@@ -357,7 +362,7 @@
}
for (Entry<String, Integer> entry : scopes.entrySet()) {
- System.out.println(entry.getKey() + ":" + entry.getValue());
+ process.out().println(entry.getKey() + ":" + entry.getValue());
}
return true;
@@ -446,13 +451,13 @@
if (buf.length() > 0) {
if (!opt.isSet("quiet")) {
- System.out.println(buf);
+ process.out().println(buf);
}
return true;
}
if (!opt.isSet("quiet")) {
- System.err.println("type: " + name + " not found.");
+ process.err().println("type: " + name + " not found.");
}
return false;
@@ -464,21 +469,22 @@
"Usage: jobs [OPTIONS]",
" -? --help show help",
};
+ Process process = Process.current();
Options opt = Options.compile(usage).parse(argv);
if (opt.isSet("help")) {
- opt.usage(System.err);
+ opt.usage(process.err());
return;
}
if (!opt.args().isEmpty()) {
- System.err.println("usage: jobs");
- session.error(2);
+ process.err().println("usage: jobs");
+ process.error(2);
return;
}
List<Job> jobs = session.jobs();
- Job current = session.currentJob();
+ Job current = Job.current();
for (Job job : jobs) {
if (job != current) {
- System.out.println("[" + job.id() + "] " + job.status().toString().toLowerCase()
+ process.out().println("[" + job.id() + "] " + job.status().toString().toLowerCase()
+ " " + job.command());
}
}
@@ -490,27 +496,28 @@
"Usage: fg [OPTIONS] [jobid]",
" -? --help show help",
};
+ Process process = Process.current();
Options opt = Options.compile(usage).parse(argv);
if (opt.isSet("help")) {
- opt.usage(System.err);
+ opt.usage(process.err());
return;
}
if (opt.args().size() > 1) {
- System.err.println("usage: fg [jobid]");
- session.error(2);
+ process.err().println("usage: fg [jobid]");
+ process.error(2);
return;
}
List<Job> jobs = session.jobs();
Collections.reverse(jobs);
- Job current = session.currentJob();
+ Job current = Job.current();
if (argv.length == 0) {
Job job = jobs.stream().filter(j -> j != current)
.findFirst().orElse(null);
if (job != null) {
job.foreground();
} else {
- System.err.println("fg: no current job");
- session.error(1);
+ process.err().println("fg: no current job");
+ process.error(1);
}
} else {
Job job = jobs.stream().filter(j -> j != current && argv[0].equals(Integer.toString(j.id())))
@@ -518,8 +525,8 @@
if (job != null) {
job.foreground();
} else {
- System.err.println("fg: job not found: " + argv[0]);
- session.error(1);
+ process.err().println("fg: job not found: " + argv[0]);
+ process.error(1);
}
}
}
@@ -530,27 +537,28 @@
"Usage: bg [OPTIONS] [jobid]",
" -? --help show help",
};
+ Process process = Process.current();
Options opt = Options.compile(usage).parse(argv);
if (opt.isSet("help")) {
- opt.usage(System.err);
+ opt.usage(process.err());
return;
}
if (opt.args().size() > 1) {
- System.err.println("usage: bg [jobid]");
- session.error(2);
+ process.err().println("usage: bg [jobid]");
+ process.error(2);
return;
}
List<Job> jobs = session.jobs();
Collections.reverse(jobs);
- Job current = session.currentJob();
+ Job current = Job.current();
if (argv.length == 0) {
Job job = jobs.stream().filter(j -> j != current)
.findFirst().orElse(null);
if (job != null) {
job.background();
} else {
- System.err.println("bg: no current job");
- session.error(1);
+ process.err().println("bg: no current job");
+ process.error(1);
}
} else {
Job job = jobs.stream().filter(j -> j != current && argv[0].equals(Integer.toString(j.id())))
@@ -558,8 +566,8 @@
if (job != null) {
job.background();
} else {
- System.err.println("bg: job not found: " + argv[0]);
- session.error(1);
+ process.err().println("bg: job not found: " + argv[0]);
+ process.error(1);
}
}
}
@@ -631,11 +639,13 @@
}
public void history(CommandSession session, String[] argv) throws IOException {
- Commands.history(Shell.getReader(session), System.out, System.err, argv);
+ Process process = Process.current();
+ Commands.history(Shell.getReader(session), process.out(), process.err(), argv);
}
public void complete(CommandSession session, String[] argv) {
- Commands.complete(Shell.getReader(session), System.out, System.err, Shell.getCompletions(session), argv);
+ Process process = Process.current();
+ Commands.complete(Shell.getReader(session), process.out(), process.err(), Shell.getCompletions(session), argv);
}
public void widget(final CommandSession session, String[] argv) throws Exception {
@@ -648,19 +658,23 @@
}
return true;
};
- Commands.widget(Shell.getReader(session), System.out, System.err, creator, argv);
+ Process process = Process.current();
+ Commands.widget(Shell.getReader(session), process.out(), process.err(), creator, argv);
}
public void keymap(CommandSession session, String[] argv) {
- Commands.keymap(Shell.getReader(session), System.out, System.err, argv);
+ Process process = Process.current();
+ Commands.keymap(Shell.getReader(session), process.out(), process.err(), argv);
}
public void setopt(CommandSession session, String[] argv) {
- Commands.setopt(Shell.getReader(session), System.out, System.err, argv);
+ Process process = Process.current();
+ Commands.setopt(Shell.getReader(session), process.out(), process.err(), argv);
}
public void unsetopt(CommandSession session, String[] argv) {
- Commands.unsetopt(Shell.getReader(session), System.out, System.err, argv);
+ Process process = Process.current();
+ Commands.unsetopt(Shell.getReader(session), process.out(), process.err(), argv);
}
public List<Candidate> __files(CommandSession session) {
diff --git a/gogo/jline/src/main/java/org/apache/felix/gogo/jline/Posix.java b/gogo/jline/src/main/java/org/apache/felix/gogo/jline/Posix.java
index 0946f5f..bbb52ad 100644
--- a/gogo/jline/src/main/java/org/apache/felix/gogo/jline/Posix.java
+++ b/gogo/jline/src/main/java/org/apache/felix/gogo/jline/Posix.java
@@ -71,6 +71,7 @@
import java.util.stream.Collectors;
import java.util.stream.Stream;
+import org.apache.felix.gogo.api.Process;
import org.apache.felix.gogo.jline.Shell.Context;
import org.apache.felix.service.command.CommandProcessor;
import org.apache.felix.service.command.CommandSession;
@@ -120,17 +121,18 @@
if (argv == null || argv.length < 1) {
throw new IllegalArgumentException();
}
+ Process process = Process.current();
try {
- run(session, argv);
+ run(session, process, argv);
} catch (IllegalArgumentException e) {
- System.err.println(e.getMessage());
- session.error(2);
+ process.err().println(e.getMessage());
+ process.error(2);
} catch (HelpException e) {
- System.err.println(e.getMessage());
- session.error(0);
+ process.err().println(e.getMessage());
+ process.error(0);
} catch (Exception e) {
- System.err.println(argv[0] + ": " + e.getMessage());
- session.error(1);
+ process.err().println(argv[0] + ": " + e.getMessage());
+ process.error(1);
}
}
@@ -155,64 +157,64 @@
return o != null ? o.toString() : null;
}
- protected Object run(CommandSession session, String[] argv) throws Exception {
+ protected Object run(CommandSession session, Process process, String[] argv) throws Exception {
switch (argv[0]) {
case "cat":
- cat(session, argv);
+ cat(session, process, argv);
break;
case "echo":
- echo(session, argv);
+ echo(session, process, argv);
break;
case "grep":
- grep(session, argv);
+ grep(session, process, argv);
break;
case "sort":
- sort(session, argv);
+ sort(session, process, argv);
break;
case "sleep":
- sleep(session, argv);
+ sleep(session, process, argv);
break;
case "cd":
- cd(session, argv);
+ cd(session, process, argv);
break;
case "pwd":
- pwd(session, argv);
+ pwd(session, process, argv);
break;
case "ls":
- ls(session, argv);
+ ls(session, process, argv);
break;
case "less":
- less(session, argv);
+ less(session, process, argv);
break;
case "watch":
- watch(session, argv);
+ watch(session, process, argv);
break;
case "nano":
- nano(session, argv);
+ nano(session, process, argv);
break;
case "tmux":
- tmux(session, argv);
+ tmux(session, process, argv);
break;
case "clear":
- clear(session, argv);
+ clear(session, process, argv);
break;
case "head":
- head(session, argv);
+ head(session, process, argv);
break;
case "tail":
- tail(session, argv);
+ tail(session, process, argv);
break;
case "wc":
- wc(session, argv);
+ wc(session, process, argv);
break;
case "date":
- date(session, argv);
+ date(session, process, argv);
break;
}
return null;
}
- protected void date(CommandSession session, String[] argv) throws Exception {
+ protected void date(CommandSession session, Process process, String[] argv) throws Exception {
String[] usage = {
"date - display date",
"Usage: date [-r seconds] [-v[+|-]val[mwdHMS] ...] [-f input_fmt new_date] [+output_fmt]",
@@ -259,7 +261,7 @@
output = "%c";
}
// Print output
- System.out.println(new SimpleDateFormat(toJavaDateFormat(output)).format(input));
+ process.out().println(new SimpleDateFormat(toJavaDateFormat(output)).format(input));
}
private String toJavaDateFormat(String format) {
@@ -339,7 +341,7 @@
return sb.toString();
}
- protected void wc(CommandSession session, String[] argv) throws Exception {
+ protected void wc(CommandSession session, Process process, String[] argv) throws Exception {
String[] usage = {
"wc - word, line, character, and byte count",
"Usage: wc [OPTIONS] [FILES]",
@@ -459,7 +461,7 @@
if (!lastNl.get()) {
lines.incrementAndGet();
}
- System.out.println(String.format(format, lines.get(), words.get(), chars.get(), bytes.get(), src.getName()));
+ process.out().println(String.format(format, lines.get(), words.get(), chars.get(), bytes.get(), src.getName()));
totalBytes += bytes.get();
totalChars += chars.get();
totalWords += words.get();
@@ -467,11 +469,11 @@
}
}
if (sources.size() > 1) {
- System.out.println(String.format(format, totalLines, totalWords, totalChars, totalBytes, "total"));
+ process.out().println(String.format(format, totalLines, totalWords, totalChars, totalBytes, "total"));
}
}
- protected void head(CommandSession session, String[] argv) throws Exception {
+ protected void head(CommandSession session, Process process, String[] argv) throws Exception {
String[] usage = {
"head - displays first lines of file",
"Usage: head [-n lines | -c bytes] [file ...]",
@@ -508,9 +510,9 @@
int lines = nbLines;
if (sources.size() > 1) {
if (src != sources.get(0)) {
- System.out.println();
+ process.out().println();
}
- System.out.println("==> " + src.getName() + " <==");
+ process.out().println("==> " + src.getName() + " <==");
}
try (InputStream is = src.read()) {
byte[] buf = new byte[1024];
@@ -526,14 +528,14 @@
}
}
bytes -= nb;
- System.out.write(buf, 0, nb);
+ process.out().write(buf, 0, nb);
}
} while (nb > 0 && lines > 0 && bytes > 0);
}
}
}
- protected void tail(CommandSession session, String[] argv) throws Exception {
+ protected void tail(CommandSession session, Process process, String[] argv) throws Exception {
String[] usage = {
"tail - displays last lines of file",
"Usage: tail [-f] [-q] [-c # | -n #] [file ...]",
@@ -703,10 +705,10 @@
private void print(String toPrint) {
if (lastPrinted.get() != this && opt.args().size() > 1 && !opt.isSet("quiet")) {
- System.out.println();
- System.out.println("==> " + name + " <==");
+ process.out().println();
+ process.out().println("==> " + name + " <==");
}
- System.out.print(toPrint);
+ process.out().print(toPrint);
lastPrinted.set(this);
}
}
@@ -741,22 +743,22 @@
}
}
- protected void clear(CommandSession session, String[] argv) throws Exception {
+ protected void clear(CommandSession session, Process process, String[] argv) throws Exception {
final String[] usage = {
"clear - clear screen",
"Usage: clear [OPTIONS]",
" -? --help Show help",
};
Options opt = parseOptions(session, usage, argv);
- if (session.isTty(1)) {
+ if (process.isTty(1)) {
Shell.getTerminal(session).puts(Capability.clear_screen);
Shell.getTerminal(session).flush();
}
}
- protected void tmux(final CommandSession session, String[] argv) throws Exception {
+ protected void tmux(final CommandSession session, Process process, String[] argv) throws Exception {
Commands.tmux(Shell.getTerminal(session),
- System.out, System.err,
+ process.out(), System.err,
() -> session.get(".tmux"),
t -> session.put(".tmux", t),
c -> startShell(session, c),
@@ -794,7 +796,7 @@
}
}
- protected void nano(final CommandSession session, String[] argv) throws Exception {
+ protected void nano(final CommandSession session, Process process, String[] argv) throws Exception {
final String[] usage = {
"nano - edit files",
"Usage: nano [FILES]",
@@ -806,7 +808,7 @@
edit.run();
}
- protected void watch(final CommandSession session, String[] argv) throws Exception {
+ protected void watch(final CommandSession session, Process process, String[] argv) throws Exception {
final String[] usage = {
"watch - watches & refreshes the output of a command",
"Usage: watch [OPTIONS] COMMAND",
@@ -863,7 +865,7 @@
}
}
- protected void less(CommandSession session, String[] argv) throws Exception {
+ protected void less(CommandSession session, Process process, String[] argv) throws Exception {
final String[] usage = {
"less - file pager",
"Usage: less [OPTIONS] [FILES]",
@@ -891,10 +893,10 @@
}
}
- if (!session.isTty(1)) {
+ if (!process.isTty(1)) {
for (Source source : sources) {
try (BufferedReader reader = new BufferedReader(new InputStreamReader(source.read()))) {
- cat(reader, opt.isSet("LINE-NUMBERS"));
+ cat(process, reader, opt.isSet("LINE-NUMBERS"));
}
}
return;
@@ -915,7 +917,7 @@
less.run(sources);
}
- protected void sort(CommandSession session, String[] argv) throws Exception {
+ protected void sort(CommandSession session, Process process, String[] argv) throws Exception {
final String[] usage = {
"sort - writes sorted standard input to standard output.",
"Usage: sort [OPTIONS] [FILES]",
@@ -941,7 +943,7 @@
}
}
} else {
- BufferedReader r = new BufferedReader(new InputStreamReader(System.in));
+ BufferedReader r = new BufferedReader(new InputStreamReader(process.in()));
read(r, lines);
}
@@ -958,13 +960,13 @@
String last = null;
for (String s : lines) {
if (!unique || last == null || !s.equals(last)) {
- System.out.println(s);
+ process.out().println(s);
}
last = s;
}
}
- protected void pwd(CommandSession session, String[] argv) throws Exception {
+ protected void pwd(CommandSession session, Process process, String[] argv) throws Exception {
final String[] usage = {
"pwd - get current directory",
"Usage: pwd [OPTIONS]",
@@ -974,10 +976,10 @@
if (!opt.args().isEmpty()) {
throw new IllegalArgumentException("usage: pwd");
}
- System.out.println(session.currentDir());
+ process.out().println(session.currentDir());
}
- protected void cd(CommandSession session, String[] argv) throws Exception {
+ protected void cd(CommandSession session, Process process, String[] argv) throws Exception {
final String[] usage = {
"cd - get current directory",
"Usage: cd [OPTIONS] DIRECTORY",
@@ -997,7 +999,7 @@
session.currentDir(cwd);
}
- protected void ls(CommandSession session, String[] argv) throws Exception {
+ protected void ls(CommandSession session, Process process, String[] argv) throws Exception {
final String[] usage = {
"ls - list files",
"Usage: ls [OPTIONS] [PATTERNS...]",
@@ -1094,7 +1096,7 @@
}
String col = colors.get(type);
boolean addSuffix = opt.isSet("F");
- if (col != null && !col.isEmpty() && session.isTty(1)) { // TODO: ability to force colors if piped
+ if (col != null && !col.isEmpty() && process.isTty(1)) { // TODO: ability to force colors if piped
return "\033[" + col + "m" + path.toString() + "\033[m" + (addSuffix ? suffix : "") + link;
} else {
return path.toString() + (addSuffix ? suffix : "") + link;
@@ -1222,14 +1224,14 @@
List<PathEntry> files = all.stream()
.filter(PathEntry::isNotDirectory)
.collect(Collectors.toList());
- PrintStream out = System.out;
+ PrintStream out = process.out();
Consumer<Stream<PathEntry>> display = s -> {
boolean optLine = opt.isSet("1");
boolean optComma = opt.isSet("m");
boolean optLong = opt.isSet("l");
boolean optCol = opt.isSet("C");
if (!optLine && !optComma && !optLong && !optCol) {
- if (session.isTty(1)) {
+ if (process.isTty(1)) {
optCol = true;
}
else {
@@ -1250,7 +1252,7 @@
}
// Column listing
else if (optCol) {
- toColumn(session, out, s.map(PathEntry::display), opt.isSet("x"));
+ toColumn(session, process, out, s.map(PathEntry::display), opt.isSet("x"));
}
};
boolean space = false;
@@ -1279,9 +1281,9 @@
}
}
- private void toColumn(CommandSession session, PrintStream out, Stream<String> ansi, boolean horizontal) {
+ private void toColumn(CommandSession session, Process process, PrintStream out, Stream<String> ansi, boolean horizontal) {
Terminal terminal = Shell.getTerminal(session);
- int width = session.isTty(1) ? terminal.getWidth() : 80;
+ int width = process.isTty(1) ? terminal.getWidth() : 80;
List<AttributedString> strings = ansi.map(AttributedString::fromAnsi).collect(Collectors.toList());
if (!strings.isEmpty()) {
int max = strings.stream().mapToInt(AttributedString::columnLength).max().getAsInt();
@@ -1318,7 +1320,7 @@
}
}
- protected void cat(CommandSession session, String[] argv) throws Exception {
+ protected void cat(CommandSession session, Process process, String[] argv) throws Exception {
final String[] usage = {
"cat - concatenate and print FILES",
"Usage: cat [OPTIONS] [FILES]",
@@ -1334,15 +1336,15 @@
for (String arg : args) {
InputStream is;
if ("-".equals(arg)) {
- is = System.in;
+ is = process.in();
} else {
is = cwd.toUri().resolve(arg).toURL().openStream();
}
- cat(new BufferedReader(new InputStreamReader(is)), opt.isSet("n"));
+ cat(process, new BufferedReader(new InputStreamReader(is)), opt.isSet("n"));
}
}
- protected void echo(CommandSession session, Object[] argv) throws Exception {
+ protected void echo(CommandSession session, Process process, Object[] argv) throws Exception {
final String[] usage = {
"echo - echoes or prints ARGUMENT to standard output",
"Usage: echo [OPTIONS] [ARGUMENTS]",
@@ -1425,13 +1427,13 @@
}
}
if (opt.isSet("n")) {
- System.out.print(buf);
+ process.out().print(buf);
} else {
- System.out.println(buf);
+ process.out().println(buf);
}
}
- protected void grep(CommandSession session, String[] argv) throws Exception {
+ protected void grep(CommandSession session, Process process, String[] argv) throws Exception {
final String[] usage = {
"grep - search for PATTERN in each FILE or standard input.",
"Usage: grep [OPTIONS] PATTERN [FILES]",
@@ -1544,12 +1546,12 @@
if (lineMatch != 0 & lineMatch + after + before <= lines.size()) {
if (!count) {
if (!firstPrint && before + after > 0) {
- System.out.println("--");
+ process.out().println("--");
} else {
firstPrint = false;
}
for (int i = 0; i < lineMatch + after; i++) {
- System.out.println(lines.get(i));
+ process.out().println(lines.get(i));
}
}
while (lines.size() > before) {
@@ -1566,24 +1568,24 @@
}
if (!count && lineMatch > 0) {
if (!firstPrint && before + after > 0) {
- System.out.println("--");
+ process.out().println("--");
} else {
firstPrint = false;
}
for (int i = 0; i < lineMatch + after && i < lines.size(); i++) {
- System.out.println(lines.get(i));
+ process.out().println(lines.get(i));
}
}
if (count) {
- System.out.println(nb);
+ process.out().println(nb);
}
match |= nb > 0;
}
}
- session.error(match ? 0 : 1);
+ Process.current().error(match ? 0 : 1);
}
- protected void sleep(CommandSession session, String[] argv) throws Exception {
+ protected void sleep(CommandSession session, Process process, String[] argv) throws Exception {
final String[] usage = {
"sleep - suspend execution for an interval of time",
"Usage: sleep seconds",
@@ -1605,15 +1607,15 @@
}
}
- private static void cat(final BufferedReader reader, boolean displayLineNumbers) throws IOException {
+ private static void cat(Process process, final BufferedReader reader, boolean displayLineNumbers) throws IOException {
String line;
int lineno = 1;
try {
while ((line = reader.readLine()) != null) {
if (displayLineNumbers) {
- System.out.print(String.format("%6d ", lineno++));
+ process.out().print(String.format("%6d ", lineno++));
}
- System.out.println(line);
+ process.out().println(line);
}
} finally {
reader.close();
diff --git a/gogo/jline/src/main/java/org/apache/felix/gogo/jline/Procedural.java b/gogo/jline/src/main/java/org/apache/felix/gogo/jline/Procedural.java
index 0515b1b..67cad88 100644
--- a/gogo/jline/src/main/java/org/apache/felix/gogo/jline/Procedural.java
+++ b/gogo/jline/src/main/java/org/apache/felix/gogo/jline/Procedural.java
@@ -25,6 +25,7 @@
import java.util.Collection;
import java.util.List;
+import org.apache.felix.gogo.api.Process;
import org.apache.felix.service.command.CommandSession;
import org.apache.felix.service.command.Function;
import org.jline.builtins.Options;
@@ -37,16 +38,17 @@
if (argv == null || argv.length < 1) {
throw new IllegalArgumentException();
}
+ Process process = Process.current();
try {
- run(session, argv);
+ run(session, process, argv);
} catch (OptionException e) {
- System.err.println(e.getMessage());
- session.error(2);
+ process.err().println(e.getMessage());
+ process.error(2);
} catch (HelpException e) {
- System.err.println(e.getMessage());
- session.error(0);
+ process.err().println(e.getMessage());
+ process.error(0);
} catch (ThrownException e) {
- session.error(1);
+ process.error(1);
throw e.getCause();
}
}
@@ -94,33 +96,34 @@
return o != null ? o.toString() : null;
}
- protected Object run(CommandSession session, Object[] argv) throws Throwable {
+ protected Object run(CommandSession session, Process process, Object[] argv) throws Throwable {
switch (argv[0].toString()) {
case "each":
- return doEach(session, argv);
+ return doEach(session, process, argv);
case "if":
- return doIf(session, argv);
+ return doIf(session, process, argv);
case "not":
- return doNot(session, argv);
+ return doNot(session, process, argv);
case "throw":
- return doThrow(session, argv);
+ return doThrow(session, process, argv);
case "try":
- return doTry(session, argv);
+ return doTry(session, process, argv);
case "until":
- return doUntil(session, argv);
+ return doUntil(session, process, argv);
case "while":
- return doWhile(session, argv);
+ return doWhile(session, process, argv);
case "break":
- return doBreak(session, argv);
+ return doBreak(session, process, argv);
case "continue":
- return doContinue(session, argv);
+ return doContinue(session, process, argv);
default:
throw new UnsupportedOperationException();
}
}
protected List<Object> doEach(CommandSession session,
- Object[] argv) throws Exception {
+ Process process,
+ Object[] argv) throws Exception {
String[] usage = {
"each - loop over the elements",
"Usage: each [-r] elements { closure }",
@@ -135,10 +138,10 @@
List<Function> functions = getFunctions(opt);
if (elements == null || functions == null || functions.size() != 1) {
- System.err.println("usage: each elements { closure }");
- System.err.println(" elements: an array to iterate on");
- System.err.println(" closure: a function or closure to call");
- session.error(2);
+ process.err().println("usage: each elements { closure }");
+ process.err().println(" elements: an array to iterate on");
+ process.err().println(" closure: a function or closure to call");
+ process.error(2);
return null;
}
@@ -161,7 +164,7 @@
return opt.isSet("result") ? results : null;
}
- protected Object doIf(CommandSession session, Object[] argv) throws Exception {
+ protected Object doIf(CommandSession session, Process process, Object[] argv) throws Exception {
String[] usage = {
"if - if / then / else construct",
"Usage: if {condition} {if-action} ... {else-action}",
@@ -170,8 +173,8 @@
Options opt = parseOptions(session, usage, argv);
List<Function> functions = getFunctions(opt);
if (functions == null || functions.size() < 2) {
- System.err.println("usage: if {condition} {if-action} ... {else-action}");
- session.error(2);
+ process.err().println("usage: if {condition} {if-action} ... {else-action}");
+ process.error(2);
return null;
}
for (int i = 0, length = functions.size(); i < length; ++i) {
@@ -182,7 +185,7 @@
return null;
}
- protected Boolean doNot(CommandSession session, Object[] argv) throws Exception {
+ protected Boolean doNot(CommandSession session, Process process, Object[] argv) throws Exception {
String[] usage = {
"not - return the opposite condition",
"Usage: not { condition }",
@@ -191,15 +194,15 @@
Options opt = parseOptions(session, usage, argv);
List<Function> functions = getFunctions(opt);
if (functions == null || functions.size() != 1) {
- System.err.println("usage: not { condition }");
- session.error(2);
+ process.err().println("usage: not { condition }");
+ process.error(2);
return null;
}
return !isTrue(session, functions.get(0));
}
- protected Object doThrow(CommandSession session, Object[] argv) throws ThrownException, HelpException, OptionException {
+ protected Object doThrow(CommandSession session, Process process, Object[] argv) throws ThrownException, HelpException, OptionException {
String[] usage = {
"throw - throw an exception",
"Usage: throw [ message [ cause ] ]",
@@ -230,7 +233,7 @@
}
}
- protected Object doTry(CommandSession session, Object[] argv) throws Exception {
+ protected Object doTry(CommandSession session, Process process, Object[] argv) throws Exception {
String[] usage = {
"try - try / catch / finally construct",
"Usage: try { try-action } [ { catch-action } [ { finally-action } ] ]",
@@ -239,8 +242,8 @@
Options opt = parseOptions(session, usage, argv);
List<Function> functions = getFunctions(opt);
if (functions == null || functions.size() < 1 || functions.size() > 3) {
- System.err.println("usage: try { try-action } [ { catch-action } [ { finally-action } ] ]");
- session.error(2);
+ process.err().println("usage: try { try-action } [ { catch-action } [ { finally-action } ] ]");
+ process.error(2);
return null;
}
try {
@@ -260,7 +263,7 @@
}
}
- protected Object doWhile(CommandSession session, Object[] argv) throws Exception {
+ protected Object doWhile(CommandSession session, Process process, Object[] argv) throws Exception {
String[] usage = {
"while - while loop",
"Usage: while { condition } { action }",
@@ -269,8 +272,8 @@
Options opt = parseOptions(session, usage, argv);
List<Function> functions = getFunctions(opt);
if (functions == null || functions.size() != 2) {
- System.err.println("usage: while { condition } { action }");
- session.error(2);
+ process.err().println("usage: while { condition } { action }");
+ process.error(2);
return null;
}
while (isTrue(session, functions.get(0))) {
@@ -285,7 +288,7 @@
return null;
}
- protected Object doUntil(CommandSession session, Object[] argv) throws Exception {
+ protected Object doUntil(CommandSession session, Process process, Object[] argv) throws Exception {
String[] usage = {
"until - until loop",
"Usage: until { condition } { action }",
@@ -304,8 +307,8 @@
}
int length = opt.argObjects().size();
if (length != 2 || functions == null) {
- System.err.println("usage: until { condition } { action }");
- session.error(2);
+ process.err().println("usage: until { condition } { action }");
+ process.error(2);
return null;
}
while (!isTrue(session, functions.get(0))) {
@@ -320,7 +323,7 @@
return null;
}
- protected Object doBreak(CommandSession session, Object[] argv) throws Exception {
+ protected Object doBreak(CommandSession session, Process process, Object[] argv) throws Exception {
String[] usage = {
"break - break from loop",
"Usage: break",
@@ -330,7 +333,7 @@
throw new BreakException();
}
- protected Object doContinue(CommandSession session, Object[] argv) throws Exception {
+ protected Object doContinue(CommandSession session, Process process, Object[] argv) throws Exception {
String[] usage = {
"continue - continue loop",
"Usage: continue",
diff --git a/gogo/jline/src/main/java/org/apache/felix/gogo/jline/Shell.java b/gogo/jline/src/main/java/org/apache/felix/gogo/jline/Shell.java
index 7e962e6..cf91985 100644
--- a/gogo/jline/src/main/java/org/apache/felix/gogo/jline/Shell.java
+++ b/gogo/jline/src/main/java/org/apache/felix/gogo/jline/Shell.java
@@ -42,8 +42,8 @@
import org.apache.felix.gogo.runtime.Closure;
import org.apache.felix.gogo.runtime.CommandProxy;
import org.apache.felix.gogo.runtime.CommandSessionImpl;
-import org.apache.felix.gogo.runtime.Job;
-import org.apache.felix.gogo.runtime.Job.Status;
+import org.apache.felix.gogo.api.Job;
+import org.apache.felix.gogo.api.Job.Status;
import org.apache.felix.gogo.runtime.Reflective;
import org.apache.felix.service.command.CommandProcessor;
import org.apache.felix.service.command.CommandSession;
diff --git a/gogo/runtime/src/main/java/org/apache/felix/gogo/runtime/Job.java b/gogo/runtime/src/main/java/org/apache/felix/gogo/api/Job.java
similarity index 75%
rename from gogo/runtime/src/main/java/org/apache/felix/gogo/runtime/Job.java
rename to gogo/runtime/src/main/java/org/apache/felix/gogo/api/Job.java
index 721fa8c..3b09044 100644
--- a/gogo/runtime/src/main/java/org/apache/felix/gogo/runtime/Job.java
+++ b/gogo/runtime/src/main/java/org/apache/felix/gogo/api/Job.java
@@ -16,12 +16,26 @@
* specific language governing permissions and limitations
* under the License.
*/
-package org.apache.felix.gogo.runtime;
+package org.apache.felix.gogo.api;
-import org.apache.felix.gogo.runtime.Pipe.Result;
+import java.util.List;
+
+import org.apache.felix.service.command.CommandSession;
public interface Job {
+ /**
+ * Get the job running in the current thead or null.
+ */
+ static Job current() {
+ Process p = Process.current();
+ Job j = p != null ? p.job() : null;
+ while (j != null && j.parent() != null) {
+ j = j.parent();
+ }
+ return j;
+ }
+
enum Status {
Created,
Suspended,
@@ -59,4 +73,10 @@
*/
Result start(Status status) throws InterruptedException;
+ List<Process> processes();
+
+ CommandSession session();
+
+ Job parent();
+
}
diff --git a/gogo/runtime/src/main/java/org/apache/felix/gogo/api/JobListener.java b/gogo/runtime/src/main/java/org/apache/felix/gogo/api/JobListener.java
index 4596176..a5d7ca6 100644
--- a/gogo/runtime/src/main/java/org/apache/felix/gogo/api/JobListener.java
+++ b/gogo/runtime/src/main/java/org/apache/felix/gogo/api/JobListener.java
@@ -18,8 +18,7 @@
*/
package org.apache.felix.gogo.api;
-import org.apache.felix.gogo.runtime.Job;
-import org.apache.felix.gogo.runtime.Job.Status;
+import org.apache.felix.gogo.api.Job.Status;
/**
* Listener for command executions.
diff --git a/gogo/runtime/src/main/java/org/apache/felix/gogo/api/Process.java b/gogo/runtime/src/main/java/org/apache/felix/gogo/api/Process.java
new file mode 100644
index 0000000..71c1305
--- /dev/null
+++ b/gogo/runtime/src/main/java/org/apache/felix/gogo/api/Process.java
@@ -0,0 +1,53 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.felix.gogo.api;
+
+import java.io.InputStream;
+import java.io.PrintStream;
+
+import org.apache.felix.gogo.runtime.Pipe;
+
+public interface Process {
+
+ static Process current() {
+ return Pipe.getCurrentPipe();
+ }
+
+ InputStream in();
+
+ PrintStream out();
+
+ PrintStream err();
+
+ /**
+ * Get the job controlling this process
+ */
+ Job job();
+
+ /**
+ * Check if the given descriptor for the currently running pipe is the terminal or not.
+ */
+ boolean isTty(int fd);
+
+ /**
+ * Set the error code for the currently running pipe.
+ */
+ void error(int error);
+
+}
diff --git a/gogo/runtime/src/main/java/org/apache/felix/gogo/api/Result.java b/gogo/runtime/src/main/java/org/apache/felix/gogo/api/Result.java
new file mode 100644
index 0000000..6b4e7c2
--- /dev/null
+++ b/gogo/runtime/src/main/java/org/apache/felix/gogo/api/Result.java
@@ -0,0 +1,30 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.felix.gogo.api;
+
+public interface Result {
+
+ boolean isSuccess();
+
+ Object result();
+
+ Exception exception();
+
+ int error();
+}
diff --git a/gogo/runtime/src/main/java/org/apache/felix/gogo/runtime/Closure.java b/gogo/runtime/src/main/java/org/apache/felix/gogo/runtime/Closure.java
index 34f70a0..de8a330 100644
--- a/gogo/runtime/src/main/java/org/apache/felix/gogo/runtime/Closure.java
+++ b/gogo/runtime/src/main/java/org/apache/felix/gogo/runtime/Closure.java
@@ -33,7 +33,7 @@
import java.util.Map;
import java.util.Map.Entry;
-import org.apache.felix.gogo.runtime.Job.Status;
+import org.apache.felix.gogo.api.Job.Status;
import org.apache.felix.gogo.runtime.Parser.Array;
import org.apache.felix.gogo.runtime.Parser.Executable;
import org.apache.felix.gogo.runtime.Parser.Operator;
@@ -224,10 +224,14 @@
toclose[1] = true;
}
- List<Pipe> pipes = new ArrayList<>();
+ CommandSessionImpl.JobImpl job;
if (executable instanceof Pipeline) {
Pipeline pipeline = (Pipeline) executable;
List<Executable> exec = pipeline.tokens();
+ Token s = exec.get(0);
+ Token e = exec.get(exec.size() - 1);
+ Token t = program.subSequence(s.start - program.start, e.start + e.length - program.start);
+ job = session().createJob(t);
for (int i = 0; i < exec.size(); i++) {
Statement ex = (Statement) exec.get(i);
Operator op = i < exec.size() - 1 ? (Operator) exec.get(++i) : null;
@@ -257,18 +261,15 @@
} else {
throw new IllegalStateException("Unrecognized pipe operator: '" + op + "'");
}
- pipes.add(new Pipe(this, ex, nstreams, ntoclose));
+ Pipe pipe = new Pipe(this, job, ex, nstreams, ntoclose);
+ job.addPipe(pipe);
}
} else {
- pipes.add(new Pipe(this, (Statement) executable, streams, toclose));
+ job = session().createJob(executable);
+ Pipe pipe = new Pipe(this, job, (Statement) executable, streams, toclose);
+ job.addPipe(pipe);
}
- // Create job
- Token s = pipes.get(0).statement;
- Token e = pipes.get(pipes.size() - 1).statement;
- Token t = program.subSequence(s.start - program.start, e.start + e.length - program.start);
- Job job = session().createJob(t, pipes);
-
// Start pipe in background
if (operator != null && Token.eq("&", operator)) {
job.start(Status.Background);
diff --git a/gogo/runtime/src/main/java/org/apache/felix/gogo/runtime/CommandProcessorImpl.java b/gogo/runtime/src/main/java/org/apache/felix/gogo/runtime/CommandProcessorImpl.java
index e12a2d0..eb0588b 100644
--- a/gogo/runtime/src/main/java/org/apache/felix/gogo/runtime/CommandProcessorImpl.java
+++ b/gogo/runtime/src/main/java/org/apache/felix/gogo/runtime/CommandProcessorImpl.java
@@ -50,6 +50,11 @@
protected final WeakHashMap<CommandSession, Object> sessions = new WeakHashMap<>();
protected boolean stopped;
+ public CommandProcessorImpl()
+ {
+ this(null);
+ }
+
public CommandProcessorImpl(ThreadIO tio)
{
threadIO = tio;
diff --git a/gogo/runtime/src/main/java/org/apache/felix/gogo/runtime/CommandSessionImpl.java b/gogo/runtime/src/main/java/org/apache/felix/gogo/runtime/CommandSessionImpl.java
index 0375a81..85370bb 100644
--- a/gogo/runtime/src/main/java/org/apache/felix/gogo/runtime/CommandSessionImpl.java
+++ b/gogo/runtime/src/main/java/org/apache/felix/gogo/runtime/CommandSessionImpl.java
@@ -51,8 +51,10 @@
import java.util.concurrent.Future;
import java.util.stream.Collectors;
+import org.apache.felix.gogo.api.Job;
+import org.apache.felix.gogo.api.Job.Status;
import org.apache.felix.gogo.api.JobListener;
-import org.apache.felix.gogo.runtime.Job.Status;
+import org.apache.felix.gogo.api.Process;
import org.apache.felix.gogo.runtime.Pipe.Result;
import org.apache.felix.service.command.CommandProcessor;
import org.apache.felix.service.command.CommandSession;
@@ -80,7 +82,6 @@
protected final ConcurrentMap<String, Object> variables = new ConcurrentHashMap<>();
private volatile boolean closed;
private final List<JobImpl> jobs = new ArrayList<>();
- private final ThreadLocal<JobImpl> currentJob = new InheritableThreadLocal<>();
private JobListener jobListener;
private final ExecutorService executor;
@@ -152,7 +153,6 @@
public Object execute(CharSequence commandline) throws Exception
{
assert processor != null;
- assert processor.threadIO != null;
if (closed)
{
@@ -494,17 +494,12 @@
@Override
public List<Job> jobs() {
synchronized (jobs) {
- return new ArrayList<>(jobs);
+ return Collections.unmodifiableList(jobs);
}
}
- @Override
- public JobImpl currentJob() {
- JobImpl job = currentJob.get();
- while (job != null && job.parent != null) {
- job = job.parent;
- }
- return job;
+ public static JobImpl currentJob() {
+ return (JobImpl) Job.current();
}
@Override
@@ -526,7 +521,7 @@
}
}
- public Job createJob(CharSequence command, List<Pipe> pipes) {
+ public JobImpl createJob(CharSequence command) {
synchronized (jobs) {
int id = 1;
synchronized (jobs) {
@@ -543,7 +538,7 @@
} while (found);
}
JobImpl cur = currentJob();
- JobImpl job = new JobImpl(id, cur, command, pipes);
+ JobImpl job = new JobImpl(id, cur, command);
if (cur == null) {
jobs.add(job);
}
@@ -551,20 +546,23 @@
}
}
- private class JobImpl implements Job {
+ class JobImpl implements Job {
private final int id;
private final JobImpl parent;
private final CharSequence command;
- private final List<Pipe> pipes;
+ private final List<Pipe> pipes = new ArrayList<>();
private Status status = Status.Created;
private Future<?> future;
private Result result;
- public JobImpl(int id, JobImpl parent, CharSequence command, List<Pipe> pipes) {
+ public JobImpl(int id, JobImpl parent, CharSequence command) {
this.id = id;
this.parent = parent;
this.command = command;
- this.pipes = pipes;
+ }
+
+ void addPipe(Pipe pipe) {
+ pipes.add(pipe);
}
@Override
@@ -606,7 +604,7 @@
if (status == Status.Done) {
throw new IllegalStateException("Job is finished");
}
- JobImpl cr = currentJob();
+ JobImpl cr = CommandSessionImpl.currentJob();
JobImpl fg = foregroundJob();
if (parent == null && fg != null && fg != this && fg != cr) {
throw new IllegalStateException("A job is already in foreground");
@@ -667,6 +665,11 @@
}
@Override
+ public Job parent() {
+ return parent;
+ }
+
+ @Override
public synchronized Result start(Status status) throws InterruptedException {
if (status == Status.Created || status == Status.Done) {
throw new IllegalArgumentException("Illegal start status");
@@ -692,13 +695,22 @@
return result;
}
+ public List<Process> processes() {
+ return Collections.unmodifiableList(pipes);
+ }
+
+ @Override
+ public CommandSession session() {
+ return CommandSessionImpl.this;
+ }
+
private Void call() throws Exception {
Thread thread = Thread.currentThread();
String name = thread.getName();
try {
thread.setName("job controller " + id);
- List<Callable<Result>> wrapped = pipes.stream().map(this::wrap).collect(Collectors.toList());
+ List<Callable<Result>> wrapped = pipes.stream().collect(Collectors.toList());
List<Future<Result>> results = executor.invokeAll(wrapped);
// Get pipe exceptions
@@ -729,27 +741,6 @@
return null;
}
- private Callable<Result> wrap(Pipe pipe) {
- return () -> {
- JobImpl prevJob = currentJob.get();
- try {
- currentJob.set(this);
- return pipe.call();
- } finally {
- currentJob.set(prevJob);
- }
- };
- }
-
}
- @Override
- public boolean isTty(int fd) {
- return Pipe.isTty(fd);
- }
-
- @Override
- public void error(int error) {
- Pipe.error(error);
- }
}
diff --git a/gogo/runtime/src/main/java/org/apache/felix/gogo/runtime/Pipe.java b/gogo/runtime/src/main/java/org/apache/felix/gogo/runtime/Pipe.java
index 0073894..bae9d3b 100644
--- a/gogo/runtime/src/main/java/org/apache/felix/gogo/runtime/Pipe.java
+++ b/gogo/runtime/src/main/java/org/apache/felix/gogo/runtime/Pipe.java
@@ -42,16 +42,20 @@
import java.util.regex.Matcher;
import java.util.regex.Pattern;
-import org.apache.felix.gogo.runtime.Job.Status;
+import org.apache.felix.gogo.runtime.CommandSessionImpl.JobImpl;
+import org.apache.felix.gogo.api.Job;
+import org.apache.felix.gogo.api.Job.Status;
+import org.apache.felix.gogo.api.Process;
import org.apache.felix.gogo.runtime.Parser.Statement;
import org.apache.felix.gogo.runtime.Pipe.Result;
import org.apache.felix.service.command.Converter;
+import org.apache.felix.service.threadio.ThreadIO;
-public class Pipe implements Callable<Result>
+public class Pipe implements Callable<Result>, Process
{
private static final ThreadLocal<Pipe> CURRENT = new ThreadLocal<>();
- public static class Result {
+ public static class Result implements org.apache.felix.gogo.api.Result {
public final Object result;
public final Exception exception;
public final int error;
@@ -77,24 +81,27 @@
public boolean isSuccess() {
return exception == null && error == 0;
}
+
+ @Override
+ public Object result() {
+ return result;
+ }
+
+ @Override
+ public Exception exception() {
+ return exception;
+ }
+
+ @Override
+ public int error() {
+ return error;
+ }
}
public static Pipe getCurrentPipe() {
return CURRENT.get();
}
- public static boolean isTty(int fd) {
- Pipe current = getCurrentPipe();
- return current != null && !current.toclose[fd];
- }
-
- public static void error(int error) {
- Pipe current = getCurrentPipe();
- if (current != null) {
- current.error = error;
- }
- }
-
private static Pipe setCurrentPipe(Pipe pipe) {
Pipe previous = CURRENT.get();
CURRENT.set(pipe);
@@ -102,14 +109,20 @@
}
final Closure closure;
+ final Job job;
final Statement statement;
final Channel[] streams;
final boolean[] toclose;
int error;
- public Pipe(Closure closure, Statement statement, Channel[] streams, boolean[] toclose)
+ InputStream in;
+ PrintStream out;
+ PrintStream err;
+
+ public Pipe(Closure closure, JobImpl job, Statement statement, Channel[] streams, boolean[] toclose)
{
this.closure = closure;
+ this.job = job;
this.statement = statement;
this.streams = streams;
this.toclose = toclose;
@@ -169,6 +182,35 @@
}
@Override
+ public InputStream in() {
+ return in;
+ }
+
+ @Override
+ public PrintStream out() {
+ return out;
+ }
+
+ @Override
+ public PrintStream err() {
+ return err;
+ }
+
+ @Override
+ public Job job() {
+ return job;
+ }
+
+ public boolean isTty(int fd) {
+ // TODO: this assumes that the session is always created with input/output tty streams
+ return !toclose[fd];
+ }
+
+ public void error(int error) {
+ this.error = error;
+ }
+
+ @Override
public Result call() throws Exception {
Thread thread = Thread.currentThread();
String name = thread.getName();
@@ -182,10 +224,6 @@
private Result doCall()
{
- InputStream in;
- PrintStream out = null;
- PrintStream err = null;
-
// The errChannel will be used to print errors to the error stream
// Before the command is actually executed (i.e. during the initialization,
// including the redirection processing), it will be the original error stream.
@@ -195,6 +233,8 @@
boolean endOfPipe = !toclose[1];
+ ThreadIO threadIo = closure.session().threadIO();
+
try
{
List<Token> tokens = statement.redirections();
@@ -283,7 +323,9 @@
// the command is about to be executed.
errChannel = (WritableByteChannel) streams[2];
- closure.session().threadIO().setStreams(in, out, err);
+ if (threadIo != null) {
+ threadIo.setStreams(in, out, err);
+ }
Pipe previous = setCurrentPipe(this);
try {
@@ -332,7 +374,9 @@
if (err != null) {
err.flush();
}
- closure.session().threadIO().close();
+ if (threadIo != null) {
+ threadIo.close();
+ }
try
{
@@ -458,28 +502,23 @@
}
private void checkSuspend(Channel ch) throws IOException {
- Job cur = closure.session().currentJob();
- if (cur != null) {
- Channel[] sch = closure.session().channels;
- if (ch == sch[0] || ch == sch[1] || ch == sch[2]) {
- synchronized (cur) {
- if (cur.status() == Status.Background) {
- // TODO: Send SIGTIN / SIGTOU
- cur.suspend();
- }
+ Channel[] sch = closure.session().channels;
+ if (ch == sch[0] || ch == sch[1] || ch == sch[2]) {
+ synchronized (job) {
+ if (job.status() == Status.Background) {
+ // TODO: Send SIGTIN / SIGTOU
+ job.suspend();
}
}
- synchronized (cur) {
- while (cur.status() == Status.Suspended) {
- try {
- cur.wait();
- } catch (InterruptedException e) {
- throw (IOException) new InterruptedIOException().initCause(e);
- }
+ }
+ synchronized (job) {
+ while (job.status() == Status.Suspended) {
+ try {
+ job.wait();
+ } catch (InterruptedException e) {
+ throw (IOException) new InterruptedIOException().initCause(e);
}
}
- } else {
- String msg = "This is definitely not expected";
}
}
}
diff --git a/gogo/runtime/src/main/java/org/apache/felix/service/command/CommandSession.java b/gogo/runtime/src/main/java/org/apache/felix/service/command/CommandSession.java
index 01fc644..3cb5068 100644
--- a/gogo/runtime/src/main/java/org/apache/felix/service/command/CommandSession.java
+++ b/gogo/runtime/src/main/java/org/apache/felix/service/command/CommandSession.java
@@ -23,8 +23,8 @@
import java.nio.file.Path;
import java.util.List;
+import org.apache.felix.gogo.api.Job;
import org.apache.felix.gogo.api.JobListener;
-import org.apache.felix.gogo.runtime.Job;
public interface CommandSession
{
@@ -113,11 +113,6 @@
List<Job> jobs();
/**
- * Get the job running in the current thead or null.
- */
- Job currentJob();
-
- /**
* Get the current foreground job or null.
*/
Job foregroundJob();
@@ -127,18 +122,13 @@
*/
void setJobListener(JobListener listener);
- //
- // Process access
- //
-
/**
- * Check if the given descriptor for the currently running pipe is the terminal or not.
+ * Return the current session.
+ * Available inside from a command call.
*/
- boolean isTty(int fd);
-
- /**
- * Set the error code for the currently running pipe.
- */
- void error(int error);
+ static CommandSession current() {
+ Job j = Job.current();
+ return j != null ? j.session() : null;
+ }
}
diff --git a/gogo/runtime/src/test/java/org/apache/felix/gogo/runtime/TestParser.java b/gogo/runtime/src/test/java/org/apache/felix/gogo/runtime/TestParser.java
index ed8fbf3..48a99af 100644
--- a/gogo/runtime/src/test/java/org/apache/felix/gogo/runtime/TestParser.java
+++ b/gogo/runtime/src/test/java/org/apache/felix/gogo/runtime/TestParser.java
@@ -27,6 +27,7 @@
import java.util.List;
import java.util.regex.Pattern;
+import org.apache.felix.gogo.api.Process;
import org.apache.felix.gogo.runtime.Parser.Pipeline;
import org.apache.felix.gogo.runtime.Parser.Program;
import org.apache.felix.gogo.runtime.Parser.Sequence;
@@ -467,7 +468,7 @@
public boolean istty(CommandSession session, int fd)
{
- return session.isTty(fd);
+ return Process.current().isTty(fd);
}
void each(CommandSession session, Collection<Object> list, Function closure)