2019-05-22 16:23:33 -07:00
|
|
|
/*
|
|
|
|
|
* ProcessController
|
|
|
|
|
*
|
|
|
|
|
* v1.0
|
|
|
|
|
*
|
|
|
|
|
* May 22, 2019
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
package JobServ;
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* ProcessController
|
|
|
|
|
* This class wraps a java Process object with metadata
|
|
|
|
|
* such as translated PID that exist for this specific API
|
|
|
|
|
* as well as general metadata like IO streams.
|
|
|
|
|
*/
|
|
|
|
|
class ProcessController {
|
|
|
|
|
// incremented in constructor
|
|
|
|
|
private static int nextPid = 0;
|
|
|
|
|
private int pid;
|
|
|
|
|
|
|
|
|
|
// TODO: add an api endpoint for streaming client input into
|
|
|
|
|
// interactive processes (out of scope for initial API)
|
|
|
|
|
private OutputStream output;
|
|
|
|
|
private InputStream input;
|
|
|
|
|
private Scanner outputScanner;
|
|
|
|
|
|
|
|
|
|
private Process process;
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* Constructor
|
|
|
|
|
* Takes a command and spawns it in a new process
|
|
|
|
|
* Redirects IO streams and assigns a fake PID
|
|
|
|
|
*/
|
|
|
|
|
public ProcessController(String command) throws IOException {
|
|
|
|
|
this.pid = ProcessController.nextPid;
|
|
|
|
|
ProcessController.nextPid += 1;
|
|
|
|
|
|
|
|
|
|
this.process = Runtime.exec(command);
|
|
|
|
|
this.output = this.process.getOutputStream();
|
|
|
|
|
this.input = this.process.getInputStream();
|
|
|
|
|
this.outputScanner = new Scanner(this.input);
|
|
|
|
|
this.outputScanner.useDelimieter("\\A");
|
|
|
|
|
}
|
|
|
|
|
|
2019-05-22 22:25:44 -07:00
|
|
|
/*
|
|
|
|
|
* getPid()
|
|
|
|
|
* returns translated pid of this process
|
|
|
|
|
*/
|
|
|
|
|
public int getPid() {
|
|
|
|
|
return this.pid;
|
|
|
|
|
}
|
|
|
|
|
|
2019-05-22 16:23:33 -07:00
|
|
|
/*
|
|
|
|
|
* getStatus()
|
|
|
|
|
* returns whether or not the process is running
|
|
|
|
|
* this isnt a very direct way of getting the information
|
|
|
|
|
* The alternative is to use reflection to get into the private UNIXProcess class
|
|
|
|
|
* for the PID and to check that against 'ps' or a similar command
|
|
|
|
|
*
|
|
|
|
|
* TODO: (for future release) return thread state
|
|
|
|
|
*/
|
|
|
|
|
public Boolean getStatus() {
|
|
|
|
|
try {
|
|
|
|
|
process.exitValue();
|
|
|
|
|
return true;
|
|
|
|
|
} catch (IllegalThreadStateException e) {
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* getReturn()
|
|
|
|
|
* returns the exit code of the process
|
|
|
|
|
* or 256 if process is still running
|
|
|
|
|
* (unix/posix defines an exit code as a uint8, so 256 is fair game)
|
|
|
|
|
*/
|
|
|
|
|
public int getReturn() {
|
|
|
|
|
try {
|
|
|
|
|
return process.exitValue();
|
|
|
|
|
} catch (IllegalThreadStateException e) {
|
|
|
|
|
return 256;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* getOutput()
|
2019-05-22 22:25:44 -07:00
|
|
|
* gets output from process
|
2019-05-22 16:23:33 -07:00
|
|
|
*/
|
|
|
|
|
public String getOutput() {
|
|
|
|
|
String out = "";
|
|
|
|
|
while(scanner.hasNext()) {
|
|
|
|
|
out += scanner.next();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return out;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* kill()
|
|
|
|
|
* Cleans up resources and destroys process
|
|
|
|
|
*/
|
|
|
|
|
public void kill() {
|
|
|
|
|
this.input.close();
|
|
|
|
|
this.output.close();
|
|
|
|
|
process.destroy();
|
|
|
|
|
}
|
|
|
|
|
}
|