uv_stream.lua 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170
  1. local uv = require('luv')
  2. local StdioStream = {}
  3. StdioStream.__index = StdioStream
  4. function StdioStream.open()
  5. local self = setmetatable({
  6. _in = uv.new_pipe(false),
  7. _out = uv.new_pipe(false)
  8. }, StdioStream)
  9. self._in:open(0)
  10. self._out:open(1)
  11. return self
  12. end
  13. function StdioStream:write(data)
  14. self._out:write(data)
  15. end
  16. function StdioStream:read_start(cb)
  17. self._in:read_start(function(err, chunk)
  18. if err then
  19. error(err)
  20. end
  21. cb(chunk)
  22. end)
  23. end
  24. function StdioStream:read_stop()
  25. self._in:read_stop()
  26. end
  27. function StdioStream:close()
  28. self._in:close()
  29. self._out:close()
  30. end
  31. local SocketStream = {}
  32. SocketStream.__index = SocketStream
  33. function SocketStream.open(file)
  34. local socket = uv.new_pipe(false)
  35. local self = setmetatable({
  36. _socket = socket,
  37. _stream_error = nil
  38. }, SocketStream)
  39. uv.pipe_connect(socket, file, function (err)
  40. self._stream_error = self._stream_error or err
  41. end)
  42. return self
  43. end
  44. function SocketStream.connect(host, port)
  45. local socket = uv.new_tcp()
  46. local self = setmetatable({
  47. _socket = socket,
  48. _stream_error = nil
  49. }, SocketStream)
  50. uv.tcp_connect(socket, host, port, function (err)
  51. self._stream_error = self._stream_error or err
  52. end)
  53. return self
  54. end
  55. function SocketStream:write(data)
  56. if self._stream_error then
  57. error(self._stream_error)
  58. end
  59. uv.write(self._socket, data, function(err)
  60. if err then
  61. error(self._stream_error or err)
  62. end
  63. end)
  64. end
  65. function SocketStream:read_start(cb)
  66. if self._stream_error then
  67. error(self._stream_error)
  68. end
  69. uv.read_start(self._socket, function(err, chunk)
  70. if err then
  71. error(err)
  72. end
  73. cb(chunk)
  74. end)
  75. end
  76. function SocketStream:read_stop()
  77. if self._stream_error then
  78. error(self._stream_error)
  79. end
  80. uv.read_stop(self._socket)
  81. end
  82. function SocketStream:close()
  83. uv.close(self._socket)
  84. end
  85. local ChildProcessStream = {}
  86. ChildProcessStream.__index = ChildProcessStream
  87. function ChildProcessStream.spawn(argv, env, io_extra)
  88. local self = setmetatable({
  89. _child_stdin = uv.new_pipe(false);
  90. _child_stdout = uv.new_pipe(false);
  91. _exiting = false;
  92. }, ChildProcessStream)
  93. local prog = argv[1]
  94. local args = {}
  95. for i = 2, #argv do
  96. args[#args + 1] = argv[i]
  97. end
  98. self._proc, self._pid = uv.spawn(prog, {
  99. stdio = {self._child_stdin, self._child_stdout, 2, io_extra},
  100. args = args,
  101. env = env,
  102. }, function(status, signal)
  103. self.status = status
  104. self.signal = signal
  105. end)
  106. if not self._proc then
  107. local err = self._pid
  108. error(err)
  109. end
  110. return self
  111. end
  112. function ChildProcessStream:write(data)
  113. self._child_stdin:write(data)
  114. end
  115. function ChildProcessStream:read_start(cb)
  116. self._child_stdout:read_start(function(err, chunk)
  117. if err then
  118. error(err)
  119. end
  120. cb(chunk)
  121. end)
  122. end
  123. function ChildProcessStream:read_stop()
  124. self._child_stdout:read_stop()
  125. end
  126. function ChildProcessStream:close(signal)
  127. if self._closed then
  128. return
  129. end
  130. self._closed = true
  131. self:read_stop()
  132. self._child_stdin:close()
  133. self._child_stdout:close()
  134. if type(signal) == 'string' then
  135. self._proc:kill('sig'..signal)
  136. end
  137. while self.status == nil do
  138. uv.run 'once'
  139. end
  140. return self.status, self.signal
  141. end
  142. return {
  143. StdioStream = StdioStream;
  144. ChildProcessStream = ChildProcessStream;
  145. SocketStream = SocketStream;
  146. }