Advertisement
Guest User

Untitled

a guest
Mar 18th, 2018
79
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 7.34 KB | None | 0 0
  1. #include <unistd.h>
  2. #include <stdlib.h>
  3. #include <stdio.h>
  4. #include <string.h>
  5. #include <fcntl.h>
  6. #include <stdarg.h>
  7. #include <stdio.h> // pour les msg d'erreur uniquement
  8. #include <stdnoreturn.h> // C norme 2011
  9. #include <sys/types.h>
  10. #include <sys/wait.h>
  11. #include <errno.h>
  12. #include <ctype.h>
  13.  
  14. #define CODE_ERREUR 255
  15. #define BUFFER_SIZE 2048
  16.  
  17. int dflag = 0;
  18. int vflag = 0;
  19.  
  20. /******************************************************************************
  21. * Gestion des erreurs
  22. */
  23.  
  24. char *prog; // nom du programme pour les erreurs
  25.  
  26. noreturn void raler (int syserr, const char *fmt, ...) {
  27. va_list ap;
  28.  
  29. va_start (ap, fmt);
  30. fprintf (stderr, "%s: ", prog);
  31. vfprintf (stderr, fmt, ap);
  32. fprintf (stderr, "\n");
  33. va_end (ap);
  34.  
  35. if (syserr)
  36. perror ("");
  37.  
  38. exit (CODE_ERREUR);
  39. }
  40.  
  41. noreturn void usage (void) {
  42. fprintf (stderr, "usage: %s [-d|-v] [fichier-spec]\n", prog);
  43. exit (1);
  44. }
  45.  
  46. /******************************************************************************
  47. * Transformation de la spécification en structure d'arbre
  48. * => utiliser la fonction analyser_spec()
  49. */
  50.  
  51. struct sommet {
  52. int val; // étiquette du sommet
  53. struct sommet *frere_suivant; // liste des frères
  54. struct sommet *premier_fils; // premier des fils
  55. /*
  56. * Ce dernier champ (dernier_fils) n'est utilisé que pendant la
  57. * construction de l'arbre, pour insérer en queue et ainsi
  58. * respecter l'ordre des processus dans la spécification.
  59. */
  60. struct sommet *dernier_fils; // pour insertion en queue
  61. };
  62.  
  63. /*
  64. * Fonction interne pour l'analyse de la spécification : analyse une
  65. * ligne de la spécification (la ligne pointée par *spec), et
  66. * retourne la profondeur, la valeur, et la position suivante (via
  67. * *spec) et un code pour dire si on a rencontré une erreur, une fin
  68. * de spéc ou si tout baigne.
  69. */
  70.  
  71. enum ret_al { AL_ERR, AL_FIN, AL_OK }; // retour de analyser_ligne
  72.  
  73. enum ret_al analyser_ligne (char **spec, int *prof, int *val) {
  74. *prof = *val = 0; // mettre les compteurs à 0
  75.  
  76. if (**spec == '\0') // spec terminée
  77. return AL_FIN;
  78.  
  79. /*
  80. * Compter les espaces pour avoir la profondeur
  81. */
  82. while (**spec == ' ') {
  83. (*spec)++;
  84. (*prof)++;
  85. }
  86.  
  87. /*
  88. * Récupérer la valeur
  89. */
  90.  
  91. char *debut = *spec; // vérifier au moins un chiffre
  92. while (isdigit (**spec)) {
  93. *val = *val * 10 + (**spec - '0');
  94. (*spec)++;
  95. }
  96.  
  97. if (debut == *spec) // on n'a pas avancé => pb
  98. return AL_ERR;
  99.  
  100. /*
  101. * Vérifier qu'on est bien à la fin d'une ligne
  102. */
  103.  
  104. if (**spec != '\n')
  105. return AL_ERR;
  106. (*spec)++; // passer au sommet suivant
  107.  
  108. return AL_OK;
  109. }
  110.  
  111. struct sommet *creer_sommet (int val) {
  112. struct sommet *s;
  113.  
  114. s = malloc (sizeof *s);
  115. if (s == NULL)
  116. raler(1, "cannot malloc %d bytes", sizeof *s);
  117.  
  118. s->frere_suivant = NULL;
  119. s->premier_fils = NULL;
  120. s->dernier_fils = NULL;
  121. s->val = val;
  122. return s;
  123. }
  124.  
  125. struct sommet *analyser_spec_profondeur(int *numl, char **spec, int prof) {
  126. char *nspec;
  127. int nprof, val;
  128. struct sommet *s;
  129. enum ret_al r;
  130.  
  131. /*
  132. * Analyser la racine du sous-arbre
  133. */
  134.  
  135. nspec = *spec;
  136. r = analyser_ligne(&nspec, &nprof, &val);
  137. switch (r) {
  138. case AL_ERR :
  139. raler (0, "cannot parse spec at line %d", *numl);
  140. case AL_FIN :
  141. return NULL;
  142. case AL_OK : // on continue en séquence
  143. break;
  144. default : // programmation défensive
  145. raler (0, "internal error at line %d", *numl);
  146. }
  147. if (nprof != prof)
  148. raler (0, "unexpected depth (%d) at line %d", nprof, *numl);
  149.  
  150. s = creer_sommet (val);
  151. *spec = nspec;
  152. (*numl)++;
  153.  
  154. /*
  155. * Chercher les fils directs de la racine
  156. */
  157.  
  158. while ((r= analyser_ligne(&nspec, &nprof, &val)) == AL_OK && nprof > prof) {
  159. struct sommet *f; // sous-arbre fils trouvé
  160.  
  161. nspec = *spec;
  162. f = analyser_spec_profondeur (numl, &nspec, prof + 1);
  163.  
  164. // Est-ce le premier fils ou bien y-a-t'il déjà au moins un ?
  165. if (s->dernier_fils == NULL) {
  166. s->premier_fils = s->dernier_fils = f;
  167. } else {
  168. s->dernier_fils->frere_suivant = f;
  169. s->dernier_fils = f;
  170. }
  171. *spec = nspec;
  172. }
  173.  
  174. if (r == AL_ERR)
  175. raler(0, "cannot parse spec at line %d", *numl);
  176.  
  177. return s;
  178. }
  179.  
  180.  
  181. struct sommet *analyser_spec (char *spec)
  182. {
  183. struct sommet *s; // arbre obtenu
  184. int numl; // numéro de ligne pour msg err
  185.  
  186. numl = 1;
  187. s = analyser_spec_profondeur (&numl, &spec, 0);
  188.  
  189. if (*spec != '\0') // est-on bien à la fin ?
  190. raler (0, "invalid spec at line %d", numl);
  191.  
  192. return s;
  193. }
  194.  
  195. void readfile(int fd, char* buff) {
  196. int nb_car;
  197. int count = 0;
  198. printf("yo %d \n", getpid());
  199.  
  200. while ((nb_car = read(fd, &buff[count], 2048)) != 0 && ) {
  201. if (nb_car == -1)
  202. raler (1, "cannot read file");
  203.  
  204. count += nb_car;
  205.  
  206. if (realloc(buff, sizeof(buff) + 2048) == NULL)
  207. raler (1, "cannot realloc");
  208. }
  209. }
  210.  
  211. int cfork (struct sommet* s) {
  212. pid_t f;
  213. unsigned int count = 0;
  214. int w, status, exits = 0;
  215. struct sommet* current;
  216. unsigned int i;
  217.  
  218. if (s == NULL)
  219. return 255;
  220.  
  221. current = s->premier_fils;
  222.  
  223. while (current != NULL) {
  224. f = fork();
  225.  
  226. switch(f) {
  227. case -1: {
  228. fprintf(stderr, "buggggggg");
  229. exit(255);
  230. break;
  231. }
  232.  
  233. case 0: {
  234. exit(cfork(current));
  235. break;
  236. }
  237.  
  238. default: {
  239. if (vflag)
  240. printf("pid %d -> %d\n", getpid(), f);
  241. break;
  242. }
  243. }
  244. current = current->frere_suivant;
  245. count++;
  246. }
  247.  
  248. if (vflag)
  249. printf("pid %d : attente %d ms\n", getpid(), s->val);
  250.  
  251. usleep(1000 * s->val);
  252.  
  253. for (i = 0; i < count; i++) {
  254. if (wait(&status) == -1)
  255. raler(0, "wait fail");
  256.  
  257. if (WIFEXITED(status) && (w = WEXITSTATUS(status)) < 255) {
  258. exits += 1 + w;
  259. } else {
  260. exit(255);
  261. }
  262. }
  263. if (vflag)
  264. printf("pid %d <- %d processus\n", getpid(), exits);
  265.  
  266. free(s);
  267. return exits;
  268. }
  269.  
  270. int main(int argc, char** argv) {
  271. int fd;
  272. char* buff;
  273. char c;
  274. struct sommet* debut;
  275.  
  276. while ((c = getopt (argc, argv, "dv")) != -1) {
  277. switch (c) {
  278. case 'd':
  279. dflag = 1;
  280. break;
  281. case 'v':
  282. vflag = 1;
  283. break;
  284. default:
  285. usage();
  286. }
  287. }
  288.  
  289. buff = malloc(2048);
  290.  
  291. if (argc-optind>1 || optind>3){
  292. usage();
  293. } else if (argc==optind){
  294. fd = 0;
  295. } else {
  296. fd = open(argv[optind], O_RDONLY);
  297. }
  298.  
  299. if (fd == -1)
  300. raler (1, "cannot open");
  301.  
  302. readfile(fd, buff);
  303.  
  304. if (close (fd) == -1)
  305. raler (1, "cannot close %s", "plop");
  306.  
  307. if (dflag)
  308. printf("%s", buff);
  309.  
  310. debut = analyser_spec(buff);
  311. free(buff);
  312.  
  313.  
  314. exit(cfork(debut) + 1);
  315.  
  316. return EXIT_SUCCESS;
  317. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement