mirror of
https://github.com/xpipe-io/xpipe.git
synced 2024-10-02 18:17:27 +13:00
More work for processes and shells
This commit is contained in:
parent
9d0da32e4f
commit
54bfcd2478
8 changed files with 115 additions and 48 deletions
|
@ -33,6 +33,8 @@ public interface CommandProcessControl extends ProcessControl {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean waitFor();
|
||||||
|
|
||||||
CommandProcessControl customCharset(Charset charset);
|
CommandProcessControl customCharset(Charset charset);
|
||||||
|
|
||||||
int getExitCode();
|
int getExitCode();
|
||||||
|
@ -70,7 +72,7 @@ public interface CommandProcessControl extends ProcessControl {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Thread discardOut();
|
void discardOut();
|
||||||
|
|
||||||
Thread discardErr();
|
void discardErr();
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,5 @@
|
||||||
package io.xpipe.core.store;
|
package io.xpipe.core.store;
|
||||||
|
|
||||||
import io.xpipe.core.util.SupportedOs;
|
|
||||||
|
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.io.OutputStream;
|
import java.io.OutputStream;
|
||||||
|
|
||||||
|
@ -19,7 +17,7 @@ public interface MachineStore extends FileSystemStore, ShellStore {
|
||||||
|
|
||||||
public default String queryMachineName() throws Exception {
|
public default String queryMachineName() throws Exception {
|
||||||
try (var pc = create().start()) {
|
try (var pc = create().start()) {
|
||||||
var operatingSystem = SupportedOs.determine(pc);
|
var operatingSystem = pc.getOsType();
|
||||||
return operatingSystem.determineOperatingSystemName(pc);
|
return operatingSystem.determineOperatingSystemName(pc);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,8 +13,6 @@ public interface ProcessControl extends AutoCloseable {
|
||||||
|
|
||||||
void writeLine(String line) throws IOException;
|
void writeLine(String line) throws IOException;
|
||||||
|
|
||||||
void typeLine(String line);
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
void close() throws IOException;
|
void close() throws IOException;
|
||||||
void kill() throws Exception;
|
void kill() throws Exception;
|
||||||
|
@ -23,8 +21,6 @@ public interface ProcessControl extends AutoCloseable {
|
||||||
|
|
||||||
ProcessControl start() throws Exception;
|
ProcessControl start() throws Exception;
|
||||||
|
|
||||||
boolean waitFor() throws Exception;
|
|
||||||
|
|
||||||
InputStream getStdout();
|
InputStream getStdout();
|
||||||
|
|
||||||
OutputStream getStdin();
|
OutputStream getStdin();
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
package io.xpipe.core.store;
|
package io.xpipe.core.store;
|
||||||
|
|
||||||
|
import io.xpipe.core.util.OsType;
|
||||||
import io.xpipe.core.util.SecretValue;
|
import io.xpipe.core.util.SecretValue;
|
||||||
import lombok.NonNull;
|
import lombok.NonNull;
|
||||||
|
|
||||||
|
@ -11,6 +12,10 @@ import java.util.stream.Collectors;
|
||||||
|
|
||||||
public interface ShellProcessControl extends ProcessControl {
|
public interface ShellProcessControl extends ProcessControl {
|
||||||
|
|
||||||
|
int getProcessId();
|
||||||
|
|
||||||
|
OsType getOsType();
|
||||||
|
|
||||||
ShellProcessControl elevated(Predicate<ShellProcessControl> elevationFunction);
|
ShellProcessControl elevated(Predicate<ShellProcessControl> elevationFunction);
|
||||||
|
|
||||||
ShellProcessControl elevation(SecretValue value);
|
ShellProcessControl elevation(SecretValue value);
|
||||||
|
@ -23,6 +28,10 @@ public interface ShellProcessControl extends ProcessControl {
|
||||||
return shell(type.openCommand());
|
return shell(type.openCommand());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
default CommandProcessControl command(@NonNull ShellType type, String command) {
|
||||||
|
return command(type.switchTo(command));
|
||||||
|
}
|
||||||
|
|
||||||
default ShellProcessControl shell(@NonNull List<String> command) {
|
default ShellProcessControl shell(@NonNull List<String> command) {
|
||||||
return shell(
|
return shell(
|
||||||
command.stream().map(s -> s.contains(" ") ? "\"" + s + "\"" : s).collect(Collectors.joining(" ")));
|
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;
|
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
|
@Override
|
||||||
ShellProcessControl start() throws Exception;
|
ShellProcessControl start() throws Exception;
|
||||||
|
|
||||||
|
@ -59,5 +63,5 @@ public interface ShellProcessControl extends ProcessControl {
|
||||||
command.stream().map(s -> s.contains(" ") ? "\"" + s + "\"" : s).collect(Collectors.joining(" ")));
|
command.stream().map(s -> s.contains(" ") ? "\"" + s + "\"" : s).collect(Collectors.joining(" ")));
|
||||||
}
|
}
|
||||||
|
|
||||||
void exit() throws IOException;
|
void exitAndWait() throws IOException;
|
||||||
}
|
}
|
||||||
|
|
|
@ -27,6 +27,8 @@ public interface ShellType {
|
||||||
|
|
||||||
String getEchoCommand(String s, boolean toErrorStream);
|
String getEchoCommand(String s, boolean toErrorStream);
|
||||||
|
|
||||||
|
String queryShellProcessId(ShellProcessControl control) throws Exception;
|
||||||
|
|
||||||
List<String> openCommand();
|
List<String> openCommand();
|
||||||
|
|
||||||
String switchTo(String cmd);
|
String switchTo(String cmd);
|
||||||
|
|
|
@ -5,6 +5,7 @@ import io.xpipe.core.charsetter.NewLine;
|
||||||
import lombok.Value;
|
import lombok.Value;
|
||||||
|
|
||||||
import java.io.BufferedReader;
|
import java.io.BufferedReader;
|
||||||
|
import java.io.IOException;
|
||||||
import java.io.InputStreamReader;
|
import java.io.InputStreamReader;
|
||||||
import java.nio.charset.Charset;
|
import java.nio.charset.Charset;
|
||||||
import java.nio.charset.StandardCharsets;
|
import java.nio.charset.StandardCharsets;
|
||||||
|
@ -50,6 +51,19 @@ public class ShellTypes {
|
||||||
return toErrorStream ? "(echo " + s + ")1>&2" : "echo " + s;
|
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
|
@Override
|
||||||
public String getConcatenationOperator() {
|
public String getConcatenationOperator() {
|
||||||
return "&";
|
return "&";
|
||||||
|
@ -144,6 +158,23 @@ public class ShellTypes {
|
||||||
@Value
|
@Value
|
||||||
public static class PowerShell implements ShellType {
|
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
|
@Override
|
||||||
public boolean echoesInput() {
|
public boolean echoesInput() {
|
||||||
return true;
|
return true;
|
||||||
|
@ -169,7 +200,11 @@ public class ShellTypes {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getEchoCommand(String s, boolean toErrorStream) {
|
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
|
@Override
|
||||||
|
@ -204,13 +239,18 @@ public class ShellTypes {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Charset determineCharset(ShellProcessControl control) throws Exception {
|
public Charset determineCharset(ShellProcessControl control) throws Exception {
|
||||||
try (CommandProcessControl c = control.command("chcp").start()) {
|
control.writeLine("chcp");
|
||||||
var output = c.readOrThrow().strip();
|
|
||||||
var matcher = Pattern.compile("\\d+").matcher(output);
|
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();
|
matcher.find();
|
||||||
return Charset.forName("ibm" + matcher.group());
|
return Charset.forName("ibm" + matcher.group());
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public NewLine getNewLine() {
|
public NewLine getNewLine() {
|
||||||
|
@ -264,6 +304,16 @@ public class ShellTypes {
|
||||||
return "echo " + s + (toErrorStream ? " 1>&2" : "");
|
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
|
@Override
|
||||||
public List<String> openCommand() {
|
public List<String> openCommand() {
|
||||||
return List.of("sh", "-i", "-l");
|
return List.of("sh", "-i", "-l");
|
||||||
|
@ -291,7 +341,7 @@ public class ShellTypes {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<String> createFileExistsCommand(String file) {
|
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
|
@Override
|
||||||
|
|
|
@ -1,36 +1,37 @@
|
||||||
package io.xpipe.core.util;
|
package io.xpipe.core.util;
|
||||||
|
|
||||||
import io.xpipe.core.store.*;
|
import io.xpipe.core.store.CommandProcessControl;
|
||||||
import lombok.SneakyThrows;
|
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.nio.file.Path;
|
||||||
|
import java.util.Locale;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
|
||||||
public interface SupportedOs {
|
public interface OsType {
|
||||||
|
|
||||||
Windows WINDOWS = new Windows();
|
Windows WINDOWS = new Windows();
|
||||||
Linux LINUX = new Linux();
|
Linux LINUX = new Linux();
|
||||||
Mac MAC = new Mac();
|
Mac MAC = new Mac();
|
||||||
|
|
||||||
static SupportedOs determine(ShellProcessControl pc) throws Exception {
|
String getName();
|
||||||
try (CommandProcessControl c = pc.command(pc.getShellType().createFileExistsCommand("C:\\pagefile.sys")).start()) {
|
|
||||||
if (c.discardAndCheckExit()) {
|
|
||||||
return WINDOWS;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return LINUX;
|
|
||||||
}
|
|
||||||
|
|
||||||
Map<String, String> getProperties(ShellProcessControl pc) throws Exception;
|
Map<String, String> getProperties(ShellProcessControl pc) throws Exception;
|
||||||
|
|
||||||
String determineOperatingSystemName(ShellProcessControl pc) throws Exception;
|
String determineOperatingSystemName(ShellProcessControl pc) throws Exception;
|
||||||
|
|
||||||
@SneakyThrows
|
public static OsType getLocal() {
|
||||||
public static SupportedOs getLocal() {
|
String osName = System.getProperty("os.name", "generic").toLowerCase(Locale.ENGLISH);
|
||||||
try (ShellProcessControl pc = ShellStore.local().create().start()) {
|
if ((osName.contains("mac")) || (osName.contains("darwin"))) {
|
||||||
return determine(pc);
|
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;
|
UUID getSystemUUID(ShellProcessControl pc) throws Exception;
|
||||||
|
|
||||||
static class Windows implements SupportedOs {
|
static class Windows implements OsType {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getName() {
|
||||||
|
return "Windows";
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Map<String, String> getProperties(ShellProcessControl pc) throws Exception {
|
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
|
@Override
|
||||||
public Map<String, String> getProperties(ShellProcessControl pc) throws Exception {
|
public Map<String, String> getProperties(ShellProcessControl pc) throws Exception {
|
||||||
|
@ -81,7 +92,7 @@ public interface SupportedOs {
|
||||||
@Override
|
@Override
|
||||||
public String determineOperatingSystemName(ShellProcessControl pc) throws Exception {
|
public String determineOperatingSystemName(ShellProcessControl pc) throws Exception {
|
||||||
try (CommandProcessControl c =
|
try (CommandProcessControl c =
|
||||||
pc.shell(ShellTypes.SH).command("lsb_release -a").start()) {
|
pc.command(ShellTypes.SH, "lsb_release -a").start()) {
|
||||||
var text = c.readOnlyStdout();
|
var text = c.readOnlyStdout();
|
||||||
if (c.getExitCode() == 0) {
|
if (c.getExitCode() == 0) {
|
||||||
return PropertiesFormatsParser.parse(text, ":").getOrDefault("Description", null);
|
return PropertiesFormatsParser.parse(text, ":").getOrDefault("Description", null);
|
||||||
|
@ -89,7 +100,7 @@ public interface SupportedOs {
|
||||||
}
|
}
|
||||||
|
|
||||||
try (CommandProcessControl c =
|
try (CommandProcessControl c =
|
||||||
pc.shell(ShellTypes.SH).command("cat /etc/*release").start()) {
|
pc.command(ShellTypes.SH, "cat /etc/*release").start()) {
|
||||||
var text = c.readOnlyStdout();
|
var text = c.readOnlyStdout();
|
||||||
if (c.getExitCode() == 0) {
|
if (c.getExitCode() == 0) {
|
||||||
return PropertiesFormatsParser.parse(text, "=").getOrDefault("PRETTY_NAME", null);
|
return PropertiesFormatsParser.parse(text, "=").getOrDefault("PRETTY_NAME", null);
|
||||||
|
@ -97,8 +108,7 @@ public interface SupportedOs {
|
||||||
}
|
}
|
||||||
|
|
||||||
String type = "Unknown";
|
String type = "Unknown";
|
||||||
try (CommandProcessControl c =
|
try (CommandProcessControl c = pc.command(ShellTypes.SH, "uname -o").start()) {
|
||||||
pc.shell(ShellTypes.SH).command("uname -o").start()) {
|
|
||||||
var text = c.readOnlyStdout();
|
var text = c.readOnlyStdout();
|
||||||
if (c.getExitCode() == 0) {
|
if (c.getExitCode() == 0) {
|
||||||
type = text.strip();
|
type = text.strip();
|
||||||
|
@ -106,8 +116,7 @@ public interface SupportedOs {
|
||||||
}
|
}
|
||||||
|
|
||||||
String version = "?";
|
String version = "?";
|
||||||
try (CommandProcessControl c =
|
try (CommandProcessControl c = pc.command(ShellTypes.SH, "uname -r").start()) {
|
||||||
pc.shell(ShellTypes.SH).command("uname -r").start()) {
|
|
||||||
var text = c.readOnlyStdout();
|
var text = c.readOnlyStdout();
|
||||||
if (c.getExitCode() == 0) {
|
if (c.getExitCode() == 0) {
|
||||||
version = text.strip();
|
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
|
@Override
|
||||||
public Map<String, String> getProperties(ShellProcessControl pc) throws Exception {
|
public Map<String, String> getProperties(ShellProcessControl pc) throws Exception {
|
|
@ -18,6 +18,7 @@ public abstract class EventHandler {
|
||||||
cat = "log";
|
cat = "log";
|
||||||
}
|
}
|
||||||
System.out.println("[" + cat + "] " + te.toString());
|
System.out.println("[" + cat + "] " + te.toString());
|
||||||
|
System.out.flush();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
Loading…
Reference in a new issue