Class: PosixPsutil::Process

Inherits:
Object
  • Object
show all
Includes:
POSIX
Defined in:
lib/posixpsutil/process.rb

Overview

Warning: There is already a Process module in ruby, so don’t confuse it with this PosixPsutil::Process. And take care of ‘include PosixPsutil`, unless you have clearly considered about it.

Constant Summary collapse

@@pmap =
{}
@@total_phymem =
nil

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Methods included from POSIX

#check_timeout, #wait_pid

Constructor Details

#initialize(pid = nil) ⇒ Process

initialize a Process instance with pid, if not pid given, initialize it with current process’s pid.

Raises:

  • (ArgumentError)


136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
# File 'lib/posixpsutil/process.rb', line 136

def initialize(pid=nil)
  pid = ::Process.pid unless pid
  @pid = pid
  raise ArgumentError.new("pid must be 
                          a positive integer (got #{@pid})") if @pid <= 0
  @name = nil
  @exe = nil
  @create_time = nil 
  @gone = false
  @proc = PlatformSpecificProcess.new(@pid)
  # for cpu_percent
  @last_sys_cpu_times = nil
  @last_proc_cpu_times = nil
  begin
    create_time
  rescue AccessDenied
    # we should never get here as AFAIK we're able to get
    # process creation time on all platforms even as a
    # limited user
  rescue NoSuchProcess
    msg = "no process found with pid #{@pid}"
    raise NoSuchProcess.new(pid:@pid, msg:msg)
  end
  # This part is supposed to indentify a Process instance
  # univocally over time (the PID alone is not enough as
  # it might refer to a process whose PID has been reused).
  # This will be used later in == and is_running().
  @identity = [@pid, @create_time]
end

Instance Attribute Details

#identityObject (readonly)

Returns the value of attribute identity.



59
60
61
# File 'lib/posixpsutil/process.rb', line 59

def identity
  @identity
end

#pidObject (readonly)

Returns the value of attribute pid.



60
61
62
# File 'lib/posixpsutil/process.rb', line 60

def pid
  @pid
end

Class Method Details

.pid_exists(pid) ⇒ Object

Return true if given PID exists in the current process list. This is faster than doing “pid in psutil.pids()” and should be preferred.



72
73
74
# File 'lib/posixpsutil/process.rb', line 72

def self.pid_exists(pid)
  POSIX::pid_exists(pid)
end

.pidsObject

Return an Array of current running PIDs.



65
66
67
# File 'lib/posixpsutil/process.rb', line 65

def self.pids
  PlatformSpecificProcess.pids()
end

.process_iterObject

Like self.processes(), but return next Process instance in each iteration. To imitate Python’s iterator, use Enumerator to implement this method, which means it will raise StopIteration when it reaches the end.



114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
# File 'lib/posixpsutil/process.rb', line 114

def self.process_iter
  processes = []
  pids().each do |pid|
    begin
      unless @@pmap.key?(pid) && @@pmap[pid].is_running
        p = Process.new(pid)
        @@pmap[p.pid] = p
      end
      processes.push @@pmap[pid]
    rescue NoSuchProcess
      @@pmap.delete(pid)
    rescue AccessDenied
      next
    end
  end
  processes.to_enum
end

.processesObject

Return all Process instances for all running processes.

Every new Process instance is only created once and then cached into an internal table which is updated every time this is used.

Cached Process instances are checked for identity so that you’re safe in case a PID has been reused by another process, in which case the cached instance is updated.



88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
# File 'lib/posixpsutil/process.rb', line 88

def self.processes
  pre_pids = @@pmap.keys
  cur_pids = pids()
  gone_pids = pre_pids - cur_pids
  
  gone_pids.each { |pid| @@pmap.delete(pid) }
  cur_pids.each do |pid|
    begin
      unless @@pmap.key?(pid) && @@pmap[pid].is_running
        p = Process.new(pid)
        @@pmap[p.pid] = p
      end
    rescue NoSuchProcess
      @@pmap.delete(pid)
    rescue AccessDenied
      # Process creation time can't be determined hence there's
      # no way to tell whether the pid of the cached process
      next
    end
  end
  @@pmap.values
end

Instance Method Details

#!=(other) ⇒ Object



189
190
191
# File 'lib/posixpsutil/process.rb', line 189

def !=(other)
  return !(self == other)
end

#==(other) ⇒ Object Also known as: eql?

Test for equality with another Process object based on PID and creation time.



184
185
186
# File 'lib/posixpsutil/process.rb', line 184

def ==(other)
  return self.class == other.class && @identity == other.identity
end

#children(recursive = false) ⇒ Object

Return the children of this process as a list of Process instances, pre-emptively checking whether PID has been reused. If recursive is true return all the parent descendants.

Example (A == this process):

A 


567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
# File 'lib/posixpsutil/process.rb', line 567

def children(recursive = false)
  ret = []
  if recursive
    # construct a hash where 'values'(an Array) are all the processes
    # having 'key' as their parent
    table = {}
    self.class.processes.each do |p|
      begin
        ppid = p.ppid
        (table.key? ppid)? table[ppid].push(p) : table[ppid] = [p]
      rescue NoSuchProcess
        next
      end
    end

    # At this point we have a mapping table where table[self.pid]
    # are the current process' children.
    # Below, we look for all descendants recursively, similarly
    # to a recursive function call.
    checkpids = [@pid]
    checkpids.each do |pid|
      next unless table.key? pid
      table[pid].each do |child|
        begin
          # if child happens to be older than its parent,
          # it means child's PID has been reused
          intime = (create_time() <= child.create_time())
        rescue NoSuchProcess
          next
        end
        if intime
          ret.push(child)
          checkpids.push(child.pid) unless checkpids.include?(child.pid)
        end
      end
    end

  else
    self.class.processes().each do |p|
      begin
        ret.push(p) if p.ppid == @pid && create_time() <= p.create_time()
      rescue NoSuchProcess
        next
      end
    end

  end

  ret
end

#cmdlineObject

The command line this process has been called with. An array will be returned



330
331
332
# File 'lib/posixpsutil/process.rb', line 330

def cmdline
  @proc.cmdline()
end

#connections(interface = :inet) ⇒ Object

Return connections opened by process as a list of #<OpenStruct fd, family, type, laddr, raddr, status> The ‘kind’ parameter filters for connections that match the following criteria:

Kind Value Connections using :inet IPv4 and IPv6 :inet4 IPv4 :inet6 IPv6 :tcp TCP :tcp4 TCP over IPv4 :tcp6 TCP over IPv6 :udp UDP :udp4 UDP over IPv4 :udp6 UDP over IPv6 :unix UNIX socket (both UDP and TCP protocols) :all the sum of all the possible families and protocols



773
774
775
# File 'lib/posixpsutil/process.rb', line 773

def connections(interface = :inet)
  @proc.connections(interface)
end

#cpu_affinity(cpus = nil) ⇒ Object

Get or set process CPU affinity. If specified ‘cpus’ must be a list of CPUs for which you want to set the affinity (e.g. [0, 1]).

If ‘cpus’ is not an Array, an ArgumentError will be raised, if the length of ‘cpus’ larger than the number of CPUs, the remain will be ignore.



516
517
518
519
520
521
522
523
524
# File 'lib/posixpsutil/process.rb', line 516

def cpu_affinity(cpus=nil)
  if cpus.nil?
    @proc.cpu_affinity
  elsif cpus.is_a?(Array)
    @proc.cpu_affinity=(cpus)
  else
    raise ArgumentError.new("cpus must be an Array, got #{cpus}")
  end
end

#cpu_percent(interval = nil) ⇒ Object

Return a float representing the current process CPU utilization as a percentage.

When interval is <= 0.0 or nil (default) compares process times to system CPU times elapsed since last call, returning immediately (non-blocking). That means that the first time this is called it will return a meaningful 0.0 value.

When interval is > 0.0 compares process times to system CPU times elapsed before and after the interval.

In this case is recommended for accuracy that this function be called with at least 0.1 seconds between calls.

Examples:

require 'posixpsutil'

p = PosixPsutil::Process.new(Process.pid)
# blocking
p.cpu_percent(1)
# 2.0

# non-blocking (percentage since last call)
p.cpu_percent
# 2.9

p = PosixPsutil::Process.new(4527)
# first called
p.cpu_percent
# 0.0

# second called
p.cpu_percent
# 0.5


654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
# File 'lib/posixpsutil/process.rb', line 654

def cpu_percent(interval = nil)
  blocking = (interval && interval > 0.0)
  num_cpus = CPU.cpu_count()
  timer = proc { Time.now.to_f * num_cpus }
  if blocking
    st1 = timer.call
    pt1 = @proc.cpu_times
    sleep interval
    st2 = timer.call
    pt2 = @proc.cpu_times
  else
    st1 = @last_sys_cpu_times
    pt1 = @last_proc_cpu_times
    st2 = timer.call
    pt2 = @proc.cpu_times
    # first called
    if st1.nil? || pt1.nil?
      @last_sys_cpu_times = st2
      @last_proc_cpu_times = pt2
      return 0.0
    end
  end

  delta_proc = (pt2.user - pt1.user) + (pt2.system - pt1.system)
  delta_time = st2 - st1
  # reset values for next call in case of interval == None
  @last_sys_cpu_times = st2
  @last_proc_cpu_times = pt2

  begin
    # The utilization split between all CPUs.
    # Note: a percentage > 100 is legitimate as it can result
    # from a process with multiple threads running on different
    # CPU cores, see:
    # http://stackoverflow.com/questions/1032357
    # https://github.com/giampaolo/psutil/issues/474
    overall_percent = ((delta_proc / delta_time) * 100) * num_cpus
    return overall_percent.round(1)
  rescue ZeroDivisionError
    # interval was too low
    return 0.0
  end
end

#cpu_timesObject

Return a #<OpenStruct user, system> representing the accumulated process time, in seconds.



351
352
353
# File 'lib/posixpsutil/process.rb', line 351

def cpu_times
  @proc.cpu_times
end

#create_timeObject

The process creation time as a floating point number expressed in seconds since the epoch, in UTC. The return value is cached after first call.



358
359
360
361
362
363
# File 'lib/posixpsutil/process.rb', line 358

def create_time
  if @create_time.nil?
    @create_time = @proc.create_time
  end
  @create_time
end

#cwdObject

Process current working directory as an absolute path.



371
372
373
# File 'lib/posixpsutil/process.rb', line 371

def cwd
  @proc.cwd
end

#exeObject

The process executable as an absolute path. May also be an empty string. The return value is cached after first call.



303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
# File 'lib/posixpsutil/process.rb', line 303

def exe
  if !@exe
    begin
      @exe = @proc.exe()
    rescue AccessDenied => e
      @exe = ''
      fallback = e
    end

    if @exe == ''
      cmdline = self.cmdline()
      if cmdline
        exe = cmdline[0] 
        if File.exists?(exe) && File.realpath == exe \
          && File.stat(exe).executable?
          @exe = exe 
        end
      else
        raise fallback if fallback
      end
    end
  end
  @exe
end

#gidsObject

Return process GIDs as #<OpenStruct real, effective, saved>



396
397
398
# File 'lib/posixpsutil/process.rb', line 396

def gids
  @proc.gids
end

#inspectObject

Return a printable version of Process instance’s description.



178
179
180
# File 'lib/posixpsutil/process.rb', line 178

def inspect
  self.to_s.inspect
end

#io_countersObject

Linux, BSD only

Return process I/O statistics as a #<OpenStruct read_count, write_count, read_bytes, write_bytes>

Those are the number of read/write calls performed and the amount of bytes read and written by the process.



429
430
431
# File 'lib/posixpsutil/process.rb', line 429

def io_counters
  @proc.io_counters
end

#ionice(ioclass = nil, value = nil) ⇒ Object

Linux only

Get or set process I/O niceness (priority).

On Linux ‘ioclass’ is one of the IOPRIO_CLASS_* constants. ‘value’ is a number which goes from 0 to 7. The higher the value, the lower the I/O priority of the process. ‘man ionice` for further info

