diff --git a/include/process.h b/include/process.h index 6b7d1c22..81fb1d7a 100644 --- a/include/process.h +++ b/include/process.h @@ -8,6 +8,7 @@ It contains relevant attributes as shown below */ class Process { public: + Process(int pid); int Pid(); // TODO: See src/process.cpp std::string User(); // TODO: See src/process.cpp std::string Command(); // TODO: See src/process.cpp @@ -18,6 +19,8 @@ class Process { // TODO: Declare any necessary private members private: + int pid_; + float cpu_utilization_; }; #endif \ No newline at end of file diff --git a/src/format.cpp b/src/format.cpp index 8f8f854b..d871143c 100644 --- a/src/format.cpp +++ b/src/format.cpp @@ -8,4 +8,36 @@ using std::string; // INPUT: Long int measuring seconds // OUTPUT: HH:MM:SS // REMOVE: [[maybe_unused]] once you define the function -string Format::ElapsedTime(long seconds[[maybe_unused]]) { return string(); } \ No newline at end of file +#include + +#include "format.h" + +using std::string; +using std::to_string; +// TODO: Complete this helper function +// INPUT: Long int measuring seconds +// OUTPUT: HH:MM:SS +// REMOVE: [[maybe_unused]] once you define the function +string Format::ElapsedTime(long seconds) { + int h = 00; + int m = 00; + int s = 00; + string hour, min, sec; + + h = seconds / (60 * 60); + m = seconds%(60 * 60) / 60; + s = seconds%(60 * 60) % 60; + + if (h < 10) {hour = "0" + to_string(h); } + else {hour = to_string(h); } + + if (m < 10) {min = "0" + to_string(m); } + else {min = to_string(m); } + + if (s < 10) {sec = "0" + to_string(s); } + else {sec = to_string(s); } + + string time = hour + ": " + min + ": " + sec; + + return time; +} \ No newline at end of file diff --git a/src/linux_parser.cpp b/src/linux_parser.cpp index 51a946a1..60ca2d44 100644 --- a/src/linux_parser.cpp +++ b/src/linux_parser.cpp @@ -6,6 +6,7 @@ #include "linux_parser.h" +using std::stoi; using std::stof; using std::string; using std::to_string; @@ -42,9 +43,10 @@ string LinuxParser::Kernel() { if (stream.is_open()) { std::getline(stream, line); std::istringstream linestream(line); - linestream >> os >> version >> kernel; + + linestream >> os >> kernel >> version; } - return kernel; + return version; } // BONUS: Update this to use std::filesystem @@ -59,58 +61,230 @@ vector LinuxParser::Pids() { string filename(file->d_name); if (std::all_of(filename.begin(), filename.end(), isdigit)) { int pid = stoi(filename); - pids.push_back(pid); + pids.emplace_back(pid); } } } closedir(directory); return pids; } - // TODO: Read and return the system memory utilization -float LinuxParser::MemoryUtilization() { return 0.0; } - + // ? Calculation : (Total memory - free memory) / Total Memory +float LinuxParser::MemoryUtilization() { + string line, label, value; + float total, free; + + std::ifstream filestream(kProcDirectory + kMeminfoFilename); + if (filestream.is_open()) { + while (std::getline(filestream, line)) { + std::istringstream linestream(line); + while (linestream >> label >> value) { + if (label == "MemTotal:") { + total = stof(value); + } + if (label == "MemFree:") { + free = stof(value); + } + } + } + } + return (total - free) / total; +} +//use kernel example // TODO: Read and return the system uptime -long LinuxParser::UpTime() { return 0; } +long LinuxParser::UpTime() { + string uptime, line; + std::ifstream stream(kProcDirectory + kUptimeFilename); + if (stream.is_open()) { + std::getline(stream, line); + std::istringstream linestream(line); + linestream >> uptime; + } + //stol--> converts string to long int + return std::stol(uptime); +} // TODO: Read and return the number of jiffies for the system -long LinuxParser::Jiffies() { return 0; } +long LinuxParser::Jiffies() { + return LinuxParser::ActiveJiffies() + LinuxParser::IdleJiffies(); +} + +// Read and return the number of active jiffies for a PID +long LinuxParser::ActiveJiffies(int pid) { + string line, value; + vector values {}; + long total; + + std::ifstream filestream(kProcDirectory + to_string(pid) + kStatFilename); + if (filestream.is_open()) { + while (std::getline(filestream, line)) { + std::istringstream linestream(line); + while (linestream >> value) { + values.emplace_back(value); + } + } + } + total = stoi(values[13]) + stoi(values[14]) + stoi(values[15]) + stoi(values[16]); // total=utime+stime+cutime+cstime per stack overflow + return total / sysconf(_SC_CLK_TCK); +} + +long LinuxParser::ActiveJiffies() { + // Read and return the number of active jiffies for the system + auto jiffies = CpuUtilization(); + + return stol(jiffies[CPUStates::kUser_]) + stol(jiffies[CPUStates::kNice_]) + + stol(jiffies[CPUStates::kSystem_]) + stol(jiffies[CPUStates::kIRQ_]) + + stol(jiffies[CPUStates::kSoftIRQ_]) + + stol(jiffies[CPUStates::kSteal_]); +} + +long LinuxParser::IdleJiffies() { + // Read and return the number of idle jiffies for the system + auto jiffies = CpuUtilization(); + return stol(jiffies[CPUStates::kIdle_]) + stol(jiffies[CPUStates::kIOwait_]); +} + + +vector LinuxParser::CpuUtilization() { + // Read and return CPU utilization + string line, cpu, value; + vector jiffies; + std::ifstream stream(kProcDirectory + kStatFilename); + if (stream.is_open()) { + std::getline(stream, line); + std::istringstream linestream(line); + + linestream >> cpu; + + while (linestream >> value) { + jiffies.emplace_back(value); + } + } + return jiffies; +} + +int LinuxParser::TotalProcesses() { + // Read and return the total number of processes + int processes; + string key, line; + std::ifstream stream(kProcDirectory + kStatFilename); + if (stream.is_open()) { + while (std::getline(stream, line)) { + std::istringstream linestream(line); + linestream >> key; + if (key == "processes") { + linestream >> processes; + break; + } + } + } + return processes; +} -// TODO: Read and return the number of active jiffies for a PID -// REMOVE: [[maybe_unused]] once you define the function -long LinuxParser::ActiveJiffies(int pid[[maybe_unused]]) { return 0; } +int LinuxParser::RunningProcesses() { + // Read and return the number of running processes + int processes; + string key, line; + std::ifstream stream(kProcDirectory + kStatFilename); + if (stream.is_open()) { + while (std::getline(stream, line)) { + std::istringstream linestream(line); + linestream >> key; + if (key == "procs_running") { + linestream >> processes; + break; + } + } + } + return processes; +} -// TODO: Read and return the number of active jiffies for the system -long LinuxParser::ActiveJiffies() { return 0; } -// TODO: Read and return the number of idle jiffies for the system -long LinuxParser::IdleJiffies() { return 0; } +// Read and return the command associated with a process +string LinuxParser::Command(int pid) { + string command; + std::ifstream stream(kProcDirectory + std::to_string(pid) + kCmdlineFilename); + if (stream.is_open()) { + std::getline(stream, command); + } + return command; +} -// TODO: Read and return CPU utilization -vector LinuxParser::CpuUtilization() { return {}; } +// DONE: Read and return the memory used by a process +string LinuxParser::Ram(int pid) { + string line, label, value; + long ram; -// TODO: Read and return the total number of processes -int LinuxParser::TotalProcesses() { return 0; } + std::ifstream filestream(kProcDirectory + to_string(pid) + kStatusFilename); + if (filestream.is_open()) { + while (std::getline(filestream, line)) { + std::istringstream linestream(line); + while (linestream >> label >> value) { + if (label == "VmRSS:") { + ram = stol(value) / 1000;// convert kilobyte value to megabytes + } + } + } + } + return to_string(ram); // covert intram into a string + ; +} -// TODO: Read and return the number of running processes -int LinuxParser::RunningProcesses() { return 0; } +// DONE: Read and return the user ID associated with a process +string LinuxParser::Uid(int pid) { + string line, label, value, user; -// TODO: Read and return the command associated with a process -// REMOVE: [[maybe_unused]] once you define the function -string LinuxParser::Command(int pid[[maybe_unused]]) { return string(); } + std::ifstream filestream(kProcDirectory + to_string(pid) + kStatusFilename); + if (filestream.is_open()) { + while (std::getline(filestream, line)) { + std::istringstream linestream(line); + while (linestream >> label >> value) { + if (label == "Uid:") { + user = value; + } + } + } + } + return user; +} + +// DONE: Read and return the user associated with a process +string LinuxParser::User(int pid) { + string line, label, value, id_value, user; + string uid = Uid(pid); + + std::ifstream filestream(kPasswordPath); + if (filestream.is_open()) { + while (std::getline(filestream, line)) { + std::replace(line.begin(), line.end(), ':', ' '); + std::istringstream linestream(line); + while (linestream >> label >> value >> id_value) { + if (id_value == uid) {//this matches the balue to the uid + user = label;//gives you the name of the user + } + } + } + } + return user; +} -// TODO: Read and return the memory used by a process -// REMOVE: [[maybe_unused]] once you define the function -string LinuxParser::Ram(int pid[[maybe_unused]]) { return string(); } -// TODO: Read and return the user ID associated with a process -// REMOVE: [[maybe_unused]] once you define the function -string LinuxParser::Uid(int pid[[maybe_unused]]) { return string(); } +// DONE: Read and return the uptime of a process -// TODO: Read and return the user associated with a process -// REMOVE: [[maybe_unused]] once you define the function -string LinuxParser::User(int pid[[maybe_unused]]) { return string(); } -// TODO: Read and return the uptime of a process -// REMOVE: [[maybe_unused]] once you define the function -long LinuxParser::UpTime(int pid[[maybe_unused]]) { return 0; } +long LinuxParser::UpTime(int pid) { + string line, value; + vector ticks {}; + int upTimePid; + std::ifstream filestream(kProcDirectory + to_string(pid) + kStatFilename); + if (filestream.is_open()) { + while (std::getline(filestream, line)) { + std::istringstream linestream(line); + while (linestream >> value) { + ticks.emplace_back(value); + } + } + } + upTimePid = UpTime() - stol(ticks[21]) / sysconf(_SC_CLK_TCK); // return the starttime (in seconds) per stack overflow + return upTimePid; +} \ No newline at end of file diff --git a/src/process.cpp b/src/process.cpp index 82119905..b561a015 100644 --- a/src/process.cpp +++ b/src/process.cpp @@ -3,31 +3,43 @@ #include #include #include - #include "process.h" - +#include "linux_parser.h" using std::string; using std::to_string; using std::vector; -// TODO: Return this process's ID -int Process::Pid() { return 0; } +Process::Process(int pid) { pid_ = pid; }; + +// DONE: Return this process's ID +int Process::Pid() {return pid_; } + +// DONE: Return this process's CPU utilization +float Process::CpuUtilization() { + long pid_cpu, sys_up_time, proc_start_time, elapse_time; -// TODO: Return this process's CPU utilization -float Process::CpuUtilization() { return 0; } + pid_cpu = LinuxParser::ActiveJiffies(Pid()); // get the CPU usage (jiffs) for this process ID + sys_up_time = LinuxParser::UpTime(); // get the system up time in seconds + proc_start_time = LinuxParser::UpTime(Pid()); // get the process up time in seconds + elapse_time = sys_up_time - proc_start_time; // get the elapsed time in seconds since this process started + if (elapse_time) { // make sure elapse_time is not zero + cpu_utilization_ = float(pid_cpu) / float(elapse_time); // calculate the % process CPU usage + } + else { cpu_utilization_ = 0.0; } + return cpu_utilization_; +}; -// TODO: Return the command that generated this process -string Process::Command() { return string(); } +// DONE: Return the command that generated this process +string Process::Command() { return LinuxParser::Command(Pid()); } -// TODO: Return this process's memory utilization -string Process::Ram() { return string(); } +// DONE: Return this process's memory utilization +string Process::Ram() { return LinuxParser::Ram(Pid()); } -// TODO: Return the user (name) that generated this process -string Process::User() { return string(); } +// DONE: Return the user (name) that generated this process +string Process::User() { return LinuxParser::User(Pid()); } -// TODO: Return the age of this process (in seconds) -long int Process::UpTime() { return 0; } +// DONE: Return the age of this process (in seconds) +long int Process::UpTime() { return LinuxParser::UpTime(Pid()); } -// TODO: Overload the "less than" comparison operator for Process objects -// REMOVE: [[maybe_unused]] once you define the function -bool Process::operator<(Process const& a[[maybe_unused]]) const { return true; } \ No newline at end of file +// DONE: Overload the "less than" comparison operator for Process objects +bool Process::operator<(Process const& a) const { return cpu_utilization_ < a.cpu_utilization_; } \ No newline at end of file diff --git a/src/processor.cpp b/src/processor.cpp index 91662895..7d4c6da2 100644 --- a/src/processor.cpp +++ b/src/processor.cpp @@ -1,4 +1,25 @@ +#include +#include +#include "linux_parser.h" + +using std::string; +using std::stof; +using std::vector; +//== + #include "processor.h" -// TODO: Return the aggregate CPU utilization -float Processor::Utilization() { return 0.0; } \ No newline at end of file +// DONE: Return the aggregate CPU utilization +float Processor::Utilization() { + + vector cpu; + float total, idle, cpu_percent; + + cpu = LinuxParser::CpuUtilization(); + total = stof(cpu[0]) + stof(cpu[1]) + stof(cpu[2]) + stof(cpu[5]) + stof(cpu[6]) + stof(cpu[7]); + idle = stof(cpu[3]) + stof(cpu[4]); + total += idle; + cpu_percent = (total - idle) / total; // calc utilization based on stack overflow discussion + + return cpu_percent; +} \ No newline at end of file diff --git a/src/system.cpp b/src/system.cpp index 98e53273..bf153705 100644 --- a/src/system.cpp +++ b/src/system.cpp @@ -1,13 +1,16 @@ #include +#include #include #include #include #include + #include "process.h" #include "processor.h" #include "system.h" + using std::set; using std::size_t; using std::string; @@ -16,26 +19,37 @@ using std::vector; You need to properly format the uptime. Refer to the comments mentioned in format. cpp for formatting the uptime.*/ + // TODO: Return the system's CPU Processor& System::Cpu() { return cpu_; } // TODO: Return a container composed of the system's processes -vector& System::Processes() { return processes_; } +vector& System::Processes() { + vector pids = LinuxParser::Pids(); + processes_ = {}; + for(auto i : pids) { + processes_.emplace_back(Process(i)); + } + std::sort(processes_.begin(), processes_.end()); + return processes_; + } // TODO: Return the system's kernel identifier (string) -std::string System::Kernel() { return string(); } +std::string System::Kernel() { return LinuxParser::Kernel(); } // TODO: Return the system's memory utilization -float System::MemoryUtilization() { return 0.0; } +float System::MemoryUtilization() { return LinuxParser::MemoryUtilization(); } // TODO: Return the operating system name -std::string System::OperatingSystem() { return string(); } +std::string System::OperatingSystem() { return LinuxParser::OperatingSystem(); } // TODO: Return the number of processes actively running on the system -int System::RunningProcesses() { return 0; } +int System::RunningProcesses() { return LinuxParser::RunningProcesses(); } // TODO: Return the total number of processes on the system -int System::TotalProcesses() { return 0; } +int System::TotalProcesses() { return LinuxParser::TotalProcesses(); } // TODO: Return the number of seconds since the system started running -long int System::UpTime() { return 0; } + +long int System::UpTime() { return LinuxParser::UpTime(); } +