1# BSD::Process.pm
2#
3# Copyright (c) 2006-2013 David Landgren
4# All rights reserved
5
6package BSD::Process;
7
8use strict;
9use warnings;
10
11use Exporter;
12use XSLoader;
13use base qw(Class::Accessor);
14
15use vars qw($VERSION @ISA @EXPORT_OK);
16$VERSION = '0.07';
17@ISA = qw(Exporter Class::Accessor);
18
19@EXPORT_OK = (qw(process_info process_list P));
20
21BEGIN {
22    my %alias = (
23        process_pid              => 'pid',
24        parent_pid               => 'ppid',
25        process_group_id         => 'pgid',
26        tty_process_group_id     => 'tpgid',
27        process_session_id       => 'sid',
28        job_control_counter      => 'jobc',
29        resident_set_size        => 'rssize',
30        rssize_before_swap       => 'swrss',
31        text_size                => 'tsize',
32        exit_status              => 'xstat',
33        accounting_flags         => 'acflag',
34        percent_cpu              => 'pctcpu',
35        estimated_cpu            => 'estcpu',
36        sleep_time               => 'slptime',
37        time_last_swap           => 'swtime',
38        elapsed_time             => 'runtime',
39        process_flags            => 'flag',
40        nice_priority            => 'nice',
41        process_lock_count       => 'lock',
42        run_queue_index          => 'rqindex',
43        current_cpu              => 'oncpu',
44        last_cpu                 => 'lastcpu',
45        wchan_message            => 'wmesg',
46        setlogin_name            => 'login',
47        command_name             => 'comm',
48        process_args             => 'args',
49        terminal_session_id      => 'tsid',
50        effective_user_id        => 'uid',
51        real_user_id             => 'ruid',
52        saved_effective_user_id  => 'svuid',
53        real_group_id            => 'rgid',
54        saved_effective_group_id => 'svgid',
55        number_of_groups         => 'ngroups',
56        group_list               => 'groups',
57        virtual_size             => 'size',
58        data_size                => 'dsize',
59        stack_size               => 'ssize',
60        start_time               => 'start',
61        children_time            => 'childtime',
62        posix_advisory_lock      => 'advlock',
63        has_controlling_terminal => 'controlt',
64        is_kernel_thread         => 'kthread',
65        no_loadavg_calc          => 'noload',
66        parent_waiting           => 'ppwait',
67        started_profiling        => 'profil',
68        stopped_profiling        => 'stopprof',
69        id_privs_set             => 'sugid',
70        system_process           => 'system',
71        single_exit_not_wait     => 'single_exit',
72        traced_by_debugger       => 'traced',
73        waited_on_by_other       => 'waited',
74        working_on_exiting       => 'wexit',
75        process_called_exec      => 'exec',
76        kernel_session_flag      => 'kiflag',
77        is_locked                => 'locked',
78        controlling_tty_active   => 'isctty',
79        is_session_leader        => 'issleader',
80        process_status           => 'stat',
81        is_being_forked          => 'stat_1',
82        is_runnable              => 'stat_2',
83        is_sleeping_on_addr      => 'stat_3',
84        is_stopped               => 'stat_4',
85        is_a_zombie              => 'stat_5',
86        is_waiting_on_intr       => 'stat_6',
87        is_blocked               => 'stat_7',
88        old_command_name         => 'ocomm',
89        name_of_lock             => 'lockname',
90        priority_scheduling_class => 'pri_class',
91        priority_level            => 'pri_level',
92        priority_native           => 'pri_native',
93        priority_user             => 'pri_user',
94        user_time                 => 'utime',
95        system_time               => 'stime',
96        total_time                => 'time',
97        max_resident_set_size     => 'maxrss',
98        shared_memory_size        => 'ixrss',
99        unshared_data_size        => 'idrss',
100        unshared_stack_size       => 'isrss',
101        page_reclaims             => 'minflt',
102        page_faults               => 'majflt',
103        number_of_swaps           => 'nswap',
104        block_input_ops           => 'inblock',
105        block_output_ops          => 'oublock',
106        messages_sent             => 'msgsnd',
107        messages_received         => 'msgrcv',
108        signals_received          => 'nsignals',
109        voluntary_context_switch   => 'nvcsw',
110        involuntary_context_switch => 'nivcsw',
111        process_had_threads        => 'hadthreads',
112        emulation_name             => 'emul',
113        process_jail_id            => 'jid',
114        number_of_threads          => 'numthreads',
115        user_time_ch               => 'utime_ch',
116        system_time_ch             => 'stime_ch',
117        total_time_ch              => 'time_ch',
118        max_resident_set_size_ch   => 'maxrss_ch',
119        shared_memory_size_ch      => 'ixrss_ch',
120        unshared_data_size_ch      => 'idrss_ch',
121        unshared_stack_size_ch     => 'isrss_ch',
122        page_reclaims_ch           => 'minflt_ch',
123        page_faults_ch             => 'majflt_ch',
124        number_of_swaps_ch         => 'nswap_ch',
125        block_input_ops_ch         => 'inblock_ch',
126        block_output_ops_ch        => 'oublock_ch',
127        messages_sent_ch           => 'msgsnd_ch',
128        messages_received_ch       => 'msgrcv_ch',
129        signals_received_ch        => 'nsignals_ch',
130        voluntary_context_switch_ch   => 'nvcsw_ch',
131        involuntary_context_switch_ch => 'nivcsw_ch',
132    );
133
134    # make some shorthand accessors
135    BSD::Process->mk_ro_accessors( values %alias );
136
137    # and map some longhand aliases to them
138    no strict 'refs';
139    for my $long (keys %alias) {
140        *{$long} = *{$alias{$long}};
141    }
142
143    sub attr {
144        return values(%alias);
145    }
146
147    sub attr_len {
148        my $len = 0;
149        for my $attr(values %alias) {
150            $len = length($attr) if $len < length($attr);
151        }
152        return $len;
153    }
154
155    sub attr_alias {
156        return keys(%alias);
157    }
158}
159
160XSLoader::load __PACKAGE__, $VERSION;
161
162sub new {
163    my $class = shift;
164    my $pid   = shift;
165    my $args;
166    if (ref($pid) eq 'HASH') {
167        $args = $pid;
168        $pid  = $$;
169    }
170    else {
171        $args = shift || {};
172    }
173    $pid = $$ unless defined $pid;
174    my $self = {
175        _pid  => $pid
176    };
177    $self->{_resolve} = exists $args->{resolve} ? $args->{resolve} : 0;
178    my $info = _info($self->{_pid}, $self->{_resolve});
179    @{$self}{keys %$info} = values %$info;
180
181    return bless $self, $class;
182}
183
184sub resolve {
185    my $self = shift;
186    $self->{_resolve} = $_[0] ? $_[0] : 1;
187    return $self->refresh;
188}
189
190sub refresh {
191    my $self = shift;
192    my $info = _info($self->{_pid}, $self->{_resolve});
193    @{$self}{keys %$info} = values %$info;
194    return $self;
195}
196
197sub _request {
198    my %arg = @_;
199    my $request = 0;
200    my $param   = 0;
201    if (exists $arg{uid}) {
202        $request = 5;
203        $param   = $arg{uid};
204        $param =~ /\D/ and $param = scalar(getpwnam($param));
205    }
206    elsif (exists $arg{effective_user_id}) {
207        $request = 5;
208        $param   = $arg{effective_user_id};
209        $param =~ /\D/ and $param = scalar(getpwnam($param));
210    }
211    elsif (exists $arg{ruid}) {
212        $request = 6;
213        $param   = $arg{ruid};
214        $param =~ /\D/ and $param = scalar(getpwnam($param));
215    }
216    elsif (exists $arg{real_user_id}) {
217        $request = 6;
218        $param   = $arg{real_user_id};
219        $param =~ /\D/ and $param = scalar(getpwnam($param));
220    }
221    elsif (exists $arg{gid}) {
222        $request = 11;
223        $param   = $arg{gid};
224        $param =~ /\D/ and $param = scalar(getgrnam($param));
225    }
226    elsif (exists $arg{effective_group_id}) {
227        $request = 11;
228        $param   = $arg{effective_group_id};
229        $param =~ /\D/ and $param = scalar(getgrnam($param));
230    }
231    elsif (exists $arg{rgid}) {
232        $request = 10;
233        $param   = $arg{rgid};
234        $param =~ /\D/ and $param = scalar(getgrnam($param));
235    }
236    elsif (exists $arg{real_group_id}) {
237        $request = 10;
238        $param   = $arg{real_group_id};
239        $param =~ /\D/ and $param = scalar(getgrnam($param));
240    }
241    elsif (exists $arg{pgid}) {
242        $request = 2;
243        $param   = $arg{pgid};
244    }
245    elsif (exists $arg{process_group_id}) {
246        $request = 2;
247        $param   = $arg{process_group_id};
248    }
249    elsif (exists $arg{sid}) {
250        $request = 2;
251        $param   = $arg{sid};
252    }
253    elsif (exists $arg{process_session_id}) {
254        $request = 2;
255        $param   = $arg{process_session_id};
256    }
257    return ($request, $param);
258}
259
260sub list {
261    return _list(_request(@_));
262}
263
264sub all {
265    my %args = @_;
266    my $resolve = exists $args{resolve} ? delete($args{resolve}) : 0;
267    return _all($resolve, _request(%args));
268}
269
270sub info {
271    my $pid = shift;
272    my $args;
273    if (ref($pid) eq 'HASH') {
274        $args = $pid;
275        $pid  = $$;
276    }
277    else {
278        $args = shift || {};
279    }
280    $pid = $$ unless defined $pid;
281    my $resolve = exists $args->{resolve} ? $args->{resolve} : 0;
282    return _info($pid, $resolve);
283}
284
285{
286    my $P;
287    sub P {
288        if ($_[0]) {
289            $P = BSD::Process->new($_[0]);
290        }
291        elsif (!$P) {
292            $P = BSD::Process->new();
293        }
294        return $P;
295    }
296}
297
298*process_info = *info;
299*process_list = *list;
300
301=head1 NAME
302
303BSD::Process - Information about running processes on BSD platforms
304
305=head1 VERSION
306
307This document describes version 0.07 of BSD::Process,
308released 2013-06-22.
309
310=head1 SYNOPSIS
311
312  use BSD::Process;
313
314  my $proc = BSD::Process->new;
315  print $proc->rssize, " resident set size\n"; # as a method
316  print "This process has made $proc->{minflt} page reclaims\n";
317
318  print $proc->time, " seconds spent on the CPU (user+system)\n";
319  $proc->refresh;
320  print "And now $proc->{time} seconds\n"; # as an attribute
321
322  # oneliner shortcut
323  perl -MBSD::Process=P -le 'print P->ppid, " is my parent"';
324
325=head1 DESCRIPTION
326
327C<BSD::Process> creates Perl objects that render the information
328the BSD kernel maintains about current processes.  These may then
329be queried, extracted and reported upon. This allows a more natural
330style of programming (as opposed to scraping the output of ps(1)).
331
332The information is retrieved via the C<kvm> subsystem, and will
333thus work even if the F</proc> filesystem is not mounted.
334
335=head1 FUNCTIONS
336
337=over 4
338
339=item new
340
341Creates a new C<BSD::Process> object. Takes an optional numeric
342value to specify the pid of the target process, otherwise the
343current process is assumed.
344
345A second optional parameter, a reference to a hash, supplies
346additional information governing the creation of the object.
347
348Currently, one key is available:
349
350B<resolve> - indicates whether uids and gids should be resolved to
351their symbolic equivalents (for instance, 0 becomes "root").
352
353Passing the hash reference as the only parameter works as may be
354expected: the pid of the current process will be used implicitly.
355
356  my $init = BSD::Process->new(1); # get info about init
357  print "children of init have taken $init->{childtime} seconds\n";
358
359  # get process info of process's parent, resolving ids
360  my $parent = BSD::Process->new(
361    BSD::Process->new->parent_pid,
362    {resolve => 1},
363  );
364
365Once the object has been created, the various process attributes
366can be examined via method calls or as hash keys, see below.
367
368At the current time C<new> is implemented in terms of C<info> (see
369below), but may in the future be implemented in terms of lazy
370fetching.
371
372=item P
373
374Stashes a global BSD::Process variable, for use in one-liners. By
375default, the current process is referenced, but any process may
376be specified via its process id.
377
378  print P->rssize, "\n"; # resident set size of running process
379  P(P->ppid);            # now refer to parent
380  print P->rssize, "\n"; # rss of parent
381  P(1);                  # talking about init(8)
382
383But more likely:
384
385  perl -MBSD::Process=P -le 'print P->rssize';
386
387As this function is implemented in terms of a global private
388variable, it is adequate for oneliners. It should not be used in
389a threaded program, use objects instead.
390
391=item info, process_info
392
393Returns the entire set of process attributes and their values,
394as specified by a process identifier (or I<pid>).
395
396The input value is numified. Thus, if a some random string is passed
397in, it will be coerced to 0, and you will receive the process
398information of process 0 (the swapper). If no parameter is passed,
399the pid of the running process is assumed.
400
401A hash reference may be passed as an optional second parameter,
402see C<new> for a list of what is available.
403
404  my $proc = BSD::Process::info( $$, {resolve => 1} );
405  print $proc->{uid};
406  # on my system, prints 'david', rather than 1001
407
408A reference to a hash is returned, which is basically a C<BSD::Process>
409object, without all the object-oriented fluff around it. The keys
410are documented below in the METHODS section, however, only the short
411names are available, the longer descriptive names are not defined.
412
413If the pid does not (or does no longer) correspond to process, undef
414is returned.
415
416The routine C<info> is not exportable (since many programs will
417no doubt already have a routine named C<info>). Instead, it is
418exportable under the name C<process_info>.
419
420=item list, process_list
421
422Returns an (unsorted) array of pids of all the running processes
423on the system. Note: fleet-footed processes may have disappeared
424between the time the snapshot is taken and the time the code
425subsequently gets around to asking for more information about
426them. On the other hand, getting this list is very fast. If you
427want the set of current processes on the system decoded as
428C<BSD::Process> objects, you should be looking at the C<all>
429meta-constructor.
430
431The routine C<list> is not exportable. It may be exported under
432the name C<process_info>.
433
434  my @pid = BSD::Process::list;
435  for my $p (@pid) {
436    my $proc =  BSD::Process::info($p);
437    print "$p $proc->{ppid}\n"; # print each pid and its parent pid
438  }
439
440The set of processes may be restricted by specifying a condition,
441defined as a key/value pair to C<list()>. The following restrictions
442are available:
443
444=over 4
445
446=item uid, effective_user_id
447
448Return the list of pids that are owned by the specified effective
449user id. The uid may be specified in the symbolic or numeric form.
450
451  my @uid_pid  = BSD::Process::list(uid => 1001);
452  my @root_pid = BSD::Process::list(uid => 'root');
453
454=item pgid, process_group_id
455
456Return the processes that belong to the specified process group.
457
458  my @pgid_pid = BSD::Process::list(process_group_id => 378);
459
460=item sid, process_session_id
461
462Return the processes that belong to the specified process session.
463
464=back
465
466=item all
467
468Return a references to a hash of C<BSD::Process> objects representing the
469current running processes. The hash keys are the process pids.
470The following program prints out the 10 processes that consume the most
471physical memory.
472
473  use BSD::Process;
474
475  my $all = BSD::Process::all;
476  my $want = 10;
477  for my $pid (
478    sort {$all->{$b}{rssize} <=> $all->{$a}{rssize}}
479    keys %$all
480  ) {
481    my $proc = $all->{$pid};
482    print $proc->command_name, ' ',  $proc->resident_set_size,
483      "Kb owned by $proc->{login}\n";
484    last unless --$want;
485  }
486
487This routine runs more slowly than C<list()>, since it has to
488instantiate the process objects. It may help to think of C<all()>
489as a meta-new constructor, since it creates many new BSD::Process
490objects in one fell swoop.
491
492This routine accepts the same parameters as C<list()>. Thus, one is
493able to restrict the set of objects returned. In addition, it also
494accepts the C<resolve> parameter, to indicate that uids and gids
495should be represented as symbolic names rather than numeric values.
496
497  my @own = BSD::Process::all(uid => 1000);
498
499  my @session = BSD::Process::all(sid => 632, resolve => 1);
500
501=item attr
502
503Returns the list of available attributes of a C<BSD::Process>
504object. You can use this to pretty-print an object:
505
506  my $self = BSD::Process->new;
507  for my $attr (BSD::Process::attr) {
508    printf "%11s %s\n", $attr, $self->{$attr};
509  }
510
511=item attr_len
512
513The problem with the above program is that on different platforms
514and operating system versions, the length of the longest attribute
515might not be 11.  In this case, one may employ C<attr_len> to obtain
516the length of the longest attribute name. The above program then
517becomes:
518
519  my $len = BSD::Process::attr_len;
520  my $self = BSD::Process->new;
521  for my $attr (BSD::Process::attr) {
522    printf "%*s %s\n", $len, $attr, $self->{$attr};
523  }
524
525=item attr_alias
526
527Returns the list of long aliases of the attributes.
528
529=item max_kernel_groups
530
531Returns the maximum number of groups to which a process may belong.
532This is probably not of direct importance to the average Perl
533programmer, but it eases calculating the number of regression tests
534to be run in a cross-platform manner.
535
536=back
537
538=head1 METHODS
539
540=over 4
541
542=item refresh
543
544Refreshes the information of a C<BSD::Process> object. For
545instance, the following snippet shows a very accurate way
546of measuring elapsed CPU time:
547
548  my $proc  = BSD::Process->new;
549  my $begin = $proc->runtime; # microseconds
550  lengthy_calculation();
551
552  $proc->refresh;
553  my $elapsed = $proc->runtime - $begin;
554  print "that took $elapsed microseconds of CPU time\n";
555
556The method may be chained:
557
558  my $runtime = $proc->refresh->runtime;
559
560It may also be used with the C<P> shortcut.
561
562  P; # to initialise
563  lengthy_calculation();
564  P->refresh;
565
566=item resolve
567
568Switches symbolic resolution on or off.
569
570  my $proc = BSD::Process->new;
571  print "$proc->{uid}\n";
572  $proc->resolve;
573  print "$proc->{uid}\n";
574
575Note that changing the resolve setting will result in the
576object being C<refresh>ed.
577
578=back
579
580=head1 PROCESS ATTRIBUTES
581
582The following methods may be called on a C<BSD::Process> object.
583Each process attribute may be accessed via two methods, a longer,
584more descriptive name, or a terse name (following the member
585name in the underlying C<kinfo_proc> C struct).
586
587Furthermore, you may also interpolate the attribute (equivalent to
588the terse method name) directly into a string. This can lead to
589simpler code. The following three statements are equivalent:
590
591  print "rss=", $p->resident_set_size;
592  print "rss=", $p->rssize;
593  print "rss=$p->{rssize};
594
595A modification of a value in the underlying hash of the object
596has no corresponding effect on the system process it represents.
597
598Older kernels do not track as many process attributes as more
599modern kernels. In these cases, the value -1 will be returned.
600
601In the following list, the key B<F5+> means that the method
602returns something useful in FreeBSD 5.x or better. The key
603B<F6> means the method returns something useful for FreeBSD
6046.x and beyond.
605
606=over 4
607
608=item process_args, args
609
610The command with all its arguments as a string. When the process
611args are unavailable, the name of the executable in brackets is
612returned (same as in the F<ps> program). This may happen when the
613length of the arguments exceeds the kernel limit set with the
614C<kern.ps_arg_cache_limit> kernel setting. This is usually 256, for
615more information check the manual page for the F<sysctl> program.
616
617If you have the companion C<BSD::Sysctl> module installed, you can
618check this with C<print sysctl("kern.ps_arg_cache_limit");> or else
619with the C<sysctl(8)> command.
620
621=item process_pid, pid
622
623The identifier that identifies a process in a unique manner. No two
624process share the same pid (process id).
625
626=item parent_pid, ppid
627
628The pid of the parent process that spawned the current process.
629Many processes may share the same parent pid. Processes whose parents
630exit before they do are reparented to init (pid 1).
631
632=item process_group_id, pgid
633
634A number of processes may belong to the same group (for instance,
635all the processes in a shell pipeline). In this case they share the
636same pgid.
637
638=item tty_process_group_id, tpgid
639
640Similarly, a number of processes belong to the same tty process
641group. This means that they were all originated from the same console
642login session or terminal window. B<F5+>
643
644=item process_session_id, sid
645
646Processes also belong to a session, identified by the process session
647id. B<F5+>
648
649=item terminal_session_id, tsid
650
651A process that has belongs to a tty process group will also have a
652terminal session id.
653
654=item job_control_counter, jobc
655
656The job control counter of a process. (purpose?) B<F5+>
657
658=item effective_user_id, uid
659
660The user id under which the process is running. A program with the
661setuid bit set can be launched by any user, and the effective user
662id will be that of the program itself, rather than that of the user.
663
664The symbolic name of the uid will be returned if the constructor
665had the C<resolve> attribute set. B<F5+>
666
667=item real_user_id, ruid
668
669The user id of the user that launched the process. B<F5+>
670
671=item saved_effective_user_id, svuid
672
673The saved effective user id of the process. (purpose?) B<F5+>
674
675=item real_group_id, rgid
676
677The primary group id of the user that launched the process.
678
679The symbolic name of the gid will be returned if the constructor
680had the C<resolve> attribute set. B<F5+>
681
682=item saved_effective_group_id, svgid
683
684The saved effective group id of the process. (purpose?) B<F5+>
685
686=item number_of_groups, ngroups
687
688The number of groups to which the process belongs. B<F5+>
689
690=item group_list, groups
691
692A reference to an array of group ids (gids) to which the process belongs. B<F5+>
693
694=item virtual_size, size
695
696The size (in bytes) of virtual memory occupied by the process. B<F5+>
697
698=item resident_set_size, rssize
699
700The size (in kilobytes) of physical memory occupied by the process.
701
702=item rssize_before_swap, swrss
703
704The resident set size of the process before the last swap.
705
706=item text_size, tsize
707
708Text size (in pages) of the process.
709
710=item data_size, dsize
711
712Data size (in pages) of the process. B<F5+>
713
714=item stack_size, ssize
715
716Stack size (in pages) of the process. B<F5+>
717
718=item exit_status, xstat
719
720Exit status of the process (usually zero).
721
722=item accounting_flags, acflag
723
724Process accounting flags (TODO: decode them).
725
726=item percent_cpu, pctcpu
727
728Percentage of CPU time used by the process (for the duration of
729swtime, see below).
730
731=item estimated_cpu, estcpu
732
733Time averaged value of ki_cpticks. (as per the comment in user.h,
734purpose?)
735
736=item sleep_time, slptime
737
738Number of seconds since the process was last blocked.
739
740=item time_last_swap, swtime
741
742Number of seconds since the process was last swapped in or out.
743
744=item elapsed_time, runtime
745
746Real time used by the process, in microseconds.
747
748=item start_time, start
749
750Epoch time of the creation of the process. B<F5+>
751
752=item children_time, childtime
753
754Amount of real time used by the children processes (if any) of the
755process. B<F5+>
756
757=item process_flags, flag
758
759A bitmap of process flags (decoded in the following methods as 0
760or 1).
761
762=item posix_advisory_lock, advlock
763
764Flag indicating whether the process holds a POSIX advisory lock. B<F5+>
765
766=item has_controlling_terminal, controlt
767
768Flag indicating whether the process has a controlling terminal (if
769true, the terminal session id is stored in the C<tsid> attribute). B<F5+>
770
771=item is_kernel_thread, kthread
772
773Flag indicating whether the process is a kernel thread. B<F5+>
774
775=item no_loadavg_calc, noload
776
777Flag indicating whether the process contributes to the load average
778calculations of the system. B<F5+>
779
780=item parent_waiting, ppwait
781
782Flag indicating whether the parent is waiting for the process to
783exit. B<F5+>
784
785=item started_profiling, profil
786
787Flag indicating whether the process has started profiling. B<F5+>
788
789=item stopped_profiling, stopprof
790
791Flag indicating whether the process has a thread that has requesting
792profiling to stop. B<F5+>
793
794=item process_had_threads, hadthreads
795
796Flag indicating whether the process has had thresds. B<F6+>
797
798=item id_privs_set, sugid
799
800Flag indicating whether the process has set id privileges since
801last exec. B<F5+>
802
803=item system_process, system
804
805Flag indicating whether the process is a system process. B<F5+>
806
807=item single_exit_not_wait, single_exit
808
809Flag indicating that threads that are suspended should exit, not
810wait. B<F5+>
811
812=item traced_by_debugger, traced
813
814Flag indicating that the process is being traced by a debugger. B<F5+>
815
816=item waited_on_by_other, waited
817
818Flag indicating that another process is waiting for the process. B<F5+>
819
820=item working_on_exiting, wexit
821
822Flag indicating that the process is working on exiting. B<F5+>
823
824=item process_called_exec, exec
825
826Flag indicating that the process has called exec. B<F5+>
827
828=item kernel_session_flag, kiflag
829
830A bitmap described kernel session status of the process, described
831via the following attributes. B<F5+>
832
833=item is_locked, locked
834
835Flag indicating that the process is waiting on a lock (whose name
836may be obtained from the C<lock> attribute). B<F5+>
837
838  if ($p->is_locked) {
839    print "$p->{comm} is waiting on lock $p->{lockname}\n";
840  }
841  else {
842    print "not waiting on a lock\n";
843  }
844
845=item controlling_tty_active, isctty
846
847Flag indicating that the vnode of the controlling tty is active. B<F5+>
848
849=item is_session_leader, issleader
850
851Flag indicating that the process is a session leader. B<F5+>
852
853=item process_status, stat
854
855Numeric value indicating the status of the process, decoded via the
856following attibutes. B<F5+>
857
858=item is_being_forked, stat_1
859
860Status indicates that the process is being forked. B<F5+>
861
862=item is_runnable, stat_2
863
864Status indicates the process is runnable. B<F5+>
865
866=item is_sleeping_on_addr, stat_3
867
868Status indicates the process is sleeping on an address. B<F5+>
869
870=item is_stopped, stat_4
871
872Status indicates the process is stopped, either suspended or in a
873debugger. B<F5+>
874
875=item is_a_zombie, stat_5
876
877Status indicates the process is a zombie. It is waiting for its
878parent to collect its exit code. B<F5+>
879
880=item is_waiting_on_intr, stat_6
881
882Status indicates the process is waiting for an interrupt. B<F5+>
883
884=item is_blocked, stat_7
885
886Status indicates the process is blocked by a lock. B<F5+>
887
888=item nice_priority, nice
889
890The nice value of the process. The more positive the value, the
891nicer the process (that is, the less it seeks to sit on the CPU).
892
893=item process_lock_count, lock
894
895Process lock count. If locked, swapping is prevented.
896
897=item run_queue_index, rqindex
898
899When multiple processes are runnable, the run queue index shows the
900order in which the processes will be scheduled to run on the CPU.
901
902=item current_cpu, oncpu
903
904Identifies which CPU the process is running on.
905
906=item last_cpu, lastcpu
907
908Identifies the last CPU on which the process was running.
909
910=item old_command_name, ocomm
911
912The old command name. B<F5+>
913
914=item wchan_message, wmesg
915
916wchan message. (purpose?)
917
918=item setlogin_name, login
919
920Name of the user login process that launched the command.
921
922=item name_of_lock, lockname
923
924Name of the lock that the process is waiting on (if the process is
925waiting on a lock). B<F5+>
926
927=item command_name, comm
928
929Name of the command.
930
931=item emulation_name, emul
932
933Name of the emulation. B<F6+>
934
935=item process_jail_id, jid
936
937The process jail identifier B<F6+>
938
939=item number_of_threads, numthreads
940
941Number of threads in the process. B<F6+>
942
943=item priority_scheduling_class, pri_class
944
945=item priority_level, pri_level
946
947=item priority_native, pri_native
948
949=item priority_user, pri_user
950
951The parameters pertaining to the scheduling of the process. B<F6+>
952
953=item user_time, utime
954
955Process resource usage information. The amount of time spent by the
956process in userland. B<F5+>
957
958=item system_time, stime
959
960Process resource usage information. The amount of time spent by the
961process in the kernel (system calls). B<F5+>
962
963=item total_time, time
964
965The sum of the user and system times of the process.
966
967Process resource usage information. The amount of time spent by the
968process in the kernel (system calls). B<F5+>
969
970=item max_resident_set_size, maxrss
971
972Process resource usage information. The maximum resident set size
973(the high-water mark of physical memory used) of the process. B<F5+>
974
975=item shared_memory_size, ixrss
976
977Process resource usage information. The size of shared memory. B<F5+>
978
979=item unshared_data_size, idrss
980
981Process resource usage information. The size of unshared memory. B<F5+>
982
983=item unshared_stack_size, isrss
984
985Process resource usage information. The size of unshared stack. B<F5+>
986
987=item page_reclaims, minflt
988
989Process resource usage information. Minor page faults, the number
990of page reclaims. B<F5+>
991
992=item page_faults, majflt
993
994Process resource usage information. Major page faults, the number
995of page faults. B<F5+>
996
997=item number_of_swaps, nswap
998
999Process resource usage information. The number of swaps the
1000process has undergone. B<F5+>
1001
1002=item block_input_ops, inblock
1003
1004Process resource usage information. Total number of input block
1005operations performed by the process. B<F5+>
1006
1007=item block_output_ops, oublock
1008
1009Process resource usage information. Total number of output block
1010operations performed by the process. B<F5+>
1011
1012=item messages_sent, msgsnd
1013
1014Process resource usage information. Number of messages sent by
1015the process. B<F5+>
1016
1017=item messages_received, msgrcv
1018
1019Process resource usage information. Number of messages received by
1020the process. B<F5+>
1021
1022=item signals_received, nsignals
1023
1024Process resource usage information. Number of signals received by
1025the process. B<F5+>
1026
1027=item voluntary_context_switch, nvcsw
1028
1029Process resource usage information. Number of voluntary context
1030switches performed by the process. B<F5+>
1031
1032=item involuntary_context_switch, nivcsw
1033
1034Process resource usage information. Number of involuntary context
1035switches performed by the process. B<F5+>
1036
1037=item user_time_ch, utime_ch
1038
1039=item system_time_ch, stime_ch
1040
1041=item total_time_ch, time_ch
1042
1043=item max_resident_set_size_ch, maxrss_ch
1044
1045=item shared_memory_size_ch, ixrss_ch
1046
1047=item unshared_data_size_ch, idrss_ch
1048
1049=item unshared_stack_size_ch, isrss_ch
1050
1051=item page_reclaims_ch, minflt_ch
1052
1053=item page_faults_ch, majflt_ch
1054
1055=item number_of_swaps_ch, nswap_ch
1056
1057=item block_input_ops_ch, inblock_ch
1058
1059=item block_output_ops_ch, oublock_ch
1060
1061=item messages_sent_ch, msgsnd_ch
1062
1063=item messages_received_ch, msgrcv_ch
1064
1065=item signals_received_ch, nsignals_ch
1066
1067=item voluntary_context_switch_ch, nvcsw_ch
1068
1069=item involuntary_context_switch_ch => nivcsw_ch
1070
1071These attributes (only available in FreeBSD 6.x) store the resource
1072usage of the child processes spawned by this process. Currently,
1073the kernel only fills in the information for the the C<utime_ch>
1074and C<stime_ch> fields (and hence the C<time_ch> value is derived
1075from them).
1076
1077In theory (and in practice as far as I can tell) C<time_ch> is
1078equal to C<childtime>.
1079
1080=back
1081
1082=head1 DIAGNOSTICS
1083
1084B<kern.proc.pid is corrupt>: a "can't happen" error when
1085attempting to retrieve the information of a process. If this
1086occurs, I'd like to know how you managed it.
1087
1088B<kvm error in all()/list()>: another "can't happen" error when
1089asking the system to return the information about a process.
1090
1091B<kvm error in list(): proc size mismatch (nnn total, nnn chunks)>:
1092you have upgraded a system across major versions, for instance 4.x
1093to 5.x, but the published system header files belong to the previous
1094version.
1095
1096=head1 NOTES
1097
1098Currently, FreeBSD versions 4 through 8 are supported. Support for
1099NetBSD and OpenBSD may be added in future versions.
1100
1101=head1 SEE ALSO
1102
1103=over 4
1104
1105=item L<BSD::Sysctl>
1106
1107Read and write kernel variables. With these two modules, there
1108should be much less need for writing shell scripts that scrape
1109the output of ps(1) and sysctl(8).
1110
1111=item L<Proc::ProcessTable>
1112
1113Seems to be a fairly wide cross-platform module. Goes into
1114a fair amount of depth, but not as much as C<BSD::Process>
1115does in its own particular niche. Also, FreeBSD has moved
1116away from the F</proc> filesystem.
1117
1118Definitely the module to use if you need to go
1119multi-platform.
1120
1121=item L<Solaris::Procfs>
1122
1123Information about processes on the Solaris platform. The
1124documentation indicates that it is not finished, however,
1125it does not appear to have been updated since 2003.
1126
1127=item L<Win32::Process::Info>
1128
1129Information about current processes on the Win32 platform.
1130
1131=back
1132
1133=head1 BUGS
1134
1135Not all of the ps(1) keywords are implemented. At the worst,
1136this (currently) means that you could not rewrite it in Perl.
1137This may be addressed in a future release.
1138
1139Please report all bugs at
1140L<http://rt.cpan.org/NoAuth/Bugs.html?Dist=BSD-Process|rt.cpan.org>
1141
1142Make sure you include the output from the following two commands:
1143
1144  perl -MBSD::Process -le 'print $BSD::Process::VERSION'
1145  perl -V
1146
1147I also accept pull requests on Github. See
1148L<https://github.com/dland/BSD-Process>
1149
1150=head1 ACKNOWLEDGEMENTS
1151
1152The FreeBSD Ports team, for their work on keeping this module up
1153to date on the ports tree. Their efforts are greatly appreciated.
1154
1155Thanks also to az5112 on Github (I've lost their name), who implemented
1156the C<args> method.
1157
1158=head1 AUTHOR
1159
1160David Landgren, copyright (C) 2006-2013. All rights reserved.
1161
1162http://www.landgren.net/perl/
1163
1164If you (find a) use this module, I'd love to hear about it. If you
1165want to be informed of updates, send me a note. You know my first
1166name, you know my domain. Can you guess my e-mail address?
1167
1168=head1 LICENSE
1169
1170This library is free software; you can redistribute it and/or modify
1171it under the same terms as Perl itself.
1172
1173=cut
1174
1175'The Lusty Decadent Delights of Imperial Pompeii';
1176
1177