You can use symbols or CONSTANTS as ioclass argument. For example, ‘p.ioclass(:be, 4)` or `p.ioclass(PosixPsutil::IOPRIO_CLASS_BE, 4)`

  • IOPRIO_CLASS_NONE :none => 0

  • IOPRIO_CLASS_RT :rt => 1

  • IOPRIO_CLASS_BE :be => 2

  • IOPRIO_CLASS_IDLE :idle => 3



453
454
455
456
457
458
459
460
461
# File 'lib/posixpsutil/process.rb', line 453

def ionice(ioclass=nil, value=nil)
  if ioclass.nil? 
    raise ArgumentError.new("'ioclass' must be specified") if value
    return @proc.ionice
  else
    # If the value is nil, a reasonable value will be assigned
    return @proc.set_ionice(ioclass, value)
  end
end

#is_runningObject

Return if this process is running. It also checks if PID has been reused by another process in which case return false.



263
264
265
266
267
268
269
270
271
# File 'lib/posixpsutil/process.rb', line 263

def is_running
  return false if @gone
  begin
    return self == Process.new(@pid)
  rescue NoSuchProcess
    @gone = true
    return false
  end
end

#killObject

Kill the current process with SIGKILL pre-emptively checking whether PID has been reused.

It is not an alias_method of send_signal



825
826
827
# File 'lib/posixpsutil/process.rb', line 825

def kill
  send_signal('KILL')
end

#memory_infoObject

Return an OpenStruct representing RSS (Resident Set Size) and VMS (Virtual Memory Size) in bytes.



700
701
702
# File 'lib/posixpsutil/process.rb', line 700

def memory_info
  @proc.memory_info
end

#memory_info_exObject

Return an OpenStruct with variable fields depending on the platform representing extended memory information about this process. All numbers are expressed in bytes.



707
708
709
# File 'lib/posixpsutil/process.rb', line 707

def memory_info_ex
  @proc.memory_info_ex
end

#memory_maps(grouped = true) ⇒ Object

If ‘grouped’ is false every mapped region is shown as a single entity and the namedtuple will also include the mapped region’s address space (‘addr’) and permission set (‘perms’).



733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
# File 'lib/posixpsutil/process.rb', line 733

def memory_maps(grouped = true)
  maps = @proc.memory_maps
  if grouped
    d = {}
    maps.each do |region|
      path = region[2]
      nums = region[3..-1]
      (d[path].nil? ) ? d[path] = nums : 
        d[path].each_index {|i| d[path][i] += nums[i]}
    end
    @proc.pmmap_grouped(d)
  else
    @proc.pmmap_ext(maps)
  end
end

#memory_percentObject

Compare physical system memory to process resident memory (RSS) and calculate process memory utilization as a percentage.



714
715
716
717
718
719
720
721
722
# File 'lib/posixpsutil/process.rb', line 714

def memory_percent
  rss = @proc.memory_info.rss
  @@total_phymem = Memory.virtual_memory.total if @@total_phymem.nil?
  begin
    return (rss / @@total_phymem.to_f * 100).round(2)
  rescue ZeroDivisionError
    return 0.0
  end
end

#nameObject

The process name. The return value is cached after first call.



281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
# File 'lib/posixpsutil/process.rb', line 281

def name
  unless @name
    @name = @proc.name()
    if @name.length >= 15
      begin
        # return an Array represented cmdline arguments( may be [] )
        cmdline = cmdline()
      rescue AccessDenied
        cmdline = []
      end
      if cmdline != []
        extended_name = File.basename(cmdline[0])
        @name = extended_name if extended_name.start_with?(@name)
      end
    end
  end
  @name
end

#niceObject

Get process niceness (priority).



376
377
378
# File 'lib/posixpsutil/process.rb', line 376

def nice
  @proc.nice
end

#nice=(value) ⇒ Object

Set process niceness. Niceness values range from -20 (most favorable to the process) to 19 (least favorable to the process) on Linux.

Raises:



383
384
385
386
387
388
# File 'lib/posixpsutil/process.rb', line 383

def nice=(value)
  raise NoSuchProcess.new(pid:@pid) unless is_running()
  # valid niceness range is system dependency, 
  # so let each platform specific implemention handle the input
  @proc.nice = value 
end

#num_ctx_switchesObject

Return the number of voluntary and involuntary context switches performed by this process.



529
530
531
# File 'lib/posixpsutil/process.rb', line 529

def num_ctx_switches
  @proc.num_ctx_switches
end

#num_fdsObject

Return the number of file descriptors opened by this process



406
407
408
# File 'lib/posixpsutil/process.rb', line 406

def num_fds
  @proc.num_fds
end

#num_threadsObject

Return the number of threads used by this process.



534
535
536
# File 'lib/posixpsutil/process.rb', line 534

def num_threads
  @proc.num_threads
end

#open_filesObject

Return regular files opened by process as a list of <#OpenStruct path, fd> including the absolute file name and file descriptor number.



752
753
754
# File 'lib/posixpsutil/process.rb', line 752

def open_files
  @proc.open_files
end

#parentObject

Return the parent process as a Process object pre-emptively checking whether PID has been reused. If no parent is known return nil.



247
248
249
250
251
252
253
254
255
256
257
258
# File 'lib/posixpsutil/process.rb', line 247

def parent
  ppid = ppid()
  if ppid 
    begin
      parent = Process.new ppid
      return parent if parent.create_time() <= create_time()
    rescue NoSuchProcess
      # ignore ...
    end
  end
  return nil
end

#ppidObject

Return the parent pid of the process.



276
277
278
# File 'lib/posixpsutil/process.rb', line 276

def ppid
  @proc.ppid
end

#resumeObject

Resume process execution with SIGCONT pre-emptively checking whether PID has been reused.



811
812
813
# File 'lib/posixpsutil/process.rb', line 811

def resume
  send_signal('CONT')
end

#rlimit(resource, limits = nil) ⇒ Object

Get or set process resource limits as a :hard Hash.

‘resource’ is one of the RLIMIT_* constants. Unlike other API, ‘limits’ is supposed to be a :hard Hash, instead of an OpenStruct. Since using Hash as input is more common than using OpenStruct (and more handy, too).

‘man prlimit` for further info. And see bits/resource.h for the detail about resource.

