myps.c 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305
  1. #define _POSIX_C_SOURCE 200809L
  2. #include <stdlib.h>
  3. #include <stdio.h>
  4. #include <dirent.h>
  5. #include <string.h>
  6. #include <sys/types.h>
  7. #include <sys/stat.h>
  8. #include <unistd.h>
  9. #include <fcntl.h>
  10. #include <pwd.h>
  11. #include "error.h"
  12. #include "color.h"
  13. #include "constante.h"
  14. typedef struct{
  15. char* path;
  16. int pid;
  17. int uid;
  18. char state;
  19. char* cmd;
  20. }processus;
  21. boolean is_numeric(const char* str){
  22. while(*str){
  23. if(*str < '0' || *str > '9'){
  24. return false;
  25. }
  26. str++;
  27. }
  28. return true;
  29. }
  30. processus** list_process(int* nb){
  31. struct dirent** dir;
  32. struct stat info;
  33. int nbRes;
  34. int length, compteur = 0;
  35. char* path;
  36. processus** result;
  37. //Recup les dossiers
  38. if((nbRes = scandir("/./proc/", &dir, 0, alphasort)) == ERR){
  39. addperror("Impossible de scanner le dossier");
  40. return NULL;
  41. }
  42. //Compte le nombre de resultat
  43. for(int i = 0; i < nbRes; i++){
  44. //Création chemin
  45. length = strlen(dir[i]->d_name) + 10;
  46. path = malloc(sizeof(char) * length);
  47. memset(path, 0, length);
  48. snprintf(path, length, "/./proc/%s/", dir[i]->d_name);
  49. //Recup info
  50. if(stat(path, &info) == ERR){
  51. //Pas un dossier
  52. continue;
  53. }
  54. //Ne regarde que les dossiers dont le nom est un nombre
  55. if(S_ISDIR(info.st_mode) && is_numeric(dir[i]->d_name)){
  56. compteur++;
  57. }
  58. free(path);
  59. }
  60. //Allocation resultat
  61. result = malloc(sizeof(processus*) * compteur);
  62. //Ajout des resultats
  63. compteur = 0;
  64. for(int i = 0; i < nbRes; i++){
  65. //Création chemin
  66. length = strlen(dir[i]->d_name) + 10;
  67. path = malloc(sizeof(char) * length);
  68. memset(path, 0, length);
  69. snprintf(path, length, "/./proc/%s/", dir[i]->d_name);
  70. //Recup info
  71. if(stat(path, &info) == ERR){
  72. //Pas un dossier
  73. continue;
  74. }
  75. //Ne regarde que les dossiers dont le nom est un nombre
  76. if(S_ISDIR(info.st_mode) && is_numeric(dir[i]->d_name)){
  77. result[compteur] = malloc(sizeof(processus));
  78. result[compteur]->path = path;
  79. result[compteur]->pid = atoi(dir[i]->d_name);
  80. result[compteur]->uid = info.st_uid;
  81. compteur++;
  82. continue;
  83. }
  84. free(path);
  85. }
  86. //Libere memoire
  87. while(nbRes--){
  88. free(dir[nbRes]);
  89. }
  90. free(dir);
  91. //Retour
  92. if(nb != NULL){
  93. *nb = compteur;
  94. }
  95. return result;
  96. }
  97. boolean read_status(processus* proc){
  98. char* file;
  99. int length, fd;
  100. char buffer;
  101. //Recup nom du fichier
  102. length = strlen(proc->path) + 7;
  103. file = malloc(sizeof(char) * length);
  104. memset(file, 0, length);
  105. snprintf(file, length, "%sstatus", proc->path);
  106. //Ouverture fichier
  107. fd = open(file, O_RDONLY);
  108. if(fd == ERR){
  109. free(file);
  110. return false;
  111. }
  112. free(file);
  113. //Lecture jusqu'a l'etat
  114. int i = 0;
  115. while(i < 2){
  116. if(read(fd, &buffer, sizeof(char)) == ERR){
  117. return false;
  118. }
  119. if(buffer == '\n'){
  120. i++;
  121. }
  122. }
  123. while(buffer != ' '){
  124. if(read(fd, &buffer, sizeof(char)) == ERR){
  125. return false;
  126. }
  127. }
  128. while(buffer == ' '){
  129. if(read(fd, &buffer, sizeof(char)) == ERR){
  130. return false;
  131. }
  132. }
  133. if(read(fd, &buffer, sizeof(char)) == ERR){
  134. return false;
  135. }
  136. proc->state = buffer;
  137. //Fermeture
  138. if(close(fd) == ERR){
  139. //Rien de particulier
  140. }
  141. return true;
  142. }
  143. boolean read_comm(processus* proc){
  144. char* file;
  145. int length, fd;
  146. int size = 0;
  147. char buf = ' ';
  148. char* buffer;
  149. boolean first = true;
  150. //Recup nom du fichier
  151. length = strlen(proc->path) + 5;
  152. file = malloc(sizeof(char) * length);
  153. memset(file, 0, length);
  154. snprintf(file, length, "%scomm", proc->path);
  155. //Ouverture fichier
  156. fd = open(file, O_RDONLY);
  157. if(fd == ERR){
  158. free(file);
  159. return false;
  160. }
  161. free(file);
  162. //Compte la taille du mot
  163. while(buf != '\n' && buf != '\0' && buf != EOF){
  164. if(read(fd, &buf, sizeof(char)) == ERR){
  165. return false;
  166. }
  167. //Au 1er tour
  168. if(first){
  169. //Si fichier vide
  170. if(buf == ' '){
  171. if(close(fd) == ERR){
  172. //Rien de particulier
  173. }
  174. return false;
  175. }
  176. first = false;
  177. }
  178. size++;
  179. }
  180. size--;
  181. //Revient au debut
  182. if(lseek(fd, 0L, SEEK_SET) == ERR){
  183. return false;
  184. }
  185. //Lecture commande
  186. buffer = malloc(sizeof(char) * (size + 3));
  187. memset(buffer, 0, size + 3);
  188. buffer[0] = '[';
  189. if(read(fd, buffer + 1, size) == ERR){
  190. return false;
  191. }
  192. buffer[strlen(buffer)] = ']';
  193. proc->cmd = buffer;
  194. //Fermeture
  195. if(close(fd) == ERR){
  196. //Rien de particulier
  197. }
  198. return true;
  199. }
  200. boolean read_cmd(processus* proc){
  201. char* file;
  202. int length, fd;
  203. int size = 0;
  204. char buf = ' ';
  205. char* buffer;
  206. boolean first = true;
  207. //Recup nom du fichier
  208. length = strlen(proc->path) + 8;
  209. file = malloc(sizeof(char) * length);
  210. memset(file, 0, length);
  211. snprintf(file, length, "%scmdline", proc->path);
  212. //Ouverture fichier
  213. fd = open(file, O_RDONLY);
  214. if(fd == ERR){
  215. free(file);
  216. return false;
  217. }
  218. free(file);
  219. //Compte la taille du mot
  220. while(buf != '\n' && buf != '\0' && buf != EOF){
  221. if(read(fd, &buf, sizeof(char)) == ERR){
  222. return false;
  223. }
  224. //Au 1er tour
  225. if(first){
  226. //Si fichier vide
  227. if(buf == ' '){
  228. if(close(fd) == ERR){
  229. //Rien de particulier
  230. }
  231. return read_comm(proc);
  232. }
  233. first = false;
  234. }
  235. size++;
  236. //On evite les boucles infini
  237. if(size > 50){
  238. break;
  239. }
  240. }
  241. size--;
  242. //Revient au debut
  243. if(lseek(fd, 0L, SEEK_SET) == ERR){
  244. return false;
  245. }
  246. //Lecture commande
  247. buffer = malloc(sizeof(char) * (size + 1));
  248. memset(buffer, 0, size + 1);
  249. if(read(fd, buffer, size) == ERR){
  250. return false;
  251. }
  252. proc->cmd = buffer;
  253. //Fermeture
  254. if(close(fd) == ERR){
  255. //Rien de particulier
  256. }
  257. return true;
  258. }
  259. void printps(processus* proc){
  260. struct passwd* user;
  261. //Recup le nom de l'utilisateur
  262. user = getpwuid(proc->uid);
  263. if(user == NULL){
  264. addperror("Impossible de récupérer le nom de l'utilisateur");
  265. return;
  266. }
  267. //Affiche
  268. if(proc->state == 's'){
  269. printf(RED);
  270. }
  271. printf("%s %d %c %s\n", user->pw_name, proc->pid, proc->state, proc->cmd);
  272. if(proc->state == 's'){
  273. printf(RESET);
  274. }
  275. }
  276. int main(){
  277. int total;
  278. processus** proc = list_process(&total);
  279. for(int i = 0; i < total; i++){
  280. //Recup info manquante
  281. if(!read_status(proc[i])){
  282. continue;
  283. }
  284. if(!read_cmd(proc[i])){
  285. continue;
  286. }
  287. //Affiche
  288. printps(proc[i]);
  289. //Supprime
  290. free(proc[i]->path);
  291. free(proc[i]->cmd);
  292. free(proc[i]);
  293. }
  294. free(proc);
  295. return EXIT_SUCCESS;
  296. }