2018-03-02 21:20:46 +00:00
/*
htop - SolarisProcess . c
( C ) 2015 Hisham H . Muhammad
2018-03-05 21:52:03 +00:00
( C ) 2017 , 2018 Guy M . Broome
2018-03-02 21:20:46 +00:00
Released under the GNU GPL , see the COPYING file
in the source distribution for its full text .
*/
# include "Process.h"
# include "ProcessList.h"
# include "SolarisProcess.h"
# include "Platform.h"
# include "CRT.h"
# include <stdlib.h>
# include <string.h>
# include <unistd.h>
# include <sys/syscall.h>
/*{
# include "Settings.h"
# include <zone.h>
2018-03-28 16:48:37 +00:00
# include <sys/proc.h>
# include <libproc.h>
2018-03-02 21:20:46 +00:00
typedef enum SolarisProcessFields {
// Add platform-specific fields here, with ids >= 100
ZONEID = 100 ,
ZONE = 101 ,
PROJID = 102 ,
TASKID = 103 ,
POOLID = 104 ,
CONTID = 105 ,
2018-03-27 16:27:12 +00:00
LWPID = 106 ,
LAST_PROCESSFIELD = 107 ,
2018-03-02 21:20:46 +00:00
} SolarisProcessField ;
typedef struct SolarisProcess_ {
2018-03-05 21:27:27 +00:00
Process super ;
int kernel ;
2018-03-02 21:20:46 +00:00
zoneid_t zoneid ;
2018-03-05 21:27:27 +00:00
char * zname ;
2018-03-02 21:20:46 +00:00
taskid_t taskid ;
projid_t projid ;
poolid_t poolid ;
ctid_t contid ;
2018-03-27 16:27:12 +00:00
bool is_lwp ;
pid_t realpid ;
pid_t realppid ;
pid_t lwpid ;
2018-03-02 21:20:46 +00:00
} SolarisProcess ;
# ifndef Process_isKernelThread
# define Process_isKernelThread(_process) (_process->kernel == 1)
# endif
# ifndef Process_isUserlandThread
# define Process_isUserlandThread(_process) (_process->pid != _process->tgid)
# endif
} */
ProcessClass SolarisProcess_class = {
. super = {
. extends = Class ( Process ) ,
. display = Process_display ,
. delete = Process_delete ,
. compare = SolarisProcess_compare
} ,
. writeField = ( Process_WriteField ) SolarisProcess_writeField ,
} ;
ProcessFieldData Process_fields [ ] = {
[ 0 ] = { . name = " " , . title = NULL , . description = NULL , . flags = 0 , } ,
2018-03-27 16:27:12 +00:00
[ PID ] = { . name = " PID " , . title = " PID " , . description = " Process/thread ID " , . flags = 0 , } ,
2018-03-02 21:20:46 +00:00
[ COMM ] = { . name = " Command " , . title = " Command " , . description = " Command line " , . flags = 0 , } ,
[ STATE ] = { . name = " STATE " , . title = " S " , . description = " Process state (S sleeping, R running, D disk, Z zombie, T traced, W paging) " , . flags = 0 , } ,
[ PPID ] = { . name = " PPID " , . title = " PPID " , . description = " Parent process ID " , . flags = 0 , } ,
[ PGRP ] = { . name = " PGRP " , . title = " PGRP " , . description = " Process group ID " , . flags = 0 , } ,
[ SESSION ] = { . name = " SESSION " , . title = " SID " , . description = " Process's session ID " , . flags = 0 , } ,
[ TTY_NR ] = { . name = " TTY_NR " , . title = " TTY " , . description = " Controlling terminal " , . flags = 0 , } ,
[ TPGID ] = { . name = " TPGID " , . title = " TPGID " , . description = " Process ID of the fg process group of the controlling terminal " , . flags = 0 , } ,
[ MINFLT ] = { . name = " MINFLT " , . title = " MINFLT " , . description = " Number of minor faults which have not required loading a memory page from disk " , . flags = 0 , } ,
[ MAJFLT ] = { . name = " MAJFLT " , . title = " MAJFLT " , . description = " Number of major faults which have required loading a memory page from disk " , . flags = 0 , } ,
[ PRIORITY ] = { . name = " PRIORITY " , . title = " PRI " , . description = " Kernel's internal priority for the process " , . flags = 0 , } ,
[ NICE ] = { . name = " NICE " , . title = " NI " , . description = " Nice value (the higher the value, the more it lets other processes take priority) " , . flags = 0 , } ,
[ STARTTIME ] = { . name = " STARTTIME " , . title = " START " , . description = " Time the process was started " , . flags = 0 , } ,
[ PROCESSOR ] = { . name = " PROCESSOR " , . title = " CPU " , . description = " Id of the CPU the process last executed on " , . flags = 0 , } ,
[ M_SIZE ] = { . name = " M_SIZE " , . title = " VIRT " , . description = " Total program size in virtual memory " , . flags = 0 , } ,
[ M_RESIDENT ] = { . name = " M_RESIDENT " , . title = " RES " , . description = " Resident set size, size of the text and data sections, plus stack usage " , . flags = 0 , } ,
[ ST_UID ] = { . name = " ST_UID " , . title = " UID " , . description = " User ID of the process owner " , . flags = 0 , } ,
[ PERCENT_CPU ] = { . name = " PERCENT_CPU " , . title = " CPU% " , . description = " Percentage of the CPU time the process used in the last sampling " , . flags = 0 , } ,
[ PERCENT_MEM ] = { . name = " PERCENT_MEM " , . title = " MEM% " , . description = " Percentage of the memory the process is using, based on resident memory size " , . flags = 0 , } ,
[ USER ] = { . name = " USER " , . title = " USER " , . description = " Username of the process owner (or user ID if name cannot be determined) " , . flags = 0 , } ,
[ TIME ] = { . name = " TIME " , . title = " TIME+ " , . description = " Total time the process has spent in user and system time " , . flags = 0 , } ,
[ NLWP ] = { . name = " NLWP " , . title = " NLWP " , . description = " Number of threads in the process " , . flags = 0 , } ,
[ TGID ] = { . name = " TGID " , . title = " TGID " , . description = " Thread group ID (i.e. process ID) " , . flags = 0 , } ,
[ ZONEID ] = { . name = " ZONEID " , . title = " ZONEID " , . description = " Zone ID " , . flags = 0 , } ,
[ ZONE ] = { . name = " ZONE " , . title = " ZONE " , . description = " Zone name " , . flags = 0 , } ,
[ PROJID ] = { . name = " PROJID " , . title = " PRJID " , . description = " Project ID " , . flags = 0 , } ,
[ TASKID ] = { . name = " TASKID " , . title = " TSKID " , . description = " Task ID " , . flags = 0 , } ,
[ POOLID ] = { . name = " POOLID " , . title = " POLID " , . description = " Pool ID " , . flags = 0 , } ,
[ CONTID ] = { . name = " CONTID " , . title = " CNTID " , . description = " Contract ID " , . flags = 0 , } ,
2018-03-27 16:27:12 +00:00
[ LWPID ] = { . name = " LWPID " , . title = " LWPID " , . description = " LWP ID " , . flags = 0 , } ,
2018-03-02 21:20:46 +00:00
[ LAST_PROCESSFIELD ] = { . name = " *** report bug! *** " , . title = NULL , . description = NULL , . flags = 0 , } ,
} ;
ProcessPidColumn Process_pidColumns [ ] = {
{ . id = ZONEID , . label = " ZONEID " } ,
{ . id = TASKID , . label = " TSKID " } ,
{ . id = PROJID , . label = " PRJID " } ,
{ . id = POOLID , . label = " POLID " } ,
{ . id = CONTID , . label = " CNTID " } ,
{ . id = PID , . label = " PID " } ,
{ . id = PPID , . label = " PPID " } ,
2018-03-27 16:27:12 +00:00
{ . id = LWPID , . label = " LWPID " } ,
2018-03-02 21:20:46 +00:00
{ . id = TPGID , . label = " TPGID " } ,
{ . id = TGID , . label = " TGID " } ,
{ . id = PGRP , . label = " PGRP " } ,
{ . id = SESSION , . label = " SID " } ,
{ . id = 0 , . label = NULL } ,
} ;
SolarisProcess * SolarisProcess_new ( Settings * settings ) {
SolarisProcess * this = xCalloc ( 1 , sizeof ( SolarisProcess ) ) ;
Object_setClass ( this , Class ( SolarisProcess ) ) ;
Process_init ( & this - > super , settings ) ;
return this ;
}
void Process_delete ( Object * cast ) {
SolarisProcess * this = ( SolarisProcess * ) cast ;
Process_done ( ( Process * ) cast ) ;
free ( this - > zname ) ;
free ( this ) ;
}
void SolarisProcess_writeField ( Process * this , RichString * str , ProcessField field ) {
SolarisProcess * sp = ( SolarisProcess * ) this ;
char buffer [ 256 ] ; buffer [ 255 ] = ' \0 ' ;
int attr = CRT_colors [ DEFAULT_COLOR ] ;
int n = sizeof ( buffer ) - 1 ;
switch ( ( int ) field ) {
// add Solaris-specific fields here
case ZONEID : xSnprintf ( buffer , n , Process_pidFormat , sp - > zoneid ) ; break ;
case PROJID : xSnprintf ( buffer , n , Process_pidFormat , sp - > projid ) ; break ;
case TASKID : xSnprintf ( buffer , n , Process_pidFormat , sp - > taskid ) ; break ;
case POOLID : xSnprintf ( buffer , n , Process_pidFormat , sp - > poolid ) ; break ;
case CONTID : xSnprintf ( buffer , n , Process_pidFormat , sp - > contid ) ; break ;
case ZONE : {
xSnprintf ( buffer , n , " %-*s " , ZONENAME_MAX / 4 , sp - > zname ) ; break ;
if ( buffer [ ZONENAME_MAX / 4 ] ! = ' \0 ' ) {
buffer [ ZONENAME_MAX / 4 ] = ' ' ;
buffer [ ( ZONENAME_MAX / 4 ) + 1 ] = ' \0 ' ;
}
break ;
}
2018-03-27 16:27:12 +00:00
case PID : xSnprintf ( buffer , n , Process_pidFormat , sp - > realpid ) ; break ;
case PPID : xSnprintf ( buffer , n , Process_pidFormat , sp - > realppid ) ; break ;
case LWPID : {
if ( sp - > lwpid < = 0 ) {
xSnprintf ( buffer , n , " - " ) ;
} else {
xSnprintf ( buffer , n , Process_pidFormat , sp - > lwpid ) ; break ;
}
} ; break ;
2018-03-02 21:20:46 +00:00
default :
Process_writeField ( this , str , field ) ;
return ;
}
RichString_append ( str , attr , buffer ) ;
}
long SolarisProcess_compare ( const void * v1 , const void * v2 ) {
SolarisProcess * p1 , * p2 ;
Settings * settings = ( ( Process * ) v1 ) - > settings ;
if ( settings - > direction = = 1 ) {
p1 = ( SolarisProcess * ) v1 ;
p2 = ( SolarisProcess * ) v2 ;
} else {
p2 = ( SolarisProcess * ) v1 ;
p1 = ( SolarisProcess * ) v2 ;
}
switch ( ( int ) settings - > sortKey ) {
case ZONEID :
return ( p1 - > zoneid - p2 - > zoneid ) ;
case PROJID :
return ( p1 - > projid - p2 - > projid ) ;
case TASKID :
return ( p1 - > taskid - p2 - > taskid ) ;
case POOLID :
return ( p1 - > poolid - p2 - > poolid ) ;
case CONTID :
return ( p1 - > contid - p2 - > contid ) ;
case ZONE :
return strcmp ( p1 - > zname ? p1 - > zname : " global " , p2 - > zname ? p2 - > zname : " global " ) ;
2018-03-27 16:27:12 +00:00
case PID :
return ( p1 - > realpid - p2 - > realpid ) ;
case PPID :
return ( p1 - > realppid - p2 - > realppid ) ;
case LWPID :
return ( p1 - > lwpid - p2 - > lwpid ) ;
2018-03-02 21:20:46 +00:00
default :
return Process_compare ( v1 , v2 ) ;
}
}
bool Process_isThread ( Process * this ) {
SolarisProcess * fp = ( SolarisProcess * ) this ;
2018-03-27 16:27:12 +00:00
if ( fp - > kernel = = 1 ) {
return 1 ;
} else if ( fp - > is_lwp ) {
2018-03-02 21:20:46 +00:00
return 1 ;
2018-03-27 16:27:12 +00:00
} else {
2018-03-02 21:20:46 +00:00
return 0 ;
2018-03-27 16:27:12 +00:00
}
2018-03-02 21:20:46 +00:00
}