mirror of
https://github.com/xpipe-io/xpipe.git
synced 2024-11-22 07:30:24 +00: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);
|
||||
|
||||
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;
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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,13 +239,18 @@ 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);
|
||||
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
|
||||
public NewLine getNewLine() {
|
||||
|
@ -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
|
||||
|
|
|
@ -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 {
|
|
@ -18,6 +18,7 @@ public abstract class EventHandler {
|
|||
cat = "log";
|
||||
}
|
||||
System.out.println("[" + cat + "] " + te.toString());
|
||||
System.out.flush();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
Loading…
Reference in a new issue