Module: DTAS::Process
- Includes:
- XS
- Included in:
- Format, Format, Mlib, PartStats, Sink, Source::Cmd, Source::File, Source::Mp3gain, SplitFX
- Defined in:
- lib/dtas/process.rb
Overview
process management helpers
Constant Summary collapse
- PIDS =
:nodoc:
{}
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 This recurses.
-
#env_expand_ary(env, key, val) ⇒ Object
warning, recursion:.
- #env_expand_i(env, key, val) ⇒ Object
-
#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)
71 72 73 74 75 76 77 78 79 80 |
# File 'lib/dtas/process.rb', line 71 def dtas_spawn(env, cmd, opts) opts = { close_others: true, pgroup: true }.merge!(opts) env = (env, opts) pid = spawn(env, cmd, opts) warn [ :spawn, pid, cmd ].inspect if $DEBUG @spawn_at = DTAS.now 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 This recurses
28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 |
# File 'lib/dtas/process.rb', line 28 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 = (env, key, val) when Array val.flatten! env[key] = Shellwords.join(val) end end end end |
#env_expand_ary(env, key, val) ⇒ Object
warning, recursion:
66 67 68 |
# File 'lib/dtas/process.rb', line 66 def (env, key, val) val.map { |v| (env.dup, key, v) } end |
#env_expand_i(env, key, val) ⇒ Object
45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 |
# File 'lib/dtas/process.rb', line 45 def (env, 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) tmp.each do |k,v| # best effort, this can get wonky tmp[k] = Shellwords.join(v.flatten) if Array === v end val = qx(tmp, "echo #{val}", expand: false) env[key] = val.chomp when Array env[key] = (env, key, val) else val 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
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 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 |
# File 'lib/dtas/process.rb', line 84 def qx(env, cmd = {}, opts = {}) unless Hash === env cmd, opts = env, cmd env = {} end buf = ''.b 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 = spawn(env, *cmd, opts) 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| case rv = io.read_nonblock(2000, buf, exception: false) when :wait_readable # spurious wakeup, bytes may be zero when nil then want.delete(io) else want[io] << rv 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(cmd)}' failed: #{status.inspect}" end |