You can use symbols or CONSTANTS as resource argument. For example:

limits = {:soft => 1024, :hard => 4096}
p.rlimit(PosixPsutil::RLIMIT_NOFILE, limits)
# or
p.rlimit(:nofile, limits)
  • RLIMIT_CPU :cpu => 0

  • RLIMIT_FSIZE :fsize => 1

  • RLIMIT_DATA :data => 2

  • RLIMIT_STACK :stack => 3

  • RLIMIT_CORE :core => 4

  • RLIMIT_RSS :rss => 5

  • RLIMIT_NPROC :nproc => 6

  • RLIMIT_NOFILE :nofile => 7

  • RLIMIT_MEMLOCK :memlock => 8

  • RLIMIT_AS :as => 9

  • RLIMIT_LOCKS :locks => 10

  • RLIMIT_SIGPENDING :sigpending => 11

  • RLIMIT_MSGQUEUE :msgqueue => 12

  • RLIMIT_NICE :nice => 13

  • RLIMIT_RTPRIO :rtprio => 14

  • RLIMIT_RTTIME :rttime => 15

  • RLIMIT_NLIMITS :nlimits => 16



501
502
503
# File 'lib/posixpsutil/process.rb', line 501

def rlimit(resource, limits=nil)
    @proc.rlimit(resource, limits)
