com.carrotsearch.procfork.ForkedProcess Maven / Gradle / Ivy
/*
* procfork
*
* Copyright (C) 2019, Dawid Weiss.
* All rights reserved.
*/
package com.carrotsearch.procfork;
import java.io.Closeable;
import java.io.IOException;
import java.io.InputStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.time.Instant;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ExecutionException;
import java.util.stream.Collectors;
public class ForkedProcess implements Closeable {
private final Process p;
private final Path processOutput;
public ForkedProcess(Process p, Path processOutput) {
this.p = p;
this.processOutput = processOutput;
}
public Process getProcess() {
return p;
}
public List destroyForcibly() {
ArrayList procList = getProcessHandles();
for (ProcessHandle ph : procList) {
if (ph.isAlive()) {
ph.destroyForcibly();
}
}
return procList;
}
public Path getProcessOutputFile() {
return processOutput;
}
public InputStream getProcessOutputAsStream() throws IOException {
return new TailInputStream(processOutput, () -> !p.isAlive());
}
public int waitFor() throws InterruptedException {
return getProcess().waitFor();
}
@Override
public void close() throws IOException {
List handles = destroyForcibly();
try {
for (ProcessHandle handle : handles) {
handle.onExit().get();
}
} catch (ExecutionException | InterruptedException e) {
throw new IOException(e);
}
Instant deadline = Instant.now().plusSeconds(2);
try {
while (true) {
try {
Files.deleteIfExists(processOutput);
break;
} catch (IOException e) {
if (Instant.now().isAfter(deadline)) {
throw e;
} else {
// Fall-through.
}
}
// Linger a bit before retrying to delete this file.
Thread.sleep(250);
}
} catch (InterruptedException e) {
throw new IOException(e);
}
}
private ArrayList getProcessHandles() {
ArrayList procList =
p.descendants().collect(Collectors.toCollection(ArrayList::new));
procList.add(p.toHandle());
return procList;
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy