13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
|
# File 'lib/browserify_rb/popen3.rb', line 13
def self.async_exec(
input: "",
env: {},
cmd: nil,
stdout_handler: DEFAULT_STDOUT_HANDLER,
stderr_handler: DEFAULT_STDERR_HANDLER,
spawn_opts: {},
chunk_size: CHUNK_SIZE)
raise ArgumentError, "'cmd' require" if cmd.nil?
stdin, stdout, stderr, wait_thr = Open3.popen3 env, cmd, spawn_opts
in_buf = StringIO.new input
opened_ins = [stdin]
opened_outs = [stdout, stderr]
Thread.fork do
begin
while not opened_outs.empty?
ios = IO.select opened_outs, opened_ins, nil, 1
if ios.nil? and Process.waitpid(wait_thr.pid, Process::WNOHANG)
break
end
outs, ins, = ios
unless outs.nil?
if outs.include? stdout
begin
d = stdout.readpartial CHUNK_SIZE
stdout_handler.yield d
rescue EOFError
opened_outs.delete stdout
end
end
if outs.include? stderr
begin
d = stderr.readpartial CHUNK_SIZE
stderr_handler.yield d
rescue EOFError
opened_outs.delete stderr
end
end
end
if not ins.nil? and ins.include? stdin
i = begin
in_buf.readpartial CHUNK_SIZE
rescue EOFError
nil
end
if i.nil?
stdin.close
opened_ins.delete stdin
else
bytes = stdin.write_nonblock(i)
in_buf.seek bytes - i.bytesize, IO::SEEK_CUR
end
end
end
rescue => e
LOG.error e
end
end
wait_thr
end
|