![]() ![]() | ![]() |
Passage de la branche 4.1 en branche stable.
1: /* 2: ================================================================================ 3: RPL/2 (R) version 4.1.0 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: int status; 818: 819: logical1 drapeau; 820: logical1 variable_partagee; 821: 822: pid_t ppid; 823: pid_t pid_final; 824: 825: pthread_attr_t attributs; 826: 827: pthread_mutexattr_t attributs_mutex; 828: 829: pthread_t thread_surveillance; 830: 831: sig_atomic_t registre_stop; 832: 833: sigset_t oldset; 834: sigset_t oldset2; 835: sigset_t set; 836: sigset_t set2; 837: 838: ssize_t longueur_ecriture; 839: 840: struct_descripteur_thread *s_argument_thread; 841: struct_descripteur_thread *s_argument_thread2; 842: 843: struct_liste_chainee *l_element_courant; 844: struct_liste_chainee *l_element_precedent; 845: struct_liste_chainee *l_element_suivant; 846: 847: struct_objet *s_copie; 848: struct_objet *s_objet; 849: struct_objet *s_objet_systeme; 850: struct_objet *s_objet_temporaire; 851: 852: struct sigaction action; 853: struct sigaction registre; 854: 855: struct timespec attente; 856: 857: unsigned char *message; 858: 859: unsigned int erreur; 860: 861: unsigned long i; 862: 863: (*s_etat_processus).erreur_execution = d_ex; 864: 865: attente.tv_sec = 0; 866: attente.tv_nsec = GRANULARITE_us * 1000; 867: s_copie = NULL; 868: 869: if ((*s_etat_processus).affichage_arguments == 'Y') 870: { 871: printf("\n DETACH "); 872: 873: if ((*s_etat_processus).langue == 'F') 874: { 875: printf("(détachement d'un processus)\n\n"); 876: } 877: else 878: { 879: printf("(fork)\n\n"); 880: } 881: 882: printf(" 1: %s, %s\n", d_NOM, d_RPN); 883: printf("-> 1: %s\n", d_PRC); 884: 885: return; 886: } 887: else if ((*s_etat_processus).test_instruction == 'Y') 888: { 889: (*s_etat_processus).nombre_arguments = -1; 890: return; 891: } 892: 893: if (test_cfsf(s_etat_processus, 31) == d_vrai) 894: { 895: if (empilement_pile_last(s_etat_processus, 1) == d_erreur) 896: { 897: return; 898: } 899: } 900: 901: if (depilement(s_etat_processus, &((*s_etat_processus).l_base_pile), 902: &s_objet) == d_erreur) 903: { 904: (*s_etat_processus).erreur_execution = d_ex_manque_argument; 905: return; 906: } 907: 908: /* 909: * Une routine fille doit pouvoir renvoyer des objets au processus 910: * père au travers de la fonction SEND. Il ne peut donc s'agir que 911: * d'une fonction ou d'une expression RPN. 912: */ 913: 914: if (((*s_objet).type != NOM) && ((*s_objet).type != RPN)) 915: { 916: liberation(s_etat_processus, s_objet); 917: 918: (*s_etat_processus).erreur_execution = d_ex_erreur_type_argument; 919: return; 920: } 921: 922: /* 923: * Si l'argument est de type NOM, il faut que la variable correspondante 924: * soit une variable de type RPN. 925: */ 926: 927: variable_partagee = d_faux; 928: 929: if ((*s_objet).type == NOM) 930: { 931: if (recherche_variable(s_etat_processus, (*((struct_nom *) 932: (*s_objet).objet)).nom) == d_vrai) 933: { 934: if ((*(*s_etat_processus).pointeur_variable_courante).objet 935: == NULL) 936: { 937: if (pthread_mutex_lock(&((*(*s_etat_processus) 938: .s_liste_variables_partagees).mutex)) != 0) 939: { 940: (*s_etat_processus).erreur_systeme = d_es_processus; 941: return; 942: } 943: 944: if (recherche_variable_partagee(s_etat_processus, 945: (*(*s_etat_processus).pointeur_variable_courante).nom, 946: (*(*s_etat_processus).pointeur_variable_courante) 947: .variable_partagee, (*(*s_etat_processus) 948: .pointeur_variable_courante).origine) == d_faux) 949: { 950: if (pthread_mutex_unlock(&((*(*s_etat_processus) 951: .s_liste_variables_partagees).mutex)) != 0) 952: { 953: (*s_etat_processus).erreur_systeme = d_es_processus; 954: return; 955: } 956: 957: liberation(s_etat_processus, s_objet); 958: 959: (*s_etat_processus).erreur_systeme = d_es; 960: (*s_etat_processus).erreur_execution = 961: d_ex_argument_invalide; 962: return; 963: } 964: 965: if (((*(*(*s_etat_processus).s_liste_variables_partagees) 966: .table[(*(*s_etat_processus) 967: .s_liste_variables_partagees).position_variable].objet) 968: .type != RPN) && ((*(*(*s_etat_processus) 969: .s_liste_variables_partagees).table 970: [(*(*s_etat_processus).s_liste_variables_partagees) 971: .position_variable].objet).type != ADR)) 972: { 973: if (pthread_mutex_unlock(&((*(*s_etat_processus) 974: .s_liste_variables_partagees).mutex)) != 0) 975: { 976: (*s_etat_processus).erreur_systeme = d_es_processus; 977: return; 978: } 979: 980: liberation(s_etat_processus, s_objet); 981: 982: (*s_etat_processus).erreur_execution = 983: d_ex_argument_invalide; 984: return; 985: } 986: 987: if ((s_copie = copie_objet(s_etat_processus, 988: (*(*s_etat_processus).s_liste_variables_partagees).table 989: [(*(*s_etat_processus).s_liste_variables_partagees) 990: .position_variable].objet, 'P')) == NULL) 991: { 992: if (pthread_mutex_unlock(&((*(*s_etat_processus) 993: .s_liste_variables_partagees).mutex)) != 0) 994: { 995: (*s_etat_processus).erreur_systeme = d_es_processus; 996: return; 997: } 998: 999: (*s_etat_processus).erreur_systeme = 1000: d_es_allocation_memoire; 1001: 1002: return; 1003: } 1004: 1005: variable_partagee = d_vrai; 1006: 1007: if (pthread_mutex_unlock(&((*(*s_etat_processus) 1008: .s_liste_variables_partagees).mutex)) != 0) 1009: { 1010: (*s_etat_processus).erreur_systeme = d_es_processus; 1011: return; 1012: } 1013: } 1014: else 1015: { 1016: if (((*(*(*s_etat_processus).pointeur_variable_courante).objet) 1017: .type != RPN) && ((*(*(*s_etat_processus) 1018: .pointeur_variable_courante).objet).type != ADR)) 1019: { 1020: liberation(s_etat_processus, s_objet); 1021: 1022: (*s_etat_processus).erreur_execution = 1023: d_ex_argument_invalide; 1024: return; 1025: } 1026: } 1027: } 1028: else // Variable inexistante 1029: { 1030: liberation(s_etat_processus, s_objet); 1031: 1032: (*s_etat_processus).erreur_systeme = d_es; 1033: (*s_etat_processus).erreur_execution = d_ex_argument_invalide; 1034: return; 1035: } 1036: } 1037: 1038: if (sigemptyset(&set) != 0) 1039: { 1040: (*s_etat_processus).erreur_systeme = d_es_processus; 1041: return; 1042: } 1043: 1044: if (sigaddset(&set, SIGSTART) != 0) 1045: { 1046: (*s_etat_processus).erreur_systeme = d_es_processus; 1047: return; 1048: } 1049: 1050: /* 1051: * Le signal SIGFSTOP doit être traité ! 1052: */ 1053: 1054: if (sigaddset(&set, SIGFSTOP) != 0) 1055: { 1056: (*s_etat_processus).erreur_systeme = d_es_processus; 1057: return; 1058: } 1059: 1060: if (sigaddset(&set, SIGFABORT) != 0) 1061: { 1062: (*s_etat_processus).erreur_systeme = d_es_processus; 1063: return; 1064: } 1065: 1066: if (sigaddset(&set, SIGURG) != 0) 1067: { 1068: (*s_etat_processus).erreur_systeme = d_es_processus; 1069: return; 1070: } 1071: 1072: if (pthread_sigmask(SIG_BLOCK, &set, &oldset) != 0) 1073: { 1074: (*s_etat_processus).erreur_systeme = d_es_processus; 1075: return; 1076: } 1077: 1078: if ((s_argument_thread = malloc(sizeof(struct_descripteur_thread))) == NULL) 1079: { 1080: (*s_etat_processus).erreur_systeme = d_es_processus; 1081: return; 1082: } 1083: 1084: if (pipe((*s_argument_thread).pipe_erreurs) != 0) 1085: { 1086: (*s_etat_processus).erreur_systeme = d_es_processus; 1087: return; 1088: } 1089: 1090: if (pipe((*s_argument_thread).pipe_interruptions) != 0) 1091: { 1092: (*s_etat_processus).erreur_systeme = d_es_processus; 1093: return; 1094: } 1095: 1096: if (pipe((*s_argument_thread).pipe_nombre_interruptions_attente) != 0) 1097: { 1098: (*s_etat_processus).erreur_systeme = d_es_processus; 1099: return; 1100: } 1101: 1102: if (pipe((*s_argument_thread).pipe_objets) != 0) 1103: { 1104: (*s_etat_processus).erreur_systeme = d_es_processus; 1105: return; 1106: } 1107: 1108: if (pipe((*s_argument_thread).pipe_acquittement) != 0) 1109: { 1110: (*s_etat_processus).erreur_systeme = d_es_processus; 1111: return; 1112: } 1113: 1114: if (pipe((*s_argument_thread).pipe_nombre_objets_attente) != 0) 1115: { 1116: (*s_etat_processus).erreur_systeme = d_es_processus; 1117: return; 1118: } 1119: 1120: if (pipe((*s_argument_thread).pipe_injections) != 0) 1121: { 1122: (*s_etat_processus).erreur_systeme = d_es_processus; 1123: return; 1124: } 1125: 1126: if (pipe((*s_argument_thread).pipe_nombre_injections) != 0) 1127: { 1128: (*s_etat_processus).erreur_systeme = d_es_processus; 1129: return; 1130: } 1131: 1132: ppid = getpid(); 1133: 1134: /* 1135: * Le mutex suivant permet de copier un contexte propre. 1136: */ 1137: 1138: if (pthread_mutex_lock(&((*s_etat_processus).mutex)) != 0) 1139: { 1140: (*s_etat_processus).erreur_systeme = d_es_processus; 1141: return; 1142: } 1143: 1144: fflush(NULL); 1145: 1146: /* 1147: * On bloque tous les threads concurents pour qu'il n'y ait ni allocation 1148: * de mémoire, ni libération, ni copie d'objet concurrent au fork(). 1149: */ 1150: 1151: sigfillset(&set2); 1152: pthread_sigmask(SIG_BLOCK, &set2, &oldset2); 1153: 1154: verrouillage_threads_concurrents(s_etat_processus); 1155: (*s_argument_thread).pid = fork(); 1156: deverrouillage_threads_concurrents(s_etat_processus); 1157: 1158: pthread_sigmask(SIG_SETMASK, &oldset2, NULL); 1159: sigpending(&set2); 1160: 1161: (*s_argument_thread).thread_pere = pthread_self(); 1162: (*s_argument_thread).processus_detache = d_vrai; 1163: 1164: pthread_mutexattr_init(&attributs_mutex); 1165: pthread_mutexattr_settype(&attributs_mutex, PTHREAD_MUTEX_RECURSIVE); 1166: pthread_mutex_init(&((*s_argument_thread).mutex), &attributs_mutex); 1167: pthread_mutexattr_destroy(&attributs_mutex); 1168: 1169: pthread_mutexattr_init(&attributs_mutex); 1170: pthread_mutexattr_settype(&attributs_mutex, PTHREAD_MUTEX_RECURSIVE); 1171: pthread_mutex_init(&((*s_argument_thread).mutex_nombre_references), 1172: &attributs_mutex); 1173: pthread_mutexattr_destroy(&attributs_mutex); 1174: 1175: if ((*s_argument_thread).pid > 0) 1176: { 1177: /* 1178: * Processus père 1179: */ 1180: 1181: if (variable_partagee == d_vrai) 1182: { 1183: liberation(s_etat_processus, s_copie); 1184: } 1185: 1186: liberation(s_etat_processus, s_objet); 1187: 1188: if ((s_objet = allocation(s_etat_processus, PRC)) == NULL) 1189: { 1190: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire; 1191: return; 1192: } 1193: 1194: (*((struct_processus_fils *) (*s_objet).objet)).thread = 1195: s_argument_thread; 1196: (*(*((struct_processus_fils *) (*s_objet).objet)).thread) 1197: .nombre_objets_dans_pipe = 0; 1198: (*(*((struct_processus_fils *) (*s_objet).objet)).thread) 1199: .nombre_interruptions_dans_pipe = 0; 1200: (*(*((struct_processus_fils *) (*s_objet).objet)).thread) 1201: .nombre_references = 1; 1202: 1203: /* 1204: * On copie l'objet plutôt que le pointeur car cet objet peut être 1205: * accédé depuis deux threads distincts et aboutir à un blocage lors 1206: * d'une copie. 1207: */ 1208: 1209: if ((s_objet_systeme = copie_objet(s_etat_processus, s_objet, 'O')) 1210: == NULL) 1211: { 1212: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire; 1213: return; 1214: } 1215: 1216: if (close((*s_argument_thread).pipe_erreurs[1]) != 0) 1217: { 1218: (*s_etat_processus).erreur_systeme = d_es_processus; 1219: return; 1220: } 1221: 1222: if (close((*s_argument_thread).pipe_interruptions[1]) != 0) 1223: { 1224: (*s_etat_processus).erreur_systeme = d_es_processus; 1225: return; 1226: } 1227: 1228: if (close((*s_argument_thread).pipe_nombre_interruptions_attente[1]) 1229: != 0) 1230: { 1231: (*s_etat_processus).erreur_systeme = d_es_processus; 1232: return; 1233: } 1234: 1235: if (close((*s_argument_thread).pipe_objets[1]) != 0) 1236: { 1237: (*s_etat_processus).erreur_systeme = d_es_processus; 1238: return; 1239: } 1240: 1241: if (close((*s_argument_thread).pipe_nombre_objets_attente[1]) != 0) 1242: { 1243: (*s_etat_processus).erreur_systeme = d_es_processus; 1244: return; 1245: } 1246: 1247: if (close((*s_argument_thread).pipe_injections[0]) != 0) 1248: { 1249: (*s_etat_processus).erreur_systeme = d_es_processus; 1250: return; 1251: } 1252: 1253: if (close((*s_argument_thread).pipe_nombre_injections[0]) != 0) 1254: { 1255: (*s_etat_processus).erreur_systeme = d_es_processus; 1256: return; 1257: } 1258: 1259: if (close((*s_argument_thread).pipe_acquittement[0]) != 0) 1260: { 1261: (*s_etat_processus).erreur_systeme = d_es_processus; 1262: return; 1263: } 1264: 1265: if (pthread_attr_init(&attributs) != 0) 1266: { 1267: (*s_etat_processus).erreur_systeme = d_es_processus; 1268: return; 1269: } 1270: 1271: if (pthread_attr_setdetachstate(&attributs, 1272: PTHREAD_CREATE_DETACHED) != 0) 1273: { 1274: (*s_etat_processus).erreur_systeme = d_es_processus; 1275: return; 1276: } 1277: 1278: # ifndef OS2 1279: # ifndef Cygwin 1280: if (pthread_attr_setschedpolicy(&attributs, SCHED_OTHER) != 0) 1281: { 1282: (*s_etat_processus).erreur_systeme = d_es_processus; 1283: return; 1284: } 1285: 1286: if (pthread_attr_setinheritsched(&attributs, 1287: PTHREAD_EXPLICIT_SCHED) != 0) 1288: { 1289: (*s_etat_processus).erreur_systeme = d_es_processus; 1290: return; 1291: } 1292: 1293: if (pthread_attr_setscope(&attributs, PTHREAD_SCOPE_SYSTEM) != 0) 1294: { 1295: (*s_etat_processus).erreur_systeme = d_es_processus; 1296: return; 1297: } 1298: # endif 1299: # endif 1300: 1301: (*s_argument_thread).s_etat_processus = s_etat_processus; 1302: 1303: if (pthread_create(&thread_surveillance, &attributs, 1304: surveillance_processus, s_argument_thread) != 0) 1305: { 1306: (*s_etat_processus).erreur_systeme = d_es_processus; 1307: return; 1308: } 1309: 1310: if (pthread_attr_destroy(&attributs) != 0) 1311: { 1312: (*s_etat_processus).erreur_systeme = d_es_processus; 1313: return; 1314: } 1315: } 1316: else if ((*s_argument_thread).pid == 0) 1317: { 1318: /* 1319: * Processus fils 1320: */ 1321: 1322: # ifdef _BROKEN_SIGINFO 1323: liberation_fifos_signaux(s_etat_processus); 1324: creation_fifos_signaux(s_etat_processus); 1325: # endif 1326: 1327: if ((*s_etat_processus).debug == d_vrai) 1328: if (((*s_etat_processus).type_debug & 1329: d_debug_processus) != 0) 1330: { 1331: if ((*s_etat_processus).langue == 'F') 1332: { 1333: printf("[%d] Lancement du processus fils %d de %d\n", 1334: (int) getpid(), (int) getpid(), (int) ppid); 1335: } 1336: else 1337: { 1338: printf("[%d] Start child process %d from %d\n", (int) getpid(), 1339: (int) getpid(), (int) ppid); 1340: } 1341: 1342: fflush(stdout); 1343: } 1344: 1345: # ifndef SEMAPHORES_NOMMES 1346: sem_post(&semaphore_gestionnaires_signaux); 1347: sem_destroy(&semaphore_gestionnaires_signaux); 1348: sem_init(&semaphore_gestionnaires_signaux, 0, 0); 1349: # else 1350: sem_post(semaphore_gestionnaires_signaux); 1351: sem_destroy2(semaphore_gestionnaires_signaux, 1352: sem_gestionnaires_signaux); 1353: 1354: if ((semaphore_gestionnaires_signaux = sem_init2(0, 1355: sem_gestionnaires_signaux)) == SEM_FAILED) 1356: { 1357: (*s_etat_processus).erreur_systeme = d_es_processus; 1358: } 1359: # endif 1360: 1361: # ifndef SEMAPHORES_NOMMES 1362: sem_post(&semaphore_liste_threads); 1363: sem_destroy(&semaphore_liste_threads); 1364: sem_init(&semaphore_liste_threads, 0, 1); 1365: # else 1366: sem_post(semaphore_liste_threads); 1367: sem_destroy2(semaphore_liste_threads, sem_liste_threads); 1368: 1369: if ((semaphore_liste_threads = sem_init2(1, 1370: sem_liste_threads)) == SEM_FAILED) 1371: { 1372: (*s_etat_processus).erreur_systeme = d_es_processus; 1373: } 1374: # endif 1375: 1376: # ifndef SEMAPHORES_NOMMES 1377: sem_destroy(&semaphore_gestionnaires_signaux_atomique); 1378: sem_init(&semaphore_gestionnaires_signaux_atomique, 0, 1); 1379: sem_trywait(&((*s_etat_processus).semaphore_fork)); 1380: # else 1381: sem_destroy2(semaphore_gestionnaires_signaux_atomique, 1382: sem_gestionnaires_signaux_atomique); 1383: 1384: if ((semaphore_gestionnaires_signaux_atomique = sem_init2(1, 1385: sem_gestionnaires_signaux_atomique)) == SEM_FAILED) 1386: { 1387: (*s_etat_processus).erreur_systeme = d_es_processus; 1388: } 1389: 1390: sem_trywait((*s_etat_processus).semaphore_fork); 1391: # endif 1392: 1393: # ifndef SEMAPHORES_NOMMES 1394: if (pthread_setspecific(semaphore_fork_processus_courant, 1395: &((*s_etat_processus).semaphore_fork)) != 0) 1396: # else 1397: if (pthread_setspecific(semaphore_fork_processus_courant, 1398: (*s_etat_processus).semaphore_fork) != 0) 1399: # endif 1400: { 1401: (*s_etat_processus).erreur_systeme = d_es_processus; 1402: } 1403: 1404: if (close((*s_argument_thread).pipe_erreurs[0]) != 0) 1405: { 1406: (*s_etat_processus).erreur_systeme = d_es_processus; 1407: } 1408: else if (close((*s_argument_thread).pipe_interruptions[0]) != 0) 1409: { 1410: (*s_etat_processus).erreur_systeme = d_es_processus; 1411: } 1412: else if (close((*s_argument_thread) 1413: .pipe_nombre_interruptions_attente[0]) != 0) 1414: { 1415: (*s_etat_processus).erreur_systeme = d_es_processus; 1416: } 1417: else if (close((*s_argument_thread).pipe_objets[0]) != 0) 1418: { 1419: (*s_etat_processus).erreur_systeme = d_es_processus; 1420: } 1421: else if (close((*s_argument_thread).pipe_nombre_objets_attente[0]) != 0) 1422: { 1423: (*s_etat_processus).erreur_systeme = d_es_processus; 1424: } 1425: else if (close((*s_argument_thread).pipe_injections[1]) != 0) 1426: { 1427: (*s_etat_processus).erreur_systeme = d_es_processus; 1428: } 1429: else if (close((*s_argument_thread).pipe_nombre_injections[1]) != 0) 1430: { 1431: (*s_etat_processus).erreur_systeme = d_es_processus; 1432: } 1433: else if (close((*s_argument_thread).pipe_acquittement[1]) != 0) 1434: { 1435: (*s_etat_processus).erreur_systeme = d_es_processus; 1436: } 1437: 1438: if ((*s_etat_processus).debug == d_vrai) 1439: if (((*s_etat_processus).type_debug & 1440: d_debug_processus) != 0) 1441: { 1442: if ((*s_etat_processus).langue == 'F') 1443: { 1444: printf("[%d] Libération des objets du processus père\n", 1445: (int) getpid()); 1446: } 1447: else 1448: { 1449: printf("[%d] Freeing parent process memory\n", getpid()); 1450: } 1451: 1452: fflush(stdout); 1453: } 1454: 1455: l_element_courant = (*s_etat_processus).liste_mutexes; 1456: while(l_element_courant != NULL) 1457: { 1458: pthread_mutex_trylock(&((*((struct_mutex *) (*(*l_element_courant) 1459: .donnee).objet)).mutex)); 1460: pthread_mutex_unlock(&((*((struct_mutex *) (*(*l_element_courant) 1461: .donnee).objet)).mutex)); 1462: pthread_mutex_destroy(&((*((struct_mutex *) (*(*l_element_courant) 1463: .donnee).objet)).mutex)); 1464: 1465: liberation(s_etat_processus, (*l_element_courant).donnee); 1466: l_element_suivant = (*l_element_courant).suivant; 1467: free(l_element_courant); 1468: l_element_courant = l_element_suivant; 1469: } 1470: 1471: (*s_etat_processus).liste_mutexes = NULL; 1472: 1473: liberation_threads(s_etat_processus); 1474: 1475: (*(*s_etat_processus).s_liste_variables_partagees) 1476: .table = NULL; 1477: (*(*s_etat_processus).s_liste_variables_partagees) 1478: .nombre_variables = 0; 1479: (*(*s_etat_processus).s_liste_variables_partagees) 1480: .nombre_variables_allouees = 0; 1481: 1482: insertion_thread(s_etat_processus, d_vrai); 1483: 1484: // Envoi d'une donnée pour signaler le démarrage du processus au thread 1485: // de surveillance. 1486: 1487: if (write_atomic(s_etat_processus, 1488: (*s_argument_thread).pipe_nombre_objets_attente[1], 1489: "-", sizeof(unsigned char)) != sizeof(unsigned char)) 1490: { 1491: pthread_mutex_unlock(&((*s_etat_processus).mutex)); 1492: (*s_etat_processus).erreur_systeme = d_es_processus; 1493: 1494: pid_final = -2; 1495: 1496: while((longueur_ecriture = write_atomic(s_etat_processus, 1497: (*s_argument_thread).pipe_nombre_interruptions_attente[1], 1498: &pid_final, sizeof(pid_final))) != sizeof(pid_final)) 1499: { 1500: if (longueur_ecriture == -1) 1501: { 1502: break; 1503: } 1504: } 1505: 1506: while((longueur_ecriture = write_atomic(s_etat_processus, 1507: (*s_argument_thread).pipe_nombre_objets_attente[1], 1508: &pid_final, sizeof(pid_final))) != sizeof(pid_final)) 1509: { 1510: if (longueur_ecriture == -1) 1511: { 1512: break; 1513: } 1514: } 1515: 1516: # ifdef _BROKEN_SIGINFO 1517: destruction_fifos_signaux(s_etat_processus); 1518: # endif 1519: 1520: BUG(1, uprintf("Process management error line %d\n", __LINE__)); 1521: exit(EXIT_FAILURE); 1522: } 1523: 1524: if (pthread_mutex_unlock(&((*s_etat_processus).mutex)) != 0) 1525: { 1526: (*s_etat_processus).erreur_systeme = d_es_processus; 1527: 1528: pid_final = -2; 1529: 1530: while((longueur_ecriture = write_atomic(s_etat_processus, 1531: (*s_argument_thread).pipe_nombre_interruptions_attente[1], 1532: &pid_final, sizeof(pid_final))) != sizeof(pid_final)) 1533: { 1534: if (longueur_ecriture == -1) 1535: { 1536: break; 1537: } 1538: } 1539: 1540: while((longueur_ecriture = write_atomic(s_etat_processus, 1541: (*s_argument_thread).pipe_nombre_objets_attente[1], 1542: &pid_final, sizeof(pid_final))) != sizeof(pid_final)) 1543: { 1544: if (longueur_ecriture == -1) 1545: { 1546: break; 1547: } 1548: } 1549: 1550: # ifdef _BROKEN_SIGINFO 1551: destruction_fifos_signaux(s_etat_processus); 1552: # endif 1553: 1554: BUG(1, uprintf("Process management error line %d\n", __LINE__)); 1555: exit(EXIT_FAILURE); 1556: } 1557: 1558: pthread_mutex_trylock(&((*s_etat_processus).protection_liste_mutexes)); 1559: 1560: if (pthread_mutex_unlock(&((*s_etat_processus) 1561: .protection_liste_mutexes)) != 0) 1562: { 1563: (*s_etat_processus).erreur_systeme = d_es_processus; 1564: 1565: pid_final = -2; 1566: 1567: while((longueur_ecriture = write_atomic(s_etat_processus, 1568: (*s_argument_thread).pipe_nombre_interruptions_attente[1], 1569: &pid_final, sizeof(pid_final))) != sizeof(pid_final)) 1570: { 1571: if (longueur_ecriture == -1) 1572: { 1573: break; 1574: } 1575: } 1576: 1577: while((longueur_ecriture = write_atomic(s_etat_processus, 1578: (*s_argument_thread).pipe_nombre_objets_attente[1], 1579: &pid_final, sizeof(pid_final))) != sizeof(pid_final)) 1580: { 1581: if (longueur_ecriture == -1) 1582: { 1583: break; 1584: } 1585: } 1586: 1587: # ifdef _BROKEN_SIGINFO 1588: destruction_fifos_signaux(s_etat_processus); 1589: # endif 1590: 1591: BUG(1, uprintf("Process management error line %d\n", __LINE__)); 1592: exit(EXIT_FAILURE); 1593: } 1594: 1595: if ((*s_etat_processus).evaluation_expression_compilee == 'N') 1596: { 1597: free((*s_etat_processus).instruction_courante); 1598: (*s_etat_processus).instruction_courante = NULL; 1599: } 1600: 1601: (*s_etat_processus).var_volatile_processus_pere = 0; 1602: (*s_etat_processus).var_volatile_processus_racine = 0; 1603: 1604: // On réinitialise toutes les interruptions. 1605: 1606: (*s_etat_processus).traitement_interruption = 'N'; 1607: (*s_etat_processus).traitement_interruptible = 'Y'; 1608: (*s_etat_processus).nombre_interruptions_en_queue = 0; 1609: (*s_etat_processus).nombre_interruptions_non_affectees = 0; 1610: (*s_etat_processus).processus_detache = d_vrai; 1611: 1612: liberation(s_etat_processus, (*s_etat_processus).at_exit); 1613: (*s_etat_processus).at_exit = NULL; 1614: liberation(s_etat_processus, (*s_etat_processus).at_poke); 1615: (*s_etat_processus).at_poke = NULL; 1616: (*s_etat_processus).traitement_at_poke = 'N'; 1617: 1618: for(i = 0; i < d_NOMBRE_INTERRUPTIONS; i++) 1619: { 1620: liberation(s_etat_processus, 1621: (*s_etat_processus).corps_interruptions[i]); 1622: 1623: (*s_etat_processus).corps_interruptions[i] = NULL; 1624: (*s_etat_processus).masque_interruptions[i] = 'N'; 1625: (*s_etat_processus).queue_interruptions[i] = 0; 1626: 1627: l_element_courant = (*s_etat_processus) 1628: .pile_origine_interruptions[i]; 1629: 1630: while(l_element_courant != NULL) 1631: { 1632: l_element_suivant = (*l_element_courant).suivant; 1633: liberation(s_etat_processus, (*l_element_courant).donnee); 1634: free(l_element_courant); 1635: l_element_courant = l_element_suivant; 1636: } 1637: 1638: (*s_etat_processus).pile_origine_interruptions[i] = NULL; 1639: } 1640: 1641: /* 1642: * On bloque l'exécution du processus fils jusqu'à ce que 1643: * le père ait renseigné correctement la pile des processus. 1644: * Dans le cas contraire, on pourrait essayer de traiter 1645: * un RECV sur un système chargé avant que cette pile soit 1646: * renseignée. 1647: */ 1648: 1649: if (sigpending(&set) != 0) 1650: { 1651: (*s_etat_processus).erreur_systeme = d_es_processus; 1652: } 1653: else if (sigismember(&set, SIGSTART) == 0) 1654: { 1655: while(sigismember(&set, SIGSTART) == 0) 1656: { 1657: if (sigpending(&set) != 0) 1658: { 1659: (*s_etat_processus).erreur_systeme = d_es_processus; 1660: } 1661: 1662: nanosleep(&attente, NULL); 1663: } 1664: } 1665: 1666: (*s_etat_processus).niveau_initial = (*s_etat_processus).niveau_courant; 1667: (*s_etat_processus).presence_pipes = d_vrai; 1668: (*s_etat_processus).debug_programme = d_faux; 1669: (*s_etat_processus).pipe_donnees = (*s_argument_thread).pipe_objets[1]; 1670: (*s_etat_processus).pipe_nombre_objets_attente = (*s_argument_thread) 1671: .pipe_nombre_objets_attente[1]; 1672: (*s_etat_processus).pipe_interruptions = (*s_argument_thread) 1673: .pipe_interruptions[1]; 1674: (*s_etat_processus).pipe_nombre_interruptions_attente = 1675: (*s_argument_thread).pipe_nombre_interruptions_attente[1]; 1676: (*s_etat_processus).pipe_injections = 1677: (*s_argument_thread).pipe_injections[0]; 1678: (*s_etat_processus).pipe_nombre_injections = 1679: (*s_argument_thread).pipe_nombre_injections[0]; 1680: (*s_etat_processus).pipe_acquittement = 1681: (*s_argument_thread).pipe_acquittement[0]; 1682: (*s_etat_processus).nombre_objets_injectes = 0; 1683: (*s_etat_processus).nombre_objets_envoyes_non_lus = 0; 1684: (*s_etat_processus).temps_maximal_cpu = 0; 1685: (*s_etat_processus).presence_fusible = d_faux; 1686: (*s_etat_processus).thread_fusible = 0; 1687: (*s_etat_processus).pid_erreur_processus_fils = getpid(); 1688: 1689: if ((*s_etat_processus).profilage == d_vrai) 1690: { 1691: liberation_profil(s_etat_processus); 1692: } 1693: 1694: (*s_etat_processus).pile_profilage = NULL; 1695: 1696: if ((*s_etat_processus).generateur_aleatoire != NULL) 1697: { 1698: liberation_generateur_aleatoire(s_etat_processus); 1699: } 1700: 1701: (*s_etat_processus).generateur_aleatoire = NULL; 1702: 1703: if ((*s_etat_processus).instruction_derniere_erreur != NULL) 1704: { 1705: free((*s_etat_processus).instruction_derniere_erreur); 1706: (*s_etat_processus).instruction_derniere_erreur = NULL; 1707: } 1708: 1709: /* 1710: * Initialisation de la pile des processus. Cette pile est effacée 1711: * par liberation_threads(). 1712: */ 1713: 1714: if (pthread_mutex_lock(&((*s_etat_processus).mutex)) != 0) 1715: { 1716: (*s_etat_processus).erreur_systeme = d_es; 1717: 1718: pid_final = -2; 1719: 1720: while((longueur_ecriture = write_atomic(s_etat_processus, 1721: (*s_argument_thread).pipe_nombre_interruptions_attente[1], 1722: &pid_final, sizeof(pid_final))) != sizeof(pid_final)) 1723: { 1724: if (longueur_ecriture == -1) 1725: { 1726: break; 1727: } 1728: } 1729: 1730: while((longueur_ecriture = write_atomic(s_etat_processus, 1731: (*s_argument_thread).pipe_nombre_objets_attente[1], 1732: &pid_final, sizeof(pid_final))) != sizeof(pid_final)) 1733: { 1734: if (longueur_ecriture == -1) 1735: { 1736: break; 1737: } 1738: } 1739: 1740: # ifdef _BROKEN_SIGINFO 1741: destruction_fifos_signaux(s_etat_processus); 1742: # endif 1743: 1744: BUG(1, uprintf("Process management error line %d\n", __LINE__)); 1745: exit(EXIT_FAILURE); 1746: } 1747: 1748: l_element_courant = (struct_liste_chainee *) 1749: (*s_etat_processus).l_base_pile_processus; 1750: 1751: while(l_element_courant != NULL) 1752: { 1753: s_argument_thread2 = (struct_descripteur_thread *) 1754: (*((struct_processus_fils *) (*(*l_element_courant).donnee) 1755: .objet)).thread; 1756: 1757: (*s_argument_thread2).nombre_references--; 1758: 1759: BUG((*s_argument_thread2).nombre_references < 0, 1760: # ifdef _BROKEN_SIGINFO 1761: destruction_fifos_signaux(s_etat_processus), 1762: # endif 1763: printf("(*s_argument_thread2).nombre_references = %d\n", 1764: (int) (*s_argument_thread2).nombre_references)); 1765: 1766: if ((*s_argument_thread2).nombre_references == 0) 1767: { 1768: close((*s_argument_thread2).pipe_objets[0]); 1769: close((*s_argument_thread2).pipe_acquittement[1]); 1770: close((*s_argument_thread2).pipe_injections[1]); 1771: close((*s_argument_thread2).pipe_nombre_injections[1]); 1772: close((*s_argument_thread2).pipe_nombre_objets_attente[0]); 1773: close((*s_argument_thread2).pipe_interruptions[0]); 1774: close((*s_argument_thread2) 1775: .pipe_nombre_interruptions_attente[0]); 1776: 1777: pthread_mutex_destroy(&((*s_argument_thread2).mutex)); 1778: 1779: if ((*s_argument_thread2).processus_detache == d_faux) 1780: { 1781: if ((*s_argument_thread2).destruction_objet == d_vrai) 1782: { 1783: liberation(s_etat_processus, 1784: (*s_argument_thread2).argument); 1785: } 1786: } 1787: 1788: free(s_argument_thread2); 1789: free((*(*l_element_courant).donnee).objet); 1790: free((*l_element_courant).donnee); 1791: } 1792: 1793: l_element_suivant = (*l_element_courant).suivant; 1794: free((struct_liste_chainee *) l_element_courant); 1795: l_element_courant = l_element_suivant; 1796: } 1797: 1798: (*s_etat_processus).l_base_pile_processus = NULL; 1799: 1800: if (pthread_mutex_unlock(&((*s_etat_processus).mutex)) != 0) 1801: { 1802: (*s_etat_processus).erreur_systeme = d_es; 1803: 1804: pid_final = -2; 1805: 1806: while((longueur_ecriture = write_atomic(s_etat_processus, 1807: (*s_argument_thread).pipe_nombre_interruptions_attente[1], 1808: &pid_final, sizeof(pid_final))) != sizeof(pid_final)) 1809: { 1810: if (longueur_ecriture == -1) 1811: { 1812: break; 1813: } 1814: } 1815: 1816: while((longueur_ecriture = write_atomic(s_etat_processus, 1817: (*s_argument_thread).pipe_nombre_objets_attente[1], 1818: &pid_final, sizeof(pid_final))) != sizeof(pid_final)) 1819: { 1820: if (longueur_ecriture == -1) 1821: { 1822: break; 1823: } 1824: } 1825: 1826: # ifdef _BROKEN_SIGINFO 1827: destruction_fifos_signaux(s_etat_processus); 1828: # endif 1829: 1830: BUG(1, uprintf("Process management error line %d\n", __LINE__)); 1831: exit(EXIT_FAILURE); 1832: } 1833: 1834: /* 1835: * Initialisation de la pile système 1836: */ 1837: 1838: l_element_courant = (struct_liste_chainee *) 1839: (*s_etat_processus).l_base_pile_systeme; 1840: while(l_element_courant != NULL) 1841: { 1842: l_element_suivant = (struct_liste_chainee *) 1843: (*((struct_liste_pile_systeme *) 1844: l_element_courant)).suivant; 1845: 1846: liberation(s_etat_processus, (*((struct_liste_pile_systeme *) 1847: l_element_courant)).indice_boucle); 1848: liberation(s_etat_processus, (*((struct_liste_pile_systeme *) 1849: l_element_courant)).limite_indice_boucle); 1850: liberation(s_etat_processus, (*((struct_liste_pile_systeme *) 1851: l_element_courant)).objet_de_test); 1852: 1853: if ((*((struct_liste_pile_systeme *) l_element_courant)) 1854: .nom_variable != NULL) 1855: { 1856: free((*((struct_liste_pile_systeme *) 1857: l_element_courant)).nom_variable); 1858: } 1859: 1860: free((struct_liste_pile_systeme *) l_element_courant); 1861: 1862: l_element_courant = l_element_suivant; 1863: } 1864: 1865: (*s_etat_processus).l_base_pile_systeme = NULL; 1866: (*s_etat_processus).hauteur_pile_systeme = 0; 1867: 1868: empilement_pile_systeme(s_etat_processus); 1869: 1870: if ((*s_etat_processus).erreur_systeme != d_es) 1871: { 1872: pid_final = -2; 1873: 1874: while((longueur_ecriture = write_atomic(s_etat_processus, 1875: (*s_argument_thread).pipe_nombre_interruptions_attente[1], 1876: &pid_final, sizeof(pid_final))) != sizeof(pid_final)) 1877: { 1878: if (longueur_ecriture == -1) 1879: { 1880: break; 1881: } 1882: } 1883: 1884: while((longueur_ecriture = write_atomic(s_etat_processus, 1885: (*s_argument_thread).pipe_nombre_objets_attente[1], 1886: &pid_final, sizeof(pid_final))) != sizeof(pid_final)) 1887: { 1888: if (longueur_ecriture == -1) 1889: { 1890: break; 1891: } 1892: } 1893: 1894: # ifdef _BROKEN_SIGINFO 1895: destruction_fifos_signaux(s_etat_processus); 1896: # endif 1897: 1898: BUG(1, uprintf("Process management error line %d\n", __LINE__)); 1899: exit(EXIT_FAILURE); 1900: } 1901: 1902: (*(*s_etat_processus).l_base_pile_systeme).retour_definition = 'Y'; 1903: 1904: l_element_courant = (struct_liste_chainee *) 1905: (*s_etat_processus).s_marques; 1906: 1907: while(l_element_courant != NULL) 1908: { 1909: free((*((struct_marque *) l_element_courant)).label); 1910: free((*((struct_marque *) l_element_courant)).position); 1911: l_element_suivant = (struct_liste_chainee *) 1912: (*((struct_marque *) l_element_courant)).suivant; 1913: free((struct_marque *) l_element_courant); 1914: l_element_courant = l_element_suivant; 1915: } 1916: 1917: (*s_etat_processus).s_marques = NULL; 1918: 1919: /* 1920: * On empile deux valeurs retour_definition pour pouvoir récupérer 1921: * les variables dans le cas d'un programme compilé. 1922: */ 1923: 1924: empilement_pile_systeme(s_etat_processus); 1925: 1926: if ((*s_etat_processus).erreur_systeme != d_es) 1927: { 1928: pid_final = -2; 1929: 1930: while((longueur_ecriture = write_atomic(s_etat_processus, 1931: (*s_argument_thread).pipe_nombre_interruptions_attente[1], 1932: &pid_final, sizeof(pid_final))) != sizeof(pid_final)) 1933: { 1934: if (longueur_ecriture == -1) 1935: { 1936: break; 1937: } 1938: } 1939: 1940: while((longueur_ecriture = write_atomic(s_etat_processus, 1941: (*s_argument_thread).pipe_nombre_objets_attente[1], 1942: &pid_final, sizeof(pid_final))) != sizeof(pid_final)) 1943: { 1944: if (longueur_ecriture == -1) 1945: { 1946: break; 1947: } 1948: } 1949: 1950: # ifdef _BROKEN_SIGINFO 1951: destruction_fifos_signaux(s_etat_processus); 1952: # endif 1953: 1954: BUG(1, uprintf("Process management error line %d\n", __LINE__)); 1955: exit(EXIT_FAILURE); 1956: } 1957: 1958: (*(*s_etat_processus).l_base_pile_systeme).retour_definition = 'Y'; 1959: 1960: /* 1961: * Destruction des sorties graphiques et PostScript 1962: */ 1963: 1964: while((*s_etat_processus).fichiers_graphiques != NULL) 1965: { 1966: free((*(*s_etat_processus).fichiers_graphiques).nom); 1967: 1968: if ((*(*s_etat_processus).fichiers_graphiques).legende != NULL) 1969: { 1970: free((*(*s_etat_processus).fichiers_graphiques).legende); 1971: } 1972: 1973: l_element_precedent = (void *) (*s_etat_processus) 1974: .fichiers_graphiques; 1975: (*s_etat_processus).fichiers_graphiques = 1976: (*(*s_etat_processus).fichiers_graphiques).suivant; 1977: free(l_element_precedent); 1978: } 1979: 1980: if ((*s_etat_processus).entree_standard != NULL) 1981: { 1982: pclose((*s_etat_processus).entree_standard); 1983: (*s_etat_processus).entree_standard = NULL; 1984: } 1985: 1986: (*s_etat_processus).requete_nouveau_plan = d_vrai; 1987: (*s_etat_processus).mise_a_jour_trace_requise = d_faux; 1988: 1989: if ((*s_etat_processus).nom_fichier_impression != NULL) 1990: { 1991: free((*s_etat_processus).nom_fichier_impression); 1992: (*s_etat_processus).nom_fichier_impression = NULL; 1993: } 1994: 1995: /* 1996: * Destruction des piles de fichiers 1997: */ 1998: 1999: l_element_courant = (*s_etat_processus).s_fichiers; 2000: 2001: while(l_element_courant != NULL) 2002: { 2003: l_element_suivant = (*l_element_courant).suivant; 2004: 2005: fclose((*((struct_descripteur_fichier *) 2006: (*l_element_courant).donnee)).descripteur_c); 2007: 2008: if ((*((struct_descripteur_fichier *) 2009: (*l_element_courant).donnee)).type != 'C') 2010: { 2011: sqlite3_close((*((struct_descripteur_fichier *) 2012: (*l_element_courant).donnee)).descripteur_sqlite); 2013: } 2014: 2015: free((*((struct_descripteur_fichier *) (*l_element_courant) 2016: .donnee)).nom); 2017: free((struct_descripteur_fichier *) (*l_element_courant).donnee); 2018: free(l_element_courant); 2019: 2020: l_element_courant = l_element_suivant; 2021: } 2022: 2023: /* 2024: * Destruction des piles de connecteurs SQL 2025: */ 2026: 2027: /* 2028: ================================================================================ 2029: À noter : on ne ferme pas la connexion car la conséquence immédiate est 2030: une destruction de l'objet pour le processus père. 2031: ================================================================================ 2032: */ 2033: 2034: l_element_courant = (*s_etat_processus).s_connecteurs_sql; 2035: 2036: while(l_element_courant != NULL) 2037: { 2038: l_element_suivant = (*l_element_courant).suivant; 2039: 2040: // sqlclose((*l_element_courant).donnee); 2041: liberation(s_etat_processus, (*l_element_courant).donnee); 2042: l_element_courant = l_element_suivant; 2043: } 2044: 2045: (*s_etat_processus).s_connecteurs_sql = NULL; 2046: 2047: /* 2048: * On ne détruit pas les sockets car il faut utiliser DETACH 2049: * pour traiter plusieurs connexions simultanées sur les sockets 2050: */ 2051: 2052: (*s_etat_processus).s_fichiers = NULL; 2053: 2054: if (pthread_sigmask(SIG_SETMASK, &oldset, NULL) != 0) 2055: { 2056: (*s_etat_processus).erreur_systeme = d_es_processus; 2057: } 2058: 2059: sigpending(&set); 2060: 2061: if ((*s_etat_processus).debug == d_vrai) 2062: { 2063: if (((*s_etat_processus).type_debug & d_debug_processus) 2064: != 0) 2065: { 2066: if ((*s_etat_processus).langue == 'F') 2067: { 2068: printf("[%d] Évaluation de l'objet détaché\n", getpid()); 2069: } 2070: else 2071: { 2072: printf("[%d] Évaluation of detached object\n", getpid()); 2073: } 2074: } 2075: } 2076: 2077: if ((*s_etat_processus).erreur_systeme == d_es) 2078: { 2079: if (variable_partagee == d_faux) 2080: { 2081: if (evaluation(s_etat_processus, s_objet, 'E') == d_erreur) 2082: { 2083: if (((*s_etat_processus).erreur_execution == d_ex) && 2084: ((*s_etat_processus).erreur_systeme == d_es)) 2085: { 2086: (*s_etat_processus).erreur_execution = 2087: d_ex_erreur_evaluation; 2088: } 2089: } 2090: else 2091: { 2092: if (((*s_etat_processus).var_volatile_alarme == 0) 2093: && ((*s_etat_processus).arret_depuis_abort == 0) 2094: && ((*s_etat_processus).at_exit != NULL)) 2095: { 2096: (*s_etat_processus).var_volatile_requete_arret = 0; 2097: 2098: if (evaluation(s_etat_processus, 2099: (*s_etat_processus).at_exit, 'E') == d_erreur) 2100: { 2101: (*s_etat_processus).erreur_execution = 2102: d_ex_erreur_evaluation; 2103: } 2104: } 2105: } 2106: } 2107: else 2108: { 2109: if (evaluation(s_etat_processus, s_copie, 'E') == d_erreur) 2110: { 2111: if (((*s_etat_processus).erreur_execution == d_ex) && 2112: ((*s_etat_processus).erreur_systeme == d_es)) 2113: { 2114: (*s_etat_processus).erreur_execution = 2115: d_ex_erreur_evaluation; 2116: } 2117: } 2118: else 2119: { 2120: if ((*s_etat_processus).at_exit != NULL) 2121: { 2122: (*s_etat_processus).var_volatile_requete_arret = 0; 2123: 2124: if (evaluation(s_etat_processus, 2125: (*s_etat_processus).at_exit, 'E') == d_erreur) 2126: { 2127: (*s_etat_processus).erreur_execution = 2128: d_ex_erreur_evaluation; 2129: } 2130: } 2131: } 2132: 2133: liberation(s_etat_processus, s_copie); 2134: } 2135: } 2136: 2137: liberation(s_etat_processus, (*s_etat_processus).at_exit); 2138: liberation(s_etat_processus, (*s_etat_processus).at_poke); 2139: 2140: l_element_courant = (*s_etat_processus).liste_mutexes; 2141: while(l_element_courant != NULL) 2142: { 2143: pthread_mutex_trylock(&((*((struct_mutex *) 2144: (*(*l_element_courant).donnee).objet)).mutex)); 2145: pthread_mutex_unlock(&((*((struct_mutex *) 2146: (*(*l_element_courant).donnee).objet)).mutex)); 2147: pthread_mutex_destroy(&((*((struct_mutex *) 2148: (*(*l_element_courant).donnee).objet)).mutex)); 2149: 2150: liberation(s_etat_processus, (*l_element_courant).donnee); 2151: l_element_suivant = (*l_element_courant).suivant; 2152: free(l_element_courant); 2153: l_element_courant = l_element_suivant; 2154: } 2155: 2156: if ((*s_etat_processus).presence_fusible == d_vrai) 2157: { 2158: pthread_cancel((*s_etat_processus).thread_fusible); 2159: } 2160: 2161: pid_final = -2; 2162: 2163: while((longueur_ecriture = write_atomic(s_etat_processus, 2164: (*s_argument_thread).pipe_nombre_interruptions_attente[1], 2165: &pid_final, sizeof(pid_final))) != sizeof(pid_final)) 2166: { 2167: if (longueur_ecriture == -1) 2168: { 2169: break; 2170: } 2171: } 2172: 2173: while((longueur_ecriture = write_atomic(s_etat_processus, 2174: (*s_argument_thread).pipe_nombre_objets_attente[1], 2175: &pid_final, sizeof(pid_final))) != sizeof(pid_final)) 2176: { 2177: if (longueur_ecriture == -1) 2178: { 2179: break; 2180: } 2181: } 2182: 2183: if ((*s_etat_processus).var_volatile_processus_pere != 0) 2184: { 2185: // Racine des processus atteinte 2186: 2187: erreur = d_ex; 2188: 2189: while((longueur_ecriture = write_atomic(s_etat_processus, 2190: (*s_argument_thread).pipe_erreurs[1], &erreur, 2191: sizeof((*s_etat_processus).erreur_execution))) != 2192: sizeof((*s_etat_processus).erreur_execution)) 2193: { 2194: if (longueur_ecriture == -1) 2195: { 2196: break; 2197: } 2198: } 2199: } 2200: else 2201: { 2202: while((longueur_ecriture = write_atomic(s_etat_processus, 2203: (*s_argument_thread).pipe_erreurs[1], 2204: &((*s_etat_processus).erreur_execution), 2205: sizeof((*s_etat_processus).erreur_execution))) != 2206: sizeof((*s_etat_processus).erreur_execution)) 2207: { 2208: if (longueur_ecriture == -1) 2209: { 2210: break; 2211: } 2212: } 2213: } 2214: 2215: if ((*s_etat_processus).var_volatile_processus_pere != 0) 2216: { 2217: // Racine des processus atteinte 2218: 2219: erreur = d_es; 2220: 2221: while((longueur_ecriture = write_atomic(s_etat_processus, 2222: (*s_argument_thread).pipe_erreurs[1], &erreur, 2223: sizeof((*s_etat_processus).erreur_systeme))) != 2224: sizeof((*s_etat_processus).erreur_systeme)) 2225: { 2226: if (longueur_ecriture == -1) 2227: { 2228: break; 2229: } 2230: } 2231: } 2232: else 2233: { 2234: while((longueur_ecriture = write_atomic(s_etat_processus, 2235: (*s_argument_thread).pipe_erreurs[1], 2236: &((*s_etat_processus).erreur_systeme), 2237: sizeof((*s_etat_processus).erreur_systeme))) != 2238: sizeof((*s_etat_processus).erreur_systeme)) 2239: { 2240: if (longueur_ecriture == -1) 2241: { 2242: break; 2243: } 2244: } 2245: } 2246: 2247: if ((*s_etat_processus).pid_erreur_processus_fils == 0) 2248: { 2249: while((longueur_ecriture = write_atomic(s_etat_processus, 2250: (*s_argument_thread).pipe_erreurs[1], 2251: &ppid, sizeof(ppid))) != sizeof(ppid)) 2252: { 2253: if (longueur_ecriture == -1) 2254: { 2255: break; 2256: } 2257: } 2258: } 2259: else 2260: { 2261: while((longueur_ecriture = write_atomic(s_etat_processus, 2262: (*s_argument_thread).pipe_erreurs[1], 2263: &((*s_etat_processus).pid_erreur_processus_fils), 2264: sizeof((*s_etat_processus).pid_erreur_processus_fils))) != 2265: sizeof((*s_etat_processus).pid_erreur_processus_fils)) 2266: { 2267: if (longueur_ecriture == -1) 2268: { 2269: break; 2270: } 2271: } 2272: } 2273: 2274: close((*s_argument_thread).pipe_erreurs[1]); 2275: close((*s_argument_thread).pipe_interruptions[1]); 2276: close((*s_argument_thread).pipe_nombre_interruptions_attente[1]); 2277: close((*s_argument_thread).pipe_objets[1]); 2278: close((*s_argument_thread).pipe_nombre_objets_attente[1]); 2279: close((*s_argument_thread).pipe_injections[0]); 2280: close((*s_argument_thread).pipe_nombre_injections[0]); 2281: close((*s_argument_thread).pipe_acquittement[0]); 2282: 2283: l_element_courant = (*s_etat_processus).s_fichiers; 2284: 2285: while(l_element_courant != NULL) 2286: { 2287: l_element_suivant = (*l_element_courant).suivant; 2288: 2289: fclose((*((struct_descripteur_fichier *) 2290: (*l_element_courant).donnee)).descripteur_c); 2291: 2292: if ((*((struct_descripteur_fichier *) 2293: (*l_element_courant).donnee)).type != 'C') 2294: { 2295: sqlite3_close((*((struct_descripteur_fichier *) 2296: (*l_element_courant).donnee)).descripteur_sqlite); 2297: } 2298: 2299: if (((*((struct_descripteur_fichier *) (*l_element_courant) 2300: .donnee)).pid == getpid()) && 2301: (pthread_equal((*((struct_descripteur_fichier *) 2302: (*l_element_courant).donnee)).tid, pthread_self()) != 0)) 2303: { 2304: if ((*((struct_descripteur_fichier *) (*l_element_courant) 2305: .donnee)).effacement == 'Y') 2306: { 2307: unlink((*((struct_descripteur_fichier *) 2308: (*l_element_courant).donnee)).nom); 2309: } 2310: } 2311: 2312: free((*((struct_descripteur_fichier *) (*l_element_courant) 2313: .donnee)).nom); 2314: free((struct_descripteur_fichier *) (*l_element_courant).donnee); 2315: free(l_element_courant); 2316: 2317: l_element_courant = l_element_suivant; 2318: } 2319: 2320: pthread_mutex_lock(&((*s_etat_processus).mutex)); 2321: 2322: l_element_courant = (struct_liste_chainee *) 2323: (*s_etat_processus).l_base_pile_processus; 2324: 2325: while(l_element_courant != NULL) 2326: { 2327: if ((*(*((struct_processus_fils *) (*(*((struct_liste_chainee *) 2328: l_element_courant)).donnee).objet)).thread) 2329: .processus_detache == d_vrai) 2330: { 2331: if ((*s_etat_processus).debug == d_vrai) 2332: { 2333: if (((*s_etat_processus).type_debug & d_debug_processus) 2334: != 0) 2335: { 2336: if ((*s_etat_processus).langue == 'F') 2337: { 2338: printf("[%d] Signalement pour arrêt du " 2339: "processus %d\n", 2340: (int) getpid(), 2341: (int) (*(*((struct_processus_fils *) 2342: (*(*((struct_liste_chainee *) 2343: l_element_courant)).donnee).objet)) 2344: .thread).pid); 2345: } 2346: else 2347: { 2348: printf("[%d] Send stop signal to process %d\n", 2349: (int) getpid(), 2350: (int) (*(*((struct_processus_fils *) 2351: (*(*((struct_liste_chainee *) 2352: l_element_courant)).donnee).objet)) 2353: .thread).pid); 2354: } 2355: } 2356: } 2357: 2358: if ((*s_etat_processus).var_volatile_alarme != 0) 2359: { 2360: kill((*(*((struct_processus_fils *) 2361: (*(*l_element_courant).donnee).objet)).thread).pid, 2362: SIGURG); 2363: } 2364: else 2365: { 2366: if ((*s_etat_processus).arret_depuis_abort == -1) 2367: { 2368: kill((*(*((struct_processus_fils *) 2369: (*(*l_element_courant).donnee).objet)).thread) 2370: .pid, SIGFABORT); 2371: } 2372: else 2373: { 2374: kill((*(*((struct_processus_fils *) 2375: (*(*l_element_courant).donnee).objet)).thread) 2376: .pid, SIGFSTOP); 2377: } 2378: } 2379: } 2380: else 2381: { 2382: if ((*s_etat_processus).debug == d_vrai) 2383: { 2384: if (((*s_etat_processus).type_debug & d_debug_processus) 2385: != 0) 2386: { 2387: if ((*s_etat_processus).langue == 'F') 2388: { 2389: printf("[%d] Signalement pour arrêt du " 2390: "thread %llu\n", 2391: (int) getpid(), (unsigned long long) 2392: (*(*((struct_processus_fils *) 2393: (*(*((struct_liste_chainee *) 2394: l_element_courant)).donnee).objet)).thread) 2395: .tid); 2396: } 2397: else 2398: { 2399: printf("[%d] Send stop signal to thread %llu\n", 2400: (int) getpid(), (unsigned long long) 2401: (*(*((struct_processus_fils *) 2402: (*(*((struct_liste_chainee *) 2403: l_element_courant)).donnee).objet)).thread) 2404: .tid); 2405: } 2406: } 2407: } 2408: 2409: pthread_mutex_lock(&((*(*((struct_processus_fils *) 2410: (*(*l_element_courant).donnee).objet)).thread).mutex)); 2411: 2412: if ((*(*((struct_processus_fils *) 2413: (*(*l_element_courant).donnee).objet)).thread) 2414: .thread_actif == d_vrai) 2415: { 2416: if ((*s_etat_processus).var_volatile_alarme != 0) 2417: { 2418: pthread_kill((*(*((struct_processus_fils *) 2419: (*(*l_element_courant).donnee).objet)).thread) 2420: .tid, SIGURG); 2421: } 2422: else 2423: { 2424: if ((*s_etat_processus).arret_depuis_abort == -1) 2425: { 2426: pthread_kill((*(*((struct_processus_fils *) 2427: (*(*l_element_courant).donnee).objet)) 2428: .thread).tid, SIGFABORT); 2429: } 2430: else 2431: { 2432: pthread_kill((*(*((struct_processus_fils *) 2433: (*(*l_element_courant).donnee).objet)) 2434: .thread).tid, SIGFSTOP); 2435: } 2436: } 2437: } 2438: 2439: pthread_mutex_unlock(&((*(*((struct_processus_fils *) 2440: (*(*l_element_courant).donnee).objet)).thread).mutex)); 2441: } 2442: 2443: l_element_courant = (*l_element_courant).suivant; 2444: } 2445: 2446: /* 2447: * Attente de la fin de tous les processus fils 2448: */ 2449: 2450: for(i = 0; i < d_NOMBRE_INTERRUPTIONS; 2451: (*s_etat_processus).masque_interruptions[i++] = 'I'); 2452: 2453: attente.tv_sec = 0; 2454: attente.tv_nsec = GRANULARITE_us * 1000; 2455: 2456: while((*s_etat_processus).l_base_pile_processus != NULL) 2457: { 2458: status = 0; 2459: 2460: l_element_courant = (struct_liste_chainee *) 2461: (*s_etat_processus).l_base_pile_processus; 2462: 2463: registre_stop = (*s_etat_processus) 2464: .var_volatile_traitement_retarde_stop; 2465: (*s_etat_processus).var_volatile_traitement_retarde_stop = 1; 2466: 2467: for(i = 0; i < (unsigned long) (*(*((struct_processus_fils *) 2468: (*(*l_element_courant) 2469: .donnee).objet)).thread).nombre_objets_dans_pipe; i++) 2470: { 2471: if ((s_objet_temporaire = lecture_pipe(s_etat_processus, 2472: (*(*((struct_processus_fils *) (*(*l_element_courant) 2473: .donnee).objet)).thread).pipe_objets[0])) != NULL) 2474: { 2475: liberation(s_etat_processus, s_objet_temporaire); 2476: 2477: (*(*((struct_processus_fils *) (*(*l_element_courant) 2478: .donnee).objet)).thread).nombre_objets_dans_pipe--; 2479: 2480: action.sa_handler = SIG_IGN; 2481: action.sa_flags = SA_ONSTACK; 2482: 2483: if (sigaction(SIGPIPE, &action, ®istre) != 0) 2484: { 2485: pthread_mutex_unlock(&((*s_etat_processus).mutex)); 2486: 2487: if (registre_stop == 0) 2488: { 2489: if ((*s_etat_processus) 2490: .var_volatile_traitement_retarde_stop 2491: == -1) 2492: { 2493: (*s_etat_processus) 2494: .var_volatile_requete_arret = -1; 2495: } 2496: 2497: (*s_etat_processus) 2498: .var_volatile_traitement_retarde_stop = 2499: registre_stop; 2500: } 2501: 2502: # ifdef _BROKEN_SIGINFO 2503: destruction_fifos_signaux(s_etat_processus); 2504: # endif 2505: 2506: (*s_etat_processus).erreur_systeme = d_es_signal; 2507: exit(EXIT_FAILURE); 2508: } 2509: 2510: while((longueur_ecriture = write_atomic( 2511: s_etat_processus, (*(*((struct_processus_fils *) 2512: (*(*l_element_courant).donnee).objet)) 2513: .thread).pipe_nombre_injections[1], "+", 2514: sizeof(unsigned char))) != 2515: sizeof(unsigned char)) 2516: { 2517: if (longueur_ecriture == -1) 2518: { 2519: // Le processus n'existe plus. 2520: break; 2521: } 2522: } 2523: 2524: if (registre_stop == 0) 2525: { 2526: if ((*s_etat_processus) 2527: .var_volatile_traitement_retarde_stop == -1) 2528: { 2529: (*s_etat_processus).var_volatile_requete_arret 2530: = -1; 2531: } 2532: 2533: (*s_etat_processus) 2534: .var_volatile_traitement_retarde_stop = 2535: registre_stop; 2536: } 2537: 2538: if (sigaction(SIGPIPE, ®istre, NULL) != 0) 2539: { 2540: # ifdef _BROKEN_SIGINFO 2541: destruction_fifos_signaux(s_etat_processus); 2542: # endif 2543: 2544: pthread_mutex_unlock(&((*s_etat_processus).mutex)); 2545: 2546: (*s_etat_processus).erreur_systeme = d_es_signal; 2547: exit(EXIT_FAILURE); 2548: } 2549: } 2550: } 2551: 2552: pthread_mutex_unlock(&((*s_etat_processus).mutex)); 2553: 2554: if ((*s_etat_processus).nombre_interruptions_non_affectees != 0) 2555: { 2556: affectation_interruptions_logicielles(s_etat_processus); 2557: } 2558: 2559: nanosleep(&attente, NULL); 2560: pthread_mutex_lock(&((*s_etat_processus).mutex)); 2561: } 2562: 2563: pthread_mutex_unlock(&((*s_etat_processus).mutex)); 2564: 2565: l_element_courant = (*s_etat_processus).s_sockets; 2566: 2567: while(l_element_courant != NULL) 2568: { 2569: l_element_suivant = (*l_element_courant).suivant; 2570: 2571: if ((*((struct_socket *) (*(*l_element_courant).donnee) 2572: .objet)).socket_connectee == d_vrai) 2573: { 2574: shutdown((*((struct_socket *) (*(*l_element_courant).donnee) 2575: .objet)).socket, SHUT_RDWR); 2576: } 2577: 2578: close((*((struct_socket *) (*(*l_element_courant).donnee) 2579: .objet)).socket); 2580: 2581: if (((*((struct_socket *) (*(*l_element_courant).donnee).objet)) 2582: .pid == getpid()) && (pthread_equal((*((struct_socket *) 2583: (*(*l_element_courant).donnee).objet)).tid, pthread_self()) 2584: != 0)) 2585: { 2586: if ((*((struct_socket *) (*(*l_element_courant).donnee).objet)) 2587: .effacement == 'Y') 2588: { 2589: unlink((*((struct_socket *) (*(*l_element_courant).donnee) 2590: .objet)).adresse); 2591: } 2592: } 2593: 2594: liberation(s_etat_processus, 2595: (*((struct_liste_chainee *) l_element_courant)).donnee); 2596: free(l_element_courant); 2597: 2598: l_element_courant = l_element_suivant; 2599: } 2600: 2601: l_element_courant = (*s_etat_processus).s_connecteurs_sql; 2602: 2603: while(l_element_courant != NULL) 2604: { 2605: l_element_suivant = (*l_element_courant).suivant; 2606: 2607: sqlclose((*l_element_courant).donnee); 2608: 2609: liberation(s_etat_processus, 2610: (*((struct_liste_chainee *) l_element_courant)).donnee); 2611: free(l_element_courant); 2612: 2613: l_element_courant = l_element_suivant; 2614: } 2615: 2616: if ((((*s_etat_processus).erreur_execution != d_ex) || 2617: ((*s_etat_processus).exception != d_ep) || 2618: ((*s_etat_processus).erreur_systeme != d_es)) && 2619: ((*s_etat_processus).var_volatile_traitement_sigint == 0)) 2620: { 2621: printf("%s [%d]\n", message = 2622: messages(s_etat_processus), (int) getpid()); 2623: free(message); 2624: 2625: if ((*s_etat_processus).core == d_vrai) 2626: { 2627: printf("\n"); 2628: 2629: if ((*s_etat_processus).langue == 'F') 2630: { 2631: printf("+++Information : Génération du fichier rpl-core " 2632: "[%d]\n", (int) getpid()); 2633: } 2634: else 2635: { 2636: printf("+++Information : Writing rpl-core file [%d]\n", 2637: (int) getpid()); 2638: } 2639: 2640: rplcore(s_etat_processus); 2641: 2642: if ((*s_etat_processus).langue == 'F') 2643: { 2644: printf("+++Information : Processus tracé [%d]\n", 2645: (int) getpid()); 2646: } 2647: else 2648: { 2649: printf("+++Information : Done [%d]\n", (int) getpid()); 2650: } 2651: 2652: printf("\n"); 2653: fflush(stdout); 2654: } 2655: } 2656: 2657: liberation_arbre_instructions(s_etat_processus, 2658: (*s_etat_processus).arbre_instructions); 2659: free((*s_etat_processus).pointeurs_caracteres); 2660: 2661: if ((*s_etat_processus).entree_standard != NULL) 2662: { 2663: pclose((*s_etat_processus).entree_standard); 2664: (*s_etat_processus).entree_standard = NULL; 2665: } 2666: 2667: liberation(s_etat_processus, (*s_etat_processus).indep); 2668: liberation(s_etat_processus, (*s_etat_processus).depend); 2669: 2670: free((*s_etat_processus).label_x); 2671: free((*s_etat_processus).label_y); 2672: free((*s_etat_processus).label_z); 2673: free((*s_etat_processus).titre); 2674: free((*s_etat_processus).legende); 2675: 2676: liberation(s_etat_processus, 2677: (*s_etat_processus).parametres_courbes_de_niveau); 2678: 2679: if ((*s_etat_processus).instruction_derniere_erreur != NULL) 2680: { 2681: free((*s_etat_processus).instruction_derniere_erreur); 2682: (*s_etat_processus).instruction_derniere_erreur = NULL; 2683: } 2684: 2685: liberation_arbre_variables(s_etat_processus, 2686: (*s_etat_processus).s_arbre_variables, d_vrai); 2687: free((*s_etat_processus).pointeurs_caracteres_variables); 2688: 2689: for(i = 0; i < (*s_etat_processus).nombre_variables_statiques; i++) 2690: { 2691: liberation(s_etat_processus, 2692: (*s_etat_processus).s_liste_variables_statiques[i].objet); 2693: free((*s_etat_processus).s_liste_variables_statiques[i].nom); 2694: } 2695: 2696: free((*s_etat_processus).s_liste_variables_statiques); 2697: 2698: for(i = 0; i < (*(*s_etat_processus).s_liste_variables_partagees) 2699: .nombre_variables; i++) 2700: { 2701: liberation(s_etat_processus, 2702: (*(*s_etat_processus).s_liste_variables_partagees) 2703: .table[i].objet); 2704: free((*(*s_etat_processus).s_liste_variables_partagees) 2705: .table[i].nom); 2706: } 2707: 2708: if ((*(*s_etat_processus).s_liste_variables_partagees).table 2709: != NULL) 2710: { 2711: free((struct_variable_partagee *) 2712: (*(*s_etat_processus).s_liste_variables_partagees).table); 2713: } 2714: 2715: pthread_mutex_destroy(&((*(*s_etat_processus) 2716: .s_liste_variables_partagees).mutex)); 2717: 2718: l_element_courant = (*s_etat_processus).l_base_pile; 2719: while(l_element_courant != NULL) 2720: { 2721: l_element_suivant = (*l_element_courant).suivant; 2722: 2723: liberation(s_etat_processus, (*l_element_courant).donnee); 2724: free(l_element_courant); 2725: 2726: l_element_courant = l_element_suivant; 2727: } 2728: 2729: l_element_courant = (*s_etat_processus).l_base_pile_last; 2730: while(l_element_courant != NULL) 2731: { 2732: l_element_suivant = (*l_element_courant).suivant; 2733: 2734: liberation(s_etat_processus, (*l_element_courant).donnee); 2735: free(l_element_courant); 2736: 2737: l_element_courant = l_element_suivant; 2738: } 2739: 2740: l_element_courant = (*s_etat_processus).l_base_pile_contextes; 2741: while(l_element_courant != NULL) 2742: { 2743: l_element_suivant = (*l_element_courant).suivant; 2744: 2745: liberation(s_etat_processus, (*l_element_courant).donnee); 2746: free(l_element_courant); 2747: 2748: l_element_courant = l_element_suivant; 2749: } 2750: 2751: l_element_courant = (*s_etat_processus).l_base_pile_taille_contextes; 2752: while(l_element_courant != NULL) 2753: { 2754: l_element_suivant = (*l_element_courant).suivant; 2755: 2756: liberation(s_etat_processus, (*l_element_courant).donnee); 2757: free(l_element_courant); 2758: 2759: l_element_courant = l_element_suivant; 2760: } 2761: 2762: l_element_courant = (struct_liste_chainee *) 2763: (*s_etat_processus).l_base_pile_systeme; 2764: while(l_element_courant != NULL) 2765: { 2766: l_element_suivant = (struct_liste_chainee *) 2767: (*((struct_liste_pile_systeme *) 2768: l_element_courant)).suivant; 2769: 2770: liberation(s_etat_processus, (*((struct_liste_pile_systeme *) 2771: l_element_courant)).indice_boucle); 2772: liberation(s_etat_processus, (*((struct_liste_pile_systeme *) 2773: l_element_courant)).limite_indice_boucle); 2774: liberation(s_etat_processus, (*((struct_liste_pile_systeme *) 2775: l_element_courant)).objet_de_test); 2776: 2777: if ((*((struct_liste_pile_systeme *) 2778: l_element_courant)).nom_variable != NULL) 2779: { 2780: free((*((struct_liste_pile_systeme *) 2781: l_element_courant)).nom_variable); 2782: } 2783: 2784: free((struct_liste_pile_systeme *) l_element_courant); 2785: 2786: l_element_courant = l_element_suivant; 2787: } 2788: 2789: /* 2790: * Destruction des bibliothèques 2791: */ 2792: 2793: l_element_courant = (*s_etat_processus).s_bibliotheques; 2794: 2795: while(l_element_courant != NULL) 2796: { 2797: l_element_suivant = (*l_element_courant).suivant; 2798: 2799: free((*((struct_bibliotheque *) (*l_element_courant).donnee)).nom); 2800: 2801: dlclose((*((struct_bibliotheque *) (*l_element_courant).donnee)) 2802: .descripteur); 2803: 2804: free((*l_element_courant).donnee); 2805: free(l_element_courant); 2806: 2807: l_element_courant = l_element_suivant; 2808: } 2809: 2810: for(i = 0; i < (*s_etat_processus).nombre_instructions_externes; i++) 2811: { 2812: free((*s_etat_processus).s_instructions_externes[i].nom); 2813: free((*s_etat_processus).s_instructions_externes[i] 2814: .nom_bibliotheque); 2815: } 2816: 2817: if ((*s_etat_processus).nombre_instructions_externes != 0) 2818: { 2819: free((*s_etat_processus).s_instructions_externes); 2820: } 2821: 2822: l_element_courant = (struct_liste_chainee *) 2823: (*s_etat_processus).s_marques; 2824: 2825: while(l_element_courant != NULL) 2826: { 2827: free((*((struct_marque *) l_element_courant)).label); 2828: free((*((struct_marque *) l_element_courant)).position); 2829: l_element_suivant = (struct_liste_chainee *) 2830: (*((struct_marque *) l_element_courant)).suivant; 2831: free((struct_marque *) l_element_courant); 2832: l_element_courant = l_element_suivant; 2833: } 2834: 2835: free((*s_etat_processus).chemin_fichiers_temporaires); 2836: 2837: if ((*s_etat_processus).debug == d_vrai) 2838: if (((*s_etat_processus).type_debug & 2839: d_debug_processus) != 0) 2840: { 2841: if ((*s_etat_processus).langue == 'F') 2842: { 2843: printf("[%d] Arrêt du processus\n", (int) getpid()); 2844: } 2845: else 2846: { 2847: printf("[%d] Stop process\n", (int) getpid()); 2848: } 2849: 2850: fflush(stdout); 2851: } 2852: 2853: liberation(s_etat_processus, s_objet); 2854: 2855: free((*s_etat_processus).definitions_chainees); 2856: free((*s_etat_processus).nom_fichier_historique); 2857: 2858: for(i = 0; i < d_NOMBRE_INTERRUPTIONS; i++) 2859: { 2860: liberation(s_etat_processus, 2861: (*s_etat_processus).corps_interruptions[i]); 2862: 2863: l_element_courant = (*s_etat_processus) 2864: .pile_origine_interruptions[i]; 2865: 2866: while(l_element_courant != NULL) 2867: { 2868: l_element_suivant = (*l_element_courant).suivant; 2869: 2870: liberation(s_etat_processus, (*l_element_courant).donnee); 2871: free(l_element_courant); 2872: 2873: l_element_courant = l_element_suivant; 2874: } 2875: } 2876: 2877: if ((*s_etat_processus).generateur_aleatoire != NULL) 2878: { 2879: liberation_generateur_aleatoire(s_etat_processus); 2880: } 2881: 2882: if ((*s_etat_processus).profilage == d_vrai) 2883: { 2884: ecriture_profil(s_etat_processus); 2885: liberation_profil(s_etat_processus); 2886: } 2887: 2888: closelog(); 2889: 2890: liberation_allocateur(s_etat_processus); 2891: retrait_thread(s_etat_processus); 2892: 2893: pthread_mutex_destroy(&((*s_etat_processus).mutex)); 2894: pthread_mutex_destroy(&((*s_etat_processus).mutex_allocation)); 2895: pthread_mutex_destroy(&((*s_etat_processus).protection_liste_mutexes)); 2896: 2897: pthread_key_delete(semaphore_fork_processus_courant); 2898: 2899: # ifndef SEMAPHORES_NOMMES 2900: sem_post(&((*s_etat_processus).semaphore_fork)); 2901: sem_destroy(&((*s_etat_processus).semaphore_fork)); 2902: # else 2903: sem_post((*s_etat_processus).semaphore_fork); 2904: sem_destroy2((*s_etat_processus).semaphore_fork, sem_fork); 2905: # endif 2906: 2907: free((*s_etat_processus).localisation); 2908: free(s_argument_thread); 2909: 2910: # ifndef SEMAPHORES_NOMMES 2911: sem_destroy(&semaphore_liste_threads); 2912: sem_post(&semaphore_gestionnaires_signaux); 2913: sem_destroy(&semaphore_gestionnaires_signaux); 2914: sem_destroy(&semaphore_gestionnaires_signaux_atomique); 2915: # else 2916: sem_destroy2(semaphore_liste_threads, sem_liste_threads); 2917: sem_post(semaphore_gestionnaires_signaux); 2918: sem_destroy2(semaphore_gestionnaires_signaux, 2919: sem_gestionnaires_signaux); 2920: sem_destroy2(semaphore_gestionnaires_signaux_atomique, 2921: sem_gestionnaires_signaux_atomique); 2922: # endif 2923: 2924: clear_history(); 2925: 2926: # ifdef _BROKEN_SIGINFO 2927: destruction_fifos_signaux(s_etat_processus); 2928: # endif 2929: 2930: free(s_etat_processus); 2931: 2932: # ifdef DEBUG_MEMOIRE 2933: debug_memoire_verification(); 2934: analyse_post_mortem(); 2935: # endif 2936: 2937: exit(EXIT_SUCCESS); 2938: } 2939: else 2940: { 2941: (*s_etat_processus).erreur_systeme = d_es_processus; 2942: return; 2943: } 2944: 2945: // Si le pid existe déjà dans la pile des processus, il s'agit forcement 2946: // d'un processus moribond. On attend donc qu'il soit effectivement 2947: // libéré. 2948: 2949: do 2950: { 2951: l_element_courant = (struct_liste_chainee *) 2952: (*s_etat_processus).l_base_pile_processus; 2953: drapeau = d_faux; 2954: 2955: attente.tv_sec = 0; 2956: attente.tv_nsec = GRANULARITE_us * 1000; 2957: 2958: while(l_element_courant != NULL) 2959: { 2960: if ((*(*((struct_processus_fils *) 2961: (*(*l_element_courant).donnee).objet)).thread) 2962: .processus_detache == d_vrai) 2963: { 2964: if ((*(*((struct_processus_fils *) 2965: (*(*l_element_courant).donnee).objet)).thread).pid == 2966: (*s_argument_thread).pid) 2967: { 2968: if (pthread_mutex_unlock(&((*s_etat_processus).mutex)) != 0) 2969: { 2970: (*s_etat_processus).erreur_systeme = d_es_processus; 2971: return; 2972: } 2973: 2974: nanosleep(&attente, NULL); 2975: INCR_GRANULARITE(attente.tv_nsec); 2976: 2977: if (pthread_mutex_lock(&((*s_etat_processus).mutex)) != 0) 2978: { 2979: (*s_etat_processus).erreur_systeme = d_es_processus; 2980: return; 2981: } 2982: 2983: drapeau = d_vrai; 2984: break; 2985: } 2986: } 2987: 2988: l_element_courant = (*l_element_courant).suivant; 2989: } 2990: } while(drapeau == d_vrai); 2991: 2992: if (empilement(s_etat_processus, 2993: (struct_liste_chainee **) &((*s_etat_processus) 2994: .l_base_pile_processus), s_objet_systeme) == d_erreur) 2995: { 2996: pthread_mutex_unlock(&((*s_etat_processus).mutex)); 2997: return; 2998: } 2999: 3000: if (empilement(s_etat_processus, &((*s_etat_processus).l_base_pile), 3001: s_objet) == d_erreur) 3002: { 3003: pthread_mutex_unlock(&((*s_etat_processus).mutex)); 3004: return; 3005: } 3006: 3007: // Être sûr que le processus fils soit déjà présent... 3008: 3009: attente.tv_sec = 0; 3010: attente.tv_nsec = GRANULARITE_us * 1000; 3011: 3012: while(kill((*s_argument_thread).pid, 0) != 0) 3013: { 3014: //if ((errno != ESRCH) && (errno != EAGAIN)) 3015: if (errno != ESRCH) 3016: { 3017: (*s_etat_processus).erreur_systeme = d_es_processus; 3018: pthread_mutex_unlock(&((*s_etat_processus).mutex)); 3019: return; 3020: } 3021: 3022: nanosleep(&attente, NULL); 3023: INCR_GRANULARITE(attente.tv_nsec); 3024: } 3025: 3026: // Le fils peut être présent sans être en attente du signal de départ. 3027: 3028: if (kill((*s_argument_thread).pid, SIGSTART) != 0) 3029: { 3030: (*s_etat_processus).erreur_systeme = d_es_processus; 3031: pthread_mutex_unlock(&((*s_etat_processus).mutex)); 3032: return; 3033: } 3034: 3035: if (pthread_sigmask(SIG_SETMASK, &oldset, NULL) != 0) 3036: { 3037: (*s_etat_processus).erreur_systeme = d_es_processus; 3038: pthread_mutex_unlock(&((*s_etat_processus).mutex)); 3039: return; 3040: } 3041: 3042: sigpending(&set); 3043: 3044: if (pthread_mutex_unlock(&((*s_etat_processus).mutex)) != 0) 3045: { 3046: (*s_etat_processus).erreur_systeme = d_es_processus; 3047: return; 3048: } 3049: 3050: return; 3051: } 3052: 3053: // vim: ts=4