hirura/hrr_rb_ssh

View on GitHub
lib/hrr_rb_ssh/connection/request_handler/reference_pty_req_request_handler.rb

Summary

Maintainability
C
1 day
Test Coverage
require 'hrr_rb_ssh/connection/request_handler'

module HrrRbSsh
  class Connection
    class RequestHandler
      class ReferencePtyReqRequestHandler < RequestHandler
        def initialize
          @proc = Proc.new { |context|
            begin
              ptm, pts = PTY.open
              passwd = Etc.getpwnam(context.username)
              FileUtils.chown passwd.uid, -1, pts
              FileUtils.chmod 'u+rw,g+w', pts
              ptm.winsize = [context.terminal_height_rows, context.terminal_width_characters, context.terminal_width_pixels, context.terminal_height_pixels]
              context.vars[:ptm] = ptm
              context.vars[:pts] = pts
              context.vars[:env] ||= Hash.new
              context.vars[:env]['TERM'] = context.term_environment_variable_value
              context.chain_proc { |chain|
                begin
                  ptm_read_thread = Thread.start {
                    loop do
                      begin
                        context.io[1].write ptm.readpartial(10240)
                      rescue EOFError => e
                        context.log_info { "ptm is EOF in ptm_read_thread" }
                        break
                      rescue IOError => e
                        context.log_warn { "IO Error in ptm_read_thread" }
                        break
                      rescue Errno::EIO => e
                        context.log_info { "EIO Error in ptm_read_thread" }
                        break
                      rescue => e
                        context.log_error { [e.backtrace[0], ": ", e.message, " (", e.class.to_s, ")\n\t", e.backtrace[1..-1].join("\n\t")].join }
                        break
                      end
                    end
                  }
                  ptm_write_thread = Thread.start {
                    loop do
                      begin
                        ptm.write context.io[0].readpartial(10240)
                      rescue EOFError => e
                        context.log_info { "IO is EOF in ptm_write_thread" }
                        break
                      rescue IOError => e
                        context.log_warn { "IO Error in ptm_write_thread" }
                        break
                      rescue Errno::EIO => e
                        context.log_info { "EIO Error in ptm_read_thread" }
                        break
                      rescue => e
                        context.log_error { [e.backtrace[0], ": ", e.message, " (", e.class.to_s, ")\n\t", e.backtrace[1..-1].join("\n\t")].join }
                        break
                      end
                    end
                  }
                  chain.call_next
                ensure
                  context.log_info { "closing pty-req request handler chain_proc" }
                  context.vars[:ptm].close rescue nil
                  context.vars[:pts].close rescue nil
                  ptm_read_thread.join
                  ptm_write_thread.exit
                  ptm_write_thread.join
                  context.log_info { "pty-req request handler chain_proc closed" }
                end
              }
            rescue => e
              ptm.close rescue nil
              pts.close rescue nil
              context.chain_proc{ |chain|
                exitstatus = 1
              }
              raise e
            end
          }
        end
      end
    end
  end
end