myps.c 6.5 KB

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