module ExecSandbox::Wait4

Interface to the wait4 system call using the ffi library.

Constants

WNOHANG

Option passed to LibC::wait4.

Public Class Methods

wait4(pid) click to toggle source

Waits for a process to end, and collects its exit status and resource usage.

@param [Fixnum] pid the PID of the process to wait for; should be a child of

this process

@return [Hash] exit code and resource usage information

# File lib/exec_sandbox/wait4.rb, line 11
def self.wait4(pid)
  _wait4 pid, 0
end
wait4_nonblock(pid) click to toggle source

Collects a child process’ exit status and resource usage.

@param [Fixnum] pid the PID of the process to wait for; should be a child of

this process

@return [Hash] exit code and resource usage information; nil if the process

hasn't terminated
# File lib/exec_sandbox/wait4.rb, line 21
def self.wait4_nonblock(pid)
  _wait4 pid, WNOHANG
end

Private Class Methods

_wait4(pid, options) click to toggle source

@private

# File lib/exec_sandbox/wait4.rb, line 27
def _wait4(pid, options)
  status_ptr = FFI::MemoryPointer.new :int
  rusage = ExecSandbox::Wait4::Rusage.new
  returned_pid = LibC.wait4(pid, status_ptr, options, rusage.pointer)
  raise SystemCallError, FFI.errno if returned_pid < 0
  return nil if returned_pid == 0

  status = { bits: status_ptr.read_int }
  status_ptr.free

  signal_code = status[:bits] & 0x7f
  status[:exit_code] = (signal_code != 0) ? -signal_code : status[:bits] >> 8
  status[:user_time] = rusage[:ru_utime_sec] +
                       rusage[:ru_utime_usec] * 0.000_001
  status[:system_time] = rusage[:ru_stime_sec] +
                         rusage[:ru_stime_usec] * 0.000_001
  status[:rss] = rusage[:ru_maxrss] / 1024.0
  return status
end