end

#send_signal(sig) ⇒ Object

Send a signal to process pre-emptively checking whether PID has been reused (see signal module constants) .

signal may be an integer signal number or a POSIX signal name (either with or without a SIG prefix). For example, ‘SIGSTOP’/‘STOP’/19 all means the signal SIGSTOP

According to Ruby doc, > If signal is negative (or starts with a minus sign), > kills process groups instead of processes

Currently I consider it as a feature and will not change this behaviour



789
790
791
792
793
794
795
796
797
798
799
800
801
# File 'lib/posixpsutil/process.rb', line 789

def send_signal(sig)
  begin
    # according to "man 2 kill" , PID 0 refers to 
    # 'every process in the process group of the calling process'
    # Luckily, @pid is >= 0
    ::Process.kill(sig, @pid)
  rescue Errno::ESRCH
    @gone = true
    raise NoSuchProcess(@pid, @name)
  rescue Errno::EPERM
    raise AccessDenied(@pid, @name)
  end
end

#statusObject

The process current status as a STATUS_* constant.



335
336
337
# File 'lib/posixpsutil/process.rb', line 335

def status
  @proc.status()
end

#suspendObject

Suspend process execution with SIGSTOP pre-emptively checking whether PID has been reused.



805
806
807
# File 'lib/posixpsutil/process.rb', line 805

