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 java.io.IOException;
|
||||||
|
|
||||||
|
import org.luaj.vm2.Globals;
|
||||||
import org.luaj.vm2.LuaTable;
|
import org.luaj.vm2.LuaTable;
|
||||||
import org.luaj.vm2.LuaValue;
|
import org.luaj.vm2.LuaValue;
|
||||||
import org.luaj.vm2.Varargs;
|
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.
|
* Subclass of {@link LibFunction} which implements the standard lua {@code os} library.
|
||||||
@@ -72,22 +82,21 @@ import org.luaj.vm2.Varargs;
|
|||||||
* @see JmePlatform
|
* @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>
|
* @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_PREFIX = ".luaj";
|
||||||
public static String TMP_SUFFIX = "tmp";
|
public static String TMP_SUFFIX = "tmp";
|
||||||
|
|
||||||
private static final int INIT = 0;
|
private static final int CLOCK = 0;
|
||||||
private static final int CLOCK = 1;
|
private static final int DATE = 1;
|
||||||
private static final int DATE = 2;
|
private static final int DIFFTIME = 2;
|
||||||
private static final int DIFFTIME = 3;
|
private static final int EXECUTE = 3;
|
||||||
private static final int EXECUTE = 4;
|
private static final int EXIT = 4;
|
||||||
private static final int EXIT = 5;
|
private static final int GETENV = 5;
|
||||||
private static final int GETENV = 6;
|
private static final int REMOVE = 6;
|
||||||
private static final int REMOVE = 7;
|
private static final int RENAME = 7;
|
||||||
private static final int RENAME = 8;
|
private static final int SETLOCALE = 8;
|
||||||
private static final int SETLOCALE = 9;
|
private static final int TIME = 9;
|
||||||
private static final int TIME = 10;
|
private static final int TMPNAME = 10;
|
||||||
private static final int TMPNAME = 11;
|
|
||||||
|
|
||||||
private static final String[] NAMES = {
|
private static final String[] NAMES = {
|
||||||
"clock",
|
"clock",
|
||||||
@@ -106,25 +115,32 @@ public class OsLib extends VarArgFunction {
|
|||||||
private static final long t0 = System.currentTimeMillis();
|
private static final long t0 = System.currentTimeMillis();
|
||||||
private static long tmpnames = t0;
|
private static long tmpnames = t0;
|
||||||
|
|
||||||
|
protected Globals globals;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create and OsLib instance.
|
* Create and OsLib instance.
|
||||||
*/
|
*/
|
||||||
public OsLib() {
|
public OsLib() {
|
||||||
}
|
}
|
||||||
|
|
||||||
public LuaValue init(LuaValue env) {
|
public LuaValue call(LuaValue env) {
|
||||||
LuaTable t = new LuaTable();
|
globals = env.checkglobals();
|
||||||
bind(t, this.getClass(), NAMES, CLOCK);
|
LuaTable os = new LuaTable();
|
||||||
env.set("os", t);
|
for (int i = 0; i < NAMES.length; ++i)
|
||||||
env.get("package").get("loaded").set("os", t);
|
os.set(NAMES[i], new OsLibFunc(i, NAMES[i]));
|
||||||
return t;
|
env.set("os", os);
|
||||||
|
globals.package_.loaded.set("os", os);
|
||||||
|
return os;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class OsLibFunc extends VarArgFunction {
|
||||||
|
public OsLibFunc(int opcode, String name) {
|
||||||
|
this.opcode = opcode;
|
||||||
|
this.name = name;
|
||||||
|
}
|
||||||
public Varargs invoke(Varargs args) {
|
public Varargs invoke(Varargs args) {
|
||||||
try {
|
try {
|
||||||
switch ( opcode ) {
|
switch ( opcode ) {
|
||||||
case INIT:
|
|
||||||
return init(args.arg1());
|
|
||||||
case CLOCK:
|
case CLOCK:
|
||||||
return valueOf(clock());
|
return valueOf(clock());
|
||||||
case DATE: {
|
case DATE: {
|
||||||
@@ -135,7 +151,7 @@ public class OsLib extends VarArgFunction {
|
|||||||
case DIFFTIME:
|
case DIFFTIME:
|
||||||
return valueOf(difftime(args.checkdouble(1),args.checkdouble(2)));
|
return valueOf(difftime(args.checkdouble(1),args.checkdouble(2)));
|
||||||
case EXECUTE:
|
case EXECUTE:
|
||||||
return valueOf(execute(args.optjstring(1, null)));
|
return execute(args.optjstring(1, null));
|
||||||
case EXIT:
|
case EXIT:
|
||||||
exit(args.optint(1, 0));
|
exit(args.optint(1, 0));
|
||||||
return NONE;
|
return NONE;
|
||||||
@@ -163,6 +179,7 @@ public class OsLib extends VarArgFunction {
|
|||||||
return varargsOf(NIL, valueOf(e.getMessage()));
|
return varargsOf(NIL, valueOf(e.getMessage()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return an approximation of the amount in seconds of CPU time used by
|
* @return an approximation of the amount in seconds of CPU time used by
|
||||||
@@ -219,8 +236,8 @@ public class OsLib extends VarArgFunction {
|
|||||||
* is available and zero otherwise.
|
* is available and zero otherwise.
|
||||||
* @param command command to pass to the system
|
* @param command command to pass to the system
|
||||||
*/
|
*/
|
||||||
protected int execute(String command) {
|
protected Varargs execute(String command) {
|
||||||
return 0;
|
return varargsOf(NIL, valueOf("exit"), ONE);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -24,6 +24,7 @@ import java.io.File;
|
|||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
|
||||||
import org.luaj.vm2.LuaValue;
|
import org.luaj.vm2.LuaValue;
|
||||||
|
import org.luaj.vm2.Varargs;
|
||||||
import org.luaj.vm2.lib.LibFunction;
|
import org.luaj.vm2.lib.LibFunction;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -79,23 +80,20 @@ public class JseOsLib extends org.luaj.vm2.lib.OsLib {
|
|||||||
public JseOsLib() {
|
public JseOsLib() {
|
||||||
}
|
}
|
||||||
|
|
||||||
protected int execute(String command) {
|
protected Varargs execute(String command) {
|
||||||
Runtime r = Runtime.getRuntime();
|
int exitValue;
|
||||||
try {
|
try {
|
||||||
final Process p = r.exec(command);
|
exitValue = new JseProcess(command, null, globals.STDOUT, globals.STDERR).waitFor();
|
||||||
try {
|
|
||||||
p.waitFor();
|
|
||||||
return p.exitValue();
|
|
||||||
} finally {
|
|
||||||
p.destroy();
|
|
||||||
}
|
|
||||||
} catch (IOException ioe) {
|
} catch (IOException ioe) {
|
||||||
return EXEC_IOEXCEPTION;
|
exitValue = EXEC_IOEXCEPTION;
|
||||||
} catch (InterruptedException e) {
|
} catch (InterruptedException e) {
|
||||||
return EXEC_INTERRUPTED;
|
exitValue = EXEC_INTERRUPTED;
|
||||||
} catch (Throwable t) {
|
} 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 {
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -34,8 +34,8 @@ import java.net.URL;
|
|||||||
|
|
||||||
import junit.framework.TestCase;
|
import junit.framework.TestCase;
|
||||||
|
|
||||||
import org.luaj.vm2.lib.BaseLib;
|
|
||||||
import org.luaj.vm2.lib.ResourceFinder;
|
import org.luaj.vm2.lib.ResourceFinder;
|
||||||
|
import org.luaj.vm2.lib.jse.JseProcess;
|
||||||
import org.luaj.vm2.luajc.LuaJC;
|
import org.luaj.vm2.luajc.LuaJC;
|
||||||
|
|
||||||
abstract
|
abstract
|
||||||
@@ -235,69 +235,8 @@ public class ScriptDrivenTest extends TestCase implements ResourceFinder {
|
|||||||
throws IOException, InterruptedException {
|
throws IOException, InterruptedException {
|
||||||
Runtime r = Runtime.getRuntime();
|
Runtime r = Runtime.getRuntime();
|
||||||
final ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
final ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
||||||
final Process p = r.exec(cmd);
|
new JseProcess(cmd, input, baos, System.err).waitFor();
|
||||||
try {
|
|
||||||
// start a thread to write the given input to the subprocess.
|
|
||||||
Thread inputCopier = (new Thread() {
|
|
||||||
public void run() {
|
|
||||||
try {
|
|
||||||
OutputStream processStdIn = p.getOutputStream();
|
|
||||||
try {
|
|
||||||
copy(input, processStdIn);
|
|
||||||
} finally {
|
|
||||||
processStdIn.close();
|
|
||||||
}
|
|
||||||
} catch (IOException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
inputCopier.start();
|
|
||||||
|
|
||||||
// start another thread to read output from the subprocess.
|
|
||||||
Thread outputCopier = (new Thread() {
|
|
||||||
public void run() {
|
|
||||||
try {
|
|
||||||
InputStream processStdOut = p.getInputStream();
|
|
||||||
try {
|
|
||||||
copy(processStdOut, baos);
|
|
||||||
} finally {
|
|
||||||
processStdOut.close();
|
|
||||||
}
|
|
||||||
} catch (IOException ioe) {
|
|
||||||
ioe.printStackTrace();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
outputCopier.start();
|
|
||||||
|
|
||||||
// start another thread to read output from the subprocess.
|
|
||||||
Thread errorCopier = (new Thread() {
|
|
||||||
public void run() {
|
|
||||||
try {
|
|
||||||
InputStream processError = p.getErrorStream();
|
|
||||||
try {
|
|
||||||
copy(processError, System.err);
|
|
||||||
} finally {
|
|
||||||
processError.close();
|
|
||||||
}
|
|
||||||
} catch (IOException ioe) {
|
|
||||||
ioe.printStackTrace();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
errorCopier.start();
|
|
||||||
|
|
||||||
p.waitFor();
|
|
||||||
inputCopier.join();
|
|
||||||
outputCopier.join();
|
|
||||||
errorCopier.join();
|
|
||||||
|
|
||||||
return new String(baos.toByteArray());
|
return new String(baos.toByteArray());
|
||||||
|
|
||||||
} finally {
|
|
||||||
p.destroy();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private String readString(InputStream is) throws IOException {
|
private String readString(InputStream is) throws IOException {
|
||||||
|
|||||||
@@ -8,13 +8,12 @@
|
|||||||
--
|
--
|
||||||
local pcall = function(...)
|
local pcall = function(...)
|
||||||
local s,e,f = pcall(...)
|
local s,e,f = pcall(...)
|
||||||
return s,type(e)
|
return s,type(e),type(f)
|
||||||
end
|
end
|
||||||
print( 'os', type(os) )
|
print( 'os', type(os) )
|
||||||
print( 'os.clock()', pcall( os.clock ) )
|
print( 'os.clock()', pcall( os.clock ) )
|
||||||
print( 'os.date()', pcall( os.date ) )
|
print( 'os.date()', pcall( os.date ) )
|
||||||
print( 'os.difftime(123000, 21500)', pcall( os.difftime, 123000, 21250 ) )
|
print( 'os.difftime(123000, 21500)', pcall( os.difftime, 123000, 21250 ) )
|
||||||
print( 'os.execute("bogus")', pcall( os.execute, '' ) )
|
|
||||||
print( 'os.getenv()', pcall( os.getenv ) )
|
print( 'os.getenv()', pcall( os.getenv ) )
|
||||||
print( 'os.getenv("bogus.key")', pcall( os.getenv, 'bogus.key' ) )
|
print( 'os.getenv("bogus.key")', pcall( os.getenv, 'bogus.key' ) )
|
||||||
local s,p = pcall( os.tmpname )
|
local s,p = pcall( os.tmpname )
|
||||||
|
|||||||
Reference in New Issue
Block a user