Module: DTAS::Process
- Includes:
- XS
- Included in:
- Format, Format, PartStats, Sink, Source::Cmd, Source::File, Source::Mp3gain, SplitFX
- Defined in:
- lib/dtas/process.rb
Overview
:nodoc:
Constant Summary collapse
- PIDS =
{}
Class Method Summary collapse
Instance Method Summary collapse
-
#dtas_spawn(env, cmd, opts) ⇒ Object
for long-running processes (sox/play/ecasound filters).
-
#env_expand(env, opts) ⇒ Object
expand common shell constructs based on environment variables this is order-dependent, but Ruby 1.9+ hashes are already order-dependent.
-
#qx(env, cmd = {}, opts = {}) ⇒ Object
this is like backtick, but takes an array instead of a string This will also raise on errors.
Methods included from XS
Class Method Details
Instance Method Details
#dtas_spawn(env, cmd, opts) ⇒ Object
for long-running processes (sox/play/ecasound filters)
46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 |
# File 'lib/dtas/process.rb', line 46 def dtas_spawn(env, cmd, opts) opts = { close_others: true, pgroup: true }.merge!(opts) env = (env, opts) pid = begin Process.spawn(env, cmd, opts) rescue Errno::EINTR # workaround for older Rubies https://bugs.ruby-lang.org/issues/8770 retry end warn [ :spawn, pid, cmd ].inspect if $DEBUG @spawn_at = Time.now.to_f PIDS[pid] = self pid end |
#env_expand(env, opts) ⇒ Object
expand common shell constructs based on environment variables this is order-dependent, but Ruby 1.9+ hashes are already order-dependent
24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 |
# File 'lib/dtas/process.rb', line 24 def (env, opts) env = env.dup if false == opts.delete(:expand) env.each do |key, val| Numeric === val and env[key] = val.to_s end else env.each do |key, val| case val when Numeric # stringify numeric values to simplify users' lives env[key] = val.to_s when /[\`\$]/ # perform variable/command expansion tmp = env.dup tmp.delete(key) val = qx(tmp, "echo #{val}", expand: false) env[key] = val.chomp end end end end |
#qx(env, cmd = {}, opts = {}) ⇒ Object
this is like backtick, but takes an array instead of a string This will also raise on errors
64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 |
# File 'lib/dtas/process.rb', line 64 def qx(env, cmd = {}, opts = {}) unless Hash === env cmd, opts = env, cmd env = {} end r, w = IO.pipe opts = opts.merge(out: w) r.binmode no_raise = opts.delete(:no_raise) if err_str = opts.delete(:err_str) re, we = IO.pipe re.binmode opts[:err] = we end env = (env, opts) pid = begin Process.spawn(env, *cmd, opts) rescue Errno::EINTR # workaround for older Rubies https://bugs.ruby-lang.org/issues/8770 retry end w.close if err_str we.close res = "".b want = { r => res, re => err_str } begin readable = IO.select(want.keys) or next readable[0].each do |io| begin want[io] << io.read_nonblock(2000) rescue Errno::EAGAIN # spurious wakeup, bytes may be zero rescue EOFError want.delete(io) end end end until want.empty? re.close else res = r.read # read until EOF end r.close _, status = Process.waitpid2(pid) return res if status.success? return status if no_raise raise RuntimeError, "`#{xs(Array(cmd))}' failed: #{status.inspect}" end |