Salut à tous,
J'essaie de faire une fork bomb que je puisse arrêter avec un CTRL+C dans le terminal. Ainsi :
-
Si je lance mon programme, le processus courant crée un processus qui en crée un autre et ainsi de suite, jusqu'à ce que la table des processus soit totalement remplie et que l'OS soit incapable d'en créer de nouveaux (c'est la définition d'une fork bomb "normale") ;
-
Mais je dois pouvoir à tout moment faire un CTRL+C dans le terminal. Ce CTRL+C tuera tous les processus et arrêtera aussi (du coup !) la création de nouveaux processus (petite fonctionnalité supplémentaire pour ma fork bomb, par rapport à une "normale").
Plus de précisions
Je veux détailler le point n°1. En effet, mon programme n'agit pas exactement comme c'est décrit.
En réalité :
-
Le tout premier processus, celui de mon programme (ie. : le principal) crée son seul et unique enfant direct.
-
Ce dernier créera ses propres enfants, jusqu'à saturation de la liste des processus.
-
Ces derniers feront des calculs, une pause, mais tourneront sans s'arrêter (pour permettre la saturation).
Les enfants de l'enfant direct du processus principal, ainsi que cet enfant direct, appartiendront à un même groupe de façon à simplifier le fait de les tuer avec CTRL+C.
Mon problème
Petit souci avec le code que j'ai écrit : le CTRL+C ne semble pas être attrapé/géré !
Du coup impossible d'arrêter mon programme, et je dois redémarrer ma machine virtuelle…
Est-ce que vous pourriez y jeter un coup d'oeil svp ? Merci !
Mon code
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 | #include <unistd.h> #include <stdlib.h> #include <stdio.h> #include <sys/resource.h> int main(int argc, char* argv[]) { pid_t pid_first_child = 0; if((pid_first_child = fork()) == -1) { // We `fork` the first child, which will always `fork` (more precisely : until the OS is glued, processes table completely filled) perror("fork"); exit(EXIT_FAILURE); } if(pid_first_child == 0) { // BEGINNING OF <FirstChild>'S CODE pid_t pid_session_leader = 0; if((pid_session_leader = setsid()) == -1) { // FirstChild is its process group's leader perror("setsid"); exit(EXIT_FAILURE); } if(setpriority(PRIO_PGRP, pid_session_leader, -10) == -1) { // The priority of FirstChild (which is the group's leader) perror("setpriority"); exit(EXIT_FAILURE); } unsigned children_counter = 0; pid_t pid_calculation_process = 0; while((pid_calculation_process = fork()) != -1) { // Now, FirstChild will `fork` until the limit ! When the limit is reached, -1 is returned : there isn't anymore `fork` and we exit the loop if(pid_calculation_process > 0) { children_counter++; fprintf(stdout, "%u\n", children_counter); } else { // BEGINNING OF <FirstChild's children>'s CODE (Why ? Consequently to the `while` and the `if` !) float j=1; while(1) { // Children can't die int i = 0; for(; i < 1000; i++) { j /= 3; } usleep(1000); } } // END OF <FirstChild's children>'s CODE (FirstChild's children) } perror("fork"); // It's what we wanted ! This message will tell the user "OS is glued, program worked correctly" exit(EXIT_SUCCESS); // `EXIT_SUCCESS` ? Because we reached the limit ! } // END OF <FirstChild>'S CODE } |