From 4bf2054147f3eaa8c9695710fe7ed39cb713e9c5 Mon Sep 17 00:00:00 2001 From: Charles Cabergs Date: Sat, 24 Apr 2021 21:39:20 +0200 Subject: Added ps draft --- src/ps.c | 365 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 365 insertions(+) create mode 100644 src/ps.c (limited to 'src/ps.c') diff --git a/src/ps.c b/src/ps.c new file mode 100644 index 0000000..bc090ec --- /dev/null +++ b/src/ps.c @@ -0,0 +1,365 @@ +#define _POSIX_C_SOURCE 200809L +#define _DEFAULT_SOURCE 1 + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define PROC_DIR "/proc" + +#define TASK_COMM_LEN 32 + +static int page_size = -1; +static long clock_tick = -1; + +typedef enum +{ + FIELD_ARGS, + FIELD_COMM, + FIELD_PID, + FIELD_PPID, + FIELD_PGID, + FIELD_ETIME, + FIELD_TIME, + FIELD_GROUP, + FIELD_RGROUP, + FIELD_USER, + FIELD_RUSER, + FIELD_NICE, + FIELD_TTY, + FIELD_PCPU, + FIELD_VSZ, + FIELD_ADDR, + FIELD_ADDR, + FIELD_C, + FIELD_PRI, + FIELD_NI, + FIELD_ADDR, + FIELD_SZ, + FIELD_WCHAN, +} t_field_id; + +typedef struct +{ + t_field_id id; + char *specifier; + char *header; + int width; +} t_field_info; + +static t_field_info field_infos[] = { + {FIELD_ARGS, "args", "COMMAND", 30}, + {FIELD_COMM, "comm", "COMMAND", -1}, + {FIELD_PID, "pid", "PID", 8}, + {FIELD_PPID, "ppid", "PPID", 8}, + {FIELD_PGID, "pgid", "PGID", 8}, + {FIELD_ETIME, "etime", "ELAPSED", -1}, + {FIELD_TIME, "time", "TIME", -1}, + {FIELD_GROUP, "group", "GROUP", -1}, + {FIELD_RGROUP, "rgroup", "RGROUP", -1}, + {FIELD_USER, "user", "USER", -1}, + {FIELD_RUSER, "ruser", "RUSER", -1}, + {FIELD_NICE, "nice", "NI", -1}, + {FIELD_TTY, "tty", "TT", -1}, + {FIELD_PCPU, "pcpu", "%CPU", -1}, + {FIELD_VSZ, "vsz", "VSZ", -1}, + {FIELD_FLAGS, "f", "F", 1}, + {FIELD_STATE, "s", "S", 1}, + {FIELD_C, "c", "C", -1}, + {FIELD_PRI, "pri", "PRI", -1}, + {FIELD_ADDR, "addr", "ADDR", -1}, + {FIELD_SZ, "sz", "SZ", -1}, + {FIELD_WCHAN, "wchan", "WCHAN", -1}, +}; + + +t_field_info *filed_info_from_specifier(const char *specifier) +{ + for (size_t i = 0; i < sizeof(field_infos) / sizeof(t_field_info); i++) + if (strcmp(field_infos[i].specifier, specifier) == 0) + return (&field_infos[i]); + return (NULL); +} + +static struct stat proc_statbuf; +static char *stat_file; +static char *cmdfile_file; + +void print_field_resource(t_field_info *field_info) +{ + switch (field_info->id) + { + case FIELD_ARGS: + snprintf(file_path, PATH_MAX, "%s/%d/cmdline", PROC_DIR, pid); + FILE *cmdline_file = fopen(file_path, "r"); + if (cmdline_file == NULL) + return; + int c = EOF; + while ((c = fgetc(cmdline_file)) != EOF) + fputc(c, stdout); + break; + + case FIELD_COMM: + char *closing_parent = strrchr(proc_stat.comm + 0, ')'); + if (closing_parent != NULL) + *closing_parent = '\0'; + printf("%s", proc_stat.comm + 1); + break; + + case FIELD_PID: printf("%*ld ", info.width, proc_stat.pid); break; + case FIELD_PPID: printf("%*ld ", info.width, proc_stat.ppid); break; + case FIELD_PGID: printf("%*ld ", info.width, proc_stat.pgrp); break; + + case FIELD_ETIME: + printf("%6lld ", /*current -*/ proc_stat.starttime / clock_tick); + break; + case FIELD_TIME: + printf("%6lld ", proc_stat.starttime / clock_tick); + break; + + case FIELD_GROUP: + break; + case FIELD_RGROUP: + break; + case FIELD_USER: + printf("%6d ", proc_statbuf.st_uid); + break; + case FIELD_RUSER: + break; + + case FIELD_NICE: + printf("%3ld ", proc_stat.nice); + break; + case FIELD_PRI: + printf("%3ld ", proc_stat.priority); + break; + + case FIELD_TTY: + printf("%6d ", proc_stat.tty_nr); + break; + case FIELD_PCPU: + break; + case FIELD_VSZ: + printf("%5ld ", proc_stat.vsize / page_size); + break; + case FIELD_ADDR: + break; + case FIELD_FLAGS: + printf("%o ", 0); //proc_stat.flags, + break; + case FIELD_STATE: + printf("%c ", proc_stat.state); + break; + + case FIELD_C: + break; + case FIELD_SZ: + break; + + case FIELD_WCHAN: + printf("%4ld ", proc_stat.wchan); + break; + + default: + exit(1); + } +} + +char full_format[] = "user pid ppid c stime tty time args"; +char long_format[] = "f s user pid ppid c pri ni addr sz wchan tty time cmd"; +char default_format[] = "pid tty time cmd"; + +size_t fields_size = 0; +t_field_info **field_infos = NULL; + +void field_infos_from_format(char *format) +{ + size_t i; + + for (i = 0; format[i] != '\0'; i++) + if (isspace(format[i]) && isspace(format[i + 1])) + exit(1); + + fields_size = 0; + for (i = 0; format[i] != '\0'; i++) + if (isspace(format[i])) + fields_size++; + + field_infos = malloc(fields_size * sizeof(t_field_info*)); + if (field_infos == NULL) + exit(1); + + i = 0; + char *specifier = NULL; + while ((specifier = strsep(&format, " ,")) != NULL) + { + field_infos[i] = field_info_from_specifier(specifier); + if (field_infos[i] == NULL) + exit(1); + i++; + } +} + +void print_header(void) +{ + for (size_t i = 0; i < fields_size; i++) + printf("%*s ", field_infos[i].width, field_infos[i].header); +} + +typedef struct +{ + pid_t pid; + char comm[TASK_COMM_LEN]; + char state; + pid_t ppid; + pid_t pgrp; + int session; + int tty_nr; + int tpgid; + unsigned int flags; + unsigned long minflt; + unsigned long cminflt; + unsigned long majflt; + unsigned long cmajflt; + unsigned long utime; + unsigned long stime; + long cutime; + long cstime; + long priority; + long nice; + long num_threads; + long itrealvalue; + unsigned long long starttime; + unsigned long vsize; + long rss; + unsigned long rsslim; + unsigned long startcode; + unsigned long endcode; + unsigned long startstack; + unsigned long kstkesp; + unsigned long kstkeip; + unsigned long signal; + unsigned long blocked; + unsigned long sigignore; + unsigned long sigcatch; + unsigned long wchan; + unsigned long nswap; + unsigned long cnswap; + int exit_signal; + int processor; + unsigned int rt_priority; + unsigned long delayacct_blkio_ticks; + unsigned long guest_time; + long cguest_time; + unsigned long end_data; + unsigned long start_brk; + unsigned long arg_start; + unsigned long arg_end; + unsigned long env_start; + unsigned long env_end; + int exit_code; +} t_proc_stat; + +int main(int argc, char **argv) +{ + field_infos_from_format(default_format); + + free(field_infos); + return; + + + page_size = getpagesize(); + clock_tick = sysconf(_SC_CLK_TCK); + + DIR *proc_dir = opendir(PROC_DIR); + if (proc_dir == NULL) + exit(1); + struct dirent *proc_dir_entry = NULL; + while ((proc_dir_entry = readdir(proc_dir)) != NULL) + { + pid_t pid = 0; + if (sscanf(proc_dir_entry->d_name, "%d", &pid) != 1) + continue; + + char file_path[PATH_MAX + 1] = {'\0'}; + snprintf(file_path, PATH_MAX, "%s/%d/stat", PROC_DIR, pid); + FILE *stat_file = fopen(file_path, "r"); + if (stat_file == NULL) + continue; + + t_proc_stat proc_stat; + fscanf( + stat_file, + "%d %s %c %d %d %d %d %d %u %lu %lu %lu %lu %lu %lu %ld %ld %ld %ld %ld %ld " + "%llu %lu %ld %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %d %d %u " + "%llu %lu %ld %lu %lu %lu %lu %lu %lu %d", + &proc_stat.pid, + &proc_stat.comm, + &proc_stat.state, + &proc_stat.ppid, + &proc_stat.pgrp, + &proc_stat.session, + &proc_stat.tty_nr, + &proc_stat.tpgid, + &proc_stat.flags, + &proc_stat.minflt, + &proc_stat.cminflt, + &proc_stat.majflt, + &proc_stat.cmajflt, + &proc_stat.utime, + &proc_stat.stime, + &proc_stat.cutime, + &proc_stat.cstime, + &proc_stat.priority, + &proc_stat.nice, + &proc_stat.num_threads, + &proc_stat.itrealvalue, + &proc_stat.starttime, + &proc_stat.vsize, + &proc_stat.rss, + &proc_stat.rsslim, + &proc_stat.startcode, + &proc_stat.endcode, + &proc_stat.startstack, + &proc_stat.kstkesp, + &proc_stat.kstkeip, + &proc_stat.signal, + &proc_stat.blocked, + &proc_stat.sigignore, + &proc_stat.sigcatch, + &proc_stat.wchan, + &proc_stat.nswap, + &proc_stat.cnswap, + &proc_stat.exit_signal, + &proc_stat.processor, + &proc_stat.rt_priority, + &proc_stat.delayacct_blkio_ticks, + &proc_stat.guest_time, + &proc_stat.cguest_time, + &proc_stat.end_data, + &proc_stat.start_brk, + &proc_stat.arg_start, + &proc_stat.arg_end, + &proc_stat.env_start, + &proc_stat.env_end, + &proc_stat.exit_code + ); + + struct stat statbuf; + if (stat(file_path, &statbuf) == -1) + continue; + + fputc('\n', stdout); + break; + } + + return 0; +} -- cgit