Class: Sys::ProcTable

Inherits:
Object
  • Object
show all
Extended by:
FFI::Library
Defined in:
lib/freebsd/sys/proctable.rb,
lib/sys/proctable/version.rb

Defined Under Namespace

Classes: Error, KInfoProc, Pargs, Priority, ProcTableStruct, Rusage, Timeval

Constant Summary collapse

VERSION =

The version of the sys-proctable library

'1.1.1'.freeze

Class Method Summary collapse

Class Method Details

.fieldsObject

Returns an array of fields that each ProcTableStruct will contain. This may be useful if you want to know in advance what fields are available without having to perform at least one read of the /proc table.

Example:

Sys::ProcTable.fields.each{ |field|
   puts "Field: #{field}"
}


334
335
336
# File 'lib/freebsd/sys/proctable.rb', line 334

def self.fields
  @fields
end

.ps(pid = nil) ⇒ Object

In block form, yields a ProcTableStruct for each process entry that you have rights to. This method returns an array of ProcTableStruct’s in non-block form.

If a pid is provided, then only a single ProcTableStruct is yielded or returned, or nil if no process information is found for that pid.

Example:

# Iterate over all processes
ProcTable.ps do |proc_info|
   p proc_info
end

# Print process table information for only pid 1001
p ProcTable.ps(1001)


199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
# File 'lib/freebsd/sys/proctable.rb', line 199

def self.ps(pid = nil)
  begin
    kd = kvm_open(nil, nil, nil, 0, nil)

    if kd.null?
      raise SystemCallError.new('kvm_open', FFI.errno)
    end

    ptr = FFI::MemoryPointer.new(:int) # count

    if pid
      procs = kvm_getprocs(kd, KERN_PROC_PID, pid, ptr)
    else
      procs = kvm_getprocs(kd, KERN_PROC_PROC, 0, ptr)
    end

    if procs.null?
      if pid && FFI.errno == Errno::ESRCH::Errno
        return nil
      else
        raise SystemCallError.new('kvm_getprocs', FFI.errno)
      end
    end

    count = ptr.read_int
    array = []

    0.upto(count-1){ |i|
      cmd = nil
      kinfo = KInfoProc.new(procs[i * KInfoProc.size])

      args = kvm_getargv(kd, kinfo, 0)

      unless args.null?
        cmd = []

        until ((ptr = args.read_pointer).null?)
          cmd << ptr.read_string
          args += FFI::Type::POINTER.size
        end

        cmd = cmd.join(' ')
      end

      struct = ProcTableStruct.new(
        kinfo[:ki_pid],
        kinfo[:ki_ppid],
        kinfo[:ki_pgid],
        kinfo[:ki_tpgid],
        kinfo[:ki_sid],
        kinfo[:ki_tsid],
        kinfo[:ki_jobc],
        kinfo[:ki_uid],
        kinfo[:ki_ruid],
        kinfo[:ki_rgid],
        kinfo[:ki_ngroups],
        kinfo[:ki_groups].to_a[0...kinfo[:ki_ngroups]],
        kinfo[:ki_size],
        kinfo[:ki_rssize],
        kinfo[:ki_swrss],
        kinfo[:ki_tsize],
        kinfo[:ki_dsize],
        kinfo[:ki_ssize],
        kinfo[:ki_xstat],
        kinfo[:ki_acflag],
        kinfo[:ki_pctcpu].to_f,
        kinfo[:ki_estcpu],
        kinfo[:ki_slptime],
        kinfo[:ki_swtime],
        kinfo[:ki_runtime],
        Time.at(kinfo[:ki_start][:tv_sec]),
        kinfo[:ki_flag],
        get_state(kinfo[:ki_stat]),
        kinfo[:ki_nice],
        kinfo[:ki_lock],
        kinfo[:ki_rqindex],
        kinfo[:ki_oncpu],
        kinfo[:ki_lastcpu],
        kinfo[:ki_wmesg].to_s,
        kinfo[:ki_login].to_s,
        kinfo[:ki_lockname].to_s,
        kinfo[:ki_comm].to_s,
        kinfo[:ki_tdev],
        devname(kinfo[:ki_tdev], S_IFCHR),
        kinfo[:ki_jid],
        kinfo[:ki_pri][:pri_level],
        kinfo[:ki_pri][:pri_user],
        cmd,
        kinfo[:ki_rusage][:ru_utime][:tv_sec],
        kinfo[:ki_rusage][:ru_stime][:tv_sec],
        kinfo[:ki_rusage][:ru_maxrss],
        kinfo[:ki_rusage][:ru_ixrss],
        kinfo[:ki_rusage][:ru_idrss],
        kinfo[:ki_rusage][:ru_isrss],
        kinfo[:ki_rusage][:ru_minflt],
        kinfo[:ki_rusage][:ru_majflt],
        kinfo[:ki_rusage][:ru_nswap],
        kinfo[:ki_rusage][:ru_inblock],
        kinfo[:ki_rusage][:ru_oublock],
        kinfo[:ki_rusage][:ru_msgsnd],
        kinfo[:ki_rusage][:ru_msgrcv],
        kinfo[:ki_rusage][:ru_nsignals],
        kinfo[:ki_rusage][:ru_nvcsw],
        kinfo[:ki_rusage][:ru_nivcsw]
      )

      struct.freeze # This is readonly data

      if block_given?
        yield struct
      else
        array << struct
      end
    }
  ensure
    kvm_close(kd) unless kd.null?
  end

  if block_given?
    nil
  else
    pid ? array.first : array
  end
end