Class: HrrRbSsh::Connection::RequestHandler::ReferencePtyReqRequestHandler

Inherits:
HrrRbSsh::Connection::RequestHandler show all
Defined in:
lib/hrr_rb_ssh/connection/request_handler/reference_pty_req_request_handler.rb

Instance Method Summary collapse

Methods inherited from HrrRbSsh::Connection::RequestHandler

#run

Constructor Details

#initializeReferencePtyReqRequestHandler

Returns a new instance of ReferencePtyReqRequestHandler.



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
# File 'lib/hrr_rb_ssh/connection/request_handler/reference_pty_req_request_handler.rb', line 15

def initialize
  @logger = Logger.new self.class.name
  @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.logger.info { "ptm is EOF in ptm_read_thread" }
                break
              rescue IOError => e
                context.logger.warn { "IO Error in ptm_read_thread" }
                break
              rescue Errno::EIO => e
                context.logger.info { "EIO Error in ptm_read_thread" }
                break
              rescue => e
                context.logger.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.logger.info { "IO is EOF in ptm_write_thread" }
                break
              rescue IOError => e
                context.logger.warn { "IO Error in ptm_write_thread" }
                break
              rescue Errno::EIO => e
                context.logger.info { "EIO Error in ptm_read_thread" }
                break
              rescue => e
                context.logger.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.vars[:ptm].close rescue nil
          context.vars[:pts].close rescue nil
          begin
            ptm_read_thread.join
          rescue => e
            context.logger.error { [e.backtrace[0], ": ", e.message, " (", e.class.to_s, ")\n\t", e.backtrace[1..-1].join("\n\t")].join }
          end
          begin
            ptm_write_thread.exit
            ptm_write_thread.join
          rescue => e
            context.logger.error { [e.backtrace[0], ": ", e.message, " (", e.class.to_s, ")\n\t", e.backtrace[1..-1].join("\n\t")].join }
          end
        end
      }
    rescue => e
      ptm.close rescue nil
      pts.close rescue nil
      context.chain_proc{ |chain|
        exitstatus = 1
      }
      raise e
    end
  }
end