blob: 48ab62ed3169936f1564983cf444d0443bc62300 (
plain) (
tree)
|
|
/**
* Simple way to execute external commands through javascript
*
* @example
cmd = exec("cat");
System.out.println("First: " +cmd.write("this is a loop.").read(Process.READ_AVAILABLE)); // prints "this is a loop."
System.out.println("Second: " +cmd.writeAndClose(" hi there").result()); // prints "this is a loop. hi there"
*
*/
jimport("java.lang.Runtime");
jimport("java.io.BufferedInputStream");
jimport("java.io.BufferedOutputStream");
jimport("java.lang.System");
/* returns a process */
function exec(process) {
return new Process(process);
};
function Process(cmd) {
this.cmd = cmd;
this.proc = Runtime.getRuntime().exec(cmd);
this.resultText = "";
this.inputStream = new BufferedInputStream(this.proc.getInputStream());
this.errorStream = new BufferedInputStream(this.proc.getErrorStream());
this.outputStream = new BufferedOutputStream(this.proc.getOutputStream());
}
Process.CHUNK_SIZE = 1024;
Process.READ_ALL = -1;
Process.READ_AVAILABLE = -2;
Process.prototype.write = function(stdinText) {
this.outputStream.write(new java.lang.String(stdinText).getBytes());
this.outputStream.flush();
return this;
};
Process.prototype.writeAndClose = function(stdinText) {
this.write(stdinText);
this.outputStream.close();
return this;
};
/* Python file-like behavior: read specified number of bytes, else until EOF*/
Process.prototype.read = function(nbytesToRead, stream) {
var inputStream = stream || this.inputStream;
var availBytes = inputStream.available();
if (!availBytes) return null;
var result = "";
var nbytes = nbytesToRead || Process.READ_ALL;
var readAll = (nbytes == Process.READ_ALL);
var readAvailable = (nbytes == Process.READ_AVAILABLE);
while (nbytes > 0 || readAll || readAvailable) {
var chunkSize = readAll ? Process.CHUNK_SIZE :
readAvailable ? Process.CHUNK_SIZE : nbytes;
// allocate a java byte array
var bytes = java.lang.reflect.Array.newInstance(java.lang.Byte.TYPE, chunkSize);
var len = inputStream.read(bytes, 0, chunkSize);
// at end of stream, or when we run out of data, stop reading in chunks.
if (len == -1) break;
if (nbytes > 0) nbytes -= len;
result += new java.lang.String(bytes);
if (readAvailable && inputStream.available() == 0) break;
}
this.resultText += new String(result);
return new String(result);
};
Process.prototype.result = function() {
this.outputStream.close();
this.proc.waitFor();
this.read(Process.READ_ALL, this.inputStream);
return new String(this.resultText);
};
Process.prototype.resultOrError = function() {
this.proc.waitFor();
this.read(Process.READ_ALL, this.inputStream);
var result = this.resultText;
if(!result || result == "") result = this.read(Process.READ_ALL, this.errorStream);
return result || "";
};
|