This code contains a program to gather information about the system, including information about memory usage, system name, machine name, version, release, architecture, user sessions, and CPU usage.
- GCC compiler
The following libraries and header files are used in the program:
- stdio.h: Standard input/output library in C.
- stdlib.h: Standard Library in C.
- unistd.h: Library with various operating system APIs, such as sleep, read, write, etc.
- string.h: String handling library in C.
- sys/utsname.h: Library for system information such as the * system name, machine name, version, release, etc.
- sys/sysinfo.h: Library for information about system resource utilization.
- sys/resource.h: Library for system resource limits and utilization.
- utmp.h: Library for system user accounting information.
- stdbool.h: Library to support the type 'bool' in C.
- ctype.h: Library for character handling functions.
- math.h: Library for mathematical functions.
- errno.h: Library for error handling.
The program can be compiled using a standard C compiler and executed in the command line. The following code can be used to complie the program:
gcc -o mySystemStats A3main.c stats_functions.c
OR make
The following executable can be used to run the program:
./mySystemStats
The program accepts 6 Command Line Arguments, with their respective short forms:
--system
or -s
System Details
To indicate that only the system usage should be generated
--user
or -u
User Details
To indicate that only the users usage should be generated
--graphics
or -g
Graphics Details
To include graphical output in the cases where a graphical outcome is possible as indicated below.
--sequential
or se
Sequential Details
To indicate that the information will be output sequentially without needing to "refresh" the screen (useful if you would like to redirect the output into a file)
--samples
or -sa=
Samples Details
If used the value N will indicate how many times the statistics are going to be collected and results will be average and reported based on the N number of repetitions.
If not value is indicated the default value will be 10.
--tdelay=
or -td=
Tdelay Details
To indicate how frequently to sample in seconds.
If not value is indicated the default value will be 1 sec.
Note: The program also accepts two positional integer arguments, where the first one represents the number of samples and the second one is the tdelay. The program will use the default values if no arguments are provided. If only one integer argument is provided, it sets that value to the number of samples
void getCpu(int pipefd_cpu[2])
getCpu Description
Parameters:
int pipefd_cpu[2]
: Pipe to write to
Return Value:
-
void
This function is used to get the CPU usage statistics. It takes two arguments, the first one is a pointer to a struct cpu_stat and the second one is the number of the CPU to be used. It uses the
/proc/stat
file to get the relevant information. The function will return the CPU usage statistics in the struct cpu_stat.
double calculate_load(struct cpu_stat *cur, long int* prev_idle, long int* prev_load)
calculate_load Description
Parameters:
struct cpu_stat *cur
: Pointer to the current CPU statisticslong int* prev_idle
: Pointer to the previous idle timelong int* prev_load
: Pointer to the previous load time
Return Value:
double
: CPU load in percentage
This function uses the following formula to calculate the CPU load:
double load = fabs((100 * (totald - idled) / (totald) + 1));
Where the load is the CPU load in percentage.
void starter(int samples, int tdelay)
starter Description
Parameters:
int samples
: Number of samples to be takenint tdelay
: Time delay between samples
Return Value:
void
This function is used as a header to the program. It prints the number of samples and the time delay between each sample. It uses the <sys/resource.h>
library, and the rusage
struct to get the system resources.
void ender()
ender Description
Parameters:
- none
Return Value:
void
This function is used as a footer to the program. It prints the system information. It uses the <sys/utsname.h>
library, and the utsname
struct to get the system information.
void UserPrint(int pipefd[2])
UserPrint Description
Parameters:
int pipefd[2]
: Pipe to write to
Return Value:
void
This function is used to print the user information. It uses the <utmp.h>
library, and the utmp
struct to get the user information. It prints the user name, the terminal name, and the host name.
void cpuPrint(char graph_arr[][1024], int samples, bool graph, int i, long int* prev_idle, long int* prev_load, struct cpu_stat *cpu_stat)
cpuPrint Description
Parameters:
char graph_arr[][1024]
: Array to store the graphical outputint samples
: Number of samples to be takenbool graph
: Boolean to indicate if graphical output is neededint i
: Number of the current samplelong int* prev_idle
: Pointer to the previous idle timelong int* prev_load
: Pointer to the previous CPU loadlong int* prev_load
: Previous CPU loadstruct cpu_stat *cpu_stat
: Pointer to the current CPU stats
Return Value:
double
: CPU load in percentage to be used in the next iteration
This function is used to print the CPU usage statistics. It uses sysconf
to get the number of cores (iteraretes through the /proc/stat
file to count the number of CPUs).
The function uses the get_stats
function to get the CPU usage statistics. It then sleeps for the desired time delay. It then uses the get_stats
function again to get the CPU usage statistics. It then uses the calculate_load
function to calculate the CPU load. It then prints the CPU load in percentage.
If graphical is called, It prints two bars if the load is less than or equal to 0.01%, an additional one bar for every 0.1 increase upto 1, an additional one bar for every 1 increase upto 10, and an additional one bar for every 10 increase upto 100. As can be seen through this code:
if (prev_load > 0.01 && prev_load <= 1.00) {barCount = (int)(prev_load * 10); }
else if (prev_load > 1.00 && prev_load <= 10.00) {barCount = prev_load + 10;}
else if (prev_load > 10.00 && prev_load <= 100.00) {barCount = prev_load / 10 + 20;}
The function returns the CPU load in percentage to be used in the next iteration.
void getMemory(int pipefd_mem[2])
getMemory Description
Parameters:
int pipefd_mem[2]
: Pipe to write to
Return Value:
void
This function is used to print the memory usage statistics. It uses the <sys/sysinfo.h>
library, and the sysinfo
struct to get the memory usage statistics.
It prints the virtual memory usage in GB. It calculates the memory usage using the following:
long long phys_mem = sys.totalram * sys.mem_unit;
long long phys_used = (sys.totalram - sys.freeram) * sys.mem_unit;
long long virt_mem = sys.totalram * sys.mem_unit + sys.totalswap * sys.mem_unit;
long long virt_used = (sys.totalram - sys.freeram) * sys.mem_unit + (sys.totalswap - sys.freeswap) * sys.mem_unit;
Each of the variables are in bytes, which is why they are divided by 1024^3 to get the value in GB.
void memoryPrint(char memory_arr[1024][1024], int samples, bool graph, int i, double* prev_virt, struct mem_stat *mem_stat)
memoryPrint Description
Parameters:
char memory_arr[1024][1024]
: Nested char array containing the output for the memoryint samples
: Number of samples to be takenbool graph
: Boolean to indicate if graphical output is neededint i
: Number of the current sampledouble *prev_virt
: Pointer to previous virtual memory usagestruct mem_stat *mem_stat
: Pointer to a struct mem_stat
Return Value:
- double: Virtual memory usage in GB to be used in the next iteration
If the graphical output is needed, the function will print the graphical output for the memory. For every 0.01 GB change, the function will print an additional symbol based on whether the memory usage is increasing or decreasing. The function returns the virtual memory usage in GB to be used in the next iteration.
void finPrint(bool sys, bool user, bool graph, bool sequen, int samples, int tdelay)
finPrint Description
Parameters:
bool sys
: Boolean to indicate if system information is neededbool user
: Boolean to indicate if user information is neededbool graph
: Boolean to indicate if graphical output is neededbool sequen
: Boolean to indicate if sequential output is neededint samples
: Number of samples to be takenint tdelay
: Time delay between samples
Return Value:
void
This function is used to print the final output. It prints the starter() at the beginning and the ender() at the end. If sequential is false, it uses printf("\033[H \033[2J \n");
to clear the screen.
It prints the CPU usage statistics and the memory usage statistics. Based on which flags are called.
It also prints the graphical output for the CPU and the memory if the graphical output is needed. If sequential is true, the screen is not cleared after each iteration, and the output is printed beneath the previous output.
It also declares and frees the memory for the char arrays that will be used to store the graphical output for the CPU and the memory.
int main(int argc, char *argv[])
main Description
Parameters:
int argc
: Number of argumentschar *argv[]
: Array of arguments
Return Value:
int: 0
This function is used to parse through the arguments passed to the program. It uses strcmp()
to compare the arguments to the flags. It also uses atoi()
to convert the arguments to integers if needed. The command line arguments are defined at the beginning of the usage page. It passes through the arguments and sets the boolean values to true if the flag is present. It also sets the number of samples and the time delay between samples if they are present. It then calls the finPrint()
function to print the final output. If the user does not pass any arguments, the program will print the usage and system page.
Note: If invalid arguments are passed, none of the commands are run, and the program will print:
Please enter valid arguments
However if at least one valid argument is passed, the program will run the valid arguments and ignore the invalid ones.
Multiple arguments can be used at the same time. For example, the following command will generate the system usage statistics with graphical output and will take 5 samples with a time delay of 2 seconds between each sample:
./mySystemStats -s -g -sa=5 -td=2
The following command will generate the user usage statistics and will take 2 samples with a time delay of 8 seconds between each sample:
./mySystemStats -u 2 8
My program uses the fork() system call to create child processes, which are executed concurrently. It uses pipes to send information from the parents to the child, and vice-versa.