|
@@ -9,16 +9,28 @@
|
|
|
#include <unistd.h>
|
|
|
#include <fcntl.h>
|
|
|
#include <pwd.h>
|
|
|
+#include <linux/limits.h>
|
|
|
+#include <time.h>
|
|
|
#include "error.h"
|
|
|
#include "color.h"
|
|
|
#include "constante.h"
|
|
|
|
|
|
+#define MAX_CMD_SIZE 50
|
|
|
+
|
|
|
+typedef long long int llint;
|
|
|
+typedef unsigned long long ull;
|
|
|
+
|
|
|
typedef struct{
|
|
|
char* path; //Chemin vers le dossier du processus /./proc/[pid]/
|
|
|
int pid; //Le pid
|
|
|
int uid; //Le uid du proprietaire
|
|
|
char state; //L'etat
|
|
|
char* cmd; //La commande
|
|
|
+ llint tty;
|
|
|
+ llint cpu;
|
|
|
+ ull start;
|
|
|
+ llint vsz;
|
|
|
+ llint rss;
|
|
|
}processus;
|
|
|
|
|
|
/**
|
|
@@ -54,6 +66,16 @@ void sort_pid(processus** proc, int size){
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+int get_uptime() {
|
|
|
+ FILE* procUptime;
|
|
|
+ int sec, ssec;
|
|
|
+ procUptime = fopen("/proc/uptime", "r");
|
|
|
+ int tmp = fscanf(procUptime, "%d.%ds", &sec, &ssec);
|
|
|
+ tmp++; //Pour ne pas avoir de warning
|
|
|
+ fclose(procUptime);
|
|
|
+ return (sec * sysconf(_SC_CLK_TCK)) + ssec;
|
|
|
+}
|
|
|
+
|
|
|
/**
|
|
|
* Liste les processus actifs
|
|
|
* @param int* Le nombre de processus actif
|
|
@@ -134,48 +156,42 @@ processus** list_process(int* nb){
|
|
|
*/
|
|
|
boolean read_status(processus* proc){
|
|
|
char* file;
|
|
|
- int length, fd;
|
|
|
- char buffer;
|
|
|
+ FILE* f;
|
|
|
+ int length, tmp;
|
|
|
+ char buffer[BUFFER_SIZE];
|
|
|
+ llint trash;
|
|
|
//Recup nom du fichier
|
|
|
- length = strlen(proc->path) + 7;
|
|
|
+ length = strlen(proc->path) + 5;
|
|
|
file = malloc(sizeof(char) * length);
|
|
|
memset(file, 0, length);
|
|
|
- snprintf(file, length, "%sstatus", proc->path);
|
|
|
+ snprintf(file, length, "%sstat", proc->path);
|
|
|
//Ouverture fichier
|
|
|
- fd = open(file, O_RDONLY);
|
|
|
- if(fd == ERR){
|
|
|
+ f = fopen(file, "r");;
|
|
|
+ if(!f){
|
|
|
free(file);
|
|
|
return false;
|
|
|
}
|
|
|
free(file);
|
|
|
- //Lecture jusqu'a l'etat
|
|
|
- int i = 0;
|
|
|
- while(i < 2){
|
|
|
- if(read(fd, &buffer, sizeof(char)) == ERR){
|
|
|
- return false;
|
|
|
- }
|
|
|
- if(buffer == '\n'){
|
|
|
- i++;
|
|
|
- }
|
|
|
- }
|
|
|
- while(buffer != ' '){
|
|
|
- if(read(fd, &buffer, sizeof(char)) == ERR){
|
|
|
- return false;
|
|
|
- }
|
|
|
+ //Lecture des informations
|
|
|
+ tmp = fscanf(f, "%lld ", &trash);
|
|
|
+ tmp = fscanf(f, "%s ", buffer);
|
|
|
+ tmp = fscanf(f, "%c ", &proc->state);
|
|
|
+ for (int i = 0; i < 3; i++){
|
|
|
+ tmp = fscanf(f, "%lld ", &trash);
|
|
|
}
|
|
|
- while(buffer == ' '){
|
|
|
- if(read(fd, &buffer, sizeof(char)) == ERR){
|
|
|
- return false;
|
|
|
- }
|
|
|
- }
|
|
|
- if(read(fd, &buffer, sizeof(char)) == ERR){
|
|
|
- return false;
|
|
|
+ tmp = fscanf(f, "%lld ", &proc->tty);
|
|
|
+ for (int i = 0; i < 6; i++){
|
|
|
+ tmp = fscanf(f, "%lld ", &trash);
|
|
|
}
|
|
|
- proc->state = buffer;
|
|
|
- //Fermeture
|
|
|
- if(close(fd) == ERR){
|
|
|
- //Rien de particulier
|
|
|
+ tmp = fscanf(f, "%lld ", &proc->cpu);
|
|
|
+ for (int i = 0; i < 7; i++){
|
|
|
+ tmp = fscanf(f, "%lld ", &trash);
|
|
|
}
|
|
|
+ tmp = fscanf(f, "%llu ", &proc->start);
|
|
|
+ tmp = fscanf(f, "%lld ", &proc->vsz);
|
|
|
+ tmp = fscanf(f, "%lld ", &proc->rss);
|
|
|
+ tmp++; //Pour ne pas avoir de warning
|
|
|
+ fclose(f);
|
|
|
return true;
|
|
|
}
|
|
|
|
|
@@ -284,7 +300,7 @@ boolean read_cmd(processus* proc){
|
|
|
}
|
|
|
size++;
|
|
|
//On evite les boucles infini
|
|
|
- if(size > 50){
|
|
|
+ if(size > MAX_CMD_SIZE){
|
|
|
break;
|
|
|
}
|
|
|
}
|
|
@@ -313,21 +329,54 @@ boolean read_cmd(processus* proc){
|
|
|
*/
|
|
|
void printps(processus* proc){
|
|
|
struct passwd* user;
|
|
|
+ boolean color = false;
|
|
|
+ llint vsize;
|
|
|
+ char start[BUFFER_SIZE];
|
|
|
//Recup le nom de l'utilisateur
|
|
|
user = getpwuid(proc->uid);
|
|
|
if(user == NULL){
|
|
|
addperror("Impossible de récupérer le nom de l'utilisateur");
|
|
|
return;
|
|
|
}
|
|
|
- //Affiche
|
|
|
+ //VSZ
|
|
|
+ vsize = proc->vsz / 1024;
|
|
|
+ //Debut
|
|
|
+ int uptime = get_uptime();
|
|
|
+ int running = uptime - proc->start;
|
|
|
+ time_t runningTime = time(NULL) - (running / sysconf(_SC_CLK_TCK));
|
|
|
+ strftime(start, sizeof(start), "%H:%M", localtime(&runningTime));
|
|
|
+ //Couleur
|
|
|
if(proc->state == 's'){
|
|
|
printf(RED);
|
|
|
}
|
|
|
if(proc->state == 'r'){
|
|
|
printf(MAGENTA);
|
|
|
}
|
|
|
- printf("%s %d %c %s\n", user->pw_name, proc->pid, proc->state, proc->cmd);
|
|
|
- if(proc->state == 's' || proc->state == 'r'){
|
|
|
+ switch(proc->state){
|
|
|
+ case 'S':
|
|
|
+ printf(RED);
|
|
|
+ color = true;
|
|
|
+ break;
|
|
|
+ case 'R':
|
|
|
+ printf(MAGENTA);
|
|
|
+ color = true;
|
|
|
+ break;
|
|
|
+ case 'N':
|
|
|
+ printf(BLUE);
|
|
|
+ color = true;
|
|
|
+ break;
|
|
|
+ case 'Z':
|
|
|
+ printf(YELLOW);
|
|
|
+ color = true;
|
|
|
+ break;
|
|
|
+ case 'T':
|
|
|
+ printf(GREEN);
|
|
|
+ color = true;
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ //Affiche (Manque %CPU, %MEM, TIME)
|
|
|
+ printf("%s %d %lld %lld %lld %c %s %s\n", user->pw_name, proc->pid, vsize, proc->rss, proc->tty, proc->state, start, proc->cmd);
|
|
|
+ if(color){
|
|
|
printf(RESET);
|
|
|
}
|
|
|
}
|
|
@@ -337,6 +386,9 @@ int main(){
|
|
|
processus** proc = list_process(&total);
|
|
|
//Tri des processus par rapport à leur pid
|
|
|
sort_pid(proc, total);
|
|
|
+ if(total > 0){
|
|
|
+ printf("USER PID VSZ RSS TTY STAT START COMMAND \n");
|
|
|
+ }
|
|
|
for(int i = 0; i < total; i++){
|
|
|
//Recup info manquante
|
|
|
if(!read_status(proc[i])){
|