dtas 0.2.0 → 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (89) hide show
  1. checksums.yaml +4 -4
  2. data/Documentation/dtas-console.txt +6 -0
  3. data/Documentation/dtas-ctl.txt +6 -0
  4. data/Documentation/dtas-cueedit.txt +6 -0
  5. data/Documentation/dtas-enq.txt +6 -0
  6. data/Documentation/dtas-msinkctl.txt +6 -0
  7. data/Documentation/dtas-player.txt +21 -14
  8. data/Documentation/dtas-player_effects.txt +6 -0
  9. data/Documentation/dtas-player_protocol.txt +14 -0
  10. data/Documentation/dtas-player_sink_examples.txt +30 -0
  11. data/Documentation/dtas-sinkedit.txt +6 -0
  12. data/Documentation/dtas-sourceedit.txt +15 -1
  13. data/Documentation/dtas-xdelay.txt +19 -6
  14. data/GIT-VERSION-GEN +1 -1
  15. data/GNUmakefile +20 -1
  16. data/HACKING +9 -0
  17. data/INSTALL +17 -10
  18. data/README +10 -10
  19. data/Rakefile +3 -1
  20. data/bin/dtas-console +7 -2
  21. data/bin/dtas-ctl +0 -3
  22. data/bin/dtas-cueedit +5 -6
  23. data/bin/dtas-enq +0 -1
  24. data/bin/dtas-msinkctl +0 -1
  25. data/bin/dtas-player +4 -2
  26. data/bin/dtas-sinkedit +0 -1
  27. data/bin/dtas-sourceedit +23 -9
  28. data/bin/dtas-xdelay +1 -1
  29. data/dtas-linux.gemspec +3 -1
  30. data/dtas-mpris.gemspec +0 -1
  31. data/lib/dtas.rb +0 -1
  32. data/lib/dtas/buffer.rb +0 -1
  33. data/lib/dtas/buffer/read_write.rb +0 -1
  34. data/lib/dtas/buffer/splice.rb +0 -1
  35. data/lib/dtas/command.rb +0 -1
  36. data/lib/dtas/compat_onenine.rb +0 -1
  37. data/lib/dtas/disclaimer.rb +5 -6
  38. data/lib/dtas/edit_client.rb +0 -1
  39. data/lib/dtas/format.rb +1 -5
  40. data/lib/dtas/pipe.rb +0 -1
  41. data/lib/dtas/player.rb +6 -2
  42. data/lib/dtas/player/client_handler.rb +33 -3
  43. data/lib/dtas/process.rb +5 -5
  44. data/lib/dtas/replaygain.rb +0 -1
  45. data/lib/dtas/rg_state.rb +3 -2
  46. data/lib/dtas/serialize.rb +0 -1
  47. data/lib/dtas/sigevent.rb +0 -1
  48. data/lib/dtas/sigevent/efd.rb +0 -1
  49. data/lib/dtas/sigevent/pipe.rb +0 -1
  50. data/lib/dtas/sink.rb +0 -1
  51. data/lib/dtas/source.rb +0 -1
  52. data/lib/dtas/source/av.rb +1 -2
  53. data/lib/dtas/source/av_ff_common.rb +67 -24
  54. data/lib/dtas/source/cmd.rb +0 -1
  55. data/lib/dtas/source/common.rb +0 -1
  56. data/lib/dtas/source/ff.rb +1 -2
  57. data/lib/dtas/source/file.rb +0 -1
  58. data/lib/dtas/source/mp3gain.rb +1 -2
  59. data/lib/dtas/source/sox.rb +6 -5
  60. data/lib/dtas/state_file.rb +2 -1
  61. data/lib/dtas/unix_accepted.rb +0 -1
  62. data/lib/dtas/unix_client.rb +5 -3
  63. data/lib/dtas/unix_server.rb +0 -1
  64. data/lib/dtas/util.rb +0 -1
  65. data/lib/dtas/writable_iter.rb +0 -1
  66. data/lib/dtas/xs.rb +14 -0
  67. data/setup.rb +0 -1
  68. data/test/covshow.rb +0 -1
  69. data/test/helper.rb +0 -1
  70. data/test/player_integration.rb +0 -1
  71. data/test/test_buffer.rb +0 -1
  72. data/test/test_format.rb +0 -1
  73. data/test/test_format_change.rb +0 -1
  74. data/test/test_player.rb +0 -1
  75. data/test/test_player_client_handler.rb +12 -1
  76. data/test/test_player_integration.rb +18 -1
  77. data/test/test_process.rb +7 -1
  78. data/test/test_rg_integration.rb +0 -1
  79. data/test/test_rg_state.rb +0 -1
  80. data/test/test_sink.rb +0 -1
  81. data/test/test_sink_pipe_size.rb +0 -1
  82. data/test/test_sink_tee_integration.rb +0 -1
  83. data/test/test_source_av.rb +2 -3
  84. data/test/test_source_sox.rb +0 -1
  85. data/test/test_unixserver.rb +0 -1
  86. data/test/test_util.rb +0 -1
  87. metadata +3 -5
  88. data/Documentation/troubleshooting.txt +0 -18
  89. data/pkg.mk +0 -28