def suspend
  send_signal('STOP')
end

#terminalObject

The terminal associated with this process, if any, else nil.



401
402
403
# File 'lib/posixpsutil/process.rb', line 401

def terminal
  @proc.terminal
end

#terminateObject

Terminate process execution with SIGTERM pre-emptively checking whether PID has been reused.



817
818
819
# File 'lib/posixpsutil/process.rb', line 817

def terminate
  send_signal('TERM')
end

#threadsObject

Return threads opened by process as a list of #<OpenStruct id, user_time, system_time> representing thread id and thread CPU times (user/system).



541
542
543
# File 'lib/posixpsutil/process.rb', line 541

def threads
  @proc.threads
end

#time_usedObject

Return the wall time cost by process, measured in seconds



366
367
368
# File 'lib/posixpsutil/process.rb', line 366

def time_used
  @proc.time_used
end

#to_hash(given_attrs = nil, default = {}) ⇒ Object

‘default’ is the value which gets assigned in case AccessDenied exception is raised when retrieving that particular process information.



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
# File 'lib/posixpsutil/process.rb', line 207

def to_hash(given_attrs = nil, default = {})
  # psutil defines some excluded methods, they won't be accessed via
  # this method.
  #
  # psutil want to warn us that the process with given pid may gone,
  # as the comment at the head of the class says.
  excluded_names = [
    :identity, :to_s, :inspect, :==, :eql?, :!=, :to_hash, :parent, 
    :is_running, :children, :rlimit, :send_signal, :kill, :terminate, 
    :resume, :suspend, :wait
  ]


  respond_to_methods = self.public_methods(false)
  included_names = respond_to_methods - excluded_names
  ret = {}
  attrs = (given_attrs ? given_attrs : included_names)
  attrs.each do |attr|
    next if !attr.is_a?(Symbol) || attr.to_s.end_with?('=')
    begin
      # filter unsafe methods
      if respond_to_methods.include?(attr)
        ret[attr] = method(attr).call()
      else
        # in case of not implemented functionality (may happen
        # on old or exotic systems) we want to crash only if
        # the user explicitly asked for that particular attr
        raise NotImplementedError if given_attrs
        ret[attr] = default[attr] if default.key? attr
      end
    rescue AccessDenied
      ret[attr] = default[attr] if default.key? attr
    end
  end
  ret
