package kernel; import java.io.*; import java.util.List; import commands.*; /** * Instance of process * * @author Jan Horký * @since 5.11.2008 * @version 4.1 */ public abstract class AbstractProcess extends Thread implements IProcess { private int id; private Command command; private InputStream in; private OutputStream out; private OutputStream err; private AbstractProcess parent; private AbstractProcess prevSibling; private AbstractProcess nextSibling; private AbstractProcess firstChild; private List args; protected Kernel services; private String currentPath; /** * Constructor without any parameters for ClassLoader */ public AbstractProcess() { // this.setName( // String.format("%s - %s", this.getId(), this.command.getCommandName()) // ); } /** * Construct process * * @param command * command name * @param in * input stream * @param out * output stream * @param err * error stream * @param services * kernel services */ public void init(Command command, InputStream in, OutputStream out, OutputStream err, Kernel services) { this.id = services.newID(); this.command = command; this.setProcessName(this.id, this.command.getCommandName()); this.in = in; this.out = out; this.err = err; this.services = services; } /** * Construct process * * @param command * command name * @param parent * parent process * @param in * input stream * @param out * output stream * @param err * error stream * @param services * kernel services */ public void init(Command command, AbstractProcess parent, InputStream in, OutputStream out, OutputStream err, Kernel services) { this.id = services.newID(); this.command = command; this.setProcessName(this.id, this.command.getCommandName()); this.services = services; this.parent = parent; this.in = in; this.out = out; this.err = err; } /** * Method for process execution */ private void setProcessName(int id, String name) { this.setName(String.format("%s - %s", id, name)); } /** * Method for process execution */ public void exec() { this.start(); } /** * thread run of process */ public void run() { try { this.realization(); if (this.parent instanceof shell) { Thread.sleep(500); this.getErrOut().close(); this.getOut().close(); ((shell) this.parent).procesEnd(); this.getServices().deleteProcess(this.getID()); this.interrupt(); } else if (this instanceof login) { this.getServices().deleteProcess(this.getID()); this.interrupt(); } } catch (Exception e) { e.printStackTrace(); } } /** * Kill process and all children */ public void kill() { AbstractProcess process; /* * kills all children */ if (this.firstChild != null) { process = this.firstChild; while (process.nextSibling != null) { process.kill(); process = process.nextSibling; } process.kill(); } /* * kill all siblings */ process = this; while (process.prevSibling != null) process = process.prevSibling; while (process.nextSibling != null) { process = process.nextSibling; if (process.prevSibling != this) process.prevSibling.kill(); } if (process != this) process.kill(); killMe(); } /** * Stop process execution */ private void killMe() { this.interrupt(); } public boolean equals(Object o) { if (o instanceof AbstractProcess) if (((AbstractProcess) o).id == this.id) return true; return false; } /** * @return first child process */ public AbstractProcess getFirstChild() { return this.firstChild; } /** * set child process */ public void setFirstChild(AbstractProcess process) { this.firstChild = process; } /** * @return next process in pipe */ public AbstractProcess getNext() { return this.nextSibling; } /** * @param next * next process in pipe */ public void setNext(AbstractProcess next) { this.nextSibling = next; } /** * @return previous process in pipe */ public AbstractProcess getPrevious() { return prevSibling; } /** * @param previous * previous process in pipe */ public void setPrevious(AbstractProcess previous) { this.prevSibling = previous; } /** * @return id of process */ public int getID() { return id; } /** * @return name of process */ public String getCommand() { return command.getCommandName(); } /** * @return input stream */ public synchronized InputStream getIn() { return this.in; } /** * @return output stream */ public synchronized OutputStream getOut() { if (this.out == null) return ((shell) this.parent).getStdOutPipe().getPipeOut(); else return this.out; } /** * @return error output stream */ public synchronized OutputStream getErrOut() { return this.err; } public synchronized void setIn(InputStream in) { this.in = in; } public synchronized void setOut(OutputStream out) { this.out = out; } public synchronized void setErrOut(OutputStream err) { this.err = err; } /** * @return list of command line arguments */ public List getArgs() { return this.command.getArguments(); } /** * @return instance of interface which contains methods for comunication with * kernel */ public Kernel getKernel() { return this.services; } /** * @return parent process */ public AbstractProcess getParent() { return this.parent; } public AbstractProcess getParentShell() { if (this instanceof shell) return this; else if (parent != null) return parent.getParentShell(); else return null; } public String toString() { return this.id + "-" + this.command.getCommandName(); } public void printError(String text) { try { this.getErrOut().write(text.getBytes()); this.getErrOut().flush(); } catch (IOException e) { e.printStackTrace(); } } public void enableStdIn() { this.parent.enableStdIn(); } public String getCurrentPath() { return currentPath; // return parent.getCurrentPath(); } public String getParentCurrentPath() { // return currentPath; return parent.getCurrentPath(); } public void setParentCurrentPath(String currentPath) { parent.setCurrentPath(currentPath); } public void setCurrentPath(String currentPath) { this.currentPath = currentPath; } public Kernel getServices() { return services; } }