module Process

def getrlimit(resource)


once within the same program would fail.
be associated with the job. In other words, trying to call it more than
it unavailable within the same process again since it would no longer
at the end of the block, while marking it for closure, would also make
to close a job handle. This is necessary because simply calling it
NOTE: Both the getrlimit and setrlimit method use an at_exit handler
--
Process.getrlimit(Process::RLIMIT_VMEM) # => [0, 0]

Example:

If [0,0] is returned then it means no limit has been set.

same.
there is no separate hard and soft limit. The values will always be the
While a two element array is returned in order to comply with the spec,

approximately 4TB (or 4GB if not NTFS).
constant is hard coded to the maximum file size on an NTFS filesystem,
refers to the per process user time limit. The Process::RLIMIT_FSIZE
all refer to the Process memory limit. The Process::RLIMIT_CPU constant
The Process:RLIMIT_AS, Process::RLIMIT_RSS and Process::VMEM constants

Process::RLIMIT_VMEM
Process::RLIMIT_RSS
Process::RLIMIT_AS
Process::RLIMIT_FSIZE
Process::RLIMIT_CPU

of flags are supported.
Gets the resource limit of the current process. Only a limited number
def getrlimit(resource)
  if resource == RLIMIT_FSIZE
    if volume_type == "NTFS"
      return ((1024**4) * 4) - (1024 * 64) # ~ 4TB
    else
      return (1024**3) * 4 # 4 GB
    end
  end
  handle = nil
  in_job = Process.job?
  # Put the current process in a job if it's not already in one
  if in_job && defined?(@win32_process_job_name)
    handle = OpenJobObjectA(JOB_OBJECT_QUERY, 1, @win32_process_job_name)
    raise SystemCallError, FFI.errno, "OpenJobObject" if handle == 0
  else
    @win32_process_job_name = "ruby_" + Process.pid.to_s
    handle = CreateJobObjectA(nil, @win32_process_job_name)
    raise SystemCallError, FFI.errno, "CreateJobObject" if handle == 0
  end
  begin
    unless in_job
      unless AssignProcessToJobObject(handle, GetCurrentProcess())
        raise Error, get_last_error
      end
    end
    ptr = JOBJECT_EXTENDED_LIMIT_INFORMATION.new
    val = nil
    # Set the LimitFlags member of the struct
    case resource
      when RLIMIT_CPU
        ptr[:BasicLimitInformation][:LimitFlags] = JOB_OBJECT_LIMIT_PROCESS_TIME
      when RLIMIT_AS, RLIMIT_VMEM, RLIMIT_RSS
        ptr[:BasicLimitInformation][:LimitFlags] = JOB_OBJECT_LIMIT_PROCESS_MEMORY
      else
        raise ArgumentError, "unsupported resource type: '#{resource}'"
    end
    bool = QueryInformationJobObject(
      handle,
      JobObjectExtendedLimitInformation,
      ptr,
      ptr.size,
      nil
    )
    unless bool
      raise SystemCallError, FFI.errno, "QueryInformationJobObject"
    end
    case resource
      when Process::RLIMIT_CPU
        val = ptr[:BasicLimitInformation][:PerProcessUserTimeLimit][:QuadPart]
      when RLIMIT_AS, RLIMIT_VMEM, RLIMIT_RSS
        val = ptr[:ProcessMemoryLimit]
    end
  ensure
    at_exit { CloseHandle(handle) if handle }
  end
  [val, val]
end