end

#to_sObject

Return description of Process instance.



167
168
169
170
171
172
173
174
175
# File 'lib/posixpsutil/process.rb', line 167

def to_s
  begin
    return "(pid=#{@pid}, name=#{name()})"
  rescue NoSuchProcess
    return "(pid=#{@pid} (terminated))"
  rescue AccessDenied
    return "(pid=#{@pid})"
  end
end

#uidsObject

Return process UIDs as #<OpenStruct real, effective, saved>



391
392
393
# File 'lib/posixpsutil/process.rb', line 391

def uids
  @proc.uids
end

#usernameObject

The name of the user that owns the process.



340
341
342
343
344
345
346
347
# File 'lib/posixpsutil/process.rb', line 340

def username
  real_uid = uids[:real]
  begin
    return Etc::getpwuid(real_uid).name
  rescue ArgumentError
    return real_uid.to_s
  end
end

#wait(timeout = nil) ⇒ Object

Waiting until process does not existed any more. Raise Timeout::Error if time out while waiting.



412
413
414
415
416
417
418
419
# File 'lib/posixpsutil/process.rb', line 412

def wait(timeout = nil)
  if timeout && timeout < 0
    raise ArgumentError.new("timeout must be a positive integer") 
  end
  return wait_pid(@pid, timeout)
  # maybe raise Timeout::Error, need not to convert it currently
  #rescue Timeout::Error
end