2
0

Process.hx 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133
  1. /*
  2. * Copyright (C)2005-2019 Haxe Foundation
  3. *
  4. * Permission is hereby granted, free of charge, to any person obtaining a
  5. * copy of this software and associated documentation files (the "Software"),
  6. * to deal in the Software without restriction, including without limitation
  7. * the rights to use, copy, modify, merge, publish, distribute, sublicense,
  8. * and/or sell copies of the Software, and to permit persons to whom the
  9. * Software is furnished to do so, subject to the following conditions:
  10. *
  11. * The above copyright notice and this permission notice shall be included in
  12. * all copies or substantial portions of the Software.
  13. *
  14. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  15. * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  16. * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  17. * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  18. * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
  19. * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
  20. * DEALINGS IN THE SOFTWARE.
  21. */
  22. package sys.io;
  23. private extern class NativeProcess {
  24. function new(cmd:String, ?args:Array<String>):Void;
  25. function close():Void;
  26. function exitCode():Int;
  27. function getPid():Int;
  28. function kill():Void;
  29. function readStderr(bytes:haxe.io.Bytes, pos:Int, len:Int):Int;
  30. function readStdout(bytes:haxe.io.Bytes, pos:Int, len:Int):Int;
  31. function closeStdin():Void;
  32. function writeStdin(bytes:haxe.io.Bytes, pos:Int, len:Int):Int;
  33. }
  34. private class Stdin extends haxe.io.Output {
  35. var proc:NativeProcess;
  36. var buf:haxe.io.Bytes;
  37. public function new(proc:NativeProcess) {
  38. this.proc = proc;
  39. buf = haxe.io.Bytes.alloc(1);
  40. }
  41. public override function close() {
  42. super.close();
  43. proc.closeStdin();
  44. }
  45. public override function writeByte(c:Int) {
  46. buf.set(0, c);
  47. writeBytes(buf, 0, 1);
  48. }
  49. public override function writeBytes(buf:haxe.io.Bytes, pos:Int, len:Int) {
  50. try {
  51. return proc.writeStdin(buf, pos, len);
  52. } catch (e:Dynamic) {
  53. throw new haxe.io.Eof();
  54. }
  55. }
  56. }
  57. private class Stdout extends haxe.io.Input {
  58. var proc:NativeProcess;
  59. var out:Bool;
  60. var buf:haxe.io.Bytes;
  61. public function new(proc:NativeProcess, out:Bool) {
  62. this.proc = proc;
  63. this.out = out;
  64. buf = haxe.io.Bytes.alloc(1);
  65. }
  66. public override function readByte() {
  67. if (readBytes(buf, 0, 1) == 0)
  68. throw haxe.io.Error.Blocked;
  69. return buf.get(0);
  70. }
  71. public override function readBytes(bytes:haxe.io.Bytes, pos:Int, len:Int):Int {
  72. try {
  73. if (out) {
  74. return proc.readStdout(bytes, pos, len);
  75. } else {
  76. return proc.readStderr(bytes, pos, len);
  77. }
  78. } catch (e:Dynamic) {
  79. throw new haxe.io.Eof();
  80. }
  81. }
  82. }
  83. @:coreApi
  84. class Process {
  85. public var stdout(default, null):haxe.io.Input;
  86. public var stderr(default, null):haxe.io.Input;
  87. public var stdin(default, null):haxe.io.Output;
  88. var proc:NativeProcess;
  89. public function new(cmd:String, ?args:Array<String>, ?detached:Bool):Void {
  90. if (detached) {
  91. throw "Detached process is not supported on this platform";
  92. }
  93. proc = new NativeProcess(cmd, args);
  94. stdout = new Stdout(proc, true);
  95. stderr = new Stdout(proc, false);
  96. stdin = new Stdin(proc);
  97. }
  98. public inline function getPid():Int {
  99. return proc.getPid();
  100. }
  101. public function exitCode(block:Bool = true):Null<Int> {
  102. if (block == false)
  103. throw "Non blocking exitCode() not supported on this platform";
  104. return proc.exitCode();
  105. }
  106. public inline function close():Void {
  107. proc.close();
  108. }
  109. public inline function kill():Void {
  110. proc.kill();
  111. }
  112. }