8080490: add $EXECV command to Nashorn scripting mode
Additional arguments to the command line can be passed as a single array, or as a sequence of varargs. Reviewed-by: attila, hannesw
This commit is contained in:
parent
f5e449156c
commit
0f1bfba6c9
48
nashorn/samples/exec.js
Normal file
48
nashorn/samples/exec.js
Normal file
@ -0,0 +1,48 @@
|
||||
# exec script requires -scripting mode
|
||||
|
||||
/*
|
||||
* Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* - Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* - Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* - Neither the name of Oracle nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
|
||||
* IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
|
||||
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
// The $EXEC builtin function can be used to run external commands:
|
||||
$EXEC("ls")
|
||||
$EXEC("ls -la")
|
||||
|
||||
// It can also be given a string to use as stdin:
|
||||
$EXEC("cat", "Hello, world!")
|
||||
|
||||
// Additional arguments can be passed after the stdin argument, as an array of
|
||||
// strings, or a sequence of varargs:
|
||||
$EXEC("ls", "" /* no stdin */, "-l", "-a")
|
||||
$EXEC("ls", "" /* no stdin */, ["-l", "-a"])
|
||||
|
||||
// Output of running external commands is returned from $EXEC:
|
||||
print($EXEC("ls"))
|
||||
|
@ -2580,15 +2580,18 @@ public abstract class ScriptObject implements PropertyAccess, Cloneable {
|
||||
|
||||
final int parameterCount = methodType.parameterCount();
|
||||
final int callCount = callType.parameterCount();
|
||||
final int pdiff = callCount - parameterCount + 1;
|
||||
|
||||
final boolean isCalleeVarArg = parameterCount > 0 && methodType.parameterType(parameterCount - 1).isArray();
|
||||
final boolean isCallerVarArg = callerVarArg != null ? callerVarArg.booleanValue() : callCount > 0 &&
|
||||
final boolean isCallerVarArg = callerVarArg != null ? callerVarArg : callCount > 0 &&
|
||||
callType.parameterType(callCount - 1).isArray();
|
||||
|
||||
if (isCalleeVarArg) {
|
||||
// A value of pdiff < 0 means that there are additional normal arguments in the callee that must not be consumed
|
||||
// by the vararg collector. No vararg collector is required in that case, and no varargs are passed.
|
||||
if (isCalleeVarArg && pdiff >= 0) {
|
||||
return isCallerVarArg ?
|
||||
methodHandle :
|
||||
MH.asCollector(methodHandle, Object[].class, callCount - parameterCount + 1);
|
||||
MH.asCollector(methodHandle, Object[].class, pdiff);
|
||||
}
|
||||
|
||||
if (isCallerVarArg) {
|
||||
|
@ -41,6 +41,7 @@ import java.lang.invoke.MethodHandles;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import jdk.nashorn.internal.objects.NativeArray;
|
||||
|
||||
/**
|
||||
* Global functions supported only in scripting mode.
|
||||
@ -54,7 +55,7 @@ public final class ScriptingFunctions {
|
||||
public static final MethodHandle READFULLY = findOwnMH("readFully", Object.class, Object.class, Object.class);
|
||||
|
||||
/** Handle to implementation of {@link ScriptingFunctions#exec} - Nashorn extension */
|
||||
public static final MethodHandle EXEC = findOwnMH("exec", Object.class, Object.class, Object.class, Object.class);
|
||||
public static final MethodHandle EXEC = findOwnMH("exec", Object.class, Object.class, Object.class, Object.class, Object[].class);
|
||||
|
||||
/** EXEC name - special property used by $EXEC API. */
|
||||
public static final String EXEC_NAME = "$EXEC";
|
||||
@ -128,17 +129,30 @@ public final class ScriptingFunctions {
|
||||
* @param self self reference
|
||||
* @param string string to execute
|
||||
* @param input input
|
||||
* @param argv additional arguments, to be appended to {@code string}. Additional arguments can be passed as
|
||||
* either one JavaScript array, whose elements will be converted to strings; or as a sequence of
|
||||
* varargs, each of which will be converted to a string.
|
||||
*
|
||||
* @return output string from the request
|
||||
*
|
||||
* @throws IOException if any stream access fails
|
||||
* @throws InterruptedException if execution is interrupted
|
||||
*/
|
||||
public static Object exec(final Object self, final Object string, final Object input) throws IOException, InterruptedException {
|
||||
public static Object exec(final Object self, final Object string, final Object input, final Object... argv) throws IOException, InterruptedException {
|
||||
// Current global is need to fetch additional inputs and for additional results.
|
||||
final ScriptObject global = Context.getGlobal();
|
||||
|
||||
// Assemble command line, process additional arguments.
|
||||
final List<String> cmdLine = tokenizeString(JSType.toString(string));
|
||||
final Object[] additionalArgs = argv.length == 1 && argv[0] instanceof NativeArray ?
|
||||
((NativeArray) argv[0]).asObjectArray() :
|
||||
argv;
|
||||
for (Object arg : additionalArgs) {
|
||||
cmdLine.add(JSType.toString(arg));
|
||||
}
|
||||
|
||||
// Set up initial process.
|
||||
final ProcessBuilder processBuilder = new ProcessBuilder(tokenizeString(JSType.toString(string)));
|
||||
final ProcessBuilder processBuilder = new ProcessBuilder(cmdLine);
|
||||
|
||||
// Current ENV property state.
|
||||
final Object env = global.get(ENV_NAME);
|
||||
|
Loading…
Reference in New Issue
Block a user