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 |
# 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 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 e.is_a?(Errno::EAGAIN) retry else system("stty -raw echo") if new? puts 'Terminating Pssh.' Kernel.exit! 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
64 65 66 67 |
# File 'lib/pssh/pty.rb', line 64 def clear_environment ENV['TMUX'] = nil ENV['STY'] = nil end |
#existing? ⇒ Boolean
73 74 75 |
# File 'lib/pssh/pty.rb', line 73 def existing? @existing_socket end |
#new? ⇒ Boolean
69 70 71 |
# File 'lib/pssh/pty.rb', line 69 def new? !existing? end |
#resize! ⇒ Object
Public: Resizes the PTY session based on all the open windows.
Returns nothing.
117 118 119 120 121 122 123 |
# File 'lib/pssh/pty.rb', line 117 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.
129 130 131 132 133 134 135 136 137 138 |
# File 'lib/pssh/pty.rb', line 129 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
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 |
# File 'lib/pssh/pty.rb', line 77 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.
144 145 146 147 |
# File 'lib/pssh/pty.rb', line 144 def store(data) @stream << data @stream = @stream[-Pssh.cache_length..-1] if @stream.length > Pssh.cache_length end |