data/README CHANGED
@@ -68,15 +68,20 @@ See http://www.git-scm.com/ for more information on git.
68
68
 
69
69
  ## Contact
70
70
 
71
- Feedback (results, bug reports, patches, pull-requests) via plain-text
72
- email is very much appreciated.
71
+ All feedback (comments, results, feature requests, bug reports, patches,
72
+ pull-requests) via plain-text mail to the mailing list is very much
73
+ appreciated.
73
74
 
74
- Please send plain-text email to Eric Wong <normalperson@yhbt.net>.
75
- HTML will not be read. dtas is for GUI-phobes, by GUI-phobes.
76
- Public mailing list coming soon.
75
+ Please send plain-text mail to the list at <dtas-all@nongnu.org>\
76
+ HTML will not be read. dtas is for GUI-phobes, by GUI-phobes.\
77
+ Mailing list archives available at <ftp://lists.gnu.org/dtas-all/>\
78
+ No subscription is necessary to post to the mailing list.
77
79
 
78
80
  ## Copyright
79
81
 
82
+ Copyright 2013, Eric Wong <normalperson@yhbt.net> and all contributors.\
83
+ License: GPLv3 or later <http://www.gnu.org/licenses/gpl-3.0.txt>
84
+
80
85
  dtas is copyrighted Free Software by all contributors, see logs
81
86
  in revision control for names and email addresses of all of them.
82
87
 
@@ -93,11 +98,6 @@ for more details.
93
98
  You should have received a copy of the GNU General Public License along
94
99
  with this program; if not, see https://www.gnu.org/licenses/gpl-3.0.txt
95
100
 
96
- dtas is distributed in the hope that it will be useful, but WITHOUT ANY
97
- WARRANTY; without even the implied warranty of MERCHANTABILITY or
98
- FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
99
- for more details.
100
-
101
101
  Note: The GPL does not and can not apply to external commands run by
102
102
  dtas scripts, so users _may_ run any non-Free Software you want via dtas
103
103
  (just like one may do so via bash). However, the dtas project does not
data/Rakefile CHANGED
@@ -41,7 +41,8 @@ if ! File.exist?(manifest) || File.stat(manifest).mtime < gitidx.mtime
41
41
  end
42
42
 
43
43
  fp.write("\n# COPYRIGHT\n")
44
- fp.puts "Copyright (C) 2013, Eric Wong <normalperson@yhbt.net> and all contributors"
44
+ bdfl = 'Eric Wong <normalperson@yhbt.net>'
45
+ fp.puts "Copyright (C) 2013, #{bdfl} and all contributors"
45
46
  fp.puts "License: GPLv3 or later (http://www.gnu.org/licenses/gpl-3.0.txt)"
46
47
  end
47
48
  end
@@ -70,6 +71,7 @@ task :rsync_docs do
70
71
  files = []
71
72
 
72
73
  # git-set-file-times is distributed with rsync,
74
+ # Also available at: http://yhbt.net/git-set-file-times
73
75
  # on Debian systems: /usr/share/doc/rsync/scripts/git-set-file-times.gz
74
76
  sh("git", "set-file-times", "Documentation")
