Module: DTAS::Process
- 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 SpawnFix
Methods included from XS
Class Method Details
Instance Method Details
#dtas_spawn(env, cmd, opts) ⇒ Object
for long-running processes (sox/play/ecasound filters)
73 74 75 76 77 78 79 80 81 82 |
# File 'lib/dtas/process.rb', line 73 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
30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 |
# File 'lib/dtas/process.rb', line 30 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:
68 69 70 |
# File 'lib/dtas/process.rb', line 68 def (env, key, val) val.map { |v| (env.dup, key, v) } end |
#env_expand_i(env, key, val) ⇒ Object
47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 |
# File 'lib/dtas/process.rb', line 47 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
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 127 128 |
# File 'lib/dtas/process.rb', line 86 def qx(env, cmd = {}, opts = {}) unless Hash === env cmd, opts = env, cmd env = {} end buf = ''.b r, w = DTAS::Nonblock.pipe opts = opts.merge(out: w) r.binmode no_raise = opts.delete(:no_raise) if err_str = opts.delete(:err_str) re, we = DTAS::Nonblock.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 |