소스 검색

Ajout myps

Loquicom 6 년 전
부모
커밋
d2f4c5e15b
4개의 변경된 파일308개의 추가작업 그리고 2개의 파일을 삭제
  1. 1 1
      README.md
  2. 2 1
      makefile
  3. BIN
      myps
  4. 305 0
      myps.c

+ 1 - 1
README.md

@@ -37,7 +37,7 @@ Absentes :
 
 ## Bug / Fonctionalitées partiels
 
-La commande myps liste les processus en cours d'exécution avec leur PID, le nom de la commande et l'utilisateur qui l'a lancé. Elle ne récupère qu'une partie des infos présente dans `ps -aux`.
+La commande myps liste les processus en cours d'exécution avec leur PID, le nom de la commande, l'etat et l'utilisateur qui l'a lancé. Elle ne récupère qu'une partie des infos présente dans `ps -aux`.
 
 La commande myls n'indique pas la valeur de la 2éme colonne du `ls -l` (un nombre), et affiche X à la place.
 

+ 2 - 1
makefile

@@ -2,7 +2,7 @@
 # CONFIGURATION GENERALE
 #
 
-EXEC = mysh myls
+EXEC = mysh myls myps
 OBJETS = error.o str.o parser.o wildcard.o command.o execute.o sem.o shm.o subdiv.o ipc.o expreg.o variable.o
 NOM_PROJET = mini-shell
 
@@ -115,3 +115,4 @@ variable.o: variable.c str.h expreg.h constante.h variable.h subdiv.h
 mysh.o: mysh.c error.h str.h parser.h constante.h mysh.h command.h ipc.h \
  sem.h shm.h subdiv.h execute.h
 myls.o: myls.c error.h color.h constante.h
+myps.o: myps.c error.h color.h constante.h

BIN
myps


+ 305 - 0
myps.c

