def run(command, options = {})
    limits = options[:limits] || {}
    
    io = {}
    if options[:in]
      io[:in] = options[:in]
      in_rd = nil
    else
      in_rd, in_wr = IO.pipe
      in_wr.write options[:in_data] if options[:in_data]
      in_wr.close
      io[:in] = in_rd
    end
    if options[:out]
      io[:out] = options[:out]
    else
      out_rd, out_wr = IO.pipe
      io[:out] = out_wr
    end
    case options[:err]
    when :out
      io[:err] = STDOUT
    when :none
      # Don't set io[:err], so the child's stderr will be closed.
    else
      io[:err] = STDERR
    end
    
    pid = ExecSandbox::Spawn.spawn command, io, @principal, limits
    # Close the pipe ends that are meant to be used in the child.
    in_rd.close if in_rd
    out_wr.close if out_wr
    
    # Collect information about the child.
    if out_rd
      out_pieces = []
      out_pieces << out_rd.read rescue nil
    end
    status = ExecSandbox::Wait4.wait4 pid
    if out_rd
      out_pieces << out_rd.read rescue nil
      out_rd.close
      status[:out_data] = out_pieces.join('')
    end
    status
  end
def run(command, options = {})
    limits = options[:limits] || {}
    
    io = {}
    if options[:in]
      io[:in] = options[:in]
      in_rd = nil
    else
      in_rd, in_wr = IO.pipe
      in_wr.write options[:in_data] if options[:in_data]
      in_wr.close
      io[:in] = in_rd
    end
    if options[:out]
      io[:out] = options[:out]
    else
      out_rd, out_wr = IO.pipe
      io[:out] = out_wr
    end
    case options[:err]
    when :out
      io[:err] = STDOUT
    when :none
      # Don't set io[:err], so the child's stderr will be closed.
    else
      io[:err] = STDERR
    end
    
    pid = ExecSandbox::Spawn.spawn command, io, @principal, limits
    # Close the pipe ends that are meant to be used in the child.
    in_rd.close if in_rd
    out_wr.close if out_wr
    
    # Collect information about the child.
    if out_rd
      out_pieces = []
      out_pieces << out_rd.read rescue nil
    end
    status = ExecSandbox::Wait4.wait4 pid
    if out_rd
      out_pieces << out_rd.read rescue nil
      out_rd.close
      status[:out_data] = out_pieces.join('')
    end
    status
  end
Runs a command in the sandbox.

 @param [Array, String] command to be run; use an array to pass arguments to
                        the command
 @param [Hash] options stdin / stdout redirection and resource limitations
 @option options [Hash] :limits see {Spawn.limit_resources}
 @option options [String] :in path to a file that is set as the child's stdin
 @option options [String] :in_data contents to be written to a pipe that is
     set as the child's stdin; if neither :in nor :in_data are specified, the
     child will receive the read end of an empty pipe
 @option options [String] :out path to a file that is set as the child's
     stdout; if not set, the child will receive the write end of a pipe whose
     contents is returned in :out_data
 @option options [Symbol] :err :none closes the child's stderr, :out
     redirects the child's stderr to stdout; by default, the child's stderr
     is the same as the parent's
 @return [Hash] the result of {Wait4.wait4}, plus an :out_data key if no :out
                option is given