module PTY

Constants

Buffer

Public Class Methods

# File samples/pty.rb, line 20
def self.build_args(args)
  cmd = args.shift
  cmd_args = args.map do |arg|
    MemoryPointer.from_string(arg)
  end
  exec_args = MemoryPointer.new(:pointer, 1 + cmd_args.length + 1)
  exec_cmd = MemoryPointer.from_string(cmd)
  exec_args[0].put_pointer(0, exec_cmd)
  cmd_args.each_with_index do |arg, i|
    exec_args[i + 1].put_pointer(0, arg)
  end
  [ cmd, exec_args ]
end
# File samples/pty.rb, line 34
def self.getpty(*args)
  mfdp = Buffer.new :int
  name = Buffer.new 1024
  #
  # All the execv setup is done in the parent, since doing anything other than
  # execv in the child after fork is really flakey
  #
  exec_cmd, exec_args = build_args(args)
  pid = LibC.forkpty(mfdp, name, nil, nil)
  raise "forkpty failed: #{LibC.strerror(FFI.errno)}" if pid < 0
  if pid == 0
    LibC.execvp(exec_cmd, exec_args)
    exit 1
  end
  masterfd = mfdp.get_int(0)
  rfp = FFI::IO.for_fd(masterfd, "r")
  wfp = FFI::IO.for_fd(LibC.dup(masterfd), "w")
  if block_given?
    yield rfp, wfp, pid
    rfp.close unless rfp.closed?
    wfp.close unless wfp.closed?
  else
    [ rfp, wfp, pid ]
  end
end
# File samples/pty.rb, line 59
def self.spawn(*args, &block)
  self.getpty("/bin/sh", "-c", args[0], &block)
end