![]() ![]() | ![]() |
Commit après restauration de la sauvegarde.
1: /* 2: ================================================================================ 3: RPL/2 (R) version 4.1.3 4: Copyright (C) 1989-2011 Dr. BERTRAND Joël 5: 6: This file is part of RPL/2. 7: 8: RPL/2 is free software; you can redistribute it and/or modify it 9: under the terms of the CeCILL V2 License as published by the french 10: CEA, CNRS and INRIA. 11: 12: RPL/2 is distributed in the hope that it will be useful, but WITHOUT 13: ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 14: FITNESS FOR A PARTICULAR PURPOSE. See the CeCILL V2 License 15: for more details. 16: 17: You should have received a copy of the CeCILL License 18: along with RPL/2. If not, write to info@cecill.info. 19: ================================================================================ 20: */ 21: 22: 23: #include "rpl-conv.h" 24: 25: 26: /* 27: ================================================================================ 28: Fonction 'DFT' 29: ================================================================================ 30: Entrées : structure processus 31: -------------------------------------------------------------------------------- 32: Sorties : 33: -------------------------------------------------------------------------------- 34: Effets de bord : néant 35: ================================================================================ 36: */ 37: 38: void 39: instruction_dft(struct_processus *s_etat_processus) 40: { 41: integer4 erreur; 42: integer4 inverse; 43: integer4 nombre_colonnes; 44: integer4 nombre_lignes; 45: 46: logical1 presence_longueur_dft; 47: 48: long longueur_dft_signee; 49: 50: struct_complexe16 *matrice_f77; 51: 52: struct_objet *s_objet_argument; 53: struct_objet *s_objet_longueur_dft; 54: struct_objet *s_objet_resultat; 55: 56: unsigned long i; 57: unsigned long j; 58: unsigned long k; 59: unsigned long longueur_dft; 60: 61: (*s_etat_processus).erreur_execution = d_ex; 62: 63: if ((*s_etat_processus).affichage_arguments == 'Y') 64: { 65: printf("\n DFT "); 66: 67: if ((*s_etat_processus).langue == 'F') 68: { 69: printf("(transformée de Fourier discrète)\n\n"); 70: } 71: else 72: { 73: printf("(discrete Fourier transform)\n\n"); 74: } 75: 76: printf(" 1: %s, %s, %s\n", d_VIN, d_VRL, d_VCX); 77: printf("-> 1: %s\n\n", d_VCX); 78: 79: printf(" 2: %s, %s, %s\n", d_VIN, d_VRL, d_VCX); 80: printf(" 1: %s\n", d_INT); 81: printf("-> 1: %s\n\n", d_VCX); 82: 83: printf(" 1: %s, %s, %s\n", d_MIN, d_MRL, d_MCX); 84: printf("-> 1: %s\n\n", d_VCX); 85: 86: printf(" 2: %s, %s, %s\n", d_MIN, d_MRL, d_MCX); 87: printf(" 1: %s\n", d_INT); 88: printf("-> 1: %s\n", d_MCX); 89: 90: return; 91: } 92: else if ((*s_etat_processus).test_instruction == 'Y') 93: { 94: (*s_etat_processus).nombre_arguments = -1; 95: return; 96: } 97: 98: /* 99: * Il est possible d'imposer une longueur de DFT au premier niveau 100: * de la pile. 101: */ 102: 103: if ((*s_etat_processus).l_base_pile == NULL) 104: { 105: (*s_etat_processus).erreur_execution = d_ex_manque_argument; 106: return; 107: } 108: 109: if ((*(*(*s_etat_processus).l_base_pile).donnee).type == INT) 110: { 111: presence_longueur_dft = d_vrai; 112: 113: if (test_cfsf(s_etat_processus, 31) == d_vrai) 114: { 115: if (empilement_pile_last(s_etat_processus, 2) == d_erreur) 116: { 117: return; 118: } 119: } 120: 121: if (depilement(s_etat_processus, &((*s_etat_processus).l_base_pile), 122: &s_objet_longueur_dft) == d_erreur) 123: { 124: (*s_etat_processus).erreur_execution = d_ex_manque_argument; 125: return; 126: } 127: 128: longueur_dft_signee = (*((integer8 *) (*s_objet_longueur_dft).objet)); 129: 130: liberation(s_etat_processus, s_objet_longueur_dft); 131: 132: if (longueur_dft_signee <= 0) 133: { 134: (*s_etat_processus).erreur_execution = d_ex_longueur_dft; 135: return; 136: } 137: 138: longueur_dft = longueur_dft_signee; 139: } 140: else 141: { 142: presence_longueur_dft = d_faux; 143: longueur_dft = 0; 144: 145: if (test_cfsf(s_etat_processus, 31) == d_vrai) 146: { 147: if (empilement_pile_last(s_etat_processus, 1) == d_erreur) 148: { 149: return; 150: } 151: } 152: } 153: 154: if (depilement(s_etat_processus, &((*s_etat_processus).l_base_pile), 155: &s_objet_argument) == d_erreur) 156: { 157: (*s_etat_processus).erreur_execution = d_ex_manque_argument; 158: return; 159: } 160: 161: /* 162: -------------------------------------------------------------------------------- 163: Vecteur 164: -------------------------------------------------------------------------------- 165: */ 166: 167: if (((*s_objet_argument).type == VIN) || 168: ((*s_objet_argument).type == VRL) || 169: ((*s_objet_argument).type == VCX)) 170: { 171: if (presence_longueur_dft == d_faux) 172: { 173: longueur_dft = (*((struct_vecteur *) 174: (*s_objet_argument).objet)).taille; 175: } 176: 177: if ((matrice_f77 = malloc(longueur_dft * 178: sizeof(struct_complexe16))) == NULL) 179: { 180: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire; 181: return; 182: } 183: 184: if ((*s_objet_argument).type == VIN) 185: { 186: for(i = 0; i < (*((struct_vecteur *) (*s_objet_argument).objet)) 187: .taille; i++) 188: { 189: matrice_f77[i].partie_reelle = (real8) ((integer8 *) 190: (*((struct_vecteur *) (*s_objet_argument).objet)) 191: .tableau)[i]; 192: matrice_f77[i].partie_imaginaire = (real8) 0; 193: } 194: } 195: else if ((*s_objet_argument).type == VRL) 196: { 197: for(i = 0; i < (*((struct_vecteur *) (*s_objet_argument).objet)) 198: .taille; i++) 199: { 200: matrice_f77[i].partie_reelle = ((real8 *) 201: (*((struct_vecteur *) (*s_objet_argument).objet)) 202: .tableau)[i]; 203: matrice_f77[i].partie_imaginaire = (real8) 0; 204: } 205: } 206: else 207: { 208: for(i = 0; i < (*((struct_vecteur *) (*s_objet_argument).objet)) 209: .taille; i++) 210: { 211: matrice_f77[i].partie_reelle = ((struct_complexe16 *) 212: (*((struct_vecteur *) (*s_objet_argument).objet)) 213: .tableau)[i].partie_reelle; 214: matrice_f77[i].partie_imaginaire = ((struct_complexe16 *) 215: (*((struct_vecteur *) (*s_objet_argument).objet)) 216: .tableau)[i].partie_imaginaire; 217: } 218: } 219: 220: for(; i < longueur_dft; i++) 221: { 222: matrice_f77[i].partie_reelle = (real8) 0; 223: matrice_f77[i].partie_imaginaire = (real8) 0; 224: } 225: 226: nombre_lignes = 1; 227: nombre_colonnes = longueur_dft; 228: inverse = 0; 229: 230: dft(matrice_f77, &nombre_lignes, &nombre_colonnes, &inverse, &erreur); 231: 232: if (erreur != 0) 233: { 234: liberation(s_etat_processus, s_objet_argument); 235: free(matrice_f77); 236: 237: (*s_etat_processus).erreur_execution = d_ex_longueur_dft; 238: return; 239: } 240: 241: if ((s_objet_resultat = allocation(s_etat_processus, VCX)) == NULL) 242: { 243: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire; 244: return; 245: } 246: 247: (*((struct_vecteur *) (*s_objet_resultat).objet)).taille = longueur_dft; 248: (*((struct_vecteur *) (*s_objet_resultat).objet)).tableau = matrice_f77; 249: } 250: 251: /* 252: -------------------------------------------------------------------------------- 253: Matrice 254: -------------------------------------------------------------------------------- 255: */ 256: 257: else if (((*s_objet_argument).type == MIN) || 258: ((*s_objet_argument).type == MRL) || 259: ((*s_objet_argument).type == MCX)) 260: { 261: if (presence_longueur_dft == d_faux) 262: { 263: longueur_dft = (*((struct_matrice *) 264: (*s_objet_argument).objet)).nombre_colonnes; 265: } 266: 267: if ((matrice_f77 = malloc(longueur_dft * 268: (*((struct_matrice *) (*s_objet_argument).objet)) 269: .nombre_lignes * sizeof(struct_complexe16))) == NULL) 270: { 271: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire; 272: return; 273: } 274: 275: if ((*s_objet_argument).type == MIN) 276: { 277: for(k = 0, j = 0; j < (*((struct_matrice *) (*s_objet_argument) 278: .objet)).nombre_lignes; j++) 279: { 280: for(i = 0; i < (*((struct_matrice *) (*s_objet_argument) 281: .objet)).nombre_colonnes; i++) 282: { 283: matrice_f77[k].partie_reelle = (real8) ((integer8 **) 284: (*((struct_matrice *) (*s_objet_argument).objet)) 285: .tableau)[j][i]; 286: matrice_f77[k++].partie_imaginaire = (real8) 0; 287: } 288: } 289: 290: for(; k < longueur_dft * (*((struct_matrice *) (*s_objet_argument) 291: .objet)).nombre_lignes; k++) 292: { 293: matrice_f77[k].partie_reelle = (real8) 0; 294: matrice_f77[k].partie_imaginaire = (real8) 0; 295: } 296: } 297: else if ((*s_objet_argument).type == MRL) 298: { 299: for(k = 0, j = 0; j < (*((struct_matrice *) (*s_objet_argument) 300: .objet)).nombre_lignes; j++) 301: { 302: for(i = 0; i < (*((struct_matrice *) (*s_objet_argument) 303: .objet)).nombre_colonnes; i++) 304: { 305: matrice_f77[k].partie_reelle = ((real8 **) 306: (*((struct_matrice *) (*s_objet_argument).objet)) 307: .tableau)[j][i]; 308: matrice_f77[k++].partie_imaginaire = (real8) 0; 309: } 310: } 311: 312: for(; k < longueur_dft * (*((struct_matrice *) (*s_objet_argument) 313: .objet)).nombre_lignes; k++) 314: { 315: matrice_f77[k].partie_reelle = (real8) 0; 316: matrice_f77[k].partie_imaginaire = (real8) 0; 317: } 318: } 319: else 320: { 321: for(k = 0, j = 0; j < (*((struct_matrice *) (*s_objet_argument) 322: .objet)).nombre_lignes; j++) 323: { 324: for(i = 0; i < (*((struct_matrice *) (*s_objet_argument) 325: .objet)).nombre_colonnes; i++) 326: { 327: matrice_f77[k].partie_reelle = ((struct_complexe16 **) 328: (*((struct_matrice *) (*s_objet_argument).objet)) 329: .tableau)[j][i].partie_reelle; 330: matrice_f77[k++].partie_imaginaire = 331: ((struct_complexe16 **) (*((struct_matrice *) 332: (*s_objet_argument).objet)).tableau)[j][i] 333: .partie_imaginaire; 334: } 335: } 336: 337: for(; k < longueur_dft * (*((struct_matrice *) (*s_objet_argument) 338: .objet)).nombre_lignes; k++) 339: { 340: matrice_f77[k].partie_reelle = (real8) 0; 341: matrice_f77[k].partie_imaginaire = (real8) 0; 342: } 343: } 344: 345: nombre_lignes = (*((struct_matrice *) (*s_objet_argument).objet)) 346: .nombre_lignes; 347: nombre_colonnes = longueur_dft; 348: inverse = 0; 349: 350: dft(matrice_f77, &nombre_lignes, &nombre_colonnes, &inverse, &erreur); 351: 352: if (erreur != 0) 353: { 354: liberation(s_etat_processus, s_objet_argument); 355: free(matrice_f77); 356: 357: (*s_etat_processus).erreur_execution = d_ex_longueur_dft; 358: return; 359: } 360: 361: if ((s_objet_resultat = allocation(s_etat_processus, MCX)) == NULL) 362: { 363: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire; 364: return; 365: } 366: 367: (*((struct_matrice *) (*s_objet_resultat).objet)).nombre_lignes = 368: (*((struct_matrice *) (*s_objet_argument).objet)) 369: .nombre_lignes; 370: (*((struct_matrice *) (*s_objet_resultat).objet)).nombre_colonnes = 371: longueur_dft; 372: 373: if (((*((struct_matrice *) (*s_objet_resultat).objet)).tableau = 374: malloc((*((struct_matrice *) (*s_objet_resultat).objet)) 375: .nombre_lignes * sizeof(struct_complexe16 *))) == NULL) 376: { 377: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire; 378: return; 379: } 380: 381: for(i = 0; i < (*((struct_matrice *) (*s_objet_resultat).objet)) 382: .nombre_lignes; i++) 383: { 384: if ((((struct_complexe16 **) (*((struct_matrice *) 385: (*s_objet_resultat).objet)).tableau)[i] = 386: malloc((*((struct_matrice *) 387: (*s_objet_resultat).objet)).nombre_colonnes * 388: sizeof(struct_complexe16))) == NULL) 389: { 390: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire; 391: return; 392: } 393: } 394: 395: for(k = 0, j = 0; j < (*((struct_matrice *) (*s_objet_resultat).objet)) 396: .nombre_lignes; j++) 397: { 398: for(i = 0; i < (*((struct_matrice *) (*s_objet_resultat).objet)) 399: .nombre_colonnes; i++) 400: { 401: ((struct_complexe16 **) (*((struct_matrice *) 402: (*s_objet_resultat).objet)).tableau)[j][i] 403: .partie_reelle = matrice_f77[k].partie_reelle; 404: ((struct_complexe16 **) (*((struct_matrice *) 405: (*s_objet_resultat).objet)).tableau)[j][i] 406: .partie_imaginaire = matrice_f77[k++].partie_imaginaire; 407: } 408: } 409: 410: free(matrice_f77); 411: } 412: 413: /* 414: -------------------------------------------------------------------------------- 415: Calcul de DFT impossible 416: -------------------------------------------------------------------------------- 417: */ 418: 419: else 420: { 421: liberation(s_etat_processus, s_objet_argument); 422: 423: (*s_etat_processus).erreur_execution = d_ex_erreur_type_argument; 424: return; 425: } 426: 427: liberation(s_etat_processus, s_objet_argument); 428: 429: if (empilement(s_etat_processus, &((*s_etat_processus).l_base_pile), 430: s_objet_resultat) == d_erreur) 431: { 432: return; 433: } 434: 435: return; 436: } 437: 438: 439: /* 440: ================================================================================ 441: Fonction 'DER' 442: ================================================================================ 443: Entrées : structure processus 444: -------------------------------------------------------------------------------- 445: Sorties : 446: -------------------------------------------------------------------------------- 447: Effets de bord : néant 448: ================================================================================ 449: */ 450: 451: void 452: instruction_der(struct_processus *s_etat_processus) 453: { 454: logical1 expression_rpn; 455: logical1 last_valide; 456: 457: struct_liste_chainee *l_element_courant; 458: struct_liste_chainee *l_element_precedent; 459: 460: struct_objet *s_copie_argument_2; 461: struct_objet *s_objet_argument_1; 462: struct_objet *s_objet_argument_2; 463: struct_objet *s_objet_resultat; 464: struct_objet *s_objet_simplifie; 465: 466: (*s_etat_processus).erreur_execution = d_ex; 467: 468: if ((*s_etat_processus).affichage_arguments == 'Y') 469: { 470: printf("\n DER "); 471: 472: if ((*s_etat_processus).langue == 'F') 473: { 474: printf("(dérivation)\n\n"); 475: } 476: else 477: { 478: printf("(derivation)\n\n"); 479: } 480: 481: printf(" 2: %s, %s, %s, %s\n", d_INT, d_REL, d_CPL, d_NOM); 482: printf(" 1: %s\n", d_NOM); 483: printf("-> 1: %s\n\n", d_INT); 484: 485: printf(" 2: %s, %s\n", d_RPN, d_ALG); 486: printf(" 1: %s\n", d_NOM); 487: printf("-> 1: %s, %s\n", d_RPN, d_ALG); 488: 489: return; 490: } 491: else if ((*s_etat_processus).test_instruction == 'Y') 492: { 493: (*s_etat_processus).nombre_arguments = 2; 494: return; 495: } 496: 497: if ((last_valide = test_cfsf(s_etat_processus, 31)) == d_vrai) 498: { 499: if (empilement_pile_last(s_etat_processus, 2) == d_erreur) 500: { 501: return; 502: } 503: } 504: 505: if (depilement(s_etat_processus, &((*s_etat_processus).l_base_pile), 506: &s_objet_argument_1) == d_erreur) 507: { 508: (*s_etat_processus).erreur_execution = d_ex_manque_argument; 509: return; 510: } 511: 512: if (depilement(s_etat_processus, &((*s_etat_processus).l_base_pile), 513: &s_objet_argument_2) == d_erreur) 514: { 515: liberation(s_etat_processus, s_objet_argument_1); 516: 517: (*s_etat_processus).erreur_execution = d_ex_manque_argument; 518: return; 519: } 520: 521: expression_rpn = d_faux; 522: 523: /* 524: * Dérivation d'une expression 525: */ 526: 527: if (((*s_objet_argument_1).type == NOM) && 528: (((*s_objet_argument_2).type == RPN) || 529: ((*s_objet_argument_2).type == ALG))) 530: { 531: if ((s_copie_argument_2 = copie_objet(s_etat_processus, 532: s_objet_argument_2, 'N')) == NULL) 533: { 534: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire; 535: return; 536: } 537: 538: if ((*s_copie_argument_2).type == RPN) 539: { 540: expression_rpn = d_vrai; 541: } 542: 543: l_element_courant = (struct_liste_chainee *) 544: (*s_copie_argument_2).objet; 545: l_element_precedent = l_element_courant; 546: 547: while((*l_element_courant).suivant != NULL) 548: { 549: l_element_precedent = l_element_courant; 550: l_element_courant = (*l_element_courant).suivant; 551: } 552: 553: if (((*l_element_precedent).suivant = 554: allocation_maillon(s_etat_processus)) == NULL) 555: { 556: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire; 557: return; 558: } 559: 560: (*(*l_element_precedent).suivant).donnee = s_objet_argument_1; 561: l_element_precedent = (*l_element_precedent).suivant; 562: 563: if (((*l_element_precedent).suivant = 564: allocation_maillon(s_etat_processus)) == NULL) 565: { 566: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire; 567: return; 568: } 569: 570: if (((*(*l_element_precedent).suivant).donnee = 571: allocation(s_etat_processus, FCT)) == NULL) 572: { 573: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire; 574: return; 575: } 576: 577: (*((struct_fonction *) (*(*(*l_element_precedent).suivant) 578: .donnee).objet)).nombre_arguments = 2; 579: (*((struct_fonction *) (*(*(*l_element_precedent).suivant) 580: .donnee).objet)).fonction = instruction_der; 581: 582: if (((*((struct_fonction *) (*(*(*l_element_precedent) 583: .suivant).donnee).objet)).nom_fonction = 584: malloc(4 * sizeof(unsigned char))) == NULL) 585: { 586: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire; 587: return; 588: } 589: 590: strcpy((*((struct_fonction *) (*(*(*l_element_precedent) 591: .suivant).donnee).objet)).nom_fonction, "DER"); 592: 593: (*(*l_element_precedent).suivant).suivant = l_element_courant; 594: 595: s_objet_resultat = s_copie_argument_2; 596: s_objet_argument_1 = NULL; 597: } 598: 599: /* 600: * Dérivation d'un nom ou d'une constante 601: */ 602: 603: else if (((*s_objet_argument_1).type == NOM) && 604: (((*s_objet_argument_2).type == NOM) || 605: ((*s_objet_argument_2).type == INT) || 606: ((*s_objet_argument_2).type == REL) || 607: ((*s_objet_argument_2).type == CPL))) 608: { 609: if ((s_objet_resultat = allocation(s_etat_processus, ALG)) == NULL) 610: { 611: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire; 612: return; 613: } 614: 615: if (((*s_objet_resultat).objet = 616: allocation_maillon(s_etat_processus)) == NULL) 617: { 618: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire; 619: return; 620: } 621: 622: l_element_courant = (*s_objet_resultat).objet; 623: 624: if (((*l_element_courant).donnee = allocation(s_etat_processus, FCT)) 625: == NULL) 626: { 627: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire; 628: return; 629: } 630: 631: (*((struct_fonction *) (*(*l_element_courant).donnee).objet)) 632: .nombre_arguments = 0; 633: (*((struct_fonction *) (*(*l_element_courant).donnee).objet)) 634: .fonction = instruction_vers_niveau_superieur; 635: 636: if (((*((struct_fonction *) (*(*l_element_courant).donnee).objet)) 637: .nom_fonction = malloc(3 * sizeof(unsigned char))) == NULL) 638: { 639: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire; 640: return; 641: } 642: 643: strcpy((*((struct_fonction *) (*(*l_element_courant).donnee).objet)) 644: .nom_fonction, "<<"); 645: 646: if (((*l_element_courant).suivant = 647: allocation_maillon(s_etat_processus)) == NULL) 648: { 649: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire; 650: return; 651: } 652: 653: l_element_courant = (*l_element_courant).suivant; 654: (*l_element_courant).donnee = s_objet_argument_2; 655: 656: if (((*l_element_courant).suivant = 657: allocation_maillon(s_etat_processus)) == NULL) 658: { 659: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire; 660: return; 661: } 662: 663: l_element_courant = (*l_element_courant).suivant; 664: (*l_element_courant).donnee = s_objet_argument_1; 665: 666: if (((*l_element_courant).suivant = 667: allocation_maillon(s_etat_processus)) == NULL) 668: { 669: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire; 670: return; 671: } 672: 673: l_element_courant = (*l_element_courant).suivant; 674: 675: if (((*l_element_courant).donnee = allocation(s_etat_processus, FCT)) 676: == NULL) 677: { 678: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire; 679: return; 680: } 681: 682: (*((struct_fonction *) (*(*l_element_courant).donnee).objet)) 683: .nombre_arguments = 2; 684: (*((struct_fonction *) (*(*l_element_courant).donnee).objet)) 685: .fonction = instruction_der; 686: 687: if (((*((struct_fonction *) (*(*l_element_courant).donnee).objet)) 688: .nom_fonction = malloc(4 * sizeof(unsigned char))) == NULL) 689: { 690: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire; 691: return; 692: } 693: 694: strcpy((*((struct_fonction *) (*(*l_element_courant).donnee).objet)) 695: .nom_fonction, "DER"); 696: 697: if (((*l_element_courant).suivant = 698: allocation_maillon(s_etat_processus)) == NULL) 699: { 700: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire; 701: return; 702: } 703: 704: l_element_courant = (*l_element_courant).suivant; 705: 706: if (((*l_element_courant).donnee = allocation(s_etat_processus, FCT)) 707: == NULL) 708: { 709: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire; 710: return; 711: } 712: 713: (*((struct_fonction *) (*(*l_element_courant).donnee).objet)) 714: .nombre_arguments = 0; 715: (*((struct_fonction *) (*(*l_element_courant).donnee).objet)) 716: .fonction = instruction_vers_niveau_inferieur; 717: 718: if (((*((struct_fonction *) (*(*l_element_courant).donnee).objet)) 719: .nom_fonction = malloc(3 * sizeof(unsigned char))) == NULL) 720: { 721: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire; 722: return; 723: } 724: 725: strcpy((*((struct_fonction *) (*(*l_element_courant).donnee).objet)) 726: .nom_fonction, ">>"); 727: 728: (*l_element_courant).suivant = NULL; 729: 730: s_objet_argument_1 = NULL; 731: s_objet_argument_2 = NULL; 732: } 733: 734: /* 735: * Dérivation impossible 736: */ 737: 738: else 739: { 740: liberation(s_etat_processus, s_objet_argument_1); 741: liberation(s_etat_processus, s_objet_argument_2); 742: 743: (*s_etat_processus).erreur_execution = d_ex_erreur_type_argument; 744: return; 745: } 746: 747: liberation(s_etat_processus, s_objet_argument_1); 748: liberation(s_etat_processus, s_objet_argument_2); 749: 750: if (expression_rpn == d_faux) 751: { 752: if (last_valide == d_vrai) 753: { 754: cf(s_etat_processus, 31); 755: } 756: 757: derivation(s_etat_processus, &s_objet_resultat); 758: 759: if (last_valide == d_vrai) 760: { 761: sf(s_etat_processus, 31); 762: } 763: 764: if (((*s_etat_processus).var_volatile_requete_arret == 0) && 765: (s_objet_resultat != NULL)) 766: { 767: if ((s_objet_simplifie = simplification(s_etat_processus, 768: s_objet_resultat)) == NULL) 769: { 770: return; 771: } 772: 773: liberation(s_etat_processus, s_objet_resultat); 774: 775: if (empilement(s_etat_processus, &((*s_etat_processus).l_base_pile), 776: s_objet_simplifie) == d_erreur) 777: { 778: return; 779: } 780: } 781: else 782: { 783: if (s_objet_resultat != NULL) 784: { 785: liberation(s_etat_processus, s_objet_resultat); 786: } 787: } 788: } 789: else 790: { 791: if (empilement(s_etat_processus, &((*s_etat_processus).l_base_pile), 792: s_objet_resultat) == d_erreur) 793: { 794: return; 795: } 796: } 797: 798: return; 799: } 800: 801: 802: /* 803: ================================================================================ 804: Fonction 'DETACH' 805: ================================================================================ 806: Entrées : structure processus 807: -------------------------------------------------------------------------------- 808: Sorties : 809: -------------------------------------------------------------------------------- 810: Effets de bord : néant 811: ================================================================================ 812: */ 813: 814: void 815: instruction_detach(struct_processus *s_etat_processus) 816: { 817: logical1 drapeau; 818: logical1 variable_partagee; 819: 820: pid_t ppid; 821: pid_t pid_final; 822: 823: pthread_attr_t attributs; 824: 825: pthread_mutexattr_t attributs_mutex; 826: 827: pthread_t thread_surveillance; 828: 829: sig_atomic_t registre_stop; 830: 831: sigset_t oldset; 832: sigset_t oldset2; 833: sigset_t set; 834: sigset_t set2; 835: 836: ssize_t longueur_ecriture; 837: 838: struct_descripteur_thread *s_argument_thread; 839: struct_descripteur_thread *s_argument_thread2; 840: 841: struct_liste_chainee *l_element_courant; 842: struct_liste_chainee *l_element_precedent; 843: struct_liste_chainee *l_element_suivant; 844: 845: struct_objet *s_copie; 846: struct_objet *s_objet; 847: struct_objet *s_objet_systeme; 848: struct_objet *s_objet_temporaire; 849: 850: struct sigaction action; 851: struct sigaction registre; 852: 853: struct timespec attente; 854: 855: unsigned char *message; 856: 857: unsigned int erreur; 858: 859: unsigned long i; 860: 861: (*s_etat_processus).erreur_execution = d_ex; 862: 863: attente.tv_sec = 0; 864: attente.tv_nsec = GRANULARITE_us * 1000; 865: s_copie = NULL; 866: 867: if ((*s_etat_processus).affichage_arguments == 'Y') 868: { 869: printf("\n DETACH "); 870: 871: if ((*s_etat_processus).langue == 'F') 872: { 873: printf("(détachement d'un processus)\n\n"); 874: } 875: else 876: { 877: printf("(fork)\n\n"); 878: } 879: 880: printf(" 1: %s, %s\n", d_NOM, d_RPN); 881: printf("-> 1: %s\n", d_PRC); 882: 883: return; 884: } 885: else if ((*s_etat_processus).test_instruction == 'Y') 886: { 887: (*s_etat_processus).nombre_arguments = -1; 888: return; 889: } 890: 891: if (test_cfsf(s_etat_processus, 31) == d_vrai) 892: { 893: if (empilement_pile_last(s_etat_processus, 1) == d_erreur) 894: { 895: return; 896: } 897: } 898: 899: if (depilement(s_etat_processus, &((*s_etat_processus).l_base_pile), 900: &s_objet) == d_erreur) 901: { 902: (*s_etat_processus).erreur_execution = d_ex_manque_argument; 903: return; 904: } 905: 906: /* 907: * Une routine fille doit pouvoir renvoyer des objets au processus 908: * père au travers de la fonction SEND. Il ne peut donc s'agir que 909: * d'une fonction ou d'une expression RPN. 910: */ 911: 912: if (((*s_objet).type != NOM) && ((*s_objet).type != RPN)) 913: { 914: liberation(s_etat_processus, s_objet); 915: 916: (*s_etat_processus).erreur_execution = d_ex_erreur_type_argument; 917: return; 918: } 919: 920: /* 921: * Si l'argument est de type NOM, il faut que la variable correspondante 922: * soit une variable de type RPN. 923: */ 924: 925: variable_partagee = d_faux; 926: 927: if ((*s_objet).type == NOM) 928: { 929: if (recherche_variable(s_etat_processus, (*((struct_nom *) 930: (*s_objet).objet)).nom) == d_vrai) 931: { 932: if ((*(*s_etat_processus).pointeur_variable_courante).objet 933: == NULL) 934: { 935: if (pthread_mutex_lock(&((*(*s_etat_processus) 936: .s_liste_variables_partagees).mutex)) != 0) 937: { 938: (*s_etat_processus).erreur_systeme = d_es_processus; 939: return; 940: } 941: 942: if (recherche_variable_partagee(s_etat_processus, 943: (*(*s_etat_processus).pointeur_variable_courante).nom, 944: (*(*s_etat_processus).pointeur_variable_courante) 945: .variable_partagee, (*(*s_etat_processus) 946: .pointeur_variable_courante).origine) == d_faux) 947: { 948: if (pthread_mutex_unlock(&((*(*s_etat_processus) 949: .s_liste_variables_partagees).mutex)) != 0) 950: { 951: (*s_etat_processus).erreur_systeme = d_es_processus; 952: return; 953: } 954: 955: liberation(s_etat_processus, s_objet); 956: 957: (*s_etat_processus).erreur_systeme = d_es; 958: (*s_etat_processus).erreur_execution = 959: d_ex_argument_invalide; 960: return; 961: } 962: 963: if (((*(*(*s_etat_processus).s_liste_variables_partagees) 964: .table[(*(*s_etat_processus) 965: .s_liste_variables_partagees).position_variable].objet) 966: .type != RPN) && ((*(*(*s_etat_processus) 967: .s_liste_variables_partagees).table 968: [(*(*s_etat_processus).s_liste_variables_partagees) 969: .position_variable].objet).type != ADR)) 970: { 971: if (pthread_mutex_unlock(&((*(*s_etat_processus) 972: .s_liste_variables_partagees).mutex)) != 0) 973: { 974: (*s_etat_processus).erreur_systeme = d_es_processus; 975: return; 976: } 977: 978: liberation(s_etat_processus, s_objet); 979: 980: (*s_etat_processus).erreur_execution = 981: d_ex_argument_invalide; 982: return; 983: } 984: 985: if ((s_copie = copie_objet(s_etat_processus, 986: (*(*s_etat_processus).s_liste_variables_partagees).table 987: [(*(*s_etat_processus).s_liste_variables_partagees) 988: .position_variable].objet, 'P')) == NULL) 989: { 990: if (pthread_mutex_unlock(&((*(*s_etat_processus) 991: .s_liste_variables_partagees).mutex)) != 0) 992: { 993: (*s_etat_processus).erreur_systeme = d_es_processus; 994: return; 995: } 996: 997: (*s_etat_processus).erreur_systeme = 998: d_es_allocation_memoire; 999: 1000: return; 1001: } 1002: 1003: variable_partagee = d_vrai; 1004: 1005: if (pthread_mutex_unlock(&((*(*s_etat_processus) 1006: .s_liste_variables_partagees).mutex)) != 0) 1007: { 1008: (*s_etat_processus).erreur_systeme = d_es_processus; 1009: return; 1010: } 1011: } 1012: else 1013: { 1014: if (((*(*(*s_etat_processus).pointeur_variable_courante).objet) 1015: .type != RPN) && ((*(*(*s_etat_processus) 1016: .pointeur_variable_courante).objet).type != ADR)) 1017: { 1018: liberation(s_etat_processus, s_objet); 1019: 1020: (*s_etat_processus).erreur_execution = 1021: d_ex_argument_invalide; 1022: return; 1023: } 1024: } 1025: } 1026: else // Variable inexistante 1027: { 1028: liberation(s_etat_processus, s_objet); 1029: 1030: (*s_etat_processus).erreur_systeme = d_es; 1031: (*s_etat_processus).erreur_execution = d_ex_argument_invalide; 1032: return; 1033: } 1034: } 1035: 1036: if (sigemptyset(&set) != 0) 1037: { 1038: (*s_etat_processus).erreur_systeme = d_es_processus; 1039: return; 1040: } 1041: 1042: if (sigaddset(&set, SIGSTART) != 0) 1043: { 1044: (*s_etat_processus).erreur_systeme = d_es_processus; 1045: return; 1046: } 1047: 1048: /* 1049: * Le signal SIGFSTOP doit être traité ! 1050: */ 1051: 1052: if (sigaddset(&set, SIGFSTOP) != 0) 1053: { 1054: (*s_etat_processus).erreur_systeme = d_es_processus; 1055: return; 1056: } 1057: 1058: if (sigaddset(&set, SIGFABORT) != 0) 1059: { 1060: (*s_etat_processus).erreur_systeme = d_es_processus; 1061: return; 1062: } 1063: 1064: if (sigaddset(&set, SIGURG) != 0) 1065: { 1066: (*s_etat_processus).erreur_systeme = d_es_processus; 1067: return; 1068: } 1069: 1070: if (pthread_sigmask(SIG_BLOCK, &set, &oldset) != 0) 1071: { 1072: (*s_etat_processus).erreur_systeme = d_es_processus; 1073: return; 1074: } 1075: 1076: if ((s_argument_thread = malloc(sizeof(struct_descripteur_thread))) == NULL) 1077: { 1078: (*s_etat_processus).erreur_systeme = d_es_processus; 1079: return; 1080: } 1081: 1082: if (pipe((*s_argument_thread).pipe_erreurs) != 0) 1083: { 1084: (*s_etat_processus).erreur_systeme = d_es_processus; 1085: return; 1086: } 1087: 1088: if (pipe((*s_argument_thread).pipe_interruptions) != 0) 1089: { 1090: (*s_etat_processus).erreur_systeme = d_es_processus; 1091: return; 1092: } 1093: 1094: if (pipe((*s_argument_thread).pipe_nombre_interruptions_attente) != 0) 1095: { 1096: (*s_etat_processus).erreur_systeme = d_es_processus; 1097: return; 1098: } 1099: 1100: if (pipe((*s_argument_thread).pipe_objets) != 0) 1101: { 1102: (*s_etat_processus).erreur_systeme = d_es_processus; 1103: return; 1104: } 1105: 1106: if (pipe((*s_argument_thread).pipe_acquittement) != 0) 1107: { 1108: (*s_etat_processus).erreur_systeme = d_es_processus; 1109: return; 1110: } 1111: 1112: if (pipe((*s_argument_thread).pipe_nombre_objets_attente) != 0) 1113: { 1114: (*s_etat_processus).erreur_systeme = d_es_processus; 1115: return; 1116: } 1117: 1118: if (pipe((*s_argument_thread).pipe_injections) != 0) 1119: { 1120: (*s_etat_processus).erreur_systeme = d_es_processus; 1121: return; 1122: } 1123: 1124: if (pipe((*s_argument_thread).pipe_nombre_injections) != 0) 1125: { 1126: (*s_etat_processus).erreur_systeme = d_es_processus; 1127: return; 1128: } 1129: 1130: ppid = getpid(); 1131: 1132: /* 1133: * Le mutex suivant permet de copier un contexte propre. 1134: */ 1135: 1136: if (pthread_mutex_lock(&((*s_etat_processus).mutex)) != 0) 1137: { 1138: (*s_etat_processus).erreur_systeme = d_es_processus; 1139: return; 1140: } 1141: 1142: fflush(NULL); 1143: 1144: /* 1145: * On bloque tous les threads concurents pour qu'il n'y ait ni allocation 1146: * de mémoire, ni libération, ni copie d'objet concurrent au fork(). 1147: */ 1148: 1149: sigfillset(&set2); 1150: pthread_sigmask(SIG_BLOCK, &set2, &oldset2); 1151: 1152: verrouillage_threads_concurrents(s_etat_processus); 1153: (*s_argument_thread).pid = fork(); 1154: deverrouillage_threads_concurrents(s_etat_processus); 1155: 1156: pthread_sigmask(SIG_SETMASK, &oldset2, NULL); 1157: sigpending(&set2); 1158: 1159: (*s_argument_thread).thread_pere = pthread_self(); 1160: (*s_argument_thread).processus_detache = d_vrai; 1161: 1162: pthread_mutexattr_init(&attributs_mutex); 1163: pthread_mutexattr_settype(&attributs_mutex, PTHREAD_MUTEX_RECURSIVE); 1164: pthread_mutex_init(&((*s_argument_thread).mutex), &attributs_mutex); 1165: pthread_mutexattr_destroy(&attributs_mutex); 1166: 1167: pthread_mutexattr_init(&attributs_mutex); 1168: pthread_mutexattr_settype(&attributs_mutex, PTHREAD_MUTEX_RECURSIVE); 1169: pthread_mutex_init(&((*s_argument_thread).mutex_nombre_references), 1170: &attributs_mutex); 1171: pthread_mutexattr_destroy(&attributs_mutex); 1172: 1173: if ((*s_argument_thread).pid > 0) 1174: { 1175: /* 1176: * Processus père 1177: */ 1178: 1179: if (variable_partagee == d_vrai) 1180: { 1181: liberation(s_etat_processus, s_copie); 1182: } 1183: 1184: liberation(s_etat_processus, s_objet); 1185: 1186: if ((s_objet = allocation(s_etat_processus, PRC)) == NULL) 1187: { 1188: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire; 1189: return; 1190: } 1191: 1192: (*((struct_processus_fils *) (*s_objet).objet)).thread = 1193: s_argument_thread; 1194: (*(*((struct_processus_fils *) (*s_objet).objet)).thread) 1195: .nombre_objets_dans_pipe = 0; 1196: (*(*((struct_processus_fils *) (*s_objet).objet)).thread) 1197: .nombre_interruptions_dans_pipe = 0; 1198: (*(*((struct_processus_fils *) (*s_objet).objet)).thread) 1199: .nombre_references = 1; 1200: 1201: /* 1202: * On copie l'objet plutôt que le pointeur car cet objet peut être 1203: * accédé depuis deux threads distincts et aboutir à un blocage lors 1204: * d'une copie. 1205: */ 1206: 1207: if ((s_objet_systeme = copie_objet(s_etat_processus, s_objet, 'O')) 1208: == NULL) 1209: { 1210: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire; 1211: return; 1212: } 1213: 1214: if (close((*s_argument_thread).pipe_erreurs[1]) != 0) 1215: { 1216: (*s_etat_processus).erreur_systeme = d_es_processus; 1217: return; 1218: } 1219: 1220: if (close((*s_argument_thread).pipe_interruptions[1]) != 0) 1221: { 1222: (*s_etat_processus).erreur_systeme = d_es_processus; 1223: return; 1224: } 1225: 1226: if (close((*s_argument_thread).pipe_nombre_interruptions_attente[1]) 1227: != 0) 1228: { 1229: (*s_etat_processus).erreur_systeme = d_es_processus; 1230: return; 1231: } 1232: 1233: if (close((*s_argument_thread).pipe_objets[1]) != 0) 1234: { 1235: (*s_etat_processus).erreur_systeme = d_es_processus; 1236: return; 1237: } 1238: 1239: if (close((*s_argument_thread).pipe_nombre_objets_attente[1]) != 0) 1240: { 1241: (*s_etat_processus).erreur_systeme = d_es_processus; 1242: return; 1243: } 1244: 1245: if (close((*s_argument_thread).pipe_injections[0]) != 0) 1246: { 1247: (*s_etat_processus).erreur_systeme = d_es_processus; 1248: return; 1249: } 1250: 1251: if (close((*s_argument_thread).pipe_nombre_injections[0]) != 0) 1252: { 1253: (*s_etat_processus).erreur_systeme = d_es_processus; 1254: return; 1255: } 1256: 1257: if (close((*s_argument_thread).pipe_acquittement[0]) != 0) 1258: { 1259: (*s_etat_processus).erreur_systeme = d_es_processus; 1260: return; 1261: } 1262: 1263: if (pthread_attr_init(&attributs) != 0) 1264: { 1265: (*s_etat_processus).erreur_systeme = d_es_processus; 1266: return; 1267: } 1268: 1269: if (pthread_attr_setdetachstate(&attributs, 1270: PTHREAD_CREATE_DETACHED) != 0) 1271: { 1272: (*s_etat_processus).erreur_systeme = d_es_processus; 1273: return; 1274: } 1275: 1276: # ifndef OS2 1277: # ifndef Cygwin 1278: if (pthread_attr_setschedpolicy(&attributs, SCHED_OTHER) != 0) 1279: { 1280: (*s_etat_processus).erreur_systeme = d_es_processus; 1281: return; 1282: } 1283: 1284: if (pthread_attr_setinheritsched(&attributs, 1285: PTHREAD_EXPLICIT_SCHED) != 0) 1286: { 1287: (*s_etat_processus).erreur_systeme = d_es_processus; 1288: return; 1289: } 1290: 1291: if (pthread_attr_setscope(&attributs, PTHREAD_SCOPE_SYSTEM) != 0) 1292: { 1293: (*s_etat_processus).erreur_systeme = d_es_processus; 1294: return; 1295: } 1296: # endif 1297: # endif 1298: 1299: (*s_argument_thread).s_etat_processus = s_etat_processus; 1300: 1301: if (pthread_create(&thread_surveillance, &attributs, 1302: surveillance_processus, s_argument_thread) != 0) 1303: { 1304: (*s_etat_processus).erreur_systeme = d_es_processus; 1305: return; 1306: } 1307: 1308: if (pthread_attr_destroy(&attributs) != 0) 1309: { 1310: (*s_etat_processus).erreur_systeme = d_es_processus; 1311: return; 1312: } 1313: } 1314: else if ((*s_argument_thread).pid == 0) 1315: { 1316: /* 1317: * Processus fils 1318: */ 1319: 1320: # ifdef _BROKEN_SIGINFO 1321: liberation_fifos_signaux(s_etat_processus); 1322: creation_fifos_signaux(s_etat_processus); 1323: # endif 1324: 1325: if ((*s_etat_processus).debug == d_vrai) 1326: if (((*s_etat_processus).type_debug & 1327: d_debug_processus) != 0) 1328: { 1329: if ((*s_etat_processus).langue == 'F') 1330: { 1331: printf("[%d] Lancement du processus fils %d de %d\n", 1332: (int) getpid(), (int) getpid(), (int) ppid); 1333: } 1334: else 1335: { 1336: printf("[%d] Start child process %d from %d\n", (int) getpid(), 1337: (int) getpid(), (int) ppid); 1338: } 1339: 1340: fflush(stdout); 1341: } 1342: 1343: # ifndef SEMAPHORES_NOMMES 1344: sem_post(&semaphore_gestionnaires_signaux); 1345: sem_destroy(&semaphore_gestionnaires_signaux); 1346: sem_init(&semaphore_gestionnaires_signaux, 0, 0); 1347: # else 1348: sem_post(semaphore_gestionnaires_signaux); 1349: sem_destroy2(semaphore_gestionnaires_signaux, 1350: sem_gestionnaires_signaux); 1351: 1352: if ((semaphore_gestionnaires_signaux = sem_init2(0, 1353: sem_gestionnaires_signaux)) == SEM_FAILED) 1354: { 1355: (*s_etat_processus).erreur_systeme = d_es_processus; 1356: } 1357: # endif 1358: 1359: # ifndef SEMAPHORES_NOMMES 1360: sem_post(&semaphore_liste_threads); 1361: sem_destroy(&semaphore_liste_threads); 1362: sem_init(&semaphore_liste_threads, 0, 1); 1363: # else 1364: sem_post(semaphore_liste_threads); 1365: sem_destroy2(semaphore_liste_threads, sem_liste_threads); 1366: 1367: if ((semaphore_liste_threads = sem_init2(1, 1368: sem_liste_threads)) == SEM_FAILED) 1369: { 1370: (*s_etat_processus).erreur_systeme = d_es_processus; 1371: } 1372: # endif 1373: 1374: # ifndef SEMAPHORES_NOMMES 1375: sem_destroy(&semaphore_gestionnaires_signaux_atomique); 1376: sem_init(&semaphore_gestionnaires_signaux_atomique, 0, 1); 1377: sem_trywait(&((*s_etat_processus).semaphore_fork)); 1378: # else 1379: sem_destroy2(semaphore_gestionnaires_signaux_atomique, 1380: sem_gestionnaires_signaux_atomique); 1381: 1382: if ((semaphore_gestionnaires_signaux_atomique = sem_init2(1, 1383: sem_gestionnaires_signaux_atomique)) == SEM_FAILED) 1384: { 1385: (*s_etat_processus).erreur_systeme = d_es_processus; 1386: } 1387: 1388: sem_trywait((*s_etat_processus).semaphore_fork); 1389: # endif 1390: 1391: # ifndef SEMAPHORES_NOMMES 1392: if (pthread_setspecific(semaphore_fork_processus_courant, 1393: &((*s_etat_processus).semaphore_fork)) != 0) 1394: # else 1395: if (pthread_setspecific(semaphore_fork_processus_courant, 1396: (*s_etat_processus).semaphore_fork) != 0) 1397: # endif 1398: { 1399: (*s_etat_processus).erreur_systeme = d_es_processus; 1400: } 1401: 1402: if (close((*s_argument_thread).pipe_erreurs[0]) != 0) 1403: { 1404: (*s_etat_processus).erreur_systeme = d_es_processus; 1405: } 1406: else if (close((*s_argument_thread).pipe_interruptions[0]) != 0) 1407: { 1408: (*s_etat_processus).erreur_systeme = d_es_processus; 1409: } 1410: else if (close((*s_argument_thread) 1411: .pipe_nombre_interruptions_attente[0]) != 0) 1412: { 1413: (*s_etat_processus).erreur_systeme = d_es_processus; 1414: } 1415: else if (close((*s_argument_thread).pipe_objets[0]) != 0) 1416: { 1417: (*s_etat_processus).erreur_systeme = d_es_processus; 1418: } 1419: else if (close((*s_argument_thread).pipe_nombre_objets_attente[0]) != 0) 1420: { 1421: (*s_etat_processus).erreur_systeme = d_es_processus; 1422: } 1423: else if (close((*s_argument_thread).pipe_injections[1]) != 0) 1424: { 1425: (*s_etat_processus).erreur_systeme = d_es_processus; 1426: } 1427: else if (close((*s_argument_thread).pipe_nombre_injections[1]) != 0) 1428: { 1429: (*s_etat_processus).erreur_systeme = d_es_processus; 1430: } 1431: else if (close((*s_argument_thread).pipe_acquittement[1]) != 0) 1432: { 1433: (*s_etat_processus).erreur_systeme = d_es_processus; 1434: } 1435: 1436: if ((*s_etat_processus).debug == d_vrai) 1437: if (((*s_etat_processus).type_debug & 1438: d_debug_processus) != 0) 1439: { 1440: if ((*s_etat_processus).langue == 'F') 1441: { 1442: printf("[%d] Libération des objets du processus père\n", 1443: (int) getpid()); 1444: } 1445: else 1446: { 1447: printf("[%d] Freeing parent process memory\n", getpid()); 1448: } 1449: 1450: fflush(stdout); 1451: } 1452: 1453: l_element_courant = (*s_etat_processus).liste_mutexes; 1454: while(l_element_courant != NULL) 1455: { 1456: pthread_mutex_trylock(&((*((struct_mutex *) (*(*l_element_courant) 1457: .donnee).objet)).mutex)); 1458: pthread_mutex_unlock(&((*((struct_mutex *) (*(*l_element_courant) 1459: .donnee).objet)).mutex)); 1460: pthread_mutex_destroy(&((*((struct_mutex *) (*(*l_element_courant) 1461: .donnee).objet)).mutex)); 1462: 1463: liberation(s_etat_processus, (*l_element_courant).donnee); 1464: l_element_suivant = (*l_element_courant).suivant; 1465: free(l_element_courant); 1466: l_element_courant = l_element_suivant; 1467: } 1468: 1469: (*s_etat_processus).liste_mutexes = NULL; 1470: 1471: liberation_threads(s_etat_processus); 1472: 1473: (*(*s_etat_processus).s_liste_variables_partagees) 1474: .table = NULL; 1475: (*(*s_etat_processus).s_liste_variables_partagees) 1476: .nombre_variables = 0; 1477: (*(*s_etat_processus).s_liste_variables_partagees) 1478: .nombre_variables_allouees = 0; 1479: 1480: insertion_thread(s_etat_processus, d_vrai); 1481: 1482: // Envoi d'une donnée pour signaler le démarrage du processus au thread 1483: // de surveillance. 1484: 1485: if (write_atomic(s_etat_processus, 1486: (*s_argument_thread).pipe_nombre_objets_attente[1], 1487: "-", sizeof(unsigned char)) != sizeof(unsigned char)) 1488: { 1489: pthread_mutex_unlock(&((*s_etat_processus).mutex)); 1490: (*s_etat_processus).erreur_systeme = d_es_processus; 1491: 1492: pid_final = -2; 1493: 1494: while((longueur_ecriture = write_atomic(s_etat_processus, 1495: (*s_argument_thread).pipe_nombre_interruptions_attente[1], 1496: &pid_final, sizeof(pid_final))) != sizeof(pid_final)) 1497: { 1498: if (longueur_ecriture == -1) 1499: { 1500: break; 1501: } 1502: } 1503: 1504: while((longueur_ecriture = write_atomic(s_etat_processus, 1505: (*s_argument_thread).pipe_nombre_objets_attente[1], 1506: &pid_final, sizeof(pid_final))) != sizeof(pid_final)) 1507: { 1508: if (longueur_ecriture == -1) 1509: { 1510: break; 1511: } 1512: } 1513: 1514: # ifdef _BROKEN_SIGINFO 1515: destruction_fifos_signaux(s_etat_processus); 1516: # endif 1517: 1518: BUG(1, uprintf("Process management error line %d\n", __LINE__)); 1519: exit(EXIT_FAILURE); 1520: } 1521: 1522: if (pthread_mutex_unlock(&((*s_etat_processus).mutex)) != 0) 1523: { 1524: (*s_etat_processus).erreur_systeme = d_es_processus; 1525: 1526: pid_final = -2; 1527: 1528: while((longueur_ecriture = write_atomic(s_etat_processus, 1529: (*s_argument_thread).pipe_nombre_interruptions_attente[1], 1530: &pid_final, sizeof(pid_final))) != sizeof(pid_final)) 1531: { 1532: if (longueur_ecriture == -1) 1533: { 1534: break; 1535: } 1536: } 1537: 1538: while((longueur_ecriture = write_atomic(s_etat_processus, 1539: (*s_argument_thread).pipe_nombre_objets_attente[1], 1540: &pid_final, sizeof(pid_final))) != sizeof(pid_final)) 1541: { 1542: if (longueur_ecriture == -1) 1543: { 1544: break; 1545: } 1546: } 1547: 1548: # ifdef _BROKEN_SIGINFO 1549: destruction_fifos_signaux(s_etat_processus); 1550: # endif 1551: 1552: BUG(1, uprintf("Process management error line %d\n", __LINE__)); 1553: exit(EXIT_FAILURE); 1554: } 1555: 1556: pthread_mutex_trylock(&((*s_etat_processus).protection_liste_mutexes)); 1557: 1558: if (pthread_mutex_unlock(&((*s_etat_processus) 1559: .protection_liste_mutexes)) != 0) 1560: { 1561: (*s_etat_processus).erreur_systeme = d_es_processus; 1562: 1563: pid_final = -2; 1564: 1565: while((longueur_ecriture = write_atomic(s_etat_processus, 1566: (*s_argument_thread).pipe_nombre_interruptions_attente[1], 1567: &pid_final, sizeof(pid_final))) != sizeof(pid_final)) 1568: { 1569: if (longueur_ecriture == -1) 1570: { 1571: break; 1572: } 1573: } 1574: 1575: while((longueur_ecriture = write_atomic(s_etat_processus, 1576: (*s_argument_thread).pipe_nombre_objets_attente[1], 1577: &pid_final, sizeof(pid_final))) != sizeof(pid_final)) 1578: { 1579: if (longueur_ecriture == -1) 1580: { 1581: break; 1582: } 1583: } 1584: 1585: # ifdef _BROKEN_SIGINFO 1586: destruction_fifos_signaux(s_etat_processus); 1587: # endif 1588: 1589: BUG(1, uprintf("Process management error line %d\n", __LINE__)); 1590: exit(EXIT_FAILURE); 1591: } 1592: 1593: if ((*s_etat_processus).evaluation_expression_compilee == 'N') 1594: { 1595: free((*s_etat_processus).instruction_courante); 1596: (*s_etat_processus).instruction_courante = NULL; 1597: } 1598: 1599: (*s_etat_processus).var_volatile_processus_pere = 0; 1600: (*s_etat_processus).var_volatile_processus_racine = 0; 1601: 1602: // On réinitialise toutes les interruptions. 1603: 1604: (*s_etat_processus).traitement_interruption = 'N'; 1605: (*s_etat_processus).traitement_interruptible = 'Y'; 1606: (*s_etat_processus).nombre_interruptions_en_queue = 0; 1607: (*s_etat_processus).nombre_interruptions_non_affectees = 0; 1608: (*s_etat_processus).processus_detache = d_vrai; 1609: 1610: liberation(s_etat_processus, (*s_etat_processus).at_exit); 1611: (*s_etat_processus).at_exit = NULL; 1612: liberation(s_etat_processus, (*s_etat_processus).at_poke); 1613: (*s_etat_processus).at_poke = NULL; 1614: (*s_etat_processus).traitement_at_poke = 'N'; 1615: 1616: for(i = 0; i < d_NOMBRE_INTERRUPTIONS; i++) 1617: { 1618: liberation(s_etat_processus, 1619: (*s_etat_processus).corps_interruptions[i]); 1620: 1621: (*s_etat_processus).corps_interruptions[i] = NULL; 1622: (*s_etat_processus).masque_interruptions[i] = 'N'; 1623: (*s_etat_processus).queue_interruptions[i] = 0; 1624: 1625: l_element_courant = (*s_etat_processus) 1626: .pile_origine_interruptions[i]; 1627: 1628: while(l_element_courant != NULL) 1629: { 1630: l_element_suivant = (*l_element_courant).suivant; 1631: liberation(s_etat_processus, (*l_element_courant).donnee); 1632: free(l_element_courant); 1633: l_element_courant = l_element_suivant; 1634: } 1635: 1636: (*s_etat_processus).pile_origine_interruptions[i] = NULL; 1637: } 1638: 1639: /* 1640: * On bloque l'exécution du processus fils jusqu'à ce que 1641: * le père ait renseigné correctement la pile des processus. 1642: * Dans le cas contraire, on pourrait essayer de traiter 1643: * un RECV sur un système chargé avant que cette pile soit 1644: * renseignée. 1645: */ 1646: 1647: if (sigpending(&set) != 0) 1648: { 1649: (*s_etat_processus).erreur_systeme = d_es_processus; 1650: } 1651: else if (sigismember(&set, SIGSTART) == 0) 1652: { 1653: while(sigismember(&set, SIGSTART) == 0) 1654: { 1655: if (sigpending(&set) != 0) 1656: { 1657: (*s_etat_processus).erreur_systeme = d_es_processus; 1658: } 1659: 1660: nanosleep(&attente, NULL); 1661: } 1662: } 1663: 1664: (*s_etat_processus).niveau_initial = (*s_etat_processus).niveau_courant; 1665: (*s_etat_processus).presence_pipes = d_vrai; 1666: (*s_etat_processus).debug_programme = d_faux; 1667: (*s_etat_processus).pipe_donnees = (*s_argument_thread).pipe_objets[1]; 1668: (*s_etat_processus).pipe_nombre_objets_attente = (*s_argument_thread) 1669: .pipe_nombre_objets_attente[1]; 1670: (*s_etat_processus).pipe_interruptions = (*s_argument_thread) 1671: .pipe_interruptions[1]; 1672: (*s_etat_processus).pipe_nombre_interruptions_attente = 1673: (*s_argument_thread).pipe_nombre_interruptions_attente[1]; 1674: (*s_etat_processus).pipe_injections = 1675: (*s_argument_thread).pipe_injections[0]; 1676: (*s_etat_processus).pipe_nombre_injections = 1677: (*s_argument_thread).pipe_nombre_injections[0]; 1678: (*s_etat_processus).pipe_acquittement = 1679: (*s_argument_thread).pipe_acquittement[0]; 1680: (*s_etat_processus).nombre_objets_injectes = 0; 1681: (*s_etat_processus).nombre_objets_envoyes_non_lus = 0; 1682: (*s_etat_processus).temps_maximal_cpu = 0; 1683: (*s_etat_processus).presence_fusible = d_faux; 1684: (*s_etat_processus).thread_fusible = 0; 1685: (*s_etat_processus).pid_erreur_processus_fils = getpid(); 1686: 1687: if ((*s_etat_processus).profilage == d_vrai) 1688: { 1689: liberation_profil(s_etat_processus); 1690: } 1691: 1692: (*s_etat_processus).pile_profilage = NULL; 1693: 1694: if ((*s_etat_processus).generateur_aleatoire != NULL) 1695: { 1696: liberation_generateur_aleatoire(s_etat_processus); 1697: } 1698: 1699: (*s_etat_processus).generateur_aleatoire = NULL; 1700: 1701: if ((*s_etat_processus).instruction_derniere_erreur != NULL) 1702: { 1703: free((*s_etat_processus).instruction_derniere_erreur); 1704: (*s_etat_processus).instruction_derniere_erreur = NULL; 1705: } 1706: 1707: /* 1708: * Initialisation de la pile des processus. Cette pile est effacée 1709: * par liberation_threads(). 1710: */ 1711: 1712: if (pthread_mutex_lock(&((*s_etat_processus).mutex)) != 0) 1713: { 1714: (*s_etat_processus).erreur_systeme = d_es; 1715: 1716: pid_final = -2; 1717: 1718: while((longueur_ecriture = write_atomic(s_etat_processus, 1719: (*s_argument_thread).pipe_nombre_interruptions_attente[1], 1720: &pid_final, sizeof(pid_final))) != sizeof(pid_final)) 1721: { 1722: if (longueur_ecriture == -1) 1723: { 1724: break; 1725: } 1726: } 1727: 1728: while((longueur_ecriture = write_atomic(s_etat_processus, 1729: (*s_argument_thread).pipe_nombre_objets_attente[1], 1730: &pid_final, sizeof(pid_final))) != sizeof(pid_final)) 1731: { 1732: if (longueur_ecriture == -1) 1733: { 1734: break; 1735: } 1736: } 1737: 1738: # ifdef _BROKEN_SIGINFO 1739: destruction_fifos_signaux(s_etat_processus); 1740: # endif 1741: 1742: BUG(1, uprintf("Process management error line %d\n", __LINE__)); 1743: exit(EXIT_FAILURE); 1744: } 1745: 1746: l_element_courant = (struct_liste_chainee *) 1747: (*s_etat_processus).l_base_pile_processus; 1748: 1749: while(l_element_courant != NULL) 1750: { 1751: s_argument_thread2 = (struct_descripteur_thread *) 1752: (*((struct_processus_fils *) (*(*l_element_courant).donnee) 1753: .objet)).thread; 1754: 1755: (*s_argument_thread2).nombre_references--; 1756: 1757: BUG((*s_argument_thread2).nombre_references < 0, 1758: # ifdef _BROKEN_SIGINFO 1759: destruction_fifos_signaux(s_etat_processus), 1760: # endif 1761: printf("(*s_argument_thread2).nombre_references = %d\n", 1762: (int) (*s_argument_thread2).nombre_references)); 1763: 1764: if ((*s_argument_thread2).nombre_references == 0) 1765: { 1766: close((*s_argument_thread2).pipe_objets[0]); 1767: close((*s_argument_thread2).pipe_acquittement[1]); 1768: close((*s_argument_thread2).pipe_injections[1]); 1769: close((*s_argument_thread2).pipe_nombre_injections[1]); 1770: close((*s_argument_thread2).pipe_nombre_objets_attente[0]); 1771: close((*s_argument_thread2).pipe_interruptions[0]); 1772: close((*s_argument_thread2) 1773: .pipe_nombre_interruptions_attente[0]); 1774: 1775: pthread_mutex_destroy(&((*s_argument_thread2).mutex)); 1776: 1777: if ((*s_argument_thread2).processus_detache == d_faux) 1778: { 1779: if ((*s_argument_thread2).destruction_objet == d_vrai) 1780: { 1781: liberation(s_etat_processus, 1782: (*s_argument_thread2).argument); 1783: } 1784: } 1785: 1786: free(s_argument_thread2); 1787: free((*(*l_element_courant).donnee).objet); 1788: free((*l_element_courant).donnee); 1789: } 1790: 1791: l_element_suivant = (*l_element_courant).suivant; 1792: free((struct_liste_chainee *) l_element_courant); 1793: l_element_courant = l_element_suivant; 1794: } 1795: 1796: (*s_etat_processus).l_base_pile_processus = NULL; 1797: 1798: if (pthread_mutex_unlock(&((*s_etat_processus).mutex)) != 0) 1799: { 1800: (*s_etat_processus).erreur_systeme = d_es; 1801: 1802: pid_final = -2; 1803: 1804: while((longueur_ecriture = write_atomic(s_etat_processus, 1805: (*s_argument_thread).pipe_nombre_interruptions_attente[1], 1806: &pid_final, sizeof(pid_final))) != sizeof(pid_final)) 1807: { 1808: if (longueur_ecriture == -1) 1809: { 1810: break; 1811: } 1812: } 1813: 1814: while((longueur_ecriture = write_atomic(s_etat_processus, 1815: (*s_argument_thread).pipe_nombre_objets_attente[1], 1816: &pid_final, sizeof(pid_final))) != sizeof(pid_final)) 1817: { 1818: if (longueur_ecriture == -1) 1819: { 1820: break; 1821: } 1822: } 1823: 1824: # ifdef _BROKEN_SIGINFO 1825: destruction_fifos_signaux(s_etat_processus); 1826: # endif 1827: 1828: BUG(1, uprintf("Process management error line %d\n", __LINE__)); 1829: exit(EXIT_FAILURE); 1830: } 1831: 1832: /* 1833: * Initialisation de la pile système 1834: */ 1835: 1836: l_element_courant = (struct_liste_chainee *) 1837: (*s_etat_processus).l_base_pile_systeme; 1838: while(l_element_courant != NULL) 1839: { 1840: l_element_suivant = (struct_liste_chainee *) 1841: (*((struct_liste_pile_systeme *) 1842: l_element_courant)).suivant; 1843: 1844: liberation(s_etat_processus, (*((struct_liste_pile_systeme *) 1845: l_element_courant)).indice_boucle); 1846: liberation(s_etat_processus, (*((struct_liste_pile_systeme *) 1847: l_element_courant)).limite_indice_boucle); 1848: liberation(s_etat_processus, (*((struct_liste_pile_systeme *) 1849: l_element_courant)).objet_de_test); 1850: 1851: if ((*((struct_liste_pile_systeme *) l_element_courant)) 1852: .nom_variable != NULL) 1853: { 1854: free((*((struct_liste_pile_systeme *) 1855: l_element_courant)).nom_variable); 1856: } 1857: 1858: free((struct_liste_pile_systeme *) l_element_courant); 1859: 1860: l_element_courant = l_element_suivant; 1861: } 1862: 1863: (*s_etat_processus).l_base_pile_systeme = NULL; 1864: (*s_etat_processus).hauteur_pile_systeme = 0; 1865: 1866: empilement_pile_systeme(s_etat_processus); 1867: 1868: if ((*s_etat_processus).erreur_systeme != d_es) 1869: { 1870: pid_final = -2; 1871: 1872: while((longueur_ecriture = write_atomic(s_etat_processus, 1873: (*s_argument_thread).pipe_nombre_interruptions_attente[1], 1874: &pid_final, sizeof(pid_final))) != sizeof(pid_final)) 1875: { 1876: if (longueur_ecriture == -1) 1877: { 1878: break; 1879: } 1880: } 1881: 1882: while((longueur_ecriture = write_atomic(s_etat_processus, 1883: (*s_argument_thread).pipe_nombre_objets_attente[1], 1884: &pid_final, sizeof(pid_final))) != sizeof(pid_final)) 1885: { 1886: if (longueur_ecriture == -1) 1887: { 1888: break; 1889: } 1890: } 1891: 1892: # ifdef _BROKEN_SIGINFO 1893: destruction_fifos_signaux(s_etat_processus); 1894: # endif 1895: 1896: BUG(1, uprintf("Process management error line %d\n", __LINE__)); 1897: exit(EXIT_FAILURE); 1898: } 1899: 1900: (*(*s_etat_processus).l_base_pile_systeme).retour_definition = 'Y'; 1901: 1902: l_element_courant = (struct_liste_chainee *) 1903: (*s_etat_processus).s_marques; 1904: 1905: while(l_element_courant != NULL) 1906: { 1907: free((*((struct_marque *) l_element_courant)).label); 1908: free((*((struct_marque *) l_element_courant)).position); 1909: l_element_suivant = (struct_liste_chainee *) 1910: (*((struct_marque *) l_element_courant)).suivant; 1911: free((struct_marque *) l_element_courant); 1912: l_element_courant = l_element_suivant; 1913: } 1914: 1915: (*s_etat_processus).s_marques = NULL; 1916: 1917: /* 1918: * On empile deux valeurs retour_definition pour pouvoir récupérer 1919: * les variables dans le cas d'un programme compilé. 1920: */ 1921: 1922: empilement_pile_systeme(s_etat_processus); 1923: 1924: if ((*s_etat_processus).erreur_systeme != d_es) 1925: { 1926: pid_final = -2; 1927: 1928: while((longueur_ecriture = write_atomic(s_etat_processus, 1929: (*s_argument_thread).pipe_nombre_interruptions_attente[1], 1930: &pid_final, sizeof(pid_final))) != sizeof(pid_final)) 1931: { 1932: if (longueur_ecriture == -1) 1933: { 1934: break; 1935: } 1936: } 1937: 1938: while((longueur_ecriture = write_atomic(s_etat_processus, 1939: (*s_argument_thread).pipe_nombre_objets_attente[1], 1940: &pid_final, sizeof(pid_final))) != sizeof(pid_final)) 1941: { 1942: if (longueur_ecriture == -1) 1943: { 1944: break; 1945: } 1946: } 1947: 1948: # ifdef _BROKEN_SIGINFO 1949: destruction_fifos_signaux(s_etat_processus); 1950: # endif 1951: 1952: BUG(1, uprintf("Process management error line %d\n", __LINE__)); 1953: exit(EXIT_FAILURE); 1954: } 1955: 1956: (*(*s_etat_processus).l_base_pile_systeme).retour_definition = 'Y'; 1957: 1958: /* 1959: * Destruction des sorties graphiques et PostScript 1960: */ 1961: 1962: while((*s_etat_processus).fichiers_graphiques != NULL) 1963: { 1964: free((*(*s_etat_processus).fichiers_graphiques).nom); 1965: 1966: if ((*(*s_etat_processus).fichiers_graphiques).legende != NULL) 1967: { 1968: free((*(*s_etat_processus).fichiers_graphiques).legende); 1969: } 1970: 1971: l_element_precedent = (void *) (*s_etat_processus) 1972: .fichiers_graphiques; 1973: (*s_etat_processus).fichiers_graphiques = 1974: (*(*s_etat_processus).fichiers_graphiques).suivant; 1975: free(l_element_precedent); 1976: } 1977: 1978: if ((*s_etat_processus).entree_standard != NULL) 1979: { 1980: pclose((*s_etat_processus).entree_standard); 1981: (*s_etat_processus).entree_standard = NULL; 1982: } 1983: 1984: (*s_etat_processus).requete_nouveau_plan = d_vrai; 1985: (*s_etat_processus).mise_a_jour_trace_requise = d_faux; 1986: 1987: if ((*s_etat_processus).nom_fichier_impression != NULL) 1988: { 1989: free((*s_etat_processus).nom_fichier_impression); 1990: (*s_etat_processus).nom_fichier_impression = NULL; 1991: } 1992: 1993: /* 1994: * Destruction des piles de fichiers 1995: */ 1996: 1997: l_element_courant = (*s_etat_processus).s_fichiers; 1998: 1999: while(l_element_courant != NULL) 2000: { 2001: l_element_suivant = (*l_element_courant).suivant; 2002: 2003: fclose((*((struct_descripteur_fichier *) 2004: (*l_element_courant).donnee)).descripteur_c); 2005: 2006: if ((*((struct_descripteur_fichier *) 2007: (*l_element_courant).donnee)).type != 'C') 2008: { 2009: sqlite3_close((*((struct_descripteur_fichier *) 2010: (*l_element_courant).donnee)).descripteur_sqlite); 2011: } 2012: 2013: free((*((struct_descripteur_fichier *) (*l_element_courant) 2014: .donnee)).nom); 2015: free((struct_descripteur_fichier *) (*l_element_courant).donnee); 2016: free(l_element_courant); 2017: 2018: l_element_courant = l_element_suivant; 2019: } 2020: 2021: /* 2022: * Destruction des piles de connecteurs SQL 2023: */ 2024: 2025: /* 2026: ================================================================================ 2027: À noter : on ne ferme pas la connexion car la conséquence immédiate est 2028: une destruction de l'objet pour le processus père. 2029: ================================================================================ 2030: */ 2031: 2032: l_element_courant = (*s_etat_processus).s_connecteurs_sql; 2033: 2034: while(l_element_courant != NULL) 2035: { 2036: l_element_suivant = (*l_element_courant).suivant; 2037: 2038: // sqlclose((*l_element_courant).donnee); 2039: liberation(s_etat_processus, (*l_element_courant).donnee); 2040: l_element_courant = l_element_suivant; 2041: } 2042: 2043: (*s_etat_processus).s_connecteurs_sql = NULL; 2044: 2045: /* 2046: * On ne détruit pas les sockets car il faut utiliser DETACH 2047: * pour traiter plusieurs connexions simultanées sur les sockets 2048: */ 2049: 2050: (*s_etat_processus).s_fichiers = NULL; 2051: 2052: if (pthread_sigmask(SIG_SETMASK, &oldset, NULL) != 0) 2053: { 2054: (*s_etat_processus).erreur_systeme = d_es_processus; 2055: } 2056: 2057: sigpending(&set); 2058: 2059: if ((*s_etat_processus).debug == d_vrai) 2060: { 2061: if (((*s_etat_processus).type_debug & d_debug_processus) 2062: != 0) 2063: { 2064: if ((*s_etat_processus).langue == 'F') 2065: { 2066: printf("[%d] Évaluation de l'objet détaché\n", getpid()); 2067: } 2068: else 2069: { 2070: printf("[%d] Évaluation of detached object\n", getpid()); 2071: } 2072: } 2073: } 2074: 2075: if ((*s_etat_processus).erreur_systeme == d_es) 2076: { 2077: if (variable_partagee == d_faux) 2078: { 2079: if (evaluation(s_etat_processus, s_objet, 'E') == d_erreur) 2080: { 2081: if (((*s_etat_processus).erreur_execution == d_ex) && 2082: ((*s_etat_processus).erreur_systeme == d_es)) 2083: { 2084: (*s_etat_processus).erreur_execution = 2085: d_ex_erreur_evaluation; 2086: } 2087: } 2088: else 2089: { 2090: if (((*s_etat_processus).var_volatile_alarme == 0) 2091: && ((*s_etat_processus).arret_depuis_abort == 0) 2092: && ((*s_etat_processus).at_exit != NULL)) 2093: { 2094: (*s_etat_processus).var_volatile_requete_arret = 0; 2095: 2096: if (evaluation(s_etat_processus, 2097: (*s_etat_processus).at_exit, 'E') == d_erreur) 2098: { 2099: (*s_etat_processus).erreur_execution = 2100: d_ex_erreur_evaluation; 2101: } 2102: } 2103: } 2104: } 2105: else 2106: { 2107: if (evaluation(s_etat_processus, s_copie, 'E') == d_erreur) 2108: { 2109: if (((*s_etat_processus).erreur_execution == d_ex) && 2110: ((*s_etat_processus).erreur_systeme == d_es)) 2111: { 2112: (*s_etat_processus).erreur_execution = 2113: d_ex_erreur_evaluation; 2114: } 2115: } 2116: else 2117: { 2118: if ((*s_etat_processus).at_exit != NULL) 2119: { 2120: (*s_etat_processus).var_volatile_requete_arret = 0; 2121: 2122: if (evaluation(s_etat_processus, 2123: (*s_etat_processus).at_exit, 'E') == d_erreur) 2124: { 2125: (*s_etat_processus).erreur_execution = 2126: d_ex_erreur_evaluation; 2127: } 2128: } 2129: } 2130: 2131: liberation(s_etat_processus, s_copie); 2132: } 2133: } 2134: 2135: liberation(s_etat_processus, (*s_etat_processus).at_exit); 2136: liberation(s_etat_processus, (*s_etat_processus).at_poke); 2137: 2138: l_element_courant = (*s_etat_processus).liste_mutexes; 2139: while(l_element_courant != NULL) 2140: { 2141: pthread_mutex_trylock(&((*((struct_mutex *) 2142: (*(*l_element_courant).donnee).objet)).mutex)); 2143: pthread_mutex_unlock(&((*((struct_mutex *) 2144: (*(*l_element_courant).donnee).objet)).mutex)); 2145: pthread_mutex_destroy(&((*((struct_mutex *) 2146: (*(*l_element_courant).donnee).objet)).mutex)); 2147: 2148: liberation(s_etat_processus, (*l_element_courant).donnee); 2149: l_element_suivant = (*l_element_courant).suivant; 2150: free(l_element_courant); 2151: l_element_courant = l_element_suivant; 2152: } 2153: 2154: if ((*s_etat_processus).presence_fusible == d_vrai) 2155: { 2156: pthread_cancel((*s_etat_processus).thread_fusible); 2157: } 2158: 2159: pid_final = -2; 2160: 2161: while((longueur_ecriture = write_atomic(s_etat_processus, 2162: (*s_argument_thread).pipe_nombre_interruptions_attente[1], 2163: &pid_final, sizeof(pid_final))) != sizeof(pid_final)) 2164: { 2165: if (longueur_ecriture == -1) 2166: { 2167: break; 2168: } 2169: } 2170: 2171: while((longueur_ecriture = write_atomic(s_etat_processus, 2172: (*s_argument_thread).pipe_nombre_objets_attente[1], 2173: &pid_final, sizeof(pid_final))) != sizeof(pid_final)) 2174: { 2175: if (longueur_ecriture == -1) 2176: { 2177: break; 2178: } 2179: } 2180: 2181: if ((*s_etat_processus).var_volatile_processus_pere != 0) 2182: { 2183: // Racine des processus atteinte 2184: 2185: erreur = d_ex; 2186: 2187: while((longueur_ecriture = write_atomic(s_etat_processus, 2188: (*s_argument_thread).pipe_erreurs[1], &erreur, 2189: sizeof((*s_etat_processus).erreur_execution))) != 2190: sizeof((*s_etat_processus).erreur_execution)) 2191: { 2192: if (longueur_ecriture == -1) 2193: { 2194: break; 2195: } 2196: } 2197: } 2198: else 2199: { 2200: while((longueur_ecriture = write_atomic(s_etat_processus, 2201: (*s_argument_thread).pipe_erreurs[1], 2202: &((*s_etat_processus).erreur_execution), 2203: sizeof((*s_etat_processus).erreur_execution))) != 2204: sizeof((*s_etat_processus).erreur_execution)) 2205: { 2206: if (longueur_ecriture == -1) 2207: { 2208: break; 2209: } 2210: } 2211: } 2212: 2213: if ((*s_etat_processus).var_volatile_processus_pere != 0) 2214: { 2215: // Racine des processus atteinte 2216: 2217: erreur = d_es; 2218: 2219: while((longueur_ecriture = write_atomic(s_etat_processus, 2220: (*s_argument_thread).pipe_erreurs[1], &erreur, 2221: sizeof((*s_etat_processus).erreur_systeme))) != 2222: sizeof((*s_etat_processus).erreur_systeme)) 2223: { 2224: if (longueur_ecriture == -1) 2225: { 2226: break; 2227: } 2228: } 2229: } 2230: else 2231: { 2232: while((longueur_ecriture = write_atomic(s_etat_processus, 2233: (*s_argument_thread).pipe_erreurs[1], 2234: &((*s_etat_processus).erreur_systeme), 2235: sizeof((*s_etat_processus).erreur_systeme))) != 2236: sizeof((*s_etat_processus).erreur_systeme)) 2237: { 2238: if (longueur_ecriture == -1) 2239: { 2240: break; 2241: } 2242: } 2243: } 2244: 2245: if ((*s_etat_processus).pid_erreur_processus_fils == 0) 2246: { 2247: while((longueur_ecriture = write_atomic(s_etat_processus, 2248: (*s_argument_thread).pipe_erreurs[1], 2249: &ppid, sizeof(ppid))) != sizeof(ppid)) 2250: { 2251: if (longueur_ecriture == -1) 2252: { 2253: break; 2254: } 2255: } 2256: } 2257: else 2258: { 2259: while((longueur_ecriture = write_atomic(s_etat_processus, 2260: (*s_argument_thread).pipe_erreurs[1], 2261: &((*s_etat_processus).pid_erreur_processus_fils), 2262: sizeof((*s_etat_processus).pid_erreur_processus_fils))) != 2263: sizeof((*s_etat_processus).pid_erreur_processus_fils)) 2264: { 2265: if (longueur_ecriture == -1) 2266: { 2267: break; 2268: } 2269: } 2270: } 2271: 2272: close((*s_argument_thread).pipe_erreurs[1]); 2273: close((*s_argument_thread).pipe_interruptions[1]); 2274: close((*s_argument_thread).pipe_nombre_interruptions_attente[1]); 2275: close((*s_argument_thread).pipe_objets[1]); 2276: close((*s_argument_thread).pipe_nombre_objets_attente[1]); 2277: close((*s_argument_thread).pipe_injections[0]); 2278: close((*s_argument_thread).pipe_nombre_injections[0]); 2279: close((*s_argument_thread).pipe_acquittement[0]); 2280: 2281: l_element_courant = (*s_etat_processus).s_fichiers; 2282: 2283: while(l_element_courant != NULL) 2284: { 2285: l_element_suivant = (*l_element_courant).suivant; 2286: 2287: fclose((*((struct_descripteur_fichier *) 2288: (*l_element_courant).donnee)).descripteur_c); 2289: 2290: if ((*((struct_descripteur_fichier *) 2291: (*l_element_courant).donnee)).type != 'C') 2292: { 2293: sqlite3_close((*((struct_descripteur_fichier *) 2294: (*l_element_courant).donnee)).descripteur_sqlite); 2295: } 2296: 2297: if (((*((struct_descripteur_fichier *) (*l_element_courant) 2298: .donnee)).pid == getpid()) && 2299: (pthread_equal((*((struct_descripteur_fichier *) 2300: (*l_element_courant).donnee)).tid, pthread_self()) != 0)) 2301: { 2302: if ((*((struct_descripteur_fichier *) (*l_element_courant) 2303: .donnee)).effacement == 'Y') 2304: { 2305: unlink((*((struct_descripteur_fichier *) 2306: (*l_element_courant).donnee)).nom); 2307: } 2308: } 2309: 2310: free((*((struct_descripteur_fichier *) (*l_element_courant) 2311: .donnee)).nom); 2312: free((struct_descripteur_fichier *) (*l_element_courant).donnee); 2313: free(l_element_courant); 2314: 2315: l_element_courant = l_element_suivant; 2316: } 2317: 2318: pthread_mutex_lock(&((*s_etat_processus).mutex)); 2319: 2320: l_element_courant = (struct_liste_chainee *) 2321: (*s_etat_processus).l_base_pile_processus; 2322: 2323: while(l_element_courant != NULL) 2324: { 2325: if ((*(*((struct_processus_fils *) (*(*((struct_liste_chainee *) 2326: l_element_courant)).donnee).objet)).thread) 2327: .processus_detache == d_vrai) 2328: { 2329: if ((*s_etat_processus).debug == d_vrai) 2330: { 2331: if (((*s_etat_processus).type_debug & d_debug_processus) 2332: != 0) 2333: { 2334: if ((*s_etat_processus).langue == 'F') 2335: { 2336: printf("[%d] Signalement pour arrêt du " 2337: "processus %d\n", 2338: (int) getpid(), 2339: (int) (*(*((struct_processus_fils *) 2340: (*(*((struct_liste_chainee *) 2341: l_element_courant)).donnee).objet)) 2342: .thread).pid); 2343: } 2344: else 2345: { 2346: printf("[%d] Send stop signal to process %d\n", 2347: (int) getpid(), 2348: (int) (*(*((struct_processus_fils *) 2349: (*(*((struct_liste_chainee *) 2350: l_element_courant)).donnee).objet)) 2351: .thread).pid); 2352: } 2353: } 2354: } 2355: 2356: if ((*s_etat_processus).var_volatile_alarme != 0) 2357: { 2358: kill((*(*((struct_processus_fils *) 2359: (*(*l_element_courant).donnee).objet)).thread).pid, 2360: SIGURG); 2361: } 2362: else 2363: { 2364: if ((*s_etat_processus).arret_depuis_abort == -1) 2365: { 2366: kill((*(*((struct_processus_fils *) 2367: (*(*l_element_courant).donnee).objet)).thread) 2368: .pid, SIGFABORT); 2369: } 2370: else 2371: { 2372: kill((*(*((struct_processus_fils *) 2373: (*(*l_element_courant).donnee).objet)).thread) 2374: .pid, SIGFSTOP); 2375: } 2376: } 2377: } 2378: else 2379: { 2380: if ((*s_etat_processus).debug == d_vrai) 2381: { 2382: if (((*s_etat_processus).type_debug & d_debug_processus) 2383: != 0) 2384: { 2385: if ((*s_etat_processus).langue == 'F') 2386: { 2387: printf("[%d] Signalement pour arrêt du " 2388: "thread %llu\n", 2389: (int) getpid(), (unsigned long long) 2390: (*(*((struct_processus_fils *) 2391: (*(*((struct_liste_chainee *) 2392: l_element_courant)).donnee).objet)).thread) 2393: .tid); 2394: } 2395: else 2396: { 2397: printf("[%d] Send stop signal to thread %llu\n", 2398: (int) getpid(), (unsigned long long) 2399: (*(*((struct_processus_fils *) 2400: (*(*((struct_liste_chainee *) 2401: l_element_courant)).donnee).objet)).thread) 2402: .tid); 2403: } 2404: } 2405: } 2406: 2407: pthread_mutex_lock(&((*(*((struct_processus_fils *) 2408: (*(*l_element_courant).donnee).objet)).thread).mutex)); 2409: 2410: if ((*(*((struct_processus_fils *) 2411: (*(*l_element_courant).donnee).objet)).thread) 2412: .thread_actif == d_vrai) 2413: { 2414: if ((*s_etat_processus).var_volatile_alarme != 0) 2415: { 2416: pthread_kill((*(*((struct_processus_fils *) 2417: (*(*l_element_courant).donnee).objet)).thread) 2418: .tid, SIGURG); 2419: } 2420: else 2421: { 2422: if ((*s_etat_processus).arret_depuis_abort == -1) 2423: { 2424: pthread_kill((*(*((struct_processus_fils *) 2425: (*(*l_element_courant).donnee).objet)) 2426: .thread).tid, SIGFABORT); 2427: } 2428: else 2429: { 2430: pthread_kill((*(*((struct_processus_fils *) 2431: (*(*l_element_courant).donnee).objet)) 2432: .thread).tid, SIGFSTOP); 2433: } 2434: } 2435: } 2436: 2437: pthread_mutex_unlock(&((*(*((struct_processus_fils *) 2438: (*(*l_element_courant).donnee).objet)).thread).mutex)); 2439: } 2440: 2441: l_element_courant = (*l_element_courant).suivant; 2442: } 2443: 2444: /* 2445: * Attente de la fin de tous les processus fils 2446: */ 2447: 2448: for(i = 0; i < d_NOMBRE_INTERRUPTIONS; 2449: (*s_etat_processus).masque_interruptions[i++] = 'I'); 2450: 2451: attente.tv_sec = 0; 2452: attente.tv_nsec = GRANULARITE_us * 1000; 2453: 2454: while((*s_etat_processus).l_base_pile_processus != NULL) 2455: { 2456: l_element_courant = (struct_liste_chainee *) 2457: (*s_etat_processus).l_base_pile_processus; 2458: 2459: registre_stop = (*s_etat_processus) 2460: .var_volatile_traitement_retarde_stop; 2461: (*s_etat_processus).var_volatile_traitement_retarde_stop = 1; 2462: 2463: for(i = 0; i < (unsigned long) (*(*((struct_processus_fils *) 2464: (*(*l_element_courant) 2465: .donnee).objet)).thread).nombre_objets_dans_pipe; i++) 2466: { 2467: if ((s_objet_temporaire = lecture_pipe(s_etat_processus, 2468: (*(*((struct_processus_fils *) (*(*l_element_courant) 2469: .donnee).objet)).thread).pipe_objets[0])) != NULL) 2470: { 2471: liberation(s_etat_processus, s_objet_temporaire); 2472: 2473: (*(*((struct_processus_fils *) (*(*l_element_courant) 2474: .donnee).objet)).thread).nombre_objets_dans_pipe--; 2475: 2476: action.sa_handler = SIG_IGN; 2477: action.sa_flags = SA_ONSTACK; 2478: 2479: if (sigaction(SIGPIPE, &action, ®istre) != 0) 2480: { 2481: pthread_mutex_unlock(&((*s_etat_processus).mutex)); 2482: 2483: if (registre_stop == 0) 2484: { 2485: if ((*s_etat_processus) 2486: .var_volatile_traitement_retarde_stop 2487: == -1) 2488: { 2489: (*s_etat_processus) 2490: .var_volatile_requete_arret = -1; 2491: } 2492: 2493: (*s_etat_processus) 2494: .var_volatile_traitement_retarde_stop = 2495: registre_stop; 2496: } 2497: 2498: # ifdef _BROKEN_SIGINFO 2499: destruction_fifos_signaux(s_etat_processus); 2500: # endif 2501: 2502: (*s_etat_processus).erreur_systeme = d_es_signal; 2503: exit(EXIT_FAILURE); 2504: } 2505: 2506: while((longueur_ecriture = write_atomic( 2507: s_etat_processus, (*(*((struct_processus_fils *) 2508: (*(*l_element_courant).donnee).objet)) 2509: .thread).pipe_nombre_injections[1], "+", 2510: sizeof(unsigned char))) != 2511: sizeof(unsigned char)) 2512: { 2513: if (longueur_ecriture == -1) 2514: { 2515: // Le processus n'existe plus. 2516: break; 2517: } 2518: } 2519: 2520: if (registre_stop == 0) 2521: { 2522: if ((*s_etat_processus) 2523: .var_volatile_traitement_retarde_stop == -1) 2524: { 2525: (*s_etat_processus).var_volatile_requete_arret 2526: = -1; 2527: } 2528: 2529: (*s_etat_processus) 2530: .var_volatile_traitement_retarde_stop = 2531: registre_stop; 2532: } 2533: 2534: if (sigaction(SIGPIPE, ®istre, NULL) != 0) 2535: { 2536: # ifdef _BROKEN_SIGINFO 2537: destruction_fifos_signaux(s_etat_processus); 2538: # endif 2539: 2540: pthread_mutex_unlock(&((*s_etat_processus).mutex)); 2541: 2542: (*s_etat_processus).erreur_systeme = d_es_signal; 2543: exit(EXIT_FAILURE); 2544: } 2545: } 2546: } 2547: 2548: pthread_mutex_unlock(&((*s_etat_processus).mutex)); 2549: 2550: if ((*s_etat_processus).nombre_interruptions_non_affectees != 0) 2551: { 2552: affectation_interruptions_logicielles(s_etat_processus); 2553: } 2554: 2555: nanosleep(&attente, NULL); 2556: pthread_mutex_lock(&((*s_etat_processus).mutex)); 2557: } 2558: 2559: pthread_mutex_unlock(&((*s_etat_processus).mutex)); 2560: 2561: l_element_courant = (*s_etat_processus).s_sockets; 2562: 2563: while(l_element_courant != NULL) 2564: { 2565: l_element_suivant = (*l_element_courant).suivant; 2566: 2567: if ((*((struct_socket *) (*(*l_element_courant).donnee) 2568: .objet)).socket_connectee == d_vrai) 2569: { 2570: shutdown((*((struct_socket *) (*(*l_element_courant).donnee) 2571: .objet)).socket, SHUT_RDWR); 2572: } 2573: 2574: close((*((struct_socket *) (*(*l_element_courant).donnee) 2575: .objet)).socket); 2576: 2577: if (((*((struct_socket *) (*(*l_element_courant).donnee).objet)) 2578: .pid == getpid()) && (pthread_equal((*((struct_socket *) 2579: (*(*l_element_courant).donnee).objet)).tid, pthread_self()) 2580: != 0)) 2581: { 2582: if ((*((struct_socket *) (*(*l_element_courant).donnee).objet)) 2583: .effacement == 'Y') 2584: { 2585: unlink((*((struct_socket *) (*(*l_element_courant).donnee) 2586: .objet)).adresse); 2587: } 2588: } 2589: 2590: liberation(s_etat_processus, 2591: (*((struct_liste_chainee *) l_element_courant)).donnee); 2592: free(l_element_courant); 2593: 2594: l_element_courant = l_element_suivant; 2595: } 2596: 2597: l_element_courant = (*s_etat_processus).s_connecteurs_sql; 2598: 2599: while(l_element_courant != NULL) 2600: { 2601: l_element_suivant = (*l_element_courant).suivant; 2602: 2603: sqlclose((*l_element_courant).donnee); 2604: 2605: liberation(s_etat_processus, 2606: (*((struct_liste_chainee *) l_element_courant)).donnee); 2607: free(l_element_courant); 2608: 2609: l_element_courant = l_element_suivant; 2610: } 2611: 2612: if ((((*s_etat_processus).erreur_execution != d_ex) || 2613: ((*s_etat_processus).exception != d_ep) || 2614: ((*s_etat_processus).erreur_systeme != d_es)) && 2615: ((*s_etat_processus).var_volatile_traitement_sigint == 0)) 2616: { 2617: printf("%s [%d]\n", message = 2618: messages(s_etat_processus), (int) getpid()); 2619: free(message); 2620: 2621: if ((*s_etat_processus).core == d_vrai) 2622: { 2623: printf("\n"); 2624: 2625: if ((*s_etat_processus).langue == 'F') 2626: { 2627: printf("+++Information : Génération du fichier rpl-core " 2628: "[%d]\n", (int) getpid()); 2629: } 2630: else 2631: { 2632: printf("+++Information : Writing rpl-core file [%d]\n", 2633: (int) getpid()); 2634: } 2635: 2636: rplcore(s_etat_processus); 2637: 2638: if ((*s_etat_processus).langue == 'F') 2639: { 2640: printf("+++Information : Processus tracé [%d]\n", 2641: (int) getpid()); 2642: } 2643: else 2644: { 2645: printf("+++Information : Done [%d]\n", (int) getpid()); 2646: } 2647: 2648: printf("\n"); 2649: fflush(stdout); 2650: } 2651: } 2652: 2653: liberation_arbre_instructions(s_etat_processus, 2654: (*s_etat_processus).arbre_instructions); 2655: free((*s_etat_processus).pointeurs_caracteres); 2656: 2657: if ((*s_etat_processus).entree_standard != NULL) 2658: { 2659: pclose((*s_etat_processus).entree_standard); 2660: (*s_etat_processus).entree_standard = NULL; 2661: } 2662: 2663: liberation(s_etat_processus, (*s_etat_processus).indep); 2664: liberation(s_etat_processus, (*s_etat_processus).depend); 2665: 2666: free((*s_etat_processus).label_x); 2667: free((*s_etat_processus).label_y); 2668: free((*s_etat_processus).label_z); 2669: free((*s_etat_processus).titre); 2670: free((*s_etat_processus).legende); 2671: 2672: liberation(s_etat_processus, 2673: (*s_etat_processus).parametres_courbes_de_niveau); 2674: 2675: if ((*s_etat_processus).instruction_derniere_erreur != NULL) 2676: { 2677: free((*s_etat_processus).instruction_derniere_erreur); 2678: (*s_etat_processus).instruction_derniere_erreur = NULL; 2679: } 2680: 2681: liberation_arbre_variables(s_etat_processus, 2682: (*s_etat_processus).s_arbre_variables, d_vrai); 2683: free((*s_etat_processus).pointeurs_caracteres_variables); 2684: 2685: for(i = 0; i < (*s_etat_processus).nombre_variables_statiques; i++) 2686: { 2687: liberation(s_etat_processus, 2688: (*s_etat_processus).s_liste_variables_statiques[i].objet); 2689: free((*s_etat_processus).s_liste_variables_statiques[i].nom); 2690: } 2691: 2692: free((*s_etat_processus).s_liste_variables_statiques); 2693: 2694: for(i = 0; i < (*(*s_etat_processus).s_liste_variables_partagees) 2695: .nombre_variables; i++) 2696: { 2697: liberation(s_etat_processus, 2698: (*(*s_etat_processus).s_liste_variables_partagees) 2699: .table[i].objet); 2700: free((*(*s_etat_processus).s_liste_variables_partagees) 2701: .table[i].nom); 2702: } 2703: 2704: if ((*(*s_etat_processus).s_liste_variables_partagees).table 2705: != NULL) 2706: { 2707: free((struct_variable_partagee *) 2708: (*(*s_etat_processus).s_liste_variables_partagees).table); 2709: } 2710: 2711: pthread_mutex_destroy(&((*(*s_etat_processus) 2712: .s_liste_variables_partagees).mutex)); 2713: 2714: l_element_courant = (*s_etat_processus).l_base_pile; 2715: while(l_element_courant != NULL) 2716: { 2717: l_element_suivant = (*l_element_courant).suivant; 2718: 2719: liberation(s_etat_processus, (*l_element_courant).donnee); 2720: free(l_element_courant); 2721: 2722: l_element_courant = l_element_suivant; 2723: } 2724: 2725: l_element_courant = (*s_etat_processus).l_base_pile_last; 2726: while(l_element_courant != NULL) 2727: { 2728: l_element_suivant = (*l_element_courant).suivant; 2729: 2730: liberation(s_etat_processus, (*l_element_courant).donnee); 2731: free(l_element_courant); 2732: 2733: l_element_courant = l_element_suivant; 2734: } 2735: 2736: l_element_courant = (*s_etat_processus).l_base_pile_contextes; 2737: while(l_element_courant != NULL) 2738: { 2739: l_element_suivant = (*l_element_courant).suivant; 2740: 2741: liberation(s_etat_processus, (*l_element_courant).donnee); 2742: free(l_element_courant); 2743: 2744: l_element_courant = l_element_suivant; 2745: } 2746: 2747: l_element_courant = (*s_etat_processus).l_base_pile_taille_contextes; 2748: while(l_element_courant != NULL) 2749: { 2750: l_element_suivant = (*l_element_courant).suivant; 2751: 2752: liberation(s_etat_processus, (*l_element_courant).donnee); 2753: free(l_element_courant); 2754: 2755: l_element_courant = l_element_suivant; 2756: } 2757: 2758: l_element_courant = (struct_liste_chainee *) 2759: (*s_etat_processus).l_base_pile_systeme; 2760: while(l_element_courant != NULL) 2761: { 2762: l_element_suivant = (struct_liste_chainee *) 2763: (*((struct_liste_pile_systeme *) 2764: l_element_courant)).suivant; 2765: 2766: liberation(s_etat_processus, (*((struct_liste_pile_systeme *) 2767: l_element_courant)).indice_boucle); 2768: liberation(s_etat_processus, (*((struct_liste_pile_systeme *) 2769: l_element_courant)).limite_indice_boucle); 2770: liberation(s_etat_processus, (*((struct_liste_pile_systeme *) 2771: l_element_courant)).objet_de_test); 2772: 2773: if ((*((struct_liste_pile_systeme *) 2774: l_element_courant)).nom_variable != NULL) 2775: { 2776: free((*((struct_liste_pile_systeme *) 2777: l_element_courant)).nom_variable); 2778: } 2779: 2780: free((struct_liste_pile_systeme *) l_element_courant); 2781: 2782: l_element_courant = l_element_suivant; 2783: } 2784: 2785: /* 2786: * Destruction des bibliothèques 2787: */ 2788: 2789: l_element_courant = (*s_etat_processus).s_bibliotheques; 2790: 2791: while(l_element_courant != NULL) 2792: { 2793: l_element_suivant = (*l_element_courant).suivant; 2794: 2795: free((*((struct_bibliotheque *) (*l_element_courant).donnee)).nom); 2796: 2797: dlclose((*((struct_bibliotheque *) (*l_element_courant).donnee)) 2798: .descripteur); 2799: 2800: free((*l_element_courant).donnee); 2801: free(l_element_courant); 2802: 2803: l_element_courant = l_element_suivant; 2804: } 2805: 2806: for(i = 0; i < (*s_etat_processus).nombre_instructions_externes; i++) 2807: { 2808: free((*s_etat_processus).s_instructions_externes[i].nom); 2809: free((*s_etat_processus).s_instructions_externes[i] 2810: .nom_bibliotheque); 2811: } 2812: 2813: if ((*s_etat_processus).nombre_instructions_externes != 0) 2814: { 2815: free((*s_etat_processus).s_instructions_externes); 2816: } 2817: 2818: l_element_courant = (struct_liste_chainee *) 2819: (*s_etat_processus).s_marques; 2820: 2821: while(l_element_courant != NULL) 2822: { 2823: free((*((struct_marque *) l_element_courant)).label); 2824: free((*((struct_marque *) l_element_courant)).position); 2825: l_element_suivant = (struct_liste_chainee *) 2826: (*((struct_marque *) l_element_courant)).suivant; 2827: free((struct_marque *) l_element_courant); 2828: l_element_courant = l_element_suivant; 2829: } 2830: 2831: free((*s_etat_processus).chemin_fichiers_temporaires); 2832: 2833: if ((*s_etat_processus).debug == d_vrai) 2834: if (((*s_etat_processus).type_debug & 2835: d_debug_processus) != 0) 2836: { 2837: if ((*s_etat_processus).langue == 'F') 2838: { 2839: printf("[%d] Arrêt du processus\n", (int) getpid()); 2840: } 2841: else 2842: { 2843: printf("[%d] Stop process\n", (int) getpid()); 2844: } 2845: 2846: fflush(stdout); 2847: } 2848: 2849: liberation(s_etat_processus, s_objet); 2850: 2851: free((*s_etat_processus).definitions_chainees); 2852: free((*s_etat_processus).nom_fichier_historique); 2853: 2854: for(i = 0; i < d_NOMBRE_INTERRUPTIONS; i++) 2855: { 2856: liberation(s_etat_processus, 2857: (*s_etat_processus).corps_interruptions[i]); 2858: 2859: l_element_courant = (*s_etat_processus) 2860: .pile_origine_interruptions[i]; 2861: 2862: while(l_element_courant != NULL) 2863: { 2864: l_element_suivant = (*l_element_courant).suivant; 2865: 2866: liberation(s_etat_processus, (*l_element_courant).donnee); 2867: free(l_element_courant); 2868: 2869: l_element_courant = l_element_suivant; 2870: } 2871: } 2872: 2873: if ((*s_etat_processus).generateur_aleatoire != NULL) 2874: { 2875: liberation_generateur_aleatoire(s_etat_processus); 2876: } 2877: 2878: if ((*s_etat_processus).profilage == d_vrai) 2879: { 2880: ecriture_profil(s_etat_processus); 2881: liberation_profil(s_etat_processus); 2882: } 2883: 2884: closelog(); 2885: 2886: liberation_allocateur(s_etat_processus); 2887: retrait_thread(s_etat_processus); 2888: 2889: pthread_mutex_destroy(&((*s_etat_processus).mutex)); 2890: pthread_mutex_destroy(&((*s_etat_processus).mutex_allocation)); 2891: pthread_mutex_destroy(&((*s_etat_processus).protection_liste_mutexes)); 2892: 2893: pthread_key_delete(semaphore_fork_processus_courant); 2894: 2895: # ifndef SEMAPHORES_NOMMES 2896: sem_post(&((*s_etat_processus).semaphore_fork)); 2897: sem_destroy(&((*s_etat_processus).semaphore_fork)); 2898: # else 2899: sem_post((*s_etat_processus).semaphore_fork); 2900: sem_destroy2((*s_etat_processus).semaphore_fork, sem_fork); 2901: # endif 2902: 2903: free((*s_etat_processus).localisation); 2904: free(s_argument_thread); 2905: 2906: # ifndef SEMAPHORES_NOMMES 2907: sem_destroy(&semaphore_liste_threads); 2908: sem_post(&semaphore_gestionnaires_signaux); 2909: sem_destroy(&semaphore_gestionnaires_signaux); 2910: sem_destroy(&semaphore_gestionnaires_signaux_atomique); 2911: # else 2912: sem_destroy2(semaphore_liste_threads, sem_liste_threads); 2913: sem_post(semaphore_gestionnaires_signaux); 2914: sem_destroy2(semaphore_gestionnaires_signaux, 2915: sem_gestionnaires_signaux); 2916: sem_destroy2(semaphore_gestionnaires_signaux_atomique, 2917: sem_gestionnaires_signaux_atomique); 2918: # endif 2919: 2920: clear_history(); 2921: 2922: # ifdef _BROKEN_SIGINFO 2923: destruction_fifos_signaux(s_etat_processus); 2924: # endif 2925: 2926: liberation_contexte_cas(s_etat_processus); 2927: free(s_etat_processus); 2928: 2929: # ifdef DEBUG_MEMOIRE 2930: debug_memoire_verification(); 2931: analyse_post_mortem(); 2932: # endif 2933: 2934: exit(EXIT_SUCCESS); 2935: } 2936: else 2937: { 2938: (*s_etat_processus).erreur_systeme = d_es_processus; 2939: return; 2940: } 2941: 2942: // Si le pid existe déjà dans la pile des processus, il s'agit forcement 2943: // d'un processus moribond. On attend donc qu'il soit effectivement 2944: // libéré. 2945: 2946: do 2947: { 2948: l_element_courant = (struct_liste_chainee *) 2949: (*s_etat_processus).l_base_pile_processus; 2950: drapeau = d_faux; 2951: 2952: attente.tv_sec = 0; 2953: attente.tv_nsec = GRANULARITE_us * 1000; 2954: 2955: while(l_element_courant != NULL) 2956: { 2957: if ((*(*((struct_processus_fils *) 2958: (*(*l_element_courant).donnee).objet)).thread) 2959: .processus_detache == d_vrai) 2960: { 2961: if ((*(*((struct_processus_fils *) 2962: (*(*l_element_courant).donnee).objet)).thread).pid == 2963: (*s_argument_thread).pid) 2964: { 2965: if (pthread_mutex_unlock(&((*s_etat_processus).mutex)) != 0) 2966: { 2967: (*s_etat_processus).erreur_systeme = d_es_processus; 2968: return; 2969: } 2970: 2971: nanosleep(&attente, NULL); 2972: INCR_GRANULARITE(attente.tv_nsec); 2973: 2974: if (pthread_mutex_lock(&((*s_etat_processus).mutex)) != 0) 2975: { 2976: (*s_etat_processus).erreur_systeme = d_es_processus; 2977: return; 2978: } 2979: 2980: drapeau = d_vrai; 2981: break; 2982: } 2983: } 2984: 2985: l_element_courant = (*l_element_courant).suivant; 2986: } 2987: } while(drapeau == d_vrai); 2988: 2989: if (empilement(s_etat_processus, 2990: (struct_liste_chainee **) &((*s_etat_processus) 2991: .l_base_pile_processus), s_objet_systeme) == d_erreur) 2992: { 2993: pthread_mutex_unlock(&((*s_etat_processus).mutex)); 2994: return; 2995: } 2996: 2997: if (empilement(s_etat_processus, &((*s_etat_processus).l_base_pile), 2998: s_objet) == d_erreur) 2999: { 3000: pthread_mutex_unlock(&((*s_etat_processus).mutex)); 3001: return; 3002: } 3003: 3004: // Être sûr que le processus fils soit déjà présent... 3005: 3006: attente.tv_sec = 0; 3007: attente.tv_nsec = GRANULARITE_us * 1000; 3008: 3009: while(kill((*s_argument_thread).pid, 0) != 0) 3010: { 3011: //if ((errno != ESRCH) && (errno != EAGAIN)) 3012: if (errno != ESRCH) 3013: { 3014: (*s_etat_processus).erreur_systeme = d_es_processus; 3015: pthread_mutex_unlock(&((*s_etat_processus).mutex)); 3016: return; 3017: } 3018: 3019: nanosleep(&attente, NULL); 3020: INCR_GRANULARITE(attente.tv_nsec); 3021: } 3022: 3023: // Le fils peut être présent sans être en attente du signal de départ. 3024: 3025: if (kill((*s_argument_thread).pid, SIGSTART) != 0) 3026: { 3027: (*s_etat_processus).erreur_systeme = d_es_processus; 3028: pthread_mutex_unlock(&((*s_etat_processus).mutex)); 3029: return; 3030: } 3031: 3032: if (pthread_sigmask(SIG_SETMASK, &oldset, NULL) != 0) 3033: { 3034: (*s_etat_processus).erreur_systeme = d_es_processus; 3035: pthread_mutex_unlock(&((*s_etat_processus).mutex)); 3036: return; 3037: } 3038: 3039: sigpending(&set); 3040: 3041: if (pthread_mutex_unlock(&((*s_etat_processus).mutex)) != 0) 3042: { 3043: (*s_etat_processus).erreur_systeme = d_es_processus; 3044: return; 3045: } 3046: 3047: return; 3048: } 3049: 3050: // vim: ts=4