/src/functions.c
https://gitlab.com/dtluna/Course · C · 223 lines · 191 code · 32 blank · 0 comment · 26 complexity · a5e97bcf4dc9c482d09e66890db9f781 MD5 · raw file
- #include "procinfo.h"
- #include "functions.h" // <sys/types.h> <dirent.h>
- #include "errors.h"
- #include "system_info.h"
- #include <stdlib.h>
- #include <string.h>
- #include <time.h>
- #include <stdio.h>
- #include <unistd.h>
- #include "alloc.h"
- int filter_dir(const struct dirent* entry)
- {
- if (( DT_DIR == entry->d_type ) && ( is_number(entry->d_name )))
- return 1;
- else
- return 0;
- }
- bool is_number (const char* string)
- {
- char* endptr = alloc_str(strlen(string));
- char* endptr_copy = endptr;
- long int number = strtol(string, &endptr, 10);
- if ( ( 0 == number ) && ( 0 == strcmp(string, endptr) ) )
- {
- free(endptr_copy);
- return false;
- }
- else
- {
- free(endptr_copy);
- return true;
- }
- }
- unsigned int get_pid_dirents_size (const struct dirent** pid_dirents)
- {
- unsigned int i = 0;
- while(NULL != pid_dirents[i])
- i++;
- return i;
- }
- unsigned int get_pid_dirnames (char*** pid_dirnames)
- {
- struct dirent** pid_entries = get_pid_dirents();
- unsigned int pid_entries_size = get_pid_dirents_size(pid_entries);
- *pid_dirnames = alloc_str_array(pid_entries_size);
- for (unsigned int i = 0; i < pid_entries_size; ++i)
- (*pid_dirnames)[i] = pid_entries[i]->d_name;
- free(pid_entries);
- return pid_entries_size;
- }
- struct dirent** get_pid_dirents ()
- {
- struct dirent** namelist = NULL;
- scandir_err(scandir(".", &namelist, &filter_dir, &pid_dir_compare));
- return namelist;
- }
- int pid_dir_compare (const struct dirent **first_entry, const struct dirent **second_entry)
- {
- pid_t first_pid = atoi((*first_entry)->d_name);
- pid_t second_pid = atoi((*second_entry)->d_name);
- return (first_pid - second_pid);
- }
- char* correct_comm (char* comm)
- {
- size_t len = strlen(comm);
- comm[len-1] = '\0';
- for (size_t i = 0; i < len; ++i)
- {
-
- comm[i] = comm[i+1];
- }
- return comm;
- }
- time_t get_proc_time ()
- {
- clock_t utime = 0, stime = 0;
- FILE* stat_file = fopen("./stat", "r");
- fopen_err(stat_file);
- fscanf(stat_file,
- "%*d %*s %*c %*d %*d"
- "%*d %*d %*u %*u %*lu"
- "%*lu %*lu %lu %lu",
- &utime, &stime);
- fclose_err(fclose(stat_file));
- time_t proc_time = ((utime+stime)/sysconf(_SC_CLK_TCK));
- return proc_time;
- }
- time_t get_uptime ()
- {
- time_t uptime = 0;
- FILE* uptime_file = fopen("/proc/uptime", "r");
- fopen_err(uptime_file);
- fscanf(uptime_file, "%lu", &uptime);
- fclose_err(fclose(uptime_file));
- return uptime;
- }
- time_t get_cpu_time ()
- {
- clock_t user = 0, nice = 0, system_time = 0, idle = 0;
- FILE* cpu_stat_file = fopen("/proc/stat", "r");
- fopen_err(cpu_stat_file);
- fscanf(cpu_stat_file,
- "%*s %lu %lu %lu %lu",
- &user, &nice, &system_time, &idle);
- fclose_err(fclose(cpu_stat_file));
- time_t cpu_time = (user+nice+system_time+idle)/sysconf(_SC_CLK_TCK);
- return cpu_time;
- }
- char* procinfo_to_string (const struct procinfo p_info)
- {
- char* string = alloc_str(2*MAX_CMDLINE_LEN);
- sprintf(string,
- "%5d "//pid
- "%c " //state
- "%5d " //ppid
- "%3d " //cpu usage
- "%5ld "//priority
- "%5ld "//nice
- "%5ld "//num_threads
- "%6llu "//uptime
- "%10lu "//vsize
- "%7ld "//rss
- "%s ",//comm
- p_info.pid, p_info.state,
- p_info.ppid, p_info.cpu_usage,
- p_info.priority, p_info.nice,
- p_info.num_threads, p_info.uptime,
- p_info.vsize, p_info.rss, p_info.comm);
- return string;
- }
- void fill_boot_time()
- {
- update_sys_info();
- time_t tse = time(NULL);
- sys_info.boot_time = tse - sys_info.uptime;
- }
- pid_t find_process (const struct procinfo* p_info_arr, const unsigned int size, const char* proc_name)
- {
- for (int i = 0; i < size; ++i)
- {
- if (0 == strcmp(p_info_arr[i].comm, proc_name))
- return p_info_arr[i].pid;
- }
- fprintf(stderr, "Error: no such process!\n");
- return -1;
- }
- void enter_decimal (int* number, char* msg)
- {
- char n_string[7];
- do
- {
- printf( "%s ", msg);
- get_string(n_string, 7);
- if (is_number(n_string))
- {
- *number = atoi(n_string);
- return;
- }
- else
- {
- fprintf(stderr, "Error: not a decimal number!\n");
- continue;
- }
-
-
- } while(1);
- }
- bool should_continue (char* msg)
- {
- char answer [256];
- do
- {
- printf("%s(yes,no)?\n", msg);
- get_string(answer, 256);
- if ( (0 == strcmp(answer, "yes")) || (0 == strcmp(answer, "y")) )
- return true;
- if ( (0 == strcmp(answer, "no")) || (0 == strcmp(answer, "n")) )
- return false;
- puts("Invalid input. Try once again.");
- }while (1);
- }
- void remove_newline(char* string)
- {
- int newline_pos = strlen(string)-1;
- if ('\n' == string[newline_pos])
- string[newline_pos] = '\0';
- }
- void get_string (char* string, size_t size)
- {
- fflush(stdin);
- fgets(string, size, stdin);
- remove_newline(string);
- return;
- }