More work for processes and shells

This commit is contained in:
Christopher Schnick 2022-11-22 05:18:05 +01:00
parent 9d0da32e4f
commit 54bfcd2478
8 changed files with 115 additions and 48 deletions

View file

@ -33,6 +33,8 @@ public interface CommandProcessControl extends ProcessControl {
}
}
public boolean waitFor();
CommandProcessControl customCharset(Charset charset);
int getExitCode();
@ -70,7 +72,7 @@ public interface CommandProcessControl extends ProcessControl {
}
}
Thread discardOut();
void discardOut();
Thread discardErr();
void discardErr();
}

View file

@ -1,7 +1,5 @@
package io.xpipe.core.store;
import io.xpipe.core.util.SupportedOs;
import java.io.InputStream;
import java.io.OutputStream;
@ -19,7 +17,7 @@ public interface MachineStore extends FileSystemStore, ShellStore {
public default String queryMachineName() throws Exception {
try (var pc = create().start()) {
var operatingSystem = SupportedOs.determine(pc);
var operatingSystem = pc.getOsType();
return operatingSystem.determineOperatingSystemName(pc);
}
}

View file

@ -13,8 +13,6 @@ public interface ProcessControl extends AutoCloseable {
void writeLine(String line) throws IOException;
void typeLine(String line);
@Override
void close() throws IOException;
void kill() throws Exception;
@ -23,8 +21,6 @@ public interface ProcessControl extends AutoCloseable {
ProcessControl start() throws Exception;
boolean waitFor() throws Exception;
InputStream getStdout();
OutputStream getStdin();

View file

@ -1,5 +1,6 @@
package io.xpipe.core.store;
import io.xpipe.core.util.OsType;
import io.xpipe.core.util.SecretValue;
import lombok.NonNull;
@ -11,6 +12,10 @@ import java.util.stream.Collectors;
public interface ShellProcessControl extends ProcessControl {
int getProcessId();
OsType getOsType();
ShellProcessControl elevated(Predicate<ShellProcessControl> elevationFunction);
ShellProcessControl elevation(SecretValue value);
@ -23,6 +28,10 @@ public interface ShellProcessControl extends ProcessControl {
return shell(type.openCommand());
}
default CommandProcessControl command(@NonNull ShellType type, String command) {
return command(type.switchTo(command));
}
default ShellProcessControl shell(@NonNull List<String> command) {
return shell(
command.stream().map(s -> s.contains(" ") ? "\"" + s + "\"" : s).collect(Collectors.joining(" ")));
@ -36,11 +45,6 @@ public interface ShellProcessControl extends ProcessControl {
void executeCommand(String command) throws Exception;
default void executeCommand(List<String> command) throws Exception {
executeCommand(
command.stream().map(s -> s.contains(" ") ? "\"" + s + "\"" : s).collect(Collectors.joining(" ")));
}
@Override
ShellProcessControl start() throws Exception;
@ -59,5 +63,5 @@ public interface ShellProcessControl extends ProcessControl {
command.stream().map(s -> s.contains(" ") ? "\"" + s + "\"" : s).collect(Collectors.joining(" ")));
}
void exit() throws IOException;
void exitAndWait() throws IOException;
}

View file

@ -27,6 +27,8 @@ public interface ShellType {
String getEchoCommand(String s, boolean toErrorStream);
String queryShellProcessId(ShellProcessControl control) throws Exception;
List<String> openCommand();
String switchTo(String cmd);

View file

@ -5,6 +5,7 @@ import io.xpipe.core.charsetter.NewLine;
import lombok.Value;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
@ -50,6 +51,19 @@ public class ShellTypes {
return toErrorStream ? "(echo " + s + ")1>&2" : "echo " + s;
}
@Override
public String queryShellProcessId(ShellProcessControl control) throws IOException {
control.writeLine("powershell (Get-WmiObject Win32_Process -Filter ProcessId=$PID).ParentProcessId");
var r = new BufferedReader(new InputStreamReader(control.getStdout(), StandardCharsets.US_ASCII));
// Read echo of command
r.readLine();
// Read actual output
var line = r.readLine();
r.readLine();
return line;
}
@Override
public String getConcatenationOperator() {
return "&";
@ -144,6 +158,23 @@ public class ShellTypes {
@Value
public static class PowerShell implements ShellType {
@Override
public String queryShellProcessId(ShellProcessControl control) throws IOException {
control.writeLine("powershell (Get-WmiObject Win32_Process -Filter ProcessId=$PID).ParentProcessId");
var r = new BufferedReader(new InputStreamReader(control.getStdout(), StandardCharsets.US_ASCII));
// Read echo of command
r.readLine();
// Read actual output
var line = r.readLine();
return line;
}
@Override
public String getConcatenationOperator() {
return ";";
}
@Override
public boolean echoesInput() {
return true;
@ -169,7 +200,11 @@ public class ShellTypes {
@Override
public String getEchoCommand(String s, boolean toErrorStream) {
return String.format("%s \"%s\"", toErrorStream ? "Write-Error" : "Write-Output", s);
if (toErrorStream) {
return String.format("$host.ui.WriteErrorLine('%s')", s);
}
return String.format("%s \"%s\"", "Write-Output", s);
}
@Override
@ -204,12 +239,17 @@ public class ShellTypes {
@Override
public Charset determineCharset(ShellProcessControl control) throws Exception {
try (CommandProcessControl c = control.command("chcp").start()) {
var output = c.readOrThrow().strip();
var matcher = Pattern.compile("\\d+").matcher(output);
matcher.find();
return Charset.forName("ibm" + matcher.group());
}
control.writeLine("chcp");
var r = new BufferedReader(new InputStreamReader(control.getStdout(), StandardCharsets.US_ASCII));
// Read echo of command
r.readLine();
// Read actual output
var line = r.readLine();
var matcher = Pattern.compile("\\d+").matcher(line);
matcher.find();
return Charset.forName("ibm" + matcher.group());
}
@Override
@ -264,6 +304,16 @@ public class ShellTypes {
return "echo " + s + (toErrorStream ? " 1>&2" : "");
}
@Override
public String queryShellProcessId(ShellProcessControl control) throws Exception {
try (CommandProcessControl c = control.command("echo $$").start()) {
var out = c.readOnlyStdout();
var matcher = Pattern.compile("\\d+$").matcher(out);
matcher.find();
return matcher.group(0);
}
}
@Override
public List<String> openCommand() {
return List.of("sh", "-i", "-l");
@ -291,7 +341,7 @@ public class ShellTypes {
@Override
public List<String> createFileExistsCommand(String file) {
return List.of("test", "-f", file, "||", "test", "-d", file);
return List.of("(", "test", "-f", file, "||", "test", "-d", file, ")");
}
@Override

View file

@ -1,36 +1,37 @@
package io.xpipe.core.util;
import io.xpipe.core.store.*;
import lombok.SneakyThrows;
import io.xpipe.core.store.CommandProcessControl;
import io.xpipe.core.store.PropertiesFormatsParser;
import io.xpipe.core.store.ShellProcessControl;
import io.xpipe.core.store.ShellTypes;
import java.nio.file.Path;
import java.util.Locale;
import java.util.Map;
import java.util.UUID;
public interface SupportedOs {
public interface OsType {
Windows WINDOWS = new Windows();
Linux LINUX = new Linux();
Mac MAC = new Mac();
static SupportedOs determine(ShellProcessControl pc) throws Exception {
try (CommandProcessControl c = pc.command(pc.getShellType().createFileExistsCommand("C:\\pagefile.sys")).start()) {
if (c.discardAndCheckExit()) {
return WINDOWS;
}
}
return LINUX;
}
String getName();
Map<String, String> getProperties(ShellProcessControl pc) throws Exception;
String determineOperatingSystemName(ShellProcessControl pc) throws Exception;
@SneakyThrows
public static SupportedOs getLocal() {
try (ShellProcessControl pc = ShellStore.local().create().start()) {
return determine(pc);
public static OsType getLocal() {
String osName = System.getProperty("os.name", "generic").toLowerCase(Locale.ENGLISH);
if ((osName.contains("mac")) || (osName.contains("darwin"))) {
return MAC;
} else if (osName.contains("win")) {
return WINDOWS;
} else if (osName.contains("nux")) {
return LINUX;
} else {
throw new UnsupportedOperationException("Unknown operating system");
}
}
@ -38,7 +39,12 @@ public interface SupportedOs {
UUID getSystemUUID(ShellProcessControl pc) throws Exception;
static class Windows implements SupportedOs {
static class Windows implements OsType {
@Override
public String getName() {
return "Windows";
}
@Override
public Map<String, String> getProperties(ShellProcessControl pc) throws Exception {
@ -71,7 +77,12 @@ public interface SupportedOs {
}
}
static class Linux implements SupportedOs {
static class Linux implements OsType {
@Override
public String getName() {
return "Linux";
}
@Override
public Map<String, String> getProperties(ShellProcessControl pc) throws Exception {
@ -81,7 +92,7 @@ public interface SupportedOs {
@Override
public String determineOperatingSystemName(ShellProcessControl pc) throws Exception {
try (CommandProcessControl c =
pc.shell(ShellTypes.SH).command("lsb_release -a").start()) {
pc.command(ShellTypes.SH, "lsb_release -a").start()) {
var text = c.readOnlyStdout();
if (c.getExitCode() == 0) {
return PropertiesFormatsParser.parse(text, ":").getOrDefault("Description", null);
@ -89,7 +100,7 @@ public interface SupportedOs {
}
try (CommandProcessControl c =
pc.shell(ShellTypes.SH).command("cat /etc/*release").start()) {
pc.command(ShellTypes.SH, "cat /etc/*release").start()) {
var text = c.readOnlyStdout();
if (c.getExitCode() == 0) {
return PropertiesFormatsParser.parse(text, "=").getOrDefault("PRETTY_NAME", null);
@ -97,8 +108,7 @@ public interface SupportedOs {
}
String type = "Unknown";
try (CommandProcessControl c =
pc.shell(ShellTypes.SH).command("uname -o").start()) {
try (CommandProcessControl c = pc.command(ShellTypes.SH, "uname -o").start()) {
var text = c.readOnlyStdout();
if (c.getExitCode() == 0) {
type = text.strip();
@ -106,8 +116,7 @@ public interface SupportedOs {
}
String version = "?";
try (CommandProcessControl c =
pc.shell(ShellTypes.SH).command("uname -r").start()) {
try (CommandProcessControl c = pc.command(ShellTypes.SH, "uname -r").start()) {
var text = c.readOnlyStdout();
if (c.getExitCode() == 0) {
version = text.strip();
@ -128,7 +137,12 @@ public interface SupportedOs {
}
}
static class Mac implements SupportedOs {
static class Mac implements OsType {
@Override
public String getName() {
return "Mac";
}
@Override
public Map<String, String> getProperties(ShellProcessControl pc) throws Exception {

View file

@ -18,6 +18,7 @@ public abstract class EventHandler {
cat = "log";
}
System.out.println("[" + cat + "] " + te.toString());
System.out.flush();
}
@Override