ソースを参照

Merge branch 'raw_cmd' into development

Andy Li 9 年 前
コミット
4ebb5b022c

+ 2 - 1
interp.ml

@@ -1862,7 +1862,8 @@ let std_lib =
 	(* process *)
 		"process_run", (Fun2 (fun p args ->
 			match p, args with
-			| VString p, VArray args -> VAbstract (AProcess (Process.run p (Array.map vstring args)))
+			| VString p, VArray args -> VAbstract (AProcess (Process.run p (Some (Array.map vstring args))))
+			| VString p, _ -> VAbstract (AProcess (Process.run p None))
 			| _ -> error()
 		));
 		"process_stdout_read", (Fun4 (fun p str pos len ->

+ 1 - 1
libs

@@ -1 +1 @@
-Subproject commit 803a97c581d8cce4649d62204498b84a758ca2c6
+Subproject commit 4c2fbca91d9cc2357dc5897bda7ddfb252c1a0ba

+ 1 - 1
std/cpp/_std/sys/io/Process.hx

@@ -97,7 +97,7 @@ class Process {
 	public var stderr(default,null) : haxe.io.Input;
 	public var stdin(default,null) : haxe.io.Output;
 
-	public function new( cmd : String, args : Array<String> ) : Void {
+	public function new( cmd : String, ?args : Array<String> ) : Void {
 		p = try _run(cmd,args) catch( e : Dynamic ) throw "Process creation failure : "+cmd;
 		stdin = new Stdin(p);
 		stdout = new Stdout(p,true);

+ 1 - 1
std/cs/_std/Sys.hx

@@ -115,7 +115,7 @@ class Sys {
 
 	public static function command( cmd : String, ?args : Array<String> ) : Int
 	{
-		var proc:Process = new Process(cmd, args == null ? [] : args);
+		var proc:Process = new Process(cmd, args);
 		var ret = proc.exitCode();
 		proc.close();
 

+ 22 - 7
std/cs/_std/sys/io/Process.hx

@@ -36,17 +36,32 @@ class Process {
 	private var native:NativeProcess;
 
 
-	public function new( cmd : String, args : Array<String> ) : Void
+	public function new( cmd : String, ?args : Array<String> ) : Void
 	{
 		this.native = new NativeProcess();
-		// mono 4.2.1 on Windows doesn't support relative path correctly
-		if (cmd.indexOf("/") != -1 || cmd.indexOf("\\") != -1)
-			cmd = sys.FileSystem.fullPath(cmd);
-		native.StartInfo.FileName = cmd;
 		native.StartInfo.CreateNoWindow = true;
-		native.StartInfo.Arguments = buildArgumentsString(args);
 		native.StartInfo.RedirectStandardError = native.StartInfo.RedirectStandardInput = native.StartInfo.RedirectStandardOutput = true;
-		native.StartInfo.UseShellExecute = false;
+		if (args != null) {
+			// mono 4.2.1 on Windows doesn't support relative path correctly
+			if (cmd.indexOf("/") != -1 || cmd.indexOf("\\") != -1)
+				cmd = sys.FileSystem.fullPath(cmd);
+			native.StartInfo.FileName = cmd;
+			native.StartInfo.UseShellExecute = false;
+			native.StartInfo.Arguments = buildArgumentsString(args);
+		} else {
+			switch (Sys.systemName()) {
+				case "Windows":
+					native.StartInfo.FileName = switch (Sys.getEnv("COMSPEC")) {
+						case null: "cmd.exe";
+						case comspec: comspec;
+					}
+					native.StartInfo.Arguments = '/C "$cmd"';
+				case _:
+					native.StartInfo.FileName = "/bin/sh";
+					native.StartInfo.Arguments = buildArgumentsString(["-c", cmd]);
+			}
+			native.StartInfo.UseShellExecute = false;
+		}
 
 		native.Start();
 

+ 1 - 1
std/java/_std/Sys.hx

@@ -112,7 +112,7 @@ using haxe.Int64;
 
 	public static function command( cmd : String, ?args : Array<String> ) : Int
 	{
-		var proc:Process = new Process(cmd, args == null ? [] : args);
+		var proc:Process = new Process(cmd, args);
 		var ret = proc.exitCode();
 		proc.close();
 

+ 35 - 15
std/java/_std/sys/io/Process.hx

@@ -36,22 +36,42 @@ class Process {
 
 	private var proc:java.lang.Process;
 
-	public function new( cmd : String, args : Array<String> ) : Void
+	public function new( cmd : String, ?args : Array<String> ) : Void
 	{
-		var pargs = new NativeArray(args.length + 1);
-		switch (Sys.systemName()) {
-			case "Windows":
-				pargs[0] = StringTools.quoteWinArg(cmd, false);
-				for (i in 0...args.length)
-				{
-					pargs[i + 1] = StringTools.quoteWinArg(args[i], false);
-				}
-			case _:
-				pargs[0] = cmd;
-				for (i in 0...args.length)
-				{
-					pargs[i + 1] = args[i];
-				}
+		var sysName = Sys.systemName();
+		var pargs;
+		if (args == null) {
+			var cmdStr = cmd;
+			switch (sysName) {
+				case "Windows":
+					pargs = new NativeArray(2);
+					pargs[0] = cmd = switch (Sys.getEnv("COMSPEC")) {
+						case null: "cmd.exe";
+						case comspec: comspec;
+					}
+					pargs[1] = '/C "$cmdStr"';
+				case _:
+					pargs = new NativeArray(3);
+					pargs[0] = cmd = "/bin/sh";
+					pargs[1] = "-c";
+					pargs[2] = cmdStr;
+			}
+		} else {
+			pargs = new NativeArray(args.length + 1);
+			switch (sysName) {
+				case "Windows":
+					pargs[0] = StringTools.quoteWinArg(cmd, false);
+					for (i in 0...args.length)
+					{
+						pargs[i + 1] = StringTools.quoteWinArg(args[i], false);
+					}
+				case _:
+					pargs[0] = cmd;
+					for (i in 0...args.length)
+					{
+						pargs[i + 1] = args[i];
+					}
+			}
 		}
 
 		try

+ 5 - 2
std/neko/_std/sys/io/Process.hx

@@ -92,8 +92,11 @@ private class Stdout extends haxe.io.Input {
 	public var stderr(default,null) : haxe.io.Input;
 	public var stdin(default,null) : haxe.io.Output;
 
-	public function new( cmd : String, args : Array<String> ) : Void {
-		p = try _run(untyped cmd.__s,neko.Lib.haxeToNeko(args)) catch( e : Dynamic ) throw "Process creation failure : "+cmd;
+	public function new( cmd : String, ?args : Array<String> ) : Void {
+		p = try 
+			_run(untyped cmd.__s, neko.Lib.haxeToNeko(args))
+		catch( e : Dynamic )
+			throw "Process creation failure : "+cmd;
 		stdin = new Stdin(p);
 		stdout = new Stdout(p,true);
 		stderr = new Stdout(p,false);

+ 1 - 1
std/php/_std/sys/io/Process.hx

@@ -85,7 +85,7 @@ class Process {
 	public var stderr(default,null) : haxe.io.Input;
 	public var stdin(default,null) : haxe.io.Output;
 
-	public function new( cmd : String, args : Array<String> ) : Void {
+	public function new( cmd : String, ?args : Array<String> ) : Void {
 		var pipes = untyped __call__("array");
 		var descriptorspec = untyped __php__("array(
 			array('pipe', 'r'),

+ 5 - 2
std/python/_std/Sys.hx

@@ -100,8 +100,11 @@ class Sys {
 	}
 
 	public static function command( cmd : String, ?args : Array<String> ) : Int {
-		var args = args == null ? [cmd] : [cmd].concat(args);
-		return python.lib.Subprocess.call(args);
+		return
+			if (args == null)
+				python.lib.Subprocess.call(cmd, { shell: true });
+			else
+				python.lib.Subprocess.call([cmd].concat(args));
 	}
 
 	public static function cpuTime() : Float {

+ 2 - 4
std/python/_std/sys/io/Process.hx

@@ -36,10 +36,8 @@ class Process {
 
 	var p:Popen;
 
-	public function new( cmd : String, args : Array<String> ) : Void {
-
-		p = Popen.create([cmd].concat(args), { stdin : Subprocess.PIPE, stdout: Subprocess.PIPE, stderr : Subprocess.PIPE });
-
+	public function new( cmd : String, ?args : Array<String> ) : Void {
+		p = Popen.create(args == null ? cmd : [cmd].concat(args), { shell : args == null, stdin : Subprocess.PIPE, stdout: Subprocess.PIPE, stderr : Subprocess.PIPE });
 		this.stdout = IoTools.createFileInputFromText(new TextIOWrapper(new BufferedReader(p.stdout)));
 		this.stderr = IoTools.createFileInputFromText(new TextIOWrapper(new BufferedReader(p.stderr)));
 		this.stdin =  IoTools.createFileOutputFromText(new TextIOWrapper(new BufferedWriter(p.stdin)));

+ 3 - 1
std/python/lib/Subprocess.hx

@@ -21,6 +21,8 @@
  */
 package python.lib;
 
+import haxe.extern.EitherType;
+
 extern class StartupInfo {
 	public var dwFlags : Int;
 
@@ -47,6 +49,6 @@ extern class Subprocess {
 
 	public static var STDOUT:Int;
 
-	public static function call(args:Array<String>):Int;
+	public static function call(args:EitherType<String,Array<String>>, ?kwArgs:python.KwArgs<Dynamic>):Int;
 
 }

+ 2 - 1
std/python/lib/subprocess/Popen.hx

@@ -27,6 +27,7 @@ import python.lib.io.TextIOBase;
 import python.lib.Subprocess.StartupInfo;
 import python.Tuple;
 import python.Dict;
+import haxe.extern.EitherType;
 
 typedef PopenOptions = {
 	?bufsize : Int,
@@ -47,7 +48,7 @@ typedef PopenOptions = {
 @:pythonImport("subprocess", "Popen")
 extern class Popen {
 
-	public static inline function create (args:Array<String>, o:PopenOptions):Popen {
+	public static inline function create (args:EitherType<String, Array<String>>, o:PopenOptions):Popen {
 
 		o.bufsize = if (Reflect.hasField(o, "bufsize")) o.bufsize else 0;
 		o.executable = if (Reflect.hasField(o, "executable")) o.executable else null;

+ 1 - 1
std/sys/io/Process.hx

@@ -27,7 +27,7 @@ extern class Process {
 	var stderr(default,null) : haxe.io.Input;
 	var stdin(default,null) : haxe.io.Output;
 
-	function new( cmd : String, args : Array<String> ) : Void;
+	function new( cmd : String, ?args : Array<String> ) : Void;
 	function getPid() : Int;
 	function exitCode() : Int;
 	function close() : Void;

+ 7 - 0
tests/sys/src/TestCommandBase.hx

@@ -122,4 +122,11 @@ class TestCommandBase extends haxe.unit.TestCase {
 			assertEquals(code, exitCode);
 		}
 	}
+
+	function testRawCommand() {
+		var bin = sys.FileSystem.absolutePath(ExitCode.bin);
+		var native = sys.FileSystem.absolutePath(ExitCode.getNative());
+		var exitCode = run('$native 1 || $native 0');
+		assertEquals(0, exitCode);
+	}
 }