everything related to duct tape audio suite (dtas)
 help / color / mirror / code / Atom feed
f5f9a9e2e05fd42afaf6cab2148d566b9c43ea33 blob 3279 bytes (raw)

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 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
 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
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
 
# Copyright (C) 2013-2015 all contributors <dtas-all@nongnu.org>
# License: GPLv3 or later (https://www.gnu.org/licenses/gpl-3.0.txt)
require 'io/wait'
require 'shellwords'
require_relative '../dtas'
require_relative 'xs'

# process management helpers
module DTAS::Process # :nodoc:
  PIDS = {}
  include DTAS::XS
  include DTAS::SpawnFix

  def self.reaper
    begin
      pid, status = Process.waitpid2(-1, Process::WNOHANG)
      pid or return
      obj = PIDS.delete(pid)
      yield status, obj
    rescue Errno::ECHILD
      return
    end while true
  end

  # expand common shell constructs based on environment variables
  # this is order-dependent, but Ruby 1.9+ hashes are already order-dependent
  # This recurses
  def env_expand(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_expand_i(env, key, val)
        when Array
          val.flatten!
          env[key] = Shellwords.join(val)
        end
      end
    end
  end

  def env_expand_i(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_expand_ary(env, key, val)
    else
      val
    end
  end

  # warning, recursion:
  def env_expand_ary(env, key, val)
    val.map { |v| env_expand_i(env.dup, key, v) }
  end

  # for long-running processes (sox/play/ecasound filters)
  def dtas_spawn(env, cmd, opts)
    opts = { close_others: true, pgroup: true }.merge!(opts)
    env = env_expand(env, opts)

    pid = spawn(env, cmd, opts)
    warn [ :spawn, pid, cmd ].inspect if $DEBUG
    @spawn_at = DTAS.now
    PIDS[pid] = self
    pid
  end

  # this is like backtick, but takes an array instead of a string
  # This will also raise on errors
  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_expand(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|
          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(cmd)}' failed: #{status.inspect}"
  end
end
debug log:

solving f5f9a9e ...
found f5f9a9e in dtas.git

everything related to duct tape audio suite (dtas)

This inbox may be cloned and mirrored by anyone:

	git clone --mirror https://80x24.org/dtas-all
	git clone --mirror http://ou63pmih66umazou.onion/dtas-all

	# If you have public-inbox 1.1+ installed, you may
	# initialize and index your mirror using the following commands:
	public-inbox-init -V1 dtas-all dtas-all/ https://80x24.org/dtas-all \
		dtas-all@nongnu.org
	public-inbox-index dtas-all

Example config snippet for mirrors.
Newsgroups are available over NNTP:
	nntp://news.public-inbox.org/inbox.comp.audio.dtas
	nntp://7fh6tueqddpjyxjmgtdiueylzoqt6pt7hec3pukyptlmohoowvhde4yd.onion/inbox.comp.audio.dtas
 note: .onion URLs require Tor: https://www.torproject.org/

code repositories for project(s) associated with this inbox:

	../../../dtas.git

AGPL code for this site: git clone http://7fh6tueqddpjyxjmgtdiueylzoqt6pt7hec3pukyptlmohoowvhde4yd.onion/public-inbox.git