/*-
* This code relies heavily on the Darwin "ps" command, which is available
* from Apple in the adv_cmds portion of the Darwin distribution. The portions
* of this code which were included from that source are:
*
* Copyright (c) 1990, 1993, 1994
* The Regents of the University of California. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* The portions of this code which were necessary to tie into the Perl
* Proc::ProcessTable module are:
*
* Copyright (c) 2003 and 2008, Thomas R. Wyant, III
*
* and may be reused under the same terms as Perl itself.
*/
#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#include <sys/time.h>
#include <mach/mach_init.h>
#include <mach/mach_port.h>
#include <mach/mach_traps.h>
#include <mach/mach_types.h>
#include <mach/shared_memory_server.h>
#include <mach/task.h>
#include <mach/thread_act.h>
#include <mach/time_value.h>
#include <mach/vm_map.h>
#include <stdlib.h>
#include <sys/proc.h>
#include <sys/resource.h>
#include <sys/stat.h>
#include <sys/sysctl.h>
#ifndef KERN_PROCARGS2 /* Not defined in Jaguar (10.2);
Defined in Panther (10.3) at least
through Leopard (10.5). */
#include <kvm.h>
#endif
#include <unistd.h>
/* these are in sys/sysctl.h */
#define KI_PROC(ki) (&(ki)->ki_p->kp_proc)
#define KI_EPROC(ki) (&(ki)->ki_p->kp_eproc)
#define STATE_MAX 7
typedef
struct
thread_values {
struct
thread_basic_info tb;
/* struct policy_infos schedinfo; */
union
{
struct
policy_timeshare_info tshare;
struct
policy_rr_info rr;
struct
policy_fifo_info fifo;
} schedinfo;
} thread_values_t;
struct
usave {
struct
timeval u_start;
struct
rusage u_ru;
struct
rusage u_cru;
char
u_acflag;
char
u_valid;
};
typedef
struct
kinfo {
struct
kinfo_proc *ki_p;
/* proc structure */
struct
usave ki_u;
/* interesting parts of user */
char
*ki_args;
/* exec args */
char
*ki_env;
/* environment */
task_port_t task;
int
state;
int
cpu_usage;
int
curpri;
int
basepri;
int
swapped;
struct
task_basic_info tasks_info;
struct
task_thread_times_info times;
/* struct policy_infos schedinfo; */
union
{
struct
policy_timeshare_info tshare;
struct
policy_rr_info rr;
struct
policy_fifo_info fifo;
} schedinfo;
int
invalid_tinfo;
#ifdef KERN_PROCARGS2 /* Defined in Panther (10.3) and up */
mach_msg_type_number_t thread_count;
#else
int
thread_count;
#endif
thread_port_array_t thread_list;
thread_values_t *thval;
int
invalid_thinfo;
} KINFO;
#define TIME_IN_MICROSECONDS 1
#ifdef TESTING
/* Note that FREE_BUFFERS is to be defined appropriately before
* DIE_HORRIBLY is used.
*/
#define DIE_HORRIBLY(s) {FREE_BUFFERS perror (s); exit (1);}
#else /* def TESTING */
#define DIE_HORRIBLY(s) {FREE_BUFFERS perror (s); return;}
extern
void
bless_into_proc(
char
* format,
char
** fields, ...);
#ifdef TIME_IN_MICROSECONDS
static
char
*Format =
"iiiiiiiiiiiiiiijjjllslsssss"
;
#else /* def TIME_IN_MICROSECONDS */
static
char
*Format =
"iiiiiiiiiiiiiiilllllslsssss"
;
#endif /* def TIME_IN_MICROSECONDS */
static
char
*Fields[] = {
"pid"
,
/* Process ID */
# define F_PID 0
"ppid"
,
/* Parent pid */
# define F_PPID 1
"pgrp"
,
/* Process group leader */
# define F_PGRP 2
"uid"
,
/* real uid */
# define F_UID 3
"gid"
,
/* real gid */
# define F_GID 4
"euid"
,
/* effective uid */
# define F_EID 5
"egid"
,
/* effective gid */
# define F_EGID 6
"suid"
,
/* saved uid */
# define F_SUID 7
"sgid"
,
/* saved gid */
# define F_SGID 8
"priority"
,
/* proiority */
# define F_PRIORITY 9
"size"
,
/* virtual size (Kbytes) */
# define F_SIZE 10
"rss"
,
/* resident set size (Kbytes) */
# define F_RSS 11
"flags"
,
/* process flags */
# define F_FLAGS 12
"nice"
,
/* nice for CPU usage */
# define F_NICE 13
"sess"
,
/* session pointer */
# define F_SESS 14
"time"
,
/* total time (system + user, centi- or microseconds, depending) */
# define F_CPTICKS 15
"stime"
,
/* system time (centi- or micrseconds, depending) */
# define F_STIME 16
"utime"
,
/* user time (centi- or microseconds, depending) */
# define F_UTIME 17
"start"
,
/* Start time in seconds since epoch */
# define F_START 18
"wchan"
,
/* Wait channel (addr of system call) */
# define F_WCHAN 19
"ttydev"
,
# define F_TTYDEV 20
"ttynum"
,
/* device number for tty, or -1 */
# define F_TTYNUM 21
"pctcpu"
,
/* Percent cpu as string representing float */
# define F_PCTCPU 22
"pctmem"
,
/* Percent memory as string representing float */
# define F_PCTMEM 23
"state"
,
/* current run state (e.g. sleep, wait ...) */
# define F_STATE 24
"cmndline"
,
/* entire command line */
# define F_CMNDLINE 25
"fname"
,
/* filename */
# define F_FNAME 26
# define F_LASTFIELD 26
};
#endif /* def TESTING */
static
char
*States[] = {
""
,
"idle"
,
"run"
,
"sleep"
,
"stop"
,
"zombie"
};