Improve compatibility with lua 5.2.
This commit is contained in:
@@ -23,9 +23,19 @@ package org.luaj.vm2.lib;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import org.luaj.vm2.Globals;
|
||||
import org.luaj.vm2.LuaTable;
|
||||
import org.luaj.vm2.LuaValue;
|
||||
import org.luaj.vm2.Varargs;
|
||||
import org.luaj.vm2.lib.PackageLib.java_searcher;
|
||||
import org.luaj.vm2.lib.PackageLib.loadlib;
|
||||
import org.luaj.vm2.lib.PackageLib.lua_searcher;
|
||||
import org.luaj.vm2.lib.PackageLib.preload_searcher;
|
||||
import org.luaj.vm2.lib.PackageLib.require;
|
||||
import org.luaj.vm2.lib.PackageLib.searchpath;
|
||||
import org.luaj.vm2.lib.jme.JmePlatform;
|
||||
import org.luaj.vm2.lib.jse.JseOsLib;
|
||||
import org.luaj.vm2.lib.jse.JsePlatform;
|
||||
|
||||
/**
|
||||
* Subclass of {@link LibFunction} which implements the standard lua {@code os} library.
|
||||
@@ -72,22 +82,21 @@ import org.luaj.vm2.Varargs;
|
||||
* @see JmePlatform
|
||||
* @see <a href="http://www.lua.org/manual/5.1/manual.html#5.8">http://www.lua.org/manual/5.1/manual.html#5.8</a>
|
||||
*/
|
||||
public class OsLib extends VarArgFunction {
|
||||
public class OsLib extends OneArgFunction {
|
||||
public static String TMP_PREFIX = ".luaj";
|
||||
public static String TMP_SUFFIX = "tmp";
|
||||
|
||||
private static final int INIT = 0;
|
||||
private static final int CLOCK = 1;
|
||||
private static final int DATE = 2;
|
||||
private static final int DIFFTIME = 3;
|
||||
private static final int EXECUTE = 4;
|
||||
private static final int EXIT = 5;
|
||||
private static final int GETENV = 6;
|
||||
private static final int REMOVE = 7;
|
||||
private static final int RENAME = 8;
|
||||
private static final int SETLOCALE = 9;
|
||||
private static final int TIME = 10;
|
||||
private static final int TMPNAME = 11;
|
||||
private static final int CLOCK = 0;
|
||||
private static final int DATE = 1;
|
||||
private static final int DIFFTIME = 2;
|
||||
private static final int EXECUTE = 3;
|
||||
private static final int EXIT = 4;
|
||||
private static final int GETENV = 5;
|
||||
private static final int REMOVE = 6;
|
||||
private static final int RENAME = 7;
|
||||
private static final int SETLOCALE = 8;
|
||||
private static final int TIME = 9;
|
||||
private static final int TMPNAME = 10;
|
||||
|
||||
private static final String[] NAMES = {
|
||||
"clock",
|
||||
@@ -106,61 +115,69 @@ public class OsLib extends VarArgFunction {
|
||||
private static final long t0 = System.currentTimeMillis();
|
||||
private static long tmpnames = t0;
|
||||
|
||||
protected Globals globals;
|
||||
|
||||
/**
|
||||
* Create and OsLib instance.
|
||||
*/
|
||||
public OsLib() {
|
||||
}
|
||||
|
||||
public LuaValue init(LuaValue env) {
|
||||
LuaTable t = new LuaTable();
|
||||
bind(t, this.getClass(), NAMES, CLOCK);
|
||||
env.set("os", t);
|
||||
env.get("package").get("loaded").set("os", t);
|
||||
return t;
|
||||
|
||||
public LuaValue call(LuaValue env) {
|
||||
globals = env.checkglobals();
|
||||
LuaTable os = new LuaTable();
|
||||
for (int i = 0; i < NAMES.length; ++i)
|
||||
os.set(NAMES[i], new OsLibFunc(i, NAMES[i]));
|
||||
env.set("os", os);
|
||||
globals.package_.loaded.set("os", os);
|
||||
return os;
|
||||
}
|
||||
|
||||
public Varargs invoke(Varargs args) {
|
||||
try {
|
||||
switch ( opcode ) {
|
||||
case INIT:
|
||||
return init(args.arg1());
|
||||
case CLOCK:
|
||||
return valueOf(clock());
|
||||
case DATE: {
|
||||
String s = args.optjstring(1, null);
|
||||
double t = args.optdouble(2,-1);
|
||||
return valueOf( date(s, t==-1? System.currentTimeMillis()/1000.: t) );
|
||||
}
|
||||
case DIFFTIME:
|
||||
return valueOf(difftime(args.checkdouble(1),args.checkdouble(2)));
|
||||
case EXECUTE:
|
||||
return valueOf(execute(args.optjstring(1, null)));
|
||||
case EXIT:
|
||||
exit(args.optint(1, 0));
|
||||
class OsLibFunc extends VarArgFunction {
|
||||
public OsLibFunc(int opcode, String name) {
|
||||
this.opcode = opcode;
|
||||
this.name = name;
|
||||
}
|
||||
public Varargs invoke(Varargs args) {
|
||||
try {
|
||||
switch ( opcode ) {
|
||||
case CLOCK:
|
||||
return valueOf(clock());
|
||||
case DATE: {
|
||||
String s = args.optjstring(1, null);
|
||||
double t = args.optdouble(2,-1);
|
||||
return valueOf( date(s, t==-1? System.currentTimeMillis()/1000.: t) );
|
||||
}
|
||||
case DIFFTIME:
|
||||
return valueOf(difftime(args.checkdouble(1),args.checkdouble(2)));
|
||||
case EXECUTE:
|
||||
return execute(args.optjstring(1, null));
|
||||
case EXIT:
|
||||
exit(args.optint(1, 0));
|
||||
return NONE;
|
||||
case GETENV: {
|
||||
final String val = getenv(args.checkjstring(1));
|
||||
return val!=null? valueOf(val): NIL;
|
||||
}
|
||||
case REMOVE:
|
||||
remove(args.checkjstring(1));
|
||||
return LuaValue.TRUE;
|
||||
case RENAME:
|
||||
rename(args.checkjstring(1), args.checkjstring(2));
|
||||
return LuaValue.TRUE;
|
||||
case SETLOCALE: {
|
||||
String s = setlocale(args.optjstring(1,null), args.optjstring(2, "all"));
|
||||
return s!=null? valueOf(s): NIL;
|
||||
}
|
||||
case TIME:
|
||||
return valueOf(time(args.arg1().isnil()? null: args.checktable(1)));
|
||||
case TMPNAME:
|
||||
return valueOf(tmpname());
|
||||
}
|
||||
return NONE;
|
||||
case GETENV: {
|
||||
final String val = getenv(args.checkjstring(1));
|
||||
return val!=null? valueOf(val): NIL;
|
||||
} catch ( IOException e ) {
|
||||
return varargsOf(NIL, valueOf(e.getMessage()));
|
||||
}
|
||||
case REMOVE:
|
||||
remove(args.checkjstring(1));
|
||||
return LuaValue.TRUE;
|
||||
case RENAME:
|
||||
rename(args.checkjstring(1), args.checkjstring(2));
|
||||
return LuaValue.TRUE;
|
||||
case SETLOCALE: {
|
||||
String s = setlocale(args.optjstring(1,null), args.optjstring(2, "all"));
|
||||
return s!=null? valueOf(s): NIL;
|
||||
}
|
||||
case TIME:
|
||||
return valueOf(time(args.arg1().isnil()? null: args.checktable(1)));
|
||||
case TMPNAME:
|
||||
return valueOf(tmpname());
|
||||
}
|
||||
return NONE;
|
||||
} catch ( IOException e ) {
|
||||
return varargsOf(NIL, valueOf(e.getMessage()));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -219,8 +236,8 @@ public class OsLib extends VarArgFunction {
|
||||
* is available and zero otherwise.
|
||||
* @param command command to pass to the system
|
||||
*/
|
||||
protected int execute(String command) {
|
||||
return 0;
|
||||
protected Varargs execute(String command) {
|
||||
return varargsOf(NIL, valueOf("exit"), ONE);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -24,6 +24,7 @@ import java.io.File;
|
||||
import java.io.IOException;
|
||||
|
||||
import org.luaj.vm2.LuaValue;
|
||||
import org.luaj.vm2.Varargs;
|
||||
import org.luaj.vm2.lib.LibFunction;
|
||||
|
||||
/**
|
||||
@@ -79,23 +80,20 @@ public class JseOsLib extends org.luaj.vm2.lib.OsLib {
|
||||
public JseOsLib() {
|
||||
}
|
||||
|
||||
protected int execute(String command) {
|
||||
Runtime r = Runtime.getRuntime();
|
||||
protected Varargs execute(String command) {
|
||||
int exitValue;
|
||||
try {
|
||||
final Process p = r.exec(command);
|
||||
try {
|
||||
p.waitFor();
|
||||
return p.exitValue();
|
||||
} finally {
|
||||
p.destroy();
|
||||
}
|
||||
exitValue = new JseProcess(command, null, globals.STDOUT, globals.STDERR).waitFor();
|
||||
} catch (IOException ioe) {
|
||||
return EXEC_IOEXCEPTION;
|
||||
exitValue = EXEC_IOEXCEPTION;
|
||||
} catch (InterruptedException e) {
|
||||
return EXEC_INTERRUPTED;
|
||||
exitValue = EXEC_INTERRUPTED;
|
||||
} catch (Throwable t) {
|
||||
return EXEC_ERROR;
|
||||
}
|
||||
exitValue = EXEC_ERROR;
|
||||
}
|
||||
if (exitValue == 0)
|
||||
return varargsOf(TRUE, valueOf("exit"), ZERO);
|
||||
return varargsOf(NIL, valueOf("signal"), valueOf(exitValue));
|
||||
}
|
||||
|
||||
protected void remove(String filename) throws IOException {
|
||||
|
||||
116
src/jse/org/luaj/vm2/lib/jse/JseProcess.java
Normal file
116
src/jse/org/luaj/vm2/lib/jse/JseProcess.java
Normal file
@@ -0,0 +1,116 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2012 Luaj.org. All rights reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
******************************************************************************/
|
||||
package org.luaj.vm2.lib.jse;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
|
||||
/** Analog of Process that pipes input and output to client-specified streams.
|
||||
*/
|
||||
public class JseProcess {
|
||||
|
||||
final Process process;
|
||||
final Thread input,output,error;
|
||||
|
||||
/** Construct a process around a command, with specified streams to redirect input and output to.
|
||||
*
|
||||
* @param cmd The command to execute, including arguments, if any
|
||||
* @param stdin Optional InputStream to read from as process input, or null if input is not needed.
|
||||
* @param stdout Optional OutputStream to copy process output to, or null if output is ignored.
|
||||
* @param stderr Optinoal OutputStream to copy process stderr output to, or null if output is ignored.
|
||||
* @throws IOException If the system process could not be created.
|
||||
* @see Process
|
||||
*/
|
||||
public JseProcess(String[] cmd, InputStream stdin, OutputStream stdout, OutputStream stderr) throws IOException {
|
||||
this(Runtime.getRuntime().exec(cmd), stdin, stdout, stderr);
|
||||
}
|
||||
|
||||
/** Construct a process around a command, with specified streams to redirect input and output to.
|
||||
*
|
||||
* @param cmd The command to execute, including arguments, if any
|
||||
* @param stdin Optional InputStream to read from as process input, or null if input is not needed.
|
||||
* @param stdout Optional OutputStream to copy process output to, or null if output is ignored.
|
||||
* @param stderr Optinoal OutputStream to copy process stderr output to, or null if output is ignored.
|
||||
* @throws IOException If the system process could not be created.
|
||||
* @see Process
|
||||
*/
|
||||
public JseProcess(String cmd, InputStream stdin, OutputStream stdout, OutputStream stderr) throws IOException {
|
||||
this(Runtime.getRuntime().exec(cmd), stdin, stdout, stderr);
|
||||
}
|
||||
|
||||
private JseProcess(Process process, InputStream stdin, OutputStream stdout, OutputStream stderr) {
|
||||
this.process = process;
|
||||
input = stdin == null? null: copyBytes(stdin, process.getOutputStream(), null, process.getOutputStream());
|
||||
output = stdout == null? null: copyBytes(process.getInputStream(), stdout, process.getInputStream(), null);
|
||||
error = stderr == null? null: copyBytes(process.getErrorStream(), stderr, process.getErrorStream(), null);
|
||||
}
|
||||
|
||||
/** Get the exit value of the process. */
|
||||
public int exitValue() {
|
||||
return process.exitValue();
|
||||
}
|
||||
|
||||
/** Wait for the process to complete, and all pending output to finish.
|
||||
* @return The exit status.
|
||||
* @throws InterruptedException
|
||||
*/
|
||||
public int waitFor() throws InterruptedException {
|
||||
int r = process.waitFor();
|
||||
if (input != null)
|
||||
input.join();
|
||||
if (output != null)
|
||||
output.join();
|
||||
if (error != null)
|
||||
error.join();
|
||||
process.destroy();
|
||||
return r;
|
||||
}
|
||||
|
||||
/** Create a thread to copy bytes from input to output. */
|
||||
private Thread copyBytes(final InputStream input,
|
||||
final OutputStream output, final InputStream ownedInput,
|
||||
final OutputStream ownedOutput) {
|
||||
Thread t = (new Thread() {
|
||||
public void run() {
|
||||
try {
|
||||
byte[] buf = new byte[1024];
|
||||
int r;
|
||||
try {
|
||||
while ((r = input.read(buf)) >= 0) {
|
||||
output.write(buf, 0, r);
|
||||
}
|
||||
} finally {
|
||||
if (ownedInput != null)
|
||||
ownedInput.close();
|
||||
if (ownedOutput != null)
|
||||
ownedOutput.close();
|
||||
}
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
});
|
||||
t.start();
|
||||
return t;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user