# File lib/mcollective/shell.rb, line 71
    def runcommand
      opts = {"env"    => @environment,
              "stdout" => @stdout,
              "stderr" => @stderr,
              "cwd"    => @cwd}

      opts["stdin"] = @stdin if @stdin


      thread = Thread.current
      # Start a double fork and exec with systemu which implies a guard thread.
      # If a valid timeout is configured the guard thread will terminate the
      # executing process and reap the pid.
      # If no timeout is specified the process will run to completion with the
      # guard thread reaping the pid on completion.
      @status = systemu(@command, opts) do |cid|
        begin
          if timeout.is_a?(Fixnum)
            # wait for the specified timeout
            sleep timeout
          else
            # sleep while the agent thread is still alive
            while(thread.alive?)
              sleep 0.1
            end
          end

          # if the process is still running
          if (Process.kill(0, cid))
            # and a timeout was specified
            if timeout
              if Util.windows?
                Process.kill('KILL', cid)
              else
                # Kill the process
                Process.kill('TERM', cid)
                sleep 2
                Process.kill('KILL', cid) if (Process.kill(0, cid))
              end
            end
            # only wait if the parent thread is dead
            Process.waitpid(cid) unless thread.alive?
          end
        rescue SystemExit
        rescue Errno::ESRCH
        rescue Errno::ECHILD
          Log.warn("Could not reap process '#{cid}'.")
        rescue Exception => e
          Log.info("Unexpected exception received while waiting for child process: #{e.class}: #{e}")
        end
      end
      @status.thread.kill
      @status
    end