75
77
 
@@ -1,19 +1,21 @@
1
1
  #!/usr/bin/env ruby
2
- # -*- encoding: binary -*-
3
2
  # Copyright (C) 2013, Eric Wong <normalperson@yhbt.net> and all contributors
4
3
  # License: GPLv3 or later (https://www.gnu.org/licenses/gpl-3.0.txt)
5
4
  #
6
5
  # Note: no idea what I'm doing, especially w.r.t. curses
7
6
  require 'dtas/unix_client'
8
7
  require 'dtas/rg_state'
8
+ require 'dtas/sigevent'
9
9
  require 'curses'
10
10
  require 'yaml'
11
11
 
12
+ se = DTAS::Sigevent.new
13
+ trap(:WINCH) { se.signal }
12
14
  w = DTAS::UNIXClient.new
13
15
  w.req_ok('watch')
14
16
  c = DTAS::UNIXClient.new
15
17
  cur = YAML.load(c.req('current'))
16
- readable = [ w, $stdin ]
18
+ readable = [ se, w, $stdin ]
17
19
 
18
20
  # current rg mode
19
21
  rg_mode = DTAS::RGState::RG_MODE.keys.unshift("off")
@@ -146,6 +148,9 @@ begin
146
148
  r = IO.select(readable, nil, nil, current ? interval : nil) or next
147
149
  r[0].each do |io|
148
150
  case io
151
+ when se
152
+ se.readable_iter {} # noop, just consume the event
153
+ Curses.clear
149
154
  when w
150
155
  event = w.res_wait
151
156
  events << "#{Time.now.strftime(tfmt)} #{event}"
@@ -1,10 +1,7 @@
1
1
  #!/usr/bin/env ruby
2
- # -*- encoding: binary -*-
3
2
  # Copyright (C) 2013, Eric Wong <normalperson@yhbt.net> and all contributors
4
3
  # License: GPLv3 or later (https://www.gnu.org/licenses/gpl-3.0.txt)
5
4
  require 'dtas/unix_client'
6
5
 
7
- # Unix paths are encoding agnostic
8
- ARGV.map! { |arg| arg.b }
9
6
  c = DTAS::UNIXClient.new
10
7
  puts c.req(ARGV)
@@ -1,16 +1,15 @@
1
1
  #!/usr/bin/env ruby
2
- # -*- encoding: binary -*-
3
2
  # Copyright (C) 2013, Eric Wong <normalperson@yhbt.net> and all contributors
4
3
  # License: GPLv3 or later (https://www.gnu.org/licenses/gpl-3.0.txt)
5
4
  require 'tempfile'
6
- require 'shellwords'
5
+ require 'dtas/xs'
7
6
  usage = "Usage: #$0 FILENAME"
8
7
  editor = ENV["VISUAL"] || ENV["EDITOR"] || "vi"
9
8
  ARGV.size > 0 or abort usage
9
+ include DTAS::XS
10
10
 
11
11
  def err_msg(cmd, status)
12
- err_cmd = cmd.map { |f| Shellwords.escape(f) }.join(' ')
13
- "E: #{err_cmd} failed: #{status.inspect}"
12
+ "E: #{xs(cmd)} failed: #{status.inspect}"
14
13
  end
15
14
 
16
15
  def x!(*cmd)
@@ -52,7 +51,7 @@ ARGV.each do |file|
52
51
  # avoid an expensive update if the user didn't change anything
53
52
  current = File.binread(tmp.path)
54
53
  if current == original
55
- $stderr.puts "tags for #{Shellwords.escape(file)} unchanged" if $DEBUG
54
+ $stderr.puts "tags for #{xs(Array(file))} unchanged" if $DEBUG
56
55
  next
57
56
  end
58
57
 
@@ -68,7 +67,7 @@ ARGV.each do |file|
68
67
  warn err_msg(cmd, $?)
69
68
  warn "E: restoring original from backup"
