2018-06-04 03:11:21 -07:00
|
|
|
#if defined(__MACH__) && defined(__APPLE__)
|
|
|
|
# define __MacOS__
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#if defined(__MacOS__) || defined(__FreeBSD__) || defined(__DragonFly__) || defined(__OpenBSD__)
|
|
|
|
# include <sys/types.h>
|
|
|
|
# include <sys/sysctl.h>
|
|
|
|
# include <sys/user.h>
|
|
|
|
# include <sys/proc.h>
|
2020-04-27 05:41:05 -07:00
|
|
|
# include <libgen.h>
|
2018-06-04 03:11:21 -07:00
|
|
|
#endif
|
|
|
|
|
2020-04-14 10:24:27 -07:00
|
|
|
#if defined(__FreeBSD__) || defined(__DragonFly__) || defined(__OpenBSD__)
|
2020-04-21 11:50:02 -07:00
|
|
|
# include <libgen.h>
|
2020-04-14 10:24:27 -07:00
|
|
|
# include <unistd.h>
|
|
|
|
# include <fcntl.h>
|
2018-06-04 03:11:21 -07:00
|
|
|
# include <kvm.h>
|
|
|
|
# include <limits.h>
|
|
|
|
# include <sys/proc.h>
|
|
|
|
# include <sys/param.h>
|
|
|
|
# include <sys/resource.h>
|
|
|
|
#endif
|
|
|
|
|
2021-02-26 00:33:07 -08:00
|
|
|
#if defined(__FreeBSD__)
|
2021-02-26 09:34:56 -08:00
|
|
|
# define _WANT_FILE
|
|
|
|
# include <sys/file.h>
|
|
|
|
# include <sys/filedesc.h>
|
2021-02-26 00:33:07 -08:00
|
|
|
#endif
|
|
|
|
|
2018-06-04 03:11:21 -07:00
|
|
|
#if defined(__MacOS__)
|
|
|
|
# include <libproc.h>
|
|
|
|
# include <sys/proc_info.h>
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#include <stdio.h>
|
|
|
|
#include <stdlib.h>
|
|
|
|
#include <string.h>
|
|
|
|
#include <ctype.h>
|
|
|
|
#include <unistd.h>
|
|
|
|
#include <limits.h>
|
|
|
|
|
|
|
|
#include "process.h"
|
|
|
|
#include <Eina.h>
|
|
|
|
#include <Ecore.h>
|
|
|
|
#include <Ecore_File.h>
|
|
|
|
|
2020-04-14 10:24:27 -07:00
|
|
|
#if defined(__linux__) && !defined(PF_KTHREAD)
|
|
|
|
# define PF_KTHREAD 0x00200000
|
|
|
|
#endif
|
|
|
|
|
2020-07-09 13:37:34 -07:00
|
|
|
#include "macros.h"
|
|
|
|
|
2021-01-24 05:48:40 -08:00
|
|
|
static Eina_Bool _show_kthreads = 1;
|
2020-07-31 11:13:23 -07:00
|
|
|
|
|
|
|
void
|
|
|
|
proc_info_kthreads_show_set(Eina_Bool enabled)
|
|
|
|
{
|
|
|
|
_show_kthreads = enabled;
|
|
|
|
}
|
|
|
|
|
|
|
|
Eina_Bool
|
|
|
|
proc_info_kthreads_show_get(void)
|
|
|
|
{
|
|
|
|
return _show_kthreads;
|
|
|
|
}
|
|
|
|
|
2021-03-03 06:44:40 -08:00
|
|
|
static const char * _states[128];
|
2021-02-02 13:55:40 -08:00
|
|
|
|
|
|
|
static void
|
|
|
|
_states_init(void)
|
2021-02-02 13:33:09 -08:00
|
|
|
{
|
|
|
|
#if defined(__linux__)
|
2021-02-02 13:55:40 -08:00
|
|
|
_states['D'] = "dsleep";
|
|
|
|
_states['I'] = "idle";
|
2021-03-01 13:58:15 -08:00
|
|
|
_states['R'] = "running";
|
|
|
|
_states['S'] = "sleeping";
|
|
|
|
_states['T'] = "stopped";
|
2021-02-02 13:55:40 -08:00
|
|
|
_states['X'] = "dead";
|
|
|
|
_states['Z'] = "zombie";
|
2018-06-04 03:11:21 -07:00
|
|
|
#else
|
2021-02-02 13:55:40 -08:00
|
|
|
_states[SIDL] = "idle";
|
2021-03-01 13:58:15 -08:00
|
|
|
_states[SRUN] = "running";
|
|
|
|
_states[SSLEEP] = "sleeping";
|
|
|
|
_states[SSTOP] = "stopped";
|
2018-06-04 03:11:21 -07:00
|
|
|
#if !defined(__MacOS__)
|
|
|
|
#if !defined(__OpenBSD__)
|
2021-02-02 13:55:40 -08:00
|
|
|
_states[SWAIT] = "wait";
|
2021-02-02 13:58:22 -08:00
|
|
|
_states[SLOCK] = "lock";
|
2021-02-02 13:55:40 -08:00
|
|
|
_states[SZOMB] = "zombie";
|
2018-06-04 03:11:21 -07:00
|
|
|
#endif
|
|
|
|
#if defined(__OpenBSD__)
|
2021-03-03 00:08:20 -08:00
|
|
|
_states[SDEAD] = "zombie";
|
2021-03-01 13:58:15 -08:00
|
|
|
_states[SONPROC] = "running";
|
2021-02-02 13:33:09 -08:00
|
|
|
#endif
|
2018-06-04 03:11:21 -07:00
|
|
|
#endif
|
|
|
|
#endif
|
2021-02-02 13:55:40 -08:00
|
|
|
}
|
2021-02-02 13:33:09 -08:00
|
|
|
|
|
|
|
static const char *
|
|
|
|
_process_state_name(char state)
|
|
|
|
{
|
2021-02-02 13:55:40 -08:00
|
|
|
static int init = 0;
|
|
|
|
if (!init)
|
|
|
|
{
|
|
|
|
_states_init();
|
|
|
|
init = 1;
|
|
|
|
}
|
|
|
|
return _states[toupper(state)];
|
2018-06-04 03:11:21 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
#if defined(__linux__)
|
|
|
|
|
|
|
|
static unsigned long
|
|
|
|
_parse_line(const char *line)
|
|
|
|
{
|
|
|
|
char *p, *tok;
|
|
|
|
|
|
|
|
p = strchr(line, ':') + 1;
|
|
|
|
while (isspace(*p))
|
|
|
|
p++;
|
|
|
|
tok = strtok(p, " ");
|
|
|
|
|
|
|
|
return atol(tok);
|
|
|
|
}
|
|
|
|
|
2020-04-22 06:30:30 -07:00
|
|
|
static void
|
2020-05-12 18:11:10 -07:00
|
|
|
_mem_size(Proc_Info *proc)
|
2020-04-22 06:30:30 -07:00
|
|
|
{
|
|
|
|
FILE *f;
|
2021-01-03 14:34:00 -08:00
|
|
|
char buf[4096];
|
2020-04-22 10:28:20 -07:00
|
|
|
unsigned int dummy, size, shared, resident, data, text;
|
2020-07-09 13:37:34 -07:00
|
|
|
static int pagesize = 0;
|
|
|
|
|
|
|
|
if (!pagesize) pagesize = getpagesize();
|
2020-04-22 06:30:30 -07:00
|
|
|
|
2021-01-03 14:34:00 -08:00
|
|
|
snprintf(buf, sizeof(buf), "/proc/%d/statm", proc->pid);
|
|
|
|
f = fopen(buf, "r");
|
2020-04-22 06:30:30 -07:00
|
|
|
if (!f) return;
|
|
|
|
|
|
|
|
if (fgets(buf, sizeof(buf), f))
|
|
|
|
{
|
2020-05-11 02:22:26 -07:00
|
|
|
if (sscanf(buf, "%u %u %u %u %u %u %u",
|
|
|
|
&size, &resident, &shared, &text,
|
2020-04-22 06:30:30 -07:00
|
|
|
&dummy, &data, &dummy) == 7)
|
|
|
|
{
|
2020-07-09 15:39:15 -07:00
|
|
|
proc->mem_rss = MEMSZ(resident) * MEMSZ(pagesize);
|
|
|
|
proc->mem_shared = MEMSZ(shared) * MEMSZ(pagesize);
|
2020-05-11 08:12:04 -07:00
|
|
|
proc->mem_size = proc->mem_rss - proc->mem_shared;
|
2020-07-09 15:39:15 -07:00
|
|
|
proc->mem_virt = MEMSZ(size) * MEMSZ(pagesize);
|
2020-04-22 06:30:30 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
fclose(f);
|
|
|
|
}
|
|
|
|
|
2020-04-22 09:14:23 -07:00
|
|
|
static void
|
2020-05-12 18:11:10 -07:00
|
|
|
_cmd_args(Proc_Info *p, char *name, size_t len)
|
2020-04-22 09:14:23 -07:00
|
|
|
{
|
2021-01-19 02:04:24 -08:00
|
|
|
char buf[8192];
|
2020-05-12 18:11:10 -07:00
|
|
|
int pid = p->pid;
|
2020-04-22 09:14:23 -07:00
|
|
|
|
2021-01-03 14:34:00 -08:00
|
|
|
snprintf(buf, sizeof(buf), "/proc/%d/exe", pid);
|
|
|
|
char *link = ecore_file_readlink(buf);
|
2020-04-22 09:14:23 -07:00
|
|
|
if (link)
|
|
|
|
{
|
|
|
|
snprintf(name, len, "%s", ecore_file_file_get(link));
|
|
|
|
free(link);
|
|
|
|
}
|
2020-05-08 16:14:30 -07:00
|
|
|
|
2021-01-03 14:34:00 -08:00
|
|
|
snprintf(buf, sizeof(buf), "/proc/%d/cmdline", pid);
|
|
|
|
FILE *f = fopen(buf, "r");
|
2020-05-08 16:14:30 -07:00
|
|
|
if (f)
|
2020-04-22 09:14:23 -07:00
|
|
|
{
|
2021-01-03 14:34:00 -08:00
|
|
|
if (fgets(buf, sizeof(buf), f))
|
2020-04-22 09:14:23 -07:00
|
|
|
{
|
2021-01-03 14:34:00 -08:00
|
|
|
Eina_Strbuf *b = eina_strbuf_new();
|
2020-05-08 16:14:30 -07:00
|
|
|
const char *n;
|
|
|
|
|
2021-01-03 14:34:00 -08:00
|
|
|
if (ecore_file_exists(buf))
|
|
|
|
snprintf(name, len, "%s", ecore_file_file_get(buf));
|
2020-05-08 16:14:30 -07:00
|
|
|
|
2021-01-03 14:34:00 -08:00
|
|
|
n = buf;
|
2021-01-19 02:04:24 -08:00
|
|
|
while (n && *n && (*n + 1))
|
2020-04-22 09:14:23 -07:00
|
|
|
{
|
2021-01-03 14:34:00 -08:00
|
|
|
eina_strbuf_append(b, n);
|
2020-05-12 11:51:05 -07:00
|
|
|
n = strchr(n, '\0') + 1;
|
2021-01-19 02:04:24 -08:00
|
|
|
if (n && *n && (*n + 1)) eina_strbuf_append(b, " ");
|
2020-04-22 09:14:23 -07:00
|
|
|
}
|
2021-01-03 14:34:00 -08:00
|
|
|
p->arguments = eina_strbuf_release(b);
|
2020-04-22 09:14:23 -07:00
|
|
|
}
|
2020-05-08 16:14:30 -07:00
|
|
|
fclose(f);
|
2020-04-22 09:14:23 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
char *end = strchr(name, ' ');
|
|
|
|
if (end) *end = '\0';
|
|
|
|
|
|
|
|
p->command = strdup(name);
|
|
|
|
}
|
|
|
|
|
|
|
|
static int
|
|
|
|
_uid(int pid)
|
|
|
|
{
|
|
|
|
FILE *f;
|
2021-01-03 14:34:00 -08:00
|
|
|
char buf[4096];
|
2020-12-24 02:46:35 -08:00
|
|
|
int uid = 0;
|
2020-04-22 09:14:23 -07:00
|
|
|
|
2021-01-03 14:34:00 -08:00
|
|
|
snprintf(buf, sizeof(buf),"/proc/%d/status", pid);
|
|
|
|
f = fopen(buf, "r");
|
2020-04-22 09:14:23 -07:00
|
|
|
if (!f) return -1;
|
|
|
|
|
2021-01-03 14:34:00 -08:00
|
|
|
while ((fgets(buf, sizeof(buf), f)) != NULL)
|
2020-04-22 09:14:23 -07:00
|
|
|
{
|
2021-01-03 14:34:00 -08:00
|
|
|
if (!strncmp(buf, "Uid:", 4))
|
2020-04-22 09:14:23 -07:00
|
|
|
{
|
2021-01-03 14:34:00 -08:00
|
|
|
uid = _parse_line(buf);
|
2020-04-22 09:14:23 -07:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
fclose(f);
|
|
|
|
|
|
|
|
return uid;
|
|
|
|
}
|
|
|
|
|
2020-08-16 06:56:50 -07:00
|
|
|
static int64_t
|
|
|
|
_boot_time(void)
|
|
|
|
{
|
|
|
|
FILE *f;
|
|
|
|
int64_t boot_time;
|
|
|
|
char buf[4096];
|
|
|
|
double uptime = 0.0;
|
|
|
|
|
|
|
|
f = fopen("/proc/uptime", "r");
|
|
|
|
if (!f) return 0;
|
|
|
|
|
|
|
|
if (fgets(buf, sizeof(buf), f))
|
|
|
|
sscanf(buf, "%lf", &uptime);
|
|
|
|
else boot_time = 0;
|
|
|
|
|
|
|
|
fclose(f);
|
|
|
|
|
|
|
|
if (uptime > 0.0)
|
|
|
|
boot_time = time(NULL) - (time_t) uptime;
|
|
|
|
|
|
|
|
return boot_time;
|
|
|
|
}
|
|
|
|
|
2020-05-12 11:51:05 -07:00
|
|
|
typedef struct {
|
2020-08-11 04:21:40 -07:00
|
|
|
int pid, ppid, utime, stime, cutime, cstime;
|
2020-05-12 11:51:05 -07:00
|
|
|
int psr, pri, nice, numthreads;
|
2021-02-02 05:54:49 -08:00
|
|
|
long long int start_time, run_time;
|
2020-05-12 11:51:05 -07:00
|
|
|
char state;
|
|
|
|
unsigned int mem_rss, flags;
|
|
|
|
unsigned long mem_virt;
|
|
|
|
char name[1024];
|
|
|
|
} Stat;
|
|
|
|
|
|
|
|
static Eina_Bool
|
|
|
|
_stat(const char *path, Stat *st)
|
|
|
|
{
|
|
|
|
FILE *f;
|
|
|
|
char line[4096];
|
2021-02-08 12:43:51 -08:00
|
|
|
char name[1024];
|
|
|
|
int dummy, len = 0;
|
2021-02-02 05:54:49 -08:00
|
|
|
static long tck = 0;
|
2020-08-16 06:56:50 -07:00
|
|
|
static int64_t boot_time = 0;
|
|
|
|
|
|
|
|
if (!boot_time) boot_time = _boot_time();
|
2020-05-12 11:51:05 -07:00
|
|
|
|
|
|
|
memset(st, 0, sizeof(Stat));
|
|
|
|
|
|
|
|
f = fopen(path, "r");
|
2021-01-24 05:48:40 -08:00
|
|
|
if (!f) return 0;
|
2020-05-12 11:51:05 -07:00
|
|
|
|
|
|
|
if (fgets(line, sizeof(line), f))
|
|
|
|
{
|
|
|
|
|
2021-02-08 12:43:51 -08:00
|
|
|
len = sscanf(line, "%d %s %c %d %d %d %d %d %u %u %u %u %u %d %d %d"
|
2020-08-16 06:56:50 -07:00
|
|
|
" %d %d %d %u %u %lld %lu %u %u %u %u %u %u %u %d %d %d %d %u"
|
2021-02-08 12:43:51 -08:00
|
|
|
" %d %d %d %d %d %d %d %d %d", &dummy, name,
|
2020-08-11 04:21:40 -07:00
|
|
|
&st->state, &st->ppid, &dummy, &dummy, &dummy, &dummy, &st->flags,
|
2020-05-12 11:51:05 -07:00
|
|
|
&dummy, &dummy, &dummy, &dummy, &st->utime, &st->stime, &st->cutime,
|
2020-08-16 06:56:50 -07:00
|
|
|
&st->cstime, &st->pri, &st->nice, &st->numthreads, &dummy, &st->start_time,
|
2020-05-12 11:51:05 -07:00
|
|
|
&st->mem_virt, &st->mem_rss, &dummy, &dummy, &dummy, &dummy, &dummy,
|
|
|
|
&dummy, &dummy, &dummy, &dummy, &dummy, &dummy, &dummy,
|
|
|
|
&dummy, &dummy, &st->psr, &dummy, &dummy, &dummy, &dummy, &dummy);
|
|
|
|
}
|
|
|
|
fclose(f);
|
|
|
|
|
2021-02-08 12:43:51 -08:00
|
|
|
if (len != 44) return 0;
|
|
|
|
|
|
|
|
len = strlen(name);
|
|
|
|
if (len)
|
|
|
|
{
|
|
|
|
name[len-1] = '\0';
|
|
|
|
snprintf(st->name, sizeof(st->name), "%s", &name[1]);
|
|
|
|
}
|
2020-05-12 11:51:05 -07:00
|
|
|
|
2021-02-02 05:54:49 -08:00
|
|
|
if (!tck) tck = sysconf(_SC_CLK_TCK);
|
|
|
|
|
|
|
|
st->start_time /= tck;
|
2020-08-16 06:56:50 -07:00
|
|
|
st->start_time += boot_time;
|
2021-02-02 05:54:49 -08:00
|
|
|
st->run_time = (st->utime + st->stime) / tck;
|
2020-08-16 06:56:50 -07:00
|
|
|
|
2021-01-24 05:48:40 -08:00
|
|
|
return 1;
|
2020-05-12 11:51:05 -07:00
|
|
|
}
|
|
|
|
|
2021-02-26 00:14:58 -08:00
|
|
|
static int
|
|
|
|
_n_files(Proc_Info *p)
|
|
|
|
{
|
2021-02-27 11:11:19 -08:00
|
|
|
char buf[256];
|
|
|
|
Eina_List *files;
|
|
|
|
char *f;
|
2021-02-26 00:14:58 -08:00
|
|
|
|
|
|
|
snprintf(buf, sizeof(buf), "/proc/%d/fd", p->pid);
|
|
|
|
|
2021-02-27 11:11:19 -08:00
|
|
|
files = ecore_file_ls(buf);
|
|
|
|
EINA_LIST_FREE(files, f)
|
|
|
|
{
|
|
|
|
p->numfiles++;
|
2021-02-28 23:32:18 -08:00
|
|
|
free(f);
|
2021-02-27 11:11:19 -08:00
|
|
|
}
|
2021-02-26 00:14:58 -08:00
|
|
|
return p->numfiles;
|
|
|
|
}
|
|
|
|
|
2018-06-04 03:11:21 -07:00
|
|
|
static Eina_List *
|
|
|
|
_process_list_linux_get(void)
|
|
|
|
{
|
2020-02-16 11:34:41 -08:00
|
|
|
Eina_List *files, *list;
|
2021-02-02 13:55:40 -08:00
|
|
|
const char *state;
|
2020-04-22 09:14:23 -07:00
|
|
|
char *n;
|
2021-01-03 14:34:00 -08:00
|
|
|
char buf[4096];
|
2020-05-12 11:51:05 -07:00
|
|
|
Stat st;
|
2018-06-04 03:11:21 -07:00
|
|
|
|
2020-02-16 11:34:41 -08:00
|
|
|
list = NULL;
|
|
|
|
|
2018-06-04 03:11:21 -07:00
|
|
|
files = ecore_file_ls("/proc");
|
2020-04-22 06:30:30 -07:00
|
|
|
EINA_LIST_FREE(files, n)
|
2018-06-04 03:11:21 -07:00
|
|
|
{
|
2020-05-12 11:51:05 -07:00
|
|
|
int pid = atoi(n);
|
2020-04-22 06:30:30 -07:00
|
|
|
free(n);
|
2018-06-04 03:11:21 -07:00
|
|
|
|
|
|
|
if (!pid) continue;
|
|
|
|
|
2021-01-03 14:34:00 -08:00
|
|
|
snprintf(buf, sizeof(buf), "/proc/%d/stat", pid);
|
|
|
|
if (!_stat(buf, &st))
|
2020-05-12 11:51:05 -07:00
|
|
|
continue;
|
2018-06-04 03:11:21 -07:00
|
|
|
|
2020-07-31 11:13:23 -07:00
|
|
|
if (st.flags & PF_KTHREAD && !proc_info_kthreads_show_get())
|
|
|
|
continue;
|
2020-04-14 10:24:27 -07:00
|
|
|
|
2020-04-22 02:10:02 -07:00
|
|
|
Proc_Info *p = calloc(1, sizeof(Proc_Info));
|
|
|
|
if (!p) return NULL;
|
|
|
|
|
2018-06-04 03:11:21 -07:00
|
|
|
p->pid = pid;
|
2020-08-11 04:21:40 -07:00
|
|
|
p->ppid = st.ppid;
|
2020-04-22 09:14:23 -07:00
|
|
|
p->uid = _uid(pid);
|
2020-05-12 11:51:05 -07:00
|
|
|
p->cpu_id = st.psr;
|
2020-08-16 06:56:50 -07:00
|
|
|
p->start = st.start_time;
|
2021-02-02 05:54:49 -08:00
|
|
|
p->run_time = st.run_time;
|
2021-02-02 13:55:40 -08:00
|
|
|
state = _process_state_name(st.state);
|
2021-02-02 13:33:09 -08:00
|
|
|
snprintf(p->state, sizeof(p->state), "%s", state);
|
2020-05-12 11:51:05 -07:00
|
|
|
p->cpu_time = st.utime + st.stime;
|
|
|
|
p->nice = st.nice;
|
|
|
|
p->priority = st.pri;
|
|
|
|
p->numthreads = st.numthreads;
|
2021-02-26 00:14:58 -08:00
|
|
|
p->numfiles = _n_files(p);
|
2020-11-11 20:08:10 -08:00
|
|
|
if (st.flags & PF_KTHREAD)
|
2020-11-11 19:56:37 -08:00
|
|
|
p->is_kernel = 1;
|
2020-05-12 18:11:10 -07:00
|
|
|
_mem_size(p);
|
|
|
|
_cmd_args(p, st.name, sizeof(st.name));
|
2020-04-22 09:14:23 -07:00
|
|
|
|
2018-06-04 03:11:21 -07:00
|
|
|
list = eina_list_append(list, p);
|
|
|
|
}
|
|
|
|
|
|
|
|
return list;
|
|
|
|
}
|
|
|
|
|
2020-05-12 12:34:07 -07:00
|
|
|
static void
|
|
|
|
_proc_thread_info(Proc_Info *p)
|
|
|
|
{
|
|
|
|
Eina_List *files;
|
2021-02-02 13:55:40 -08:00
|
|
|
const char *state;
|
2020-05-12 12:34:07 -07:00
|
|
|
char *n;
|
2021-01-03 14:34:00 -08:00
|
|
|
char buf[4096];
|
2020-05-12 12:34:07 -07:00
|
|
|
Stat st;
|
|
|
|
|
2021-01-03 14:34:00 -08:00
|
|
|
snprintf(buf, sizeof(buf), "/proc/%d/task", p->pid);
|
|
|
|
files = ecore_file_ls(buf);
|
2020-05-12 12:34:07 -07:00
|
|
|
EINA_LIST_FREE(files, n)
|
|
|
|
{
|
|
|
|
int tid = atoi(n);
|
|
|
|
free(n);
|
2021-01-03 14:34:00 -08:00
|
|
|
snprintf(buf, sizeof(buf), "/proc/%d/task/%d/stat", p->pid, tid);
|
|
|
|
if (!_stat(buf, &st))
|
2020-05-12 12:34:07 -07:00
|
|
|
continue;
|
|
|
|
|
|
|
|
Proc_Info *t = calloc(1, sizeof(Proc_Info));
|
|
|
|
if (!t) continue;
|
|
|
|
t->cpu_id = st.psr;
|
2021-02-02 13:55:40 -08:00
|
|
|
state = _process_state_name(st.state);
|
|
|
|
snprintf(t->state, sizeof(t->state), "%s", state);
|
2020-05-12 12:34:07 -07:00
|
|
|
t->cpu_time = st.utime + st.stime;
|
|
|
|
t->nice = st.nice;
|
|
|
|
t->priority = st.pri;
|
|
|
|
t->numthreads = st.numthreads;
|
|
|
|
t->mem_virt = st.mem_virt;
|
|
|
|
t->mem_rss = st.mem_rss;
|
2020-05-15 13:17:00 -07:00
|
|
|
|
|
|
|
t->tid = tid;
|
|
|
|
t->thread_name = strdup(st.name);
|
|
|
|
|
2020-05-12 12:34:07 -07:00
|
|
|
p->threads = eina_list_append(p->threads, t);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-04-16 14:03:25 -07:00
|
|
|
Proc_Info *
|
2018-06-04 03:11:21 -07:00
|
|
|
proc_info_by_pid(int pid)
|
|
|
|
{
|
2021-02-02 13:33:09 -08:00
|
|
|
const char *state;
|
2020-05-12 11:51:05 -07:00
|
|
|
Stat st;
|
2021-01-03 14:34:00 -08:00
|
|
|
char buf[4096];
|
2018-06-04 03:11:21 -07:00
|
|
|
|
2021-01-03 14:34:00 -08:00
|
|
|
snprintf(buf, sizeof(buf), "/proc/%d/stat", pid);
|
|
|
|
if (!_stat(buf, &st))
|
2020-05-12 11:51:05 -07:00
|
|
|
return NULL;
|
2018-06-04 03:11:21 -07:00
|
|
|
|
2020-04-22 02:10:02 -07:00
|
|
|
Proc_Info *p = calloc(1, sizeof(Proc_Info));
|
|
|
|
if (!p) return NULL;
|
|
|
|
|
2018-06-04 03:11:21 -07:00
|
|
|
p->pid = pid;
|
2020-08-11 04:21:40 -07:00
|
|
|
p->ppid = st.ppid;
|
2020-04-22 09:14:23 -07:00
|
|
|
p->uid = _uid(pid);
|
2020-05-12 11:51:05 -07:00
|
|
|
p->cpu_id = st.psr;
|
2020-08-16 06:56:50 -07:00
|
|
|
p->start = st.start_time;
|
2021-02-02 05:54:49 -08:00
|
|
|
p->run_time = st.run_time;
|
2021-02-02 13:33:09 -08:00
|
|
|
state = _process_state_name(st.state);
|
|
|
|
snprintf(p->state, sizeof(p->state), "%s", state);
|
2020-05-12 11:51:05 -07:00
|
|
|
p->cpu_time = st.utime + st.stime;
|
|
|
|
p->priority = st.pri;
|
|
|
|
p->nice = st.nice;
|
|
|
|
p->numthreads = st.numthreads;
|
2021-02-26 00:14:58 -08:00
|
|
|
p->numfiles = _n_files(p);
|
2020-11-16 17:53:59 -08:00
|
|
|
if (st.flags & PF_KTHREAD) p->is_kernel = 1;
|
2020-05-12 18:11:10 -07:00
|
|
|
_mem_size(p);
|
|
|
|
_cmd_args(p, st.name, sizeof(st.name));
|
2020-04-22 09:14:23 -07:00
|
|
|
|
2020-05-12 12:34:07 -07:00
|
|
|
_proc_thread_info(p);
|
|
|
|
|
2018-06-04 03:11:21 -07:00
|
|
|
return p;
|
|
|
|
}
|
|
|
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#if defined(__OpenBSD__)
|
|
|
|
|
2020-05-15 16:13:18 -07:00
|
|
|
static void
|
|
|
|
_proc_get(Proc_Info *p, struct kinfo_proc *kp)
|
2018-06-04 03:11:21 -07:00
|
|
|
{
|
2020-05-15 16:13:18 -07:00
|
|
|
static int pagesize = 0;
|
2021-02-02 12:18:54 -08:00
|
|
|
const char *state;
|
2018-06-04 03:11:21 -07:00
|
|
|
|
2020-05-15 16:13:18 -07:00
|
|
|
if (!pagesize) pagesize = getpagesize();
|
2020-02-15 18:03:32 -08:00
|
|
|
|
2018-06-04 03:11:21 -07:00
|
|
|
p->pid = kp->p_pid;
|
2020-08-11 04:54:06 -07:00
|
|
|
p->ppid = kp->p_ppid;
|
2018-06-04 03:11:21 -07:00
|
|
|
p->uid = kp->p_uid;
|
|
|
|
p->cpu_id = kp->p_cpuid;
|
2020-08-16 06:56:27 -07:00
|
|
|
p->start = kp->p_ustart_sec;
|
2021-02-02 12:18:54 -08:00
|
|
|
p->run_time = kp->p_uutime_sec + kp->p_ustime_sec +
|
|
|
|
(kp->p_uutime_usec / 1000000) + (kp->p_ustime_usec / 1000000);
|
2021-03-01 13:58:15 -08:00
|
|
|
|
|
|
|
state = _process_state_name(kp->p_stat);
|
2021-02-02 12:18:54 -08:00
|
|
|
snprintf(p->state, sizeof(p->state), "%s", state);
|
2021-03-01 13:58:15 -08:00
|
|
|
snprintf(p->wchan, sizeof(p->wchan), "%s", kp->p_wmesg);
|
2018-06-04 03:11:21 -07:00
|
|
|
p->cpu_time = kp->p_uticks + kp->p_sticks + kp->p_iticks;
|
2020-07-09 15:39:15 -07:00
|
|
|
p->mem_virt = p->mem_size = (MEMSZ(kp->p_vm_tsize) * MEMSZ(pagesize)) +
|
|
|
|
(MEMSZ(kp->p_vm_dsize) * MEMSZ(pagesize)) + (MEMSZ(kp->p_vm_ssize) * MEMSZ(pagesize));
|
|
|
|
p->mem_rss = MEMSZ(kp->p_vm_rssize) * MEMSZ(pagesize);
|
2018-06-04 03:11:21 -07:00
|
|
|
p->priority = kp->p_priority - PZERO;
|
|
|
|
p->nice = kp->p_nice - NZERO;
|
2020-05-15 16:13:18 -07:00
|
|
|
p->tid = kp->p_tid;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
2021-03-03 06:31:56 -08:00
|
|
|
_kvm_get(Proc_Info *p, kvm_t *kern, struct kinfo_proc *kp)
|
2020-05-15 16:13:18 -07:00
|
|
|
{
|
|
|
|
char **args;
|
2021-01-03 14:34:00 -08:00
|
|
|
char name[4096];
|
2018-06-04 03:11:21 -07:00
|
|
|
|
2020-04-22 02:52:22 -07:00
|
|
|
if ((args = kvm_getargv(kern, kp, sizeof(name)-1)))
|
2020-04-21 13:44:24 -07:00
|
|
|
{
|
2020-04-22 02:52:22 -07:00
|
|
|
Eina_Strbuf *buf = eina_strbuf_new();
|
|
|
|
for (int i = 0; args[i]; i++)
|
2020-04-21 13:44:24 -07:00
|
|
|
{
|
2020-04-22 02:52:22 -07:00
|
|
|
eina_strbuf_append(buf, args[i]);
|
2020-05-15 08:15:27 -07:00
|
|
|
if (args[i + 1])
|
|
|
|
eina_strbuf_append(buf, " ");
|
2020-04-21 13:44:24 -07:00
|
|
|
}
|
2020-04-22 02:52:22 -07:00
|
|
|
p->arguments = eina_strbuf_string_steal(buf);
|
|
|
|
eina_strbuf_free(buf);
|
2020-05-11 09:52:48 -07:00
|
|
|
|
|
|
|
if (args[0] && ecore_file_exists(args[0]))
|
|
|
|
p->command = strdup(ecore_file_file_get(args[0]));
|
2020-04-21 13:44:24 -07:00
|
|
|
}
|
2021-03-03 06:31:56 -08:00
|
|
|
struct kinfo_file *kf;
|
|
|
|
int n;
|
|
|
|
|
|
|
|
if ((kf = kvm_getfiles(kern, KERN_FILE_BYPID, -1, sizeof(struct kinfo_file), &n)))
|
|
|
|
{
|
|
|
|
for (int i = 0; i < n; i++)
|
|
|
|
{
|
|
|
|
if (kf[i].p_pid == kp->p_pid)
|
|
|
|
{
|
|
|
|
if (kf[i].fd_fd >= 0) p->numfiles++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2020-04-21 13:44:24 -07:00
|
|
|
|
2020-05-11 09:52:48 -07:00
|
|
|
if (!p->command)
|
|
|
|
p->command = strdup(kp->p_comm);
|
2020-05-15 16:13:18 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
Proc_Info *
|
|
|
|
proc_info_by_pid(int pid)
|
|
|
|
{
|
|
|
|
struct kinfo_proc *kp, *kpt;
|
|
|
|
kvm_t *kern;
|
|
|
|
char errbuf[_POSIX2_LINE_MAX];
|
|
|
|
int count, pid_count;
|
|
|
|
|
|
|
|
kern = kvm_openfiles(NULL, NULL, NULL, KVM_NO_FILES, errbuf);
|
|
|
|
if (!kern) return NULL;
|
|
|
|
|
|
|
|
kp = kvm_getprocs(kern, KERN_PROC_PID, pid, sizeof(*kp), &count);
|
|
|
|
if (!kp) return NULL;
|
|
|
|
|
|
|
|
if (count == 0) return NULL;
|
|
|
|
|
|
|
|
Proc_Info *p = calloc(1, sizeof(Proc_Info));
|
|
|
|
if (!p) return NULL;
|
|
|
|
|
|
|
|
_proc_get(p, kp);
|
2021-03-03 06:31:56 -08:00
|
|
|
_kvm_get(p, kern, kp);
|
2020-05-11 09:52:48 -07:00
|
|
|
|
2018-06-04 03:11:21 -07:00
|
|
|
kp = kvm_getprocs(kern, KERN_PROC_SHOW_THREADS, 0, sizeof(*kp), &pid_count);
|
|
|
|
|
|
|
|
for (int i = 0; i < pid_count; i++)
|
|
|
|
{
|
2020-05-15 08:15:27 -07:00
|
|
|
if (kp[i].p_pid != p->pid) continue;
|
|
|
|
|
|
|
|
kpt = &kp[i];
|
2020-05-15 16:13:18 -07:00
|
|
|
|
|
|
|
if (kpt->p_tid <= 0) continue;
|
2020-05-15 08:15:27 -07:00
|
|
|
|
|
|
|
Proc_Info *t = calloc(1, sizeof(Proc_Info));
|
|
|
|
if (!t) continue;
|
|
|
|
|
2020-05-15 16:13:18 -07:00
|
|
|
_proc_get(t, kpt);
|
|
|
|
|
|
|
|
t->tid = kpt->p_tid;
|
|
|
|
t->thread_name = strdup(kpt->p_comm);
|
2020-05-15 08:15:27 -07:00
|
|
|
|
|
|
|
p->threads = eina_list_append(p->threads, t);
|
2018-06-04 03:11:21 -07:00
|
|
|
}
|
|
|
|
|
2020-05-15 16:13:18 -07:00
|
|
|
p->numthreads = eina_list_count(p->threads);
|
|
|
|
|
2018-06-04 03:11:21 -07:00
|
|
|
kvm_close(kern);
|
|
|
|
|
|
|
|
return p;
|
|
|
|
}
|
|
|
|
|
|
|
|
static Eina_List *
|
|
|
|
_process_list_openbsd_get(void)
|
|
|
|
{
|
2020-04-21 13:44:24 -07:00
|
|
|
struct kinfo_proc *kps, *kp;
|
2020-04-16 14:03:25 -07:00
|
|
|
Proc_Info *p;
|
2018-06-04 03:11:21 -07:00
|
|
|
char errbuf[4096];
|
|
|
|
kvm_t *kern;
|
2020-05-15 16:13:18 -07:00
|
|
|
int pid_count;
|
2020-04-21 13:44:24 -07:00
|
|
|
Eina_List *list = NULL;
|
2018-06-04 03:11:21 -07:00
|
|
|
|
|
|
|
kern = kvm_openfiles(NULL, NULL, NULL, KVM_NO_FILES, errbuf);
|
|
|
|
if (!kern) return NULL;
|
|
|
|
|
2020-04-21 13:44:24 -07:00
|
|
|
kps = kvm_getprocs(kern, KERN_PROC_ALL, 0, sizeof(*kps), &pid_count);
|
|
|
|
if (!kps) return NULL;
|
2018-06-04 03:11:21 -07:00
|
|
|
|
|
|
|
for (int i = 0; i < pid_count; i++)
|
|
|
|
{
|
2020-04-16 14:03:25 -07:00
|
|
|
p = calloc(1, sizeof(Proc_Info));
|
2020-02-15 18:03:32 -08:00
|
|
|
if (!p) return NULL;
|
|
|
|
|
2020-04-21 13:44:24 -07:00
|
|
|
kp = &kps[i];
|
2020-05-11 09:52:48 -07:00
|
|
|
|
2020-12-31 04:19:26 -08:00
|
|
|
Proc_Info *p = proc_info_by_pid(kp->p_pid);
|
|
|
|
if (p)
|
|
|
|
list = eina_list_append(list, p);
|
2018-06-04 03:11:21 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
kvm_close(kern);
|
|
|
|
|
|
|
|
return list;
|
|
|
|
}
|
|
|
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#if defined(__MacOS__)
|
2020-04-27 05:41:05 -07:00
|
|
|
static void
|
|
|
|
_cmd_get(Proc_Info *p, int pid)
|
|
|
|
{
|
|
|
|
char *cp, *args, **argv;
|
|
|
|
int mib[3], argmax, argc;
|
|
|
|
size_t size;
|
|
|
|
|
|
|
|
mib[0] = CTL_KERN;
|
|
|
|
mib[1] = KERN_ARGMAX;
|
|
|
|
|
|
|
|
size = sizeof(argmax);
|
|
|
|
|
|
|
|
if (sysctl(mib, 2, &argmax, &size, NULL, 0) == -1) return;
|
|
|
|
|
|
|
|
mib[0] = CTL_KERN;
|
|
|
|
mib[1] = KERN_PROCARGS2;
|
|
|
|
mib[2] = pid;
|
|
|
|
|
|
|
|
size = (size_t) argmax;
|
|
|
|
args = malloc(argmax);
|
|
|
|
if (!args) return;
|
|
|
|
|
2020-07-26 14:48:52 -07:00
|
|
|
/* See libtop.c (top) for the origin of this comment, which is necessary as
|
|
|
|
* there is little other documentation...thanks Apple.
|
|
|
|
*
|
2020-04-27 05:41:05 -07:00
|
|
|
* Make a sysctl() call to get the raw argument space of the process.
|
|
|
|
* The layout is documented in start.s, which is part of the Csu
|
|
|
|
* project. In summary, it looks like:
|
|
|
|
*
|
|
|
|
* /---------------\ 0x00000000
|
|
|
|
* : :
|
|
|
|
* : :
|
|
|
|
* |---------------|
|
|
|
|
* | argc |
|
|
|
|
* |---------------|
|
|
|
|
* | arg[0] |
|
|
|
|
* |---------------|
|
|
|
|
* : :
|
|
|
|
* : :
|
|
|
|
* |---------------|
|
|
|
|
* | arg[argc - 1] |
|
|
|
|
* |---------------|
|
|
|
|
* | 0 |
|
|
|
|
* |---------------|
|
|
|
|
* | env[0] |
|
|
|
|
* |---------------|
|
|
|
|
* : :
|
|
|
|
* : :
|
|
|
|
* |---------------|
|
|
|
|
* | env[n] |
|
|
|
|
* |---------------|
|
|
|
|
* | 0 |
|
|
|
|
* |---------------| <-- Beginning of data returned by sysctl() is here.
|
|
|
|
* | argc |
|
|
|
|
* |---------------|
|
|
|
|
* | exec_path |
|
|
|
|
* |:::::::::::::::|
|
|
|
|
* | |
|
|
|
|
* | String area. |
|
|
|
|
* | |
|
|
|
|
* |---------------| <-- Top of stack.
|
|
|
|
* : :
|
|
|
|
* : :
|
|
|
|
* \---------------/ 0xffffffff
|
|
|
|
*/
|
|
|
|
|
|
|
|
if (sysctl(mib, 3, args, &size, NULL, 0) == -1) return;
|
|
|
|
|
|
|
|
memcpy(&argc, args, sizeof(argc));
|
|
|
|
cp = args + sizeof(argc);
|
|
|
|
|
|
|
|
/* Skip exec path */
|
|
|
|
for (;cp < &args[size]; cp++)
|
|
|
|
{
|
|
|
|
if (*cp == '\0') break;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (cp == &args[size]) return;
|
|
|
|
|
2020-04-27 05:48:35 -07:00
|
|
|
/* Skip any padded NULLs. */
|
2020-04-27 05:41:05 -07:00
|
|
|
for (;cp < &args[size]; cp++)
|
|
|
|
{
|
|
|
|
if (*cp == '\0') break;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (cp == &args[size]) return;
|
|
|
|
|
|
|
|
argv = malloc(1 + argc * sizeof(char *));
|
|
|
|
if (!argv) return;
|
|
|
|
|
|
|
|
int i = 0;
|
|
|
|
argv[i] = cp;
|
|
|
|
|
|
|
|
for (cp = args + sizeof(int); cp < &args[size] && i < argc; cp++)
|
|
|
|
{
|
|
|
|
if (*cp == '\0')
|
|
|
|
{
|
|
|
|
while (*cp == '\0') cp++;
|
|
|
|
argv[i++] = cp;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (i == 0) i++;
|
|
|
|
|
|
|
|
argv[i] = NULL;
|
|
|
|
|
|
|
|
p->command = strdup(basename(argv[0]));
|
|
|
|
|
|
|
|
Eina_Strbuf *buf = eina_strbuf_new();
|
|
|
|
|
|
|
|
for (i = 0; i < argc; i++)
|
|
|
|
eina_strbuf_append_printf(buf, "%s ", argv[i]);
|
|
|
|
|
|
|
|
if (argc > 0)
|
|
|
|
p->arguments = eina_strbuf_release(buf);
|
|
|
|
else
|
|
|
|
eina_strbuf_free(buf);
|
|
|
|
|
|
|
|
free(args);
|
|
|
|
free(argv);
|
|
|
|
}
|
|
|
|
|
2020-05-15 15:00:44 -07:00
|
|
|
static Proc_Info *
|
|
|
|
_proc_pidinfo(size_t pid)
|
|
|
|
{
|
2021-02-02 13:33:09 -08:00
|
|
|
const char *state;
|
2020-05-15 15:00:44 -07:00
|
|
|
struct proc_taskallinfo taskinfo;
|
|
|
|
int size = proc_pidinfo(pid, PROC_PIDTASKALLINFO, 0, &taskinfo, sizeof(taskinfo));
|
|
|
|
if (size != sizeof(taskinfo)) return NULL;
|
|
|
|
|
|
|
|
Proc_Info *p = calloc(1, sizeof(Proc_Info));
|
|
|
|
if (!p) return NULL;
|
|
|
|
|
|
|
|
p->pid = pid;
|
2020-08-11 04:00:02 -07:00
|
|
|
p->ppid = taskinfo.pbsd.pbi_ppid;
|
2020-05-15 15:00:44 -07:00
|
|
|
p->uid = taskinfo.pbsd.pbi_uid;
|
|
|
|
p->cpu_id = -1;
|
|
|
|
p->cpu_time = taskinfo.ptinfo.pti_total_user +
|
|
|
|
taskinfo.ptinfo.pti_total_system;
|
|
|
|
p->cpu_time /= 10000000;
|
2020-08-16 07:07:00 -07:00
|
|
|
p->start = taskinfo.pbsd.pbi_start_tvsec;
|
2021-02-02 13:33:09 -08:00
|
|
|
state = _process_state_name(taskinfo.pbsd.pbi_status);
|
|
|
|
snprintf(p->state, sizeof(p->state), "%s", state);
|
2020-05-15 15:00:44 -07:00
|
|
|
p->mem_size = p->mem_virt = taskinfo.ptinfo.pti_virtual_size;
|
|
|
|
p->mem_rss = taskinfo.ptinfo.pti_resident_size;
|
|
|
|
p->priority = taskinfo.ptinfo.pti_priority;
|
|
|
|
p->nice = taskinfo.pbsd.pbi_nice;
|
|
|
|
p->numthreads = taskinfo.ptinfo.pti_threadnum;
|
|
|
|
_cmd_get(p, pid);
|
|
|
|
|
|
|
|
return p;
|
|
|
|
}
|
|
|
|
|
2018-06-04 03:11:21 -07:00
|
|
|
static Eina_List *
|
2020-05-15 15:00:44 -07:00
|
|
|
_process_list_macos_fallback_get(void)
|
2018-06-04 03:11:21 -07:00
|
|
|
{
|
|
|
|
Eina_List *list = NULL;
|
|
|
|
|
|
|
|
for (int i = 1; i <= PID_MAX; i++)
|
|
|
|
{
|
2020-05-15 15:00:44 -07:00
|
|
|
Proc_Info *p = _proc_pidinfo(i);
|
|
|
|
if (p)
|
|
|
|
list = eina_list_append(list, p);
|
|
|
|
}
|
2018-06-04 03:11:21 -07:00
|
|
|
|
2020-05-15 15:00:44 -07:00
|
|
|
return list;
|
|
|
|
}
|
2020-02-15 18:03:32 -08:00
|
|
|
|
2020-05-15 15:00:44 -07:00
|
|
|
static Eina_List *
|
|
|
|
_process_list_macos_get(void)
|
|
|
|
{
|
|
|
|
Eina_List *list = NULL;
|
|
|
|
pid_t *pids = NULL;
|
|
|
|
int size, pid_count;
|
2018-06-04 03:11:21 -07:00
|
|
|
|
2020-05-15 15:00:44 -07:00
|
|
|
size = proc_listpids(PROC_ALL_PIDS, 0, NULL, 0);
|
|
|
|
if (size == -1)
|
|
|
|
return _process_list_macos_fallback_get();
|
|
|
|
|
|
|
|
pids = malloc(size * sizeof(pid_t));
|
|
|
|
if (!pids) return NULL;
|
|
|
|
|
|
|
|
size = proc_listpids(PROC_ALL_PIDS, 0, pids, size * sizeof(pid_t));
|
|
|
|
if (size == -1)
|
|
|
|
{
|
|
|
|
free(pids);
|
|
|
|
return _process_list_macos_fallback_get();
|
|
|
|
}
|
|
|
|
|
|
|
|
pid_count = size / sizeof(pid_t);
|
|
|
|
for (int i = 0; i < pid_count; i++)
|
|
|
|
{
|
|
|
|
pid_t pid = pids[i];
|
|
|
|
Proc_Info *p = _proc_pidinfo(pid);
|
|
|
|
if (p)
|
|
|
|
list = eina_list_append(list, p);
|
2018-06-04 03:11:21 -07:00
|
|
|
}
|
|
|
|
|
2020-05-15 15:00:44 -07:00
|
|
|
free(pids);
|
|
|
|
|
2018-06-04 03:11:21 -07:00
|
|
|
return list;
|
|
|
|
}
|
|
|
|
|
2020-04-16 14:03:25 -07:00
|
|
|
Proc_Info *
|
2018-06-04 03:11:21 -07:00
|
|
|
proc_info_by_pid(int pid)
|
|
|
|
{
|
2021-02-02 13:33:09 -08:00
|
|
|
const char *state;
|
2018-06-04 03:11:21 -07:00
|
|
|
struct proc_taskallinfo taskinfo;
|
|
|
|
struct proc_workqueueinfo workqueue;
|
|
|
|
size_t size;
|
|
|
|
|
|
|
|
size = proc_pidinfo(pid, PROC_PIDTASKALLINFO, 0, &taskinfo, sizeof(taskinfo));
|
|
|
|
if (size != sizeof(taskinfo))
|
|
|
|
return NULL;
|
|
|
|
|
|
|
|
size = proc_pidinfo(pid, PROC_PIDWORKQUEUEINFO, 0, &workqueue, sizeof(workqueue));
|
|
|
|
if (size != sizeof(workqueue))
|
2020-05-11 09:00:33 -07:00
|
|
|
memset(&workqueue, 0, sizeof(struct proc_workqueueinfo));
|
2018-06-04 03:11:21 -07:00
|
|
|
|
2020-04-16 14:03:25 -07:00
|
|
|
Proc_Info *p = calloc(1, sizeof(Proc_Info));
|
2020-02-15 18:03:32 -08:00
|
|
|
if (!p) return NULL;
|
|
|
|
|
2018-06-04 03:11:21 -07:00
|
|
|
p->pid = pid;
|
|
|
|
p->uid = taskinfo.pbsd.pbi_uid;
|
2020-08-12 03:03:19 -07:00
|
|
|
p->ppid = taskinfo.pbsd.pbi_ppid;
|
2018-06-04 03:11:21 -07:00
|
|
|
p->cpu_id = workqueue.pwq_nthreads;
|
2020-05-11 02:22:26 -07:00
|
|
|
p->cpu_time = taskinfo.ptinfo.pti_total_user +
|
|
|
|
taskinfo.ptinfo.pti_total_system;
|
2018-06-04 03:11:21 -07:00
|
|
|
p->cpu_time /= 10000000;
|
2020-08-16 07:07:00 -07:00
|
|
|
p->start = taskinfo.pbsd.pbi_start_tvsec;
|
2021-02-02 13:33:09 -08:00
|
|
|
state = _process_state_name(taskinfo.pbsd.pbi_status);
|
|
|
|
snprintf(p->state, sizeof(p->state), "%s", state);
|
2020-04-22 07:22:25 -07:00
|
|
|
p->mem_size = p->mem_virt = taskinfo.ptinfo.pti_virtual_size;
|
2018-06-04 03:11:21 -07:00
|
|
|
p->mem_rss = taskinfo.ptinfo.pti_resident_size;
|
|
|
|
p->priority = taskinfo.ptinfo.pti_priority;
|
|
|
|
p->nice = taskinfo.pbsd.pbi_nice;
|
|
|
|
p->numthreads = taskinfo.ptinfo.pti_threadnum;
|
2020-04-27 05:41:05 -07:00
|
|
|
_cmd_get(p, pid);
|
2018-06-04 03:11:21 -07:00
|
|
|
|
|
|
|
return p;
|
|
|
|
}
|
|
|
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#if defined(__FreeBSD__) || defined(__DragonFly__)
|
2020-04-29 01:50:55 -07:00
|
|
|
|
|
|
|
static int
|
|
|
|
_pid_max(void)
|
|
|
|
{
|
|
|
|
size_t len;
|
|
|
|
static int pid_max = 0;
|
|
|
|
|
|
|
|
if (pid_max != 0) return pid_max;
|
|
|
|
|
|
|
|
len = sizeof(pid_max);
|
|
|
|
if (sysctlbyname("kern.pid_max", &pid_max, &len, NULL, 0) == -1)
|
|
|
|
{
|
|
|
|
#if defined(__FreeBSD__)
|
|
|
|
pid_max = 99999;
|
|
|
|
#elif defined(__DragonFly__)
|
|
|
|
pid_max = 999999;
|
|
|
|
#else
|
|
|
|
pid_max = PID_MAX;
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
|
|
|
return pid_max;
|
|
|
|
}
|
|
|
|
|
2020-05-15 06:27:34 -07:00
|
|
|
static void
|
2021-02-26 09:34:56 -08:00
|
|
|
_kvm_get(Proc_Info *p, struct kinfo_proc *kp)
|
2020-05-15 06:27:34 -07:00
|
|
|
{
|
|
|
|
kvm_t * kern;
|
2021-01-03 14:34:00 -08:00
|
|
|
char name[4096];
|
2021-01-24 05:48:40 -08:00
|
|
|
Eina_Bool have_command = 0;
|
2020-05-15 06:27:34 -07:00
|
|
|
|
2021-02-26 09:34:56 -08:00
|
|
|
kern = kvm_open(NULL, "/dev/mem", NULL, O_RDONLY, "kvm_open");
|
|
|
|
if (!kern) goto nokvm;
|
|
|
|
char **args;
|
|
|
|
if ((args = kvm_getargv(kern, kp, sizeof(name)-1)) && (args[0]))
|
2020-05-15 06:27:34 -07:00
|
|
|
{
|
2021-02-26 09:34:56 -08:00
|
|
|
char *base = strdup(args[0]);
|
|
|
|
if (base)
|
2020-05-15 06:27:34 -07:00
|
|
|
{
|
2021-02-26 09:34:56 -08:00
|
|
|
char *spc = strchr(base, ' ');
|
|
|
|
if (spc) *spc = '\0';
|
|
|
|
|
|
|
|
if (ecore_file_exists(base))
|
2020-05-15 06:27:34 -07:00
|
|
|
{
|
2021-02-26 09:34:56 -08:00
|
|
|
snprintf(name, sizeof(name), "%s", basename(base));
|
|
|
|
have_command = 1;
|
2020-05-15 06:27:34 -07:00
|
|
|
}
|
2021-02-26 09:34:56 -08:00
|
|
|
free(base);
|
|
|
|
}
|
|
|
|
Eina_Strbuf *buf = eina_strbuf_new();
|
|
|
|
for (int i = 0; args[i] != NULL; i++)
|
|
|
|
{
|
|
|
|
eina_strbuf_append(buf, args[i]);
|
|
|
|
if (args[i + 1])
|
|
|
|
eina_strbuf_append(buf, " ");
|
|
|
|
}
|
|
|
|
p->arguments = eina_strbuf_string_steal(buf);
|
|
|
|
eina_strbuf_free(buf);
|
|
|
|
}
|
|
|
|
|
|
|
|
struct filedesc filed;
|
|
|
|
struct fdescenttbl *fdt;
|
|
|
|
unsigned int n;
|
|
|
|
|
|
|
|
if (!kvm_read(kern, (unsigned long)kp->ki_fd, &filed, sizeof(filed)))
|
|
|
|
goto kvmerror;
|
|
|
|
|
|
|
|
if (!kvm_read(kern, (unsigned long)filed.fd_files, &n, sizeof(n)))
|
|
|
|
goto kvmerror;
|
|
|
|
|
|
|
|
unsigned int size = sizeof(*fdt) + n * sizeof(struct filedescent);
|
|
|
|
fdt = malloc(size);
|
|
|
|
if (fdt)
|
|
|
|
{
|
|
|
|
if (kvm_read(kern, (unsigned long)filed.fd_files, fdt, size))
|
|
|
|
{
|
|
|
|
for (int i = 0; i < n; i++)
|
2020-05-15 06:27:34 -07:00
|
|
|
{
|
2021-02-26 09:34:56 -08:00
|
|
|
if (!fdt->fdt_ofiles[i].fde_file) continue;
|
|
|
|
p->numfiles++;
|
2020-05-15 06:27:34 -07:00
|
|
|
}
|
|
|
|
}
|
2021-02-26 09:34:56 -08:00
|
|
|
free(fdt);
|
2020-05-15 06:27:34 -07:00
|
|
|
}
|
|
|
|
|
2021-02-26 09:34:56 -08:00
|
|
|
kvmerror:
|
|
|
|
if (kern)
|
|
|
|
kvm_close(kern);
|
|
|
|
nokvm:
|
2020-05-15 06:27:34 -07:00
|
|
|
if (!have_command)
|
|
|
|
snprintf(name, sizeof(name), "%s", kp->ki_comm);
|
|
|
|
|
|
|
|
p->command = strdup(name);
|
|
|
|
}
|
|
|
|
|
2020-05-16 03:57:57 -07:00
|
|
|
static Proc_Info *
|
|
|
|
_proc_thread_info(struct kinfo_proc *kp, Eina_Bool is_thread)
|
|
|
|
{
|
|
|
|
struct rusage *usage;
|
2021-02-02 13:33:09 -08:00
|
|
|
const char *state;
|
2020-05-16 03:57:57 -07:00
|
|
|
Proc_Info *p;
|
|
|
|
static int pagesize = 0;
|
|
|
|
|
|
|
|
if (!pagesize) pagesize = getpagesize();
|
|
|
|
|
|
|
|
p = calloc(1, sizeof(Proc_Info));
|
|
|
|
if (!p) return NULL;
|
|
|
|
|
|
|
|
p->pid = kp->ki_pid;
|
2020-08-11 03:49:49 -07:00
|
|
|
p->ppid = kp->ki_ppid;
|
2020-05-16 03:57:57 -07:00
|
|
|
p->uid = kp->ki_uid;
|
|
|
|
|
|
|
|
if (!is_thread)
|
2021-02-26 09:34:56 -08:00
|
|
|
_kvm_get(p, kp);
|
2020-05-16 03:57:57 -07:00
|
|
|
|
|
|
|
p->cpu_id = kp->ki_oncpu;
|
|
|
|
if (p->cpu_id == -1)
|
|
|
|
p->cpu_id = kp->ki_lastcpu;
|
|
|
|
|
|
|
|
usage = &kp->ki_rusage;
|
|
|
|
|
2021-02-02 06:18:05 -08:00
|
|
|
p->cpu_time = ((usage->ru_utime.tv_sec * 1000000) + usage->ru_utime.tv_usec +
|
|
|
|
(usage->ru_stime.tv_sec * 1000000) + usage->ru_stime.tv_usec) / 10000;
|
|
|
|
p->run_time = (kp->ki_runtime + 500000) / 1000000;
|
2021-03-01 13:58:15 -08:00
|
|
|
state = _process_state_name(kp->ki_stat);
|
2021-02-02 13:33:09 -08:00
|
|
|
snprintf(p->state, sizeof(p->state), "%s", state);
|
2021-03-01 13:58:15 -08:00
|
|
|
snprintf(p->wchan, sizeof(p->wchan), "%s", kp->ki_wmesg);
|
2020-05-16 03:57:57 -07:00
|
|
|
p->mem_virt = kp->ki_size;
|
2020-07-09 15:39:15 -07:00
|
|
|
p->mem_rss = MEMSZ(kp->ki_rssize) * MEMSZ(pagesize);
|
2020-08-16 05:49:06 -07:00
|
|
|
p->start = kp->ki_start.tv_sec;
|
2020-05-16 03:57:57 -07:00
|
|
|
p->mem_size = p->mem_virt;
|
|
|
|
p->nice = kp->ki_nice - NZERO;
|
|
|
|
p->priority = kp->ki_pri.pri_level - PZERO;
|
|
|
|
p->numthreads = kp->ki_numthreads;
|
|
|
|
|
|
|
|
p->tid = kp->ki_tid;
|
|
|
|
p->thread_name = strdup(kp->ki_tdname);
|
2020-11-11 19:56:37 -08:00
|
|
|
if (kp->ki_flag & P_KPROC) p->is_kernel = 1;
|
2020-05-16 03:57:57 -07:00
|
|
|
|
|
|
|
return p;
|
|
|
|
}
|
|
|
|
|
|
|
|
static Eina_List *
|
|
|
|
_process_list_freebsd_fallback_get(void)
|
|
|
|
{
|
|
|
|
Eina_List *list;
|
|
|
|
struct kinfo_proc kp;
|
|
|
|
int mib[4];
|
|
|
|
size_t len;
|
2020-07-10 02:50:35 -07:00
|
|
|
static int pid_max;
|
2020-05-16 03:57:57 -07:00
|
|
|
|
|
|
|
pid_max = _pid_max();
|
|
|
|
|
|
|
|
list = NULL;
|
|
|
|
|
|
|
|
len = sizeof(int);
|
|
|
|
if (sysctlnametomib("kern.proc.pid", mib, &len) == -1)
|
|
|
|
return NULL;
|
|
|
|
|
|
|
|
for (int i = 1; i <= pid_max; i++)
|
|
|
|
{
|
|
|
|
mib[3] = i;
|
|
|
|
len = sizeof(kp);
|
|
|
|
if (sysctl(mib, 4, &kp, &len, NULL, 0) == -1)
|
|
|
|
continue;
|
|
|
|
|
2020-07-31 11:13:23 -07:00
|
|
|
if (kp.ki_flag & P_KPROC && !proc_info_kthreads_show_get())
|
2020-05-16 03:57:57 -07:00
|
|
|
continue;
|
|
|
|
|
2021-01-24 05:48:40 -08:00
|
|
|
Proc_Info *p = _proc_thread_info(&kp, 0);
|
2020-05-16 03:57:57 -07:00
|
|
|
if (p)
|
|
|
|
list = eina_list_append(list, p);
|
|
|
|
}
|
|
|
|
|
|
|
|
return list;
|
|
|
|
}
|
2020-05-15 06:27:34 -07:00
|
|
|
|
2020-04-14 10:24:27 -07:00
|
|
|
static Eina_List *
|
|
|
|
_process_list_freebsd_get(void)
|
|
|
|
{
|
|
|
|
kvm_t *kern;
|
|
|
|
Eina_List *list = NULL;
|
2020-04-21 11:50:02 -07:00
|
|
|
struct kinfo_proc *kps, *kp;
|
2020-04-14 10:24:27 -07:00
|
|
|
char errbuf[_POSIX2_LINE_MAX];
|
|
|
|
int pid_count;
|
|
|
|
|
|
|
|
kern = kvm_openfiles(NULL, NULL, NULL, O_RDONLY, errbuf);
|
|
|
|
if (!kern)
|
|
|
|
return _process_list_freebsd_fallback_get();
|
|
|
|
|
2020-04-21 11:50:02 -07:00
|
|
|
kps = kvm_getprocs(kern, KERN_PROC_PROC, 0, &pid_count);
|
|
|
|
if (!kps)
|
|
|
|
{
|
|
|
|
kvm_close(kern);
|
|
|
|
return _process_list_freebsd_fallback_get();
|
|
|
|
}
|
2020-04-14 10:24:27 -07:00
|
|
|
|
|
|
|
for (int i = 0; i < pid_count; i++)
|
|
|
|
{
|
2020-07-31 11:13:23 -07:00
|
|
|
if (kps[i].ki_flag & P_KPROC && !proc_info_kthreads_show_get())
|
2020-04-14 10:24:27 -07:00
|
|
|
continue;
|
|
|
|
|
2020-04-21 11:50:02 -07:00
|
|
|
kp = &kps[i];
|
2020-04-22 03:05:17 -07:00
|
|
|
|
2021-01-24 05:48:40 -08:00
|
|
|
Proc_Info *p = _proc_thread_info(kp, 0);
|
2020-05-16 03:57:57 -07:00
|
|
|
if (p)
|
2020-05-16 09:13:31 -07:00
|
|
|
list = eina_list_append(list, p);
|
2020-04-14 10:24:27 -07:00
|
|
|
}
|
|
|
|
|
2020-04-21 11:50:02 -07:00
|
|
|
kvm_close(kern);
|
|
|
|
|
2020-04-14 10:24:27 -07:00
|
|
|
return list;
|
|
|
|
}
|
|
|
|
|
2020-05-15 06:24:38 -07:00
|
|
|
static Proc_Info *
|
|
|
|
_proc_info_by_pid_fallback(int pid)
|
2018-06-04 03:11:21 -07:00
|
|
|
{
|
|
|
|
struct kinfo_proc kp;
|
|
|
|
int mib[4];
|
|
|
|
size_t len;
|
|
|
|
|
|
|
|
len = sizeof(int);
|
|
|
|
if (sysctlnametomib("kern.proc.pid", mib, &len) == -1)
|
|
|
|
return NULL;
|
|
|
|
|
|
|
|
mib[3] = pid;
|
|
|
|
|
|
|
|
len = sizeof(kp);
|
|
|
|
if (sysctl(mib, 4, &kp, &len, NULL, 0) == -1)
|
|
|
|
return NULL;
|
|
|
|
|
2021-01-24 05:48:40 -08:00
|
|
|
Proc_Info *p = _proc_thread_info(&kp, 0);
|
2020-05-15 13:27:59 -07:00
|
|
|
|
2020-05-15 06:24:38 -07:00
|
|
|
return p;
|
|
|
|
}
|
|
|
|
|
|
|
|
Proc_Info *
|
|
|
|
proc_info_by_pid(int pid)
|
|
|
|
{
|
|
|
|
kvm_t *kern;
|
|
|
|
struct kinfo_proc *kps, *kp;
|
|
|
|
char errbuf[_POSIX2_LINE_MAX];
|
|
|
|
int pid_count;
|
|
|
|
|
|
|
|
kern = kvm_openfiles(NULL, NULL, NULL, O_RDONLY, errbuf);
|
|
|
|
if (!kern)
|
|
|
|
return _proc_info_by_pid_fallback(pid);
|
|
|
|
|
|
|
|
kps = kvm_getprocs(kern, KERN_PROC_ALL, 0, &pid_count);
|
|
|
|
if (!kps)
|
|
|
|
{
|
|
|
|
kvm_close(kern);
|
|
|
|
return _proc_info_by_pid_fallback(pid);
|
|
|
|
}
|
|
|
|
|
|
|
|
Proc_Info *p = NULL;
|
|
|
|
|
2021-02-03 00:03:55 -08:00
|
|
|
// XXX: run_time does not include interrupts.
|
|
|
|
|
2020-05-15 06:24:38 -07:00
|
|
|
for (int i = 0; i < pid_count; i++)
|
|
|
|
{
|
2020-07-31 11:13:23 -07:00
|
|
|
if (kps[i].ki_flag & P_KPROC && !proc_info_kthreads_show_get())
|
2020-05-15 06:24:38 -07:00
|
|
|
continue;
|
|
|
|
if (kps[i].ki_pid != pid)
|
|
|
|
continue;
|
|
|
|
|
|
|
|
kp = &kps[i];
|
2021-01-24 05:48:40 -08:00
|
|
|
Proc_Info *t = _proc_thread_info(kp, 1);
|
2020-05-15 06:24:38 -07:00
|
|
|
if (!p)
|
2020-05-16 04:26:35 -07:00
|
|
|
{
|
2021-01-24 05:48:40 -08:00
|
|
|
p = _proc_thread_info(kp, 0);
|
2020-05-16 04:26:35 -07:00
|
|
|
p->cpu_time = 0;
|
|
|
|
}
|
2020-05-15 06:24:38 -07:00
|
|
|
|
2020-05-16 04:26:35 -07:00
|
|
|
p->cpu_time += t->cpu_time;
|
2020-05-15 06:24:38 -07:00
|
|
|
p->threads = eina_list_append(p->threads, t);
|
|
|
|
}
|
|
|
|
|
|
|
|
kvm_close(kern);
|
|
|
|
|
|
|
|
if (!p) return _proc_info_by_pid_fallback(pid);
|
|
|
|
|
|
|
|
return p;
|
|
|
|
}
|
2018-06-04 03:11:21 -07:00
|
|
|
#endif
|
|
|
|
|
2020-04-22 02:10:02 -07:00
|
|
|
void
|
|
|
|
proc_info_free(Proc_Info *proc)
|
|
|
|
{
|
2020-05-12 12:34:07 -07:00
|
|
|
Proc_Info *t;
|
|
|
|
|
2020-11-16 04:25:07 -08:00
|
|
|
if (!proc) return;
|
|
|
|
|
2020-05-12 12:34:07 -07:00
|
|
|
EINA_LIST_FREE(proc->threads, t)
|
2021-02-26 00:14:58 -08:00
|
|
|
proc_info_free(t);
|
2020-05-12 12:34:07 -07:00
|
|
|
|
2020-04-22 02:10:02 -07:00
|
|
|
if (proc->command)
|
|
|
|
free(proc->command);
|
|
|
|
if (proc->arguments)
|
|
|
|
free(proc->arguments);
|
2020-05-15 13:17:00 -07:00
|
|
|
if (proc->thread_name)
|
|
|
|
free(proc->thread_name);
|
|
|
|
|
2020-04-22 02:10:02 -07:00
|
|
|
free(proc);
|
|
|
|
}
|
|
|
|
|
2018-06-04 03:11:21 -07:00
|
|
|
Eina_List *
|
|
|
|
proc_info_all_get(void)
|
|
|
|
{
|
|
|
|
Eina_List *processes;
|
|
|
|
|
|
|
|
#if defined(__linux__)
|
|
|
|
processes = _process_list_linux_get();
|
|
|
|
#elif defined(__FreeBSD__) || defined(__DragonFly__)
|
|
|
|
processes = _process_list_freebsd_get();
|
|
|
|
#elif defined(__MacOS__)
|
|
|
|
processes = _process_list_macos_get();
|
|
|
|
#elif defined(__OpenBSD__)
|
|
|
|
processes = _process_list_openbsd_get();
|
|
|
|
#else
|
|
|
|
processes = NULL;
|
|
|
|
#endif
|
|
|
|
|
|
|
|
return processes;
|
|
|
|
}
|
|
|
|
|
2020-10-03 06:19:29 -07:00
|
|
|
static Eina_Bool
|
|
|
|
_child_add(Eina_List *parents, Proc_Info *child)
|
|
|
|
{
|
|
|
|
Eina_List *l;
|
|
|
|
Proc_Info *parent;
|
|
|
|
|
|
|
|
EINA_LIST_FOREACH(parents, l, parent)
|
|
|
|
{
|
|
|
|
if (parent->pid == child->ppid)
|
|
|
|
{
|
|
|
|
parent->children = eina_list_append(parent->children, child);
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
Eina_List *
|
|
|
|
proc_info_all_children_get()
|
|
|
|
{
|
|
|
|
Proc_Info *proc;
|
|
|
|
Eina_List *l;
|
|
|
|
Eina_List *procs;
|
|
|
|
|
|
|
|
procs = proc_info_all_get();
|
|
|
|
|
|
|
|
EINA_LIST_FOREACH(procs, l, proc)
|
|
|
|
{
|
|
|
|
int ok =_child_add(procs, proc);
|
|
|
|
(void) ok;
|
|
|
|
}
|
|
|
|
|
|
|
|
return procs;
|
|
|
|
}
|
|
|
|
|
|
|
|
Eina_List *
|
|
|
|
_append_wanted(Eina_List *wanted, Eina_List *tree)
|
|
|
|
{
|
|
|
|
Eina_List *l;
|
|
|
|
Proc_Info *parent;
|
|
|
|
|
|
|
|
EINA_LIST_FOREACH(tree, l, parent)
|
|
|
|
{
|
|
|
|
wanted = eina_list_append(wanted, parent);
|
|
|
|
if (parent->children)
|
|
|
|
wanted = _append_wanted(wanted, parent->children);
|
|
|
|
}
|
|
|
|
return wanted;
|
|
|
|
}
|
|
|
|
|
|
|
|
Eina_List *
|
|
|
|
proc_info_pid_children_get(pid_t pid)
|
|
|
|
{
|
|
|
|
Proc_Info *proc;
|
|
|
|
Eina_List *l, *procs, *wanted = NULL;
|
|
|
|
|
|
|
|
procs = proc_info_all_children_get();
|
|
|
|
|
|
|
|
EINA_LIST_FOREACH(procs, l, proc)
|
|
|
|
{
|
|
|
|
if (!wanted && proc->pid == pid)
|
|
|
|
{
|
|
|
|
wanted = eina_list_append(wanted, proc);
|
|
|
|
if (proc->children)
|
|
|
|
wanted = _append_wanted(wanted, proc->children);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
EINA_LIST_FREE(procs, proc)
|
|
|
|
{
|
|
|
|
if (!eina_list_data_find(wanted, proc))
|
|
|
|
{
|
|
|
|
proc_info_free(proc);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return wanted;
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
proc_info_all_children_free(Eina_List *pstree)
|
|
|
|
{
|
|
|
|
Proc_Info *parent, *child;
|
|
|
|
|
|
|
|
EINA_LIST_FREE(pstree, parent)
|
|
|
|
{
|
|
|
|
EINA_LIST_FREE(parent->children, child)
|
|
|
|
proc_info_pid_children_free(child);
|
|
|
|
proc_info_free(parent);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
proc_info_pid_children_free(Proc_Info *proc)
|
|
|
|
{
|
|
|
|
Proc_Info *child;
|
|
|
|
|
|
|
|
EINA_LIST_FREE(proc->children, child)
|
|
|
|
proc_info_free(child);
|
|
|
|
|
|
|
|
proc_info_free(proc);
|
|
|
|
}
|
|
|
|
|
2021-02-06 00:50:53 -08:00
|
|
|
int
|
|
|
|
proc_sort_by_pid(const void *p1, const void *p2)
|
|
|
|
{
|
|
|
|
const Proc_Info *inf1, *inf2;
|
|
|
|
|
|
|
|
inf1 = p1; inf2 = p2;
|
|
|
|
|
|
|
|
return inf1->pid - inf2->pid;
|
|
|
|
}
|
|
|
|
|
|
|
|
int
|
|
|
|
proc_sort_by_uid(const void *p1, const void *p2)
|
|
|
|
{
|
|
|
|
const Proc_Info *inf1, *inf2;
|
|
|
|
|
|
|
|
inf1 = p1; inf2 = p2;
|
|
|
|
|
|
|
|
return inf1->uid - inf2->uid;
|
|
|
|
}
|
|
|
|
|
|
|
|
int
|
|
|
|
proc_sort_by_nice(const void *p1, const void *p2)
|
|
|
|
{
|
|
|
|
const Proc_Info *inf1, *inf2;
|
|
|
|
|
|
|
|
inf1 = p1; inf2 = p2;
|
|
|
|
|
|
|
|
return inf1->nice - inf2->nice;
|
|
|
|
}
|
|
|
|
|
|
|
|
int
|
|
|
|
proc_sort_by_pri(const void *p1, const void *p2)
|
|
|
|
{
|
|
|
|
const Proc_Info *inf1, *inf2;
|
|
|
|
|
|
|
|
inf1 = p1; inf2 = p2;
|
|
|
|
|
|
|
|
return inf1->priority - inf2->priority;
|
|
|
|
}
|
|
|
|
|
|
|
|
int
|
|
|
|
proc_sort_by_cpu(const void *p1, const void *p2)
|
|
|
|
{
|
|
|
|
const Proc_Info *inf1, *inf2;
|
|
|
|
|
|
|
|
inf1 = p1; inf2 = p2;
|
|
|
|
|
|
|
|
return inf1->cpu_id - inf2->cpu_id;
|
|
|
|
}
|
|
|
|
|
|
|
|
int
|
|
|
|
proc_sort_by_threads(const void *p1, const void *p2)
|
|
|
|
{
|
|
|
|
const Proc_Info *inf1, *inf2;
|
|
|
|
|
|
|
|
inf1 = p1; inf2 = p2;
|
|
|
|
|
|
|
|
return inf1->numthreads - inf2->numthreads;
|
|
|
|
}
|
|
|
|
|
2021-02-26 00:14:58 -08:00
|
|
|
int
|
|
|
|
proc_sort_by_files(const void *p1, const void *p2)
|
|
|
|
{
|
|
|
|
const Proc_Info *inf1, *inf2;
|
|
|
|
|
|
|
|
inf1 = p1; inf2 = p2;
|
|
|
|
|
|
|
|
return inf1->numfiles - inf2->numfiles;
|
|
|
|
}
|
|
|
|
|
2021-02-06 00:50:53 -08:00
|
|
|
int
|
|
|
|
proc_sort_by_size(const void *p1, const void *p2)
|
|
|
|
{
|
|
|
|
const Proc_Info *inf1, *inf2;
|
|
|
|
int64_t size1, size2;
|
|
|
|
|
|
|
|
inf1 = p1; inf2 = p2;
|
|
|
|
|
|
|
|
size1 = inf1->mem_size;
|
|
|
|
size2 = inf2->mem_size;
|
|
|
|
|
|
|
|
if (size1 > size2)
|
|
|
|
return 1;
|
|
|
|
if (size1 < size2)
|
|
|
|
return -1;
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2021-02-24 11:22:47 -08:00
|
|
|
int
|
|
|
|
proc_sort_by_virt(const void *p1, const void *p2)
|
|
|
|
{
|
|
|
|
const Proc_Info *inf1, *inf2;
|
|
|
|
int64_t size1, size2;
|
|
|
|
|
|
|
|
inf1 = p1; inf2 = p2;
|
|
|
|
|
|
|
|
size1 = inf1->mem_virt;
|
|
|
|
size2 = inf2->mem_virt;
|
|
|
|
|
|
|
|
if (size1 > size2)
|
|
|
|
return 1;
|
|
|
|
if (size1 < size2)
|
|
|
|
return -1;
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2021-02-06 00:50:53 -08:00
|
|
|
int
|
|
|
|
proc_sort_by_rss(const void *p1, const void *p2)
|
|
|
|
{
|
|
|
|
const Proc_Info *inf1, *inf2;
|
|
|
|
int64_t size1, size2;
|
|
|
|
|
|
|
|
inf1 = p1; inf2 = p2;
|
|
|
|
|
|
|
|
size1 = inf1->mem_rss;
|
|
|
|
size2 = inf2->mem_rss;
|
|
|
|
|
2021-02-24 11:22:47 -08:00
|
|
|
if (size1 > size2)
|
|
|
|
return 1;
|
|
|
|
if (size1 < size2)
|
|
|
|
return -1;
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
int
|
|
|
|
proc_sort_by_shared(const void *p1, const void *p2)
|
|
|
|
{
|
|
|
|
const Proc_Info *inf1, *inf2;
|
|
|
|
int64_t size1, size2;
|
|
|
|
|
|
|
|
inf1 = p1; inf2 = p2;
|
|
|
|
|
|
|
|
size1 = inf1->mem_shared;
|
|
|
|
size2 = inf2->mem_shared;
|
|
|
|
|
2021-02-06 00:50:53 -08:00
|
|
|
if (size1 > size2)
|
|
|
|
return 1;
|
|
|
|
if (size1 < size2)
|
|
|
|
return -1;
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
int
|
|
|
|
proc_sort_by_time(const void *p1, const void *p2)
|
|
|
|
{
|
|
|
|
const Proc_Info *inf1, *inf2;
|
|
|
|
int64_t t1, t2;
|
|
|
|
|
|
|
|
inf1 = p1; inf2 = p2;
|
|
|
|
|
|
|
|
t1 = inf1->run_time;
|
|
|
|
t2 = inf2->run_time;
|
|
|
|
|
|
|
|
if (t1 > t2)
|
|
|
|
return 1;
|
|
|
|
if (t1 < t2)
|
|
|
|
return -1;
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
int
|
|
|
|
proc_sort_by_cpu_usage(const void *p1, const void *p2)
|
|
|
|
{
|
|
|
|
const Proc_Info *inf1, *inf2;
|
|
|
|
double one, two;
|
|
|
|
|
|
|
|
inf1 = p1; inf2 = p2;
|
|
|
|
|
|
|
|
one = inf1->cpu_usage;
|
|
|
|
two = inf2->cpu_usage;
|
|
|
|
|
|
|
|
if (one > two)
|
|
|
|
return 1;
|
|
|
|
else if (one < two)
|
|
|
|
return -1;
|
|
|
|
else return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
int
|
|
|
|
proc_sort_by_cmd(const void *p1, const void *p2)
|
|
|
|
{
|
|
|
|
const Proc_Info *inf1, *inf2;
|
|
|
|
|
|
|
|
inf1 = p1; inf2 = p2;
|
|
|
|
|
|
|
|
return strcasecmp(inf1->command, inf2->command);
|
|
|
|
}
|
|
|
|
|
|
|
|
int
|
|
|
|
proc_sort_by_state(const void *p1, const void *p2)
|
|
|
|
{
|
|
|
|
const Proc_Info *inf1, *inf2;
|
|
|
|
|
|
|
|
inf1 = p1; inf2 = p2;
|
|
|
|
|
|
|
|
return strcmp(inf1->state, inf2->state);
|
|
|
|
}
|
|
|
|
|
|
|
|
int
|
|
|
|
proc_sort_by_age(const void *p1, const void *p2)
|
|
|
|
{
|
|
|
|
const Proc_Info *c1 = p1, *c2 = p2;
|
|
|
|
|
|
|
|
return c1->start - c2->start;
|
|
|
|
}
|
|
|
|
|