Class: Pssh::Pty
- Inherits:
-
Object
- Object
- Pssh::Pty
- Defined in:
- lib/pssh/pty.rb
Instance Attribute Summary collapse
-
#attach_cmd ⇒ Object
readonly
Returns the value of attribute attach_cmd.
-
#path ⇒ Object
readonly
Returns the value of attribute path.
-
#pid ⇒ Object
readonly
Returns the value of attribute pid.
-
#read ⇒ Object
readonly
Returns the value of attribute read.
-
#stream ⇒ Object
readonly
attr_reader :write.
Instance Method Summary collapse
- #clear_environment ⇒ Object
- #existing? ⇒ Boolean
-
#initialize ⇒ Pty
constructor
A new instance of Pty.
- #new? ⇒ Boolean
-
#resize! ⇒ Object
Public: Resizes the PTY session based on all the open windows.
-
#send_display_message(user) ⇒ Object
Public: Sends a message to the tmux or screen display notifying of a new user that has connected.
- #set_command ⇒ Object
-
#store(data) ⇒ Object
Internal: Store data to the stream so that when a new connection is started we can send all that data and give them the visual.
-
#write(data) ⇒ Object
Public: Writes to the open stream if they have access.
Constructor Details
#initialize ⇒ Pty
Returns a new instance of Pty.
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 |
# File 'lib/pssh/pty.rb', line 12 def initialize @stream = '' set_command clear_environment Thread.new do begin @read, @write, @pid = PTY.spawn(@command) @write.winsize = $stdout.winsize if new? system("clear") pssh = <<-BANNER # [ pssh terminal ] # Type `exit` to terminate this terminal. BANNER $stdout.puts pssh Signal.trap(:WINCH) do resize! end system("stty raw -echo") end @active = true while @active do begin io = [@read] io << $stdin if new? rs, ws = IO.select(io) r = rs[0] while (data = r.read_nonblock(2048)) do if new? && r == $stdin @write.write_nonblock data else $stdout.write_nonblock data if new? data.encode!('UTF-16', 'UTF-8', :invalid => :replace, :replace => '') data.encode!('UTF-8', 'UTF-16') if data.valid_encoding? store data Pssh.socket.write data end end end rescue Exception => e if @active if e.is_a?(Errno::EAGAIN) retry else system("stty -raw echo") if new? puts 'Terminating Pssh.' Kernel.exit! @active = false end end end end end end end |
Instance Attribute Details
#attach_cmd ⇒ Object (readonly)
Returns the value of attribute attach_cmd.
10 11 12 |
# File 'lib/pssh/pty.rb', line 10 def attach_cmd @attach_cmd end |
#path ⇒ Object (readonly)
Returns the value of attribute path.
9 10 11 |
# File 'lib/pssh/pty.rb', line 9 def path @path end |
#pid ⇒ Object (readonly)
Returns the value of attribute pid.
7 8 9 |
# File 'lib/pssh/pty.rb', line 7 def pid @pid end |
#read ⇒ Object (readonly)
Returns the value of attribute read.
4 5 6 |
# File 'lib/pssh/pty.rb', line 4 def read @read end |
#stream ⇒ Object (readonly)
attr_reader :write
6 7 8 |
# File 'lib/pssh/pty.rb', line 6 def stream @stream end |
Instance Method Details
#clear_environment ⇒ Object
69 70 71 72 |
# File 'lib/pssh/pty.rb', line 69 def clear_environment ENV['TMUX'] = nil ENV['STY'] = nil end |
#existing? ⇒ Boolean
78 79 80 |
# File 'lib/pssh/pty.rb', line 78 def existing? @existing_socket end |
#new? ⇒ Boolean
74 75 76 |
# File 'lib/pssh/pty.rb', line 74 def new? !existing? end |
#resize! ⇒ Object
Public: Resizes the PTY session based on all the open windows.
Returns nothing.
122 123 124 125 126 127 128 |
# File 'lib/pssh/pty.rb', line 122 def resize! winsizes = Pssh.socket.sessions.values.map { |sess| sess[:winsize] } winsizes << $stdout.winsize if new? y = winsizes.map { |w| w[0] }.min x = winsizes.map { |w| w[1] }.min @write.winsize = [ y, x ] end |
#send_display_message(user) ⇒ Object
Public: Sends a message to the tmux or screen display notifying of a new user that has connected.
Returns nothing.
134 135 136 137 138 139 140 141 142 143 |
# File 'lib/pssh/pty.rb', line 134 def (user) if @existing_socket case Pssh.command.to_sym when :tmux `tmux -S #{@path} display-message "#{user} has connected"` when :screen `screen -S #{@path} -X wall "#{user} has connected"` end end end |
#set_command ⇒ Object
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 |
# File 'lib/pssh/pty.rb', line 82 def set_command case Pssh.command.to_sym when :tmux if ENV['TMUX'] @path = ENV['TMUX'].split(',').first @existing_socket = true @command = "tmux -S #{@path} attach" else @path = "/tmp/#{Pssh.default_socket_path}" @command = "tmux -S #{@path} new" end @attach_cmd = "tmux -S #{@path} attach" when :screen if ENV['STY'] @path = ENV['STY'] @existing_socket = true @command = "screen -S #{@path} -X multiuser on && screen -x #{@path}" else @path = Pssh.default_socket_path @command = "screen -S #{@path}" puts @command end @attach_cmd = "screen -x #{@path}" else @path = nil @command = ENV['SHELL'] || (`which zsh` && 'zsh') || (`which sh` && 'sh') || 'bash' end end |
#store(data) ⇒ Object
Internal: Store data to the stream so that when a new connection is started we can send all that data and give them the visual.
Returns nothing.
149 150 151 152 |
# File 'lib/pssh/pty.rb', line 149 def store(data) @stream << data @stream = @stream[-Pssh.cache_length..-1] if @stream.length > Pssh.cache_length end |