70
69
  x!(*%W(metaflac --import-cuesheet-from=#{backup.path} #{file}))
71
- warn "E: backup cuesheet restored, #{Shellwords.escape(file)} unchanged"
70
+ warn "E: backup cuesheet restored, #{xs(Array(file))} unchanged"
72
71
  exit(false)
73
72
  end
74
73
  ensure
@@ -1,5 +1,4 @@
1
1
  #!/usr/bin/env ruby
2
- # -*- encoding: binary -*-
3
2
  # Copyright (C) 2013, Eric Wong <normalperson@yhbt.net> and all contributors
4
3
  # License: GPLv3 or later (https://www.gnu.org/licenses/gpl-3.0.txt)
5
4
  require 'dtas/unix_client'
@@ -1,5 +1,4 @@
1
1
  #!/usr/bin/env ruby
2
- # -*- encoding: binary -*-
3
2
  # Copyright (C) 2013, Eric Wong <normalperson@yhbt.net> and all contributors
4
3
  # License: GPLv3 or later (https://www.gnu.org/licenses/gpl-3.0.txt)
5
4
  require 'yaml'
@@ -1,5 +1,4 @@
1
1
  #!/usr/bin/env ruby
2
- # -*- encoding: binary -*-
3
2
  # Copyright (C) 2013, Eric Wong <normalperson@yhbt.net> and all contributors
4
3
  # License: GPLv3 or later (https://www.gnu.org/licenses/gpl-3.0.txt)
5
4
  Thread.abort_on_exception = $stderr.sync = $stdout.sync = true
@@ -27,7 +26,10 @@ else
27
26
  player.socket = sock
28
27
  end
29
28
 
30
- at_exit { player.close }
29
+ at_exit do
30
+ player.close
31
+ Process.waitall
32
+ end
31
33
  player.bind
32
34
  trap(:INT) { exit }
33
35
  trap(:TERM) { exit }
@@ -1,5 +1,4 @@
1
1
  #!/usr/bin/env ruby
2
- # -*- encoding: binary -*-
3
2
  # Copyright (C) 2013, Eric Wong <normalperson@yhbt.net> and all contributors
4
3
  # License: GPLv3 or later (https://www.gnu.org/licenses/gpl-3.0.txt)
5
4
  require 'dtas/edit_client'
@@ -1,27 +1,37 @@
1
1
  #!/usr/bin/env ruby
2
- # -*- encoding: binary -*-
3
2
  # Copyright (C) 2013, Eric Wong <normalperson@yhbt.net> and all contributors
4
3
  # License: GPLv3 or later (https://www.gnu.org/licenses/gpl-3.0.txt)
5
4
  require 'dtas/edit_client'
6
5
  include DTAS::EditClient
7
6
  c = client_socket
8
7
  sources = c.req('source ls') || "(unknown)"
9
- usage = "Usage: #{DTAS_PROGNAME} SOURCENAME\n" \
8
+ usage = "Usage: #{DTAS_PROGNAME} [-n|--dry-run][-V|--verbose] SOURCENAME\n" \
10
9
  "available SOURCENAME values: #{sources}"
10
+
11
+ # use a real option parser if we have anything more complex
12
+ dry_run = !!(ARGV.delete('-n') || ARGV.delete('--dry-run'))
13
+ verbose = !!(ARGV.delete('-V') || ARGV.delete('--verbose'))
14
+
11
15
  ARGV.size <= 1 or abort usage
12
16
  name = ARGV[0] || "sox"
13
17
 
14
- tmp = tmpyaml
18
+ st_in = $stdin.stat
19
+
15
20
  buf = c.req(%W(source cat #{name}))
16
21
  abort(buf) if buf =~ /\AERR/
17
22
  orig = YAML.load(buf)
18
23
 
19
- tmp.write(buf << DTAS_DISCLAIMER)
20
- cmd = "#{editor} #{tmp.path}"
21
- system(cmd) or abort "#{cmd} failed: #$?"
22
- tmp.rewind
23
- source = YAML.load(tmp.read)
24
+ if st_in.file? || st_in.pipe?
25
+ tmp = $stdin
26
+ else
27
+ tmp = tmpyaml
28
+ tmp.write(buf << DTAS_DISCLAIMER)
29
+ cmd = "#{editor} #{tmp.path}"
30
+ system(cmd) or abort "#{cmd} failed: #$?"
31
+ tmp.rewind
32
+ end
24
33
 
34
+ source = YAML.load(tmp.read)
25
35
  cmd = %W(source ed #{name})
26
36
  update_cmd_env(cmd, orig, source)
27
37
 
@@ -30,4 +40,8 @@ update_cmd_env(cmd, orig, source)
30
40
  cmd << "#{field}=#{source[field]}"
31
41
  end
32
42
 
33
- c.req_ok(cmd)
43
+ if verbose || dry_run
44
+ warn Shellwords.join(cmd)
45
+ end
46
+
47
+ c.req_ok(cmd) unless dry_run
@@ -1,5 +1,4 @@
1
1
  #!/usr/bin/env ruby
2
- # -*- encoding: binary -*-
3
2
  # Copyright (C) 2013, Eric Wong <normalperson@yhbt.net> and all contributors
4
3
  # License: GPLv3 or later (https://www.gnu.org/licenses/gpl-3.0.txt)
5
4
  USAGE = "Usage: #$0 [-x FREQ] [-l] /dev/fd/LO /dev/fd/HI DELAY [DELAY ...]"
@@ -74,6 +73,7 @@ when "sox"
74
73
  args.unshift "sox"
75
74
  args.concat(%W(-t#{out_type} -c#{out_channels} -r#{out_rate} -))
76
75
  when "play"
76
+ args.unshift "-q"
77
77
  args.unshift "play"
78
78
  else
79
79
  abort "BUG: bad cmd=#{cmd.inspect}"
@@ -1,4 +1,6 @@
1
- # -*- encoding: binary -*-
1
+ # Copyright (C) 2013, Eric Wong <normalperson@yhbt.net> and all contributors
2
+ # License: GPLv3 or later (https://www.gnu.org/licenses/gpl-3.0.txt)
3
+ #
2
4
  # this just declares dependencies to make gem installation a little easier
3
5
  # for Linux users
4
6
  Gem::Specification.new do |s|
@@ -1,4 +1,3 @@
1
- # -*- encoding: binary -*-
2
1
  # Copyright 2013, Eric Wong <normalperson@yhbt.net> and all contributors.
3
2
  # License: GPLv2 or later <http://www.gnu.org/licenses/gpl-2.0.txt>
4
3
  # This is GPLv2+ instead of GPLv3+ because ruby-dbus is LGPLv2.1 (only)
@@ -1,4 +1,3 @@
1
- # -*- encoding: binary -*-
2
1
  # Copyright (C) 2013, Eric Wong <normalperson@yhbt.net> and all contributors
3
2
  # License: GPLv3 or later (https://www.gnu.org/licenses/gpl-3.0.txt)
4
3
  module DTAS # :nodoc:
@@ -1,4 +1,3 @@
1
- # -*- encoding: binary -*-
2
1
  # Copyright (C) 2013, Eric Wong <normalperson@yhbt.net> and all contributors
3
2
  # License: GPLv3 or later (https://www.gnu.org/licenses/gpl-3.0.txt)
4
3
  require_relative '../dtas'
@@ -1,4 +1,3 @@
1
- # -*- encoding: binary -*-
2
1
  # Copyright (C) 2013, Eric Wong <normalperson@yhbt.net> and all contributors
3
2
  # License: GPLv3 or later (https://www.gnu.org/licenses/gpl-3.0.txt)
4
3
  require 'io/wait'
@@ -1,4 +1,3 @@
1
- # -*- encoding: binary -*-
2
1
  # Copyright (C) 2013, Eric Wong <normalperson@yhbt.net> and all contributors
3
2
  # License: GPLv3 or later (https://www.gnu.org/licenses/gpl-3.0.txt)
4
3
  require 'io/wait'
@@ -1,4 +1,3 @@
1
- # -*- encoding: binary -*-
2
1
  # Copyright (C) 2013, Eric Wong <normalperson@yhbt.net> and all contributors
3
2
  # License: GPLv3 or later (https://www.gnu.org/licenses/gpl-3.0.txt)
4
3
  # common code for wrapping SoX/ecasound/... commands
@@ -1,4 +1,3 @@
1
- # -*- encoding: binary -*-
2
1
  # Copyright (C) 2013, Eric Wong <normalperson@yhbt.net> and all contributors
3
2
  # License: GPLv3 or later (https://www.gnu.org/licenses/gpl-3.0.txt)
4
3
 
@@ -1,4 +1,3 @@
1
- # -*- encoding: binary -*-
2
1
  # :enddoc:
3
2
  # Copyright (C) 2013, Eric Wong <normalperson@yhbt.net> and all contributors
4
3
  # License: GPLv3 or later (https://www.gnu.org/licenses/gpl-3.0.txt)
@@ -6,14 +5,14 @@ DTAS_PROGNAME = File.basename($0)
6
5
  DTAS_DISCLAIMER = <<EOF
7
6
  # WARNING!
8
7
  #
9
- # Ignorant or improper use of #{DTAS_PROGNAME} may lead to
10
- # data loss, hearing loss, and damage to audio equipment.
8
+ # Ignorant or improper use of #{DTAS_PROGNAME}
9
+ # may lead to data loss, hearing loss, and damage to audio equipment.
11
10
  #
12
11
  # Please read and understand the documentation of all commands you
13
12
  # attempt to configure.
14
13
  #
15
- # #{DTAS_PROGNAME} will never prevent you from doing stupid things.
14
+ # dtas will never prevent you from doing stupid things.
16
15
  #
17
- # There is no warranty, the developers of #{DTAS_PROGNAME}
18
- # are not responsible for your actions.
16
+ # There is no warranty, the developers of dtas are not responsible
17
+ # for your actions.
19
18
  EOF
@@ -1,4 +1,3 @@
1
- # -*- encoding: binary -*-
2
1
  # Copyright (C) 2013, Eric Wong <normalperson@yhbt.net> and all contributors
3
2
  # License: GPLv3 or later (https://www.gnu.org/licenses/gpl-3.0.txt)
4
3
  require 'tempfile'
@@ -1,4 +1,3 @@
1
- # -*- encoding: binary -*-
2
1
  # Copyright (C) 2013, Eric Wong <normalperson@yhbt.net> and all contributors
3
2
  # License: GPLv3 or later (https://www.gnu.org/licenses/gpl-3.0.txt)
4
3
  # class represents an audio format (type/bits/channels/sample rate/...)
@@ -9,6 +8,7 @@ require_relative 'serialize'
9
8
  class DTAS::Format # :nodoc:
10
9
  include DTAS::Process
11
10
  include DTAS::Serialize
11
+
12
12
  NATIVE_ENDIAN = [1].pack("l") == [1].pack("l>") ? "big" : "little"
13
13
 
14
14
  attr_accessor :type # s32, f32, f64 ... any point in others?
@@ -63,10 +63,6 @@ class DTAS::Format # :nodoc:
63
63
  %W(-f #{@type}_#{endian2},#@channels,#@rate)
64
64
  end
65
65
 
66
- def inspect
67
- "<#{self.class}(#{Shellwords.join(to_sox_arg)})>"
68
- end
69
-
70
66
  def to_hsh
71
67
  to_hash.delete_if { |k,v| v == FORMAT_DEFAULTS[k] }
72
68
  end
@@ -1,4 +1,3 @@
1
- # -*- encoding: binary -*-
2
1
  # Copyright (C) 2013, Eric Wong <normalperson@yhbt.net> and all contributors
3
2
  # License: GPLv3 or later (https://www.gnu.org/licenses/gpl-3.0.txt)
4
3
  begin
@@ -1,9 +1,9 @@
1
- # -*- encoding: binary -*-
2
1
  # Copyright (C) 2013, Eric Wong <normalperson@yhbt.net> and all contributors
3
2
  # License: GPLv3 or later (https://www.gnu.org/licenses/gpl-3.0.txt)
4
3
  require 'yaml'
5
4
  require 'shellwords'
6
5
  require_relative '../dtas'
6
+ require_relative 'xs'
7
7
  require_relative 'source'
8
8
  require_relative 'source/sox'
9
9
  require_relative 'source/av'
@@ -18,6 +18,7 @@ require_relative 'state_file'
18
18
 
19
19
  class DTAS::Player # :nodoc:
20
20
  require_relative 'player/client_handler'
21
+ include DTAS::XS
21
22
  include DTAS::Player::ClientHandler
22
23
  attr_accessor :state_file
23
24
  attr_accessor :socket
@@ -52,7 +53,7 @@ class DTAS::Player # :nodoc:
52
53
  end
53
54
 
54
55
  def echo(msg)
55
- msg = Shellwords.join(msg) if Array === msg
56
+ msg = xs(Array(msg))
56
57
  @watchers.delete_if do |io, _|
57
58
  if io.closed?
58
59
  true
@@ -211,6 +212,8 @@ class DTAS::Player # :nodoc:
211
212
  io.emit("OK")
212
213
  when "source"
213
214
  source_handler(io, msg)
215
+ when "state"
216
+ state_file_handler(io, msg)
214
217
  when "cd"
215
218
  chdir_handler(io, msg)
216
219
  when "pwd"
@@ -416,6 +419,7 @@ class DTAS::Player # :nodoc:
416
419
  end while true
417
420
  ensure
418
421
  __current_requeue
422
+ stop_sinks
419
423
  trap(:CHLD, old_chld)
420
424
  sev.close if sev
421
425
  # for state file
@@ -1,7 +1,8 @@
1
- # -*- encoding: binary -*-
2
1
  # Copyright (C) 2013, Eric Wong <normalperson@yhbt.net> and all contributors
3
2
  # License: GPLv3 or later (https://www.gnu.org/licenses/gpl-3.0.txt)
3
+ require_relative '../xs'
4
4
  module DTAS::Player::ClientHandler # :nodoc:
5
+ include DTAS::XS
5
6
 
6
7
  # returns true on success, wait_ctl arg on error
7
8
  def set_bool(io, kv, v)
@@ -116,7 +117,7 @@ module DTAS::Player::ClientHandler # :nodoc:
116
117
  name = msg[1]
117
118
  case msg[0]
118
119
  when "ls"
119
- io.emit(Shellwords.join(@sinks.keys.sort))
120
+ io.emit(xs(@sinks.keys.sort))
120
121
  when "rm"
121
122
  sink = @sinks.delete(name) or return io.emit("ERR #{name} not found")
122
123
  drop_sink(sink)
@@ -384,7 +385,7 @@ module DTAS::Player::ClientHandler # :nodoc:
384
385
  def restart_pipeline
385
386
  return if @paused
386
387
  __current_requeue
387
- @targets.each { |t| drop_target(t) }.clear
388
+ stop_sinks
388
389
  end
389
390
 
390
391
  def format_handler(io, msg)
@@ -415,6 +416,14 @@ module DTAS::Player::ClientHandler # :nodoc:
415
416
  end
416
417
 
417
418
  def env_handler(io, msg)
419
+ if msg.empty?
420
+ # this may fail for large envs due to SEQPACKET size restrictions
421
+ # do we care?
422
+ env = ENV.map do |k,v|
423
+ "#{Shellwords.escape(k)}=#{Shellwords.escape(v)}"
424
+ end.join(' ')
425
+ return io.emit(env)
426
+ end
418
427
  msg.each do |kv|
419
428
  case kv
420
429
  when %r{\A([^=]+)=(.*)\z}
@@ -478,5 +487,26 @@ module DTAS::Player::ClientHandler # :nodoc:
478
487
  # echo(%W(cd msg[0])) # should we broadcast this?
479
488
  io.emit("OK")
480
489
  end
490
+
491
+ def state_file_handler(io, msg)
492
+ case msg.shift
493
+ when "dump"
494
+ dest = msg.shift
495
+ if dest
496
+ sf = DTAS::StateFile.new(dest, false)
497
+ elsif @state_file
498
+ sf = @state_file
499
+ dest = sf.path
500
+ else
501
+ return io.emit("ERR no state file configured")
502
+ end
503
+ begin
504
+ sf.dump(self)
505
+ rescue => e
506
+ return io.emit("ERR dumping to #{xs(Array(dest))} #{e.message}")
507
+ end
508
+ end
509
+ io.emit("OK")
510
+ end
481
511
  end
482
512
  # :startdoc: