class HrrRbSsh::Connection::RequestHandler::ReferenceExecRequestHandler

Public Class Methods

new() click to toggle source
# File lib/hrr_rb_ssh/connection/request_handler/reference_exec_request_handler.rb, line 11
def initialize
  @proc = Proc.new { |context|
    ptm = context.vars[:ptm]
    pts = context.vars[:pts]

    context.chain_proc { |chain|
      passwd = Etc.getpwnam(context.username)

      env = context.vars.fetch(:env, Hash.new)
      env['USER']  = passwd.name
      env['HOME']  = passwd.dir
      env['SHELL'] = passwd.shell

      program = context.command

      args = Array.new

      options = Hash.new
      options[:unsetenv_others] = true
      options[:close_others] = true
      unless ptm
        options[:in]  = context.io[0]
        options[:out] = context.io[1]
        options[:err] = context.io[2]
      end

      pid = fork do
        Process.setsid
        Dir.chdir passwd.dir
        Process::GID.change_privilege passwd.gid
        Process::UID.change_privilege passwd.uid
        if ptm
          STDIN.reopen  pts, 'r'
          STDOUT.reopen pts, 'w'
          STDERR.reopen pts, 'w'
          pts.close
        end
        exec env, program, *args, options
      end

      unless ptm
        pid, status = Process.waitpid2 pid
        status.exitstatus
      else
        pts.close

        begin
          pid, status = Process.waitpid2 pid
          context.log_info { "program exited with status #{status.inspect}" }
          status.exitstatus
        ensure
          unless status
            context.log_info { "exiting program" }
            Process.kill :TERM, pid
            begin
              Timeout.timeout(1) do
                pid, status = Process.waitpid2 pid
              end
            rescue Timeout::Error
              context.log_warn { "force exiting program" }
              Process.kill :KILL, pid
              pid, status = Process.waitpid2 pid
            end
            context.log_info { "program exited with status #{status.inspect}" }
          end
        end
      end
    }
  }
end