@@ -0,0 +1,305 @@
+#define _POSIX_C_SOURCE 200809L
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <dirent.h>
+#include <string.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <pwd.h>
+#include "error.h"
+#include "color.h"
+#include "constante.h"
+
+typedef struct{
+	char* path;
+	int pid;
+	int uid;
+	char state;
+	char* cmd;
+}processus;
+
+boolean is_numeric(const char* str){
+	while(*str){
+		if(*str < '0' || *str > '9'){
+			return false;
+		}
+		str++;
+	}
+	return true;
+}
+
+processus** list_process(int* nb){
+	struct dirent** dir;
+	struct stat info;
+	int nbRes;
+	int length, compteur = 0;
+	char* path;
+	processus** result;
+	//Recup les dossiers
+    if((nbRes = scandir("/./proc/", &dir, 0, alphasort)) == ERR){
+        addperror("Impossible de scanner le dossier");
+        return NULL;
+    }
+    //Compte le nombre de resultat
+    for(int i = 0; i < nbRes; i++){
+    	//Création chemin
+    	length = strlen(dir[i]->d_name) + 10;
+	   	path = malloc(sizeof(char) * length);
+	   	memset(path, 0, length);
+	   	snprintf(path, length, "/./proc/%s/", dir[i]->d_name);
+    	//Recup info
+        if(stat(path, &info) == ERR){
+            //Pas un dossier
+            continue;
+        }
+        //Ne regarde que les dossiers dont le nom est un nombre
+        if(S_ISDIR(info.st_mode) && is_numeric(dir[i]->d_name)){
+        	compteur++;
+        }
+        free(path);
+    }
+    //Allocation resultat
+    result = malloc(sizeof(processus*) * compteur);
+    //Ajout des resultats
+    compteur = 0;
+    for(int i = 0; i < nbRes; i++){
+    	//Création chemin
+    	length = strlen(dir[i]->d_name) + 10;
+	    path = malloc(sizeof(char) * length);
+	    memset(path, 0, length);
+	    snprintf(path, length, "/./proc/%s/", dir[i]->d_name);
+    	//Recup info
+        if(stat(path, &info) == ERR){
+        	//Pas un dossier
+            continue;
+        }
+        //Ne regarde que les dossiers dont le nom est un nombre
+        if(S_ISDIR(info.st_mode) && is_numeric(dir[i]->d_name)){
+        	result[compteur] = malloc(sizeof(processus));
+        	result[compteur]->path = path;
+        	result[compteur]->pid = atoi(dir[i]->d_name);
+        	result[compteur]->uid = info.st_uid;
+        	compteur++;
+        	continue;
+        }
+        free(path);
+    }
+    //Libere memoire
+    while(nbRes--){
+    	free(dir[nbRes]);
+    }
+    free(dir);
+    //Retour
+    if(nb != NULL){
+    	*nb = compteur;
+    }
+    return result;
+}
+
+boolean read_status(processus* proc){
+	char* file;
+	int length, fd;
+	char buffer;
+	//Recup nom du fichier
+	length = strlen(proc->path) + 7;
+	file = malloc(sizeof(char) * length);
+	memset(file, 0, length);
+	snprintf(file, length, "%sstatus", proc->path);
+	//Ouverture fichier
+	fd = open(file, O_RDONLY);
+	if(fd == ERR){
+		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;
+		}
+	}
+	while(buffer == ' '){
+		if(read(fd, &buffer, sizeof(char)) == ERR){
+			return false;
+		}
+	}
+	if(read(fd, &buffer, sizeof(char)) == ERR){
+		return false;
+	}
+	proc->state = buffer;
+	//Fermeture
+	if(close(fd) == ERR){
+		//Rien de particulier
+	}
+	return true;
+}
+
+boolean read_comm(processus* proc){
+	char* file;
+	int length, fd;
+	int size = 0;
+	char buf = ' ';
+	char* buffer;
+	boolean first = true;
+	//Recup nom du fichier
+	length = strlen(proc->path) + 5;
+	file = malloc(sizeof(char) * length);
+	memset(file, 0, length);
+	snprintf(file, length, "%scomm", proc->path);
+	//Ouverture fichier
+	fd = open(file, O_RDONLY);
+	if(fd == ERR){
+		free(file);
+		return  false;
+	}
+	free(file);
+	//Compte la taille du mot
+	while(buf != '\n' && buf != '\0' && buf != EOF){
+		if(read(fd, &buf, sizeof(char)) == ERR){
+			return false;
+		}
+		//Au 1er tour
+		if(first){
+			//Si fichier vide
+			if(buf == ' '){
+				if(close(fd) == ERR){
+				//Rien de particulier
+				}
+				return false;
+			}
+			first = false;
+		}
+		size++;
+	}
+	size--;
+	//Revient au debut
+	if(lseek(fd, 0L, SEEK_SET) == ERR){
+		return false;
+	}
+	//Lecture commande
+	buffer = malloc(sizeof(char) * (size + 3));
+	memset(buffer, 0, size + 3);
+	buffer[0] = '[';
+	if(read(fd, buffer + 1, size) == ERR){
+		return false;
+	}
+	buffer[strlen(buffer)] = ']';
+	proc->cmd = buffer;
+	//Fermeture
+	if(close(fd) == ERR){
+		//Rien de particulier
+	}
+	return true;
+}
+
+boolean read_cmd(processus* proc){
+	char* file;
+	int length, fd;
+	int size = 0;
+	char buf = ' ';
+	char* buffer;
+	boolean first = true;
+	//Recup nom du fichier
+	length = strlen(proc->path) + 8;
+	file = malloc(sizeof(char) * length);
+	memset(file, 0, length);
+	snprintf(file, length, "%scmdline", proc->path);
+	//Ouverture fichier
+	fd = open(file, O_RDONLY);
+	if(fd == ERR){
+		free(file);
+		return  false;
+	}
+	free(file);
+	//Compte la taille du mot
+	while(buf != '\n' && buf != '\0' && buf != EOF){
+		if(read(fd, &buf, sizeof(char)) == ERR){
+			return false;
+		}
+		//Au 1er tour
+		if(first){
+			//Si fichier vide
+			if(buf == ' '){
+				if(close(fd) == ERR){
+				//Rien de particulier
+				}
+				return read_comm(proc);
+			}
+			first = false;
+		}
+		size++;
+		//On evite les boucles infini
+		if(size > 50){
+			break;
+		}
+	}
+	size--;
+	//Revient au debut
+	if(lseek(fd, 0L, SEEK_SET) == ERR){
+		return false;
+	}
+	//Lecture commande
+	buffer = malloc(sizeof(char) * (size + 1));
+	memset(buffer, 0, size + 1);
+	if(read(fd, buffer, size) == ERR){
+		return false;
+	}
+	proc->cmd = buffer;
+	//Fermeture
+	if(close(fd) == ERR){
+		//Rien de particulier
+	}
+	return true;
+}
+
+void printps(processus* proc){
+	struct passwd* user;
+	//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
+	if(proc->state == 's'){
+		printf(RED);
+	}
+	printf("%s %d %c %s\n", user->pw_name, proc->pid, proc->state, proc->cmd);
+	if(proc->state == 's'){
+		printf(RESET);
+	}
+}
+
+int main(){
+	int total;
+	processus** proc = list_process(&total);
+	for(int i = 0; i < total; i++){
+		//Recup info manquante
+		if(!read_status(proc[i])){
+			continue;
+		}
+		if(!read_cmd(proc[i])){
+			continue;
+		}
+		//Affiche
+		printps(proc[i]);
+		//Supprime
+		free(proc[i]->path);
+		free(proc[i]->cmd);
+		free(proc[i]);
+	}
+	free(proc);
+	return EXIT_SUCCESS;
+}